Firestar3D

04-03-2011, 12:22 PM

Hi all,

I'm trying to put together an accelerometer script so that I can measure the acceleration of a target object and apply it to a null for use in my animation work. One of these applications is in the automated assignment of thrust vectors on a spacecraft for example.

I've already worked out how to get the acceleration values of the target object from comparisons between frames, and if all I wanted to do was focus on just the world coordinates, my job would be pretty much done, but I'm trying to implement a facing vector adjustment to the results. This is where I've run into problems.

I found no way to transfer the motion vectors around a set of rotation axes using built in commands, so I've had to look up matrices online, and have concocted the following code as a result.

// Get values for object position and rotation. fvec is in RADIANS.

tmp1=srcobj.param(ROTATION, time);

fvec = rad(tmp1); // fvec = -fvec;

wvec=(srcobj.param(POSITION, time));

// Get current velocity from comparison between previous and next frames.

locvel=wvec-srcobj.param(POSITION, time-(1/sceneObj.fps));

nlocvel=srcobj.param(POSITION, time+(1/sceneObj.fps))-wvec;

// Get Acceleration Values for World Velocity

accelworld=nlocvel-locvel;

// Extract acceleration coordinates to separate variables.

// This is so we can perform a sin/cos calculation later.

ax = accelworld.x;

ay = accelworld.y;

az = accelworld.z;

// Build Matrices

// Matrix for Heading

a[1][1] = ax * cos(fvec.h); a[1][2] = 0; a[1][3] = az * sin(fvec.h);

b[1][1] = 0; b[1][2] = ay; b[1][3] = 0;

c[1][1] = ax * -sin(fvec.h); c[1][2] = 0; c[1][3] = az * cos(fvec.h);

// Matrix for Pitch

a[2][1] = ax; a[2][2] = 0; a[2][3] = 0;

b[2][1] = 0; b[2][2] = ay * cos(fvec.p); b[2][3] = az * sin(fvec.p);

c[2][1] = 0; c[2][2] = ay * sin(fvec.p); c[2][3] = az * cos(fvec.p);

// Matrix for Bank

a[3][1] = ax * cos(fvec.b); a[3][2] = ay * -sin(fvec.b); a[3][3] = 0;

b[3][1] = ax * sin(fvec.b); b[3][2] = ay * cos(fvec.b); b[3][3] = 0;

c[3][1] = 0; c[3][2] = 0; c[3][3] = az;

// Multiply cells

/* Matrix format: X* Y* Z*

H A1 A2 A3

P B1 B2 B3

B C1 C2 C3 */

for (i=1;i<=3;i++)

{

m[1][i] = a[1][i] * a[2][i] * a[3][i];

m[2][i] = b[1][i] * b[2][i] * b[3][i];

m[3][i] = c[1][i] * c[2][i] * c[3][i];

}

// Add the matrix cells together to get all rotations.

matx = m[1][1] + m[1][2] + m[1][3];

maty = m[2][1] + m[2][2] + m[2][3];

matz = m[3][1] + m[3][2] + m[3][3];

// Adjust vectors

fvaccx = matx;

fvaccy = maty;

fvaccz = matz;

// Feed this back as a vector to output to our positional object.

fveclvel = <fvaccx, fvaccy, fvaccz>;

// Apply to our positional object

ma.set(POSITION, fveclvel);

The problem is that I have not gotten the desired results. On testing, I applied some forward motion on my target object so that I had some Z acceleration. What should happen is if the object rotates to face at right angles on either the heading or banking angles, the object this script is applied to should rotate counter to it, so that the null position maintains a constant world coordinate acceleration in relation to the facing vector (such that if it's parented to the control object it doesn't change direction when looking at it in the perspective view), but this doesn't happen. The result is that it seems to only take information on one axis.

I suspect it's my matrix construction at fault, which I tried to build based on the information I found at mikegreen.name, but I think I took a wrong turn somewhere.

Any math geniuses want to see where I've gone wrong?

