panda3d 根据collision detection(碰撞检测)实例探究Panda3d类组织结构

来源:互联网 发布:java sftp下载 编辑:程序博客网 时间:2024/04/30 21:39

首先贴一段代码:

from direct.showbase.ShowBase import ShowBase
from panda3d.core import *
import random

class Application(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)
        self.cam.setPos(0,-50,10)
        self.setupCD()
        self.addSmiley()
        self.addFloor()
        taskMgr.add(self.updateSmiley,"UpdateSmiley")
    
    #add the method that initializes the collision detection system
    def setupCD(self):
        '''
        base is the __builtin__ variable
        '''
        base.cTrav=CollisionTraverser()
        base.cTrav.showCollisions(render)
        self.notifier=CollisionHandlerEvent()
        self.notifier.addInPattern("%fn-in-%in")
        self.accept("frowney-in-floor",self.onCollision)

    #implement the method for adding the frowney model to the scene
    def addSmiley(self):

        self.frowney=loader.loadModel("frowney")
        self.ballpath=render.attachNewNode("ballcenter")
        self.frowney.reparentTo(self.ballpath)
        
        self.frowney.setPos(0,0,10)
        self.frowney.setPythonTag("velocity",0)
        
        col=self.frowney.attachNewNode(CollisionNode("frowney"))
        col.node().addSolid(CollisionSphere(0,0,0,1.1))
        col.show()
        base.cTrav.addCollider(col,self.notifier)
    
    #add a floor plane to the scene and handle the collision response
    def addFloor(self):
        floor=render.attachNewNode(CollisionNode("floor"))
        floor.node().addSolid(CollisionPlane(Plane(Vec3(0,0,1),Point3(0,0,0))))
        floor.show()
        
    def onCollision(self,entry):
        vel=random.uniform(0.01,0.2)
        self.frowney.setPythonTag("velocity",vel)
        
    #make the frrowney model bounce up and down
    def updateSmiley(self,task):
        vel=self.frowney.getPythonTag("velocity")
        z=self.frowney.getZ()
        self.frowney.setZ(z+vel)
        vel-=0.001
        self.frowney.setPythonTag("velocity",vel)
        return task.cont

a=Application()
run()

最让人困惑的可能是两个加红的中间addSmiley的函数了。下面简单的介绍一下addSmiley创建模型,挂载模型到render,挂载碰撞体到模型的过程。

如上面所说addSmiley首先创建模型由如下代码完成

self.frowney=loader.loadModel("frowney")

这里loader.loadModel返回的是NodePath是PandaNode的handle

然后挂载模型到render完成显示由如下代码完成

self.ballpath=render.attachNewNode("ballcenter")

self.frowney.reparetoTo(self.ballpath)

其中self.ballpath是中心在(0,0,0)点的NodePath,这是panda3d的常用技巧在之后的对self.frowney 的调整就是相对于self.ballpath了。

下面介绍挂载一个球星碰撞体到frowney模型的方法,由如下代码完成

col=self.frowney.attachNewNode(CollisionNode("frowney"))

col.node().addSolid(CollisionSphere(0,0,0,1.1))

加载了名为“frowney”的CollisionNode到self.frowney上,这样CollisionNode可以跟随self.frowney所代表的模型一同运动了,然后再CollisionNode中加入CollisonSphere这样碰撞体就为一个碰撞球。

从上面对addSmiley函数的解析中可以看出panda3d的组织结构:

以PandaNode为载体可以加载相应的性质,而加载的对象又以PandaNode为载体加载相应的属性对象(如这里的碰撞球的加载)。给出继承关系帮助大家理解:

PandaNode:

 

CollisionNode:为可以加载不同碰撞体类型(CollisionSolid类)的类

CollisionSolid: