这是Apple的Fox示例代码的屏幕截图.如您所见,它们使用.scn文件格式作为图形对象.他们在wwdc2015视频中明确指出这是由艺术家完成的.到目前为止,我只与.dae合作,直到最近才确信这是唯一受支持的格式.我的问题是,如何将存储在.dae文件中的对象导出到.scn文件?
编辑:这是我得到的编辑 - >转换为SceneKit场景文件格式(.scn)
我一直在研究各种各样的地方,试图获得网格的宽度和高度,但我已经能够找到任何有用的东西.我有一个我导入的collada模型,我想要做的就是在Webgl/Three.js单位中获取它的尺寸,以便我可以在我的简单游戏中计算碰撞.那么我如何在THREE.js中获取网格的宽度和高度呢?
我正在写一个游戏引擎,我想知道我应该使用什么3D模型格式/加载/导出?Obj看似普遍且容易,但它似乎也不可靠,因为那里的大多数模型都包含错误,并且它不存储任何接近其他格式的地方.
似乎有专门用于MD2/3/5等游戏的格式,但我不确定,如果我建模我会使用wings3d,而且我不知道除了纯粹加载我需要的内容以及格式ID必须支持的其他细节实现,比如我需要实现IK?我可以使用脚本化的每片动画而不是反向运动学和骨骼绑定吗?
我正在尝试将自定义3D模型格式导出到Collada.我已经通过XSD构建了Collada数据类,现在当我尝试用数据填充它们时会出现问题,特别是对于矩阵的问题.
我的Skeleton类基本上是一个Joint类的数组,我从二进制文件中读取,每个Joint看起来像这样(traslation和rotation的值相对于父Joint,或者如果没有父,则始终为Root):
class Joint
{
List<Joint> Children;
Quaternion Rotation;
Joint Parent;
String Name;
UInt32 Id;
Vector3 Traslation;
}
Run Code Online (Sandbox Code Playgroud)
我要做的第一件事是在文件的"library_visual_scenes"部分中构建JOINT节点.这很简单,我得到了正确的结果:
foreach (Joint joint in hierarchicalJoints)
WriteJointNodes(joint);
private void WriteJointNodes(Joint joint)
{
Vector3 rotationEulers = Quaternion.ToEulers(joint.Rotation, EulersOrder.ZYX);
WriteStartElement("node");
WriteAttributeString("id", String.Concat(joint.Name, "_id"));
WriteAttributeString("type", "JOINT");
WriteAttributeString("name", joint.Name);
{
WriteElementString("translate", bone.Traslation);
WriteElementStringAttributes("rotate", String.Concat("0.0 0.0 1.0 ", rotation.Z.ToDegrees()), { "sid", "rotateZ" });
WriteElementStringAttributes("rotate", String.Concat("0.0 1.0 0.0 ", rotation.Y.ToDegrees()), { "sid", "rotateY" });
WriteElementStringAttributes("rotate", String.Concat("1.0 0.0 0.0 ", rotation.X.ToDegrees()), { "sid", "rotateX" });
WriteElementString("scale", "1.0 1.0 1.0"); …
Run Code Online (Sandbox Code Playgroud) 我一直在网上阅读很多思考,COLLADA是一种死文件格式?因为应用程序没有更新它们的支持等.这是真的吗?它最初被设计成一种几乎可以独立应用的格式,所以我的问题分为两部分.这是死格式吗?如果是这样,目前可接受的格式是什么才能最大化应用程序间开发(以及与OpenGL应用程序一起使用)?
我无法理解.dae
文件中的几何应该如何加载到iOS SceneKit场景图中.
我知道你可以.dae
直接将文件加载到SCNScene中:
// create a new scene
let scene = SCNScene("test.scnassets/test.dae")
Run Code Online (Sandbox Code Playgroud)
我也知道你可以创建一个空的SCNScene并将内置的3D对象作为子节点添加到其中:
let scene = SCNScene()
var sphereNode = SCNNode()
sphereNode.geometry = SCNSphere(radius: 1.0)
scene.rootNode.addChildNode(sphereNode)
Run Code Online (Sandbox Code Playgroud)
在第二种情况下,您可以将.dae
文件加载到SCNNode而不是使用内置对象吗?或者是否.dae
需要首先将所有文件加载到SCNScene中?
如果后者为真,那么如何将SCNNode对象放在SCNScene下的场景图层次结构中的正确位置?编辑#1:
这对我来说很有用,这是@FlippinFun建议的修改版本.
let url = NSBundle.mainBundle().URLForResource("test.scnassets/test", withExtension: "dae")
let source = SCNSceneSource(URL: url, options: nil)
let block = source.entryWithIdentifier("ID10", withClass: SCNGeometry.self) as SCNGeometry
scene.rootNode.addChildNode(SCNNode(geometry: block))
Run Code Online (Sandbox Code Playgroud)
但也许有更好的方法?以上涉及从.dae树手动加载每个标识符.在我的文件中,有一个节点"SketchUp",子标识符为"ID2"和"ID10".此方法不允许您加载根"SketchUp".(我收到运行时错误.)
Google的Sketchup是一个不错的简单3D对象建模器.此外,谷歌拥有一个巨大的3D物体仓库,因此如果你不是特别有天赋的话,你实际上不需要做太多的建模.Google地球中的许多3D建筑都是使用Sketchup制作的.在Mathematica中导入Sketchup的SKP文件的能力非常好,但是,它还没有这样做.
Sketchup 的免费版本不会导出为KMZ(Google Earth)和DAE(Collada)格式之外的任何其他格式.虽然MMA可以读取KMZ/KML文件,但它不会读取包含3D对象的文件.DAE文件是压缩的Collada文件,这些文件可以通过MMA的Import读取为XML.生成的XML树相当复杂,Collada的定义也很复杂,并且获取对象的几何结构远非微不足道(我设法强制模型的坐标集).
我的问题是:如何在Mathematica中基于干净多边形的结构转换SKP文件?
我更喜欢为MMA提供此导入功能的导入转换器,但也欢迎其他路由.我将发布我目前正在使用的相当间接的方法作为明天的答案.
我正准备用Java写一个COLLADA导入器.没有任何预先写好的进口商,即使有可能我会挑剔,所以我相信这是最好的.我将使用COLLADA 1.4,因为我不需要1.5功能,许多程序还不支持它.我找到了它的规范并计划跟随它,但是通过示例更容易,并参考规范以获取更多信息.
所有这些......在COLLADA经验丰富的人中,有些人能指出一些我可以用来学习和测试我的进口商的简单模型吗?我将导出几个只有几何,但我需要一些纹理或材料,骨架和关键帧动画等.任何建议?
或者,我知道Blender可以导出COLLADA 1.4,它可以导入大多数格式.如果你对一个拥有另一种格式的简单3D模型的网站有一个非常好的建议,我将导入和导出为COLLADA,那也没关系!
谢谢!
我对了解scenekit几何有问题.
我有Blender的默认立方体,我导出为collada(DAE),并且可以将它带入scenekit ....一切都很好.
现在我想看到立方体的顶点.在DAE中,我可以看到"Cube-mesh-positions-array"的以下内容,
"1 1 -1 1 -1 -1 -1 -0.9999998 -1 -0.9999997 1 -1 1 0.9999995 1 0.9999994 -1.000001 1 -1 -0.9999997 1 -1 1 1"
现在我想在scenekit中做的是使用以下内容返回顶点:
SCNGeometrySource *vertexBuffer = [[cubeNode.geometry geometrySourcesForSemantic:SCNGeometrySourceSemanticVertex] objectAtIndex:0];
Run Code Online (Sandbox Code Playgroud)
如果我处理vertexBuffer(我已经尝试了很多查看数据的方法),它似乎不正确.
有人可以解释"SCNGeometrySourceSemanticVertex"给我的内容,以及如何正确提取顶点数据?我想看到的是:
X = "float"
Y = "float"
Z = "float"
Run Code Online (Sandbox Code Playgroud)
此外,我正在调查以下类/方法,这看起来很有前景(这里有一些好的数据值),但是来自gmpe的数据显示为空,是否有人能够解释"SCNGeometryElement"的数据属性包含什么?
SCNGeometryElement *gmpe = [theCurrentNode.geometry geometryElementAtIndex:0];
Run Code Online (Sandbox Code Playgroud)
谢谢,非常感谢,
d
我正在编写自己的COLLADA导入器.我已经相当远,加载网格和材料等.但我在动画方面遇到了障碍,特别是联合轮换.
我用来为我的网格蒙皮的公式是直截了当的:
weighted;
for (i = 0; i < joint_influences; i++)
{
weighted +=
joint[joint_index[i]]->parent->local_matrix *
joint[joint_index[i]]->local_matrix *
skin->inverse_bind_pose[joint_index[i]] *
position *
skin->weight[j];
}
position = weighted;
Run Code Online (Sandbox Code Playgroud)
就文献而言,这是正确的公式.现在,COLLADA为关节指定了两种类型的旋转:局部和全局.您必须将旋转连接在一起以获得关节的局部变换.
COLLADA文档没有区分的是联合的局部轮换和联合的全局轮换.但在我见过的大多数模型中,旋转可以具有rotate
(全局)或jointOrient
(本地)的id .
当我忽略全局旋转并仅使用本地旋转时,我得到了模型的绑定姿势.但是当我将全局旋转添加到关节的局部转换时,奇怪的事情开始发生.
这不使用全局轮换:
这是全球轮换:
在这两个截图中,我使用线条绘制骨架,但在第一个中它是不可见的,因为关节位于网格内部.在第二个屏幕截图中,顶点到处都是!
为了比较,这是第二个截图应该是这样的:
很难看到,但你可以看到第二个屏幕截图中的关节处于正确的位置.
但现在奇怪的是.如果我忽略了COLLADA指定的反向绑定姿势,而是采用关节的父本地变换的倒数乘以关节的局部变换,我得到以下结果:
在这个截图中,我从每个顶点到有影响的关节画一条线.我得到绑定姿势的事实并不那么奇怪,因为现在公式变为:
world_matrix * inverse_world_matrix * position * weight
Run Code Online (Sandbox Code Playgroud)
但它让我怀疑COLLADA的反向绑定姿势是在错误的空间.
所以我的问题是:COLLADA在什么空间指定其反向绑定姿势?如何将逆绑定姿势转换为我需要的空间?