Sign in to follow this  
Raeldor

Gah! Right to Left Handed Conversion Driving Me Crazy

Recommended Posts

I have a 3D studio exporter which works fine, but my models are sideways because max is right handed and has y and z swapped. So, when exporting I swap y and z and negate z. This work fine for the model, but for the animation frames which are exported as translations and euler angles it doesn't seem to work. It seems to be a problem with the euler angles to which I am doing the same conversion. I have tried all permetations of converting the euler angles I can think of, but nothing is working. Any help as to what is going on here would be appreciated. Thanks

Share this post


Link to post
Share on other sites
Hi Raeldor,

I usually try to avoid giving advice on things I don't have direct experience with, which includes converting animations between coordinate systems. But since no one's answered yet I thought I'd just ask if you could give a more detailed description of the coordinate systems involved. For example you could say (assuming you're looking from behind the model), 'my system has z up, y forward, and x right, and max has y up, z forward, and x left'. Or whatever. That might make it easier to offer a specific suggestion about how to convert between the two systems.

Share this post


Link to post
Share on other sites
Quote:
Original post by jyk
Hi Raeldor,

I usually try to avoid giving advice on things I don't have direct experience with, which includes converting animations between coordinate systems. But since no one's answered yet I thought I'd just ask if you could give a more detailed description of the coordinate systems involved. For example you could say (assuming you're looking from behind the model), 'my system has z up, y forward, and x right, and max has y up, z forward, and x left'. Or whatever. That might make it easier to offer a specific suggestion about how to convert between the two systems.


Thank you. Any advice right now would be good advice. DirectX seems to have X right, Y up and Z into the distance. Max has X right, Z up and Y into the distance. I have negated one the the axis to convert from right to left handed when exporting vertices and normals which seems to work fine, but taking the euler angles from the conversion and doing the same does not give the desired result.

At this time I am not really sure if it is my math or the idiosynchrocies (spelling?) of Max. I read in the help file for max that taking rotation values from the matrix gives you a left handed rotation where as the rest of max is right handed. How can they use left handed matrices on a right handed system? Besides when I do take the rotation values it looks exactly the same as the rotation values in the interface which are supposed to be right handed.

FYI, I am getting the rotation values down the hierarchy by multiplying the world matrix for the node by the inverse of it's parent. That seems to work ok.

Share this post


Link to post
Share on other sites
Well, I don't think I have any more ideas - I just don't know enough about max or its format. But, here is a link to a series of articles (note the 'next time' link at the bottom) which appears to be related to the subject. It's several years old and I have no idea if it'll be useful, but who knows...

Share this post


Link to post
Share on other sites
Quote:
Original post by Raeldor

Thank you. Any advice right now would be good advice. DirectX seems to have X right, Y up and Z into the distance. Max has X right, Z up and Y into the distance. I have negated one the the axis to convert from right to left handed when exporting vertices and normals which seems to work fine, but taking the euler angles from the conversion and doing the same does not give the desired result.



Hi Raeldor, the issue is that you do not need to negate the Z axis in your conversion. As you say, the 3ds max Y axis points into the screen and the Z axis up, so swapping the Z and Y axis will make your Z point into the screen and Y up, the way directx likes it to be. You might also want to change the winding order of your triangles or you could change the cullmode. And don't forget to swap the axis on your normals and any transforms you export as well.

hope this helps,
svein

Share this post


Link to post
Share on other sites
Quote:
Original post by sveinm
Quote:
Original post by Raeldor

Thank you. Any advice right now would be good advice. DirectX seems to have X right, Y up and Z into the distance. Max has X right, Z up and Y into the distance. I have negated one the the axis to convert from right to left handed when exporting vertices and normals which seems to work fine, but taking the euler angles from the conversion and doing the same does not give the desired result.



