Beispiel #1
0
 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)
Beispiel #2
0
    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"
Beispiel #3
0
    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
Beispiel #4
0
    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))
Beispiel #5
0
    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))
Beispiel #7
0
	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')
Beispiel #9
0
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))
Beispiel #10
0
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
Beispiel #12
0
 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)
Beispiel #14
0
 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)
Beispiel #17
0
 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))
Beispiel #18
0
    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)
Beispiel #20
0
    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
Beispiel #21
0
 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)
Beispiel #22
0
 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)))
Beispiel #23
0
    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
Beispiel #24
0
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
Beispiel #25
0
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
Beispiel #26
0
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))
Beispiel #27
0
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
Beispiel #28
0
        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())
Beispiel #29
0
        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())
Beispiel #30
0
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()
Beispiel #31
0
	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
Beispiel #32
0
    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
Beispiel #33
0
 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))
Beispiel #35
0
 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))