Animation Thread setPos
by Steve Lamperti · in Torque Game Engine · 06/30/2004 (11:01 am) · 8 replies
I'm trying to get an object up and running that has an animation in it that I want to be able to set to specific states. (In this example, it's a forklift where I want to be able to set the lift to variable heights.) The object animation works fine in the show tool. I start the lift thread running, then stop it, and then use the slider to raise and lower it. When I try to do what I think should be the same thing from the project window, nothing happens. It's starting to feel like there's something in the engine that doesn't like doing this kind of animation, but I may also just be missing something in my code.
Here's the routine I added to shapebase, that I am calling from my C++ code when I want to set the animation position:
If anyone sees anything I am missing, or has any other suggestions I would appreciate some responses.
Here's the routine I added to shapebase, that I am calling from my C++ code when I want to set the animation position:
// JSL - added to allow simple control of the forklift lift.
bool ShapeBase::setThreadPos(U32 slot, F32 pos)
{
Thread& st = mScriptThread[slot];
if (st.thread != NULL)
{
//st.state = Thread::Stop;
//updateThread(st);
mShapeInstance->setPos(st.thread, pos);
st.atEnd = true;
mShapeInstance->setTimeScale(st.thread, 1.0);
return(true);
}
return(false);
}If anyone sees anything I am missing, or has any other suggestions I would appreciate some responses.
#2
I would suggest looking at the WheeledVehicle.cc file to see how they update the steerring sequence which is based on a variable t.
The problem I was having was seperating different sequences within the same thread. But, I have solved that problem. I first assigned each sequence as its own thread like it is in WheeledVehicle.cc file for the steering sequence.
I would suggest trying to take out the st.atEnd = true; because I think that when you do that the engine automatically sets your position to 1. Thinking you want it to be set at the end.
The code that is working for me is:
if(mythread){
mShapeInstance->setPos(mythread,myvariable);
}
simple but it works. I have it in the advanceTime part of my objects functions. I control it with a variable, which is the problem I am having.
good luck, nice to see someone dealing with the same bs I am.
07/02/2004 (1:39 pm)
I am trying to do the same thing. I have it working, but I am still having some problems.I would suggest looking at the WheeledVehicle.cc file to see how they update the steerring sequence which is based on a variable t.
The problem I was having was seperating different sequences within the same thread. But, I have solved that problem. I first assigned each sequence as its own thread like it is in WheeledVehicle.cc file for the steering sequence.
I would suggest trying to take out the st.atEnd = true; because I think that when you do that the engine automatically sets your position to 1. Thinking you want it to be set at the end.
The code that is working for me is:
if(mythread){
mShapeInstance->setPos(mythread,myvariable);
}
simple but it works. I have it in the advanceTime part of my objects functions. I control it with a variable, which is the problem I am having.
good luck, nice to see someone dealing with the same bs I am.
#3
Thanks for your response. I am still fighting with this. I think your observation about the sequences may be related to what is giving me problems. I had already changed my code so it is otherwise similar to what you are describing. I.e. I just set a position flag in my SetThreadPos routine, and in advanceTime I call setPos on the object using the value of that flag. Unfortunately for me it is still doing nothing. I am thinking that I may have the sequence problem you are describing. If you wouldn't mind, I would appreciate it if you could paste a couple of lines of code from where you set up your sequence into this thread. I might help me get up and running.
I looked at WheeledVehicle, but unfortunately I am still struggling with understanding the Thread/Sequence relationship, so I wasn't able to figure it out sufficiently.
07/02/2004 (2:08 pm)
Chris,Thanks for your response. I am still fighting with this. I think your observation about the sequences may be related to what is giving me problems. I had already changed my code so it is otherwise similar to what you are describing. I.e. I just set a position flag in my SetThreadPos routine, and in advanceTime I call setPos on the object using the value of that flag. Unfortunately for me it is still doing nothing. I am thinking that I may have the sequence problem you are describing. If you wouldn't mind, I would appreciate it if you could paste a couple of lines of code from where you set up your sequence into this thread. I might help me get up and running.
I looked at WheeledVehicle, but unfortunately I am still struggling with understanding the Thread/Sequence relationship, so I wasn't able to figure it out sufficiently.
#4
Thanks again for your response, I think I've got this working. It was definately the missing sequence code that was messing me up.
07/02/2004 (2:58 pm)
Chris,Thanks again for your response, I think I've got this working. It was definately the missing sequence code that was messing me up.
#5
07/22/2005 (10:00 am)
I should also add that I am also having this problem. I'm trying to keep it all in shapeBase.cc and if I get something that works, I'll post it.
#6
It should all be in shapeBase.cc: (with method declaration in shapeBase.h)
a console method:
I've added a new switch case in ShapeBase::updateThread()
I was seeing my initial position but I couldn't modify it on the fly until I made sure the information was transmitted from server to client so...
in ShapeBase::packUpdate() (where we are packing the Thread stuff (look for ThreadMask)
in ShapeBase::unpackUpdate() (where we are unpacking the Thread stuff (look for the for loop that has 'MaxScriptThreads')
in shapeBase.h:
the shapeBase class has an internal 'struct Thread' so we modify it thus:
add this down by the other thread manipulation methods:
That should do it...
Then, to call it in script, its just something like:
Should work.
-L
07/22/2005 (2:22 pm)
Ok, I have something that kind of works, so I'll try to list it out:It should all be in shapeBase.cc: (with method declaration in shapeBase.h)
// new function
bool ShapeBase::setThreadPos(U32 slot, S32 seq, F32 time)
{
Thread& st = mScriptThread[slot];
st.sequence = seq;
if (!st.thread)
st.thread = mShapeInstance->addThread();
mShapeInstance->setSequence(st.thread,seq,0);
st.state = Thread::Set;
st.pos = time;
if (st.sequence != -1 && st.thread)
{
setMaskBits(ThreadMaskN << slot);
updateThread(st);
return true;
}
return false;
}a console method:
ConsoleMethod( ShapeBase, setThreadPos, bool, 5, 5, "(int slot, string sequenceName, float time)")
{
int slot = dAtoi(argv[2]);
F32 time = dAtof(argv[4]);
if (slot >= 0 && slot < ShapeBase::MaxScriptThreads)
{
S32 seq = object->getShape()->findSequence(argv[3]);
if ( object->setThreadPos(slot, seq, time) )
return true;
}
return false;
}I've added a new switch case in ShapeBase::updateThread()
case Thread::Set: mShapeInstance->setTimeScale(st.thread,0); mShapeInstance->setPos(st.thread, st.pos); break;
I was seeing my initial position but I couldn't modify it on the fly until I made sure the information was transmitted from server to client so...
in ShapeBase::packUpdate() (where we are packing the Thread stuff (look for ThreadMask)
stream->writeFloat(mClampF(st.pos, 0.f, 1.f),ThreadSequenceBits);
in ShapeBase::unpackUpdate() (where we are unpacking the Thread stuff (look for the for loop that has 'MaxScriptThreads')
st.pos = stream->readFloat(ThreadSequenceBits); // place this after the assignment to st.atEnd
in shapeBase.h:
the shapeBase class has an internal 'struct Thread' so we modify it thus:
enum State {
Play, Stop, Pause, Set // added the 'Set' state
};
F32 pos; /// we need a position if we're "setting" the animationadd this down by the other thread manipulation methods:
/// Attempt to pause and set the thread to a specific time in the animation bool setThreadPos(U32 slot, S32 seq, F32 time);
That should do it...
Then, to call it in script, its just something like:
%shape.setThreadPos(1, "Jump", 0.5); // set the shape to the 1/2 point in the jump animation
Should work.
-L
#7
Wow.
Can we say -> Resource!
07/22/2005 (2:32 pm)
So, if I read this all correctly, this will essentially allow you to select a specific frame within a sequence, and apply that frame to the model, while still allowing unaffected areas of the model to be animated via seperate animation threads?Wow.
Can we say -> Resource!
#8
im thinking the starting position isnt being sent to the client, any idea where that would be in code?
never mind, figured it out.
07/07/2007 (3:28 pm)
Ive been trying to fiddle with this to make a script function that plays the animation only in a certain area of the animation, like playthreadarea(0,"open",0.5,1.0) would play the open animation from half to finish, it works fine when i apply the code+my edits to a clientsidetsstatic object, but once i try todo it on a networked shapebase, it doesn't, it merely plays the animation like normal for the period of time it would todo the area you specify.im thinking the starting position isnt being sent to the client, any idea where that would be in code?
never mind, figured it out.
Torque Owner Steve Lamperti
Imagine That!