Hi Raeldor, the issue is that you do not need to negate the Z axis in your conversion. As you say, the 3ds max Y axis points into the screen and the Z axis up, so swapping the Z and Y axis will make your Z point into the screen and Y up, the way directx likes it to be. You might also want to change the winding order of your triangles or you could change the cullmode. And don't forget to swap the axis on your normals and any transforms you export as well.

hope this helps,
svein


Thank you. This seems to work for the geometry, but the rotation animations are still wrong somewhere. If I take my rotation information as euler angles, should I just be able to swap the axis in the same way, or is it more complicated than that?

Share this post


Link to post
Share on other sites
Quote:
Original post by Raeldor
Thank you. This seems to work for the geometry, but the rotation animations are still wrong somewhere. If I take my rotation information as euler angles, should I just be able to swap the axis in the same way, or is it more complicated than that?


My guess would be that you should be able to just swap the axis in the same way for your angles and it should work. However, if the animation used to work when the model was on its side (pre y/z swap), you will probably have to change the order you apply the rotations in, and possibly the sign of the angles as well. Sorry about this sounding pretty vague, but these things tend to be a bit confusing. Another thing I would recommend would be to make some simple animations, rotating around each of the axis to see which components you need to swap, and wether the signs are right etc. Also, don't forget to swap the y and z on your translations as well.

good luck,
svein

Share this post


Link to post
Share on other sites
hi. swapping y with z for direct x and -y with z for opengl works fine for geometry, but it gets complicated when using textures and stuff. the method i use (for opengl, but it would work for directx too) is to apply a rotation and save it on the stack before all transformations in the scene, after you load the identity matrix. In opengl will be:
glLoadIdentity();
glRotatef(90.0, 1.0, 0, 0); //a rotation around the X axis, that brings up the Y axis)
glPushMatrix();
....
//al the transform code goes here
....
glPopMatrix();

hope it helps.

Share this post


Link to post
Share on other sites
Quote:
Original post by sveinm
Quote:
Original post by Raeldor
Thank you. This seems to work for the geometry, but the rotation animations are still wrong somewhere. If I take my rotation information as euler angles, should I just be able to swap the axis in the same way, or is it more complicated than that?


My guess would be that you should be able to just swap the axis in the same way for your angles and it should work. However, if the animation used to work when the model was on its side (pre y/z swap), you will probably have to change the order you apply the rotations in, and possibly the sign of the angles as well. Sorry about this sounding pretty vague, but these things tend to be a bit confusing. Another thing I would recommend would be to make some simple animations, rotating around each of the axis to see which components you need to swap, and wether the signs are right etc. Also, don't forget to swap the y and z on your translations as well.

good luck,
svein


I finally got it to work, but it's not ideal. Instead of swapping the Y and Z, I instead negated the Z axis for all vertex and translation output. However to get the rotations to work I had to negate the X and Y portion or the euler angles. What is the logic behind this?

As I say it is not ideal, as now I have to rotate all my models when I import them. If I can figure out why I have to negate the XY of the rotations, maybe it will help fix the problems I am having when swapping YZ on the vertices.

Share this post


Link to post
Share on other sites
Quote:
Original post by Raeldor
I finally got it to work, but it's not ideal. Instead of swapping the Y and Z, I instead negated the Z axis for all vertex and translation output. However to get the rotations to work I had to negate the X and Y portion or the euler angles. What is the logic behind this?

As I say it is not ideal, as now I have to rotate all my models when I import them. If I can figure out why I have to negate the XY of the rotations, maybe it will help fix the problems I am having when swapping YZ on the vertices.


Not quite sure what the logic is behind negating the x and y portion of the euler angles are, but I can only assume that when you change the coordinate system around like that you need to change the sign of your rotations.

Anyways, if you're calculating your euler angles from the world transform of the node, you will need to swap the rows and columns of your matrix around before you calculate the euler angles as well, that is if you would like ot swap the y and z of your vertices around. Just swap row 1 and 2 and column 1 and 2 around before you calculate the euler angles, that way the transform should be in the same coordinate space as your vertices.

svein

Share this post


Link to post
Share on other sites
Hi,

