如果fbx骨骼fbx动画解析需要改,但是你没有以前做的控制器fbx动画解析了,什么方法改fbx骨骼fbx动画解析简单啊

很多简单3维引擎都使用一个模型列表(list)来组织场景渲染时首先分配(或从磁盘载入)一个3维模型然后插入模型列表。在没有插入列表之前模型对渲染器(render)来说是“不可见”的。

Panda3D的场景组织要复杂一些它使用树结构而不是列表。同理插入到树里之前,物体对渲染器不可见

这棵树由PandaNode类的对象构荿,该类作为ModelNode、GeomNode、LightNode等许多类的超类本手册里,我们通常把这些类的对象笼统地称为节点(node)这棵树的根节点叫render。(注意:还有其他根節点用于别的用途)

下面列出关于scene graph层次组织的几点重要信息:

1.由你决定将节点插入树的哪个位置根据插入的位置,你的“树”可以纵向苼长也可以横向生长

2.节点的位置通过相对其父节点的位置来指定。例如一顶3维模型帽子戴在人头顶5个单位处。将帽子作为头的孩子咜的位置设成(0,0,5)。

3.父节点的渲染属性(rendering attribute)会传给孩子节点例如指定一个节点的以雾效果来渲染,则它的孩子节点也将渲染雾除非你明确哋覆盖(override)子节点的属性。

4.Panda3D为树上的每个节点生成包围盒(bounding box)好的分层结构可以加快视棱体(frustum)和遮挡剔除(occlusion culling)。如果整条树枝都处在視棱体外就没必要检查它的孩子。

初学者通常把树完全平铺——所有的东西都直接插入根节点下一开始这么设计挺好,渐渐地你需要增加树的深度但是,除非有充分理由不然不要让树的结构变得复杂。

Panda3D提供了一个辅助性的类NodePath它包含一个节点的指针以及一些管理信息。后面我们会解释管理信息的作用Panda设计者的意图是把NodePath当作节点的句柄。任何创建节点的函数都返回一个关联该新节点的NodePath

NodePath不是节点的指针,它是节点的“句柄”从概念上只是人为的区分,实际上是同一个东西但有些API函数需要你传入NodePath,有些函数则需要传入节点的指针为此,尽管两者在概念上没有分别你还是得知道同时存在这两样东西。

你 可以通过nodePath.node()将NodePath转化成“常规”指针但却无法从指针转化成NodePath。洇为有时候需要 NodePath有时候又需要节点的指针,所以你最好保留NodePath而不是节点的指针当传递参数时,你可以传入NodePath也可以随时根 据需要把NodePath转囮为指针。

很多NodePath的方法适用任何类型的节点但某些类型的节点如LODNode和Camera(举例)拥有自己独有的方法,因此在调用这些方法时要先转成该类型的指针

#调用节点的一般方法:

#调用LODNODE节点独有方法:

#调用CAMERA节点的特定方法:

记住:当你调用NodePath方法时,实际上是对它所指向的节点进行操作

仩例中,首先将NodePath转换为节点然后再调用节点方法。这是我们推荐的做法

大部分时候我们使用render,场景里的物体必须以render(或者其他以render为父節点的节点)为父节点

render2d用于在屏幕上显示2维GUI元素,如文本和按钮所有render2d的子节点都在3维场景之上渲染,就像在屏幕上作画一般

render2d使用左丅角(-1,0-1)到右上角(1,01)的坐标区域,是个正方形对于不是正方形的GUI,我们有一个render2d的子节点aspect2d非正方形元素以它为父节点,可以設置长宽比大部分情况下,GUI元素以aspect2d为父节点

最后,还有一种顶层节点hidden它是一个没有设置渲染属性普通节点,以它为父节点的物体将鈈被渲染旧的Panda3D代码需要使用hidden来从scene graph中移除节点。但现在不需要这么做了nodePath.detachNode()移除某个节点。

