4

Currently I'm writing a plugin for my company and we want to offset some math operations on meshes to C# to gain some speed in calculations. I'm not only a C# beginner (I'm a Python / Maxscript guy) but I also struggle to find good SDK documentation for 3DS Max.

My current problem: obtaining the world-relative position of a vertex in a mesh. Sounds easy but it poses some problems for me. I can get the vert position by using:

IPoint3 x = mesh.GetVert(vertID);

and for vert 3 which is in [0,0,0] of the scene it returns a Point3 value of [-23,86499, 17,5783, 0], probably relative to... well, center of the object I think. Or some local transformation matrix. The thing I want to get is the position of the vert in world space, which in this case I know is [0,0,0], as well as I can probe it with MaxScript by using:

polyOp.getVert $ 3

The simple function I'm using to poke around is:

List<IINode> nodes = nodesFromHandles(objHandles);
foreach (IINode i in nodes)
{
    log(i.Name);
    IObjectState iState = i.EvalWorldState(0, true);
    IObject iObj = iState.Obj;
    IPolyObject iPoly = (IPolyObject)iObj.ConvertToType(0, global.PolyObjectClassID);
    ITriObject iTri = (ITriObject)iObj.ConvertToType(0, global.TriObjectClassID);
    IMesh mesh = iTri.Mesh;
    for (int vertID = 0; vertID < mesh.NumVerts; vertID++)
    {
        IPoint3 x = mesh.GetVert(vertID); /// RETURNS A BAD POSITION? RELATIVE TO WHAT MATRIX?
        log(vertID.ToString() + ": " + x.X.ToString() + ", " + x.Y.ToString() + ", " + x.Z.ToString());
    }
}

I guess I should probably do something with the object transform matrix, but I'm in the dark with that. Working on: 3ds Max 2014, MS visual Studio Community 2015 (C#), Win7x64, using Autodesk.Max.DLL. Any and all help appreciated, thank you in advance!

Expected vertex position.

EDIT: (solution?) Correct me if I'm wrong, but by doing some satanic rituals and sacrificing some of my teeth I've come up with this thing. I essentially grab the object world Transform Matrix at a given time (set to frame 0, because why not?) and then doing a point transform. Seems to work quite well for now, but I need to do more tests.

List<IINode> nodes = nodesFromHandles(objHandles);
foreach (IINode i in nodes)
{
    log(i.Name);
    IObjectState iState = i.EvalWorldState(0, true);
    IObject iObj = iState.Obj;
    ITriObject iTri = (ITriObject)iObj.ConvertToType(0, global.TriObjectClassID);
    IMesh mesh = iTri.Mesh;

    /// OBJECT TRANSFORM MATRIX
    IInterval iTimeRange = i.GetTimeRange(0);
    IMatrix3 worldTm = i.GetObjTMAfterWSM(0, iTimeRange);

    for (int vertID = 0; vertID < mesh.NumVerts; vertID++)
    {
        IPoint3 x = mesh.GetVert(vertID); /// RETURNS A BAD POSITION? RELATIVE TO WHAT MATRIX?
        IPoint3 v = worldTm.PointTransform(x);
        log(vertID.ToString() + ": " + v.X.ToString() + ", " + v.Y.ToString() + ", " + v.Z.ToString());
    }
}

If anybody can verify or improve this - your welcome. :)

bitworks
  • 90
  • 9

1 Answers1

0

Adding some explanations to your answer. The following line:

IPoint3 vertObjectSpace = mesh.GetVert(vertID);

Returns the vertex position in object space, which is unfortunately not mentioned in the docs. As you are interested in the positions in world space, you have to transform them using the following:

IMatrix3 tmObj2World= i.GetObjectTM(0, iTimeRange); // where i is your IINode
IPoint3 vertWorldSpace = tmObj2World.PointTransform(vertObjectSpace);

Hope that helps for your understanding.

Some notes / further reading:

tkazik
  • 919
  • 3
  • 12
  • 27