I'm not a math wizzard, so I can't explain how I came up with the following code (it was pure hack : try something, see if it works, etc. ^^) But I've been using it for more than half a year now, and it works.

Here's a piece of code I use in my exporter :


// transform each vertex
for (unsigned int v = 0; v < m_VertexList.GetNum(); v++)
{
m_VertexList[v].position.x = -m_VertexList[v].position.x;
m_VertexList[v].normal.x = -m_VertexList[v].normal.x;
}

// ...

// extract the transformations from the transform
transform.getRotation(eulerRotation);
transform.getScale(scale);
translation = transform.translation(MSpace::kWorld);

// convert it to left handed :
// - negate translation along X
// - negate rotations around Y and Z
translation.x = -translation.x;
eulerRotation.y = -eulerRotation.y;
eulerRotation.z = -eulerRotation.z;

// rebuild a transformtion matrix from the modified transformations
MTransformationMatrix transformationMatrix;
transformationMatrix = transformationMatrix.identity;
transformationMatrix.rotateBy(eulerRotation, MSpace::kWorld);
transformationMatrix.setScale(scale, MSpace::kObject);
transformationMatrix.setTranslation(translation, MSpace::kWorld);



It's the same as you do. I think that when we switch from right to left handed systems, the rotation orders change. So we should invert all rotations. BUT we also have to invert 1 axis. So, inverting this axis and inverting the rotation around it would give the same rotation. That's why, if we invert X, we only need to invert rotations around Y and Z.
I'm pretty sur that if we add to invert the Y axis (for example), we would have to invert rotations around X and Z.

That's the only explanation I can find with the pieces of math I still remember from my studies ^^

Share this post


Link to post
Share on other sites
Euler angle rotation is not commutative. Also, they rotate clockwise (left handed) or anti-clockwise (right handed) depending on the handedness of the coordinate system.

Also, to my understanding, Euler angles work by a rotation first around the x then the y then the z axes. Currently doing this with a right handed model on a left handed system, you're actually doing rotations around x, then z, then y.

So theoretically, in order for this to work, first you should swap your y and z axes to convert the coordinate system (i.e. swap your y and z components of the Euler angle set).

Thereby rotations will be applied in x, y and z in correct order.

Now, only slightly more difficult, negate the angle of each subset in the Euler angle set you're using.

-X, -Y, -Z

reason being that you have to convert from rotating anti-clockwise to clockwise.

I hope this works, I'm a little rusty with Euler angles and I've never actually used them in a game or programmed them or converted them from right handed to left handed. This is more or less a guess and my doing some working in the past 5 minutes off the top of my head.

Share this post


Link to post
Share on other sites
Quote:
It's the same as you do. I think that when we switch from right to left handed systems, the rotation orders change. So we should invert all rotations. BUT we also have to invert 1 axis. So, inverting this axis and inverting the rotation around it would give the same rotation. That's why, if we invert X, we only need to invert rotations around Y and Z.
I'm pretty sur that if we add to invert the Y axis (for example), we would have to invert rotations around X and Z.

Thanks. This makes a lot of sense and I think that's what is going on here. However, I still can't get my head around what is going on when I instead swap the Y and Z axis.

Quote:
So theoretically, in order for this to work, first you should swap your y and z axes to convert the coordinate system (i.e. swap your y and z components of the Euler angle set).

Thereby rotations will be applied in x, y and z in correct order.

Now, only slightly more difficult, negate the angle of each subset in the Euler angle set you're using.

-X, -Y, -Z

reason being that you have to convert from rotating anti-clockwise to clockwise.

I tried this, but still no luck and the animations are still mangled. I tried a few combinations of negating different axis, but still no joy.

Share this post


Link to post
Share on other sites
Quote:
Original post by Leo_E_49
Question, are you negating the angles or their sines and cosines? There's a BIG difference between the two.


I am negating the angles, ie the euler values.

Share this post


