SceneKit gets the current SCNNode position form. Animated SCNNode

I want to get the current position shape of the node animated by SCNNode I know presentationNode , and I tried to extract the position shape there, but Luck

Here is my code

 SCNNode * pelvis = [_unit childNodeWithName:@"Bip01_Pelvis" recursively:YES]; SCNNode * present = pelvis.presentationNode; SCNVector3 position = [self convertPosition:present.position toNode:self.parentNode]; 

I have a SCNNode position in rest mode before applying CAAnimation .

How to get properties like position form 'presentationNode'?

Edit

Own sections of the class:

 @interface UndeadSimple : RepresentationNode <CAAnimationDelegate> { //Animations SCNNode * _undead; CAAnimation * _currentAnimation; NSString * _currAnimationkey; CAAnimation * _death1; ... SCNNode * _audioNode; SCNAudioSource * _deathSource; SCNAudioPlayer * _player; } 

Init:

 NSString * sceneName = @ZOMBIE; SCNScene *scene2 = [SCNScene sceneNamed:sceneName]; _undead = [SCNNode node]; for(SCNNode * node in scene2.rootNode.childNodes) { [_undead addChildNode:node]; [node removeAllAnimations]; } [_undead setScale:(SCNVector3Make(0.024, 0.02, 0.024))]; [self addChildNode:_undead]; [_undead removeAllAnimations]; _currentAnimation = _idleAnimation; _currAnimationkey = @"resting"; [_undead addAnimation:_currentAnimation forKey:_currAnimationkey]; 

Animation and event:

 SCNAnimationEvent * event2 = [SCNAnimationEvent animationEventWithKeyTime:0.9 block:^(CAAnimation * _Nonnull animation, id _Nonnull animatedObject, BOOL playingBackward) { [self.delegate finishedDeathAnimation]; }]; _death1 = anims.death1.mutableCopy; [_death1 setDelegate:self]; [_death1 setFillMode:kCAFillModeForwards]; _death1.removedOnCompletion = NO; [_death1 setAnimationEvents:@[event2]]; 

Animation call:

 - (void)die { if([_currAnimationkey isEqualToString:@"dead"]) { return; } [_undead removeAllAnimations]; CAAnimation * death = nil; int anim = arc4random_uniform(3); if(anim < 1) { death = _death1; } else if(anim < 2) { death = _death2; } else { death = _death3; } _currAnimationkey = @"dead"; _currentAnimation = death; 

}

// Helper Method For Getting A Node Presentation

 - (SCNNode *)getSnapNode { SCNNode * repNode = [_undead presentationNode]; _undead.transform = repNode.transform; repNode = _undead.clone; return repNode; } 

// When calling the callback and trying to get the position:

 - (void)finishedDeathAnimation { SCNPlane * bloodgeometry = [SCNPlane planeWithWidth:4 height:4]; bloodgeometry.firstMaterial.diffuse.contents = [NSImage imageNamed:@"blood"]; SCNNode * bloodNode = [SCNNode node]; [bloodNode setEulerAngles:SCNVector3Make(-M_PI_2, 0, 0)]; bloodNode.geometry = bloodgeometry; //Bip01_Pelvis SCNNode * deadBody = [_unit getSnapNode]; SCNNode * pelvis = [deadBody childNodeWithName:@"Bip01_Pelvis" recursively:YES]; SCNNode * present = pelvis.presentationNode; SCNVector3 position = [self convertPosition:present.position toNode:self.parentNode]; NSLog(@"pelvis position %lf,%lf,%lf", present.position.x, present.position.y, present.position.z); //Always {0,0,0} bloodNode.position = SCNVector3Make(position.x, 0.0001, position.z); [self.parentNode addChildNode:bloodNode]; [self removeFromParentNode]; } 

Edit 2

I also tried to simplify it a bit:

another helper method:

// in the undead / unit class

 - (SCNVector3)getPosition { SCNNode * repNode = [[_undead childNodeWithName:@"Bip01_Pelvis" recursively:YES] presentationNode]; return repNode.position; } 

In callback mode:

 - (void)finishedDeathAnimation { position = [_unit getPosition]; NSLog(@"pelvis position %lf,%lf,%lf", position.x, position.y, position.z); //Alway 0,0,0 as well :( } 
+5
source share
2 answers

It's rare to find someone like me who still believes in Objective-C, and not fast, so I would like to offer complete help.

I had this problem for animations exported from Blender as Collada, but she managed to get the actual position after several attempts.

Using presentationNode is the right way, but you need to get it from the child while you are doing the animation, for example, how to start the animation to notify the node Called _monkey that in the last code I got _present. child.presentationNode Not from _monkey.presentationNode Also it should be received during enumeration not after

so first i need to define

 NSNode * _present; 

then i play animation

  [_monkey enumerateChildNodesUsingBlock:^(SCNNode *child, BOOL *stop) { for(NSString *key in child.animationKeys) { // for every animation key CAAnimation *animation = [child animationForKey:key]; // get the animation animation.usesSceneTimeBase = NO; // make it system time based animation.repeatCount = FLT_MAX; // make it repeat forever animation.speed = 0.2; [child addAnimation:animation forKey:key]; // animations are copied upon addition, so we have to replace the previous animation } _present = child.presentationNode; }]; 

Then, under the render, I can check the results, which change as the animation moves (also if you worked with iOS11, you can check the worldPosition, not the position, this gives excellent results too).

 - (void)renderer:(id <SCNSceneRenderer>)renderer didSimulatePhysicsAtTime:(NSTimeInterval)time { NSLog(@" Location X:%f Y:%f Z:%f", _present.position.x, _present.position.y, _present.position.z); } 

Finally, here are the results

 Y:-2.505034 Z:4.426160 2017-10-11 04:42:19.700435+0200 monkey[547:137368] Location X:-5.266642 Y:-2.480119 Z:4.427162 2017-10-11 04:42:19.720763+0200 monkey[547:137368] Location X:-5.215315 Y:-2.455228 Z:4.428163 2017-10-11 04:42:19.740449+0200 monkey[547:137346] Location X:-5.163589 Y:-2.430143 Z:4.429171 2017-10-11 04:42:19.760397+0200 monkey[547:137368] Location X:-5.112190 Y:-2.405216 Z:4.430173 2017-10-11 04:42:19.780557+0200 monkey[547:137346] Location X:-5.060925 Y:-2.380355 Z:4.431173 2017-10-11 04:42:19.800418+0200 monkey[547:137342] Location X:-5.008560 Y:-2.355031 Z:4.432024 

This will give me good results. Hope it works for you.

+1
source

There is no animation, at least not in the code that you showed us. Check the presentation of the node while playing the animation, possibly in renderer:updateAtTime: (see SCNRendererDelegate).

+1
source

Source: https://habr.com/ru/post/1260604/


All Articles