示例#1
0
class Game(DirectObject):
    def __init__(self):
        base.setBackgroundColor(0.1, 0.1, 0.8, 1)
        base.setFrameRateMeter(True)

        base.cam.setPos(0, -40, 10)
        base.cam.lookAt(0, 0, 0)

        # Light
        alight = AmbientLight('ambientLight')
        alight.setColor(Vec4(0.5, 0.5, 0.5, 1))
        alightNP = render.attachNewNode(alight)

        dlight = DirectionalLight('directionalLight')
        dlight.setDirection(Vec3(5, 0, -2))
        dlight.setColor(Vec4(0.7, 0.7, 0.7, 1))
        dlightNP = render.attachNewNode(dlight)

        render.clearLight()
        render.setLight(alightNP)
        render.setLight(dlightNP)

        # Input
        self.accept('escape', self.doExit)
        self.accept('r', self.doReset)
        self.accept('f1', self.toggleWireframe)
        self.accept('f2', self.toggleTexture)
        self.accept('f3', self.toggleDebug)
        self.accept('f5', self.doScreenshot)

        # Task
        taskMgr.add(self.update, 'updateWorld')

        # Physics
        self.setup()

    # _____HANDLER_____

    def doExit(self):
        self.cleanup()
        sys.exit(1)

    def doReset(self):
        self.cleanup()
        self.setup()

    def toggleWireframe(self):
        base.toggleWireframe()

    def toggleTexture(self):
        base.toggleTexture()

    def toggleDebug(self):
        if self.debugNP.isHidden():
            self.debugNP.show()
        else:
            self.debugNP.hide()

    def doScreenshot(self):
        base.screenshot('Bullet')

    # ____TASK___

    def update(self, task):
        dt = globalClock.getDt()

        self.world.doPhysics(dt, 10, 0.004)

        return task.cont

    def cleanup(self):
        self.world = None
        self.worldNP.removeNode()

    def setup(self):
        self.worldNP = render.attachNewNode('World')

        # World
        self.debugNP = self.worldNP.attachNewNode(BulletDebugNode('Debug'))
        self.debugNP.show()

        self.world = BulletWorld()
        self.world.setGravity(Vec3(0, 0, -9.81))
        self.world.setDebugNode(self.debugNP.node())

        # Box
        shape = BulletBoxShape(Vec3(0.5, 0.5, 0.5) * 2.0)

        boxNP = self.worldNP.attachNewNode(BulletRigidBodyNode('Box'))
        boxNP.node().setMass(150.0)
        boxNP.node().addShape(shape)
        boxNP.setPos(0, 0, 2)
        boxNP.setCollideMask(BitMask32.allOn())

        self.world.attachRigidBody(boxNP.node())

        visualNP = loader.loadModel('models/box.egg')
        visualNP.clearModelNodes()
        visualNP.setScale(2.0)
        visualNP.reparentTo(boxNP)

        # Soft body world information
        info = self.world.getWorldInfo()
        info.setAirDensity(1.2)
        info.setWaterDensity(0)
        info.setWaterOffset(0)
        info.setWaterNormal(Vec3(0, 0, 0))

        # Softbody
        nx = 31
        ny = 31

        p00 = Point3(-8, -8, 0)
        p10 = Point3(8, -8, 0)
        p01 = Point3(-8, 8, 0)
        p11 = Point3(8, 8, 0)
        bodyNode = BulletSoftBodyNode.makePatch(info, p00, p10, p01, p11, nx,
                                                ny, 1 + 2 + 4 + 8, True)

        material = bodyNode.appendMaterial()
        material.setLinearStiffness(0.4)
        bodyNode.generateBendingConstraints(2, material)
        bodyNode.setTotalMass(50.0)
        bodyNode.getShape(0).setMargin(0.5)

        bodyNP = self.worldNP.attachNewNode(bodyNode)
        self.world.attachSoftBody(bodyNode)

        # Rendering with Geom:
        fmt = GeomVertexFormat.getV3n3t2()
        geom = BulletHelper.makeGeomFromFaces(bodyNode, fmt, True)
        bodyNode.linkGeom(geom)
        visNode = GeomNode('')
        visNode.addGeom(geom)
        visNP = bodyNP.attachNewNode(visNode)

        # Now we want to have a texture and texture coordinates.
        # The geom's format has already a column for texcoords, so we just need
        # to write texcoords using a GeomVertexRewriter.
        tex = loader.loadTexture('models/panda.jpg')
        visNP.setTexture(tex)
        BulletHelper.makeTexcoordsForPatch(geom, nx, ny)
class Game(DirectObject):

  def __init__(self):
    base.setBackgroundColor(0.1, 0.1, 0.8, 1)
    base.setFrameRateMeter(True)

    base.cam.setPos(0, -60, 20)
    base.cam.lookAt(0, 0, 0)

    # Light
    alight = AmbientLight('ambientLight')
    alight.setColor(Vec4(0.5, 0.5, 0.5, 1))
    alightNP = render.attachNewNode(alight)

    dlight = DirectionalLight('directionalLight')
    dlight.setDirection(Vec3(1, 1, -1))
    dlight.setColor(Vec4(0.7, 0.7, 0.7, 1))
    dlightNP = render.attachNewNode(dlight)

    render.clearLight()
    render.setLight(alightNP)
    render.setLight(dlightNP)

    # Input
    self.accept('escape', self.doExit)
    self.accept('r', self.doReset)
    self.accept('f1', self.toggleWireframe)
    self.accept('f2', self.toggleTexture)
    self.accept('f3', self.toggleDebug)
    self.accept('f5', self.doScreenshot)

    # Task
    taskMgr.add(self.update, 'updateWorld')

    # Physics
    self.setup()

  # _____HANDLER_____

  def doExit(self):
    self.cleanup()
    sys.exit(1)

  def doReset(self):
    self.cleanup()
    self.setup()

  def toggleWireframe(self):
    base.toggleWireframe()

  def toggleTexture(self):
    base.toggleTexture()

  def toggleDebug(self):
    if self.debugNP.isHidden():
      self.debugNP.show()
    else:
      self.debugNP.hide()

  def doScreenshot(self):
    base.screenshot('Bullet')

  # ____TASK___

  def update(self, task):
    dt = globalClock.getDt()

    self.world.doPhysics(dt, 10, 0.008)

    return task.cont

  def cleanup(self):
    self.world = None
    self.worldNP.removeNode()

  def setup(self):
    self.worldNP = render.attachNewNode('World')

    # World
    self.debugNP = self.worldNP.attachNewNode(BulletDebugNode('Debug'))
    self.debugNP.show()

    #self.debugNP.showTightBounds()
    #self.debugNP.showBounds()

    self.world = BulletWorld()
    self.world.setGravity(Vec3(0, 0, -9.81))
    self.world.setDebugNode(self.debugNP.node())

    # Ground
    p0 = Point3(-20, -20, 0)
    p1 = Point3(-20, 20, 0)
    p2 = Point3(20, -20, 0)
    p3 = Point3(20, 20, 0)
    mesh = BulletTriangleMesh()
    mesh.addTriangle(p0, p1, p2)
    mesh.addTriangle(p1, p2, p3)
    shape = BulletTriangleMeshShape(mesh, dynamic=False)

    np = self.worldNP.attachNewNode(BulletRigidBodyNode('Mesh'))
    np.node().addShape(shape)
    np.setPos(0, 0, -2)
    np.setCollideMask(BitMask32.allOn())

    self.world.attachRigidBody(np.node())

    # Stair
    origin = Point3(0, 0, 0)
    size = Vec3(2, 10, 1)
    shape = BulletBoxShape(size * 0.5)
    for i in range(10):
      pos = origin + size * i
      pos.setY(0)

      np = self.worldNP.attachNewNode(BulletRigidBodyNode('Stair%i' % i))
      np.node().addShape(shape)
      np.setPos(pos)
      np.setCollideMask(BitMask32.allOn())

      npV = loader.loadModel('models/box.egg')
      npV.reparentTo(np)
      npV.setScale(size)

      self.world.attachRigidBody(np.node())

    # Soft body world information
    info = self.world.getWorldInfo()
    info.setAirDensity(1.2)
    info.setWaterDensity(0)
    info.setWaterOffset(0)
    info.setWaterNormal(Vec3(0, 0, 0))

    # Softbody
    center = Point3(0, 0, 0)
    radius = Vec3(1, 1, 1) * 1.5
    node = BulletSoftBodyNode.makeEllipsoid(info, center, radius, 128)
    node.setName('Ellipsoid')
    node.getMaterial(0).setLinearStiffness(0.1)
    node.getCfg().setDynamicFrictionCoefficient(1)
    node.getCfg().setDampingCoefficient(0.001)
    node.getCfg().setPressureCoefficient(1500)
    node.setTotalMass(30, True)
    node.setPose(True, False)

    np = self.worldNP.attachNewNode(node)
    np.setPos(15, 0, 12)
    #np.setH(90.0)
    #np.showBounds()
    #np.showTightBounds()
    self.world.attachSoftBody(np.node())

    geom = BulletHelper.makeGeomFromFaces(node)
    node.linkGeom(geom)
    nodeV = GeomNode('EllipsoidVisual')
    nodeV.addGeom(geom)
    npV = np.attachNewNode(nodeV)