Link to post
Share on other sites
Is there any chance you could change the animation system to use quaternions? There are a bunch of other advantages to this representation as well. In my Max exporter I just convert the quaternions by converting to axis angle, then applying the same axis swap (y <-> z) then converting back to a quaternion. This probably isn't the best way but it works and makes sense.

Share this post


Link to post
Share on other sites
Quote:
Original post by d00fus
Is there any chance you could change the animation system to use quaternions? There are a bunch of other advantages to this representation as well. In my Max exporter I just convert the quaternions by converting to axis angle, then applying the same axis swap (y <-> z) then converting back to a quaternion. This probably isn't the best way but it works and makes sense.


I am currently exporting as euler angles and then converting the eulers into quaternions in my engine. The reason I went with eulers is because it makes the export file more readable and easier to find errors.

I could go with quaternions (I originally was using quaternions but changed to eulers), but I am thinking I will still have the same problem and it will just make it worse because the quaternions are pretty unreadable and I will end up with less of a clue than I have now (pretty much why I changed to eulers in the first place! :P).

Share this post


Link to post
Share on other sites
Quote:
Original post by Leo_E_49
Now, only slightly more difficult, negate the angle of each subset in the Euler angle set you're using.

-X, -Y, -Z


Actully come to think of it... Why do you need to swap the Y and Z axes for rotations? Translations yes, but rotations, this is confusing me. :S

This concept supports your results from negating X and Y components. All you should have to do is negate the Z component too. Why it popped into my head that you have to swap the Y and Z axes for rotations I don't know. :(

Share this post


Link to post
Share on other sites
Quote:
Actully come to think of it... Why do you need to swap the Y and Z axes for rotations? Translations yes, but rotations, this is confusing me. :S


Yeah, it's confusing me too. I know that it doesn't work if I just leave them as is, so swapping the Y and Z for vertices definitely affects the rotations somehow.

Share this post


Link to post
Share on other sites
Quote:
Original post by Leo_E_49
Would you mind showing us your actual code? It might make things a little easier.


Ok, this is the code that works...

--
-- my first export script
--
-- export all selected objects and scene materials
-- written by ray price 8/30/05
--

-- check we have a selected object
if selection.count < 1 then
messagebox "You must have at least one object selected."
else
(
-- check validity of objects
allvalid=true
for s=1 to selection.count do
(
-- must be an editable mesh
mytri = snapshotasmesh selection[s]
mymesh = selection[s]
if classof mytri != trimesh then
(
msg="Mesh "+mymesh.name+" is not an editable mesh. Cannot export."
messagebox msg
allvalid=false
exit
)
else
(
-- mesh must have a standard material
if classof mymesh.material != standardmaterial then
(
msg="Mesh " + mymesh.name + " must have a standard material. Cannot export."
messagebox msg
allvalid=false
exit
)
)
)

-- if all objects are valid for export
if allvalid then
(
-- open binary file
myfilename = getsavefilename caption:"Export to..." types:"Data(*.dat)|*.dat"
outfile = fopen myfilename "wbS"

-- get used material count
usedmaterialcount=0
for m=1 to scenematerials.count do
(
-- make sure item is used
used=false
for s=1 to selection.count do
(
matindex = finditem scenematerials selection[s].material
if matindex == m then
(
used=true
exit
)
)

-- if used, add to count
if used then
usedmaterialcount = usedmaterialcount + 1
)

-- write out scene materials
writeshort outfile usedmaterialcount #unsigned
for m=1 to scenematerials.count do
(
-- make sure item is used
used=false
for s=1 to selection.count do
(
matindex = finditem scenematerials selection[s].material
if matindex == m then
(
used=true
exit
)
)

-- if used, continue
if used then
(
-- get next material
thismat=scenematerials[m]

-- write out the material properties
writefloat outfile (thismat.ambient.a/255)
writefloat outfile (thismat.ambient.r/255)
writefloat outfile (thismat.ambient.g/255)
writefloat outfile (thismat.ambient.b/255)
writefloat outfile (thismat.diffuse.a/255)
writefloat outfile (thismat.diffuse.r/255)
writefloat outfile (thismat.diffuse.g/255)
writefloat outfile (thismat.diffuse.b/255)
writefloat outfile (thismat.specular.a/255)
writefloat outfile (thismat.specular.r/255)
writefloat outfile (thismat.specular.g/255)
writefloat outfile (thismat.specular.b/255)

-- write out the texture filename
if classof thismat.diffusemap == undefinedclass then
writestring outfile ""
else
writestring outfile thismat.diffusemap.filename
)
)

-- write as a hierarchy so only process root objects
rootcount=0
for i=1 to selection.count do
(
if selection[i].parent == selection[1].parent then
rootcount=rootcount+1
)

-- for each selected object
writeshort outfile rootcount #unsigned
for s=1 to selection.count do
(
-- process root objects resursively
if selection[s].parent == selection[1].parent then
(
writemesh selection[s] outfile
)
)

-- close file
fclose outfile

-- success
messagebox "Export complete"
)
)

