Changing animation speeds via dabablock
by Peter Simard · 11/13/2006 (4:44 pm) · 12 comments
This resource will allow you to alter the play speed of specific animations. Each animation inside of your TSShapeConstructor can have a percent speed modifier applied to it. This is especially useful if you use a lot of content packs and don't have access to the source material.
Installation
ts/tsShapeConstruct.h modifications
Change this line
To:
ts/tsShapeConstruct.cc modifications
Change this code inside preload:
Change this code inside of packData
Change this code inside of unpackData
Change this code inside of initPersistFields
Inside of the constructor change:
ts/tsShape.h modifications
Add this line inside of the struct Sequence
ts/tsThread.cc modifications
Change this function
Thats it! You should now be able to change the speed of animations from inside of their datablock.
Example:
That will play the attack animation at 60% speed and the death animation at 110% speed.
Installation
ts/tsShapeConstruct.h modifications
Change this line
StringTableEntry mSequence[MaxSequences];
To:
StringTableEntry mSequence[MaxSequences]; F32 mSequenceSpeed[MaxSequences];
ts/tsShapeConstruct.cc modifications
Change this code inside preload:
}
ResourceManager->closeStream(f);To:}
ResourceManager->closeStream(f);
shape->sequences.last().speed = mSequenceSpeed[ i ];Change this code inside of packData
else
{
stream->writeString(mSequence[ i ]);
}To:else
{
stream->writeString(mSequence[ i ]);
}
stream->write(mSequenceSpeed[ i ]);Change this code inside of unpackData
else
mSequence[ i ] = StringTable->insert(seq_name);To:else
mSequence[ i ] = StringTable->insert(seq_name);
stream->read(&mSequenceSpeed[ i ]);Change this code inside of initPersistFields
dSprintf(buf,sizeof(buf),"sequence%i",i);
addField(buf, TypeFilename, OffsetNonConst(mSequence[ i ], TSShapeConstructor));To:dSprintf(buf,sizeof(buf),"sequence%i",i);
addField(buf, TypeFilename, OffsetNonConst(mSequence[ i ], TSShapeConstructor));
dSprintf(buf,sizeof(buf),"sequence%ispeed",i);
addField(buf, TypeF32, OffsetNonConst(mSequenceSpeed[ i ], TSShapeConstructor));Inside of the constructor change:
for (S32 i = 0; i<MaxSequences; i++)
{
mSequence[ i ] = NULL;To:for (S32 i = 0; i<MaxSequences; i++)
{
mSequence[ i ] = NULL;
mSequenceSpeed[ i ] = 1.0;ts/tsShape.h modifications
Add this line inside of the struct Sequence
F32 speed;
ts/tsThread.cc modifications
Change this function
void TSThread::setTimeScale(F32 ts)
{
timeScale = ts;
}To:void TSThread::setTimeScale(F32 ts)
{
timeScale = ts * sequence->speed;
}Thats it! You should now be able to change the speed of animations from inside of their datablock.
Example:
datablock TSShapeConstructor(undeadWarriorDts)
{
baseShape = "~/data/shapes/mobs/warrior/c_warrior.dts";
sequence0 = "~/data/shapes/mobs/warrior/attack.dsq rightSlash";
sequence1 = "~/data/shapes/mobs/warrior/die.dsq death1";
sequence0speed = 0.6;
sequence1speed = 1.1;
};That will play the attack animation at 60% speed and the death animation at 110% speed.
#2
09/24/2006 (1:32 pm)
Thanks a lot! This going to be really useful.
#3
10/05/2006 (9:28 pm)
This seems to bust NON-sequence animations, such as weapon, animations built into the DTS shape.
#4
i need the solvation for this.
10/11/2006 (5:23 am)
it had worked fine with the player who has his animations in dsq files but on the models which don't have dsq files it didn't work, sometimes the animation is appearred and other times the model appear as a constant object....i need the solvation for this.
#5
The 750 being milliseconds to override the original animations length.
11/16/2006 (5:05 pm)
Haven't tried it but I was just thinking about something like this cause I would like something like obj.setActionThread("death1", false, false, "750");The 750 being milliseconds to override the original animations length.
#6
I tried this resource but got an out of read range error.
*edit* turns out I had too many player dsq animations.
see: www.garagegames.com/mg/forums/result.thread.php?qt=25552
11/23/2006 (2:24 am)
@Caylo & Joy - The problem was not that they weren't animated, they were, but since those datablocks didn't contain the speed variable they were playing at timescale=0. We just need to insert a (hack job) check to see if a speed variable exists. Like this:void TSThread::setTimeScale(F32 ts)
{
if(sequence->speed > 0 )
timeScale = ts * sequence->speed;
else
timeScale = ts;
}I tried this resource but got an out of read range error.
*edit* turns out I had too many player dsq animations.
see: www.garagegames.com/mg/forums/result.thread.php?qt=25552
#7
I enter you hack, and it still did not work. But before posting back here, i tested your hack like this:
if(sequence->speed >ts )
timeScale = ts * sequence->speed;
else
timeScale = ts;
and it DO work. At least it seems to be working, i will post back if something is found to be wrong.
12/01/2006 (2:21 am)
Tom, Thanks much. I had expected it was something like that. I enter you hack, and it still did not work. But before posting back here, i tested your hack like this:
if(sequence->speed >ts )
timeScale = ts * sequence->speed;
else
timeScale = ts;
and it DO work. At least it seems to be working, i will post back if something is found to be wrong.
#8
By using an Con::warnf("setTimeScale(F32 ts) %f ",ts); inside void TSThread::setTimeScale(F32 ts) it becomes clear that F32 ts is all over the place.
F32 ts of course IS the time scale variable, so it seem logical that it would use a -# to play an animation backwards, or a fractional number when going uphill. In any case my if(sequence->speed >ts ) as posted above, will not work correctly, the >ts will come true in cases where we do not want to use the NEW timeScale = ts * sequence->speed.
So i think what we actually want is to test if sequence->speed is in use at all, (sorta like Tom "epicglottis" MacGregor have above) and only then apply the multiplier.
I left the CON output debug lines in so if you wish you can see how ODD F32 ts behave.
The above code snip, DO seem to work. Of course I will return if i find it in error....
12/01/2006 (12:36 pm)
Ok, it still dont work right. Now some of the player animations are stuttering (side stepping animation). By using an Con::warnf("setTimeScale(F32 ts) %f ",ts); inside void TSThread::setTimeScale(F32 ts) it becomes clear that F32 ts is all over the place.
F32 ts of course IS the time scale variable, so it seem logical that it would use a -# to play an animation backwards, or a fractional number when going uphill. In any case my if(sequence->speed >ts ) as posted above, will not work correctly, the >ts will come true in cases where we do not want to use the NEW timeScale = ts * sequence->speed.
So i think what we actually want is to test if sequence->speed is in use at all, (sorta like Tom "epicglottis" MacGregor have above) and only then apply the multiplier.
void TSThread::setTimeScale(F32 ts)
{
//Con::warnf("sequence->speed) %f ",sequence->speed);
if(sequence->speed > 0.001 )
{
timeScale = ts * sequence->speed;
//Con::warnf("timeScale = ts * sequence->speed %f ",timeScale);
}
else
{
timeScale = ts;
//Con::warnf("timeScale = ts; %f ",timeScale);
}
}I left the CON output debug lines in so if you wish you can see how ODD F32 ts behave.
The above code snip, DO seem to work. Of course I will return if i find it in error....
#9
Read everything over very carefully- Then i notice there was a change to the resourse made on Nov 13, 2006. I was still useing the code i had typed in back before Oct 05, 2006.
It would have been nice to see EDIT: and some note about what was changed...
But rechecking all the code bits still do not fix all the problems. But it did not take much to learn WHAT the trouble is. Some animations for some reason will always return 0.0 for sequence->speed. I fixed my problem by making sure 0.0 never get into the TSThread::setTimeScale . My solution is just simply to ugly to post without making people feel bad for my sad programing ability.
12/05/2006 (5:51 pm)
So i come back because SOME types of animation type are still acting oddly. Read everything over very carefully- Then i notice there was a change to the resourse made on Nov 13, 2006. I was still useing the code i had typed in back before Oct 05, 2006.
It would have been nice to see EDIT: and some note about what was changed...
But rechecking all the code bits still do not fix all the problems. But it did not take much to learn WHAT the trouble is. Some animations for some reason will always return 0.0 for sequence->speed. I fixed my problem by making sure 0.0 never get into the TSThread::setTimeScale . My solution is just simply to ugly to post without making people feel bad for my sad programing ability.
#10
Adding this line at the end of TSShape::Sequence::read(Stream * s, bool readNameIndex) in tsShapeOldRead.cc :
speed = 1.0f;
will fix the problem by ensuring that the speed value is initialized at 1.0 when reading in sequences from the shape file.
it may also be worth while adding:
seq.speed = 1.0f;
inside the read sequences loop of TSShape::importSequences(Stream * s) in the same file just to make certain the value is always initialized to 1.0f when a new sequence is read.
01/18/2008 (8:51 am)
I know this is old, but I've just implemented it with TGE 1.5.2, and had the same problems Caylo was experiencing.Adding this line at the end of TSShape::Sequence::read(Stream * s, bool readNameIndex) in tsShapeOldRead.cc :
speed = 1.0f;
will fix the problem by ensuring that the speed value is initialized at 1.0 when reading in sequences from the shape file.
it may also be worth while adding:
seq.speed = 1.0f;
inside the read sequences loop of TSShape::importSequences(Stream * s) in the same file just to make certain the value is always initialized to 1.0f when a new sequence is read.
#11
01/20/2008 (1:05 pm)
Oh my! Man, i have been messing with this on/off for weeks now after my 1.52 upgrade, and was about to just rip this out. Being i use just about every type of animation TGE support, no matter what i did, one or more animations would not work. And it was inconsistent, works sometimes crash out cold others or just plain NOT animate at all...
#12
07/10/2009 (8:20 pm)
Have this working for T3D with a bit of changes here and there. Seems to work fine with DSQ animations so far. 
Torque Owner Demolishun
DemolishunConsulting Rocks!