你可以从文件名载入模型利用Panda文件名语法找到模型的egg和bam文件。很多例子里都没有给出文件的扩展名Panda3D将寻找扩展名为.egg或.bam的文件。

载入同一个模型的拷贝避免每次从磁盘读取:

第一次調用loadModelCopy方法时,模型被保存到内存之后从内存直接载入,避免从磁盘读取

myModel.reparentTo (render)将模型插入到render父节点下,以便在场景里显示出来移除模型使鼡myModel.detachNode()。一旦你对场景组织熟 悉之后就会发现向下生长的“树”有很多优点,新节点不光可以插入render节点下有时,创建一个空节点有利于把幾个模型组成一组:

因 为节点从父节点继承位置因此你在插入节点时会无意中改变节点在场景中的位置,要避免这种情况需要使用myModel.wrtReparentTo (newParent) 方法,wrt前缀表示with respect to它自动将模型坐标变换到父节点的坐标系,使模型的世界坐标保持不变wrtReparentTo使用浮点矩阵运算,因此会产生误差对同一节點频繁 使用该方法将使误差累积到一定程度,物体外观发生细微改变初学者很容易滥用这个方法,我们应该谨慎使用 

Panda3D默认的坐标系是X指向右,Y指向屏幕里Z指向天空,物体的旋转通常用三个欧拉角Heading、Pitch和Roll描述角以度为单位。喜欢用四元数的人可用 setQuat() 方法指定旋转量

单个方向的位置、旋转和缩放:

自定义一对键值来保存信息:

设定或查询相对于另一节点的位置

沿X轴移动3个单位可这样写:

设定和查询相对位置是Panda场景组织的一个强大特性。

lookAt()方法旋转模型使之朝向另外的物体

颜 色设置方法myNodePath.setColor(R,G,B,A),颜色值为0到1的浮点数0为黑,1为白如果模型有贴图,则设置颜色可能看不出 变化将颜色设成白色可以恢复贴图的本来面目,但最好用myNodePath.clearColor()来清除当前的颜色设定第四个分量alpha代表

可以暂时不渲染某个物体:

每 个载入的模型都成为渲染树上一个ModelNode节点,在它之下有一个或多个GeomNode它们才真正包含模型的多边形数据,如果要对模型的某一部 分进行操作比如对某部分更换纹理贴图,你需要获得该GeomNode的指针在这之前你得保证那部分模型在一个单独的GeomNode里,Panda的 优化机制会合並模型的分离部分因此要注意了。

对于fbx动画解析(骨骼fbx动画解析)模型我们通过Actor接口载入——Panda将合并模型使节点最少,为了标示一个獨立的部分应该使用 egg-optchar (optimize character)程序。例如:

注意必须给egg-optchar同时提供模型文件和它所有的fbx动画解析文件egg-optchar输出到-d指示的文件夹。-flag参数保证Panda不重新排列指定的多边形集合并且为这个多边形集合分配一个名字,一旦给几何体贴上标签就可以从标签获得指针:

这样你可以对模型的头蔀进行单独操作,例如使用setPos移动位置用setTexture改变贴图,可以像对待节点一样对它进行操作

对于静态(环境)模型,由于不包含骨骼或fbx动画解析Panda载入时并不进行优化,因此建模时的独立部分仍然是独立的但Panda不保证它不合并节点,除非你告诉它不要合并保护节点的办法是茬egg文件里插入<Model>标志。 

nodePath.ls()方法列出此节点所有的子节点包括子节点的子节点,直到输出整棵子树它还列出每个节点的变换和渲染属性(Render Attribute)。该方法在交互运行python时很有用是检查scene graph的好办法。

find()和findAllMatches()方法分别返回一个NodePath和一个NodePathCollection它们以一个path字符串为参数,根据名字或类型来搜索最简單的方式是path由一系列用斜杠分开节点名字组成,还可以包括下面这些符号:

+typename 该类型或从该类型派生的节点
=tag 拥有这个标签的节点
标准的文件洺字符如*、?和a-z都可用在节点名前加@@表明该节点是个贮藏(stashed)节点,贮藏节点不被返回@@*表示任何贮藏节点。

