Open Nanxia opened 6 years ago
only a portion of the animation
.NSString *filePath = [[NSBundle mainBundle] pathForResource:@"duilian" ofType:@"FBX"];
self.modelFilePath = filePath; self.animFilePath = self.modelFilePath;
SCNAssimpScene *scene = [SCNScene assimpSceneWithURL:[NSURL URLWithString:self.modelFilePath] postProcessFlags:AssimpKit_Process_FlipUVs | AssimpKit_Process_Triangulate];
// Load the animation scene if (self.animFilePath) { SCNAssimpScene animScene = [SCNScene assimpSceneWithURL:[NSURL URLWithString:self.animFilePath] postProcessFlags:AssimpKit_Process_FlipUVs | AssimpKit_Process_Triangulate]; NSArray animationKeys = animScene.animationKeys; // If multiple animations exist, load the first animation if (animationKeys.count > 0) { SCNAssimpAnimSettings *settings = [[SCNAssimpAnimSettings alloc] init]; settings.repeatCount = 3;
NSString *key = [animationKeys objectAtIndex:0];
SCNAnimationEventBlock eventBlock =
^(CAAnimation *animation, id animatedObject,
BOOL playingBackward) {
NSLog(@" Animation Event triggered ");
// To test removing animation uncomment
// Then the animation wont repeat 3 times
// as it will be removed after 90% of the first loop
// is completed, as event key time is 0.9
// [scene.rootNode removeAnimationSceneForKey:key
// fadeOutDuration:0.3];
// [scene.rootNode pauseAnimationSceneForKey:key];
// [scene.rootNode resumeAnimationSceneForKey:key];
};
SCNAnimationEvent *animEvent =
[SCNAnimationEvent animationEventWithKeyTime:0.1f
block:eventBlock];
NSArray *animEvents =
[[NSArray alloc] initWithObjects:animEvent, nil];
settings.animationEvents = animEvents;
settings.delegate = self;
SCNScene *animation = [animScene animationSceneForKey:key];
[scene.modelScene.rootNode addAnimationScene:animation
forKey:key
withSettings:settings];
} }
// retrieve the SCNView SCNView scnView = (SCNView )self.view;
// set the scene to the view scnView.scene = scene.modelScene;
// allows the user to manipulate the camera scnView.allowsCameraControl = YES;
// show statistics such as fps and timing information scnView.showsStatistics = YES;
// configure the view scnView.backgroundColor = [UIColor blackColor];
scnView.scene.rootNode.position = SCNVector3Make(0, 0, -50);
scnView.playing = YES; }
After I tried to change the AssimpKit source code, I solved the animation problem but did not know if it was correct and the changes were as follows:
No change before :
After the change :
Thanks for providing the file. Comparing it with FBX review tool, I can see only 1 vertical block on the left is animated using AssimpKit.
Btw, your code change is wrong and unnecessary. You should probably read how to load animations.
The gist is: you load the model scene, then load the animations (from the scene you just loaded or another scene if they are defined externally) and add the animation to the model scene. The above docs referred to use the same scenarios.
So AssimpKit loading FBX animation is a problem right?
The correct way is as follows:
(void)viewDidLoad { [super viewDidLoad];
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"duilian" ofType:@"FBX"];
SCNAssimpScene animScene = [SCNScene assimpSceneWithURL:[NSURL URLWithString:filePath] postProcessFlags:AssimpKit_Process_FlipUVs | AssimpKit_Process_Triangulate]; NSArray animationKeys = animScene.animationKeys; // If multiple animations exist, load the first animation if (animationKeys.count > 0) { SCNAssimpAnimSettings *settings = [[SCNAssimpAnimSettings alloc] init]; settings.repeatCount = 3;
NSString *key = [animationKeys objectAtIndex:0];
SCNAnimationEventBlock eventBlock =
^(CAAnimation *animation, id animatedObject,
BOOL playingBackward) {
NSLog(@" Animation Event triggered ");
// To test removing animation uncomment
// Then the animation wont repeat 3 times
// as it will be removed after 90% of the first loop
// is completed, as event key time is 0.9
// [scene.rootNode removeAnimationSceneForKey:key
// fadeOutDuration:0.3];
// [scene.rootNode pauseAnimationSceneForKey:key];
// [scene.rootNode resumeAnimationSceneForKey:key];
};
SCNAnimationEvent *animEvent =
[SCNAnimationEvent animationEventWithKeyTime:0.9f
block:eventBlock];
NSArray *animEvents =
[[NSArray alloc] initWithObjects:animEvent, nil];
settings.animationEvents = animEvents;
settings.delegate = self;
SCNScene *animation = [animScene animationSceneForKey:key];
[animScene.modelScene.rootNode addAnimationScene:animation
forKey:key
withSettings:settings];
}
// retrieve the SCNView SCNView scnView = (SCNView )self.view;
// set the scene to the view scnView.scene = animScene.modelScene;
// allows the user to manipulate the camera scnView.allowsCameraControl = YES;
// show statistics such as fps and timing information scnView.showsStatistics = YES;
// configure the view scnView.backgroundColor = [UIColor blackColor];
scnView.scene.rootNode.position = SCNVector3Make(0, 0, -20);
scnView.playing = YES; }
Yes, hence I have labeled this issue as a bug.
Thank you @dmsurti for sharing, looking forward to your update
Hi! Any updates?
I'm banging my head against the wall on similiar issue downstream with swift port https://github.com/eugenebokhan/AssetImportKit/issues/14
failed attempts to get my fbx import to animate in swift. @Nanxia - I followed your instructions but no joy. https://github.com/johndpope/demo-unistroy
if let pathToObject = Bundle.main.path(forResource: "ely", ofType: "fbx") {
let scaleFactor:Float = 0.0025
do {
// 1. you load the model scene
let assimpScene = try SCNScene.assimpScene(filePath: pathToObject, postProcessSteps:[.defaultQuality]) //realtimeFast realtimeQuality realtimeMaxQuality [.optimizeGraph,
// ( add the model to the scene / scale it down / is this wrong?)
let modelScene = assimpScene.modelScene!
modelScene.rootNode.childNodes.forEach {
$0.position = $0.position * scaleFactor
$0.scale = $0.scale * scaleFactor
sceneView.scene.rootNode.addChildNode($0) // the robot is added - it has a root - below it fails to add animation due to no root: nil nil
self.robotNode = $0
}
// print("skeletonNode:",assimpScene.skeletonNode)
// print("animations:",assimpScene.animations)
// print("animationKeys:",assimpScene.animationScenes.allKeys)
//assimpScene.makeAnimationScenes()
// for animSceneKey in assimpScene.animations.allKeys {
// if let animSceneKey = animSceneKey as? String {
// if let assimpAnim = assimpScene.animations.value(forKey: animSceneKey) as? AssetImporterAnimation {
// let animScene = SCNScene()
// animScene.rootNode.addChildNode(assimpScene.skeletonNode.clone())
// assimpScene.addAnimation(assimpAnimation: assimpAnim,to: assimpScene.modelScene!)
// assimpScene.animationScenes.setValue( assimpScene.modelScene!,forKey: animSceneKey)
// }
// }
// }
//
// 2. then load the animations
// either these lines are wrong... OR
for (_,animScene) in assimpScene.animationScenes{
print("animScene:",animScene)
if animScene is SCNScene{
let animation = assimpScene.animations["ely-1"] as! AssetImporterAnimation
print("animation:",animation)
// 3. and add the animation to the model scene.
// assimpScene.modelScene!.rootNode.addAnimationScene(animation, forKey: "ely-1", with: settings) // FAILS
// self.robotNode?.parent?.addAnimationScene(animation, forKey: "ely-1", with: settings) // FAILS
// self.robotNode?.addAnimationScene(animation, forKey: "ely-1", with: settings) // FAILS
// sceneView.scene.rootNode.addAnimationScene(animation, forKey: "ely-1", with: settings) // FAILS
// just attempt to hijack view and coerce the animation scene to sceneView.scene
sceneView.scene = animScene as! SCNScene // FAILS
}
}
sceneView.isPlaying = true
sceneView.showsStatistics = true
}catch let error{
print("error:",error)
}
}
UPDATE - I got the library loading fbx + animations with swift / via carthage. The eugenebokhan/AssetImportKit seems to not work. https://github.com/johndpope/swift-2
if anyone knows how to pass the flags in swift - would like to know.
let flipUVs = AssimpKitPostProcessSteps.process_FlipUVs
let trianglulate = AssimpKitPostProcessSteps.process_Triangulate
// let flags = [flipUVs,trianglulate] // passing this doesn't work.
let scene = SCNScene.assimpScene(with: modelFileURL,postProcessFlags:trianglulate)
AssimpKit can not display all the animations of the FBX model, only a portion of the animation. I would like to ask what is the reason for such a result