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]))
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
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()
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
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)
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