示例#3
0
class Game(ShowBase):

  def __init__(self):
    ShowBase.__init__(self)
    base = self
    base.setBackgroundColor(0.1, 0.1, 0.8, 1)
    #base.setFrameRateMeter(True)

    self.mybase = NodePath("MyBase")
    self.mybase.reparentTo(render)

    self.camholder = NodePath("CamHolder")
    self.camholder.reparentTo(render)
    self.camera.reparentTo(self.camholder)

    self.camholder.setPos(0, 0, 90)
    self.camholder.lookAt(0, 0, 0)
    self.camholder.setH(np.random.randint(0,360))

    # Light
    alight = AmbientLight('ambientLight')
    alight.setColor(Vec4(0.6, 0.6, 0.6, 1))
    alightNP = render.attachNewNode(alight)

    dlight = DirectionalLight('directionalLight')
    #dlight.setDirection(Vec3(5, 0, -2))
    dlight.setColor(Vec4(0.7, 0.7, 0.7, 1))
    dlightNP = render.attachNewNode(dlight)
    dlightNP.lookAt(np.random.randint(-15,15), np.random.randint(-15,15), -2)

    render.clearLight()
    render.setLight(alightNP)
    render.setLight(dlightNP)

    # Input
    self.accept('escape', self.doExit)
    self.accept('r', self.doReset)
    self.accept('f1', self.toggleWireframe)
    self.accept('f2', self.toggleTexture)
    self.accept('d', self.toggleDebug)
    self.accept('f5', self.doScreenshot)

    # Task
    taskMgr.add(self.update, 'updateWorld')

    # Physics
    self.setup()

    sky = loader.loadModel('smiley.egg')
    sky.setColor(0,1,0)
    sky.setTwoSided(True)
    sky.reparentTo(self.mybase)
    sky.setScale(100)

    m = Material()
    m.clearDiffuse()
    sky.setMaterial(m)

    self.flowgen = FlowGen()
    self.flowgen.flow_cam.reparentTo(self.camholder)
    setup_flow_shading_on_node(self.mybase)

  # _____HANDLER_____

  def doExit(self):
    self.cleanup()
    sys.exit(1)

  def doReset(self):
    self.cleanup()
    self.setup()

  def toggleWireframe(self):
    base.toggleWireframe()

  def toggleTexture(self):
    base.toggleTexture()

  def toggleDebug(self):
    if self.debugNP.isHidden():
      self.debugNP.show()
    else:
      self.debugNP.hide()

  def doScreenshot(self):
    base.screenshot('Bullet')

  # ____TASK___
  tt = 0

  def update(self, task):
    dt = globalClock.getDt()
    #dt *= 0.01

    self.world.doPhysics(dt, 10, 0.008)

    self.tt += 1
    print self.tt

    if int(self.tt) % 200 == 0:
        gv = Vec3(np.random.randn()*3, np.random.randn()*3, 0)
        print gv
        print base.cam.getPos()
        print base.cam.getHpr()
        self.world.setGravity(gv)

    return task.cont

  def cleanup(self):
    self.world = None
    self.worldNP.removeNode()

  def setup(self):
    self.worldNP = render.attachNewNode('World')

    # World
    self.debugNP = self.worldNP.attachNewNode(BulletDebugNode('Debug'))
    #self.debugNP.show()

    self.world = BulletWorld()
    self.world.setGravity(Vec3(np.random.randn()*3, np.random.randn()*3, 0))
    self.world.setDebugNode(self.debugNP.node())

    # Ground
    p0 = Point3(-20, -20, 0)
    p1 = Point3(-20, 20, 0)
    p2 = Point3(20, -20, 0)
    p3 = Point3(20, 20, 0)
    mesh = BulletTriangleMesh()
    mesh.addTriangle(p0, p1, p2)
    mesh.addTriangle(p1, p2, p3)
    shape = BulletTriangleMeshShape(mesh, dynamic=False)

    npp = self.worldNP.attachNewNode(BulletRigidBodyNode('Mesh'))
    npp.node().addShape(shape)
    npp.setPos(0, 0, -2)
    npp.setCollideMask(BitMask32.allOn())

    self.ground = npp

    self.world.attachRigidBody(npp.node())

    # Soft body world information
    info = self.world.getWorldInfo()
    info.setAirDensity(1.2)
    info.setWaterDensity(0)
    info.setWaterOffset(0)
    info.setWaterNormal(Vec3(0, 0, 0))

    # Softbody
    def makeSB(pos, hpr):
      model = loader.loadModel('moleculemesh/smoothed/clathrinfixsmth%02d.obj' % np.random.randint(1,21))
      geom = model.findAllMatches('**/+GeomNode').getPath(0).node().modifyGeom(0)

      geomNode = GeomNode('')
      geomNode.addGeom(geom)

      node = BulletSoftBodyNode.makeTriMesh(info, geom) 
      node.linkGeom(geomNode.modifyGeom(0))

      node.generateBendingConstraints(2)
      node.getCfg().setPositionsSolverIterations(6)
      node.getCfg().setCollisionFlag(BulletSoftBodyConfig.CFVertexFaceSoftSoft, True)
      node.randomizeConstraints()
      node.setTotalMass(50, True)
      node.getMaterial(0).setLinearStiffness(0.2)
      #node.getCfg().setDynamicFrictionCoefficient(1)
      #node.getCfg().setDampingCoefficient(0.001)
      node.getCfg().setPressureCoefficient(1500)


      softNP = self.worldNP.attachNewNode(node)
      softNP.setPos(pos)
      softNP.setHpr(hpr)
      self.world.attachSoftBody(node)

      geomNP = softNP.attachNewNode(geomNode)

      #softNP.node().appendAnchor(1, self.ground.node())
      softNP.node().appendAnchor(1217, self.ground.node())
      softNP.node().appendAnchor(1157, self.ground.node())
      softNP.node().appendAnchor(2052, self.ground.node())
      #softNP.node().appendAnchor(1800, self.ground.node())
      softNP.reparentTo(self.mybase)

    #makeSB(Point3(-3, 0, 4), (0, 0, 0))
    #makeSB(Point3(0, 0, 4), (0, 90, 90))
    makeSB(Point3(4+np.random.randn(), 2+np.random.randn(), 4), (0, 0, 0))
示例#4
0
class Game(DirectObject):

  def __init__(self):
    base.setBackgroundColor(0.1, 0.1, 0.8, 1)
    base.setFrameRateMeter(True)

    base.cam.setPos(0, -40, 10)
    base.cam.lookAt(0, 0, 0)

    # Light
    alight = AmbientLight('ambientLight')
    alight.setColor(Vec4(0.5, 0.5, 0.5, 1))
    alightNP = render.attachNewNode(alight)

    dlight = DirectionalLight('directionalLight')
    dlight.setDirection(Vec3(5, 0, -2))
    dlight.setColor(Vec4(0.7, 0.7, 0.7, 1))
    dlightNP = render.attachNewNode(dlight)

    render.clearLight()
    render.setLight(alightNP)
    render.setLight(dlightNP)

    # Input
    self.accept('escape', self.doExit)
    self.accept('r', self.doReset)
    self.accept('f1', self.toggleWireframe)
    self.accept('f2', self.toggleTexture)
    self.accept('f3', self.toggleDebug)
    self.accept('f5', self.doScreenshot)

    # Task
    taskMgr.add(self.update, 'updateWorld')

    # Physics
    self.setup()

  # _____HANDLER_____

  def doExit(self):
    self.cleanup()
    sys.exit(1)

  def doReset(self):
    self.cleanup()
    self.setup()

  def toggleWireframe(self):
    base.toggleWireframe()

  def toggleTexture(self):
    base.toggleTexture()

  def toggleDebug(self):
    if self.debugNP.isHidden():
      self.debugNP.show()
    else:
      self.debugNP.hide()

  def doScreenshot(self):
    base.screenshot('Bullet')

  # ____TASK___

  def update(self, task):
    dt = globalClock.getDt()
    #dt *= 0.01

    self.world.doPhysics(dt, 10, 0.008)

    return task.cont

  def cleanup(self):
    self.world = None
    self.worldNP.removeNode()

  def setup(self):
    self.worldNP = render.attachNewNode('World')

    # World
    self.debugNP = self.worldNP.attachNewNode(BulletDebugNode('Debug'))
    self.debugNP.show()

    self.world = BulletWorld()
    self.world.setGravity(Vec3(0, 0, -9.81))
    self.world.setDebugNode(self.debugNP.node())

    # Ground
    p0 = Point3(-20, -20, 0)
    p1 = Point3(-20, 20, 0)
    p2 = Point3(20, -20, 0)
    p3 = Point3(20, 20, 0)
    mesh = BulletTriangleMesh()
    mesh.addTriangle(p0, p1, p2)
    mesh.addTriangle(p1, p2, p3)
    shape = BulletTriangleMeshShape(mesh, dynamic=False)

    np = self.worldNP.attachNewNode(BulletRigidBodyNode('Mesh'))
    np.node().addShape(shape)
    np.setPos(0, 0, -2)
    np.setCollideMask(BitMask32.allOn())

    self.world.attachRigidBody(np.node())

    # Soft body world information
    info = self.world.getWorldInfo()
    info.setAirDensity(1.2)
    info.setWaterDensity(0)
    info.setWaterOffset(0)
    info.setWaterNormal(Vec3(0, 0, 0))

    # Softbody
    def makeSB(pos, hpr):

      import torus
      geom = torus.makeGeom()

      #geom = loader.loadModel('models/torus.egg') \
      #    .findAllMatches('**/+GeomNode').getPath(0).node() \
      #    .modifyGeom(0)

      geomNode = GeomNode('')
      geomNode.addGeom(geom)

      node = BulletSoftBodyNode.makeTriMesh(info, geom) 
      node.linkGeom(geomNode.modifyGeom(0))

      node.generateBendingConstraints(2)
      node.getCfg().setPositionsSolverIterations(2)
      node.getCfg().setCollisionFlag(BulletSoftBodyConfig.CFVertexFaceSoftSoft, True)
      node.randomizeConstraints()
      node.setTotalMass(50, True)

      softNP = self.worldNP.attachNewNode(node)
      softNP.setPos(pos)
      softNP.setHpr(hpr)
      self.world.attachSoftBody(node)

      geomNP = softNP.attachNewNode(geomNode)

    makeSB(Point3(-3, 0, 4), (0, 0, 0))
    makeSB(Point3(0, 0, 4), (0, 90, 90))
    makeSB(Point3(3, 0, 4), (0, 0, 0))
