SceneKit - Как узнать, если SCNNode с MDLObject загружен и видим? - PullRequest
0 голосов
/ 31 октября 2018

У меня проблема с анимацией 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 Ответ

0 голосов
/ 31 октября 2018

Вам повезло. Я занимаюсь этой темой в последнее время. Предположим, что вы используете 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.
    }
}];

Надеюсь, это то, что вам нужно.

...