예제 #1
0
def getitem(M, k):
    """
    Returns the value of entry k in M, if k is a 2-tuple.
    Returns the vector M[k], if k is a number (column-vector, if k label is present both for rows and columns).
    >>> M = Mat(({1,3,5}, {'a'}), {(1,'a'):4, (5,'a'): 2})
    >>> M[1,'a']
    4
    >>> M[3,'a']
    0
    >>> M['a'] == Vec({1, 3, 5}, {1:4, 5:2})
    True
    >>> M = Mat(({'a','b'}, {'a','b'}), {('a','a'):1, ('b','b'):1, ('b','a'):1})
    >>> M['a'] == Vec({'a','b'}, {'a':1, 'b':1})
    True
    >>> M['b'] == Vec({'a','b'}, {'a':0, 'b':1})
    True
    """
    if tuple == type(k):  # getting number by pair of indices
        assert k[0] in M.D[0] and k[1] in M.D[1]
        return M.f.get((k[0], k[1]), 0)

    else:  # getting vector by one index, preference given to column-vectors
        assert k in M.D[0] or k in M.D[1]
        if k in M.D[1]:
            return Vec(M.D[0],
                       {i: M.f.get((i, k), 0)
                        for i in M.D[0]})  # return column labeled with k
        else:  # in M.D[0]
            return Vec(M.D[1], {i: M.f.get((k, i), 0)
                                for i in M.D[1]})  # return row labeled with k
예제 #2
0
    def setup_light(self):
        light = Light()
        light.direction = Vec(-5, -5, -5)
        light.direction.norm()
        light.color = Vec(1, 1, 1)
        light.ambient_intensity = 0.3
        light.diffuse_intensity = 1.0

        return light
예제 #3
0
    def __init__(self, resource, scene, actor_type):
        """Constructor.

        :param resource: The character resource
        :type resource: :class:`loaders.Resource`

        :param scene: Scene to add the actor to.
        :type scene: :class:`renderlib.scene.Scene`

        :param actor_type: Type of actor entity.
        :type actor_type: :enum:`game.entities.actor.ActorType`
        """
        self.resource = resource
        self.actor_type = actor_type

        mesh = resource['model']

        # root transformation to apply to the mesh
        self.transform = mesh.transform

        # instantiate animations
        self.init_animations(mesh)
        self.current_anim = self.animations[action_anim_index(ActionType.idle)]

        # create a 2D texture from texture image
        texture = Texture.from_image(resource['texture'],
                                     Texture.TextureType.texture_2d)

        # create a material
        material = Material()
        material.texture = texture
        material.receive_light = True

        # rendering props
        self.props = MeshProps()
        self.props.material = material
        self.props.animation = self.current_anim
        self.props.receive_shadows = True
        self.props.cast_shadows = True

        # add the mesh to the scene
        self.obj = scene.add_mesh(mesh, self.props)

        # Initialize movable component
        movable = Movable((0.0, 0.0))

        # initialize actor
        super().__init__(movable)

        # FIXME: hardcoded bounding box
        self._bounding_box = Vec(-0.5, 0, -0.5), Vec(0.5, 2, 0.5)

        self.heading = 0.0
예제 #4
0
    def bounding_box(self):
        """The bounding box of the entity.

        The bounding box is represented by the smaller and bigger edge of the box
        itself.

        :returns: The bounding box of the actor
        :rtype: :class:`tuple`
        """
        l, m = self._bounding_box
        pos = self.position
        return l + Vec(pos[0], 0, pos[1]), m + Vec(pos[0], 0, pos[1])