-- write out vertex details now we have the index!!
fn writevertex mytri mymesh vindex outfile =
(
-- now we have the real vertex details, output to file
-- reverse z and y like direct3d
-- multiply world vertex by inverse mesh objecttransform to get true local
--
-- mytri tri is fixed vertices at time of snapshot, so make sure snapshot
-- is not taken in pose position!
--
meshvert = in coordsys world getvert mytri vindex
meshvert = meshvert * (inverse mymesh.transform)
writefloat outfile meshvert.x
writefloat outfile meshvert.y
writefloat outfile -meshvert.z

-- now we need to calculate the vertex normal
-- using all the attached polys faces
vertfaces = meshop.getpolysusingvert mytri vindex
vertnorm = point3 0 0 0
for vf=1 to vertfaces.count do
(
if vertfaces[vf] then
(
-- get the normal for this face
-- use mesh to get local normal, not tri
thisnorm = in coordsys local getfacenormal mymesh vf

-- add to running normal
vertnorm = vertnorm + thisnorm
)
)

-- normalize our normal
vertnorm = normalize vertnorm

-- output the vertex normal
writefloat outfile vertnorm.x
writefloat outfile vertnorm.y
writefloat outfile -vertnorm.z
)

fn writemesh mymesh outfile =
(
-- set to first animation frame
at time 1
(
-- get mesh version of object
-- mytri = snapshotasmesh mymesh
mytri=mymesh

-- write out name
writestring outfile mymesh.name

-- get local position and rotation info from controller helper
-- use it to build a local transform matrix
conthelper=exposetm pos:[0,0,0]
conthelper.exposenode=mymesh
conthelper.localreferencenode=mymesh.parent

-- write out initial rotation
-- this is currently in left handed form, need to convert to right handed
-- also, y and z are reversed
myquat=eulertoquat (eulerangles conthelper.localeulerx conthelper.localeulery conthelper.localeulerz)
myquat=inverse myquat
writefloat outfile myquat.x
writefloat outfile myquat.y
writefloat outfile myquat.z
writefloat outfile myquat.w

-- write out initial position
writefloat outfile conthelper.localposition.x
writefloat outfile conthelper.localposition.y
writefloat outfile -conthelper.localposition.z

-- see if we have uv mapping
mapsupport=meshop.getmapsupport mytri 1

-- get vertex count
if mapsupport then
numverts = meshop.getnummapverts mytri 1
else
numverts = meshop.getnumverts mytri

-- find true vertex count (those used by texture faces)
if mapsupport then
(
trueverts = 0
for v=1 to numverts do
(
-- find texture faces that uses this vert
tvertfaces = meshop.getmapfacesusingmapvert mytri 1 v
for f=1 to tvertfaces.count do
(
-- if this face uses the texture vertex
if tvertfaces[f] then
(
trueverts = trueverts + 1
exit
)
)
)
)
else
trueverts = numverts

-- write out vertex count
writelong outfile trueverts #unsigned

-- we have to build a mapping array because some of the texture vertices can be un-used
-- by any of the faces


-- really we must output same number of vertices
-- as that of tverts, not verts! this will mean
-- outputing the texture vertices instead of the
-- regular vertices and the texture faces instead
-- of the regular faces
ourvertindex=1
ourvertmap=#()
for v=1 to numverts do
(
-- default index map to zero
ourvertmap[v]=0

if not mapsupport then
(
-- write out this vertex
writevertex mytri mymesh v outfile

-- output dummy uv for now!
writefloat outfile 0
writefloat outfile 0

-- build our vertex index array
ourvertmap[v]=ourvertindex
ourvertindex=ourvertindex+1
)
else
(
-- find texture faces that uses this vert
tvertfaces = meshop.getmapfacesusingmapvert mytri 1 v
for f=1 to tvertfaces.count do
(
-- if this face uses the texture vertex
if tvertfaces[f] then
(
-- find which index in texture face
tvertindexes = meshop.getmapface mytri 1 f
tvindex = 0
if tvertindexes[1] == v then tvindex=1
if tvertindexes[2] == v then tvindex=2
if tvertindexes[3] == v then tvindex=3

-- find same index in mesh face
vertindexes = getface mytri f
vindex = vertindexes[tvindex]

-- write vertex out using function
writevertex mytri mymesh vindex outfile

-- now get texture vertex and output uv
texvert = meshop.getmapvert mytri 1 v
writefloat outfile texvert.x
writefloat outfile texvert.y

-- build our vertex index array
ourvertmap[v]=ourvertindex
ourvertindex=ourvertindex+1

-- we only need to find the first one
exit
)
)
)
)

-- write out number of faces
if mapsupport then
numfaces = meshop.getnummapfaces mytri 1
else
numfaces = meshop.getnumfaces mytri
writelong outfile numfaces #unsigned

-- now write out mesh faces using texture faces so we get
-- correct corresponding uv's
for f=1 to numfaces do
(
-- use texure vertex index
-- use zero based though, so -1!
if mapsupport then
face=meshop.getmapface mytri 1 f
else
face=getface mytri f

-- reverse winding order of faces for left handed
writeshort outfile (ourvertmap[face.x]-1) #unsigned
writeshort outfile (ourvertmap[face.z]-1) #unsigned
writeshort outfile (ourvertmap[face.y]-1) #unsigned
)
)

-- write out material index
matindex = finditem scenematerials mymesh.material
writeshort outfile matindex #unsigned

-- animationrange.start
-- animationrange.end
-- currenttime
-- framerate
-- trackbar.getnextkeytime
-- write out number of rotation keyframes
writelong outfile (animationrange.end-animationrange.start+1) #unsigned

-- loop through animation frames
for fr=animationrange.start to animationrange.end do
(
-- write out rotation keyframe
at time fr
(
writefloat outfile (fr/framerate)
if mymesh.parent == selection[1].parent then
mymat=in coordsys world mymesh.transform
else
mymat=in coordsys world (mymesh.transform*(inverse mymesh.parent.transform))
myeuler=(inverse mymat.rotationpart) as eulerangles
writefloat outfile -myeuler.x
writefloat outfile -myeuler.y
writefloat outfile myeuler.z
)
)

-- write out number of translation keyframes
writelong outfile (animationrange.end-animationrange.start+1) #unsigned

-- loop through animation frames
for fr=animationrange.start to animationrange.end do
(
-- write out translation keyframe
at time fr
(
writefloat outfile (fr/framerate)
if mymesh.parent == selection[1].parent then
mypos=in coordsys world mymesh.transform.position
else
mypos=in coordsys world (mymesh.transform*(inverse mymesh.parent.transform)).position
writefloat outfile mypos.x
writefloat outfile mypos.y
writefloat outfile -mypos.z
)
)

-- delete cont helper
delete conthelper

-- only count children that are selected
childcount=0
for c=1 to mymesh.children.count do
(
if mymesh.children[c].isselected then
childcount=childcount+1
)

-- write out number of children
writeshort outfile childcount #unsigned

-- process children
for c=1 to mymesh.children.count do
if mymesh.children[c].isselected then
writemesh mymesh.children[c] outfile
)



