Applying components of a move delta

Started by
3 comments, last by LWard 7 years, 7 months ago

I have a vec3 called delta that represents (in world coordinates) the amount by which an object's position should be moved in the X,Y and Z directions (in world coordinates).

But sometimes I want to apply just the X delta for instance (i.e. I want to discard the Y and Z components) moving the object by X delta along the object's X-axis so that when the delta is applied it effectively moves the object in the world but along the direction of the object's X-axis (if that makes sense).

I tried doing this by (given an object with a 4x4 local to world matrix):

a) Multiply vec3(1.f, 0.f, 0.f) (i.e. the object's X-axis in its local coord system) by the object's local to world matrix, i.e. translate the object's x-axis into the world coord system

b) Multiply the vec3 delta by the transformed x-axis vector from step (a) in the hope of adjusting the delta so it only applies the X component

c) Apply the X delta from step (b) to the object's position

This doesn't work so clearly I'm confused about something, I think step a) is wrong so instead for step a):

If I have the object's local to world transform components stored separately i.e. scale, orientation (quaternion) and position then I think I can generate a 3x3 rotation matrix from the orientation quaternion that will give me the object's basis vectors (i.e. the X, Y and Z axis) expressed in world coordinates un-scaled and un-translated? If so I can then do steps b and c with the X basis vector to mask off (remove) the Y and Z components.

Is this correct?

Thanks in advance for any help.

Advertisement

If you want to translate an object on just one axis, such as the X axis, all you will need to do is get the objects current location (i.e. 4x4 Matrix or 3D vector etc. depending how you're storing it) then apply your delta vec3 to that and update the original matrix or vec3.

For example:

get position from object

get delta from object

add delta to oringial position

set position with the new position

However, this doesn't take into account of the rotation of the object. For example, if it is 45 degrees to the right.

You're on the right tracks when you're going to generate a rotation matrix from the quaternion, you could also do this as a quaternion without converting to a matrix if you like. The quaternion (or matrix) will tell you the orientation your object is facing in, from this you can work out the objects local X axis (i.e left and right of the object), now apply this to your delta vector then add the delta vector to your position like you would normally.

Another way of thinking about it is you're rotating your delta vector to apply the objects' orientation, then using this for the translation.

Thanks for the reply LWard. I haven't tried it yet but glad to know the 2nd approach is closer to how it should be done.

The following works but I have to hop from the world coord system into local (to multiply out the components I dont need) and then hop back into the world coord system to apply the delta. If anyone can explain how to do this staying in the world coordinate system that would be great:

// basis vectors (local object coord system)
Vector3 basis[3] =
{
Vector3(1.f, 0.f, 0.f), // X basis
Vector3(0.f, 1.f, 0.f), // Y basis
Vector3(0.f, 0.f, 1.f) // Z basis
};
Vector3 delta;
if(hasPrevious_)
{
delta = ip - previousPos_; // ip (intersection point) and previousPos_ (previous intersection point) are in world coords
Vector4 deltaX = rPicked.GetWorldMatrixInverse() * Vector4(delta, 0.f); // translate the delta into the objetc's coord system
delta = Vector3(deltaX) * basis[activeAxis_]; // remove components we aren't interested in, so if we want just X component of delta multiply by X basis
delta = Vector3(rPicked.GetWorldMatrix() * Vector4(delta, 0.f)); // translate the delta back into world coords
}
// apply delta to object's position (object's position being expressed in world coords)

// ...

If there's a simpler way then it would be great if someone could share / explain it.

Glad to hear that you have got it working.

There are a few ways you can do this without converting from world space to local space and back again that I can think of.

The first idea would be to not multiplying the objects position with any matrices until you need to, such as not until passing values into your shaders for rendering. This way you could then apply your delta to the objects position without worrying about any matrices.

The second idea, might involve less work or restructuring than the first idea, is to apply the same world matrix to the delta vector so the delta and objects position are in the same world space. Now you can do the same with the delta vector as you have done already then update the position like normal, this should give you the same result. For example:


delta = ip - previousPos_; // ip (intersection point) and previousPos_ (previous intersection point) are in world coords
Vector4 deltaX = rPicked.GetWorldMatrix() * Vector4(delta, 0.f); // turn delta into the same world space as the object
delta = Vector3(deltaX) * basis[activeAxis_]; // remove components we aren't interested in, so if we want just X component of delta multiply by X basis

This topic is closed to new replies.

Advertisement