예제 #1
0
    def move_camera_relative(self, forward, up, right, pitch, yaw):
        if (forward, up, right, pitch, yaw) == (0, 0, 0, 0, 0):
            if not self._mouse_lock and self._mouse_moved:
                self._mouse_moved = False
                self._change_box_location()
            return
        self._camera[0] += self._camera_move_speed * (
            cos(self._camera[4]) * right + sin(self._camera[4]) * forward)
        self._camera[1] += self._camera_move_speed * up
        self._camera[2] += self._camera_move_speed * (
            sin(self._camera[4]) * right - cos(self._camera[4]) * forward)

        self._camera[3] += self._camera_rotate_speed * pitch
        if not -90 <= self._camera[3] <= 90:
            self._camera[3] = max(min(self._camera[3], 90), -90)
        self._camera[4] += self._camera_rotate_speed * yaw
        self._transformation_matrix = None
        self._render_world.camera = self._camera
        self._change_box_location()
        wx.PostEvent(
            self,
            CameraMoveEvent(x=self._camera[0],
                            y=self._camera[1],
                            z=self._camera[2],
                            rx=self._camera[3],
                            ry=self._camera[4]))
예제 #2
0
    def transformation_matrix(self) -> numpy.ndarray:
        # camera translation
        if self._transformation_matrix is None:
            transformation_matrix = numpy.eye(4, dtype=numpy.float32)
            transformation_matrix[3, :3] = numpy.array(self._camera[:3]) * -1

            c = cos(self._camera[4])
            s = sin(self._camera[4])

            y_rot = numpy.array(
                [
                    [c, 0, -s, 0],
                    [0, 1, 0, 0],
                    [s, 0, c, 0],
                    [0, 0, 0, 1]
                ],
                dtype=numpy.float32
            )

            transformation_matrix = numpy.matmul(transformation_matrix, y_rot)

            # rotations
            c = cos(self._camera[3])
            s = sin(self._camera[3])

            x_rot = numpy.array(
                [
                    [1, 0, 0, 0],
                    [0, c, s, 0],
                    [0, -s, c, 0],
                    [0, 0, 0, 1]
                ],
                dtype=numpy.float32
            )

            transformation_matrix = numpy.matmul(transformation_matrix, x_rot)

            # camera projection
            fovy, aspect, z_near, z_far = self._projection
            fovy = math.radians(fovy)
            f = 1 / math.tan(fovy / 2)
            projection = numpy.array(
                [
                    [f/aspect, 0, 0, 0],
                    [0, f, 0, 0],
                    [0, 0, (z_far+z_near)/(z_near-z_far), -1],
                    [0, 0, (2*z_far*z_near)/(z_near-z_far), 0]
                ],
                dtype=numpy.float32
            )

            self._transformation_matrix = numpy.matmul(transformation_matrix, projection)

        return self._transformation_matrix
예제 #3
0
    def move_camera_relative(self, forward, up, right, pitch, yaw):
        if (forward, up, right, pitch, yaw) == (0, 0, 0, 0, 0):
            return
        self._camera[0] += self._camera_move_speed * (
            cos(self._camera[4]) * right + sin(self._camera[4]) * forward)
        self._camera[1] += self._camera_move_speed * up
        self._camera[2] += self._camera_move_speed * (
            sin(self._camera[4]) * right - cos(self._camera[4]) * forward)

        self._camera[3] += self._camera_rotate_speed * pitch
        if not -90 <= self._camera[3] <= 90:
            self._camera[3] = max(min(self._camera[3], 90), -90)
        self._camera[4] += self._camera_rotate_speed * yaw
        self._collision_locations_cache = None
        self._transformation_matrix = None
        self._render_world.camera = self._camera
        self._change_box_location()
예제 #4
0
    def _collision_locations(self):
        if self._collision_locations_cache is None:
            dx = sin(self._camera[4]) * cos(self._camera[3])
            dy = -sin(self._camera[3])
            dz = -cos(self._camera[4]) * cos(self._camera[3])
            look_vector = numpy.array([dx, dy, dz])
            look_vector[abs(look_vector) < 0.000001] = 0.000001
            dx, dy, dz = look_vector
            max_distance = 30

            vectors = numpy.array([
                look_vector / abs(dx), look_vector / abs(dy),
                look_vector / abs(dz)
            ])
            offsets = -numpy.eye(3)

            locations = set()
            start: numpy.ndarray = numpy.array(self._camera[:3],
                                               numpy.float32) % 1

            for axis in range(3):
                location: numpy.ndarray = start.copy()
                vector = vectors[axis]
                offset = offsets[axis]
                if vector[axis] > 0:
                    location = location + vector * (1 - location[axis])
                else:
                    location = location + vector * location[axis]
                while numpy.all(abs(location) < max_distance):
                    locations.add(
                        tuple(numpy.floor(location).astype(numpy.int)))
                    locations.add(
                        tuple(
                            numpy.floor(location + offset).astype(numpy.int)))
                    location += vector
            self._collision_locations_cache = numpy.array(
                sorted(list(locations),
                       key=lambda loc: sum(abs(loc_)
                                           for loc_ in loc))) + numpy.floor(
                                               self._camera[:3]).astype(
                                                   numpy.int)

        return self._collision_locations_cache
예제 #5
0
    def move_camera_relative(self, forward, up, right, pitch, yaw):
        """Move the camera relative to its current location."""
        if not any((forward, up, right, pitch, yaw)):
            if not self._mouse_lock and self._mouse_moved:
                self._mouse_moved = False
                self._selection_moved = True
            return
        x, y, z = self.camera_location
        rx, ry = self.camera_rotation
        x += self._camera_move_speed * (cos(ry) * right + sin(ry) * forward)
        y += self._camera_move_speed * up
        z += self._camera_move_speed * (sin(ry) * right - cos(ry) * forward)

        rx += self._camera_rotate_speed * pitch
        if not -90 <= rx <= 90:
            rx = max(min(rx, 90), -90)
        ry += self._camera_rotate_speed * yaw
        self.camera_location = (x, y, z)
        self.camera_rotation = (rx, ry)
예제 #6
0
 def _look_vector(self) -> numpy.ndarray:
     """
     The x,y,z vector for the direction the camera is facing
     :return: (x, y, z) numpy float array ranging from -1 to 1
     """
     look_vector = numpy.array([0, 0, -1, 0])
     if not self._mouse_lock:
         screen_x, screen_y = numpy.array(self.GetSize(), numpy.int) / 2
         screen_dx = atan(self.aspect_ratio * tan(self.fov / 2) * self._mouse_delta_x / screen_x)
         screen_dy = atan(cos(screen_dx) * tan(self.fov / 2) * self._mouse_delta_y / screen_y)
         look_vector = numpy.matmul(self.rotation_matrix(screen_dy, screen_dx), look_vector)
     look_vector = numpy.matmul(self.rotation_matrix(*self._camera[3:5]), look_vector)[:3]
     look_vector[abs(look_vector) < 0.000001] = 0.000001
     return look_vector