예제 #5
0
def matrix_vector_mul(M, v):
    """
    Returns the product of matrix M and vector v.

    Consider using brackets notation v[...] in your procedure
    to access entries of the input vector.  This avoids some sparsity bugs.

    >>> N1 = Mat(({1, 3, 5, 7}, {'a', 'b'}), {(1, 'a'): -1, (1, 'b'): 2, (3, 'a'): 1, (3, 'b'):4, (7, 'a'): 3, (5, 'b'):-1})
    >>> u1 = Vec({'a', 'b'}, {'a': 1, 'b': 2})
    >>> N1*u1 == Vec({1, 3, 5, 7},{1: 3, 3: 9, 5: -2, 7: 3})
    True
    >>> N1 == Mat(({1, 3, 5, 7}, {'a', 'b'}), {(1, 'a'): -1, (1, 'b'): 2, (3, 'a'): 1, (3, 'b'):4, (7, 'a'): 3, (5, 'b'):-1})
    True
    >>> u1 == Vec({'a', 'b'}, {'a': 1, 'b': 2})
    True
    >>> N2 = Mat(({('a', 'b'), ('c', 'd')}, {1, 2, 3, 5, 8}), {})
    >>> u2 = Vec({1, 2, 3, 5, 8}, {})
    >>> N2*u2 == Vec({('a', 'b'), ('c', 'd')},{})
    True
    >>> M3 = Mat(({0,1},{'a','b'}),{(0,'a'):1, (0,'b'):1, (1,'a'):1, (1,'b'):1})
    >>> v3 = Vec({'a','b'},{'a':1,'b':1})
    >>> M3*v3 == Vec({0, 1},{0: 2, 1: 2})
    True
    """
    assert M.D[1] == v.D
    # A(m*n), x(n*1) => A*x = [ dot(a1*,v), ..., dot(an*v) ] => column-vector (m*1)
    # return Vec(M.D[0], {i:sum(M[i,j]*v[j] for j in M.D[1]) for i in M.D[0]})  # not using sparsity => need to rewrite

    # Sparse matrix optimization
    # b = Vec(M.D[0], {i:0 for i in M.D[0]})
    b = Vec(M.D[0], {})
    for i, j in M.f:
        b[i] = b[i] + v[j] * M[i, j]
    return b
예제 #6
0
def vector_matrix_mul(v, M):
    """
    returns the product of vector v and matrix M

    Consider using brackets notation v[...] in your procedure
    to access entries of the input vector.  This avoids some sparsity bugs.

    >>> v1 = Vec({1, 2, 3}, {1: 1, 2: 8})
    >>> M1 = Mat(({1, 2, 3}, {'a', 'b', 'c'}), {(1, 'b'): 2, (2, 'a'):-1, (3, 'a'): 1, (3, 'c'): 7})
    >>> v1*M1 == Vec({'a', 'b', 'c'},{'a': -8, 'b': 2, 'c': 0})
    True
    >>> v1 == Vec({1, 2, 3}, {1: 1, 2: 8})
    True
    >>> M1 == Mat(({1, 2, 3}, {'a', 'b', 'c'}), {(1, 'b'): 2, (2, 'a'):-1, (3, 'a'): 1, (3, 'c'): 7})
    True
    >>> v2 = Vec({'a','b'}, {})
    >>> M2 = Mat(({'a','b'}, {0, 2, 4, 6, 7}), {})
    >>> v2*M2 == Vec({0, 2, 4, 6, 7},{})
    True
    >>> v3 = Vec({'a','b'},{'a':1,'b':1})
    >>> M3 = Mat(({'a', 'b'}, {0, 1}), {('a', 1): 1, ('b', 1): 1, ('a', 0): 1, ('b', 0): 1})
    >>> v3*M3 == Vec({0, 1},{0: 2, 1: 2})
    True
    """
    assert M.D[0] == v.D
    # v*(1*m), A(m*n) => v*A = [ dot(v*,a1), ..., dot(v*,an) ]* => row-vector (1*n)
    # return Vec(M.D[1], {j:sum(v[i]*M[i,j] for i in M.D[0]) for j in M.D[1]})  # not using sparsity => need to rewrite

    # Sparse matrix optimization
    # b = Vec(M.D[1], {i:0 for i in M.D[1]})
    b = Vec(M.D[1], {})
    for i, j in M.f:
        b[j] = b[j] + v[i] * M[i, j]
    return b
예제 #7
0
    def __init__(self, resource, scene):
        """Constructor.

        :param resource: Resource containing map data.
        :type resource: :class:`resource_manager.Resource`

        :param scene: Scene to add the health bar to.
        :type scene: :class:`renderlib.scene.Scene`
        """
        super().__init__()

        mesh = resource['walls_mesh']
        texture = Texture.from_image(resource['walls_texture'],
                                     Texture.TextureType.texture_2d)

        material = Material()
        material.texture = texture
        material.receive_light = True

        props = MeshProps()
        props.material = material
        props.receive_shadows = False
        props.cast_shadows = False

        self.obj = scene.add_mesh(mesh, props)
        # FIXME: this offset here is due to the calculation of the walkable
        # matrix that adds one more walkable line on top of the scenario.
        self.obj.position = Vec(0.0, 0.0, 1.0)

        self.objects = []

        # Initialize static objects
        for obj in resource.data['objects']:
            self.add_object(MapObject(resource[obj['ref']], scene, obj))
