Notifications
Clear all

[Closed] [SDK] Matrix problems INode vs Mesh

Matrix problems INode vs Mesh

I’m having a hard time understanding how to apply the same transformations I was applying to an INode to a Mesh

This is a follow question to what I asked on this thread Sdk attach mesh but I’m creating a new one in case some one else has a similar question.

I’m distributing a bunch of planes throughout a mesh, When placing regular planes they are correctly positioned and rotated but when I to do the same with a mesh which I converted from a plane it no longer works as expected.

This following code is if I use a INode and works fine.

// used so we can set the proper pivot later
Matrix3 tm = sceneNode->GetNodeTM(0); 

for (int n = 0; i < planes.size(); i++)
        {
            //........
            //........   Calculate the position of the new plane
            //........
            Point3 center = (planes[i]->pos);

            float planeSize = 1.0f;
            int planeWsegs = 1;
            int planeLsegs = 1;
            bool planeUV = true;

            INode* tmpPlane = createPlane(planeSize, planeSize, planeWsegs, planeLsegs, planeUV);

            TSTR name(_T("tmpPlane_"));
            ip->MakeNameUnique(name);
            tmpPlane->SetName(name);

            tm.SetTranslate(center);
            tmpPlane->SetNodeTM(TimeValue(0), tm);

            //// move the pivot
            float xOffset = planeSize - (planeSize / 2.0);
            tmpPlane->SetObjOffsetPos(Point3(0.0f, -xOffset, 0.0f));

            // Align to the direction vector
            Quat alignQ;
            Matrix3 alignRotation;
            alignRotation.IdentityMatrix();
            dirVec = planes[i]->dirVector;

            //align 
            alignRotation.SetRow(2, Normalize(dirVec));									
            alignRotation.SetRow(0, Point3(0, 1, 0) ^ alignRotation.GetRow(2));			
            alignRotation.SetRow(1, alignRotation.GetRow(2) ^ alignRotation.GetRow(0));	

            alignQ = Quat(alignRotation*tm);
            alignQ.MakeMatrix(alignRotation);

            tm *= alignRotation;
        
            /////////////////

            tm.SetTrans(center);
            tmpPlane->SetNodeTM(TimeValue(0), tm);                  
        }

Now when I try to use the mesh the planes are all in the wrong locations…

I create the Mesh plane with this.

// Create a plane and convert it to a Mesh
int planeWsegs = 1;
int planeLsegs = 1;
bool planeUV = true;
float planeSize = 1.0f;

// Create the default plane
SimpleObject2* planeObj = (SimpleObject2*)GetCOREInterface()->CreateInstance(GEOMOBJECT_CLASS_ID, PLANE_CLASS_ID);

IParamBlock2* pb = (IParamBlock2*)planeObj->GetReference(0);
if (pb)
{
	pb->SetValue(0, 0, planeSize);			//grid_length
	pb->SetValue(1, 0, planeSize);		//grid_width
	pb->SetValue(2, 0, planeWsegs);			//grid_wsegs
	pb->SetValue(3, 0, planeLsegs);			//grid_lsegs
	pb->SetValue(6, 0, planeUV);			//grid_genuvs					
}

// collapse it
Object *obj = planeObj->CollapseObject();

int t = 0;
TriObject *tri = NULL;

if (obj->CanConvertToType(Class_ID(POLYOBJ_CLASS_ID, 0)))
{
	PolyObject *pTri = (PolyObject *)obj->ConvertToType(t, Class_ID(POLYOBJ_CLASS_ID, 0));
	
	if (pTri->CanConvertToType(Class_ID(TRIOBJ_CLASS_ID, 0))) {
		
		tri = (TriObject *)pTri->ConvertToType(t, Class_ID(TRIOBJ_CLASS_ID, 0));
	}
}

Mesh& planeMesh = tri->GetMesh();

Mesh tempMesh;
tempMesh.DeepCopy(&tri->GetMesh(), GEOM_CHANNEL | TOPO_CHANNEL | TEXMAP_CHANNEL | MTL_CHANNEL | DISP_ATTRIB_CHANNEL | TM_CHANNEL);

The same loop as above but now with Meshes
just trying the position but even that is not working
I realize I most be doing something wrong I just don’t know what or how to do it right.

Matrix3 tm = sceneNode->GetNodeTM(0); 

for (int n = 0; i < planes.size(); i++)
        {
            //........
            //........   Calculate the position of the new plane
            //........
            Point3 center = (planes[i]->pos);

            Matrix3 tmpTM;
            tmpTM.IdentityMatrix();
            tmpTM.SetTrans(center);
            
            Mesh copyMesh = tri->GetMesh();

            // Move the new plane around
            for (int v = 0; v < copyMesh.numVerts; v++)
            {
                copyMesh.verts[v] = copyMesh.verts[v] * tmpTM;
            }

            CombineMeshes(planeMesh, tempMesh, copyMesh);
            copyMesh.InvalidateGeomCache();                 
        }

Any pointers really appreciate it.

Guillermo

1 Reply

Got it working.

In case anyone needs this.

            Mesh *copyMesh = new Mesh;
				copyMesh->DeepCopy(&planeMesh, GEOM_CHANNEL | TOPO_CHANNEL | TEXMAP_CHANNEL | MTL_CHANNEL | DISP_ATTRIB_CHANNEL | TM_CHANNEL);

				Matrix3 tmpTM;
				tmpTM = ScaleMatrix(Point3(1, 1, 1));
				tmpTM.RotateX(0.0f);
				tmpTM.RotateY(0.0f);
				tmpTM.RotateZ(0.0f);

				// Position
				tmpTM.SetTrans(center);

				CombineMeshes(planeMesh, *copyMesh, tempMesh , NULL ,&tmpTM, -1);