如何将 .dae 文件加载到 iOS SceneKit 中的 SCNNode 中?
Posted
技术标签:
【中文标题】如何将 .dae 文件加载到 iOS SceneKit 中的 SCNNode 中?【英文标题】:How do you load a .dae file into an SCNNode in iOS SceneKit? 【发布时间】:2014-10-10 22:52:23 【问题描述】:我无法理解如何将 .dae
文件中的几何图形加载到 ios SceneKit 场景图中。
我知道您可以将.dae
文件直接加载到 SCNScene 中:
// create a new scene
let scene = SCNScene("test.scnassets/test.dae")
我也知道你可以创建一个空的 SCNScene 并将内置的 3D 对象作为子节点添加到其中:
let scene = SCNScene()
var sphereNode = SCNNode()
sphereNode.geometry = SCNSphere(radius: 1.0)
scene.rootNode.addChildNode(sphereNode)
在第二种情况下,您可以将.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))
但也许有更好的方法?以上涉及从 .dae 树中手动加载每个标识符。在我的文件中,有一个带有子标识符“ID2”和“ID10”的节点“SketchUp”。此方法不会让您加载根“SketchUp”。 (我得到一个运行时错误。)
【问题讨论】:
我已经发布了这个。这是一个链接。 ***.com/questions/25031774/… 谢谢。所以你的建议是使用SCNSceneSource
。不幸的是,这对我来说现在崩溃了。
您的代码中似乎有一个错误可以检索几何。该类应该是 SCNGeometry 而不是 SCNNode。例如:let block = source.entryWithIdentifier("ID10", withClass: SCNGeometry.self) as SCNGeometry
。有了这个修复,它对我有用。
是的,有一个错误。我将进行编辑。谢谢!
【参考方案1】:
通常的模式是加载您的场景并使用其名称检索您感兴趣的节点
[scene.rootNode childNodeWithName:aName recursively:YES];
然后您可以将此节点重新设置为您的主场景。
【讨论】:
但是在那种情况下,节点已经是根节点的直接子节点,对吗?因此,如果我需要它位于场景图中的某个其他节点下,我需要使用这种方法重新定位它。这就是为什么我要询问加载独立于 SCNScene 的 SCNNode 几何体。 无论如何,这是一个有用的方法。谢谢。 您通常会使用您的“其他”dae 文件创建一个新场景,检索您感兴趣的节点,并在您的主场景中重新设置它 您通常如何重新定义节点? 你可以看看WWDC 2014示例代码中的-[SCNNode asc_addChildNodeNamed:fromSceneNamed:withScale:]
扩展方法。构建场景,使用-childNodeWithName:recursively:
获取节点,然后将-addChildNode:
简单地添加到主场景中的节点。【参考方案2】:
我有一个类似的问题,我有一个 .dae 文件,我想将该文件中的多个节点加载到一个节点中。这对我有用:
var node = SCNNode()
let scene = SCNScene(named: "helloScene.dae")
var nodeArray = scene.rootNode.childNodes
for childNode in nodeArray
node.addChildNode(childNode as SCNNode)
首先,我设置了一个节点,它将所有内容保存在一起,使其看起来像在原始文件中一样。接下来我们导入我们想要的 .dae 文件并复制其中的所有节点。最后,对于数组中的每个节点,我将其添加到节点中。
【讨论】:
我用 var nodeArray = scene!.rootNode.childNodes 替换了 var nodeArray = scene.rootNode.childNodes【参考方案3】:感谢您的帮助!
这是一个简单的 collada2Node 类。
//collada2SCNNode
class func collada2SCNNode(filepath:String) -> SCNNode
var node = SCNNode()
let scene = SCNScene(named: filepath)
var nodeArray = scene!.rootNode.childNodes
for childNode in nodeArray
node.addChildNode(childNode as SCNNode)
return node
【讨论】:
【参考方案4】:func nodeWithFile(path: String) -> SCNNode
if let scene = SCNScene(named: path)
let node = scene.rootNode.childNodes[0] as SCNNode
return node
else
println("Invalid path supplied")
return SCNNode()
【讨论】:
【参考方案5】:以下答案对我不起作用。
这是在 Xcode 7.0 beta 5、iOS 9.0 beta / Swift 2.0 中对我有用的:
3D 模型类型:科拉达 3D 模型名称:“model.dae”
加载场景:
let lampScene = SCNScene(named: "art.scnassets/model.dae")
访问SCNScene中的子SCNode:
let lampRootNode = lampScene?.rootNode.childNodes[0]
将加载场景中的灯节点添加到当前加载并查看的场景中:
self.scene.rootNode.addChildNode(lampRootNode!)
注意:self.scene
存在的原因是:
private var scene:SCNScene!
在将对象添加到场景之前,我已经根据场景套件示例进行了一些场景设置。如果您需要代码,请在 cmets 中提及。
希望对你有帮助。
【讨论】:
你为什么不使用 SCNReferenceNode?这种方法有优势吗?【参考方案6】:guard let shipScene = SCNScene(named: "ship.dae") else return
let shipNode = SCNNode()
let shipSceneChildNodes = shipScene.rootNode.childNodes
for childNode in shipSceneChildNodes
shipNode.addChildNode(childNode)
【讨论】:
以上是关于如何将 .dae 文件加载到 iOS SceneKit 中的 SCNNode 中?的主要内容,如果未能解决你的问题,请参考以下文章
将 collada (dae) 文件加载到 SCNNode (Swift - SceneKit)
将 Collada dae 文件加载到 SceneKit 以进行联合操作
Android 将 FBX 或 Collada(.dae) 加载到 Android Studio Activity 中
如何在 SceneKit 中使用 OBJ 文件或 CTM 文件而不是 DAE 文件?