【问题标题】:Don't have childNodes when running on device在设备上运行时没有子节点
【发布时间】:2015-12-31 16:35:35
【问题描述】:

我创建了一个简单的项目来试用 SceneKit,添加了一个包含人物角色和相机的场景。

问题是代码在模拟器和设备上的行为不同。

当将人角色加载到 SCNNode 对象中时,在模拟器中,这个“人”节点具有子节点,这些子节点本身包含几何体。

但是,在设备上运行时,man 节点不包含子节点,并且本身具有几何结构。

为什么会这样?谁能解释一下我到底搞砸了什么?

我已将示例项目上传到 GitHub,因此您可以查看它并在您的模拟器和设备上运行它。

https://github.com/iamBlueGene/SceneKitExperiment

谢谢,伊莱。

【问题讨论】:

    标签: ios objective-c cocoa-touch scenekit


    【解决方案1】:

    我想我已经想通了。

    问题是由于顶点在.dae文件中的容器中被分割是由于顶点数量的限制,不同的配置可以不同的打开文件。

    您可以尝试再次打开场景并再次导出它(或者如果可以,也可以只导出角色)并再次检查。

    【讨论】:

      【解决方案2】:

      我将以下方法添加到您的ViewController.m 只是为了看看发生了什么。

      - (void)printNodeTree: (SCNNode*)node levelIndent:(NSString*) indent{
      
          if (node != nil) {
              BOOL hasGeom = node.geometry == nil;
              NSString *nodeName = [NSString stringWithFormat:@"%@%@", indent, node.name];
              NSString *geomStr = [NSString stringWithFormat:@"%@ has geometry: %@", indent, hasGeom ? @"YES" : @"NO"];
              printf("%s \n", [nodeName UTF8String]);
              printf("%s \n", [geomStr UTF8String]);
      
              for (id childNode in [node childNodes]) {
                  [self printNodeTree:childNode levelIndent:[NSString stringWithFormat:@"%@   ",indent]];
              }
          } else {
              return;
          }
      }
      

      在模拟器和设备上运行时(传递对 man 节点的引用时)收到以下输出。

      Model_1 
       has geometry: YES 
         Model_1-splitContainer 
          has geometry: YES 
            Model_1-splitContainer-split0 
             has geometry: NO 
            Model_1-splitContainer-split1 
             has geometry: NO 
            Model_1-splitContainer-split2 
             has geometry: NO 
            Model_1-splitContainer-split3 
             has geometry: NO 
            . . .
      

      这似乎与您在设备上运行时看到的一致。查看 XCode 场景编辑器和 Blender 显示有几个组件显然正在合并。

      您可以在导入场景时指定一些选项。默认记录为不平整场景(正如我们观察到的那样),但只是为了确认我尝试了以下操作。这产生了与上面相同的输出。

      NSDictionary* sceneLoadOpts = [NSDictionary dictionaryWithObjectsAndKeys:
          SCNSceneSourceFlattenSceneKey, [NSNumber numberWithBool:NO],
          nil];
      
      SCNScene *characterScene = [SCNScene sceneNamed:@"character-male-muscle.dae"
          inDirectory:nil 
          options:sceneLoadOpts];
      

      设备(或模拟器)不会直接加载.dae 文件。这是由scntool 编译成一个c3d 文件。我将 dae 转换为 c3d 文件,然后再转换回 dae,发现仍然存在不同的组件。扁平化不是这种压缩过程的结果。

      最后,我在 Blender 中加载了模型并重新排列了模型树,使所有几何节点都与父节点处于同一级别。这确实导致模拟器和设备上都有多个几何组件,但这可能有点远......

      顶点数 (65535) 和这些组件的名称 ("splitContainerX") 似乎表明它们只是单独的几何组件,因为顶点索引 (2^16) 的限制。简而言之,我不认为您真的想将此模型视为单独的组件。目前的理论是,dae 文件中的某处有一个标志,表明这些组件应尽可能合并。

      【讨论】:

      • 我有两台 mac,我在它们上运行同一个项目,在我的 iMac 上,man 节点确实有我期望的所有子节点(与模拟器上相同),但是在我的 macbook 上运行时,即使使用您指定的加载选项,这也是我在 po<SCNNode: 0x1567300b0 'Model_1' rot(-1.000000 0.000000 0.000000 1.575542) scale(1.000000 1.000000 1.000000) | geometry=<SCNGeometry: 0x1565f53f0 'Model_1Mesh'> | no child> 时得到的
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-28
      • 1970-01-01
      • 2012-01-23
      • 2020-09-11
      • 2018-03-18
      • 2015-08-30
      相关资源
      最近更新 更多