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