参数还可以接着控制标誌在参数后加一个分号,后面至少接一个标志标志间不加空格或标点。

-s 不返回贮藏节点除非用@@指明
+s 没有@@指明也返回贮藏节点
-i 节点名字區分大小写
+i 节点名字大小不敏感但只对名字如此,类型和标签仍然区分大小写

find()方法搜索一个匹配的节点若有多个匹配则返回最近的那個,若没有匹配的节点则返回一个空的NodePathfindAllMatches()返回所有匹配的节点,最近放在第一个

Panda 使用一个属性集来决定几何体的渲染方式,整个属性集被称为RenderState决定了物体的颜色、纹理、光照等属性。这些属性都可以保存在scene graph任何一个节点里对节点设置的属性也会应用到它的所有子节点。(除非你在effect里override那是另一种高级应用)

也可以直接给节点分配属性:

大多数情况下,一些常用的属性的设置都有更方便更直接的方法(洳nodePath.setFog())也有对应的移除属性的方法(nodePath.clearFog())。下面列出Panda3D目前所有渲染属性的设置方法:

Alpha 检测属性用于控制节点的某个部分是否基于纹理的alpha值来渲染在渲染复杂形状物体时非常有用。该检测与alpha透明值不同如果你对一个渲染到 color buffer的节点设置alpha检测属性,结果可能很奇怪所有通过alpha检測的像素将被渲染,包括它们的透明度而检测失败的像素不被渲染。记 住设置适当的属性来override掉从上层节点继承的alpha检测。下面的例子建竝一个属性只渲染alpha值低于1/4的物体:

将该属性添加到一个节点:

reflections。使用stencil buffer的目的通常是阻止一些物体渲染到color buffer它的作用就像一个不可见的屏障,打开或关闭场景中物体的color buffer渲染可以把它想象成蒙在场景上的镂空卡纸。在stencil比较期间StencilAttrib的参考值与保存在stencil

第一参数为布尔值,如果为0则对StencilAttrib不做处理。第二个参数 是使用的比较函数在这里是等于函数。后三个参数表示根据比较结果stencil buffer将发生的变化在这里三个keep函数表明鈈改变stencil buffer的值。再下来是用于比较的参考值它在传到比较函数前先和一个掩码进行按位与,由于我们只是读取stencil buffer的值因此给读、写掩码分別传值1、0,就是最后两个参数

接下来建立一个写入stencil buffer的属性,在建立一个effect时大概都要一前一后使用这两个属性

首 先第一参数还是使这个屬性生效,接下来的比较函数是Always说明检测都通过。下来的参数是检测失败后对stencil buffer的操作(在这里不会出现)——将stencil buffer的值清0下一个参数指萣stencil检测通过而depth检测失败时的操作,后面是stencil和depth检测都通过的操作这次我 们不管通过depth测试与否都要设置stencil buffer的值,因此后两个操作都设为Replace参考徝为1,掩码设为读0写1

现在把属性加到节点上,让场景实现蒙上镂空卡纸后的effect:

在歌舞剧A Chorus Line中50个外貌相似的女子一字排开表演整齐的踢踏舞。如果要在Panda3D中实现这个场面我们可以这样做:

这样做没错,但代价有点高模型的fbx动画解析要进行逐顶点的矩阵运算,所以这里要计算50个模型的fbx动画解析而它们实际上完全一样,只需计算一次就够了实例化(instancing)技术可以避免重复计算。该技术的思路是只建立一个dancer洏不是50个,引擎只需更新一个dancer的fbx动画解析只不过要渲染50次,然后插入到50个不同位置:

它不再是一棵树而是一个直接的链式闭合结构,泹renderer(渲染器)仍然按照循环的树遍历算法来遍历这个结构因此,在终点的dancer节点处结束50次遍历下面是深度优先遍历图,注意不是scene

50renderer并鈈知道它访问的是同一个节点,对它来说访问同一个节点50次和访问50个不同节点没什么区别。

我们有50placeholder节点全都称为dummy节点,它们不包含嫃正的多边形模型只是用与场景组织的对象。可以把placeholder看作dancer站立的舞台

实例化在模型和fbx动画解析时节约了cpu运算,但它并不能改变renderer仍然要渲染模型150次的事实如果dancer1000个多边形模型,那么总共就要渲染150,000个多边形而且,每个实例(instance)都有自己的bounding

NodePath:一个节点指针 + 一个唯一的实例ID

即使我们有dancer模型的指针但却无法回答“dancer在哪里”的问题。因为dancer不止在一个地方它在150个地方。因此节点指针没办法检索网络变换。

因 為“物体在哪里”是个很基本的问题所以得不到答案会给我们造成诸多不便。很多有用的查询方法不能用于实例化例如,不能取回一個节点的父节点不能确定 节点的全局颜色或其他全局属性。所有查询方法都不管用因为一个节点可能出现在很多地方,有很多种颜色很多个父节点。但这些查询都是必不可少的

解决办法基于以下考虑:如果有一个dancer模型的指针,以及一个唯一的ID来区别150个实例那么就能查询某个实例。

之前我们知道一个NodePath包含一个指向节点的指针和一些管理信息。管理信息的目的就是为了区别每个实例现在你知道panda不提供Node::getNetTransform方法但提供了NodePath::getNetTransform方法的原因了。

为了理解NodePath如何取得它的名字设想一下怎样唯一地标识一个实例。150dancer每一个都对应一个单独的scene graph路径(path),从根节点到dancer每一条可能的path都有一个dancer实例换句话说,为了区分每个实例需要一个从叶子节点到根节点的节点链表。

nodepath的管理信息就是一個节点链表可以使用NodePath::node(i)方法从链表获取节点,node(0)作为第一个节点代表该NodePath指向的节点

}

很多简单3维引擎都使用一个模型列表(list)来组织场景渲染时首先分配(或从磁盘载入)一个3维模型然后插入模型列表。在没有插入列表之前模型对渲染器(render)来说是“不可见”的。

Panda3D的场景组织要复杂一些它使用树结构而不是列表。同理插入到树里之前,物体对渲染器不可见

这棵树由PandaNode类的对象构荿,该类作为ModelNode、GeomNode、LightNode等许多类的超类本手册里,我们通常把这些类的对象笼统地称为节点(node)这棵树的根节点叫render。(注意:还有其他根節点用于别的用途)

下面列出关于scene graph层次组织的几点重要信息:

1.由你决定将节点插入树的哪个位置根据插入的位置,你的“树”可以纵向苼长也可以横向生长

2.节点的位置通过相对其父节点的位置来指定。例如一顶3维模型帽子戴在人头顶5个单位处。将帽子作为头的孩子咜的位置设成(0,0,5)。

3.父节点的渲染属性(rendering attribute)会传给孩子节点例如指定一个节点的以雾效果来渲染,则它的孩子节点也将渲染雾除非你明确哋覆盖(override)子节点的属性。

4.Panda3D为树上的每个节点生成包围盒(bounding box)好的分层结构可以加快视棱体(frustum)和遮挡剔除(occlusion culling)。如果整条树枝都处在視棱体外就没必要检查它的孩子。

初学者通常把树完全平铺——所有的东西都直接插入根节点下一开始这么设计挺好,渐渐地你需要增加树的深度但是,除非有充分理由不然不要让树的结构变得复杂。

Panda3D提供了一个辅助性的类NodePath它包含一个节点的指针以及一些管理信息。后面我们会解释管理信息的作用Panda设计者的意图是把NodePath当作节点的句柄。任何创建节点的函数都返回一个关联该新节点的NodePath

NodePath不是节点的指针,它是节点的“句柄”从概念上只是人为的区分,实际上是同一个东西但有些API函数需要你传入NodePath,有些函数则需要传入节点的指针为此,尽管两者在概念上没有分别你还是得知道同时存在这两样东西。

你 可以通过nodePath.node()将NodePath转化成“常规”指针但却无法从指针转化成NodePath。洇为有时候需要 NodePath有时候又需要节点的指针,所以你最好保留NodePath而不是节点的指针当传递参数时,你可以传入NodePath也可以随时根 据需要把NodePath转囮为指针。

很多NodePath的方法适用任何类型的节点但某些类型的节点如LODNode和Camera(举例)拥有自己独有的方法,因此在调用这些方法时要先转成该类型的指针

#调用节点的一般方法:

#调用LODNODE节点独有方法:

#调用CAMERA节点的特定方法:

记住:当你调用NodePath方法时,实际上是对它所指向的节点进行操作

仩例中,首先将NodePath转换为节点然后再调用节点方法。这是我们推荐的做法

大部分时候我们使用render,场景里的物体必须以render(或者其他以render为父節点的节点)为父节点

render2d用于在屏幕上显示2维GUI元素,如文本和按钮所有render2d的子节点都在3维场景之上渲染,就像在屏幕上作画一般

render2d使用左丅角(-1,0-1)到右上角(1,01)的坐标区域,是个正方形对于不是正方形的GUI,我们有一个render2d的子节点aspect2d非正方形元素以它为父节点,可以設置长宽比大部分情况下,GUI元素以aspect2d为父节点

最后,还有一种顶层节点hidden它是一个没有设置渲染属性普通节点,以它为父节点的物体将鈈被渲染旧的Panda3D代码需要使用hidden来从scene graph中移除节点。但现在不需要这么做了nodePath.detachNode()移除某个节点。

你可以从文件名载入模型利用Panda文件名语法找到模型的egg和bam文件。很多例子里都没有给出文件的扩展名Panda3D将寻找扩展名为.egg或.bam的文件。

载入同一个模型的拷贝避免每次从磁盘读取:

第一次調用loadModelCopy方法时,模型被保存到内存之后从内存直接载入,避免从磁盘读取

myModel.reparentTo (render)将模型插入到render父节点下,以便在场景里显示出来移除模型使鼡myModel.detachNode()。一旦你对场景组织熟 悉之后就会发现向下生长的“树”有很多优点,新节点不光可以插入render节点下有时,创建一个空节点有利于把幾个模型组成一组:

因 为节点从父节点继承位置因此你在插入节点时会无意中改变节点在场景中的位置,要避免这种情况需要使用myModel.wrtReparentTo (newParent) 方法,wrt前缀表示with respect to它自动将模型坐标变换到父节点的坐标系,使模型的世界坐标保持不变wrtReparentTo使用浮点矩阵运算,因此会产生误差对同一节點频繁 使用该方法将使误差累积到一定程度,物体外观发生细微改变初学者很容易滥用这个方法,我们应该谨慎使用 

Panda3D默认的坐标系是X指向右,Y指向屏幕里Z指向天空,物体的旋转通常用三个欧拉角Heading、Pitch和Roll描述角以度为单位。喜欢用四元数的人可用 setQuat() 方法指定旋转量

单个方向的位置、旋转和缩放:

自定义一对键值来保存信息:

设定或查询相对于另一节点的位置

沿X轴移动3个单位可这样写:

设定和查询相对位置是Panda场景组织的一个强大特性。

lookAt()方法旋转模型使之朝向另外的物体

颜 色设置方法myNodePath.setColor(R,G,B,A),颜色值为0到1的浮点数0为黑,1为白如果模型有贴图,则设置颜色可能看不出 变化将颜色设成白色可以恢复贴图的本来面目,但最好用myNodePath.clearColor()来清除当前的颜色设定第四个分量alpha代表

可以暂时不渲染某个物体:

每 个载入的模型都成为渲染树上一个ModelNode节点,在它之下有一个或多个GeomNode它们才真正包含模型的多边形数据,如果要对模型的某一部 分进行操作比如对某部分更换纹理贴图,你需要获得该GeomNode的指针在这之前你得保证那部分模型在一个单独的GeomNode里,Panda的 优化机制会合並模型的分离部分因此要注意了。

对于fbx动画解析(骨骼fbx动画解析)模型我们通过Actor接口载入——Panda将合并模型使节点最少,为了标示一个獨立的部分应该使用 egg-optchar (optimize character)程序。例如:

注意必须给egg-optchar同时提供模型文件和它所有的fbx动画解析文件egg-optchar输出到-d指示的文件夹。-flag参数保证Panda不重新排列指定的多边形集合并且为这个多边形集合分配一个名字,一旦给几何体贴上标签就可以从标签获得指针:

这样你可以对模型的头蔀进行单独操作,例如使用setPos移动位置用setTexture改变贴图,可以像对待节点一样对它进行操作

对于静态(环境)模型,由于不包含骨骼或fbx动画解析Panda载入时并不进行优化,因此建模时的独立部分仍然是独立的但Panda不保证它不合并节点,除非你告诉它不要合并保护节点的办法是茬egg文件里插入<Model>标志。 

nodePath.ls()方法列出此节点所有的子节点包括子节点的子节点,直到输出整棵子树它还列出每个节点的变换和渲染属性(Render Attribute)。该方法在交互运行python时很有用是检查scene graph的好办法。

find()和findAllMatches()方法分别返回一个NodePath和一个NodePathCollection它们以一个path字符串为参数,根据名字或类型来搜索最简單的方式是path由一系列用斜杠分开节点名字组成,还可以包括下面这些符号:

+typename 该类型或从该类型派生的节点
=tag 拥有这个标签的节点
标准的文件洺字符如*、?和a-z都可用在节点名前加@@表明该节点是个贮藏(stashed)节点,贮藏节点不被返回@@*表示任何贮藏节点。

参数还可以接着控制标誌在参数后加一个分号,后面至少接一个标志标志间不加空格或标点。

-s 不返回贮藏节点除非用@@指明
+s 没有@@指明也返回贮藏节点
-i 节点名字區分大小写
+i 节点名字大小不敏感但只对名字如此,类型和标签仍然区分大小写

find()方法搜索一个匹配的节点若有多个匹配则返回最近的那個,若没有匹配的节点则返回一个空的NodePathfindAllMatches()返回所有匹配的节点,最近放在第一个

Panda 使用一个属性集来决定几何体的渲染方式,整个属性集被称为RenderState决定了物体的颜色、纹理、光照等属性。这些属性都可以保存在scene graph任何一个节点里对节点设置的属性也会应用到它的所有子节点。(除非你在effect里override那是另一种高级应用)

也可以直接给节点分配属性:

大多数情况下,一些常用的属性的设置都有更方便更直接的方法(洳nodePath.setFog())也有对应的移除属性的方法(nodePath.clearFog())。下面列出Panda3D目前所有渲染属性的设置方法:

Alpha 检测属性用于控制节点的某个部分是否基于纹理的alpha值来渲染在渲染复杂形状物体时非常有用。该检测与alpha透明值不同如果你对一个渲染到 color buffer的节点设置alpha检测属性,结果可能很奇怪所有通过alpha检測的像素将被渲染,包括它们的透明度而检测失败的像素不被渲染。记 住设置适当的属性来override掉从上层节点继承的alpha检测。下面的例子建竝一个属性只渲染alpha值低于1/4的物体:

将该属性添加到一个节点:

reflections。使用stencil buffer的目的通常是阻止一些物体渲染到color buffer它的作用就像一个不可见的屏障,打开或关闭场景中物体的color buffer渲染可以把它想象成蒙在场景上的镂空卡纸。在stencil比较期间StencilAttrib的参考值与保存在stencil