Cheers,

I'm trying to put together an accelerometer script so that I can measure the acceleration of a target object and apply it to a null for use in my animation work. One of these applications is in the automated assignment of thrust vectors on a spacecraft for example.

I've already worked out how to get the acceleration values of the target object from comparisons between frames, and if all I wanted to do was focus on just the world coordinates, my job would be pretty much done, but I'm trying to implement a facing vector adjustment to the results. This is where I've run into problems.

I found no way to transfer the motion vectors around a set of rotation axes using built in commands, so I've had to look up matrices online, and have concocted the following code as a result.

// Get values for object position and rotation. fvec is in RADIANS.

tmp1=srcobj.param(ROTATION, time);

fvec = rad(tmp1); // fvec = -fvec;

wvec=(srcobj.param(POSITION, time));

// Get current velocity from comparison between previous and next frames.

locvel=wvec-srcobj.param(POSITION, time-(1/sceneObj.fps));

nlocvel=srcobj.param(POSITION, time+(1/sceneObj.fps))-wvec;

// Get Acceleration Values for World Velocity

accelworld=nlocvel-locvel;

// Extract acceleration coordinates to separate variables.

// This is so we can perform a sin/cos calculation later.

ax = accelworld.x;

ay = accelworld.y;

az = accelworld.z;

// Build Matrices

// Matrix for Heading

a[1][1] = ax * cos(fvec.h); a[1][2] = 0; a[1][3] = az * sin(fvec.h);

b[1][1] = 0; b[1][2] = ay; b[1][3] = 0;

c[1][1] = ax * -sin(fvec.h); c[1][2] = 0; c[1][3] = az * cos(fvec.h);

// Matrix for Pitch

a[2][1] = ax; a[2][2] = 0; a[2][3] = 0;

b[2][1] = 0; b[2][2] = ay * cos(fvec.p); b[2][3] = az * sin(fvec.p);

c[2][1] = 0; c[2][2] = ay * sin(fvec.p); c[2][3] = az * cos(fvec.p);

// Matrix for Bank

a[3][1] = ax * cos(fvec.b); a[3][2] = ay * -sin(fvec.b); a[3][3] = 0;

b[3][1] = ax * sin(fvec.b); b[3][2] = ay * cos(fvec.b); b[3][3] = 0;

c[3][1] = 0; c[3][2] = 0; c[3][3] = az;

// Multiply cells

/* Matrix format: X* Y* Z*

H A1 A2 A3

P B1 B2 B3

B C1 C2 C3 */

for (i=1;i<=3;i++)

{

m[1][i] = a[1][i] * a[2][i] * a[3][i];

m[2][i] = b[1][i] * b[2][i] * b[3][i];

m[3][i] = c[1][i] * c[2][i] * c[3][i];

}

// Add the matrix cells together to get all rotations.

matx = m[1][1] + m[1][2] + m[1][3];

maty = m[2][1] + m[2][2] + m[2][3];

matz = m[3][1] + m[3][2] + m[3][3];

// Adjust vectors

fvaccx = matx;

fvaccy = maty;

fvaccz = matz;

// Feed this back as a vector to output to our positional object.

fveclvel = <fvaccx, fvaccy, fvaccz>;

// Apply to our positional object

ma.set(POSITION, fveclvel);

The problem is that I have not gotten the desired results. On testing, I applied some forward motion on my target object so that I had some Z acceleration. What should happen is if the object rotates to face at right angles on either the heading or banking angles, the object this script is applied to should rotate counter to it, so that the null position maintains a constant world coordinate acceleration in relation to the facing vector (such that if it's parented to the control object it doesn't change direction when looking at it in the perspective view), but this doesn't happen. The result is that it seems to only take information on one axis.

I suspect it's my matrix construction at fault, which I tried to build based on the information I found at mikegreen.name, but I think I took a wrong turn somewhere.

Any math geniuses want to see where I've gone wrong?

Cheers,