class Game(DirectObject):
    def __init__(self):
        base.setBackgroundColor(0.1, 0.1, 0.8, 1)
        base.setFrameRateMeter(True)

        base.cam.setPos(0, -40, 10)
        base.cam.lookAt(0, 0, 0)

        # Light
        alight = AmbientLight('ambientLight')
        alight.setColor(Vec4(0.5, 0.5, 0.5, 1))
        alightNP = render.attachNewNode(alight)

        dlight = DirectionalLight('directionalLight')
        dlight.setDirection(Vec3(5, 0, -2))
        dlight.setColor(Vec4(0.7, 0.7, 0.7, 1))
        dlightNP = render.attachNewNode(dlight)

        render.clearLight()
        render.setLight(alightNP)
        render.setLight(dlightNP)

        # Input
        self.accept('escape', self.doExit)
        self.accept('r', self.doReset)
        self.accept('f1', self.toggleWireframe)
        self.accept('f2', self.toggleTexture)
        self.accept('f3', self.toggleDebug)
        self.accept('f5', self.doScreenshot)

        # Task
        taskMgr.add(self.update, 'updateWorld')

        # Physics
        self.setup()

    # _____HANDLER_____

    def doExit(self):
        self.cleanup()
        sys.exit(1)

    def doReset(self):
        self.cleanup()
        self.setup()

    def toggleWireframe(self):
        base.toggleWireframe()

    def toggleTexture(self):
        base.toggleTexture()

    def toggleDebug(self):
        if self.debugNP.isHidden():
            self.debugNP.show()
        else:
            self.debugNP.hide()

    def doScreenshot(self):
        base.screenshot('Bullet')

    # ____TASK___

    def update(self, task):
        dt = globalClock.getDt()

        self.world.doPhysics(dt, 10, 0.004)

        return task.cont

    def cleanup(self):
        self.world = None
        self.worldNP.removeNode()

    def setup(self):
        self.worldNP = render.attachNewNode('World')

        # World
        self.debugNP = self.worldNP.attachNewNode(BulletDebugNode('Debug'))
        self.debugNP.show()

        self.world = BulletWorld()
        self.world.setGravity(Vec3(0, 0, -9.81))
        self.world.setDebugNode(self.debugNP.node())

        # Soft body world information
        info = self.world.getWorldInfo()
        info.setAirDensity(1.2)
        info.setWaterDensity(0)
        info.setWaterOffset(0)
        info.setWaterNormal(Vec3(0, 0, 0))

        # Softbody
        def make(p1):
            n = 8
            p2 = p1 + Vec3(10, 0, 0)

            bodyNode = BulletSoftBodyNode.makeRope(info, p1, p2, n, 1)
            bodyNode.setTotalMass(50.0)
            bodyNP = self.worldNP.attachNewNode(bodyNode)
            self.world.attachSoftBody(bodyNode)

            # Render option 1: Line geom
            #geom = BulletSoftBodyNode.makeGeomFromLinks(bodyNode)
            #bodyNode.linkGeom(geom)
            #visNode = GeomNode('')
            #visNode.addGeom(geom)
            #visNP = bodyNP.attachNewNode(visNode)

            # Render option 2: NURBS curve
            curve = NurbsCurveEvaluator()
            curve.reset(n + 2)
            bodyNode.linkCurve(curve)

            visNode = RopeNode('')
            visNode.setCurve(curve)
            visNode.setRenderMode(RopeNode.RMTube)
            visNode.setUvMode(RopeNode.UVParametric)
            visNode.setNumSubdiv(4)
            visNode.setNumSlices(8)
            visNode.setThickness(0.4)
            visNP = self.worldNP.attachNewNode(visNode)
            #visNP = bodyNP.attachNewNode(visNode) # --> renders with offset!!!
            visNP.setTexture(loader.loadTexture('models/iron.jpg'))

            #bodyNP.showBounds()
            #visNP.showBounds()

            return bodyNP

        np1 = make(Point3(-2, -1, 8))
        np2 = make(Point3(-2, 1, 8))

        # Box
        shape = BulletBoxShape(Vec3(2, 2, 6))

        boxNP = self.worldNP.attachNewNode(BulletRigidBodyNode('Box'))
        boxNP.node().setMass(50.0)
        boxNP.node().addShape(shape)
        boxNP.setPos(10, 0, 8)
        boxNP.setCollideMask(BitMask32.allOn())

        self.world.attachRigidBody(boxNP.node())

        np1.node().appendAnchor(np1.node().getNumNodes() - 1, boxNP.node())
        np2.node().appendAnchor(np1.node().getNumNodes() - 1, boxNP.node())

        visNP = loader.loadModel('models/box.egg')
        visNP.clearModelNodes()
        visNP.setScale(4, 4, 12)
        visNP.reparentTo(boxNP)
示例#6
0
class Game(DirectObject):

  def __init__(self):
    base.setBackgroundColor(0.1, 0.1, 0.8, 1)
    base.setFrameRateMeter(True)

    base.cam.setPos(0, -40, 10)
    base.cam.lookAt(0, 0, 0)

    # Light
    alight = AmbientLight('ambientLight')
    alight.setColor(Vec4(0.5, 0.5, 0.5, 1))
    alightNP = render.attachNewNode(alight)

    dlight = DirectionalLight('directionalLight')
    dlight.setDirection(Vec3(5, 0, -2))
    dlight.setColor(Vec4(0.7, 0.7, 0.7, 1))
    dlightNP = render.attachNewNode(dlight)

    render.clearLight()
    render.setLight(alightNP)
    render.setLight(dlightNP)

    # Input
    self.accept('escape', self.doExit)
    self.accept('r', self.doReset)
    self.accept('f1', self.toggleWireframe)
    self.accept('f2', self.toggleTexture)
    self.accept('f3', self.toggleDebug)
    self.accept('f5', self.doScreenshot)

    # Task
    taskMgr.add(self.update, 'updateWorld')

    # Physics
    self.setup()

  # _____HANDLER_____

  def doExit(self):
    self.cleanup()
    sys.exit(1)

  def doReset(self):
    self.cleanup()
    self.setup()

  def toggleWireframe(self):
    base.toggleWireframe()

  def toggleTexture(self):
    base.toggleTexture()

  def toggleDebug(self):
    if self.debugNP.isHidden():
      self.debugNP.show()
    else:
      self.debugNP.hide()

  def doScreenshot(self):
    base.screenshot('Bullet')

  # ____TASK___

  def update(self, task):
    dt = globalClock.getDt()

    self.world.doPhysics(dt, 10, 0.004)

    return task.cont

  def cleanup(self):
    self.world = None
    self.worldNP.removeNode()

  def setup(self):
    self.worldNP = render.attachNewNode('World')

    # World
    self.debugNP = self.worldNP.attachNewNode(BulletDebugNode('Debug'))
    self.debugNP.show()

    self.world = BulletWorld()
    self.world.setGravity(Vec3(0, 0, -9.81))
    self.world.setDebugNode(self.debugNP.node())

    # Soft body world information
    info = self.world.getWorldInfo()
    info.setAirDensity(1.2)
    info.setWaterDensity(0)
    info.setWaterOffset(0)
    info.setWaterNormal(Vec3(0, 0, 0))

    # Softbody
    def make(p1):
      n = 8
      p2 = p1 + Vec3(10, 0, 0)

      bodyNode = BulletSoftBodyNode.makeRope(info, p1, p2, n, 1) 
      bodyNode.setTotalMass(50.0)
      bodyNP = self.worldNP.attachNewNode(bodyNode)
      self.world.attachSoftBody(bodyNode)

      # Render option 1: Line geom
      #geom = BulletSoftBodyNode.makeGeomFromLinks(bodyNode)
      #bodyNode.linkGeom(geom)
      #visNode = GeomNode('')
      #visNode.addGeom(geom)
      #visNP = bodyNP.attachNewNode(visNode)

      # Render option 2: NURBS curve
      curve = NurbsCurveEvaluator()
      curve.reset(n + 2)
      bodyNode.linkCurve(curve)

      visNode = RopeNode('')
      visNode.setCurve(curve)
      visNode.setRenderMode(RopeNode.RMTube)
      visNode.setUvMode(RopeNode.UVParametric)
      visNode.setNumSubdiv(4)
      visNode.setNumSlices(8)
      visNode.setThickness(0.4)
      visNP = self.worldNP.attachNewNode(visNode)
      #visNP = bodyNP.attachNewNode(visNode) # --> renders with offset!!!
      visNP.setTexture(loader.loadTexture('models/iron.jpg'))

      #bodyNP.showBounds()
      #visNP.showBounds()

      return bodyNP

    np1 = make(Point3(-2, -1, 8))
    np2 = make(Point3(-2,  1, 8))

    # Box
    shape = BulletBoxShape(Vec3(2, 2, 6))

    boxNP = self.worldNP.attachNewNode(BulletRigidBodyNode('Box'))
    boxNP.node().setMass(50.0)
    boxNP.node().addShape(shape)
    boxNP.setPos(10, 0, 8)
    boxNP.setCollideMask(BitMask32.allOn())

    self.world.attachRigidBody(boxNP.node())

    np1.node().appendAnchor(np1.node().getNumNodes() - 1, boxNP.node())
    np2.node().appendAnchor(np1.node().getNumNodes() - 1, boxNP.node())

    visNP = loader.loadModel('models/box.egg')
    visNP.clearModelNodes()
    visNP.setScale(4, 4, 12)
    visNP.reparentTo(boxNP)
