JCPalmer Posted January 4, 2016 Share Posted January 4, 2016 I do not see where AnimationRanges can be placed in a .babylon file. Just thinking out loud, but this might a method of implementing the export of Actions in Blender, which are also named. I got 90% down the Mocap path using a .bvh, and am just making sure I am really going the right way. (Questioning myself usually happens when I stopping on something for a while, holidays) The really big reason I went the mocap route is to try to reduce say a 2 second walk @ 120 fps to maybe 5 poses, where the frame number indicates the relative amount of time to interpolate to each pose. I have code which is starting to do that analysis. Frame based animation is not scalable, because it "performs" the animation externally (pose>>Animation>>Bake Action) & the file size just explodes. I have no intention of using it. I know Blender had a way of actually posing skeletons on just the key frames, but until I actually started playing with inverse kinematics, posing was impossible. I have performed tests in python & can determine which frames the poses occur in an action. I think I can @ the skeleton level:iterate through the actionsget the key frames of an actioniterate through those framesget the bone matrix of each boneIf going to a .babylon / BJS, just make sure every action was baked. If going to .js / QueuedInterpolation, skip the bake. Either way, both should able to get multiple animations via AnimationRanges if they can be put in a .babylon. Also, right now the animation is captured by iterating through every frame in the scene for EVERY bone. Blends with skeletal animation export very slowing. One with a 32 bone skeleton should get a 32x speed up when exporting If you have a skeleton you are going to use in a .blend all by itself, then you could add your actions to it. You can then add those actions to any other .blend using File>>append. This separates the animation from the character. What am I thinking that is wrong? Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted January 4, 2016 Share Posted January 4, 2016 If we want animation ranges we need to add a new placeholder for them alongside animations (like at the end, after the keys for instance) I see no problem with this idea Quote Link to comment Share on other sites More sharing options...
JCPalmer Posted January 4, 2016 Author Share Posted January 4, 2016 Ok, the range info would need to stored in skeleton during pass 1. It would then need to be passed to each bone's to_script_file() / to_scene_file() method. Not a big deal, since these are called within the skeleton's writing method. What is 2.3 production timeframe? Will add lines to Skeleton.Parse untested if close. The .babylon format is usually developed after the .js works, not concurrent. Quote Link to comment Share on other sites More sharing options...
JCPalmer Posted January 6, 2016 Author Share Posted January 6, 2016 I implement the deletion of frames of a range in Animation:public deleteRange(name: string, deleteFrames?: boolean): void { for (var index = 0; index < this._ranges.length; index++) { if (this._ranges[index].name === name) { if (deleteFrames) { var from = this._ranges[index].from; var to = this._ranges[index].to; // this loop MUST go high to low for multiple splices to work for (var key = this._keys.length - 1; key >= 0; key--) { if (this._keys[key].frame >= from && this._keys[key].frame <= to) { this._keys.splice(key, 1); } } } this._ranges.splice(index, 1); return; } }}For a whole skeleton, I added this in Skeleton:public removeAnimationRange(rangeName : string): void { for (var i = 0, nBones = this.bones.length; i < nBones; i++) { this.bones[i].animations[0].deleteRange(rangeName, true); }}I implemented copyAnimationRange in both bone & skeleton. Skeleton's call each bones as they were matched up between skeletons. I added range parsing / serializing to Animation & hand edited a .babylon to add one. When I went to change the html, it is started in skeleton. I looked both skeleton & animation have _ranges. In order for this to work I need to also parse / serialize at skeleton and change my removeAnimationRange, and put the code inside skeleton.deleteRange. Right??? Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted January 7, 2016 Share Posted January 7, 2016 Correct Quote Link to comment Share on other sites More sharing options...
JCPalmer Posted January 7, 2016 Author Share Posted January 7, 2016 As you know, I never wait for answers. Over night, I cam to the same conclusion. Done, now in test. I made it so that skeleton.createAnimationRange(), skeleton.deleteAnimationRange(), also did the same to each bone's animations[0]. The skeleton.Parse calls createAnimationRange(), so the range need only be at the skeleton level in the JSON. This is a new feature for 2.3, so I made a couple of minor changes before they get locked in.deleteFrames arg of deleteRange() is now default true. Seems to only keep when explicitly requested.changed implementation of ranges- _ranges : { [name: string] : AnimationRange; } = {};Since a name was always being passed to calls, you can easily access without looping. Avoids writing loops to validate a range does not already exist in Parse from JSON. This can occur if a scene serialized, then reloaded. A little more testing, then PR. Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted January 8, 2016 Share Posted January 8, 2016 And do not forget to credit yourself in what's new Quote Link to comment Share on other sites More sharing options...
JCPalmer Posted January 8, 2016 Author Share Posted January 8, 2016 Yeah, I have a few todo, mostly all related to skeletons: this, variableBoneInfluencer, Blender exporter. Will do all at the same time. Making good progress in Actions support in Blender. Made this python class, AnimationRange, which has a static actionPrep method which makes the passed in action the current action. It figures the frames based on 'includeAllFrames' returns an AnimationRange instance.class AnimationRange: # constructor called by the static actionPrep method def __init__(self, name, frames, frameOffset): self.name = name self.highest_frame = frames[len(frames) - 1] self.frame_start = frameOffset + frames[0] self.frame_end = frameOffset + self.highest_frame self.frames = frames# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # assume the following JS variables have already been declared: skeleton. animation def to_script_file(self, file_handler, indent, isSkeleton): func = 'skeleton.createAnimationRange' if isSkeleton else 'animation.createRange' file_handler.write(indent + func + '("' + self.name + '", ' + format_int(self.frame_start) + ', ' + format_int(self.frame_start) + ');\n')# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @staticmethod def actionPrep(object, action, includeAllFrames, frameOffset, attrInBlender = None): # assign the action & test if there is any data for that action for this object object.animation_data.action = action if len(object.animation_data.action.fcurves) == 0: return None if includeAllFrames: frame_start, frame_end = [int(x) for x in action.frame_range] frames = range(frame_start, frame_end else: # capture built up from fcurves frames = dict() for fcurve in object.animation_data.action.fcurves: if attrInBlender != None and fcurve.data_path != attrInBlender: continue for key in fcurve.keyframe_points: frame = key.co.x frames[frame] = True # check that there were frames for this attribute if (len(frames) == 0): return None frames = sorted(frames) return AnimationRange(action.name, frames, frameOffset)This worked with my preminary test. The really good thing is you do not have to bake your skeleton poses, in fact you NEVER SHOULD, even when going to a .babylon. This will simply 'run' the animation and snap the matrices at that point. If you bake the poses & save the .blend then you cannot edit the key frames, or copy the action as easily. I also pulled iterating through the scene animation at the skeleton level, not bone, and did speed up. Finally, The Mesh, Camera, Light animations will have ranges. I am wondering if node.ts should convenience AnimationRanges like Skeleton? Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.