예제 #8
0
def ray_cast(x, y, w, h, camera):
    """Returns the world coordinates related to the given x,y coordinates.

    :param x: The x coordinate relative to screen
    :type x: int

    :param y: The y coordinate relative to screen
    :type y: int

    :param w: The width of the screen
    :type w: int

    :param h: The height of the screen
    :type h: int

    :param camera: The camera we are using to trace the ray.
    :type camera: :class:`renderer.Camera`

    :returns: The point in world coordinates.
    :type: :class:`mat.Vec`
    """
    # Find the direction applying the modelview matrix to the facing direction
    # of the camera
    pos, ray = camera.trace_ray(x, y, w, h)

    # The normal vector for the y=0 plane
    norm = Vec(0, 1, 0)

    # And here finally we have the target of the click in world coordinates More
    # reference about the used math here:
    #  * http://antongerdelan.net/opengl/raycasting.html
    t = -(pos.dot(norm)) / ray.dot(norm)
    return pos + (ray * t)
예제 #9
0
    def partial_movement(self, distance, position, next_position, path):
        """Recursive function to calculate parial movements (to consider cases
        in which during the given dt we are actually going over a the
        destination point.

        :param distance: The magnitude of the movement vector.
        :type distance: float

        :param position: The current position of the movable.
        :type position: tuple

        :param next_position: The next position in the path.
        :type next_position: tuple

        :param path: The other points of the path.
        :type path: list
        """
        # Actual distance from destination
        np = Vec(next_position[0], next_position[1], 0.0)
        p = Vec(position[0], position[1], 0.0)
        dst = (np - p).mag()

        # We did not reach the next_position yet.
        if distance < dst:
            self._direction = np - p
            self._direction.norm()
            cur = p + self._direction * distance
            self._position = cur.x, cur.y

        # We arrived in next_position, continue toward the next waypoint of the
        # path recursively calling partial_movement.
        elif path:
            position, next_position, path = next_position, path[0], path[1:]
            LOG.debug('Switched destination to {}'.format(next_position))
            self.partial_movement(distance - dst, position, next_position,
                                  path)

        # We reached or surpassed next_position and there are no more path
        # steps: we arrived!
        else:
            LOG.debug('Movable arrived at destination {}'.format(
                self._position))
            self.next_position = None
            self._direction = None
            self.path = []
            self.speed = 0
            self._position = next_position
예제 #10
0
    def __init__(self, resource, scene, position, progress, completed):
        """Constructor.

        :param resource: The building resource
        :type resource: :class:`loaders.Resource`

        :param scene: Scene to add the building bar to.
        :type scene: :class:`renderlib.scene.Scene`

        :param position: The position of the building
        :type position: :class:`tuple`

        :param progress: The current amount of hp and the total one
        :type progress: :class:`tuple`

        :param completed: Whether the building is completed or not
        :type completed: :class:`bool`
        """
        super().__init__()

        self.scene = scene
        self.obj = None
        self._position = to_scene(*position)
        self._completed = None

        # create texture
        texture = Texture.from_image(resource['texture'],
                                     Texture.TextureType.texture_2d)
        self.mesh_project = resource['model_project']
        self.mesh_complete = resource['model_complete']

        # create material
        material = Material()
        material.texture = texture

        # create render props
        self.props = MeshProps()
        self.props.material = material

        # set initial building status
        self.completed = completed

        # FIXME: hardcoded bounding box
        self._bounding_box = Vec(-0.5, 0, -0.5), Vec(0.5, 2, 0.5)
예제 #11
0
    def update(self, dt):
        """Update the local player.

        This method computes player's game logic as a function of time and sends
        the appropriate event.

        :param dt: Time delta from last update.
        :type dt: float
        """
        super(Player, self).update(dt)

        # map player game position to world (x,y -> x,z)
        x, z = self.position

        # update camera position and orientation
        context = Context.get_instance()
        camera = context.camera
        camera.position = Vec(x, 20, z + 5)
        camera.look_at(camera.position, Vec(x, 0, z))
예제 #12
0
파일: ui.py 프로젝트: eyedeekay/surviveler
    def __init__(self, resource, width, height, player_data):
        """Constructor.

        :param resource: The UI resource.
        :type resource: :class:`loaders.Resource`

        :param width: UI width in pixels.
        :type width: int

        :param height: UI height in pixels.
        :type height: int

        :param player_data: Player resource.
        :type player_ddata: :class:`loaders.Resource`
        """
        self.w = width
        self.h = height
        self.scene = Scene()
        self.camera = OrthographicCamera(
            -self.w / 2,  # left
            +self.w / 2,  # right
            +self.h / 2,  # top
            -self.h / 2,  # bottom
            0,  # near
            1)  # far

        font = resource['font'].get_size(16)
        props = TextProps()
        props.color = Vec(1, 1, 1, 1)

        # Mode node
        self.game_mode_text = Text(font, Context.GameMode.default.value)
        self.game_mode = self.scene.add_text(self.game_mode_text, props)
        self.transform(self.game_mode, self.w * 0.85, 20)

        # FPS counter
        self.fps_counter_text = Text(font, 'FPS')
        self.fps_counter = self.scene.add_text(self.fps_counter_text, props)
        self.transform(self.fps_counter, self.w * 0.85, 0)

        # clock
        self.clock_text = Text(font, '--:--')
        self.clock = self.scene.add_text(self.clock_text, props)
        self.transform(self.clock, self.w * 0.5, 0)

        # avatar
        avatar_res, avatar = player_data['avatar_res'], player_data['avatar']
        self.avatar = Avatar(self.scene, avatar_res, avatar)
        self.transform(self.avatar.obj, 0, 0)

        # healthbar
        self.health_bar = HealthBar(self.scene, resource['health_bar'])
        self.transform(self.health_bar.bg_obj, 0, avatar_res.data['width'] + 5)
        self.transform(self.health_bar.fg_obj, 0, avatar_res.data['width'] + 5)
예제 #13
0
    def update(self, dt):
        """Update the character.

        This method computes character's game logic as a function of time.

        :param dt: Time delta from last update.
        :type dt: float
        """
        self[Movable].update(dt)
        x, y = self[Movable].position

        rot, scale = self.TRANSFORMS[self.actor_type]
        self.obj.position = to_scene(x, y)
        self.obj.rotation.rotatev(Vec(0, 1, 0), rot + -self.heading)
        self.obj.scale = Vec(scale, scale, scale)

        self.orientate()

        # play animation
        if self.current_anim:
            self.current_anim.play(dt)
예제 #14
0
    def __init__(self, resource, scene, parameters):
        """Constructor.

        :param resource: Resource containing the object data.
        :type resource: :class:`resource_manager.Resource`

        :param scene: Scene to add the health bar to.
        :type scene: :class:`renderlib.scene.Scene`

        :param parameters: Parameters for the object.
        :type parameters: :class:`dict`
        """
        super().__init__()

        mesh = resource['model']
        texture = Texture.from_image(
            resource['texture'],
            Texture.TextureType.texture_2d)

        material = Material()
        material.texture = texture
        material.receive_light = True

        props = MeshProps()
        props.material = material
        props.cast_shadows = True
        props.receive_shadows = True

        self.obj = scene.add_mesh(mesh, props)
        self.obj.position = to_scene(*parameters['pos'])
        # FIXME: an added offset to match the level displacement
        self.obj.position.z += 1

        if 'rotation' in parameters:
            self.obj.rotation.rotatev(
                Y_AXIS, parameters['rotation'] * pi / 180)

        # FIXME: hardcoded bounding box
        self._position = parameters['pos']
        self._bounding_box = Vec(-0.5, 0.5, -0.5), Vec(0.5, 1.5, 0.5)
예제 #15
0
def intersect(pos, ray, bb):
    """Check if the ray starting from position pos intersects the bounding box.

    :param pos: The origin of the ray
    :type pos: :class:`matlib.Vec`

    :param ray: The ray
    :type ray: :class:`matlib.Vec`

    :param bb: The entity bounding box
    :type bb: :class:`tuple`
    """
    # FIXME: please generalize me
    l, m = bb
    # front plane
    p = intersection(pos, ray, Vec(0, 0, -1), m.z)
    if l.x <= p.x <= m.x and l.y <= p.y <= m.y:
        return True
    # left plane
    p = intersection(pos, ray, Vec(1, 0, 0), l.x)
    if l.y <= p.y <= m.y and l.z <= p.z <= m.z:
        return True
    # right plane
    p = intersection(pos, ray, Vec(-1, 0, 0), m.x)
    if l.y <= p.y <= m.y and l.z <= p.z <= m.z:
        return True
    # top plane
    p = intersection(pos, ray, Vec(0, -1, 0), m.y)
    if l.x <= p.x <= m.x and l.z <= p.z <= m.z:
        return True
    # back plane
    p = intersection(pos, ray, Vec(1, 0, 0), l.z)
    if l.x <= p.x <= m.x and l.y <= p.y <= m.y:
        return True

    return False
예제 #16
0
    def update(self, dt):
        """Update the building template.

        This method just applies the current position of the entity to the
        renderable transform.

        :param dt: Time delta from last update.
        :type dt: float
        """
        x, y = self.pos

        m_x, m_y = to_matrix(x, y, self.scale_factor)
        if not in_matrix(self.matrix, m_x, m_y) or not self.matrix[m_y][m_x]:
            self.props.material.color = self.NON_BUILDABLE_COLOR
        else:
            self.props.material.color = self.BUILDABLE_COLOR

        self.obj.position = to_scene(x, y)
        self.obj.scale = Vec(1.05, 1.05, 1.05)
예제 #17
0
class BuildingTemplate(Entity):
    """Game entity which represents a building template."""

    BUILDABLE_COLOR = Vec(0.0, 0.8, 0.4, 1)

    NON_BUILDABLE_COLOR = Vec(1, 0.0, 0.2, 1)

    def __init__(self, resource, scene, matrix, scale_factor):
        """Constructor.

        :param resource: The character resource
        :type resource: :class:`loaders.Resource`

        :type scene: :class:`renderlib.scene.Scene`
        :param scene: Scene to add the health bar to.

        :param matrix: The walkable matrix
        :type matrix: :class:`loaders.Resource`

        :param scale_factor: The scale factor of the grid.
        :type scale_factor: int
        """
        super().__init__()

        self.pos = (0, 0)
        self.matrix = matrix
        self.scale_factor = scale_factor

        mesh = resource['model_complete']

        # create material
        material = Material()
        material.color = self.BUILDABLE_COLOR

        # create render props container
        self.props = MeshProps()
        self.props.material = material

        # create components
        self.obj = scene.add_mesh(mesh, self.props)

    def remove(self):
        """Removes itself from the scene.
        """
        LOG.debug('Remove building template {}'.format(self.e_id))
        self.obj.remove()

    def update(self, dt):
        """Update the building template.

        This method just applies the current position of the entity to the
        renderable transform.

        :param dt: Time delta from last update.
        :type dt: float
        """
        x, y = self.pos

        m_x, m_y = to_matrix(x, y, self.scale_factor)
        if not in_matrix(self.matrix, m_x, m_y) or not self.matrix[m_y][m_x]:
            self.props.material.color = self.NON_BUILDABLE_COLOR
        else:
            self.props.material.color = self.BUILDABLE_COLOR

        self.obj.position = to_scene(x, y)
        self.obj.scale = Vec(1.05, 1.05, 1.05)
예제 #18
0
def to_world(x, y, z):
    """Convert scene coordinates to world coordinates."""
    return Vec(x, z, 0)
예제 #19
0
def to_scene(x, y):
    """Convert world coordinates to scene coordinates."""
    return Vec(x, 0, y)
예제 #20
0
 def bounding_box(self):
     l, m = self._bounding_box
     pos = self.position
     # FIXME: this offset here is due to the calculation of the walkable
     # matrix that adds one more walkable line on top of the scenario.
     return l + Vec(pos[0], 0, pos[1] + 1), m + Vec(pos[0], 0, pos[1] + 1)
예제 #21
0
from game.entities.entity import Entity
from game.events import EntityPick
from game.events import ObjectSpawn
from math import pi
from matlib.vec import Vec
from network.message import Message
from network.message import MessageField as MF
from network.message import MessageType
from renderlib.material import Material
from renderlib.mesh import MeshProps
from renderlib.texture import Texture
from utils import to_scene
import logging


Y_AXIS = Vec(0, 1, 0)


LOG = logging.getLogger(__name__)


@unique
class ObjectType(IntEnum):
    """Enumeration of the possible static objects"""
    coffee = 0


class MapObject(Entity):
    """Static object on the map."""

    def __init__(self, resource, scene, parameters):