PDA

View Full Version : Aargh! Constant rotate with same angle!



kevman3d
03-17-2003, 04:40 AM
Can anyone tell me what stupid thing I've done wrong here?

Basically, this script is supposed to rotate an object, but only when its Y is above 0 - Simple. I also want to retain the last angle when its on 0 as well. (So it stops when it lands - Its a sorta 'spin as you bounce' thing)

What's odd is that I've got an 'if' statement that does the updating of the rotation value when y > 0, however the object just spins constantly when on 0! I added a dump to a disk log file to analyse the issue - The rotation value doesn't change unless Y > 0, yet it still spins on screen! (Spooky!)

I changed the code and removed the 'If' statement to just force the same value into the ma.set command, and it doesn't spin like you would expect... So somehow the rotation is changing *without* the if statement, but I'll be darned if I can figure this one out! :)

I also moved the ma.set command into the 'If' statement which fixed the problem, however when not in the 'If', the object obviously resets its rotation to its last keyframed position, leaving me with a flickering effect as the rotation flips back...

Anyone? What have I done wrong? Cheers! :)



@version 2.2
@warnings
@script motion

// global values go here
numRotate = 0.0; // The amount to rotate the object by
numStart = 0.0; // The current angle of rotation of the objects heading

create
{
}

destroy
{
}

process: ma, frame, time
{
// Only Initialise the rotator if the values are blank
if (numRotate == 0)
{
// Grab the rotation of the heading at frame 0
numStart = ma.get(ROTATION,0).h;
// Set the rotation to 10 degrees
numRotate = 10;
}

// Grab the current details from the object
oRot = ma.get(ROTATION,time);
oPos = ma.get(POSITION,time);
oRh = oRot.h;
oRp = oRot.p;
oRb = oRot.b;

// Only update if the object is above the 0 plane
if (oPos.y > 0)
{
// Increment the rotation of the object
numStart += numRotate;
}

// Set the new values
oRh = numStart;
ma.set(ROTATION,<oRh,oRp,oRb>);
}

load: what,io
{
if(what == SCENEMODE) // processing an ASCII scene file
{
}
}

save: what,io
{
if(what == SCENEMODE)
{
}
}

options
{
reqbegin("Spin above 0");
return if !reqpost();
// get requester control values here
reqend();
}

faulknermano
03-17-2003, 05:19 AM
BUG! :D


yup.. i just check it out between v2.6 and 2.5.1. 2.5.1 returns the correct position, but v2.6 keeps on reverting back to zero. it's outputting the correct position, but not consistently, so the multiple calls made to the process function within will yield different results. this is definitely a bug: i have a good bug-report-version here: i'll email the lscript mailing list and file this is a bug report.

in the meantime, you can do either of two things:

1.) revert back to lw75.

2.) provide an interface to get the Object Agent of the item you are processing and then use getPosition() method instead. you cannot use the ma Object Agent provided by the process function of the IA script because it is of a different type. so

target = Mesh("myItem"); // assume the myItem is a mesh in layout
pos = target.getPosition(Scene().currenttime);

faulknermano
03-17-2003, 10:17 PM
i dont know if you've been following the progression of this 'bug' in the lscript mailing list: but this is not a bug after all.. this is how IA scripts work.

apparently the process function is called many times with different arguments. so even if you are on frame 10, the process function will feed 0.0 to whatever-time index-you-are-on. the explanation is that the lw queries the plug for all the motion info within its WHOLE time span. lw does this, for example, to draw the motion path, to calculate motion blur.

thus: if you want to do condition checking within your process, do not use the inbuilt get(POSITION,time) commands. instead, you must 'loop back' using anther method to get your Object Agent and use the getPosition() function instead. the getPosition() is does not behave in the same was as get(POSITION,time) and is more transparent.

ideas: you can 'loop back' by getting the name of your object through the create function:



create: obj
{
objName = obj.name
}


and use this name to search for your object agent. if the object agent is a mesh, it'll be easier for you:



mObj = mesh(objName);


if it is a bone:



myObj = nil;
mesh = Mesh();
while(mesh)
{
b = mesh.bone();
while(b)
{
if(b.name == objName)
{
myObj = b;
break;
}
if(myObj)
break;
}
}