示例#7
0
class Game(DirectObject):
    def __init__(self):
        base.setBackgroundColor(0.1, 0.1, 0.8, 1)
        base.setFrameRateMeter(True)

        base.cam.setPos(0, -40, 10)
        base.cam.lookAt(0, 0, 0)

        # Light
        alight = AmbientLight('ambientLight')
        alight.setColor(Vec4(0.5, 0.5, 0.5, 1))
        alightNP = render.attachNewNode(alight)

        dlight = DirectionalLight('directionalLight')
        dlight.setDirection(Vec3(5, 0, -2))
        dlight.setColor(Vec4(0.7, 0.7, 0.7, 1))
        dlightNP = render.attachNewNode(dlight)

        render.clearLight()
        render.setLight(alightNP)
        render.setLight(dlightNP)

        # Input
        self.accept('escape', self.doExit)
        self.accept('r', self.doReset)
        self.accept('f1', self.toggleWireframe)
        self.accept('f2', self.toggleTexture)
        self.accept('f3', self.toggleDebug)
        self.accept('f5', self.doScreenshot)

        # Task
        taskMgr.add(self.update, 'updateWorld')

        # Physics
        self.setup()

    # _____HANDLER_____

    def doExit(self):
        self.cleanup()
        sys.exit(1)

    def doReset(self):
        self.cleanup()
        self.setup()

    def toggleWireframe(self):
        base.toggleWireframe()

    def toggleTexture(self):
        base.toggleTexture()

    def toggleDebug(self):
        if self.debugNP.isHidden():
            self.debugNP.show()
        else:
            self.debugNP.hide()

    def doScreenshot(self):
        base.screenshot('Bullet')

    # ____TASK___

    def update(self, task):
        dt = globalClock.getDt()
        #dt *= 0.01

        self.world.doPhysics(dt, 10, 0.008)

        return task.cont

    def cleanup(self):
        self.world = None
        self.worldNP.removeNode()

    def setup(self):
        self.worldNP = render.attachNewNode('World')

        # World
        self.debugNP = self.worldNP.attachNewNode(BulletDebugNode('Debug'))
        self.debugNP.show()

        self.world = BulletWorld()
        self.world.setGravity(Vec3(0, 0, -9.81))
        self.world.setDebugNode(self.debugNP.node())

        # Ground
        p0 = Point3(-20, -20, 0)
        p1 = Point3(-20, 20, 0)
        p2 = Point3(20, -20, 0)
        p3 = Point3(20, 20, 0)
        mesh = BulletTriangleMesh()
        mesh.addTriangle(p0, p1, p2)
        mesh.addTriangle(p1, p2, p3)
        shape = BulletTriangleMeshShape(mesh, dynamic=False)

        np = self.worldNP.attachNewNode(BulletRigidBodyNode('Mesh'))
        np.node().addShape(shape)
        np.setPos(0, 0, -2)
        np.setCollideMask(BitMask32.allOn())

        self.world.attachRigidBody(np.node())

        # Soft body world information
        info = self.world.getWorldInfo()
        info.setAirDensity(1.2)
        info.setWaterDensity(0)
        info.setWaterOffset(0)
        info.setWaterNormal(Vec3(0, 0, 0))

        # Softbody
        def makeSB(pos, hpr):

            import torus
            geom = torus.makeGeom()

            #geom = loader.loadModel('models/torus.egg') \
            #    .findAllMatches('**/+GeomNode').getPath(0).node() \
            #    .modifyGeom(0)

            geomNode = GeomNode('')
            geomNode.addGeom(geom)

            node = BulletSoftBodyNode.makeTriMesh(info, geom)
            node.linkGeom(geomNode.modifyGeom(0))

            node.generateBendingConstraints(2)
            node.getCfg().setPositionsSolverIterations(2)
            node.getCfg().setCollisionFlag(
                BulletSoftBodyConfig.CFVertexFaceSoftSoft, True)
            node.randomizeConstraints()
            node.setTotalMass(50, True)

            softNP = self.worldNP.attachNewNode(node)
            softNP.setPos(pos)
            softNP.setHpr(hpr)
            self.world.attachSoftBody(node)

            geomNP = softNP.attachNewNode(geomNode)

        makeSB(Point3(-3, 0, 4), (0, 0, 0))
        makeSB(Point3(0, 0, 4), (0, 90, 90))
        makeSB(Point3(3, 0, 4), (0, 0, 0))
示例#8
0
class Game(DirectObject):

  def __init__(self):
    base.setBackgroundColor(0.1, 0.1, 0.8, 1)
    base.setFrameRateMeter(True)

    base.cam.setPos(0, -80, 40)
    base.cam.lookAt(0, 0, 10)

    # Light
    alight = AmbientLight('ambientLight')
    alight.setColor(Vec4(0.5, 0.5, 0.5, 1))
    alightNP = render.attachNewNode(alight)

    dlight = DirectionalLight('directionalLight')
    dlight.setDirection(Vec3(0, 0, -1))
    dlight.setColor(Vec4(0.7, 0.7, 0.7, 1))
    dlightNP = render.attachNewNode(dlight)

    render.clearLight()
    render.setLight(alightNP)
    render.setLight(dlightNP)

    # Input
    self.accept('escape', self.doExit)
    self.accept('r', self.doReset)
    self.accept('f1', self.toggleWireframe)
    self.accept('f2', self.toggleTexture)
    self.accept('f3', self.toggleDebug)
    self.accept('f5', self.doScreenshot)

    # Task
    taskMgr.add(self.update, 'updateWorld')

    # Physics
    self.setup()

  # _____HANDLER_____

  def doExit(self):
    self.cleanup()
    sys.exit(1)

  def doReset(self):
    self.cleanup()
    self.setup()

  def toggleWireframe(self):
    base.toggleWireframe()

  def toggleTexture(self):
    base.toggleTexture()

  def toggleDebug(self):
    if self.debugNP.isHidden():
      self.debugNP.show()
    else:
      self.debugNP.hide()

  def doScreenshot(self):
    base.screenshot('Bullet')

  # ____TASK___

  def update(self, task):
    dt = globalClock.getDt()

    self.world.doPhysics(dt, 10, 0.008)

    return task.cont

  def cleanup(self):
    self.world = None
    self.worldNP.removeNode()

  @staticmethod
  def Vec3Rand():
    x = 2 * random.random() - 1
    y = 2 * random.random() - 1
    z = 2 * random.random() - 1
    return Vec3(x, y, z)

  def setup(self):
    self.worldNP = render.attachNewNode('World')

    # World
    self.debugNP = self.worldNP.attachNewNode(BulletDebugNode('Debug'))
    self.debugNP.show()

    self.world = BulletWorld()
    self.world.setGravity(Vec3(0, 0, -9.81))
    self.world.setDebugNode(self.debugNP.node())

    # Ground
    p0 = Point3(-20, -20, 0)
    p1 = Point3(-20, 20, 0)
    p2 = Point3(20, -20, 0)
    p3 = Point3(20, 20, 0)
    mesh = BulletTriangleMesh()
    mesh.addTriangle(p0, p1, p2)
    mesh.addTriangle(p1, p2, p3)
    shape = BulletTriangleMeshShape(mesh, dynamic=False)

    np = self.worldNP.attachNewNode(BulletRigidBodyNode('Mesh'))
    np.node().addShape(shape)
    np.setPos(0, 0, -2)
    np.setCollideMask(BitMask32.allOn())

    self.world.attachRigidBody(np.node())

    # Soft body world information
    info = self.world.getWorldInfo()
    info.setAirDensity(1.2)
    info.setWaterDensity(0)
    info.setWaterOffset(0)
    info.setWaterNormal(Vec3(0, 0, 0))

    # Softbody
    for i in range(50):
      p00 = Point3(-2, -2, 0)
      p10 = Point3( 2, -2, 0)
      p01 = Point3(-2,  2, 0)
      p11 = Point3( 2,  2, 0)
      node = BulletSoftBodyNode.makePatch(info, p00, p10, p01, p11, 6, 6, 0, True)
      node.generateBendingConstraints(2)
      node.getCfg().setLiftCoefficient(0.004)
      node.getCfg().setDynamicFrictionCoefficient(0.0003)
      node.getCfg().setAeroModel(BulletSoftBodyConfig.AMVertexTwoSided)
      node.setTotalMass(0.1)
      node.addForce(Vec3(0, 2, 0), 0)

      np = self.worldNP.attachNewNode(node)
      np.setPos(self.Vec3Rand() * 10 + Vec3(0, 0, 20))
      np.setHpr(self.Vec3Rand() * 16)
      self.world.attachSoftBody(node)

      fmt = GeomVertexFormat.getV3n3t2()
      geom = BulletHelper.makeGeomFromFaces(node, fmt, True)
      node.linkGeom(geom)
      nodeV = GeomNode('')
      nodeV.addGeom(geom)
      npV = np.attachNewNode(nodeV)
