Notifications
Clear all

[Closed] Sub-object matrix transform woes

I am trying to figure out all the different matrix transformations that are needed to convert a 3D point in world space into a coordinate in modifier space, including all effects caused by scaled objects, transformed pivot points and funky modifier context transforms, but I am still struggling, I must admit.

Could someone please try to explain me once more what is the relationship between

a) node.transfrom
b) node.objectTransform
c) node.objectoffsetpos, node.objectoffsetrot, node.objectoffsetscale
d) getModContextTM()

and what the 3ds Max UI equivalent of modifying each transform is?
Which one of these is left-handed and which is right-handed?

Also I would like to understand why node.modifiers[#slice].slice_plane.transform is something different than what getModContextTM resturns?!

Attached is a small test scene for 3ds Max 2008. It contains two boxes, each with a slice modifier, and a point helper. The task is now to move/align the slice planes of the boxes with the pivot of the point helper. Ideally, the solution should work without using the setModContextTM function from avg_dlx, but merely by setting the slice_plane.transform matrix.

Thanks very much indeed for any insights!
– MartinB

6 Replies
 eek

ok. ( I might skip, i just got into work – so bear with me. Bobo adjust if im incorrect in places)

Basic’s

In max a transform consists of a 4 by 3 matrix, of 4 rows by 3 columns. Each row is a vector. (thxs for the fix Paul)

The first three vectors, are vectors in space from an origin and they dictate both the orientation and scale of the object. The last vector is the positional offset from the origin [0,0,0] also known as ‘position’.

These three vectors must be orthogonal, ie 90 degree perpendicular to each other, because scale is essentially the length between each vector and the origin also known as the unit length eg.

matrix [1,0,0] [0,1,0] [0,0,1] [0,0,0] – is the identity matrix of the object. Its scale is uniform and its position is at [0,0,0].

If it’s matrix is [2,0,0] [0,1,0] [0,0,1] [0,0,0] – it has a non-uniform scale of 2 along its x axis. And there for non-uniform. For it to be uniform – you would have to normalize each vector.

Matrix Transformations -(I warn you now, it took 5 years for me to finally get this.)

An object has a node Transformation and an object-offset Transformation.

The node transform is the pivot of the object, the object-offset transformation is the offset of the mesh in respect to the pivot about the world.

Max handles all objects like this: objectTransform = objectOffset transform * node Transform

E.g. if and object is at [0,0,0] and we move the pivot (the node transform), the object mesh is being transformed about the world, and needs the object-offset matrix offset added back.

(node.transform * inverse object-offset.transform) (this maybe off)

node.objectoffsetpos, node.objectoffsetrot, node.objectoffsetscale

This is the mesh offset position, rotation and scale in respect to the node transform.

Modifiers, verts etc

A mesh in subobject mode works in world space the verts of an object are in world space and need to relative to a space to get there position respectively. For example:

(a.verts[1].pos * inverse a.pos) this will get the transform space of vert[1] relative to a.

Transform Space

Matrix transforms are respective and communicative based on row and column order. Matrix multiplication and inverse are similiar to standard + – math. The rule being a matrix can only multiply against another matrix with the same rows as the first has columns. E.g:

|1 2 3 | * |1 2 3|
|4 5 3 |

This is incorrect as the first matrix has 3 columns 2 rows, but the second matrix only has 1 row.

|1 2 3| *|1|
|4 5 6| |2|
|3|
This is correct. As the first has the same columns as the second has rows. Multiplying these would result in:

|1 4 9|
|4 10 18|

Inverse space is similiar to + – math. For example 10 * inverse 20 = -10. Because we add 10 to -20 resulting in -10 as our transform space. Now when we add -10 to 20 we get 10. Matrix inversions have to be square (in most cases), with max i think it uses the first 3 vectors and leaves the fourth (position)

Btw, I myself are still learning inverse matrix math – which is a little complex. (right-sided identity method)

1 Reply
(@martinb)
Joined: 1 year ago

Posts: 0

Thanks a lot for your interest!

I understand the basics (I hope)
What I need are details on what each transform matrix does.

I am with you so far. I have been using this to get world/local positions of vertices, for example.

So, if node.transform describes the pivot in world space, what does objectOffset? It transforms from which coordinate system to which?

Yeah, but this does not apply directly to modifiers, right? After all, they have a modifier context that you can query with getModContextTM.

AFAIK, inversion needs to take row4 into account.

– MartinB

 PEN

Sorry I can’t jump in deep here as I’m in deep. First thing that I saw eek was the matrix explanation. In Max it is a 4×3, 4 rows, 3 columns. Hence $.transform.row4 returns the position. I’ll see If I can find time later to try and explain the rest.

 eek

It decribes the mesh offset itself.

I think i was slightly off before. The node transform is in respect to its parent, in this case the world. The object-offset is in world space. I.e if the object-offset.transform is at matrix3 [1,0,0] [0,1,0] [0,0,1] [0,0,0] the object itself will be at the node.transform. ( i think) – The mesh-offset is the difference needed for the pivot. So basically its back transforming.

Its tricky to explain this:

essentially if my pivot, goes one way my skin goes the other in respect to the world. Then i have to add my object-offset transformation back.

Im looking at this in terms of world-space and node-space – its why it might be confusing.

1 Reply
(@martinb)
Joined: 1 year ago

Posts: 0

AFAIK, node.transform is always in world coordinates. At least if you type $.transform and then link the object to some other object and run that command again, the values will not change.

– MartinB

I’m late but…

inverse is like dividing the matrix M * 1/M but not like numbers ie: 5 * 1/5 = 5/5

here goes my explanation:
if you create and object at [40,40,40], will be easier to understand

$.pivot
[40,40,40]
$.pos
[40,40,40]

$.pivot = [50,0,0] –we move the pivot – world coordinates
[50,0,0]

$.pos – world coordinates
[50,0,0]

$.ObjectTransform.pos –The object pos in world coordinates
[40,40,40]

$.ObjectoffsetPos – the object pos relative to the node
[-10,40,40]

$.ObjectoffsetPos + $.transform.pos
[40,40,40]

everything is relative, the object to the node, the node to it’s parent, and modifiers gizmos are relative to the object itself