However, when I swap the Y and Z axis instead of using the negating of Z then it all goes pear-shaped when it's bought into my engine. The fact that it works using the negating leads me to believe my engine is ok, and that the euler to quaternions and quaternions to matrix functions are all good. I think the issue lies somewhere in how to handle exporting the rotations when you swap Y and Z.

Share this post


Link to post
Share on other sites
Hi,
I had the same problem once, and I realized that I had to talk to the artists on their own terms... so I switched the hand of the engine.

This is pretty easy to do with DX and just in 3 easy steps.

a. Instead of using D3DXCreateLeftHandedViewMatrix (or something like that... I dont recall the exact name) just use the D3DXCreateRightHandedViewMatrix in order to create your view. This puts you in the same system than Max.

b. Change your up vector. In a D3D app this is usually Y for up and Z for depth, noy you use Z for up and Y for depth.

c. Change your cull mode from CCW to CW.

Thats all. Its really easy and your artists will thank you a lot.

Luck!
Guimo


Share this post


Link to post
Share on other sites
Then you'd have to change your entire game to a left handed coordinate system, wouldn't you?

Try this, for translations and vertex positions only swap the Y and Z coordinates but for rotations only negate all x, y and z components without swapping the Y and Z axes. This should work and is logical and can be explained.

When you rotate around the z axis in the left handed model, converting that you don't want to rotate around the y axis!, you want to rotate the other direction about the z axis! The right handedness changes rotations from clockwise to anti-clockwise but it doesn't affect the axes at all!

