def get_bone_transform_mat(self, bone_transform_array, bone_index): """ Returns the transform related to the given bone. The transform is returned as a 4-dimensions transform matrix. bone_transform_array : Array containing all the bones transformations bone_index : Index of the bone transformation to retrieve. """ if bone_index < len(bone_transform_array): bone_transform = bone_transform_array[bone_index] if bone_transform is not None: position = bone_transform.position orientation = bone_transform.orientation transform_mat = LMatrix4() compose_matrix(transform_mat, LVector3(1), LVector3(0), self.convert_quaternion(orientation).get_hpr(), self.convert_vector(position).get_xyz()) return self.coord_mat_inv * transform_mat * self.coord_mat else: print( "ERROR: No transform data for bone {}".format(bone_index)) else: print("ERROR: Invalid bone index {}".format(bone_index)) return LMatrix4.ident_mat()
def drawLeaf( nodePath, vdata, pos=LVector3(0, 0, 0), vecList=[LVector3(0, 0, 1), LVector3(1, 0, 0), LVector3(0, -1, 0)], scale=0.125): # use the vectors that describe the direction the branch grows to make the right # rotation matrix newCs = LMatrix4(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) newCs.setRow(0, vecList[2]) # right newCs.setRow(1, vecList[1]) # up newCs.setRow(2, vecList[0]) # forward newCs.setRow(3, (0, 0, 0)) newCs.setCol(3, (0, 0, 0, 1)) axisAdj = LMatrix4.scaleMat(scale) * newCs * LMatrix4.translateMat(pos) # orginlly made the leaf out of geometry but that didnt look good # I also think there should be a better way to handle the leaf texture other than # hardcoding the filename leafModel = loader.loadModel('models/shrubbery') leafTexture = loader.loadTexture('models/material-10-cl.png') leafModel.reparentTo(nodePath) leafModel.setTexture(leafTexture, 1) leafModel.setTransform(TransformState.makeMat(axisAdj))
def __init__(self, verbose=True): """ Wrapper around pyopenvr to allow it to work with Panda3D. See the init() method below for the actual initialization. * verbose specifies if the library prints status information when running. """ self.vr_system = None self.verbose = verbose self.vr_input = None self.compositor = None self.poses = None self.action_url = None self.action_path = None self.action_set_handle = None self.buffers = [] self.nextsort = base.win.getSort() - 1000 self.tracking_space = None self.hmd_anchor = None self.left_eye_anchor = None self.right_eye_anchor = None self.left_cam = None self.right_cam = None self.tracked_devices_anchors = {} self.empty_world = None self.coord_mat = LMatrix4.convert_mat(CS_yup_right, CS_default) self.coord_mat_inv = LMatrix4.convert_mat(CS_default, CS_yup_right) self.submit_together = True
def update_shader_shape(self, shape, appearance): planet = self.parameters.planet factor = 1.0 / shape.owner.scene_scale_factor inner_radius = self.parameters.planet_radius #TODO: We should get the oblateness correctly planet_scale = self.parameters.planet.surface.get_scale() descale = LMatrix4.scale_mat(inner_radius / planet_scale[0], inner_radius / planet_scale[1], inner_radius / planet_scale[2]) rotation_mat = LMatrix4() orientation = LQuaternion(*shape.owner.scene_orientation) orientation.extract_to_matrix(rotation_mat) rotation_mat_inv = LMatrix4() rotation_mat_inv.invert_from(rotation_mat) descale_mat = rotation_mat_inv * descale * rotation_mat pos = planet.rel_position scaled_pos = descale_mat.xform_point(LPoint3(*pos)) star_pos = planet.star._local_position - planet._local_position scaled_star_pos = descale_mat.xform_point(LPoint3(*star_pos)) scaled_star_pos.normalize() camera_height = scaled_pos.length() shape.instance.setShaderInput("v3OriginPos", pos) shape.instance.setShaderInput("v3CameraPos", -scaled_pos) shape.instance.setShaderInput("fCameraHeight", camera_height) shape.instance.setShaderInput("fCameraHeight2", camera_height * camera_height) shape.instance.setShaderInput("v3LightPos", scaled_star_pos) shape.instance.setShaderInput("model_scale", factor) shape.instance.setShaderInput("atm_descale", descale_mat)
def convert_mat(self, mat): if len(mat.m) == 4: result = LMatrix4(mat.m[0][0], mat.m[1][0], mat.m[2][0], mat.m[3][0], mat.m[0][1], mat.m[1][1], mat.m[2][1], mat.m[3][1], mat.m[0][2], mat.m[1][2], mat.m[2][2], mat.m[3][2], mat.m[0][3], mat.m[1][3], mat.m[2][3], mat.m[3][3]) elif len(mat.m) == 3: result = LMatrix4(mat.m[0][0], mat.m[1][0], mat.m[2][0], 0.0, mat.m[0][1], mat.m[1][1], mat.m[2][1], 0.0, mat.m[0][2], mat.m[1][2], mat.m[2][2], 0.0, mat.m[0][3], mat.m[1][3], mat.m[2][3], 1.0) return result
def rotationMagic(self, timestamp, angular_velocity, acceleration, magnetic_field): dt = timestamp - self.last_t self.last_t = timestamp angular_velocity = Vec3(*angular_velocity) acceleration = Vec3(*acceleration) magnetic_field = Vec3(*magnetic_field) correction = (0, 0, 0) if abs(acceleration.length() - 1) <= 0.3: correction_strength = 1 rotationCompass = self.rotationFromCompass(acceleration, magnetic_field) rotationMatrix = LMatrix4() self.rotation.extractToMatrix(rotationMatrix) correction = rotationCompass.getRow3(0).cross( rotationMatrix.getRow3(0)) correction += rotationCompass.getRow3(1).cross( rotationMatrix.getRow3(1)) correction += rotationCompass.getRow3(2).cross( rotationMatrix.getRow3(2)) correction *= correction_strength self.rotate(self.rotation, angular_velocity + correction, dt)
def ledgeCollisionCallback(self,action): ledge = action.game_obj2 ghost_body = self.character_obj_.getActionGhostBody() self.character_obj_.getStatus().ledge = ledge self.character_obj_.setStatic(True) # detemining position of ghost action body relative to character pos = ghost_body.node().getShapePos(0) if not self.character_obj_.isFacingRight(): # rotate about z by 180 if looking left pos.setX(-pos.getX()) # creating transform for placement of character relative to ledge ref_np = self.character_obj_.getReferenceNodePath() tf_obj_to_ghost = LMatrix4.translateMat(pos) tf_ghost_to_object = LMatrix4(tf_obj_to_ghost) tf_ghost_to_object.invertInPlace() tf_ref_to_ledge = ledge.getMat(ref_np) tf_ref_to_obj = TransformState.makeMat(tf_ref_to_ledge * tf_ghost_to_object) pos = tf_ref_to_obj.getPos() # placing character on ledge self.character_obj_.setX(ref_np,pos.getX()) self.character_obj_.setZ(ref_np,pos.getZ()) self.character_obj_.setLinearVelocity(Vec3(0,0,0)) # turning off collision ghost_body.node().setIntoCollideMask(CollisionMasks.NO_COLLISION) logging.debug(inspect.stack()[0][3] + ' invoked')
def convert_mat(self, mat): """ Convert a OpenVR Matrix into a Panda3D Matrix. No coordinate system conversion is performed. Note that 3x4 matrices are converted into 4x4 matrices. """ if len(mat.m) == 4: result = LMatrix4(mat.m[0][0], mat.m[1][0], mat.m[2][0], mat.m[3][0], mat.m[0][1], mat.m[1][1], mat.m[2][1], mat.m[3][1], mat.m[0][2], mat.m[1][2], mat.m[2][2], mat.m[3][2], mat.m[0][3], mat.m[1][3], mat.m[2][3], mat.m[3][3]) elif len(mat.m) == 3: result = LMatrix4(mat.m[0][0], mat.m[1][0], mat.m[2][0], 0.0, mat.m[0][1], mat.m[1][1], mat.m[2][1], 0.0, mat.m[0][2], mat.m[1][2], mat.m[2][2], 0.0, mat.m[0][3], mat.m[1][3], mat.m[2][3], 1.0) return result
def __init__(self, base=None, verbose=True): """ Wrapper around pyopenvr to allow it to work with Panda3D. See the init() method below for the actual initialization. * verbose specifies if the library prints status information when running. """ if base is None: base = __builtins__.get('base') self.base = base self.verbose = verbose self.vr_system = None self.vr_applications = None self.vr_input = None self.compositor = None self.poses = None self.action_set_handles = [] self.buffers = [] self.nextsort = self.base.win.getSort() - 1000 self.tracking_space = None self.hmd_anchor = None self.left_eye_anchor = None self.right_eye_anchor = None self.left_cam = None self.right_cam = None self.ham_shader = None self.tracked_devices_anchors = {} self.empty_world = None self.coord_mat = LMatrix4.convert_mat(CS_yup_right, CS_default) self.coord_mat_inv = LMatrix4.convert_mat(CS_default, CS_yup_right) self.submit_together = True self.event_handlers = [] self.submit_error_handler = None self.new_tracked_device_handler = None self.has_focus = False #Deprecation flags to avoid spamming self.process_vr_event_notified = False self.new_tracked_device_notified = False self.update_action_notified = False self.on_texture_submit_error_notified = False
def __init__(self): self.vr_system = None self.vr_input = None self.compositor = None self.poses = None self.action_url = None self.action_path = None self.action_set_handle = None self.buffers = [] self.nextsort = base.win.getSort() - 1000 self.tracking_space = None self.hmd_anchor = None self.left_eye_anchor = None self.right_eye_anchor = None self.left_cam = None self.right_cam = None self.tracked_devices_anchors = {} self.empty_world = None self.coord_mat = LMatrix4.convert_mat(CS_yup_right, CS_default) self.coord_mat_inv = LMatrix4.convert_mat(CS_default, CS_yup_right)
def update(self, instance, face): instance.set_shader_input('noiseOffset', self.offset) instance.set_shader_input('noiseScale', self.scale) instance.set_shader_input('global_frequency', self.global_frequency) instance.set_shader_input('global_offset', self.global_offset) #instance.set_shader_input('permTexture', self.texture) if self.coord == TexCoord.NormalizedCube or self.coord == TexCoord.SqrtCube: mat = self.get_rot_for_face(face) mat.transpose_in_place() instance.set_shader_input('cube_rot', LMatrix4(mat)) self.noise_source.update(instance)
def create_frustum(pos=None, mat=None): """Return an infinite frustum centered on the origin, looking towards +Y and with a near plane at (0, 1.0, 0) The default FoV is 30deg""" if pos is None: pos = LPoint3d() if mat is None: mat = LMatrix4() lens = PerspectiveLens() bh = lens.make_bounds() f = InfiniteFrustum(bh, mat, pos) return f
def drawLeaf(nodePath, vdata, pos=LVector3(0, 0, 0), vecList=[LVector3(0, 0, 1), LVector3(1, 0, 0), LVector3(0, -1, 0)], scale=0.125): # use the vectors that describe the direction the branch grows to make the right # rotation matrix newCs = LMatrix4(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) newCs.setRow(0, vecList[2]) # right newCs.setRow(1, vecList[1]) # up newCs.setRow(2, vecList[0]) # forward newCs.setRow(3, (0, 0, 0)) newCs.setCol(3, (0, 0, 0, 1)) axisAdj = LMatrix4.scaleMat(scale) * newCs * LMatrix4.translateMat(pos) # orginlly made the leaf out of geometry but that didnt look good # I also think there should be a better way to handle the leaf texture other than # hardcoding the filename leafModel = loader.loadModel('models/shrubbery') leafTexture = loader.loadTexture('models/material-10-cl.png') leafModel.reparentTo(nodePath) leafModel.setTexture(leafTexture, 1) leafModel.setTransform(TransformState.makeMat(axisAdj))
def rotationFromCompass(acceleration, magnetic_field): down = -acceleration east = down.cross(magnetic_field) north = east.cross(down) east.normalize() north.normalize() down.normalize() r = LMatrix4() r.setRow(0, north) r.setRow(1, east) r.setRow(2, down) return r
def test_frustum_intersection(): f = create_frustum() assert not f.is_sphere_in(LPoint3d(), 0) assert f.is_sphere_in(LPoint3d(), 1.1) assert f.is_sphere_in(LPoint3d(0, 1.1, 0), 0) mat = LMatrix4() mat.set_rotate_mat(90, LVector3.up()) f = create_frustum(mat=mat) assert not f.is_sphere_in(LPoint3d(), 0) assert f.is_sphere_in(LPoint3d(), 1.1) assert f.is_sphere_in(LPoint3d(-1.1, 0, 0), 0) assert not f.is_sphere_in(LPoint3d(0, 1.1, 0), 0) pos = LPoint3d(0, 1, 0) f = create_frustum(pos=pos) assert not f.is_sphere_in(LPoint3d(), 0) assert not f.is_sphere_in(LPoint3d(), 1.1) assert not f.is_sphere_in(LPoint3d(0, 1.1, 0), 0) assert f.is_sphere_in(LPoint3d(), 2.1) assert f.is_sphere_in(LPoint3d(0, 2.1, 0), 0)
def testMat4ToNumpyArray(self): xr = np.random.random((4, 4)) mat = LMatrix4(*xr.ravel()) x = mat4ToNumpyArray(mat) self.assertTrue(np.allclose(x, xr, atol=1e-6))
def make_rigid_transform(rotation, translation): """Return a TransformState comprising the given rotation followed by the given translation""" return TransformState.makeMat(LMatrix4(rotation, translation))