Smoothly move a shape using script?
by Yannick Lahay · in Torque Game Engine · 05/01/2007 (2:50 pm) · 29 replies
After searching and testing, I haven't found any way to move a shape smoothly.
Here's an example of a scripted animation I'd like to code:
(my shape is a rock)
- it moves left
- pause 1sec
- it moves right
- pause 1sec
and so on.
I also need a variable to change the speed of the move, because maybe the speed will change depending of the level being played.
It seems to be easy to code, but since I'm a beginner... actually it's not easy for me lol
Thank you for any help.
Here's an example of a scripted animation I'd like to code:
(my shape is a rock)
- it moves left
- pause 1sec
- it moves right
- pause 1sec
and so on.
I also need a variable to change the speed of the move, because maybe the speed will change depending of the level being played.
It seems to be easy to code, but since I'm a beginner... actually it's not easy for me lol
Thank you for any help.
#22
However when doing something like this:
Perhaps my function could do with a little work. In all honesty, this isn't something I need so I haven't spent much time on it.
05/05/2007 (6:53 am)
That works for me too.However when doing something like this:
function MoveableObject::Move(%obj, %direction, %rate, %ticks)
{
if(!%rate)
%rate = 0.1;
if(!%ticks)
%ticks = 5;
%pos = %obj.getTransform();
echo("current transform = " @ %pos);
%posX = getWord(%obj.getTransform(), 0);
%posY = getWord(%obj.getTransform(), 1);
%posZ = getWord(%obj.getTransform(), 2);
switch$(%direction)
{
case left:
%posX = %posX + %rate;
case right:
%posX = %posX - %rate;
case forward:
%posY = %posY + %rate;
case back:
%posY = %posY - %rate;
case up:
%posZ = %posZ + %rate;
case down:
%posZ = %posZ - %rate;
}
%obj.setTransform(%posX SPC %posY SPC %posZ);
while(%ticks)
{
%obj.schedule(100, "Move", %direction, %rate, %ticks);
%ticks--;
}
echo("new transform = " @ %obj.getTransform());
}It would only increment by 0.1 regardless of what I define %rate as.Perhaps my function could do with a little work. In all honesty, this isn't something I need so I haven't spent much time on it.
#23
I'll assume for the moment the problem you see is an artifact of something there.
05/05/2007 (7:27 am)
Ok, I'll labor on with my methods. I'm taking a more general approach to the problem using numerical integration over time, which I have used in other physical systems, and expect to be able to make most anything in the scene whizz about in a realistic fashion. For example, moving checkers on a board or cards in a solitare program, etc.I'll assume for the moment the problem you see is an artifact of something there.
#24
05/06/2007 (8:53 pm)
So here's my first version of this. Rather than using a datablock to store the state, I chose to simply pass the state on each iteration to simplify the setup so it's easier to use it.// moveTarget will move any objects to new x,y,z coordinates.
// usage: moveTarget(%id, %x SPC %y SPC %z);
//
function moveTarget(%target, %position)
{
%dt = 0.030; // in seconds
%Vmax = 50.0; // in units per second
%a = 9.8; // in units per second^2 if a unit were a meter, this would be equivalent to one G.
%targetPosition = %target.getPosition();
%sx = %x0 = getWord(%targetPosition, 0);
%sy = %y0 = getWord(%targetPosition, 1);
%sz = %z0 = getWord(%targetPosition, 2);
%x1 = getWord(%position, 0);
%y1 = getWord(%position, 1);
%z1 = getWord(%position, 2);
%dx = %x1-%x0;
%dy = %y1-%y0;
%dz = %z1-%z0;
%ds = mSqrt(%dx*%dx+%dy*%dy+%dz*%dz);
if(%ds == 0) {
return;
}
%mx = %dx/%ds;
%my = %dy/%ds;
%mz = %dz/%ds;
%dvdt = %a*%dt;
%ax = %mx * %dvdt;
%ay = %my * %dvdt;
%az = %mz * %dvdt;
%vx = %vy = %vz = 0;
%sMax = %Vmax * %Vmax / (2 * %a); // accl ramp to reach maxV from v0
%s2 = %ds - 2 * %sMax;
if(%s2 < 0) { // triangular shape, not long enough for constant speed.
%s2 = 0;
%s1 = %s3 = %ds / 2;
}
else // trapezoidal shape, has constant velocity segment
%s1 = %s3 = %sMax;
%s = %v = 0;
%state = %dt SPC %ds SPC %a SPC %v SPC %s SPC %s1 SPC %s2 SPC %s3 SPC %Smax SPC %Vmax SPC %vSave SPC %sx SPC %sy SPC %sz SPC %vx SPC %vy SPC %vz SPC %ax SPC %ay SPC %az SPC %dvdt;
// echo(%state);
nextTargetPosition(%target, %state);
}
function nextTargetPosition(%target, %state)
{
//state = dt ds a v s s1 s2 s3 Smax Vmax vSave sx sy sz vx vy vz ax ay az dvdt;
// echo(%state);
%dt = getWord(%state, 0);
%ds = getWord(%state, 1);
%a = getWord(%state, 2);
%v = getWord(%state, 3);
%s = getWord(%state, 4);
%s1 = getWord(%state, 5);
%s2 = getWord(%state, 6);
%s3 = getWord(%state, 7);
%Smax = getWord(%state, 8);
%Vmax = getWord(%state, 9);
%vSave = getWord(%state, 10);
%sx = getWord(%state, 11);
%sy = getWord(%state, 12);
%sz = getWord(%state, 13);
%vx = getWord(%state, 14);
%vy = getWord(%state, 15);
%vz = getWord(%state, 16);
%ax = getWord(%state, 17);
%ay = getWord(%state, 18);
%az = getWord(%state, 19);
%dvdt = getWord(%state, 20);
if(%s < %ds)
{
// Acceleration phase of trapezoid, if any...
if(%s1 > 0) {
if(%s < %s1) {
%v += %dvdt;
%vx += %ax;
%vy += %ay;
%vz += %az;
%s += %v * %dt;
%sx += %vx * %dt;
%sy += %vy * %dt;
%sz += %vz * %dt;
}
else {
%s1 = 0;
if(%s2 > 0) { // Use precise maxV if switching to constant speed
%vSave = %v;
%v = %Vmax;
}
}
}
// constant speed portion of trapezoid, if any...
if(%s1 == 0 && %s2 > 0) {
%sx += %vx * %dt;
%sy += %vy * %dt;
%sz += %vz * %dt;
%s += %v * %dt;
if(%s >= %ds - %s3) {
%s2 = 0;
%v = %vSave;
}
}
// Decelleration phase of movement, if any...
if(%s1 == 0 && %s2 == 0 && %s3 > 0) {
if(%s < %ds) {
%s += %v * %dt;
%sx += %vx * %dt;
%sy += %vy * %dt;
%sz += %vz * %dt;
%v -= %dvdt;
%vx -= %ax;
%vy -= %ay;
%vz -= %az;
}
else {
%s3 = 0;
}
}
}
else
{
%v = %vf;
%s1 = %s2 = %s3 = 0;
}
%p = %target.getTransform();
%target.setTransform(%sx SPC %sy SPC %sz SPC getWord(%p,3) SPC getWord(%p,4) SPC getWord(%p,5) SPC getWord(%p,6));
if(%s1 > 0 || %s2 > 0 || %s3 > 0)
{
%state = %dt SPC %ds SPC %a SPC %v SPC %s SPC %s1 SPC %s2 SPC %s3 SPC %Smax SPC %Vmax SPC %vSave SPC %sx SPC %sy SPC %sz SPC %vx SPC %vy SPC %vz SPC %ax SPC %ay SPC %az SPC %dvdt;
schedule(%dt*1000,0, nextTargetPosition, %target, %state);
}
}
#25
Secondly, it seems that while moving ShapeBase objects around on the ground looks pretty nice (smooth), anything raised up into the air gets real jumpy, (seem to oscillate vertically), for some reason. I noticed that they are jumpy while falling too, after I release them (function ends). So that seems like a TGE issue
This was with TGE1.3 so I'll have to check it with versions 1.4 and 1.5.
05/07/2007 (4:06 am)
So after playng with this for a while, two things become obvious. One, trying to move TSStatic objects around results in them being moved in terms of their transforms, they never move on the screen. For example, I can move a fence out of the way. I can drive through it but its still there. If I save the mission at that point and reload it, the fence is moved to the new location. Secondly, it seems that while moving ShapeBase objects around on the ground looks pretty nice (smooth), anything raised up into the air gets real jumpy, (seem to oscillate vertically), for some reason. I noticed that they are jumpy while falling too, after I release them (function ends). So that seems like a TGE issue
This was with TGE1.3 so I'll have to check it with versions 1.4 and 1.5.
#26
05/07/2007 (1:41 pm)
Thank you for this code, it's a great step forward ^^
#27
I didn't really try it much with anything but a wheeledVehicle object but it scooted that around pretty nicely, except when in the air. I think that is due to the way wheeled vehicles try to locate the ground in the C++ engine and the forces artificially generated for that so I didn't pay much attention to it.
05/07/2007 (2:26 pm)
Let us know how well your rock moves. :o)I didn't really try it much with anything but a wheeledVehicle object but it scooted that around pretty nicely, except when in the air. I think that is due to the way wheeled vehicles try to locate the ground in the C++ engine and the forces artificially generated for that so I didn't pay much attention to it.
#28
Thank you very much Tim!! :)
05/10/2007 (3:43 am)
Sorry, I'm a bit busy at the moment, I'll try your code as soon as I can.Thank you very much Tim!! :)
#29
ShapeBase object seems to be afected by gravity because of the engine.
When the object is up, it begins to fall.
05/21/2007 (9:51 am)
It seems to me that objects that oscillate vertically is because of gravity.ShapeBase object seems to be afected by gravity because of the engine.
When the object is up, it begins to fall.
Torque Owner Tim Hutcheson
==>echo(tbot01.gettransform());
-0.735262 -217.26 100.012 0.00668695 -0.00902176 0.999937 1.86597
==>tbot01.settransform("-1 -217 100 0 0 1 2");
==>tbot01.settransform("-1.03 -217 100 0 0 1 2");
==>echo(tbot01.gettransform());
-1.02979 -217 100.012 0.00579423 -0.0090241 0.999943 2.00005
You can see that I found the position of the robot, then cleaned the position in each axis with x set to -1, then set the position to -1.03 in x and printed the result. x-axis moved to -1.02979 which is within .0002 units of where I wanted it.