class Game(DirectObject):

  def __init__(self):
    base.setBackgroundColor(0.1, 0.1, 0.8, 1)
    base.setFrameRateMeter(True)

    base.cam.setPos(0, -40, 10)
    base.cam.lookAt(0, 0, 0)

    # Light
    alight = AmbientLight('ambientLight')
    alight.setColor(Vec4(0.5, 0.5, 0.5, 1))
    alightNP = render.attachNewNode(alight)

    dlight = DirectionalLight('directionalLight')
    dlight.setDirection(Vec3(5, 0, -2))
    dlight.setColor(Vec4(0.7, 0.7, 0.7, 1))
    dlightNP = render.attachNewNode(dlight)

    render.clearLight()
    render.setLight(alightNP)
    render.setLight(dlightNP)

    # Input
    self.accept('escape', self.doExit)
    self.accept('r', self.doReset)
    self.accept('f1', self.toggleWireframe)
    self.accept('f2', self.toggleTexture)
    self.accept('f3', self.toggleDebug)
    self.accept('f5', self.doScreenshot)

    # Task
    taskMgr.add(self.update, 'updateWorld')

    # Physics
    self.setup()

  # _____HANDLER_____

  def doExit(self):
    self.cleanup()
    sys.exit(1)

  def doReset(self):
    self.cleanup()
    self.setup()

  def toggleWireframe(self):
    base.toggleWireframe()

  def toggleTexture(self):
    base.toggleTexture()

  def toggleDebug(self):
    if self.debugNP.isHidden():
      self.debugNP.show()
    else:
      self.debugNP.hide()

  def doScreenshot(self):
    base.screenshot('Bullet')

  # ____TASK___

  def update(self, task):
    dt = globalClock.getDt()

    self.world.doPhysics(dt, 10, 0.008)

    return task.cont

  def cleanup(self):
    self.world = None
    self.worldNP.removeNode()

  def setup(self):
    self.worldNP = render.attachNewNode('World')

    # World
    self.debugNP = self.worldNP.attachNewNode(BulletDebugNode('Debug'))
    self.debugNP.show()

    self.world = BulletWorld()
    self.world.setGravity(Vec3(0, 0, -9.81))
    self.world.setDebugNode(self.debugNP.node())

    # Ground
    p0 = Point3(-20, -20, 0)
    p1 = Point3(-20, 20, 0)
    p2 = Point3(20, -20, 0)
    p3 = Point3(20, 20, 0)
    mesh = BulletTriangleMesh()
    mesh.addTriangle(p0, p1, p2)
    mesh.addTriangle(p1, p2, p3)
    shape = BulletTriangleMeshShape(mesh, dynamic=False)

    np = self.worldNP.attachNewNode(BulletRigidBodyNode('Mesh'))
    np.node().addShape(shape)
    np.setPos(0, 0, -4)
    np.setCollideMask(BitMask32.allOn())

    self.world.attachRigidBody(np.node())

    # Soft body world information
    info = self.world.getWorldInfo()
    info.setAirDensity(1.2)
    info.setWaterDensity(0)
    info.setWaterOffset(0)
    info.setWaterNormal(Vec3(0, 0, 0))

    # Softbody - From points/indices
    #import cube
    #points = [Point3(x,y,z) * 3 for x,y,z in cube.nodes]
    #indices = sum([list(x) for x in cube.elements], [])

    #node = BulletSoftBodyNode.makeTetMesh(info, points, indices, True)
    #node.setVolumeMass(300);
    #node.getShape(0).setMargin(0.01)
    #node.getMaterial(0).setLinearStiffness(0.8)
    #node.getCfg().setPositionsSolverIterations(1)
    #node.getCfg().clearAllCollisionFlags()
    #node.getCfg().setCollisionFlag(BulletSoftBodyConfig.CFClusterSoftSoft, True)
    #node.getCfg().setCollisionFlag(BulletSoftBodyConfig.CFClusterRigidSoft, True)
    #node.generateClusters(16)

    #softNP = self.worldNP.attachNewNode(node)
    #softNP.setPos(0, 0, 8)
    #softNP.setHpr(0, 0, 45)
    #self.world.attachSoftBody(node)

    # Softbody - From tetgen data
    ele = file('models/cube/cube.1.ele', 'r').read()
    face = file('models/cube/cube.1.face', 'r').read()
    node = file('models/cube/cube.1.node', 'r').read()

    node = BulletSoftBodyNode.makeTetMesh(info, ele, face, node)
    node.setName('Tetra')
    node.setVolumeMass(300)
    node.getShape(0).setMargin(0.01)
    node.getMaterial(0).setLinearStiffness(0.1)
    node.getCfg().setPositionsSolverIterations(1)
    node.getCfg().clearAllCollisionFlags()
    node.getCfg().setCollisionFlag(BulletSoftBodyConfig.CFClusterSoftSoft, True)
    node.getCfg().setCollisionFlag(BulletSoftBodyConfig.CFClusterRigidSoft, True)
    node.generateClusters(6)

    softNP = self.worldNP.attachNewNode(node)
    softNP.setPos(0, 0, 8)
    softNP.setHpr(45, 0, 0)
    self.world.attachSoftBody(node)

    # Option 1:
    visNP = loader.loadModel('models/cube/cube.egg')
    visNP.reparentTo(softNP)

    geom = visNP \
        .findAllMatches('**/+GeomNode').getPath(0).node() \
        .modifyGeom(0)
    node.linkGeom(geom)
示例#10
0
class PandaUtil:
    def __init__(self,*args,**kw):
        self.solver="bullet"
        if "solver" in kw :
            self.solver = kw["solver"]
        self.rb_func_dic={"bullet":{
            "SingleSphere":self.addSingleSphereRB,
            "SingleCube":self.addSingleCubeRB,
            "MultiSphere":self.addMultiSphereRB,
            "MultiCylinder":self.addMultiCylinderRB,
            "Mesh":self.addMeshRB,
            },
            "ode":{
            "SingleSphere":self.addSingleSphereRBODE,
#            "SingleCube":self.addSingleCubeRBODE,
#            "MultiSphere":self.addMultiSphereRBODE,
#            "MultiCylinder":self.addMultiCylinderRBODE,
#            "Mesh":self.addMeshRBODE,
            },
            }
    def setup(self):
        if self.solver == "bullet":
            self.setupPanda()
        elif self.solver == "ode" :
            self.setupODE()

    def setupODE(self,*args,**kw):
        if self.world is None :
            if panda3d is None :
                return
            from panda3d.core import loadPrcFileData            
            loadPrcFileData("", "window-type none" ) 
            # Make sure we don't need a graphics engine 
            #(Will also prevent X errors / Display errors when starting on linux without X server)
            loadPrcFileData("", "audio-library-name null" ) # Prevent ALSA errors 
#            loadPrcFileData('', 'bullet-enable-contact-events true')
#            loadPrcFileData('', 'bullet-max-objects 50')#10240
            
            import direct.directbase.DirectStart 
#            bullet.bullet-max-objects = 1024 * 10#sum of all predicted n Ingredient ?
#            self.worldNP = render.attachNewNode('World')            
            self.world = OdeWorld()
            self.world.setGravity(Vec3(0, 0, 0))
            self.static=[]
            self.moving = None
            self.rb_panda = []
            return self.world

    def addSingleSphereRBODE()  :
        pass          
    def setupPanda(self,*args,**kw):
        if panda3d is None :
            return
        from panda3d.core import loadPrcFileData
        
        loadPrcFileData("", "window-type none" ) 
        # Make sure we don't need a graphics engine 
        #(Will also prevent X errors / Display errors when starting on linux without X server)
        loadPrcFileData("", "audio-library-name null" ) # Prevent ALSA errors 
        loadPrcFileData('', 'bullet-max-objects 100240')#what number here ?
        import direct.directbase.DirectStart
        self.scale  = 10.0   
        self.worldNP = render.attachNewNode('World')            
        self.world = BulletWorld()
        if "gravity" in kw and kw["gravity"]:
            self.world.setGravity(Vec3(0, -9.81, 0))
        else :
            self.world.setGravity(Vec3(0, 0, 0))
        self.static=[]
        self.moving = None
        self.rb_panda = []

    def delRB(self, node):
        if panda3d is None :
                return
        self.world.removeRigidBody(node)
        if node in self.rb_panda: self.rb_panda.pop(self.rb_panda.index(node))
        if node in self.static: self.static.pop(self.static.index(node))
        if node == self.moving: self.moving = None
        np = NodePath(node)
        np.removeNode()

    def setRB(self,inodenp,**kw):
        if "adamping" in kw :
            inodenp.node().setAngularDamping(kw["adamping"])
        if "ldamping" in kw :
            inodenp.node().setLinearDamping(kw["ldamping"])
        if "mass" in kw :
            inodenp.node().setMass(kw["mass"])
        if "pos" in kw :
            inodenp.setPos(kw["pos"][0],kw["pos"][1],kw["pos"][2])

    def addSinglePlaneRB(self,up,const,**kw):
        pup = Vec3(up[0],up[1],up[2])
        shape = BulletPlaneShape(pup,const)#nomal and constant
        name = "plane"
        if "name" in kw :
            name = kw["name"]
        inodenp = self.worldNP.attachNewNode(BulletRigidBodyNode(name))
#        inodenp.node().setMass(1.0)
#        inodenp.node().addShape(shape)
        inodenp.node().addShape(shape)#rotation ?      ,TransformState.makePos(Point3(0, 0, 0))  
#        spherenp.setPos(-2, 0, 4)
        self.setRB(inodenp,**kw)
        inodenp.setCollideMask(BitMask32.allOn())    
        self.world.attachRigidBody(inodenp.node())
        return inodenp

    def addSingleSphereRB(self,rad,**kw):
        shape = BulletSphereShape(rad)
        name = "sphere"
        if "name" in kw :
            name = kw["name"]
        inodenp = self.worldNP.attachNewNode(BulletRigidBodyNode(name))
        inodenp.node().setMass(1.0)
#        inodenp.node().addShape(shape)
        inodenp.node().addShape(shape,TransformState.makePos(Point3(0, 0, 0)))#rotation ?
#        spherenp.setPos(-2, 0, 4)
        self.setRB(inodenp,**kw)
        inodenp.setCollideMask(BitMask32.allOn())    
        self.world.attachRigidBody(inodenp.node())
        return inodenp
        
    def addMultiSphereRB(self,rads,centT,**kw):
        inodenp = self.worldNP.attachNewNode(BulletRigidBodyNode("Sphere"))
        inodenp.node().setMass(1.0)
        for radc, posc in zip(rads, centT):
            shape = BulletSphereShape(radc)#if radis the same can use the same shape for each node
            inodenp.node().addShape(shape, TransformState.makePos(Point3(posc[0],posc[1],posc[2])))#
        self.setRB(inodenp,**kw)
        inodenp.setCollideMask(BitMask32.allOn())    
        self.world.attachRigidBody(inodenp.node())
        return inodenp

    def addMultiSphereGhost(self,rads,centT,**kw):
        inodenp = self.worldNP.attachNewNode(BulletGhostNode("Sphere"))
        for radc, posc in zip(rads, centT):
            shape = BulletSphereShape(radc)
            inodenp.node().addShape(shape, TransformState.makePos(Point3(posc[0],posc[1],posc[2])))#
        self.setRB(inodenp,**kw)
        inodenp.setCollideMask(BitMask32.allOn())    
        self.world.attachRigidBody(inodenp.node())
        return inodenp     
        
    def addSingleCubeRB(self,halfextents,**kw):
        shape = BulletBoxShape(Vec3(halfextents[0], halfextents[1], halfextents[2]))#halfExtents
        inodenp = self.worldNP.attachNewNode(BulletRigidBodyNode("Box"))
#        inodenp.node().setMass(1.0)
#        inodenp.node().addShape(shape)
        inodenp.node().addShape(shape,TransformState.makePos(Point3(0, 0, 0)))#, pMat)#TransformState.makePos(Point3(jtrans[0],jtrans[1],jtrans[2])))#rotation ?