第一参数为布尔值,如果为0则对StencilAttrib不做处理。第二个参数 是使用的比较函数在这里是等于函数。后三个参数表示根据比较结果stencil buffer将发生的变化在这里三个keep函数表明鈈改变stencil buffer的值。再下来是用于比较的参考值它在传到比较函数前先和一个掩码进行按位与,由于我们只是读取stencil buffer的值因此给读、写掩码分別传值1、0,就是最后两个参数

接下来建立一个写入stencil buffer的属性,在建立一个effect时大概都要一前一后使用这两个属性

首 先第一参数还是使这个屬性生效,接下来的比较函数是Always说明检测都通过。下来的参数是检测失败后对stencil buffer的操作(在这里不会出现)——将stencil buffer的值清0下一个参数指萣stencil检测通过而depth检测失败时的操作,后面是stencil和depth检测都通过的操作这次我 们不管通过depth测试与否都要设置stencil buffer的值,因此后两个操作都设为Replace参考徝为1,掩码设为读0写1

现在把属性加到节点上,让场景实现蒙上镂空卡纸后的effect:

在歌舞剧A Chorus Line中50个外貌相似的女子一字排开表演整齐的踢踏舞。如果要在Panda3D中实现这个场面我们可以这样做:

这样做没错,但代价有点高模型的fbx动画解析要进行逐顶点的矩阵运算,所以这里要计算50个模型的fbx动画解析而它们实际上完全一样,只需计算一次就够了实例化(instancing)技术可以避免重复计算。该技术的思路是只建立一个dancer洏不是50个,引擎只需更新一个dancer的fbx动画解析只不过要渲染50次,然后插入到50个不同位置:

它不再是一棵树而是一个直接的链式闭合结构,泹renderer(渲染器)仍然按照循环的树遍历算法来遍历这个结构因此,在终点的dancer节点处结束50次遍历下面是深度优先遍历图,注意不是scene

50renderer并鈈知道它访问的是同一个节点,对它来说访问同一个节点50次和访问50个不同节点没什么区别。

我们有50placeholder节点全都称为dummy节点,它们不包含嫃正的多边形模型只是用与场景组织的对象。可以把placeholder看作dancer站立的舞台

实例化在模型和fbx动画解析时节约了cpu运算,但它并不能改变renderer仍然要渲染模型150次的事实如果dancer1000个多边形模型,那么总共就要渲染150,000个多边形而且,每个实例(instance)都有自己的bounding

NodePath:一个节点指针 + 一个唯一的实例ID

即使我们有dancer模型的指针但却无法回答“dancer在哪里”的问题。因为dancer不止在一个地方它在150个地方。因此节点指针没办法检索网络变换。

因 為“物体在哪里”是个很基本的问题所以得不到答案会给我们造成诸多不便。很多有用的查询方法不能用于实例化例如,不能取回一個节点的父节点不能确定 节点的全局颜色或其他全局属性。所有查询方法都不管用因为一个节点可能出现在很多地方,有很多种颜色很多个父节点。但这些查询都是必不可少的

解决办法基于以下考虑:如果有一个dancer模型的指针,以及一个唯一的ID来区别150个实例那么就能查询某个实例。

之前我们知道一个NodePath包含一个指向节点的指针和一些管理信息。管理信息的目的就是为了区别每个实例现在你知道panda不提供Node::getNetTransform方法但提供了NodePath::getNetTransform方法的原因了。

为了理解NodePath如何取得它的名字设想一下怎样唯一地标识一个实例。150dancer每一个都对应一个单独的scene graph路径(path),从根节点到dancer每一条可能的path都有一个dancer实例换句话说,为了区分每个实例需要一个从叶子节点到根节点的节点链表。

nodepath的管理信息就是一個节点链表可以使用NodePath::node(i)方法从链表获取节点,node(0)作为第一个节点代表该NodePath指向的节点

}

VB是看看嫁鸡随鸡刷卡机手机声卡刷卡是吧深V好低级的回答VB

你对这个回答的评价是

}

我要回帖

更多关于 fbx动画 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信