SceneKit – Playing DAE and USDZ animation using Objective-C
Asked Answered
V

1

6

I want to create walking man animation in SceneKit. I'm exporting animated .dae files from 3DSMax + OpenCollada , I also use ConvertToXcodeCollada to combine all animations in one. How i get animation:

 SCNScene *humanScene = [SCNScene sceneNamed:@"art.scnassets/myScene.DAE"];

CAAnimation *Animation = [[humanScene rootNode] animationForKey:@"myScene-1"];

I also try to get animation from "SCNSceneSource"

How i add animation:

SCNNode *humanNode = [humanScene.rootNode childNodeWithName:@"myScene-1" recursively:YES];
[humanNode addAnimation:walkingAnimation forKey:@"myScene-1"];

or:

SCNNode* humanNode = [SCNNode new];
for(SCNNode* node in humanScene.rootNode.childNodes){
    [humanNode addChildNode:node];
} 
[humanNode addAnimation:walkingAnimation forKey:@"myScene-1"];

My object "walkingAnimation" is "CAAnimationGroup".

But it doesn't animate in application. I can see animation only in Xcode sceneKit editor.

example of my .DAE file

Vaporizer answered 1/11, 2016 at 10:45 Comment(1)
the issue is that i am using SCNRender to render animation objects in openGLContextVaporizer
B
0

Try the following code with your model. It works. I used Xcode 13.2.1 in macOS 12.1.

At first fill viewDidLoad method:

#import "GameViewController.h"

@implementation GameViewController

SCNView *sceneView;
bool notRunningSwitch;
NSMutableDictionary<NSString*, CAAnimation*> *animations;
SCNNode *node;

- (void)viewDidLoad
{
    [super viewDidLoad];

    sceneView = (SCNView *)self.view;
    notRunningSwitch = YES;
    animations = @{}.mutableCopy;
    node = [SCNNode node];
    
    SCNScene *scene = [SCNScene scene];
    sceneView.scene = scene;
    sceneView.autoenablesDefaultLighting = YES;
    sceneView.allowsCameraControl = YES;

    [self anime];
}

Then anime and loadAnime methods:

- (void)anime
{
    SCNScene *standStillScene = [SCNScene sceneNamed:@"art.scnassets/Idle"];
    
    for (SCNNode *childNode in standStillScene.rootNode.childNodes)
    {
        [node addChildNode:childNode];
    }
    
    node.scale = SCNVector3Make(0.1, 0.1, 0.1);
    node.position = SCNVector3Make(0, 0,-2.5);

    [sceneView.scene.rootNode addChildNode: node];

    [self loadAnime:@"running" inScene:@"art.scnassets/Running" withID:@"Running-1"];
}

- (void)loadAnime:(NSString*)withKey inScene:(NSString*)scene withID:(NSString*)id
{
    NSURL *url = [NSBundle.mainBundle URLForResource:scene withExtension:@"usdz"];
    
    SCNSceneSource *source = [SCNSceneSource sceneSourceWithURL:url options:Nil];
    
    CAAnimation *charAnimation = [source entryWithIdentifier:id 
                                                   withClass:CAAnimation.self];

    charAnimation.repeatCount = 1;
    charAnimation.fadeInDuration = 1;
    charAnimation.fadeOutDuration = 1;

    [animations setValue:charAnimation forKey:withKey];
}

And at last touchesBegan:

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    CGPoint point = [touches.allObjects.firstObject locationInView: sceneView];

    NSDictionary<SCNHitTestOption, id> *options = @{ SCNHitTestBoundingBoxOnlyKey: @(YES) };
    
    NSArray<SCNHitTestResult *> *hitTestResults = [sceneView hitTest: point options: options];
        
    if (notRunningSwitch == YES) {
        [sceneView.scene.rootNode addAnimation:animations[@"running"] forKey:@"running"];
    } else {
        [sceneView.scene.rootNode removeAnimationForKey:@"running" blendOutDuration:1.0];
    }
    notRunningSwitch = !notRunningSwitch;
    
    NSLog(@"%@", hitTestResults.firstObject.node.name);
    NSLog(@"%f", hitTestResults.firstObject.modelTransform.m43);
}

@end
Bimestrial answered 26/1, 2022 at 14:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.