#        spherenp.setPos(-2, 0, 4)
        self.setRB(inodenp,**kw)
        inodenp.setCollideMask(BitMask32.allOn())    
        self.world.attachRigidBody(inodenp.node())
        return inodenp
        
    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 setGeomFaces(self,tris,face):                
        #have to add vertices one by one since they are not in order
        if len(face) == 2 :
            face = numpy.array([face[0],face[1],face[1],face[1]],dtype='int')
        for i in face :        
            tris.addVertex(i)
        tris.closePrimitive()

    def addMeshRB(self,vertices, faces,ghost=False,**kw):
        #step 1) create GeomVertexData and add vertex information
        format=GeomVertexFormat.getV3()
        vdata=GeomVertexData("vertices", format, Geom.UHStatic)
        
        vertexWriter=GeomVertexWriter(vdata, "vertex")
        [vertexWriter.addData3f(v[0],v[1],v[2]) for v in vertices]
        
        #step 2) make primitives and assign vertices to them
        tris=GeomTriangles(Geom.UHStatic)
        [self.setGeomFaces(tris,face) for face in faces]
        
        #step 3) make a Geom object to hold the primitives
        geom=Geom(vdata)
        geom.addPrimitive(tris)
        
        #step 4) create the bullet mesh and node
        mesh = BulletTriangleMesh()
        mesh.addGeom(geom)

        shape = BulletTriangleMeshShape(mesh, dynamic=not ghost)#BulletConvexHullShape
        if ghost :
            inodenp = self.worldNP.attachNewNode(BulletGhostNode('Mesh'))
        else :
            inodenp = self.worldNP.attachNewNode(BulletRigidBodyNode('Mesh'))
        inodenp.node().addShape(shape)
#        inodenp.setPos(0, 0, 0.1)
        self.setRB(inodenp,**kw)
        inodenp.setCollideMask(BitMask32.allOn())
   
        self.world.attachRigidBody(inodenp.node())
        return inodenp

    def addMeshConvexRB(self,vertices, faces,ghost=False,**kw):
        #step 1) create GeomVertexData and add vertex information
        format=GeomVertexFormat.getV3()
        vdata=GeomVertexData("vertices", format, Geom.UHStatic)
        
        vertexWriter=GeomVertexWriter(vdata, "vertex")
        [vertexWriter.addData3f(v[0],v[1],v[2]) for v in vertices]
        
        #step 2) make primitives and assign vertices to them
        tris=GeomTriangles(Geom.UHStatic)
        [self.setGeomFaces(tris,face) for face in faces]
        
        #step 3) make a Geom object to hold the primitives
        geom=Geom(vdata)
        geom.addPrimitive(tris)
        
        #step 4) create the bullet mesh and node
        mesh = BulletTriangleMesh()
        mesh.addGeom(geom)

        shape = BulletConvexHullShape(mesh, dynamic=not ghost)#
        if ghost :
            inodenp = self.worldNP.attachNewNode(BulletGhostNode('Mesh'))
        else :
            inodenp = self.worldNP.attachNewNode(BulletRigidBodyNode('Mesh'))
        inodenp.node().addShape(shape)
#        inodenp.setPos(0, 0, 0.1)
        self.setRB(inodenp,**kw)
        inodenp.setCollideMask(BitMask32.allOn())
   
        self.world.attachRigidBody(inodenp.node())
        return inodenp
        
    def addTriMeshSB(self,vertices, faces,normals = None,ghost=False,**kw):
        #step 1) create GeomVertexData and add vertex information
        # Soft body world information
        info = self.world.getWorldInfo()
        info.setAirDensity(0.0)
        info.setWaterDensity(0)
        info.setWaterOffset(0)
        info.setWaterNormal(Vec3(0, 0, 0))
        
        format=GeomVertexFormat.getV3n3() #getV3()#http://www.panda3d.org/manual/index.php/Pre-defined_vertex_formats
#        vdata = GeomVertexData('name', format, Geom.UHStatic)
        vdata=GeomVertexData("Mesh", format, Geom.UHStatic)
        
        vertexWriter=GeomVertexWriter(vdata, "vertex")
        [vertexWriter.addData3f(v[0],v[1],v[2]) for v in vertices]

        if normals is not None :
            normalWriter = GeomVertexWriter(vdata, 'normal')
            [normalWriter.addData3f(n[0],n[1],n[2]) for n in normals] 
        else :
            print "we need normals to bind geom to SoftBody"
            return None
        
        #step 2) make primitives and assign vertices to them
        tris=GeomTriangles(Geom.UHStatic)
        [self.setGeomFaces(tris,face) for face in faces]
        
        #step 3) make a Geom object to hold the primitives
        geom=Geom(vdata)
        geom.addPrimitive(tris)
        
        vdata = geom.getVertexData()
#        print (vdata,vdata.hasColumn(InternalName.getVertex()))
        geomNode = GeomNode('')
        geomNode.addGeom(geom)

        #step 4) create the bullet softbody and node
        bodyNode = BulletSoftBodyNode.makeTriMesh(info, geom)
#        bodyNode.linkGeom(geomNode.modifyGeom(0))
        bodyNode.setName('Tri')
        bodyNode.linkGeom(geom)  
        bodyNode.generateBendingConstraints(1)#???
        #bodyNode.getMaterial(0).setLinearStiffness(0.8)
        bodyNode.getCfg().setPositionsSolverIterations(4)
#        bodyNode.getCfg().setCollisionFlag(BulletSoftBodyConfig.CFVertexFaceSoftSoft, True)
        bodyNode.getCfg().setDynamicFrictionCoefficient(1)
        bodyNode.getCfg().setDampingCoefficient(0.001)
        bodyNode.getCfg().setPressureCoefficient(15000*10.0)  
        bodyNode.getCfg().setPoseMatchingCoefficient(0.2)
        bodyNode.setPose(True, True)
#        bodyNode.randomizeConstraints()
        bodyNode.setTotalMass(50000*10, True)
        
        bodyNP = self.worldNP.attachNewNode(bodyNode)
#        fmt = GeomVertexFormat.getV3n3t2()
#        geom = BulletHelper.makeGeomFromFaces(bodyNode, fmt,True)

#        bodyNode.linkGeom(geomNode.modifyGeom(0))
#        geomNode = GeomNode('')
#        geomNode.addGeom(geom)
        
#        world.attachSoftBody(bodyNode)
#        inodenp.setPos(0, 0, 0.1)
#        self.setRB(bodyNP,**kw)#set po
#        inodenp.setCollideMask(BitMask32.allOn())
        self.world.attachSoftBody(bodyNode)
        geomNP = bodyNP.attachNewNode(geomNode)
        return bodyNP,geomNP

    def addTetraMeshSB(self,vertices, faces,normals = None,ghost=False,**kw):
        #step 1) create GeomVertexData and add vertex information
        # Soft body world information
        info = self.world.getWorldInfo()
        info.setAirDensity(1.2)
        info.setWaterDensity(0)
        info.setWaterOffset(0)
        info.setWaterNormal(Vec3(0, 0, 0))
    
        points = [Point3(x,y,z) * 3 for x,y,z in vertices]
        indices = sum([list(x) for x in faces], [])
        #step 4) create the bullet softbody and node
        bodyNode = BulletSoftBodyNode.makeTetMesh(info, points, indices, True)

        bodyNode.setName('Tetra')
        bodyNode.setVolumeMass(150000)
        bodyNode.getShape(0).setMargin(0.01)
        bodyNode.getMaterial(0).setLinearStiffness(0.9)
        bodyNode.getCfg().setPositionsSolverIterations(4)
        bodyNode.getCfg().clearAllCollisionFlags()
        bodyNode.getCfg().setCollisionFlag(BulletSoftBodyConfig.CFClusterSoftSoft, True)
        bodyNode.getCfg().setCollisionFlag(BulletSoftBodyConfig.CFClusterRigidSoft, True)
        bodyNode.generateClusters(12)
        bodyNode.setPose(True, True)
        bodyNP = self.worldNP.attachNewNode(bodyNode)
        
        geom = BulletHelper.makeGeomFromFaces(bodyNode)
        geomNode = GeomNode('vtetra')
        geomNode.addGeom(geom)
        
#        self.setRB(bodyNP,**kw)#set po
#        inodenp.setCollideMask(BitMask32.allOn())
        self.world.attachSoftBody(bodyNode)
        geomNP = bodyNP.attachNewNode(geomNode)
        bodyNode.linkGeom(geom)
        return bodyNP,geomNP

    def getVertices(self,node,gnode):
        geomNode = gnode.node()
        ts = node.getTransform() 
        m = ts.getMat().getUpper3()
        p = ts.getMat().getRow3(3)
        points=[]
        geom = geomNode.getGeoms()[0]
        vdata = geom.getVertexData()
        reader = GeomVertexReader(vdata, 'vertex')
        while not reader.isAtEnd():
            v = reader.getData3f()
            v = m.xform(v) + p
            points.append(Point3(v))
        return numpy.array(points,dtype=numpy.float32)
        
    def pandaMatrice(self,mat):
        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],
                   mat[12],mat[13],mat[14],mat[15],)
        return pMat
        
#    
#    def addRB(self,rtype,static,**kw):
#        # Sphere
#        if panda3d is None :
#            return None
#        if rotMatis not None and trans is not None:
#            mat = rotMat.copy()
#            mat = mat.transpose().reshape((16,))
#
#            pMat = TransformState.makeMat(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],))
#        shape = None
#        inodenp = None
##        print (pMat) 
#        inodenp = self.rb_func_dic[rtype](ingr,pMat,trans,rotMat)

#        inodenp.setCollideMask(BitMask32.allOn())
    
#        self.world.attachRigidBody(inodenp.node())
#        if static :
#            self.static.append(inodenp.node())
#        else :
#            self.moving = inodenp.node()
#        self.rb_panda.append(inodenp.node())
#        return inodenp.node()
    
    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)
#        nodenp.setPos(trans[0],trans[1],trans[2])
#        print nodenp.getPos()

    def applyForce(self,node,F):
        F*=self.scale
        node.node().applyCentralForce(Vec3(F[0],F[1],F[2]))