[eureka moment]When you translate, sweeping the y to z axis in the left handed coordinate system occurs clockwise, in the right handed system it occurs anti-clockwise. Therefore we reverse the direction which one is swept to another by swapping their positions. This is why we swap y and z axes for translations, we're negating the rotation of one axis to the other. It all makes sense now! :)[/eureka moment]

Ignore the eureka moment, things just fell in place in my mind and I felt like writing it down. If you can actually understand it, congratulations, you must be one of the best translators on the planet.

Share this post


Link to post
Share on other sites
Quote:
Try this, for translations and vertex positions only swap the Y and Z coordinates but for rotations only negate all x, y and z components without swapping the Y and Z axes. This should work and is logical and can be explained.

I tried this and it VERY close, but still not quite right. My characters legs appear crossed. Interestingly enough I am not sure if this applies, but the the model is a four legged animal. The front legs look wrong, but the back legs look right. Is it possible that swapping the Y and Z could produce an effect where the rotations have to be reversed on only one side of the axis?

Share this post


Link to post
Share on other sites
Quote:
Original post by Raeldor
I tried this and it VERY close, but still not quite right. My characters legs appear crossed. Interestingly enough I am not sure if this applies, but the the model is a four legged animal. The front legs look wrong, but the back legs look right. Is it possible that swapping the Y and Z could produce an effect where the rotations have to be reversed on only one side of the axis?


I still think you will need to rearrange the rows and columns in the matrix before you convert to euler angles, pretty much the same way as you do with the y and z components in the vertices and normals, the following code snippet should do it ....


-- your code
if mymesh.parent == selection[1].parent then
mymat=in coordsys world mymesh.transform
else
mymat=in coordsys world (mymesh.transform*(inverse mymesh.parent.transform))

--insert this bit
m = matrix3 [1,0,0] [0,0,1] [0,1,0] [0,0,0]
mymat = m * mymat * m
-- your code continues here...
myeuler=(inverse mymat.rotationpart) as eulerangles




hopefully this will do the trick, I do something similar in my animation exporter and it works fine, however I use quaternions not euler angles.

svein

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this