PDA

View Full Version : Calculating a point from rotation matrix

05-11-2008, 01:39 PM
My brain is mush.

I'm trying to calculate an xyz vector point from the rotation matrix in Lscript.
basically, if I have two bones, and I want the offset of the child's bone's tip (see attached img), it should be a simple matrix operation.

Multiply the length of the bone times it's rotation matrix.

But I'm missing something...

SelectItem(bone.id);
lng = bone.restlength;

//transform vector by a matrix

m0vec = bone.getRight(0);
m1vec = bone.getUp(0);
m2vec = bone.getForward(0);

//my x and y are 0
//z = length of bone
newx = 0 + 0 + m0vec.z * lng ;
newy = 0 + 0 + m1vec.z * lng ;
newz = 0 + 0 + m2vec.z * lng ;

Position(<newx,newy,newz>);

The up, right , forward may be mixed up, but i've tried different combos.
Can anyone confirm that this is the right matrix? What am i miss-thinking?

Lightwolf
05-11-2008, 01:50 PM
Erm... I'm wondering if the matrix is needed in the first place.
You want to find the tip, which is bone.restlength * bone.getForward(0) if I'm not entirely mistaken.

Edit: bone.getForward(0) needs to get normalized, at least according to the (C) SDK.

Cheers,
Mike

05-11-2008, 02:33 PM
Ok. So I pulled the wrong forward out of the matrix in the above sample.
Revised, I am still not seeing good results.

SelectItem(bone.id);
lng = bone.restlength;

//transform vector by a matrix

m0vec = normalize(bone.getRight(0));
m1vec = normalize(bone.getUp(0));
m2vec = normalize(bone.getForward(0));

//my x and y are 0
//z = length of bone
newx = 0 + 0 + m2vec.x * lng ;
newy = 0 + 0 + m2vec.y * lng ;
newz = 0 + 0 + m2vec.z * lng ;

Position(<newx,newy,newz>);

05-11-2008, 02:40 PM

I've set up a test scene.

Attached is the scene file (v9.5beta), and here is a "move_to_tip" script.
create a null, parent to bone.
select null, run script.
null should be placed at tip of bone

@version 2.6
@warnings 1
@name "Move_to_tip"
@script generic

//useage: create a null, parent to bone. select null, run script. null should be placed at tip of bone
generic {
scene = Scene();
if(!scene.getSelect()) return; //there are times when no mesh is selected
s = scene.getSelect();

if(sizeof(s) >1) {
info("Available for only one object at a time.");
return 0;
}

if(s[1]) obj = pp = s[1];

//create bone ob
while(pp) {
par = pp;
pp = pp.parent;
}

m = Mesh(par.id);
startbone = m.bone();

if(!startbone ) {
info("No bones.");
return 0;
}

//bone we want is parented already to
bone = obj.parent;

lng = bone.restlength;
pos = bone.getPosition(0);
rot = bone.getRotation(0);

//since we are in the parent's rotation space
//we need to position to the current bone's rotation space to position properly
//transform vector by a matrix

m0vec = normalize(bone.getRight(0));
m1vec = normalize(bone.getUp(0));
m2vec = normalize(bone.getForward(0));

//my x and y are 0
//z = length of bone
newx = 0 + 0 + m2vec.x * lng ;
newy = 0 + 0 + m2vec.y * lng ;
newz = 0 + 0 + m2vec.z * lng ;

SelectItem(obj.id);
Position(<newx,newy,newz>);

}

Doesn't seem to work.
Anyone have any insight?

Lightwolf
05-11-2008, 02:49 PM
Erm, if it is parented to the parent bone, all you need is to shift along Z.

Cheers,
Mike

05-11-2008, 04:02 PM
For this specific result, yes, that would work. But I'm using this setup as a test to try and figure out how to get the math to work.

The need for this is that I want to move a bone's base to it's own tip. So therefore it'll be in it's parent's space.

The bigger idea is to incorporate this into a zbone to joints converter for 9.5.

05-19-2008, 01:04 AM
I have found my solution, but the answer is not pretty (if anyone cares).

I don't know why, but LScript's getForward() isn't returning expected results. I don't know why and I'm not going to waste time with it.

My answer was to build my own matrix from HPB, and do the calculations from that.

Plus, the "move-to-tip" experiment was a little off-- the null should be parented to the parent of the bone in question-- any movement to the rotation of the bone will result in a change in relational space. Parent the null to the parent bone, and apply an offset and things worked (with my own matrix).

But it didn't work with getForward(). I didn't try getWorldForward, because I didn't feel like changing to local space. I also didn't test any calculations in C/C++, because I wanted a quick and dirty cross-platform solution.