#        node.node().applyForce(Vec3(F[0],F[1],F[2]),Point3(0, 0, 0))
#        print F
        
    def rayCast(self, startp,endp,closest=False):
        start=Point3(startp[0],startp[1],startp[2])
        end=Point3(endp[0],endp[1],endp[2])
        if closest :
            res = self.world.rayTestClosest(start, end)
        else :
            res = self.world.rayTestAll(start, end)  
        return res

    def sweepRay(self, startp,endp):
        tsFrom = TransformState.makePos(Point3(0, 0, 0))
        tsTo = TransformState.makePos(Point3(10, 0, 0))
        shape = BulletSphereShape(0.5)
        penetration = 0.0
        result = self.world.sweepTestClosest(shape, tsFrom, tsTo, penetration)
        return result 

    def update(self,task,cb=None):
#        print "update"
        dt = globalClock.getDt()
#        print dt
        self.world.doPhysics(dt, 10, 0.008)#,100,1.0/500.0)#world.doPhysics(dt, 10, 1.0/180.0)
        #this may be different for relaxing ?
#        print task.time
        if cb is not None :
            cb()
        if task is not None:
            return task.cont
示例#11
0
class Game(DirectObject):

  def __init__(self):
    base.setBackgroundColor(0.1, 0.1, 0.8, 1)
    base.setFrameRateMeter(True)

    base.cam.setPos(0, -40, 10)
    base.cam.lookAt(0, 0, 0)

    # Light
    alight = AmbientLight('ambientLight')
    alight.setColor(Vec4(0.5, 0.5, 0.5, 1))
    alightNP = render.attachNewNode(alight)

    dlight = DirectionalLight('directionalLight')
    dlight.setDirection(Vec3(5, 0, -2))
    dlight.setColor(Vec4(0.7, 0.7, 0.7, 1))
    dlightNP = render.attachNewNode(dlight)

    render.clearLight()
    render.setLight(alightNP)
    render.setLight(dlightNP)

    # Input
    self.accept('escape', self.doExit)
    self.accept('r', self.doReset)
    self.accept('f1', self.toggleWireframe)
    self.accept('f2', self.toggleTexture)
    self.accept('f3', self.toggleDebug)
    self.accept('f5', self.doScreenshot)

    # Task
    taskMgr.add(self.update, 'updateWorld')

    # Physics
    self.setup()

  # _____HANDLER_____

  def doExit(self):
    self.cleanup()
    sys.exit(1)

  def doReset(self):
    self.cleanup()
    self.setup()

  def toggleWireframe(self):
    base.toggleWireframe()

  def toggleTexture(self):
    base.toggleTexture()

  def toggleDebug(self):
    if self.debugNP.isHidden():
      self.debugNP.show()
    else:
      self.debugNP.hide()

  def doScreenshot(self):
    base.screenshot('Bullet')

  # ____TASK___

  def update(self, task):
    dt = globalClock.getDt()

    self.world.doPhysics(dt, 10, 0.004)

    return task.cont

  def cleanup(self):
    self.world = None
    self.worldNP.removeNode()

  def setup(self):
    self.worldNP = render.attachNewNode('World')

    # World
    self.debugNP = self.worldNP.attachNewNode(BulletDebugNode('Debug'))
    self.debugNP.show()

    self.world = BulletWorld()
    self.world.setGravity(Vec3(0, 0, -9.81))
    self.world.setDebugNode(self.debugNP.node())

    # Box
    shape = BulletBoxShape(Vec3(0.5, 0.5, 0.5) * 2.0)

    boxNP = self.worldNP.attachNewNode(BulletRigidBodyNode('Box'))
    boxNP.node().setMass(150.0)
    boxNP.node().addShape(shape)
    boxNP.setPos(0, 0, 2)
    boxNP.setCollideMask(BitMask32.allOn())

    self.world.attachRigidBody(boxNP.node())

    visualNP = loader.loadModel('models/box.egg')
    visualNP.clearModelNodes()
    visualNP.setScale(2.0)
    visualNP.reparentTo(boxNP)

    # Soft body world information
    info = self.world.getWorldInfo()
    info.setAirDensity(1.2)
    info.setWaterDensity(0)
    info.setWaterOffset(0)
    info.setWaterNormal(Vec3(0, 0, 0))

    # Softbody
    nx = 31
    ny = 31

    p00 = Point3(-8, -8, 0)
    p10 = Point3( 8, -8, 0)
    p01 = Point3(-8,  8, 0)
    p11 = Point3( 8,  8, 0)
    bodyNode = BulletSoftBodyNode.makePatch(info, p00, p10, p01, p11, nx, ny, 1+2+4+8, True) 

    material = bodyNode.appendMaterial()
    material.setLinearStiffness(0.4)
    bodyNode.generateBendingConstraints(2, material);
    bodyNode.setTotalMass(50.0)
    bodyNode.getShape(0).setMargin(0.5)

    bodyNP = self.worldNP.attachNewNode(bodyNode)
    self.world.attachSoftBody(bodyNode)

    # Rendering with Geom:
    fmt = GeomVertexFormat.getV3n3t2()
    geom = BulletHelper.makeGeomFromFaces(bodyNode, fmt, True)
    bodyNode.linkGeom(geom)
    visNode = GeomNode('')
    visNode.addGeom(geom)
    visNP = bodyNP.attachNewNode(visNode)

    # Now we want to have a texture and texture coordinates.
    # The geom's format has already a column for texcoords, so we just need
    # to write texcoords using a GeomVertexRewriter.
    tex = loader.loadTexture('models/panda.jpg')
    visNP.setTexture(tex)
    BulletHelper.makeTexcoordsForPatch(geom, nx, ny)
示例#12
0
class Game(DirectObject):
    def __init__(self):
        base.setBackgroundColor(0.1, 0.1, 0.8, 1)
        base.setFrameRateMeter(True)

        base.cam.setPos(0, -60, 20)
        base.cam.lookAt(0, 0, 0)

        # Light
        alight = AmbientLight('ambientLight')
        alight.setColor(Vec4(0.5, 0.5, 0.5, 1))
        alightNP = render.attachNewNode(alight)

        dlight = DirectionalLight('directionalLight')
        dlight.setDirection(Vec3(1, 1, -1))
        dlight.setColor(Vec4(0.7, 0.7, 0.7, 1))
        dlightNP = render.attachNewNode(dlight)

        render.clearLight()
        render.setLight(alightNP)
        render.setLight(dlightNP)

        # Input
        self.accept('escape', self.doExit)
        self.accept('r', self.doReset)
        self.accept('f1', self.toggleWireframe)
        self.accept('f2', self.toggleTexture)
        self.accept('f3', self.toggleDebug)
        self.accept('f5', self.doScreenshot)

        # Task
        taskMgr.add(self.update, 'updateWorld')

        # Physics
        self.setup()

    # _____HANDLER_____

    def doExit(self):
        self.cleanup()
        sys.exit(1)

    def doReset(self):
        self.cleanup()
        self.setup()

    def toggleWireframe(self):
        base.toggleWireframe()

    def toggleTexture(self):
        base.toggleTexture()

    def toggleDebug(self):
        if self.debugNP.isHidden():
            self.debugNP.show()
        else:
            self.debugNP.hide()

    def doScreenshot(self):
        base.screenshot('Bullet')

    # ____TASK___

    def update(self, task):
        dt = globalClock.getDt()

        self.world.doPhysics(dt, 10, 0.008)

        return task.cont

    def cleanup(self):
        self.world = None
        self.worldNP.removeNode()

    def setup(self):
        self.worldNP = render.attachNewNode('World')

        # World
        self.debugNP = self.worldNP.attachNewNode(BulletDebugNode('Debug'))
        self.debugNP.show()

        #self.debugNP.showTightBounds()
        #self.debugNP.showBounds()

        self.world = BulletWorld()
        self.world.setGravity(Vec3(0, 0, -9.81))
        self.world.setDebugNode(self.debugNP.node())

        # Ground
        p0 = Point3(-20, -20, 0)
        p1 = Point3(-20, 20, 0)
        p2 = Point3(20, -20, 0)
        p3 = Point3(20, 20, 0)
        mesh = BulletTriangleMesh()
        mesh.addTriangle(p0, p1, p2)
        mesh.addTriangle(p1, p2, p3)
        shape = BulletTriangleMeshShape(mesh, dynamic=False)

        np = self.worldNP.attachNewNode(BulletRigidBodyNode('Mesh'))
        np.node().addShape(shape)
        np.setPos(0, 0, -2)
        np.setCollideMask(BitMask32.allOn())

        self.world.attachRigidBody(np.node())

        # Stair
        origin = Point3(0, 0, 0)
        size = Vec3(2, 10, 1)
        shape = BulletBoxShape(size * 0.5)
        for i in range(10):
            pos = origin + size * i
            pos.setY(0)

            np = self.worldNP.attachNewNode(BulletRigidBodyNode('Stair%i' % i))
            np.node().addShape(shape)
            np.setPos(pos)
            np.setCollideMask(BitMask32.allOn())

            npV = loader.loadModel('models/box.egg')
            npV.reparentTo(np)
            npV.setScale(size)

            self.world.attachRigidBody(np.node())

        # Soft body world information
        info = self.world.getWorldInfo()
        info.setAirDensity(1.2)
        info.setWaterDensity(0)
        info.setWaterOffset(0)
        info.setWaterNormal(Vec3(0, 0, 0))

        # Softbody
        center = Point3(0, 0, 0)
        radius = Vec3(1, 1, 1) * 1.5
        node = BulletSoftBodyNode.makeEllipsoid(info, center, radius, 128)
        node.setName('Ellipsoid')
        node.getMaterial(0).setLinearStiffness(0.1)
        node.getCfg().setDynamicFrictionCoefficient(1)
        node.getCfg().setDampingCoefficient(0.001)
        node.getCfg().setPressureCoefficient(1500)
        node.setTotalMass(30, True)
        node.setPose(True, False)

        np = self.worldNP.attachNewNode(node)
        np.setPos(15, 0, 12)
        #np.setH(90.0)
        #np.showBounds()
        #np.showTightBounds()
        self.world.attachSoftBody(np.node())

        geom = BulletHelper.makeGeomFromFaces(node)
        node.linkGeom(geom)
        nodeV = GeomNode('EllipsoidVisual')
        nodeV.addGeom(geom)
        npV = np.attachNewNode(nodeV)
