SceneKit - 如何知道带有 MDLObject 的 SCNNode 是不是已加载并可见?

Posted

技术标签:

【中文标题】SceneKit - 如何知道带有 MDLObject 的 SCNNode 是不是已加载并可见?【英文标题】:SceneKit - How to know if SCNNode with MDLObject is loaded and visible?SceneKit - 如何知道带有 MDLObject 的 SCNNode 是否已加载并可见? 【发布时间】:2019-04-04 02:14:32 【问题描述】:

我在“渲染时”为 SCNNode 设置动画时遇到问题,所以我的问题是如何知道 SCNNode 已完全加载并在场景中可见?我想在加载/渲染后立即为其缩放设置动画。

我是这样初始化的:

NSString* ring = [[NSBundle mainBundle]
                 pathForResource:[NSString stringWithFormat:@"sweep"]
                 ofType:@"obj"];
NSURL *url = [NSURL fileURLWithPath:ring];

MDLAsset *asset = [[MDLAsset alloc]initWithURL:url];
self.node = [SCNNode nodeWithMDLObject:[asset objectAtIndex:0]];
self.node.geometry.firstMaterial = goldMaterial;
self.node.geometry.subdivisionLevel = 1;

[self.node setRotation:SCNVector4Make(-1, 0, 0, M_PI/2.5)]; //M_PI = 180d
[self.node setScale:SCNVector3Make(0.1, 0.1, 0.1)];
[scene.rootNode addChildNode: self.node];

然后我尝试添加这样的操作

SCNAction *scaleUp = [SCNAction scaleTo:1.0f duration:0.5f];
scaleUp.timingMode = SCNActionTimingModeEaseInEaseOut;
[self.node runAction:scaleUp];

但我的节点只是按比例放大,因为加载 obj 资产需要大约 2 秒。 当我将持续时间更改为 5 秒时,我可以看到动画。

我也尝试委托 SCNSceneRenderer: didRenderScene,但我也无法成功运行该动画。

【问题讨论】:

【参考方案1】:

你很幸运。我最近正在处理这个话题。假设您使用 SCNView 作为 SCNSceneRender,您可以将 rootNode 添加到以下调用中,然后在完成回调中处理其他操作,如下所示:

 // setup everything here. It's your code.

 NSString* ring = [[NSBundle mainBundle]
             pathForResource:[NSString stringWithFormat:@"sweep"]
             ofType:@"obj"];
NSURL *url = [NSURL fileURLWithPath:ring];

MDLAsset *asset = [[MDLAsset alloc]initWithURL:url];
self.node = [SCNNode nodeWithMDLObject:[asset objectAtIndex:0]];
self.node.geometry.firstMaterial = goldMaterial;
self.node.geometry.subdivisionLevel = 1;

[self.node setRotation:SCNVector4Make(-1, 0, 0, M_PI/2.5)]; //M_PI = 180d
[self.node setScale:SCNVector3Make(0.1, 0.1, 0.1)];
 [scene.rootNode addChildNode: self.node];
SCNAction *scaleUp = [SCNAction scaleTo:1.0f duration:0.5f];
scaleUp.timingMode = SCNActionTimingModeEaseInEaseOut;

 [self.node runAction:scaleUp];




SCNView * view; // you don't need this if you have one already.
[view prepareObjects:@[scene.rootNode] withCompletionHandler:^(BOOL success)   
    if(success) 
        //scene will be rendered after this point.
    
];

希望这是你需要的。

【讨论】:

谢谢,这正是我所需要的 :) 我什至有这部分,但经过几个小时的挫折后忘记了 if(success) :)

以上是关于SceneKit - 如何知道带有 MDLObject 的 SCNNode 是不是已加载并可见?的主要内容,如果未能解决你的问题,请参考以下文章

带有 SceneKit SCNProgram 的金属着色器

从 SceneKit 中的 SCNGeometry 中提取人脸信息

如何在 SceneKit 中使用 SCNBufferBindingBlock?

将带有物理的 collada 场景加载到 SceneKit

如何将复杂的 .dae 模型导入到 SceneKit?

如何在 SceneKit 中将 allowCameraControl 与相机节点一起使用