def complete_shape(self, id_mb1, node, transform): """ create the shape then call recursive function""" #print "complete shape {}".format(node) ## construct the node self.add_node_to_shape(node, id_mb1, transform) if node.gen_type == 'piece': self.shape_building_status[node] = True elif node.gen_type() == 'link': self.link_building_status[node][1] = (id_mb1, TransformState.makeMat(transform.getMat())) self.build_link(node) ## recursive loop over the edges for face, edge in enumerate(node.edges[1:]): if edge.type() != 'empty': transform = self.change_transform(transform, face + 1, type) if edge.gen_type() == 'shape': if not self.shape_building_status[edge]: #then we have to add this node (because it #is not entirely finished self.complete_shape(id_mb1, edge, transform) elif edge.gen_type() == 'link': if self.link_building_status[edge][0][0] is None: # first time we see this link #print "hi new link" self.add_node_to_shape(edge, id_mb1, transform) self.link_building_status[edge][0] = (id_mb1, TransformState.makeMat(transform.getMat())) else: # link is complete: #print " hi end link" self.add_node_to_shape(edge, id_mb1) self.link_building_status[edge][1] = (id_mb1, TransformState.makeMat(transform.getMat())) self.build_link(edge) transform = self.change_back_transform(transform, face + 1, type)
def build_link(self, node): (id_bda, ta), (id_bdb, tb) = self.link_building_status[node] bda = self.factory.multiboxes[id_bda] bdb = self.factory.multiboxes[id_bdb] pos = bda.body.getPosition() quat = LQuaternionf(bda.body.getQuaternion()) mat = TransformState.makePosQuatScale(pos, quat, Vec3(1, 1, 1)).getMat() mat = ta.getMat() * mat print "ta", ta print "absol", TransformState.makeMat(mat) mat = LMatrix4f.translateMat(Vec3(0.5, 0, 0)) * mat anchor = TransformState.makeMat(mat).getPos() print "absol", TransformState.makeMat(mat) axis = self.quat_dict[1][1] if node.orientation == 1: t = LMatrix4f.rotateMat(*self.quat_dict[4]) * mat else: t = LMatrix4f.rotateMat(*self.quat_dict[2]) * mat row = t.getRow(0) print "rotation", t.getRow(0), type(t.getRow(0)) #axis = t.getQuat().getAxis() axis = Vec3(row.getX(), row.getY(), row.getZ()) print "axis",axis print "anchor", anchor mat = LMatrix4f.translateMat(Vec3(0.5, 0, 0)) * mat mat = tb.getInverse().getMat() * mat t = TransformState.makeMat(mat) posb = t.getPos() quatb = t.getQuat() bdb.body.setPosition(posb) bdb.body.setQuaternion(quatb) cs = OdeHingeJoint(self.physics.world, self.physics.servogroup) cs.attach(bda.body, bdb.body) cs.setAxis(axis) cs.setAnchor(anchor) #add the motor cs.setParamFMax(self.satu_cmd) cs.setParamFudgeFactor(0.5) cs.setParamCFM(11.1111) cs.setParamStopCFM(11.1111) cs.setParamStopERP(0.444444) cs.setParamLoStop(- math.pi * 0.5) cs.setParamHiStop(math.pi * 0.5) pid = PID() self.dof_motors[node] = (cs, pid) print "add constraint"
def move_city(self, task): # moves the city, using the transformation matrix # first, get the current transformation matrix # getTransform() returns a TransformState, which is a higher level # abstraction of our matrix # getMat() retrieves the inner matrix. the returned matrix is const # though oldmat = self.cityModel.getTransform().getMat() # oldmat ist a const Mat4, we need one we can manipulate newmat = Mat4(oldmat) # the matrices in Panda3d are suitable for row-vector multiplication, that is # vector * Matrix (same as opengl). the bottom row (3) is therefore the # translation in xyzt order # # replace it with a different one, we want to move the value of # time, which is the number of seconds passed since starting this task newmat.setRow(3, Vec4(1 - task.time, 3, 0, 1)) # we need to create a new TransformState from the matrix, and set it # to apply the transformation self.cityModel.setTransform(TransformState.makeMat(newmat)) return Task.cont
def _createInputHandles(self): """ Defines various inputs to be used in the shader passes. Most inputs use pta-arrays, so updating them is faster than using setShaderInput all the time. """ self.cameraPosition = PTAVecBase3f.emptyArray(1) self.currentViewMat = PTALMatrix4f.emptyArray(1) self.currentProjMatInv = PTALMatrix4f.emptyArray(1) self.lastMVP = PTALMatrix4f.emptyArray(1) self.currentMVP = PTALMatrix4f.emptyArray(1) self.frameIndex = PTAInt.emptyArray(1) self.frameDelta = PTAFloat.emptyArray(1) self.renderPassManager.registerStaticVariable("lastMVP", self.lastMVP) self.renderPassManager.registerStaticVariable("currentMVP", self.currentMVP) self.renderPassManager.registerStaticVariable("frameIndex", self.frameIndex) self.renderPassManager.registerStaticVariable("cameraPosition", self.cameraPosition) self.renderPassManager.registerStaticVariable("mainCam", self.showbase.cam) self.renderPassManager.registerStaticVariable("mainRender", self.showbase.render) self.renderPassManager.registerStaticVariable("frameDelta", self.frameDelta) self.renderPassManager.registerStaticVariable("currentViewMat", self.currentViewMat) self.renderPassManager.registerStaticVariable("currentProjMatInv", self.currentProjMatInv) self.renderPassManager.registerStaticVariable("zeroVec2", Vec2(0)) self.renderPassManager.registerStaticVariable("zeroVec3", Vec3(0)) self.renderPassManager.registerStaticVariable("zeroVec4", Vec4(0)) self.transformMat = TransformState.makeMat(Mat4.convertMat(CSYupRight, CSZupRight))
def __init__(self): """ Creates a new ShadowSource. After the creation, a lens can be added with setupPerspectiveLens or setupOrtographicLens. """ self.index = self._generateUID() DebugObject.__init__(self, "ShadowSource-" + str(self.index)) ShaderStructElement.__init__(self) self.valid = False self.camera = Camera("ShadowSource-" + str(self.index)) self.camera.setActive(False) self.cameraNode = NodePath(self.camera) self.cameraNode.reparentTo(Globals.render.find("RPCameraDummys")) self.cameraNode.hide() self.resolution = 512 self.atlasPos = Vec2(0) self.doesHaveAtlasPos = False self.sourceIndex = 0 self.mvp = UnalignedLMatrix4f() self.sourceIndex = -1 self.nearPlane = 0.0 self.farPlane = 1000.0 self.converterYUR = None self.transforMat = TransformState.makeMat( Mat4.convertMat( Globals.base.win.getGsg().getInternalCoordinateSystem(), CSZupRight))
def __init__(self): """ Creates a new ShadowSource. After the creation, a lens can be added with setupPerspectiveLens or setupOrtographicLens. """ self.index = self._generateUID() DebugObject.__init__(self, "ShadowSource-" + str(self.index)) ShaderStructElement.__init__(self) self.valid = False self.camera = Camera("ShadowSource-" + str(self.index)) self.camera.setActive(False) self.cameraNode = NodePath(self.camera) self.cameraNode.reparentTo(Globals.render.find("RPCameraDummys")) self.cameraNode.hide() self.resolution = 512 self.atlasPos = Vec2(0) self.doesHaveAtlasPos = False self.sourceIndex = 0 self.mvp = UnalignedLMatrix4f() self.sourceIndex = -1 self.nearPlane = 0.0 self.farPlane = 1000.0 self.converterYUR = None self.transforMat = TransformState.makeMat( Mat4.convertMat(Globals.base.win.getGsg().getInternalCoordinateSystem(), CSZupRight))
def move_city(self, task): # moves the city, using the transformation matrix # first, get the current transformation matrix # getTransform() returns a TransformState, which is a higher level # abstraction of our matrix # getMat() retrieves the inner matrix. the returned matrix is const # though oldmat = self.cityModel.getTransform().getMat() # oldmat ist a const Mat4, we need one we can manipulate newmat = Mat4(oldmat) # the matrices in Panda3d are suitable for row-vector multiplication, that is # vector * Matrix (same as opengl). the bottom row (3) is therefore the # translation in xyzt order # # replace it with a different one, we want to move the value of # time, which is the number of seconds passed since starting this task newmat.setRow(3, Vec4(1-task.time, 3, 0, 1)) # we need to create a new TransformState from the matrix, and set it # to apply the transformation self.cityModel.setTransform(TransformState.makeMat(newmat)) return Task.cont
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 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 draw_debugging_arrow(base, v_from, v_to): arrowModel = base.loader.loadModel('models/debuggingArrow') mat = align_to_vector(v_to-v_from) arrowModel.setTransform(TransformState.makeMat(mat)) arrowModel.setPos(*v_from) arrowModel.reparentTo(base.render) return arrowModel
def _computeMVP(self): projMat = Mat4.convertMat(CSYupRight, base.camLens.getCoordinateSystem( )) * base.camLens.getProjectionMat() transformMat = TransformState.makeMat( Mat4.convertMat(base.win.getGsg().getInternalCoordinateSystem(), CSZupRight)) modelViewMat = transformMat.invertCompose(render.getTransform( base.cam)).getMat() self.lastMVP = modelViewMat * projMat
def set_world_matrix(self, matrix): self.matrix = matrix panda_mat = LMatrix4f(matrix[0][0], matrix[1][0], matrix[2][0], matrix[3][0], matrix[0][1], matrix[1][1], matrix[2][1], matrix[3][1], matrix[0][2], matrix[1][2], matrix[2][2], matrix[3][2], matrix[0][3], matrix[1][3], matrix[2][3], matrix[3][3]) self.geom_path.setTransform(TransformState.makeMat(panda_mat))
def computeMVP(self): projMat = Mat4.convertMat( CSYupRight, self.lens.getCoordinateSystem()) * self.lens.getProjectionMat() transformMat = TransformState.makeMat( Mat4.convertMat(base.win.getGsg().getInternalCoordinateSystem(), CSZupRight)) modelViewMat = transformMat.invertCompose( render.getTransform(self.cameraNode)).getMat() self.mvp = UnalignedLMatrix4f(modelViewMat * projMat)
def sethomomat(self, homomat): """ set the pose of the dynamic body :param homomat: the homomat of the original frame (the collision model) :return: author: weiwei date: 2019?, 20201119 """ pos = rm.homomat_transform_points(homomat, self.com) rotmat = homomat[:3, :3] self.setTransform(TransformState.makeMat(dh.npv3mat3_to_pdmat4(pos, rotmat)))
def computeMVP(self): """ Computes the modelViewProjection matrix for the lens. Actually, this is the worldViewProjection matrix, but for convenience it is called mvp. """ projMat = self.converterYUR transformMat = TransformState.makeMat( Mat4.convertMat(Globals.base.win.getGsg().getInternalCoordinateSystem(), CSZupRight)) modelViewMat = transformMat.invertCompose( Globals.render.getTransform(self.cameraNode)).getMat() self.mvp = UnalignedLMatrix4f(modelViewMat * projMat)
def attachCubes(self, loader): for collider in self.colliders: for i in range(collider.node().getNumShapes()): shape = collider.node().getShape(i) mat = collider.node().getShapeMat(i) scale = shape.getHalfExtentsWithMargin() transform = TransformState.makeMat(mat) cube = loader.loadModel("cube.egg") cube.setTransform(transform) cube.setScale(scale) cube.reparentTo(collider)
def drawLeaf(self, pos=Vec3(0, 0, 0), quat=None, scale=0.125): """ this draws leafs when we reach an end """ #use the vectors that describe the direction the branch grows to make #the right rotation matrix newCs = Mat4() quat.extractToMatrix(newCs) axisAdj = Mat4.scaleMat(scale) * newCs * Mat4.translateMat(pos) leafModel = NodePath("leaf") self.leafModel.instanceTo(leafModel) leafModel.reparentTo(self.leaves) leafModel.setTransform(TransformState.makeMat(axisAdj))
def moveRBnode(self,node, trans, rotMat): mat = rotMat.copy() # mat[:3, 3] = trans # mat = mat.transpose() mat = mat.transpose().reshape((16,)) # print mat,len(mat),mat.shape pMat = Mat4(mat[0],mat[1],mat[2],mat[3], mat[4],mat[5],mat[6],mat[7], mat[8],mat[9],mat[10],mat[11], trans[0],trans[1],trans[2],mat[15],) pTrans = TransformState.makeMat(pMat) nodenp = NodePath(node) nodenp.setMat(pMat)
def _computeMVP(self): """ Computes the current mvp. Actually, this is the worldViewProjectionMatrix, but for convience it's called mvp. """ camLens = self.showbase.camLens projMat = Mat4.convertMat( CSYupRight, camLens.getCoordinateSystem()) * camLens.getProjectionMat() transformMat = TransformState.makeMat( Mat4.convertMat(self.showbase.win.getGsg().getInternalCoordinateSystem(), CSZupRight)) modelViewMat = transformMat.invertCompose( self.showbase.render.getTransform(self.showbase.cam)).getMat() return UnalignedLMatrix4f(modelViewMat * projMat)
def _computeAdditionalData(self): """ Internal method to recompute the spotlight MVP """ self.ghostCameraNode.setPos(self.position) transMat = TransformState.makeMat( Mat4.convertMat(Globals.base.win.getGsg().getInternalCoordinateSystem(), CSZupRight)) converterMat = Mat4.convertMat(CSYupRight, self.ghostLens.getCoordinateSystem()) * self.ghostLens.getProjectionMat() modelViewMat = transMat.invertCompose( Globals.render.getTransform(self.ghostCameraNode)).getMat() self.mvp = modelViewMat * converterMat
def _computeMVP(self): """ Computes the current mvp. Actually, this is the worldViewProjectionMatrix, but for convience it's called mvp. """ camLens = self.showbase.camLens projMat = Mat4.convertMat( CSYupRight, camLens.getCoordinateSystem()) * camLens.getProjectionMat() transformMat = TransformState.makeMat( Mat4.convertMat( self.showbase.win.getGsg().getInternalCoordinateSystem(), CSZupRight)) modelViewMat = transformMat.invertCompose( self.showbase.render.getTransform(self.showbase.cam)).getMat() return UnalignedLMatrix4f(modelViewMat * projMat)
def set_homomat(self, homomat): """ set the pose of the dynamic body :param homomat: the homomat of the original frame (the collision model) :return: author: weiwei date: 2019?, 20201119 """ tmp_homomat = copy.deepcopy(homomat) tmp_homomat[:3, 3] = tmp_homomat[:3, 3] * base.physics_scale pos = rm.homomat_transform_points(tmp_homomat, self.com) rotmat = tmp_homomat[:3, :3] self.setTransform( TransformState.makeMat(dh.npv3mat3_to_pdmat4(pos, rotmat)))
def addMultiCylinderRB(self,rads,centT1,centT2,**kw): inodenp = self.worldNP.attachNewNode(BulletRigidBodyNode("Cylinder")) inodenp.node().setMass(1.0) centT1 = ingr.positions[0]#ingr.transformPoints(jtrans, rotMat, ingr.positions[0]) centT2 = ingr.positions2[0]#ingr.transformPoints(jtrans, rotMat, ingr.positions2[0]) for radc, p1, p2 in zip(rads, centT1, centT2): length, mat = helper.getTubePropertiesMatrix(p1,p2) pMat = self.pandaMatrice(mat) # d = numpy.array(p1) - numpy.array(p2) # s = numpy.sum(d*d) shape = BulletCylinderShape(radc, length,1)#math.sqrt(s), 1)# { XUp = 0, YUp = 1, ZUp = 2 } or LVector3f const half_extents inodenp.node().addShape(shape, TransformState.makeMat(pMat))# self.setRB(inodenp,**kw) inodenp.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(inodenp.node()) return inodenp
def genBulletCDBox(obstaclecm, name='autogen'): """ generate a bullet cd obj using a list of AABB box generated from obstaclenp :param obstaclenp: the AABB box of the obstaclenp will be computed and used for cd :return: bulletrigidbody author: weiwei date: 20190126, osaka """ bulletboxesnode = BulletRigidBodyNode(name) bulletboxshape = BulletBoxShape.makeFromSolid(obstaclecm.cdcn.getSolid(0)) bulletboxesnode.addShape(bulletboxshape, TransformState.makeMat(obstaclecm.getMat())) return bulletboxesnode
def genBulletCDBox(obstaclecm, name='autogen'): """ generate a bullet cd obj using the AABB boundary of a obstacle collision model :param obstaclecm: a collision model :return: bulletrigidbody author: weiwei date: 20190313, toyonaka """ if obstaclecm.type is not "box": raise Exception( "Wrong obstaclecm type! Box is required to genBulletCDBox.") bulletboxesnode = BulletRigidBodyNode(name) bulletboxshape = BulletBoxShape.makeFromSolid(obstaclecm.cdcn.getSolid(0)) bulletboxesnode.addShape(bulletboxshape, TransformState.makeMat(obstaclecm.getMat())) return bulletboxesnode
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 genBulletCDBoxList(obstaclecmlist, name='autogen'): """ generate a bullet cd obj using the AABB boundaries stored in obstacle collision models :param obstaclecmlist: a list of collision models (cmshare doesnt work!) :return: bulletrigidbody author: weiwei date: 20190313, toyonaka """ bulletboxlistnode = BulletRigidBodyNode(name) for obstaclecm in obstaclecmlist: if obstaclecm.type is not "box": raise Exception( "Wrong obstaclecm type! Box is required to genBulletCDBox.") cdsolid = obstaclecm.cdcn.getSolid(0) bulletboxshape = BulletBoxShape.makeFromSolid(cdsolid) rotmatpd4 = obstaclecm.getMat(base.render) bulletboxlistnode.addShape( bulletboxshape, TransformState.makeMat(rotmatpd4).setPos( rotmatpd4.xformPoint(cdsolid.getCenter()))) return bulletboxlistnode
axisAdj = Mat4.scaleMat(scale) * newCs * Mat4.translateMat(pos) except TypeError, e: print e print scale, 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 = NodePath('leaf') nodePath.leafModel.copyTo(leafModel) leafModel.reparentTo(nodePath) leafModel.setTexture(nodePath.leafTex, 1) leafModel.setTransform(TransformState.makeMat(axisAdj)) #recursive algorthim to make the tree def make_fractal_tree(bodydata, nodePath, length, pos=Vec3(0, 0, 0), numIterations=11, numCopies=4, vecList=[Vec3(0, 0, 1), Vec3(1, 0, 0), Vec3(0, -1, 0)]): if numIterations > 0: draw_body(nodePath, bodydata, pos, vecList, length.getX())
axisAdj = Mat4.scaleMat(scale) * newCs * Mat4.translateMat(pos) except TypeError, e: print e print scale, 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 = NodePath("leaf") nodePath.leafModel.copyTo(leafModel) leafModel.reparentTo(nodePath) leafModel.setTexture(nodePath.leafTex, 1) leafModel.setTransform(TransformState.makeMat(axisAdj)) # recursive algorthim to make the tree def make_fractal_tree( bodydata, nodePath, length, pos=Vec3(0, 0, 0), numIterations=11, numCopies=4, vecList=[Vec3(0, 0, 1), Vec3(1, 0, 0), Vec3(0, -1, 0)], ): if numIterations > 0: draw_body(nodePath, bodydata, pos, vecList, length.getX())
def processModel(path): scene = loadModel(path) if scene.isEmpty(): print("Error converting `{0}`!".format(path)) return fPath = Filename.fromOsSpecific(path) outputPath = Filename.toOsSpecific( Filename("bam2smd/" + fPath.getDirname() + "/" + fPath.getBasenameWoExtension() + "/")) if not os.path.exists(outputPath): os.makedirs(outputPath) isCharacter = not scene.find("**/+Character").isEmpty() isAnimation = not scene.find("**/+AnimBundleNode").isEmpty() if not isAnimation: if isCharacter: nodes = Skeleton(scene.findAllMatches("**/+Character")) else: nodes = Skeleton(None) names = {} for geomNp in scene.findAllMatches("**/+GeomNode"): smd = "version 1\n" smd += str(nodes) smd += "skeleton\n" smd += "time 0\n" if isCharacter: boneIds = sorted(nodes.bones.keys()) for iBone in range(len(boneIds)): boneId = boneIds[iBone] bone = nodes.bones[boneId] if isinstance(bone, CharacterJoint): boneTform = bone.getTransformState() pos = boneTform.getPos() boneMat = boneTform.getMat().getUpper3() #boneMat.transposeInPlace() rot = mat3NormalizedToEulO(boneMat) else: pos = Vec3() rot = Vec3() smd += boneFrameString(boneId, pos, rot) else: smd += "0 0 0 0 0 0 0\n" smd += "end\n" smd += "triangles\n" for geom in geomNp.node().getGeoms(): geom = geom.decompose() vdata = geom.getVertexData() blendTable = vdata.getTransformBlendTable() for prim in geom.getPrimitives(): numTris = prim.getNumPrimitives() for nTri in range(numTris): start = prim.getPrimitiveStart(nTri) end = prim.getPrimitiveEnd(nTri) smd += "no_material\n" for primVert in range(start, end): vertIdx = prim.getVertex(primVert) reader = GeomVertexReader(vdata) reader.setColumn(InternalName.getVertex()) reader.setRow(vertIdx) pos = reader.getData3f() uv = Vec2(0, 0) if vdata.hasColumn(InternalName.getTexcoord()): reader.setColumn(InternalName.getTexcoord()) reader.setRow(vertIdx) uv = reader.getData2f() norm = Vec3.forward() if vdata.hasColumn(InternalName.getNormal()): reader.setColumn(InternalName.getNormal()) reader.setRow(vertIdx) norm = reader.getData3f() smd += "0 {0:.6f} {1:.6f} {2:.6f} {3:.6f} {4:.6f} {5:.6f} {6:.6f} {7:.6f} ".format( pos[0], pos[1], pos[2], norm[0], norm[1], norm[2], uv[0], uv[1]) if (isCharacter and blendTable and vdata.getNumArrays() > 1 and vdata.getArray(1).hasColumn( InternalName.getTransformBlend())): reader.setColumn( 1, vdata.getArray( 1).getArrayFormat().getColumn( InternalName.getTransformBlend())) reader.setRow(vertIdx) nBlend = reader.getData1i() blend = blendTable.getBlend(nBlend) numTransforms = blend.getNumTransforms() smd += "{0} ".format(numTransforms) for nTransform in range(numTransforms): transform = blend.getTransform(nTransform) if isinstance(transform, JointVertexTransform): boneId = nodes.getBoneId( transform.getJoint()) smd += "{0} {1:.6f} ".format( boneId, blend.getWeight(nTransform)) else: smd += "1 0 1.0" smd += "\n" smd += "end\n" smdFile = geomNp.getName() if len(smdFile) == 0: smdFile = getUnknownName() elif names.get(smdFile, 0) > 0: smdFile = smdFile + "_{0}".format(names[smdFile]) names[smdFile] += 1 else: names[smdFile] = 1 smdFile += ".smd" outFile = open(outputPath + "\\" + smdFile, "w") outFile.write(smd) outFile.flush() outFile.close() else: bundles = scene.findAllMatches("**/+AnimBundleNode") bundle = bundles[0].node().getBundle() nodes = Skeleton(bundles) smd = "version 1\n" smd += str(nodes) smd += "skeleton\n" numFrames = bundle.getNumFrames() boneIds = sorted(nodes.bones.keys()) for iFrame in range(numFrames): smd += "time {0}\n".format(iFrame) for iBone in range(len(boneIds)): bone = nodes.getBone(boneIds[iBone]) if isinstance(bone, AnimChannelACMatrixSwitchType): boneFrameMat = Mat4() bone.getValueNoScaleShear(iFrame, boneFrameMat) boneFrameTransform = TransformState.makeMat(boneFrameMat) pos = boneFrameTransform.getPos() rotMat = boneFrameMat.getUpper3() #rotMat.transposeInPlace() rot = mat3NormalizedToEulO(rotMat) smd += boneFrameString(boneIds[iBone], pos, rot) smd += "end\n" smdFile = fPath.getBasenameWoExtension() + ".smd" outFile = open(outputPath + "\\" + smdFile, "w") outFile.write(smd) outFile.flush() outFile.close()
def __init__(self, base, board, tileset = None, x_stretch = 3/2., y_stretch = sqrt(3)/2., z_plane = 0): self.base = base self.board = board self.tileset = tileset or SimpleTileset(base) self.x_stretch = x_stretch self.y_stretch = y_stretch self.z_plane = 0 # we get s == 1 by using to tile-scaling # the projection of the tile uses integers, multiplying by # x and y stretch should result in correct coordinates for pos, tile in board.tiles.iteritems(): # load model (tileModel, chip_offset) = self.tileset.get_tile_model_with_chip_offset(tile) # calculate position tile_coordinates = self.get_tile_coordinates(pos) tileModel.setPos(*tile_coordinates) tileModel.setTag('pickable', 'True') # load and place chip if tile.number: chipModel = self.tileset.get_chip_model(tile.number) chipModel.setPos(chip_offset) chipModel.reparentTo(tileModel) chipModel.setTag('pickable', 'False') # render tileModel.reparentTo(base.render) # handle graph nodes for n in self.board.network.nodes_iter(): building = self.board.network.node[n].get('building',None) if building == 'city': cityModel = self.tileset.get_city_model() self.apply_player_texture(cityModel, self.board.network.node[n]['player']) cityModel.setH(random.random()*360) # rotation randomly cityModel.setPos(*self.get_node_coordinates(n)) cityModel.reparentTo(base.render) cityModel.setTag('pickable', 'True') # handle graph edges for e in self.board.network.edges_iter(): if 'road' in self.board.network.edge[e[0]][e[1]]: roadModel = self.tileset.get_road_model() self.apply_player_texture(roadModel, self.board.network.edge[e[0]][e[1]]['player']) # get coordinates co_s, co_t = map(self.get_node_coordinates, e) # align mat = align_to_vector(co_t-co_s) roadModel.setTransform(TransformState.makeMat(mat)) roadModel.setPos(co_s) roadModel.reparentTo(base.render) roadModel.setTag('pickable', 'True') # place robber if self.board.robber: robberModel = self.tileset.get_robber_model() robberModel.setPos(*self.get_tile_coordinates(self.board.robber)) robberModel.reparentTo(base.render) robberModel.setTag('pickable', 'True') # place harbors try: coast_nodes = self.board.walk_coast() while True: node_id = coast_nodes.next() if 'harbor' in self.board.network.node[node_id]: # harbors should appear in pairs node_id2 = coast_nodes.next() assert(self.board.network.node[node_id]['harbor'] == self.board.network.node[node_id2]['harbor']) # harbor edge h1, h2 = self.get_node_coordinates(node_id), self.get_node_coordinates(node_id2) harborModel = self.tileset.get_harbor_model() # rotate harbor mat = align_to_vector(h2-h1) harborModel.setTransform(TransformState.makeMat(mat)) harborModel.setPos(h1) harborModel.setTag('pickable', 'True') harborModel.reparentTo(base.render) except StopIteration: pass
def loadHouseFromJson(houseId, datasetRoot): filename = SunCgSceneLoader.getHouseJsonPath(datasetRoot, houseId) with open(filename) as f: data = json.load(f) assert houseId == data['id'] houseId = str(data['id']) # Create new node for house instance houseNp = NodePath('house-' + str(houseId)) objectIds = {} for levelId, level in enumerate(data['levels']): logger.debug('Loading Level %s to scene' % (str(levelId))) # Create new node for level instance levelNp = houseNp.attachNewNode('level-' + str(levelId)) roomNpByNodeIndex = {} for nodeIndex, node in enumerate(level['nodes']): if not node['valid'] == 1: continue modelId = str(node['modelId']) if node['type'] == 'Room': logger.debug('Loading Room %s to scene' % (modelId)) # Create new nodes for room instance roomNp = levelNp.attachNewNode('room-' + str(modelId)) roomLayoutsNp = roomNp.attachNewNode('layouts') roomObjectsNp = roomNp.attachNewNode('objects') # Load models defined for this room for roomObjFilename in reglob( os.path.join(datasetRoot, 'room', houseId), modelId + '[a-z].obj'): # Convert extension from OBJ + MTL to EGG format f, _ = os.path.splitext(roomObjFilename) modelFilename = f + ".egg" if not os.path.exists(modelFilename): raise Exception( 'The SUNCG dataset object models need to be convert to Panda3D EGG format!' ) # Create new node for object instance objectNp = NodePath('object-' + str(modelId) + '-0') objectNp.reparentTo(roomLayoutsNp) model = loadModel(modelFilename) model.setName('model-' + os.path.basename(f)) model.reparentTo(objectNp) model.hide() if 'nodeIndices' in node: for childNodeIndex in node['nodeIndices']: roomNpByNodeIndex[childNodeIndex] = roomObjectsNp elif node['type'] == 'Object': logger.debug('Loading Object %s to scene' % (modelId)) # Instance identification if modelId in objectIds: objectIds[modelId] = objectIds[modelId] + 1 else: objectIds[modelId] = 0 # Create new node for object instance objectNp = NodePath('object-' + str(modelId) + '-' + str(objectIds[modelId])) #TODO: loading the BAM format would be much more efficient # Convert extension from OBJ + MTL to EGG format objFilename = os.path.join(datasetRoot, 'object', node['modelId'], node['modelId'] + '.obj') assert os.path.exists(objFilename) f, _ = os.path.splitext(objFilename) modelFilename = f + ".egg" if not os.path.exists(modelFilename): raise Exception( 'The SUNCG dataset object models need to be convert to Panda3D EGG format!' ) model = loadModel(modelFilename) model.setName('model-' + os.path.basename(f)) model.reparentTo(objectNp) model.hide() # 4x4 column-major transformation matrix from object coordinates to scene coordinates transform = np.array(node['transform']).reshape((4, 4)) # Transform from Y-UP to Z-UP coordinate systems #TODO: use Mat4.convertMat(CS_zup_right, CS_yup_right) yupTransform = np.array([[1, 0, 0, 0], [0, 0, -1, 0], [0, 1, 0, 0], [0, 0, 0, 1]]) zupTransform = np.array([[1, 0, 0, 0], [0, 0, 1, 0], [0, -1, 0, 0], [0, 0, 0, 1]]) transform = np.dot(np.dot(yupTransform, transform), zupTransform) transform = TransformState.makeMat( LMatrix4f(*transform.ravel())) # Calculate the center of this object minBounds, maxBounds = model.getTightBounds() centerPos = minBounds + (maxBounds - minBounds) / 2.0 # Add offset transform to make position relative to the center objectNp.setTransform( transform.compose(TransformState.makePos(centerPos))) model.setTransform(TransformState.makePos(-centerPos)) # Get the parent nodepath for the object (room or level) if nodeIndex in roomNpByNodeIndex: objectNp.reparentTo(roomNpByNodeIndex[nodeIndex]) else: objectNp.reparentTo(levelNp) # Validation assert np.allclose(mat4ToNumpyArray( model.getNetTransform().getMat()), mat4ToNumpyArray(transform.getMat()), atol=1e-6) objectNp.setTag('model-id', str(modelId)) objectNp.setTag('level-id', str(levelId)) objectNp.setTag('house-id', str(houseId)) elif node['type'] == 'Ground': logger.debug('Loading Ground %s to scene' % (modelId)) # Create new nodes for ground instance groundNp = levelNp.attachNewNode('ground-' + str(modelId)) groundLayoutsNp = groundNp.attachNewNode('layouts') # Load model defined for this ground for groundObjFilename in reglob( os.path.join(datasetRoot, 'room', houseId), modelId + '[a-z].obj'): # Convert extension from OBJ + MTL to EGG format f, _ = os.path.splitext(groundObjFilename) modelFilename = f + ".egg" if not os.path.exists(modelFilename): raise Exception( 'The SUNCG dataset object models need to be convert to Panda3D EGG format!' ) objectNp = NodePath('object-' + str(modelId) + '-0') objectNp.reparentTo(groundLayoutsNp) model = loadModel(modelFilename) model.setName('model-' + os.path.basename(f)) model.reparentTo(objectNp) model.hide() else: raise Exception('Unsupported node type: %s' % (node['type'])) scene = Scene() houseNp.reparentTo(scene.scene) # Recenter objects in rooms for room in scene.scene.findAllMatches('**/room*'): # Calculate the center of this room minBounds, maxBounds = room.getTightBounds() centerPos = minBounds + (maxBounds - minBounds) / 2.0 # Add offset transform to room node room.setTransform(TransformState.makePos(centerPos)) # Add recentering transform to all children nodes for childNp in room.getChildren(): childNp.setTransform(TransformState.makePos(-centerPos)) # Recenter objects in grounds for ground in scene.scene.findAllMatches('**/ground*'): # Calculate the center of this ground minBounds, maxBounds = ground.getTightBounds() centerPos = minBounds + (maxBounds - minBounds) / 2.0 # Add offset transform to ground node ground.setTransform(TransformState.makePos(centerPos)) # Add recentering transform to all children nodes for childNp in ground.getChildren(): childNp.setTransform(TransformState.makePos(-centerPos)) return scene
def __init__(self, initor, cdtype="triangles", mass=.3, restitution=0, allow_deactivation=False, allow_ccd=True, friction=.2, dynamic=True, name="rbd"): """ TODO: triangles do not seem to work (very slow) in the github version (20210418) Use convex if possible :param initor: could be itself (copy), or an instance of collision model :param type: triangle or convex :param mass: :param restitution: bounce parameter :param friction: :param dynamic: only applicable to triangle type, if an object does not move with force, it is not dynamic :param name: author: weiwei date: 20190626, 20201119 """ super().__init__(name) if isinstance(initor, gm.GeometricModel): if initor._objtrm is None: raise ValueError("Only applicable to models with a trimesh!") self.com = initor.objtrm.center_mass * base.physics_scale self.setMass(mass) self.setRestitution(restitution) self.setFriction(friction) self.setLinearDamping(.3) self.setAngularDamping(.3) if allow_deactivation: self.setDeactivationEnabled(True) self.setLinearSleepThreshold(.01 * base.physics_scale) self.setAngularSleepThreshold(.01 * base.physics_scale) else: self.setDeactivationEnabled(False) if allow_ccd: # continuous collision detection self.setCcdMotionThreshold(1e-7) self.setCcdSweptSphereRadius(0.0005 * base.physics_scale) geom_np = initor.objpdnp.getChild(0).find("+GeomNode") geom = copy.deepcopy(geom_np.node().getGeom(0)) vdata = geom.modifyVertexData() vertices = copy.deepcopy( np.frombuffer(vdata.modifyArrayHandle(0).getData(), dtype=np.float32)) vertices.shape = (-1, 6) vertices[:, :3] = vertices[:, :3] * base.physics_scale - self.com vdata.modifyArrayHandle(0).setData( vertices.astype(np.float32).tobytes()) geomtf = geom_np.getTransform() geomtf = geomtf.setPos(geomtf.getPos() * base.physics_scale) if cdtype == "triangles": geombmesh = BulletTriangleMesh() geombmesh.addGeom(geom) bulletshape = BulletTriangleMeshShape(geombmesh, dynamic=dynamic) bulletshape.setMargin(1e-6) self.addShape(bulletshape, geomtf) elif cdtype == "convex": bulletshape = BulletConvexHullShape( ) # TODO: compute a convex hull? bulletshape.addGeom(geom, geomtf) bulletshape.setMargin(1e-6) self.addShape(bulletshape, geomtf) elif cdtype == 'box': minx = min(vertices[:, 0]) miny = min(vertices[:, 1]) minz = min(vertices[:, 2]) maxx = max(vertices[:, 0]) maxy = max(vertices[:, 1]) maxz = max(vertices[:, 2]) pcd_box = CollisionBox(Point3(minx, miny, minz), Point3(maxx, maxy, maxz)) bulletshape = BulletBoxShape.makeFromSolid(pcd_box) bulletshape.setMargin(1e-6) self.addShape(bulletshape, geomtf) else: raise NotImplementedError pd_homomat = geomtf.getMat() pd_com_pos = pd_homomat.xformPoint( Vec3(self.com[0], self.com[1], self.com[2])) np_homomat = dh.pdmat4_to_npmat4(pd_homomat) np_com_pos = dh.pdv3_to_npv3(pd_com_pos) np_homomat[:3, 3] = np_com_pos # update center to com self.setTransform( TransformState.makeMat(dh.npmat4_to_pdmat4(np_homomat))) elif isinstance(initor, BDBody): self.com = initor.com.copy() self.setMass(initor.getMass()) self.setRestitution(initor.restitution) self.setFriction(initor.friction) self.setLinearDamping(.3) self.setAngularDamping(.3) if allow_deactivation: self.setDeactivationEnabled(True) self.setLinearSleepThreshold(.01 * base.physics_scale) self.setAngularSleepThreshold(.01 * base.physics_scale) else: self.setDeactivationEnabled(False) if allow_ccd: self.setCcdMotionThreshold(1e-7) self.setCcdSweptSphereRadius(0.0005 * base.physics_scale) np_homomat = copy.deepcopy(initor.get_homomat()) np_homomat[:3, 3] = np_homomat[:3, 3] * base.physics_scale self.setTransform( TransformState.makeMat(dh.npmat4_to_pdmat4(np_homomat))) self.addShape(initor.getShape(0), initor.getShapeTransform(0))
def make_rigid_transform(rotation, translation): """Return a TransformState comprising the given rotation followed by the given translation""" return TransformState.makeMat(LMatrix4(rotation, translation))
def __init__(self, objinit, cdtype="triangle", mass=.3, restitution=0, allowdeactivation=False, allowccd=True, friction=.2, dynamic=True, name="rbd"): """ :param objinit: could be itself (copy), or an instance of collision model :param type: triangle or convex :param mass: :param restitution: bounce parameter :param friction: :param dynamic: only applicable to triangle type, if an object does not move with force, it is not dynamic :param name: author: weiwei date: 20190626, 20201119 """ super().__init__(name) if isinstance(objinit, gm.GeometricModel): if objinit._objtrm is None: raise ValueError("Only applicable to models with a trimesh!") self.com = objinit.objtrm.center_mass self.setMass(mass) self.setRestitution(restitution) self.setFriction(friction) self.setLinearDamping(.3) self.setAngularDamping(.3) if allowdeactivation: self.setDeactivationEnabled(True) self.setLinearSleepThreshold(0.001) self.setAngularSleepThreshold(0.001) else: self.setDeactivationEnabled(False) if allowccd: # continuous collision detection self.setCcdMotionThreshold(1e-6) self.setCcdSweptSphereRadius(0.0005) gnd = objinit.objpdnp.getChild(0).find("+GeomNode") geom = copy.deepcopy(gnd.node().getGeom(0)) vdata = geom.modifyVertexData() vertrewritter = GeomVertexRewriter(vdata, 'vertex') while not vertrewritter.isAtEnd(): # shift local coordinate to geom to correctly update dynamic changes v = vertrewritter.getData3f() vertrewritter.setData3f(v[0] - self.com[0], v[1] - self.com[1], v[2] - self.com[2]) geomtf = gnd.getTransform() if cdtype is "triangle": geombmesh = BulletTriangleMesh() geombmesh.addGeom(geom) bulletshape = BulletTriangleMeshShape(geombmesh, dynamic=dynamic) bulletshape.setMargin(1e-6) self.addShape(bulletshape, geomtf) elif cdtype is "convex": bulletshape = BulletConvexHullShape() # TODO: compute a convex hull? bulletshape.addGeom(geom, geomtf) bulletshape.setMargin(1e-6) self.addShape(bulletshape, geomtf) else: raise NotImplementedError pdmat4 = geomtf.getMat() pdv3 = pdmat4.xformPoint(Vec3(self.com[0], self.com[1], self.com[2])) homomat = dh.pdmat4_to_npmat4(pdmat4) pos = dh.pdv3_to_npv3(pdv3) homomat[:3, 3] = pos # update center to com self.setTransform(TransformState.makeMat(dh.npmat4_to_pdmat4(homomat))) elif isinstance(objinit, BDBody): self.com = objinit.com.copy() self.setMass(objinit.getMass()) self.setRestitution(objinit.restitution) self.setFriction(objinit.friction) self.setLinearDamping(.3) self.setAngularDamping(.3) if allowdeactivation: self.setDeactivationEnabled(True) self.setLinearSleepThreshold(0.001) self.setAngularSleepThreshold(0.001) else: self.setDeactivationEnabled(False) if allowccd: self.setCcdMotionThreshold(1e-6) self.setCcdSweptSphereRadius(0.0005) self.setTransform(TransformState.makeMat(dh.npmat4_to_pdmat4(objinit.gethomomat()))) self.addShape(objinit.getShape(0), objinit.getShapeTransform(0))