class Game(DirectObject):
    def __init__(self):
        base.setBackgroundColor(0.1, 0.1, 0.8, 1)
        base.setFrameRateMeter(True)

        base.cam.setPos(0, -40, 10)
        base.cam.lookAt(0, 0, 0)

        # Light
        alight = AmbientLight('ambientLight')
        alight.setColor(Vec4(0.5, 0.5, 0.5, 1))
        alightNP = render.attachNewNode(alight)

        dlight = DirectionalLight('directionalLight')
        dlight.setDirection(Vec3(5, 0, -2))
        dlight.setColor(Vec4(0.7, 0.7, 0.7, 1))
        dlightNP = render.attachNewNode(dlight)

        render.clearLight()
        render.setLight(alightNP)
        render.setLight(dlightNP)

        # Input
        self.accept('escape', self.doExit)
        self.accept('r', self.doReset)
        self.accept('f1', self.toggleWireframe)
        self.accept('f2', self.toggleTexture)
        self.accept('f3', self.toggleDebug)
        self.accept('f5', self.doScreenshot)

        # Task
        taskMgr.add(self.update, 'updateWorld')

        # Physics
        self.setup()

    # _____HANDLER_____

    def doExit(self):
        self.cleanup()
        sys.exit(1)

    def doReset(self):
        self.cleanup()
        self.setup()

    def toggleWireframe(self):
        base.toggleWireframe()

    def toggleTexture(self):
        base.toggleTexture()

    def toggleDebug(self):
        if self.debugNP.isHidden():
            self.debugNP.show()
        else:
            self.debugNP.hide()

    def doScreenshot(self):
        base.screenshot('Bullet')

    # ____TASK___

    def update(self, task):
        dt = globalClock.getDt()

        self.world.doPhysics(dt, 10, 0.008)

        return task.cont

    def cleanup(self):
        self.world = None
        self.worldNP.removeNode()

    def setup(self):
        self.worldNP = render.attachNewNode('World')

        # World
        self.debugNP = self.worldNP.attachNewNode(BulletDebugNode('Debug'))
        self.debugNP.show()

        self.world = BulletWorld()
        self.world.setGravity(Vec3(0, 0, -9.81))
        self.world.setDebugNode(self.debugNP.node())

        # Ground
        p0 = Point3(-20, -20, 0)
        p1 = Point3(-20, 20, 0)
        p2 = Point3(20, -20, 0)
        p3 = Point3(20, 20, 0)
        mesh = BulletTriangleMesh()
        mesh.addTriangle(p0, p1, p2)
        mesh.addTriangle(p1, p2, p3)
        shape = BulletTriangleMeshShape(mesh, dynamic=False)

        np = self.worldNP.attachNewNode(BulletRigidBodyNode('Mesh'))
        np.node().addShape(shape)
        np.setPos(0, 0, -4)
        np.setCollideMask(BitMask32.allOn())

        self.world.attachRigidBody(np.node())

        # Soft body world information
        info = self.world.getWorldInfo()
        info.setAirDensity(1.2)
        info.setWaterDensity(0)
        info.setWaterOffset(0)
        info.setWaterNormal(Vec3(0, 0, 0))

        # Softbody - From points/indices
        #import cube
        #points = [Point3(x,y,z) * 3 for x,y,z in cube.nodes]
        #indices = sum([list(x) for x in cube.elements], [])

        #node = BulletSoftBodyNode.makeTetMesh(info, points, indices, True)
        #node.setVolumeMass(300);
        #node.getShape(0).setMargin(0.01)
        #node.getMaterial(0).setLinearStiffness(0.8)
        #node.getCfg().setPositionsSolverIterations(1)
        #node.getCfg().clearAllCollisionFlags()
        #node.getCfg().setCollisionFlag(BulletSoftBodyConfig.CFClusterSoftSoft, True)
        #node.getCfg().setCollisionFlag(BulletSoftBodyConfig.CFClusterRigidSoft, True)
        #node.generateClusters(16)

        #softNP = self.worldNP.attachNewNode(node)
        #softNP.setPos(0, 0, 8)
        #softNP.setHpr(0, 0, 45)
        #self.world.attachSoftBody(node)

        # Softbody - From tetgen data
        ele = open('models/cube/cube.1.ele', 'r').read()
        face = open('models/cube/cube.1.face', 'r').read()
        node = open('models/cube/cube.1.node', 'r').read()

        node = BulletSoftBodyNode.makeTetMesh(info, ele, face, node)
        node.setName('Tetra')
        node.setVolumeMass(300)
        node.getShape(0).setMargin(0.01)
        node.getMaterial(0).setLinearStiffness(0.1)
        node.getCfg().setPositionsSolverIterations(1)
        node.getCfg().clearAllCollisionFlags()
        node.getCfg().setCollisionFlag(BulletSoftBodyConfig.CFClusterSoftSoft,
                                       True)
        node.getCfg().setCollisionFlag(BulletSoftBodyConfig.CFClusterRigidSoft,
                                       True)
        node.generateClusters(6)

        softNP = self.worldNP.attachNewNode(node)
        softNP.setPos(0, 0, 8)
        softNP.setHpr(45, 0, 0)
        self.world.attachSoftBody(node)

        # Option 1:
        visNP = loader.loadModel('models/cube/cube.egg')
        visNP.reparentTo(softNP)

        geom = visNP \
            .findAllMatches('**/+GeomNode').getPath(0).node() \
            .modifyGeom(0)
        node.linkGeom(geom)
class Game(DirectObject):
    def __init__(self):
        base.setBackgroundColor(0.1, 0.1, 0.8, 1)
        base.setFrameRateMeter(True)

        base.cam.setPos(0, -80, 40)
        base.cam.lookAt(0, 0, 10)

        # Light
        alight = AmbientLight('ambientLight')
        alight.setColor(Vec4(0.5, 0.5, 0.5, 1))
        alightNP = render.attachNewNode(alight)

        dlight = DirectionalLight('directionalLight')
        dlight.setDirection(Vec3(0, 0, -1))
        dlight.setColor(Vec4(0.7, 0.7, 0.7, 1))
        dlightNP = render.attachNewNode(dlight)

        render.clearLight()
        render.setLight(alightNP)
        render.setLight(dlightNP)

        # Input
        self.accept('escape', self.doExit)
        self.accept('r', self.doReset)
        self.accept('f1', self.toggleWireframe)
        self.accept('f2', self.toggleTexture)
        self.accept('f3', self.toggleDebug)
        self.accept('f5', self.doScreenshot)

        # Task
        taskMgr.add(self.update, 'updateWorld')

        # Physics
        self.setup()

    # _____HANDLER_____

    def doExit(self):
        self.cleanup()
        sys.exit(1)

    def doReset(self):
        self.cleanup()
        self.setup()

    def toggleWireframe(self):
        base.toggleWireframe()

    def toggleTexture(self):
        base.toggleTexture()

    def toggleDebug(self):
        if self.debugNP.isHidden():
            self.debugNP.show()
        else:
            self.debugNP.hide()

    def doScreenshot(self):
        base.screenshot('Bullet')

    # ____TASK___

    def update(self, task):
        dt = globalClock.getDt()

        self.world.doPhysics(dt, 10, 0.008)

        return task.cont

    def cleanup(self):
        self.world = None
        self.worldNP.removeNode()

    @staticmethod
    def Vec3Rand():
        x = 2 * random.random() - 1
        y = 2 * random.random() - 1
        z = 2 * random.random() - 1
        return Vec3(x, y, z)

    def setup(self):
        self.worldNP = render.attachNewNode('World')

        # World
        self.debugNP = self.worldNP.attachNewNode(BulletDebugNode('Debug'))
        self.debugNP.show()

        self.world = BulletWorld()
        self.world.setGravity(Vec3(0, 0, -9.81))
        self.world.setDebugNode(self.debugNP.node())

        # Ground
        p0 = Point3(-20, -20, 0)
        p1 = Point3(-20, 20, 0)
        p2 = Point3(20, -20, 0)
        p3 = Point3(20, 20, 0)
        mesh = BulletTriangleMesh()
        mesh.addTriangle(p0, p1, p2)
        mesh.addTriangle(p1, p2, p3)
        shape = BulletTriangleMeshShape(mesh, dynamic=False)

        np = self.worldNP.attachNewNode(BulletRigidBodyNode('Mesh'))
        np.node().addShape(shape)
        np.setPos(0, 0, -2)
        np.setCollideMask(BitMask32.allOn())

        self.world.attachRigidBody(np.node())

        # Soft body world information
        info = self.world.getWorldInfo()
        info.setAirDensity(1.2)
        info.setWaterDensity(0)
        info.setWaterOffset(0)
        info.setWaterNormal(Vec3(0, 0, 0))

        # Softbody
        for i in range(50):
            p00 = Point3(-2, -2, 0)
            p10 = Point3(2, -2, 0)
            p01 = Point3(-2, 2, 0)
            p11 = Point3(2, 2, 0)
            node = BulletSoftBodyNode.makePatch(info, p00, p10, p01, p11, 6, 6,
                                                0, True)
            node.generateBendingConstraints(2)
            node.getCfg().setLiftCoefficient(0.004)
            node.getCfg().setDynamicFrictionCoefficient(0.0003)
            node.getCfg().setAeroModel(BulletSoftBodyConfig.AMVertexTwoSided)
            node.setTotalMass(0.1)
            node.addForce(Vec3(0, 2, 0), 0)

            np = self.worldNP.attachNewNode(node)
            np.setPos(self.Vec3Rand() * 10 + Vec3(0, 0, 20))
            np.setHpr(self.Vec3Rand() * 16)
            self.world.attachSoftBody(node)

            fmt = GeomVertexFormat.getV3n3t2()
            geom = BulletHelper.makeGeomFromFaces(node, fmt, True)
            node.linkGeom(geom)
            nodeV = GeomNode('')
            nodeV.addGeom(geom)
            npV = np.attachNewNode(nodeV)