def mouseMovimiento(self, xoffset, yoffset, detector=True): # Valores del mouse xoffset = xoffset * self.sensibilidad yoffset = yoffset * self.sensibilidad self.dataX = self.dataX + xoffset self.dataY = self.dataY + yoffset # Si detecta un mouse que tome los siguientes datos if detector: # Si el dato es mayor o menor al dato en y que tome los datos if (self.dataY > 45.0): self.dataY = 45.0 if (self.dataY < -45.0): self.dataY = -45.0 # Vector para la camara frontal front = Vector3([0.0, 0.0, 0.0]) # Encontramos cada uno de los datos de la camara front tanto en x, y e z front.x = cos(radians(self.dataX)) * cos(radians(self.dataY)) front.y = sin(radians(self.dataY)) front.z = sin(radians(self.dataX)) * cos(radians(self.dataY)) # Normalizamos el vector, para obtener datos cercanos # debug ---> print(self.frontal) self.frontal = vector.normalise(front) # debug ---> print(self.derecha) # debug ---> print(self.arriba) self.derecha = vector.normalise( vector3.cross(self.frontal, Vector3([0.0, 1.0, 0.0]))) self.arriba = vector.normalise( vector3.cross(self.derecha, self.frontal))
def point_closest_point_on_line( point, line ): """Calculates the point on the line that is closest to the specified point. :param numpy.array point: The point to check with. :param numpy.array line: The line to check against. :rtype: numpy.array :return: The closest point on the line to the point. """ """ rl = va->b (relative line) rp = va->p (relative point) u' = u / |u| (normalise) cp = a + (u' * (u'.v)) where: a = line start b = line end p = point cp = closest point """ rl = line[ 1 ] - line[ 0 ] rp = point - line[ 0 ] vector.normalise( rl ) dot = vector.dot( rl, rp ) return line[ 0 ] + (rl * dot)
def look_at(self, position, target, world_up): # 1.Position = known # 2.Calculate cameraDirection zaxis = vector.normalise(position - target) # 3.Get positive right axis vector xaxis = vector.normalise( vector3.cross(vector.normalise(world_up), zaxis)) # 4.Calculate the camera up vector yaxis = vector3.cross(zaxis, xaxis) # create translation and rotation matrix translation = Matrix44.identity() translation[3][0] = -position.x translation[3][1] = -position.y translation[3][2] = -position.z rotation = Matrix44.identity() rotation[0][0] = xaxis[0] rotation[1][0] = xaxis[1] rotation[2][0] = xaxis[2] rotation[0][1] = yaxis[0] rotation[1][1] = yaxis[1] rotation[2][1] = yaxis[2] rotation[0][2] = zaxis[0] rotation[1][2] = zaxis[1] rotation[2][2] = zaxis[2] return translation * rotation
def move_camera(self, direction): current_frame = time.get_ticks() delta_time = current_frame - self.last_frame camera_speed = delta_time / 20000 if direction == "UP": self.camera_position[1] += camera_speed self.last_cam_y = self.camera_position[1] if direction == "DOWN": self.camera_position[1] -= camera_speed self.last_cam_y = self.camera_position[1] if direction == "FORWARD": self.camera_position += camera_speed * self.camera_front if direction == "BACK": self.camera_position -= camera_speed * self.camera_front if direction == "LEFT": self.camera_position -= vector.normalise( vector3.cross(np.array(self.camera_front, dtype=np.float32), np.array([0., 1., 0.], dtype=np.float32))) * camera_speed if direction == "RIGHT": self.camera_position += vector.normalise( vector3.cross(np.array(self.camera_front, dtype=np.float32), np.array([0., 1., 0.], dtype=np.float32))) * camera_speed self.camera_position[1] = self.last_cam_y
def _gl_look_at(self, pos, target, up) -> numpy.ndarray: """The standard lookAt method. Args: pos: current position target: target position to look at up: direction up Returns: numpy.ndarray: The matrix """ z = vector.normalise(pos - target) x = vector.normalise(vector3.cross(vector.normalise(up), z)) y = vector3.cross(z, x) translate = matrix44.create_identity() translate[3][0] = -pos.x translate[3][1] = -pos.y translate[3][2] = -pos.z rotate = matrix44.create_identity() rotate[0][0] = x[0] # -- X rotate[1][0] = x[1] rotate[2][0] = x[2] rotate[0][1] = y[0] # -- Y rotate[1][1] = y[1] rotate[2][1] = y[2] rotate[0][2] = z[0] # -- Z rotate[1][2] = z[1] rotate[2][2] = z[2] return matrix44.multiply(translate, rotate)
def update_camera_vectors(self): front = Vector3([0.0, 0.0, 0.0]) front.x = cos(radians(self.yaw)) * cos(radians(self.pitch)) front.y = sin(radians(self.pitch)) front.z = sin(radians(self.yaw)) * cos(radians(self.pitch)) self.camera_front = vector.normalise(front) self.camera_right = vector.normalise(vector3.cross(self.camera_front, Vector3([0.0, 1.0, 0.0]))) self.camera_up = vector.normalise(vector3.cross(self.camera_right, self.camera_front))
def _update_yaw_and_pitch(self) -> None: """Updates the camera vectors based on the current yaw and pitch""" front = Vector3([0.0, 0.0, 0.0]) front.x = cos(radians(self.yaw)) * cos(radians(self.pitch)) front.y = sin(radians(self.pitch)) front.z = sin(radians(self.yaw)) * cos(radians(self.pitch)) self.dir = vector.normalise(front) self.right = vector.normalise(vector3.cross(self.dir, self._up)) self.up = vector.normalise(vector3.cross(self.right, self.dir))
def update_camera_vectors(self): front = glm.vec3(0.0, 0.0, 0.0) front.x = cos(radians(self.jaw)) * cos(radians(self.pitch)) front.y = sin(radians(self.pitch)) front.z = sin(radians(self.jaw)) * cos(radians(self.pitch)) self.camera_front = vector.normalise(front) self.camera_right = vector.normalise( vector3.cross(self.camera_front, glm.vec3(0.0, 1.0, 0.0))) self.camera_up = vector.normalise( vector3.cross(self.camera_right, self.camera_front))
def set_position(self, camera_position_index: CameraPose): self.move_vector = Vector3([0, 0, 0]) self.camera_up = Vector3([0.0, 1.0, 0.0]) self.camera_pos = CAMERA_POSE_POSITION[camera_position_index] self.camera_pos = self.base + self.camera_pos self.camera_front = Vector3( vector.normalise(self.base - self.camera_pos)) self.set_yaw_pitch_from_front(not camera_position_index == 0) self.camera_right = Vector3( vector.normalise(np.cross(self.camera_up, self.camera_front))) self.yaw_offset = 0.0
def lookAtMatrix( camera, target, up ): forward = vector.normalise(target - camera) side = vector.normalise( vector.cross( forward, up ) ) #shifts 'up' to the camera's up up = vector.cross( side, forward ) matrix2 = array( [[ side[0], up[0], -forward[0], 0.0 ], [ side[1], up[1], -forward[1], 0.0 ], [ side[2], up[2], -forward[2], 0.0 ], [ 0.0, 0.0, 0.0, 1.0 ]], dtype = float32) return array(mat4.multiply( mat4.create_from_translation( -camera ), matrix2 ), dtype=float32)
def AdjustView(self, eyePosition, targetPosition, upVector): eye = Vector3(eyePosition) target = Vector3(targetPosition) up = Vector3(upVector) zaxis = vector.normalise(eye - target) # The "forward" vector. xaxis = vector.normalise(vector3.cross(up, zaxis)) # The "right" vector. yaxis = vector3.cross(zaxis, xaxis) # The "up" vector. # Create a 4x4 view matrix from the right, up, forward and eye position vectors self.view.r1 = [xaxis[0], yaxis[0], zaxis[0], 0] self.view.r2 = [xaxis[1], yaxis[1], zaxis[1], 0] self.view.r3 = [xaxis[2], yaxis[2], zaxis[2], 0] self.view.r4 =[-vector3.dot( xaxis, eye ), -vector3.dot( yaxis, eye ), -vector3.dot( zaxis, eye ), 1 ] return self.view
def test_spherical( self ): angle_vector = numpy.array([ 1.0, 0.0, 1.0 ]) angle_vector = vector.normalise( angle_vector ) normals = numpy.array([ [ 1.0, 0.0, 0.0 ], [ 0.0, 0.0, 1.0 ], [ angle_vector[ 0 ], angle_vector[ 1 ], angle_vector[ 2 ] ] ]) uv = Spherical( scale = (2.0, 1.0), offset = (0.0, 0.0) ) # ignored anyway vertices = [] texture_coords = uv.generate_coordinates( vertices, normals ) self.assertEqual( texture_coords[ 0 ][ 1 ], 0.5, "UV coordinates incorrect" )
def create_ray( start, direction ): return numpy.array( [ start, vector.normalise( direction ) ] )
def point_camera(self): pos = mouse.get_rel() x_offset = pos[0] y_offset = pos[1] x_offset *= self.sensitivity y_offset *= self.sensitivity self.yaw += x_offset * self.sensitivity self.pitch += -y_offset * self.sensitivity if self.pitch > 89.0: self.pitch = 89.0 if self.pitch < -89.0: self.pitch = -89.0 direction_x = cos(radians(self.pitch)) * cos(radians(self.yaw)) direction_y = sin(radians(self.pitch)) direction_z = cos(radians(self.pitch)) * sin(radians(self.yaw)) self.camera_front = vector.normalise( np.array([direction_x, direction_y, direction_z], dtype=np.float32)) self.camera_front = Vector3(self.camera_front) view_matrix = self.look_at(self.camera_position, self.camera_position + self.camera_front) glUniformMatrix4fv(self.view_loc, 1, GL_FALSE, view_matrix)
def normalise( quat ): """Ensure a quaternion is unit length (length ~= 1.0). The quaternion is **not** changed in place. :param numpy.array quat: The quaternion to normalise. :rtype: numpy.array :return: The normalised quaternion(s). """ return vector.normalise( quat )
def create_from_line( line ): """ Converts a line or line segment to a ray. """ # direction = vend - vstart return numpy.array( [ line[ 0 ], vector.normalise( line[ 1 ] - line[ 0 ] ) ] )
def track_update_camera_vectors(self): pos = Vector3([0.0, 0.0, 0.0]) pos.x = self.distance * cos(radians(self.yaw)) * cos( radians(self.pitch)) pos.y = self.distance * sin(radians(self.pitch)) pos.z = self.distance * sin(radians(self.yaw)) * cos( radians(self.pitch)) self.camera_pos = pos self.camera_right = vector.normalise( vector3.cross(self.world_centre, self.camera_up))
def test_create_from_position(self): position = np.array([1.0, 0.0, 0.0]) normal = np.array([0.0, 3.0, 0.0]) result = plane.create_from_position(position, normal) self.assertTrue(np.allclose(result, [0., 1., 0., 0.])) p0 = position + [1., 0., 0.] p = position n = vector.normalise(normal) coplanar = p - p0 self.assertEqual(np.sum(n * coplanar), 0.)
def single_vector(): vec = numpy.array( [ 1.0, 1.0, 1.0 ] ) result = vector.normalise( vec ) length = numpy.array( [ math.sqrt( numpy.sum( vec ** 2 ) ) ] ) expected = vec / length self.assertTrue( numpy.array_equal( result, expected ), "Vector normalise not unit length" )
def gravitational_force_from(self, other) -> Vector3: """ :math:`\vec{F} = -G * (m_1 * m_2)/(|r|^2) * \vec{r}` """ if self.intersecting and other.intersecting: return Vector3([0.0, 0.0, 0.0]) else: return -( WorldSettings.gravity_constant * self.mass * other.mass / self.squared_distance_to(other) ) * vector.normalise(self.vector_to(other))
def look_at(position: Vector3, target: Vector3, world_up: Vector3) -> Matrix44: z_axis: Vector3 = vector.normalise(position - target) x_axis: Vector3 = vector.normalise( vector3.cross(vector.normalise(world_up), z_axis)) y_axis: Vector3 = vector3.cross(z_axis, x_axis) translation: Matrix44 = Matrix44.identity() translation[3][0] = -position.x translation[3][1] = -position.y translation[3][2] = -position.z rotation: Matrix44 = Matrix44.identity() rotation[0][0] = x_axis[0] rotation[1][0] = x_axis[1] rotation[2][0] = x_axis[2] rotation[0][1] = y_axis[0] rotation[1][1] = y_axis[1] rotation[2][1] = y_axis[2] rotation[0][2] = z_axis[0] rotation[1][2] = z_axis[1] rotation[2][2] = z_axis[2] return rotation * translation
def lookAtMe(self, position, target, world_up): # Calculamos la direccion de la camara en z zaxis = vector.normalise(position - target) # Calculamos la direccion de la camara en x xaxis = vector.normalise( vector3.cross(vector.normalise(world_up), zaxis)) # Calculamos la direccion de la camara en y yaxis = vector3.cross(zaxis, xaxis) # Creamos la matriz de transaltion y de rotation translation = Matrix44.identity() rotation = Matrix44.identity() ''' matrix identidad = [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ] ''' # Dentro de la matriz ingresamos cada uno de los valores translation[3][0] = -position.x translation[3][1] = -position.y translation[3][2] = -position.z # Añadimos a la matriz los valores rotation[0][0] = xaxis[0] rotation[1][0] = xaxis[1] rotation[2][0] = xaxis[2] rotation[0][1] = yaxis[0] rotation[1][1] = yaxis[1] rotation[2][1] = yaxis[2] rotation[0][2] = zaxis[0] rotation[1][2] = zaxis[1] rotation[2][2] = zaxis[2] return translation * rotation
def update_camera_vectors(self): if not self.rotate_around_base: front: Vector3 = Vector3([0.0, 0.0, 0.0]) front.x = cos(radians(self.yaw + self.yaw_offset)) * cos( radians(self.pitch)) front.y = sin(radians(self.pitch)) front.z = sin(radians(self.yaw + self.yaw_offset)) * cos( radians(self.pitch)) self.camera_front = vector.normalize(front) self.camera_right = vector.normalize( vector3.cross(self.camera_front, Vector3([0.0, 1.0, 0.0]))) self.camera_up = vector.normalise( vector3.cross(self.camera_right, self.camera_front)) self.camera_pos = self.camera_pos + self.camera_right * self.move_vector.x * self.move_speed self.camera_pos = self.camera_pos + self.camera_up * self.move_vector.y * self.move_speed self.camera_pos = self.camera_pos + self.camera_front * self.move_vector.z * self.move_speed else: self.yaw_offset += self.rotation_speed front: Vector3 = Vector3([0.0, 0.0, 0.0]) front.x = cos(radians(self.yaw + self.yaw_offset)) * cos( radians(self.pitch)) front.y = sin(radians(self.pitch)) front.z = sin(radians(self.yaw + self.yaw_offset)) * cos( radians(self.pitch)) front_offset = vector.normalize(front) - self.camera_front self.camera_pos -= front_offset * vector.length(self.camera_pos - self.base) self.camera_front = vector.normalize(front) self.camera_right = vector.normalize( vector3.cross(self.camera_front, Vector3([0.0, 1.0, 0.0]))) self.camera_up = vector.normalise( vector3.cross(self.camera_right, self.camera_front)) self.camera_pos = self.camera_pos + self.camera_right * self.move_vector.x * self.move_speed self.camera_pos = self.camera_pos + self.camera_up * self.move_vector.y * self.move_speed self.camera_pos = self.camera_pos + self.camera_front * self.move_vector.z * self.move_speed
def __init__( self, position, forward, up, size = (1.0, 1.0, 1.0) ): """ Creates a Box with the bottom left corner at position with the normal being the depth and up the height @param position: The 3d vector representing the centre of the box. @param forward: The forward vector of the box. Must be co-planar with the up vector. @param up: The up vector of the box. Must be co-planar with the forward vector. will be normalised during construction. @param size: The size of the box where X is right, Y is forward, Z is up @raise ValueError: raised if the up vector is not co-planar """ super( BoxWrap, self ).__init__() self.position = numpy.array( position, dtype = float ) self.size = size self.forward = numpy.array( forward, dtype = float ) self.up = numpy.array( up, dtype = float ) vector.normalise( self.forward ) vector.normalise( self.up ) if numpy.dot( self.forward, self.up ) != 0.0: raise ValueError( "Vectors are not co-planar" )
def look_at(self, position, target, up=Vector3([0., 1., 0.])): direction = vector.normalise(position - target) direction = np.array(direction, dtype=np.float32) up = np.array(up, dtype=np.float32) camera_right = vector.normalise(vector3.cross(up, direction)) camera_up = vector.normalise(vector3.cross(direction, camera_right)) translation = Matrix44.identity() translation[3][0] = -position[0] translation[3][1] = -position[1] translation[3][2] = -position[2] rotation = Matrix44.identity() rotation[0][0] = camera_right[0] rotation[1][0] = camera_right[1] rotation[2][0] = camera_right[2] rotation[0][1] = camera_up[0] rotation[1][1] = camera_up[1] rotation[2][1] = camera_up[2] rotation[0][2] = direction[0] rotation[1][2] = direction[1] rotation[2][2] = direction[2] return np.array(translation * rotation, dtype=np.float32)
def __init__(self, position, forward, up, size=(1.0, 1.0, 1.0)): """ Creates a Box with the bottom left corner at position with the normal being the depth and up the height @param position: The 3d vector representing the centre of the box. @param forward: The forward vector of the box. Must be co-planar with the up vector. @param up: The up vector of the box. Must be co-planar with the forward vector. will be normalised during construction. @param size: The size of the box where X is right, Y is forward, Z is up @raise ValueError: raised if the up vector is not co-planar """ super(BoxWrap, self).__init__() self.position = numpy.array(position, dtype=float) self.size = size self.forward = numpy.array(forward, dtype=float) self.up = numpy.array(up, dtype=float) vector.normalise(self.forward) vector.normalise(self.up) if numpy.dot(self.forward, self.up) != 0.0: raise ValueError("Vectors are not co-planar")
def batch_normalise(): vec = numpy.array([ 1.0, 1.0, 1.0 ] ) batch = numpy.tile( vec, (3, 1) ) result = vector.normalise( batch ) lengths = numpy.array( [ math.sqrt( numpy.sum( vec ** 2 ) ) ] ) lengths = numpy.tile( lengths, (3,1) ) expected = batch / lengths self.assertTrue( numpy.array_equal( result, expected ), "Batch vector normalise not unit length" )
def create_from_position( position, normal ): """Creates a plane at position with the normal being above the plane and up being the rotation of the plane. :param numpy.array position: The position of the plane. :param numpy.array normal: The normal of the plane. Will be normalised during construction. :rtype: numpy.array :return: A plane that crosses the specified position with the specified normal. """ # -d = a * px + b * py + c * pz n = vector.normalise( normal ) d = -numpy.sum( n * position ) return numpy.array( [ n[ 0 ], n[ 1 ], n[ 2 ], d ] )
def test_spherical(self): angle_vector = numpy.array([1.0, 0.0, 1.0]) angle_vector = vector.normalise(angle_vector) normals = numpy.array( [[1.0, 0.0, 0.0], [0.0, 0.0, 1.0], [angle_vector[0], angle_vector[1], angle_vector[2]]]) uv = Spherical(scale=(2.0, 1.0), offset=(0.0, 0.0)) # ignored anyway vertices = [] texture_coords = uv.generate_coordinates(vertices, normals) self.assertEqual(texture_coords[0][1], 0.5, "UV coordinates incorrect")
def apply( quat, vec3 ): """ v = numpy.array( vec ) return v + 2.0 * vector.cross( quat[:-1], vector.cross( quat[:-1], v ) + (quat[-1] * v) ) """ length = vector.length( vec3 ) vec3 = vector.normalise( vec3 ) # use the vector to create a new quaternion # this is basically the vector3 to vector4 conversion with W = 0 vec_quat = numpy.array( [ vec3[ 0 ], vec3[ 1 ], vec3[ 2 ], 0.0 ] ) # quat * vec * quat^-1 result = cross( quat, cross( vec_quat, conjugate( quat ) ) ) return result[ :-1 ] * length
def point_closest_point_on_ray( point, ray ): """Calculates the point on a ray that is closest to a point. :param numpy.array point: The point to check with. :param numpy.array ray: The ray to check against. :rtype: numpy.array :return: The closest point on the ray to the point. """ """ t = (p - rp).n cp = rp + (n * t) where p is the point rp is the ray origin n is the ray normal of unit length t is the distance along the ray to the point """ normalised_n = vector.normalise( ray[ 1 ] ) relative_point = (point - ray[ 0 ]) t = vector.dot( relative_point, normalised_n ) return ray[ 0 ] + ( normalised_n * t )
def regenViewMatrix(self): forward = array([ math.cos( self.verticalAngle ) * math.sin( self.horizontalAngle ), math.sin( self.verticalAngle ), math.cos( self.verticalAngle ) * math.cos( self.horizontalAngle ) ]) up = array([0.,-1.,0.,]) side = -vector.normalise( vector.cross( forward, up ) ) #shifts 'up' to the camera's up up = vector.cross( side, forward ) matrix2 = array( [[ side[0], up[0], forward[0], 0.0 ], [ side[1], up[1], forward[1], 0.0 ], [ side[2], up[2], forward[2], 0.0 ], [ 0.0, 0.0, 0.0, 1.0 ]], dtype = float32) self.position += forward * self.xMovement self.position += side * self.yMovement self.xMovement = self.yMovement = 0. self.viewMatrix = array(mat4.multiply( mat4.create_from_translation( self.position ), matrix2 ), dtype=float32)