[1.1b] Sequences in character with different proportions (notquiteabug) - LOGGED
by Manoel Neto · in Torque 3D Professional · 02/26/2010 (11:41 am) · 28 replies
When porting the game I'm working on from beta 5 to 1.1 beta, my characters look strange when animated. They are using sequences which were designed for a character with different body proportions (aka: different node positions) and T3D 1.1 just decided to use translation animation for all nodes, which overrides my character proportions and make them look shorter/taller/stumpier/etc. Digging through the code, I found this is actually done on purpose by new code in TSShape::addSequence():
Right bellow there is another code block that does the same for rotations, which I actually found useful because it actually fixes incoherences with joints which don't animate in a sequence and makes sure the character is positioned as it should in the animation without changing body proportions.
...
else if (defaultTranslations[nodeMap[i]] != srcShape->defaultTranslations[i])
{
seq.translationMatters.set(nodeMap[i]);
S32 dest = seq.baseTranslation + seq.numKeyframes * seq.translationMatters.count(nodeMap[i]);
for (S32 j = 0; j < seq.numKeyframes; j++)
nodeTranslations.insert(dest, srcShape->defaultTranslations[i]);
}
...This is adding translation keys to the animation when the target shape and the source shape have different default translations (bind poses). I don't know why someone would want this, since it prevents animations from being re-used on characters which use joint positioning to change skeleton proportions over different characters. I commented it out and now my characters look correct.Right bellow there is another code block that does the same for rotations, which I actually found useful because it actually fixes incoherences with joints which don't animate in a sequence and makes sure the character is positioned as it should in the animation without changing body proportions.
About the author
Recent Threads
#22
05/07/2010 (11:30 am)
Ok, glad I misunderstood in this case. I should be able to get the functionality that I want, as long as all of my sequences have setBlendEnabled. Which they do.. and is the default. So it does seem like a bug, which hopefully someone can reproduce.
#23
More of a concern is your issue #2, if it's not the "add sequence keyframes when bind-poses don't match" issue, I don't know what could have changed in the collada loader that could be causing this.
05/07/2010 (8:22 pm)
Can you describe a bit more what was the problem when playing two sequences with the same priority? I just tried this in current T3D trunk and didn't notice anything obviously wrong, but I wasn't really sure what to look for.More of a concern is your issue #2, if it's not the "add sequence keyframes when bind-poses don't match" issue, I don't know what could have changed in the collada loader that could be causing this.
#24
If it's working for you in both cases, then it could be an issue w/ how we are using the collada exporter. BUT!, we have been using the same exporting process since Alpha, and did not have this problem until Beta.
Btw, when you say "blend", are you referring to the 'isBlendDisabled' or are you referring to setting up a succession of animations in the shape editor?
05/13/2010 (11:45 am)
Take a character rigged w/ the common biped skeleton. Make an ambient animation, let's say breathing or dancing or whatever you want. Don't key the jaw. Make an animation that flaps the jaw around some. Leave priorities the same. Try to play the jaw animation while the ambient animation is running. The jaw animation should be distorted, even though it is only keyed in one animation. Then change the jaw animation to priority 5 and ambient to priority 1. It should now work.If it's working for you in both cases, then it could be an issue w/ how we are using the collada exporter. BUT!, we have been using the same exporting process since Alpha, and did not have this problem until Beta.
Btw, when you say "blend", are you referring to the 'isBlendDisabled' or are you referring to setting up a succession of animations in the shape editor?
#25
Neither. 'Blend' is a property of the sequence. It changes how the node transforms are stored and applied to the shape. You can disable blends for a thread (basically, don't apply the blended sequence).
05/14/2010 (3:23 am)
Quote:Btw, when you say "blend", are you referring to the 'isBlendDisabled' or are you referring to setting up a succession of animations in the shape editor?
Neither. 'Blend' is a property of the sequence. It changes how the node transforms are stored and applied to the shape. You can disable blends for a thread (basically, don't apply the blended sequence).
#26
What follows is just brain dump, but maybe useful for others searching the forum. I've seen other threads from 2/10 about animation issues, but most have gone unanswered, and I seem to be alone wrt the depth of weirdness I'm encountering.
---
So, as long as I have different priorities and hard code the slot to use, I can pretty much get everything working ok if I only use 'playThread' for the body animations, and the custom facial animation code for facial animations. I have no conflicts between facial and body animations now that I have priorities set appropriately.
Of course, I need multiple sequences active on the body at once. And I need features that setActionThread and playThread both have, but only setActionThread actually implements (e.g. reverse apparently does not work w/ playThread - ?).
So, now I've tried mixing setActionThread for wholesale body movements e.g. lying down, and playThread for local movements, e.g. breathing, waving. But of course there's a conflict! For example if I have a character lie down (using setActionThread) during a breathing animation (set by playThread), node position data from playThread seems to override that of the setActionThread. I realize this is Player specific, but priority is only set by the sequence, so it shouldn't (intuitively) matter what thread (a new one or Player's main thread) it's played on.
One solution is to have artists make an animation for all of the different permutations of sequence options (reverse, non holding, etc) and always use playThread. But that's kind of annoying, and I don't like the idea of hardcoding a map of each possible sequence name to the slot on which it must play to avoid booting off animations on other parts of the character.
So, yesterday I wrote a custom animation system for my Player subclass. It has a queue of animations for each chunk of the skeletal hierarchy, and one thread per queue. Priorities are getting set based on the hierarchy...though I'm not sure the priority value isn't being overwritten or set too late to matter (*coda). In any case, I'm noticing issues similar to the playThread vs. setActionThread problem.
I'm fairly puzzled. We're going to screw around with our export process to see if it's an issue on the art side.
(*coda) Rant about sequence priorities: A more flexible mechanism for setting priority is needed...easiest way is to make it a parameter to setSequence & transitionToSequence. Also it might make sense to make priorities and playThread slots correlative. The priority of an about-to-be-played animation can't be set manually at all now. I've tried the obvious fix by making Thread::priority public, but any set value is overwritten on setSequence - to the sequence's priority. Which is set at load time only. So it would make more sense to let me set priority on a Sequence object. BUT, the Sequence class off limits! No method anywhere returns a Sequence. Annoying, because it would be simple to set priority on the sequence and leave the rest of the code alone. Simple fix to add a method to ShapeInstance, that gets a Sequence* by id.
Customization of the engine was probably not in mind when this was written. I suspect that it's not being considered much w/ the new versions either. The engine (if it's going to be sold as source code) needs much better design for HIGH-LEVEL customization. More core functionality must be exposed, to the higher level the better. Realistically, low level customization (me rewriting Sequence, Thread, and ShapeInstance) is not a solution because I'll have to re-do all changes every time I upgrade.
In any case, I think we are finding that when you need more complex animation abilities than are used in most shooters, you will have plenty of issues trying to use a game engine designed for shooters.
05/14/2010 (7:15 am)
Yeah, that's the first one I was referring to. Maybe got the variable name wrong. Thanks for the clarification.What follows is just brain dump, but maybe useful for others searching the forum. I've seen other threads from 2/10 about animation issues, but most have gone unanswered, and I seem to be alone wrt the depth of weirdness I'm encountering.
---
So, as long as I have different priorities and hard code the slot to use, I can pretty much get everything working ok if I only use 'playThread' for the body animations, and the custom facial animation code for facial animations. I have no conflicts between facial and body animations now that I have priorities set appropriately.
Of course, I need multiple sequences active on the body at once. And I need features that setActionThread and playThread both have, but only setActionThread actually implements (e.g. reverse apparently does not work w/ playThread - ?).
So, now I've tried mixing setActionThread for wholesale body movements e.g. lying down, and playThread for local movements, e.g. breathing, waving. But of course there's a conflict! For example if I have a character lie down (using setActionThread) during a breathing animation (set by playThread), node position data from playThread seems to override that of the setActionThread. I realize this is Player specific, but priority is only set by the sequence, so it shouldn't (intuitively) matter what thread (a new one or Player's main thread) it's played on.
One solution is to have artists make an animation for all of the different permutations of sequence options (reverse, non holding, etc) and always use playThread. But that's kind of annoying, and I don't like the idea of hardcoding a map of each possible sequence name to the slot on which it must play to avoid booting off animations on other parts of the character.
So, yesterday I wrote a custom animation system for my Player subclass. It has a queue of animations for each chunk of the skeletal hierarchy, and one thread per queue. Priorities are getting set based on the hierarchy...though I'm not sure the priority value isn't being overwritten or set too late to matter (*coda). In any case, I'm noticing issues similar to the playThread vs. setActionThread problem.
I'm fairly puzzled. We're going to screw around with our export process to see if it's an issue on the art side.
(*coda) Rant about sequence priorities: A more flexible mechanism for setting priority is needed...easiest way is to make it a parameter to setSequence & transitionToSequence. Also it might make sense to make priorities and playThread slots correlative. The priority of an about-to-be-played animation can't be set manually at all now. I've tried the obvious fix by making Thread::priority public, but any set value is overwritten on setSequence - to the sequence's priority. Which is set at load time only. So it would make more sense to let me set priority on a Sequence object. BUT, the Sequence class off limits! No method anywhere returns a Sequence. Annoying, because it would be simple to set priority on the sequence and leave the rest of the code alone. Simple fix to add a method to ShapeInstance, that gets a Sequence* by id.
Customization of the engine was probably not in mind when this was written. I suspect that it's not being considered much w/ the new versions either. The engine (if it's going to be sold as source code) needs much better design for HIGH-LEVEL customization. More core functionality must be exposed, to the higher level the better. Realistically, low level customization (me rewriting Sequence, Thread, and ShapeInstance) is not a solution because I'll have to re-do all changes every time I upgrade.
In any case, I think we are finding that when you need more complex animation abilities than are used in most shooters, you will have plenty of issues trying to use a game engine designed for shooters.
#27
06/01/2010 (5:54 am)
logged Key: TQA-183
#28
if you have a multimesh character with hand aligned verts so shadows dont show in the seams you cant export it with a skin in to old exporters -and if you export the model as collada...
then when you import the model to T3D from collada, it could end up doing odd stuff attempting to handle its .dsq animations -because the collada parsing does all kind of wierd stuff per default ?
08/20/2010 (8:06 pm)
So the essence of this is;if you have a multimesh character with hand aligned verts so shadows dont show in the seams you cant export it with a skin in to old exporters -and if you export the model as collada...
then when you import the model to T3D from collada, it could end up doing odd stuff attempting to handle its .dsq animations -because the collada parsing does all kind of wierd stuff per default ?
Associate Chris Robertson
No - I didn't mean that. Each individual node is animated according to the following rules:
1. If no sequences animate the node, it retains its default transform.
2. If only one sequence animates the node, the node obviously gets its transform from that sequence.
3. If two sequences try to animate the same node, only the sequence with higher priority animates the node. If the sequences have the same priority, the one in a higher thread (in order of thread creation) animates the node.
4. If a blend sequence animates the node, the animation transform is applied on top of any previous thread, regardless of priority (blend sequences store relative transforms, so it is safe to 'add' them to other sequences).
Thus, the artist is in control of which nodes are animated (not withstanding any bug introduced into the codebase while trying to fix an unrelated issue! ;-) )