基础
组成结构
- 树型结构
Render -> NodePath -> PandaNode(Geom)[GeomVertexData, GeomPrimitive]
GeomVertexData 保存顶点数据, GeomPrimitive 保存顶点的index
坐标
- render(3d) X右,Y前,Z上
- render2d 坐标左下角(-1,0,-1)到右上角(1,0,1)
移动、形变
位移 NodePath.setPos(X,Y,Z) #位移
旋转 NodePath.setHpr(H,P,R)
- 旋转方向
- Heading: 绕Y轴转
- Pitch: 绕X轴转
- Roll: 绕Z轴转
旋转的例子: hprtest.py 使用simples/tutorial1中的model
- 旋转方向
缩放 NodePath.setScale(uniform) #
文件格式
EGG
创建EGG
EggData()
- .addChild
- .addVertex
- .recomputePolygonNormal
EggVertexPool()
- .addVertex
- .loadEggData()
镜头
- base.camera
地形
高度图算法
Diamond-Square Algorithm
碰撞
solid
CollisionPolygon 多边型 (昂贵,不准确)
CollisionRay 射线
CollisionLine 双向射线
CollisionSegment 两点间线
Collision Handlers
1 queue = CollisionHandlerQueue()
2 traverser.addCollider(fromObject, queue)
3 traverser.traverse(render)
4 for i in range(queue.getNumEntries()):
5 entry = queue.getEntry(i)
6 print entry
CollisionHandlerEvent 碰撞时产生事件(in again out)
1 class MyObject(DirectObject.DirectObject):
2 def __init__(self):
3 self.accept('car-into-rail', handleRailCollision) #接受in事件
4 def handleRailCollision(self, entry):
5 print entry
Collision Entries
碰撞发生时产生Entry,记录碰撞信息
Collision Traversers
碰撞检测,付到base.cTrav后,每嵮自动检测
1 traverser = CollisionTraverser('traverser name')
2 base.cTrav = traverser
3 traverser.addCollider(fromObject, handler)
只用加入碰撞物(fromObject),不用被碰撞物,所有加入场景的物体自动成为被碰撞物
碰撞掩码(Collision Bitmasks)
碰撞物的“碰撞”掩码和被碰撞物的“被碰撞”掩码相与(AND),如果结果不等于0——意味着两个掩码至少有一位相同——那么进行碰撞测试。
nodePath.node().setFromCollideMask(BitMask32(0x10)) #设置碰撞掩码,必须在node上设置,不能在nodePath上设
nodePath.setCollideMask(BitMask32(0x04), BitMask32(0xff)) #设置被碰撞掩码
GeomNode.getDefaultCollideMask() #得到被碰撞掩码
光和雾
雾
=== 基本用法 ==
1 myFog = Fog("Fog Name")
2 myFog.setColor(R,G,B)
3 myFog.setExpDensity(Float 0 to 1)
4 render.setFog(myFog)
5 render.clearFog()
雾的模式
fog.setMode(Fog.Mode)
- 线性模式
1 colour = (0.5,0.8,0.8)
2 linfog = Fog("A linear-mode Fog node")
3 linfog.setColor(*colour)
4 linfog.setLinearRange(0,320)
5 linfog.setLinearFallback(45,160,320)
6 render.attachNewNode(linfog)
7 render.setFog(linfog)
修改参数
1 getLinearOnsetPoint()
2 getLinearOpaquePoint()
3 setLinearOnsetPoint(float x,y,z)
4 setLinearOpaquePoint(Point3D pos)
5 setLinearRange(float onset, float opaque)
- 指数模式
1 colour = (0.5,0.8,0.8)
2 expfog = Fog("Scene-wide exponential Fog object")
3 expfog.setColor(*colour)
4 expfog.setExpDensity(0.005)
5 render.setFog(expfog)
6 base.setBackgroundColor(*colour) # 一般来说,如果场景的背景颜色与雾颜色匹配的话效果非常不错
光
render.setLight(dlnp)
点光
需要一个位置
1 plight = PointLight('plight')
2 plight.setColor(VBase4(0.2, 0.2, 0.2, 1))
3 plnp = render.attachNewNode(plight)
4 plnp.setPos(10, 20, 0)
5 render.setLight(plnp)
有向光
需要一个角度,位置不重要
1 dlight = DirectionalLight('dlight')
2 dlight.setColor(VBase4(0.8, 0.8, 0.5, 1))
3 dlnp = render.attachNewNode(dlight)
4 dlnp.setHpr(0, -60, 0)
5 render.setLight(dlnp)
环境光
均匀分布,一般不用
1 alight = AmbientLight('alight')
2 alight.setColor(VBase4(0.2, 0.2, 0.2, 1))
3 alnp = render.attachNewNode(alight.upcastToPandaNode())
4 render.setLight(alnp)
聚光灯
有它的位置和方向,以及一个视域
1 slight = Spotlight('slight')
2 slight.setColor(VBase4(1, 1, 1, 1))
3 lens = PerspectiveLens()
4 slight.setLens(lens)
5 slnp = render.attachNewNode(slight.upcastToLensNode())
6 slnp.setPos(10, 20, 0)
7 slnp.lookAt(myObject)
8 render.setLight(slnp)
任务与事件处理(Tasks and Event Handling)
任务
基本用法
- 定义任务函数
1 from direct.task import Task
2
3 #This task runs for two seconds, then prints done
4 def exampleTask(task):
5 if task.time < 2.0:
6 return Task.cont
7 print 'Done'
8 return Task.done
- 加入任务管理器
1 taskMgr.add(exampleTask, 'MyTaskName')
- 移除
1 taskMgr.remove('MyTaskName')
- 延时执行
1 taskMgr.doMethodLater(delayTime, myFunction, 'Task Name')
事件
- accept('Event Name',myDirectObjectMethod)
- .acceptOnce 接受一次
- 忽略 .ignore('Event Name') .ignoreAll()
- 发送 messenger.send('Event Name')