Beispiel #1
0
    def generate_city(
        self,
        buildingShader,
        building_textures,
        building_shaders,
        lanternShader,
        lantern_textures,
        lantern_shaders,
    ):
        """Generate a cityscape

        Arguments:
            buildingShader {shader} -- Default shader to use for buildings
            building_textures {dict} -- Texture info for buildings
            building_shaders {dict} -- Shader material info for buildings
            lanternShader {shader} -- Default shaders to use for lanterns
            lantern_textures {dict} -- Texture info for lanterns
            lantern_shaders {dict} -- Shader material info for lanterns
        """
        # Load building models
        models = [
            load_obj("models/building1.obj"),
            load_obj("models/building2.obj")
        ]

        # Load lamp model
        lamp_model = load_obj("models/lantern.obj")

        # Create buildings and lampposts at each 'city block'
        for xx in range(-300, 300, 200):
            for zz in range(-300, 300, 200):
                # This position marks the center of each concrete block
                position = gltypes.vec3(xx, 0, zz)

                # Building positions - four in the centre of the block
                for bpos in [(-45, -45), (-45, 45), (45, -45), (45, 45)]:
                    building_pos = position + gltypes.vec3(bpos[0], 0, bpos[1])
                    self.add_model(
                        random.choice(models),
                        buildingShader,
                        building_pos,
                        building_textures,
                        building_shaders,
                    )

                # Lantern positions - eight around the edge of the block
                for lpos in [
                    (-70, -70),
                    (-70, 0),
                    (-70, 70),
                    (70, -70),
                    (70, 0),
                    (70, 70),
                    (0, -70),
                    (0, 70),
                ]:
                    lantern_pos = position + gltypes.vec3(lpos[0], 0, lpos[1])
                    self.add_model(
                        lamp_model,
                        lanternShader,
                        lantern_pos,
                        lantern_textures,
                        lantern_shaders,
                    )
Beispiel #2
0
class Object:
    """Basic object class
    This has some basic things that all objects can derive from

    Most useful functionality will be in the ObjModel class
    """

    position = gltypes.vec3(0, 0, 0)
    shader = None

    material_textures = {}
    material_shaders = {}

    def ui(self):
        """Super lame UI for adjusting the position of the object
        """
        if True:
            return

        if imgui.tree_node("Object", imgui.TREE_NODE_DEFAULT_OPEN):
            _, x = imgui.slider_float("X", self.position[0], -10, 10)
            _, y = imgui.slider_float("Y", self.position[1], -10, 10)
            _, z = imgui.slider_float("Z", self.position[2], -10, 10)
            self.position = gltypes.vec3(x, y, z)
            imgui.tree_pop()

    def bindTextures(self, shader, material):
        """Bind all relevant textures for a material to the given shader

        Arguments:
            shader {int} -- Shader
            material {str} -- Material name to assign textures to
        """
        if material not in self.material_textures:
            return
        tex_data = self.material_textures[material]

        if isinstance(tex_data, dict):
            # Dictionary of textures, unpack
            if "diffuse" in tex_data:
                self.bindDiffuseTexture(shader, tex_data["diffuse"])

            if "specular" in tex_data:
                self.bindSpecularTexture(shader, tex_data["specular"])
            else:
                self.bindSpecularTexture(shader, -1)
        else:
            # Single texture, treat as diffuse only
            self.bindDiffuseTexture(shader, tex_data)

    def bindDiffuseTexture(self, shader, texture):
        """Bind a single diffuse texture to a shader

        Arguments:
            shader {int} -- Shader
            texture {int} -- Texture ID to assign
        """
        shaders.setUniform(shader, "diffuseTexture", TEX_DIFFUSE)
        shaders.bindTexture(TEX_DIFFUSE, texture, GL_TEXTURE_2D)

    def bindSpecularTexture(self, shader, texture):
        """Bind a single specular texture to a shader

        Arguments:
            shader {int} -- Shader
            texture {int} -- Texture ID to assign
        """
        shaders.setUniform(shader, "specularTexture", TEX_SPECULAR)
        shaders.bindTexture(TEX_SPECULAR, texture, GL_TEXTURE_2D)

    def applyShaderUniforms(self, shader, transforms):
        """Utility function to assign a list of uniforms to a shader

        Arguments:
            shader {int} -- Shader
            transforms {dict} -- Name, value pairs of uniforms to assign
        """
        for name, value in transforms.items():
            shaders.setUniform(shader, name, value)
Beispiel #3
0
 def getWorldToViewMatrix(self):
     return gltypes.make_lookAt(self.position, gltypes.vec3(0, 0, 0),
                                self.up)
Beispiel #4
0
 def __init__(self, target=gltypes.vec3(0, 0, 0)):
     self.target = target
Beispiel #5
0
class FreeCamera(Camera):
    """More complicated freeform camera mode

    Controlled by WASD for movement and arrow keys for angle control
    """

    yaw = 10
    pitch = -30

    rotate_speed = 60
    pitch_speed = 60
    move_speed = 50

    position = gltypes.vec3(50, 10, 0)

    def __init__(self, target=gltypes.vec3(0, 0, 0)):
        self.target = target

    def update(self, dt, keys):
        """Camera update function

        Arrow keys for angular rotation
        WASD for freeform movement

        Arguments:
            dt {float} -- Time, in seconds, since the last update
            keys {dict} -- Mapping of keys currently pressed
        """
        forwardSpeed = 0
        strafeSpeed = 0
        yawSpeed = 0
        pitchSpeed = 0

        # Handle angular movement
        if keys["UP"]:
            pitchSpeed -= self.pitch_speed
        if keys["DOWN"]:
            pitchSpeed += self.pitch_speed
        if keys["RIGHT"]:
            yawSpeed += self.rotate_speed
        if keys["LEFT"]:
            yawSpeed -= self.rotate_speed

        # Handle positional movement
        if keys["W"]:
            forwardSpeed += self.move_speed
        if keys["S"]:
            forwardSpeed -= self.move_speed
        if keys["D"]:
            strafeSpeed -= self.move_speed
        if keys["A"]:
            strafeSpeed += self.move_speed

        # Rotate
        self.yaw += yawSpeed * dt
        self.pitch = min(60, max(-60, self.pitch + pitchSpeed * dt))

        # Generate rotation
        self.cameraRotation = Mat3(
            gltypes.make_rotation_y(math.radians(self.yaw))) * Mat3(
                gltypes.make_rotation_x(math.radians(self.pitch)))

        # Movement
        self.position += np.array(
            self.cameraRotation * [0, 0, 1]) * forwardSpeed * dt
        self.position += np.array(
            self.cameraRotation * [1, 0, 0]) * strafeSpeed * dt

    def ui(self):
        """No UI for this camera because I'm lazy
        See the above function for controls
        """
        pass

    def getWorldToViewMatrix(self):
        """Generate a worldToViewTransform matrix
        This is a simple looking in the direction of the camera
        """
        return self.make_lookFrom(self.cameraRotation * [0, 0, 1])