Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exported lights point in the "wrong" direction #231

Open
sercero opened this issue Apr 6, 2024 · 9 comments
Open

Exported lights point in the "wrong" direction #231

sercero opened this issue Apr 6, 2024 · 9 comments

Comments

@sercero
Copy link
Collaborator

sercero commented Apr 6, 2024

Hello, @paroj.

While developing the ability to export rectangular lights, it came to my attention an issue regarding the exporting of lights.

Suppose we have a scene with a cube and a directional light of type "Sun".
image

By default in Blender a light with identity transform will have the light pointing downwards.

If we export the scene to OGREs coordinate system, and since blender2ogre does a conversion where x->x, y->z, z->-y,
then the result is that the cube now is in position (1, 0, -1) and the light is pointing towards -Z.
image

This is because since the light had identity transform in Blender its transform will not change in OGRE.
But the thing is that in OGRE the light will point towards -Z because that is what happens with a light that has no rotation.

I changed the code in scene.py so that the lights are the only objects transformed by a -90° rotation on the X axis.

What do you think?

@paroj
Copy link
Member

paroj commented Apr 6, 2024

This is because since the light had identity transform in Blender its transform will not change in OGRE.

can you link the code for this?

I would assume that issue this is not limited to lights. Try exporting the monkey mesh, instead of the symmetrical cube.

@paroj
Copy link
Member

paroj commented Apr 6, 2024

sidenote: if you are exporting the whole scene, you should not need to flip the coordinate axes. those are defined by the scene, which you are in full control of

@sercero
Copy link
Collaborator Author

sercero commented Apr 6, 2024

This is the function where each node in the scene is processed in terms of "axis swapping":

def _ogre_node_helper( doc, ob, prefix='', pos=None, rot=None, scl=None ):
# Get the object transform matrix
mat = ob.matrix_local
o = doc.createElement('node')
o.setAttribute('name', prefix + ob.name)
if pos:
v = swap(pos)
else:
v = swap( mat.to_translation() )
p = doc.createElement('position')
p.setAttribute('x', '%6f' % v.x)
p.setAttribute('y', '%6f' % v.y)
p.setAttribute('z', '%6f' % v.z)
o.appendChild(p)
if rot:
v = swap(rot)
else:
v = swap( mat.to_quaternion() )
q = doc.createElement('rotation') #('quaternion')
q.setAttribute('qx', '%6f' % v.x)
q.setAttribute('qy', '%6f' % v.y)
q.setAttribute('qz', '%6f' % v.z)
q.setAttribute('qw', '%6f' % v.w)
o.appendChild(q)
if scl: # this should not be used
v = swap(scl)
x=abs(v.x); y=abs(v.y); z=abs(v.z)
else: # scale is different in Ogre from blender - rotation is removed
ri = mat.to_quaternion().inverted().to_matrix()
scale = ri.to_4x4() @ mat
v = swap( scale.to_scale() )
x=abs(v.x); y=abs(v.y); z=abs(v.z)
s = doc.createElement('scale')
s.setAttribute('x', '%6f' % x)
s.setAttribute('y', '%6f' % y)
s.setAttribute('z', '%6f' % z)
o.appendChild(s)
return o

And in util.py you have the function that does the swapping for most of bleder2ogre:

def swap(vec):
if config.get('SWAP_AXIS') == 'xyz': return vec
elif config.get('SWAP_AXIS') == 'xzy':
if len(vec) == 3: return mathutils.Vector( [vec.x, vec.z, vec.y] )
elif len(vec) == 4: return mathutils.Quaternion( [ vec.w, vec.x, vec.z, vec.y] )
elif config.get('SWAP_AXIS') == '-xzy':
if len(vec) == 3: return mathutils.Vector( [-vec.x, vec.z, vec.y] )
elif len(vec) == 4: return mathutils.Quaternion( [ vec.w, -vec.x, vec.z, vec.y] )
elif config.get('SWAP_AXIS') == 'xz-y':
if len(vec) == 3: return mathutils.Vector( [vec.x, vec.z, -vec.y] )
elif len(vec) == 4: return mathutils.Quaternion( [ vec.w, vec.x, vec.z, -vec.y] )
else:
logging.warn( 'unknown swap axis mode %s', config.get('SWAP_AXIS') )
assert 0

@paroj
Copy link
Member

paroj commented Apr 7, 2024

ah.. ok.. I thought there is some explicit check for identity transform somewhere.

frankly I think that swap function is just broken for rotations and being needlessly slow due to all the ifs.

The correct approach would be just to construct a 3x3 matrix to transform both rotations and positions.
Note, that a Quaternion is not sufficient as the matrix would contain mirroring and not pure rotation.

@sercero
Copy link
Collaborator Author

sercero commented Apr 8, 2024

Yes, you are right.

When I discovered this, I spent 3 days in a deep confusion 😂.

I'll see how to do it with matrices.

Although let me tell you that despite all that... it works.

If you export a scene it looks correct even with rotations.

@sercero
Copy link
Collaborator Author

sercero commented Apr 8, 2024

So, really my question is this:
If you create a light in OGRE and the transform is identity, then the light should point towards -Z?
(I know it can be tested fairly easily but I want to know how it is supposed to work.)

If that is true, then there needs to be a correction.

@paroj
Copy link
Member

paroj commented Apr 8, 2024

If you create a light in OGRE and the transform is identity, then the light should point towards -Z?

yes. with identity transform lights and cameras in ogre point towards Z-

Although let me tell you that despite all that... it works.

actually, for meshes the rotation is taken care of by swapping the vertices (position) and lights are broken. So I still assume that it does not work :P

@sercero
Copy link
Collaborator Author

sercero commented Apr 8, 2024

If you create a light in OGRE and the transform is identity, then the light should point towards -Z?

yes. with identity transform lights and cameras in ogre point towards Z-

Although let me tell you that despite all that... it works.

actually, for meshes the rotation is taken care of by swapping the vertices (position) and lights are broken. So I still assume that it does not work :P

I mean, it works for everything except lights.

That is in fact everything is properly converted.

The issue is that in Blender lights with identity transform point downwards (-Y in OGRE) and in OGRE they point towards the "back" (-Z in OGRE), that is why lights need special handling.

@paroj
Copy link
Member

paroj commented Apr 15, 2024

That is in fact everything is properly converted.

see #240

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants