Unity-like transform component

Started by
9 comments, last by cadjunkie 10 years, 2 months ago

I'd like to implement a transform component just like Unity's transform, i.e. a transform hierarchy which allows rotation, translation and non uniform scaling stored as quaternions and vectors

the task shouldn't be too hard, but there's an aspect i'm not sure of

Unity allows programmers to access world position, rotation and scaling individually and i'm wondering what's a good way to implement this

my naive solution would be just computing the 4x4 transform matrix through the hierarchy and decompose it somehow (polar decomposition or singular value decoposition should do the job i think but i don't know much about this yet)

however, this way i would not make use of the decomposition i already have for each transform in the hierarchy so i wonder if there's some way to do it faster

Advertisement

Is there a framework that you're using or are you creating something like that in DirectX/OpenGL/etc?

Is there a framework that you're using or are you creating something like that in DirectX/OpenGL/etc?

i am not sure what you mean, i just have a transformation stored as 2 vectors for scaling and position and 1 quaternion for rotation, i don't have any dependency for that

i want it to have one or no parent, thus forming a hierarchy of transformation

i can easily compute the world matrix for a node in the hierarchy by multiplying the transform (T * R * S) for each transform 4x4 matrix along the hierarchy

but what i'd like and i'm not sure of is how to implement the same methods Unity transform component has that allow to read and write the global rotation translation and scaling of any "node" in the hierarchy

this means to me i have to somehow decompose the transform matrix (obtained multiplying the ancestor matrices) in the T, R, S components, but this doesn't seem to me like a task i want to do each time i reposition something in the hierarchy

i'm actually curious if it can be done more efficiently, or how Unity provides this decomposition, if anybody has an idea about it

It's probably doing a lazy evaluation. In other words, it probably only calculates the global R/T/S the moment you access them, and keeps a 'global properties are dirty' flag otherwise. Since most scripts aren't doing this very frequently it doesn't impact performance too much.

This is just speculation, though.

It's probably doing a lazy evaluation. In other words, it probably only calculates the global R/T/S the moment you access them, and keeps a 'global properties are dirty' flag otherwise. Since most scripts aren't doing this very frequently it doesn't impact performance too much.

This is just speculation, though.

i think so too, probably i should just drop it, my goal was like having a transform i can update from physics but even unity just either uses transforms or physics component actually

so whatever, thank you

I wonder how Unity does this. If they support non-uniform scaling they cannot decompose necessarily only into TRS. They might be also a shear component like in Maya.

I wonder how Unity does this. If they support non-uniform scaling they cannot decompose necessarily only into TRS. They might be also a shear component like in Maya.

yes non uniform scaling

i'm not sure about this either, if this is the best you can do, it's not enough

edit: ok, this makes it clearer (quote from here)

Performance Issues and Limitations with Non-Uniform Scaling

Non-uniform scaling is when the Scale in a Transform has different values for x, y, and z; for example (2, 4, 2). In contrast, uniform scaling has the same value for x, y, and z; for example (3, 3, 3). Non-uniform scaling can be useful in a few select cases but should be avoided whenever possible.

Non-uniform scaling has a negative impact on rendering performance. In order to transform vertex normals correctly, we transform the mesh on the CPU and create an extra copy of the data. Normally we can keep the mesh shared between instances in graphics memory, but in this case you pay both a CPU and memory cost per instance.

There are also certain limitations in how Unity handles non-uniform scaling:

  • Certain components do not fully support non-uniform scaling. For example, for components with a radius property or similar, such as a Sphere Collider, Capsule Collider, Light, Audio Source etc., the shape will never become elliptical but remain circular/spherical regardless of non-uniform scaling.
  • A child object that has a non-uniformly scaled parent and is rotated relative to that parent may have a non-orthogonal matrix, meaning that it may appear skewed. Some components that do support simple non-uniform scaling still do not support non-orthogonal matrices. For example, a Box Collider cannot be skewed so if its transform is non-orthogonal, the Box Collider will not match the shape of the rendered mesh accurately.
  • For performance reasons, a child object that has a non-uniformly scaled parent will not have its scale/matrix automatically updated while rotating. This may result in popping of the scale once the scale is updated, for example if the object is detached from its parent.

I like how joints in Maya handle scale. Essentially the scale doesn't propagate down to the children. I recently needed to work with Maya and while their SDK is definitely ugly, you will find a lot of interesting things.

Here are some references:

http://download.autodesk.com/us/maya/2009help/API/class_m_fn_transform.html

http://download.autodesk.com/us/maya/2011help/API/class_m_fn_ik_joint.html

http://download.autodesk.com/us/maya/2011help/API/class_m_transformation_matrix.html

I actually wanted to do the exact same thing as tuccio. I used glm (since I'm using OpenGL).
This is how far I came:

http://pastebin.com/xGfcYq0n (.h file)
http://pastebin.com/xk1LzXJi (.cpp file)

But it still doesnt provide all needed funtionality, for example I dont know how to implement scaling now. Some parts of the copy comes from google, so I also dont know if there is a better way to do it. Maybe we could build something useful together?
Anyone? I currently really have problems with the rotation part. I would like to create the rotate function like unity, so that i can tell in which orientation to rotate. (world or local). But I dont know how to do that.

This topic is closed to new replies.

Advertisement