Example #1
0
Matrix3 FormationBhvr::GetFollowerMatrix(TimeValue t,int which)
{
	//we are using 4 Point3's to represent the matrix..
	Point3 point;
	Matrix3 matrix;
	
	pblock->GetValue(follower_matrix1,	0,point,FOREVER,which);
	matrix.SetRow(0,point);
	
	pblock->GetValue(follower_matrix2,	0,point,FOREVER,which);
	matrix.SetRow(1,point);

	
	pblock->GetValue(follower_matrix3,	0,point,FOREVER,which);
	matrix.SetRow(2,point);
	
	pblock->GetValue(follower_matrix4,	0,point,FOREVER,which);
	matrix.SetRow(3,point);

	matrix.ValidateFlags();
	return matrix;

	//Note that when this code was written that the Matrix3 paramblock
	//parameter wasn't working correctly in R4 at the time this was written.
	/*
    if(which<0||which>=GetFollowerCount(t))
		return NULL;

	Matrix3 mat;
	pblock->GetValue(follower_matrix,t,mat,FOREVER,which);
	return mat;
	*/
}
Example #2
0
static void UnwrapMatrixFromNormal(Point3& normal, Matrix3& mat)
	{
	Point3 vx;
	vx.z = .0f;
	vx.x = -normal.y;
	vx.y = normal.x;	
	if ( vx.x == .0f && vx.y == .0f ) {
		vx.x = 1.0f;
		}
	mat.SetRow(0,vx);
	mat.SetRow(1,normal^vx);
	mat.SetRow(2,normal);
	mat.SetTrans(Point3(0,0,0));
	mat.NoScale();
	}
Example #3
0
Void SoftBody::_UpdatePose()
{
    if ( !(m_hPose.bIsFrame) )
        return;

    // Update COM
    m_hPose.vCenterOfMass = _ComputeCenterOfMass();

    // Update Rotation & Scaling
    const Node * pNode;
    UInt iNodeIndex;

    Vector3 vTmpRow, vWeigthedDelta;
    Matrix3 matRotScale;
    matRotScale.MakeNull();
    matRotScale.m00 = SCALAR_EPSILON;
    matRotScale.m11 = SCALAR_EPSILON * 2.0f;
    matRotScale.m22 = SCALAR_EPSILON * 3.0f;

    EnumNodes();
    pNode = EnumNextNode();
    while( pNode != NULL ) {
        iNodeIndex = pNode->GetIndex();
        const Vector3 & vDelta = m_hPose.arrDeltas[iNodeIndex];
        vWeigthedDelta = ( (pNode->Position - m_hPose.vCenterOfMass) * m_hPose.arrWeights[iNodeIndex] );
        matRotScale.GetRow( vTmpRow, 0 );
        matRotScale.SetRow( 0, vTmpRow + (vDelta * vWeigthedDelta.X) );
        matRotScale.GetRow( vTmpRow, 1 );
        matRotScale.SetRow( 1, vTmpRow + (vDelta * vWeigthedDelta.Y) );
        matRotScale.GetRow( vTmpRow, 2 );
        matRotScale.SetRow( 2, vTmpRow + (vDelta * vWeigthedDelta.Z) );
        pNode = EnumNextNode();
    }

    Matrix3 matRot, matScale;
    matRotScale.PolarDecomposition( matRot, matScale );

    m_hPose.matRotation = matRot;
    m_hPose.matScaling = ( m_hPose.matBaseScaling * matScale );
    if ( m_fMaxVolumeRatio > 1.0f ) {
        Scalar fInvDet = Clamp<Scalar>( MathFn->Invert( m_hPose.matScaling.Determinant() ),
                                        1.0f, m_fMaxVolumeRatio );
        m_hPose.matScaling *= fInvDet;
    }
}
Example #4
0
void
TrackMouseCallBack::draw_marker(ViewExp& vpt, Point3 p, Point3 norm)
{
return;   // sorry, this doesn't work yet - I'll post it later
	// set GW tm to orientation specified by norm and draw a circle
	Matrix3 tm;
	Point3 zdir, ydir, xdir;
	// compute the direction of the z axis to be.
	// the positive z axis points AWAY from the target.
	zdir = Normalize(norm);
	// compute direction of the X axis before roll.
	xdir = Normalize(CrossProd(zdir.x > 0 ? Point3(0, 0, 1) : Point3(0, 0, -1), zdir));
	// compute direction of the Y axis before roll.
	ydir = Normalize(CrossProd(zdir, xdir));
	tm.SetRow(0, xdir);
	tm.SetRow(1, ydir);
	tm.SetRow(2, zdir);

	vpt.getGW()->setTransform(tm);
	vpt.getGW()->setColor(LINE_COLOR, MARKER_COLOR);
	vpt.getGW()->marker(&p, CIRCLE_MRKR);
}
Example #5
0
void RemovePivotScale(INode* node)
{
	const TimeValue  t  = ccMaxWorld::MaxTime();
	Matrix3 nodeTM = node->GetNodeTM(t);

	Point3 pos = nodeTM.GetRow(3);
	Matrix3 objectTM = node->GetObjectTM(t);
	nodeTM = objectTM;
	nodeTM.SetRow(3, pos);
	Matrix3 pv = objectTM * Inverse(nodeTM);
	node->SetNodeTM(t, nodeTM);

	node->SetObjOffsetPos(pv.GetTrans()); 
	node->SetObjOffsetRot(IdentQuat()); 
	node->SetObjOffsetScale(ScaleValue(Point3(1,1,1))); 
}
//---------------------------------------------------------------------------
Matrix3 U2MaxSceneExport::UniformMatrix(Matrix3 orig_cur_mat)
{
	AffineParts   parts;  
	Matrix3       mat;   

	// Remove scaling from orig_cur_mat
	// 1) Decompose original and get decomposition info
	decomp_affine(orig_cur_mat, &parts); 

	// 2) construct 3x3 rotation from quaternion parts.q
	parts.q.MakeMatrix(mat);

	// 3) construct position row from translation parts.t  
	mat.SetRow(3, parts.t);

	return mat;
}
Example #7
0
void XsiExp::ExportNodeTM( INode * node, int indentLevel)
{
	// dump the full matrix
	Matrix3 matrix = node->GetNodeTM(GetStaticFrame());
	TSTR indent = GetIndent(indentLevel);
	
	fprintf(pStream,"%s\t%s {\n\n", indent.data(), "FrameTransformMatrix");

	Object * obj = node->EvalWorldState(0).obj;
  BOOL isBone = obj && obj->ClassID() == Class_ID(BONE_CLASS_ID, 0) ? TRUE : FALSE;

  if (node->GetParentNode() && node->GetParentNode()->IsRootNode())
  {
    // bone chains get grafted into the hierarchy tree
    //
	  if (!isBone)
    {
      // root mesh
      oTopMatrix = matrix;
      AffineParts ap;
      decomp_affine( matrix, &ap);
      topMatrix.Set( Point3( ap.k.x,0.0f,0.0f), Point3( 0.0f,ap.k.z,0.0f), Point3(0.0f,0.0f,ap.k.y), Point3(0,0,0));

      // root transform is controlled by the engine
      matrix.IdentityMatrix();
    }
  }
  else
  {
    matrix = matrix * Inverse(node->GetParentTM(GetStaticFrame()));
    if (!isBone)
    {
      matrix.SetRow( 3, topMatrix * matrix.GetRow(3));
    }
  }

  // write the matrix values
  DumpMatrix3( &matrix, indentLevel+2);

  // transform close brace
	fprintf(pStream,"%s\t}\n", indent.data());
}
//tm the mirror tm 
void CopyBuffer::PasteToBuffer(MorphByBone *mod, MorphByBoneData *targ, Matrix3 mirrorTM, float threshold, BOOL flipTM)
{
	if (copyData == NULL) return;
	if (copyData->morphTargets.Count() == 0) return;


	if (targ == NULL) return;

//delete any existing morphs
	for (int i = 0; i < targ->morphTargets.Count(); i++)
		delete targ->morphTargets[i];

	targ->morphTargets.ZeroCount();
	int realCount= 0;
	for (int i = 0; i < copyData->morphTargets.Count(); i++)
		{
		if (!copyData->morphTargets[i]->IsDead()) realCount++;
		}
	targ->morphTargets.SetCount(realCount);

	for (int i = 0; i < mod->localDataList.Count(); i++)
		{
		MorphByBoneLocalData *ld = mod->localDataList[i];
		if (ld)
			{
			ld->tempPoints = ld->preDeform;
			ld->tempMatchList.SetCount(ld->tempPoints.Count());
			for (int j = 0; j < ld->preDeform.Count(); j++)
				{
				Matrix3 tm(1);
				//need to put our original points
				ld->tempPoints[j] = ld->tempPoints[j] * mirrorTM;
				ld->tempMatchList[j] = -1;
				}
			}
		}
//now find closest pairs
	for (int i = 0; i < mod->localDataList.Count(); i++)
		{
		MorphByBoneLocalData *ld = mod->localDataList[i];
		if (ld)
			{			
			for (int j = 0; j < ld->tempPoints.Count(); j++)
				{
				Point3 sourcePoint = ld->preDeform[j];
				float closest = 3.4e+38;
				int closestID = -1;
				for (int k = 0; k < ld->tempPoints.Count(); k++)
					{
					Point3 mirrorPoint = ld->tempPoints[k];
					float dist = Length(sourcePoint-mirrorPoint);
					if ((dist < threshold) && (dist < closest))
						{
						closest = dist;
						closestID = k;
						}

					}
				if (closestID != -1)
					ld->tempMatchList[closestID] = j;
				}
			}
		}
//create a blank set of morphs
	int currentMorph = 0;
	for (int i = 0; i < copyData->morphTargets.Count(); i++)
		{
		if (!copyData->morphTargets[i]->IsDead())
			{
			targ->morphTargets[currentMorph] = new MorphTargets();
			int currentVert=0;
			for (int j = 0; j < mod->localDataList.Count(); j++)
				{
				targ->morphTargets[currentMorph]->d.SetCount(mod->localDataList[j]->preDeform.Count());
				for (int k =0; k < mod->localDataList[j]->preDeform.Count(); k++)
					{
					targ->morphTargets[currentMorph]->d[currentVert].vertexID = k;
					targ->morphTargets[currentMorph]->d[currentVert].vec = Point3(0.0f,0.0f,0.0f);
					targ->morphTargets[currentMorph]->d[currentVert].vecParentSpace = Point3(0.0f,0.0f,0.0f);
					targ->morphTargets[currentMorph]->d[currentVert].originalPt = mod->localDataList[j]->preDeform[k];//*tm;
					targ->morphTargets[currentMorph]->d[currentVert].localOwner = j;
					currentVert++;
					}
				}
			currentMorph++;
			}
		
		}
//this only works if it is not instanced
//loop through morphs
	currentMorph = 0;
	for (int i = 0; i < copyData->morphTargets.Count(); i++)
		{
		if (!copyData->morphTargets[i]->IsDead())
			{

		//loop through points
			for (int j = 0; j <targ->morphTargets[currentMorph]->d.Count(); j++)
				{

		//get the mirror index if there is one
				int ldIndex = targ->morphTargets[currentMorph]->d[j].localOwner;
				MorphByBoneLocalData *ld = mod->localDataList[ldIndex];

				Matrix3 boneTM = copyData->currentBoneNodeTM;
				Matrix3 parentTM = copyData->parentBoneNodeCurrentTM;
				Matrix3 mirror = Inverse(ld->selfNodeTM) * mirrorTM * ld->selfNodeTM;
				Matrix3 mirrorBoneTM = targ->currentBoneNodeTM;
				Matrix3 mirrorParentTM = targ->parentBoneNodeCurrentTM;

				Matrix3 lTM, pTM;
				lTM = boneTM * mirror * Inverse(mirrorBoneTM);
				pTM = parentTM * mirror * Inverse(mirrorParentTM);


				if (ld)
					{
					int  mirrorID = targ->morphTargets[currentMorph]->d[j].vertexID;
					int sourceID = ld->tempMatchList[mirrorID];
					//now look though our list and swap the 2
					if (sourceID != -1)
						{

	////transform the vec into local space, flip them, then back into bone space
	//					targ->morphTargets[i]->d[j].vec = VectorTransform(copyData->morphTargts[i]->d[sourceID].vec,mirrorTM);
						if (1)//(flipTM)
							{
							Point3 vec = copyData->morphTargets[i]->d[sourceID].vec; // in local bone space
							targ->morphTargets[currentMorph]->d[j].vec = VectorTransform(lTM,vec);

							vec = copyData->morphTargets[i]->d[sourceID].vecParentSpace; // in local bone space
							targ->morphTargets[currentMorph]->d[j].vecParentSpace = VectorTransform(pTM,vec);
							//current bone tm
							//current parent tm

							//invserse of the self
							//mirror
							//self tm

							//inverse of mirror bone
							//inverse of mirror parent bone

							}
						else 
							{
							targ->morphTargets[currentMorph]->d[j].vec = copyData->morphTargets[i]->d[sourceID].vec;
							targ->morphTargets[currentMorph]->d[j].vecParentSpace = copyData->morphTargets[i]->d[sourceID].vecParentSpace;
							}


//						Point3 pvec = copyData->morphTargets[i]->d[sourceID].vecParentSpace;

//						Matrix3 selfTM = ld->selfNodeTM;
//						Matrix3 parentTM = copyData->parentBoneNodeCurrentTM;
//						Matrix3 tm = parentTM * Inverse(selfTM) * mirrorTM * selfTM * Inverse(parentTM);

//						pvec = VectorTransform(tm,pvec);

						//do we need to flip the vecs?
						targ->morphTargets[currentMorph]->d[j].originalPt = copyData->morphTargets[i]->d[sourceID].originalPt * mirrorTM;

						}
					}
				}

	//resolve tms
			if (flipTM)
				{
				MorphByBoneLocalData *ld = mod->localDataList[0];
				Matrix3 mirror = Inverse(ld->selfNodeTM) * mirrorTM * ld->selfNodeTM;

		//mirror the initial copy node tm
				Matrix3 copyTM = copyData->currentBoneNodeTM;
				copyTM *= mirror;
				copyTM.SetRow(3,targ->currentBoneNodeTM.GetRow(3));

	//			targ->morphTargets[currentMorph]->boneTMInParentSpace = copyTM * ;


		//put our current targ node tm into the copyTM space
				Matrix3 targTM = targ->currentBoneNodeTM;
				targTM *= Inverse(copyTM);

		//put the morph tm in worldspace
				Matrix3 morphTM = copyData->morphTargets[i]->boneTMInParentSpace * copyData->parentBoneNodeCurrentTM;
		//mirror it
	//			morphTM *= mirror;
	//			morphTM.SetRow(3,targ->currentBoneNodeTM.GetRow(3));

		//now animate it back to world using the morph target tm
				targTM *= morphTM;
		//jam it back into our parent space
				targTM *= Inverse(targ->currentBoneNodeTM);

				targ->morphTargets[currentMorph]->boneTMInParentSpace = targTM;
				}
			else targ->morphTargets[currentMorph]->boneTMInParentSpace = copyData->morphTargets[i]->boneTMInParentSpace;


//puts it in world space
/*
			morphTM = copyData->morphTargets[i]->boneTMInParentSpace * copyData->parentBoneNodeCurrentTM;
			morphTM.SetRow(3,targ->currentBoneNodeTM.GetRow(3));
			morphTM = morphTM * mirror;
			morphTM = morphTM * Inverse(targ->parentBoneNodeCurrentTM);
			targ->morphTargets[currentMorph]->boneTMInParentSpace = morphTM;
*/


/*
	//mirror all the morph tms
			MorphByBoneLocalData *ld = mod->localDataList[0];
			Matrix3 mirror = Inverse(ld->selfNodeTM) * mirrorTM * ld->selfNodeTM;
			Matrix3 ptm = copyData->parentBoneNodeCurrentTM;
			Matrix3 mtm = copyData->morphTargets[i]->boneTMInParentSpace;
			Matrix3 morphWorldSpaceTM = mtm * ptm *mirror;
			morphWorldSpaceTM.SetRow(3,targ->currentBoneNodeTM.GetRow(3));
	

	//link the target bone initial to the mirrored initial copy node tm
			//remcompute the mirror tms
			//but pack into our targ space


			if (flipTM)
				{
				MorphByBoneLocalData *ld = mod->localDataList[0];

				Matrix3 mirror = Inverse(ld->selfNodeTM) * mirrorTM * ld->selfNodeTM;

				//transform the tm into local space
				//flip it thenback in parent space
				Matrix3 mtm = copyData->morphTargets[i]->boneTMInParentSpace;
				mtm = mtm * copyData->parentBoneNodeCurrentTM; //this puts in world space
				Point3 x,y,z;
				x = VectorTransform(mirror,mtm.GetRow(0));
				y = VectorTransform(mirror,mtm.GetRow(1));
				z = VectorTransform(mirror,mtm.GetRow(2));
				mtm.SetRow(0,x);
				mtm.SetRow(1,y);
				mtm.SetRow(2,z);
				mtm = mtm * Inverse(copyData->parentBoneNodeCurrentTM);
				mtm.SetRow(3,copyData->morphTargets[i]->boneTMInParentSpace.GetRow(3));
				//put in world space, then by the mirror then back into parent
				targ->morphTargets[currentMorph]->boneTMInParentSpace = copyData->morphTargets[i]->boneTMInParentSpace;
				}
			else targ->morphTargets[currentMorph]->boneTMInParentSpace = copyData->morphTargets[i]->boneTMInParentSpace;

  */
			targ->morphTargets[currentMorph]->influenceAngle = copyData->morphTargets[i]->influenceAngle;
			targ->morphTargets[currentMorph]->falloff = copyData->morphTargets[i]->falloff;

			targ->morphTargets[currentMorph]->name = copyData->morphTargets[i]->name;
			targ->morphTargets[currentMorph]->treeHWND = NULL;
			targ->morphTargets[currentMorph]->weight = copyData->morphTargets[i]->weight;
			targ->morphTargets[currentMorph]->flags = copyData->morphTargets[i]->flags;
			currentMorph++;
			}
		

		}



//clean up temp data
	for (int i = 0; i < mod->localDataList.Count(); i++)
		{
		MorphByBoneLocalData *ld = mod->localDataList[i];
		if (ld)
			{			
			ld->tempPoints.Resize(0);
			ld->tempMatchList.Resize(0);
			}
		}
}
Example #9
0
Void SoftBody::_SetupPose( Bool bIsVolume, Bool bIsFrame )
{
    const Node * pNode;
    UInt iNodeIndex;

    // Update links
    EnumLinks();
    Link * pLink = EnumNextLink();
    while( pLink != NULL ) {
        pLink->UpdateConstants();
        pLink = EnumNextLink();
    }

    // Compute total mass
    Scalar fTotalMass = _ComputeMass();
    Scalar fMassK = fTotalMass * 1000.0f * (Scalar)( GetNodeCount() );

    EnumNodes();
    pNode = EnumNextNode();
    while( pNode != NULL ) {
        if ( pNode->InvMass == 0.0f )
            fTotalMass += fMassK;
        pNode = EnumNextNode();
    }
    Scalar fInvTotalMass = MathFn->Invert( fTotalMass );

    // Flags
    m_hPose.bIsVolume = bIsVolume;
    m_hPose.bIsFrame = bIsFrame;

    // Weights
    m_hPose.arrWeights.Clear();

    EnumNodes();
    pNode = EnumNextNode();
    while( pNode != NULL ) {
        if ( pNode->InvMass > 0.0f )
            m_hPose.arrWeights.Push( pNode->Mass * fInvTotalMass );
        else
            m_hPose.arrWeights.Push( fMassK * fInvTotalMass );
        pNode = EnumNextNode();
    }

    // COM
    m_hPose.vCenterOfMass = _ComputeCenterOfMass();

    // Deltas
    m_hPose.arrDeltas.Clear();

    EnumNodes();
    pNode = EnumNextNode();
    while( pNode != NULL ) {
        m_hPose.arrDeltas.Push( pNode->Position - m_hPose.vCenterOfMass );
        pNode = EnumNextNode();
    }

    // Volume
    m_hPose.fVolume = ( (bIsVolume) ? _ComputeVolume() : 0.0f );

    // BaseScaling
    Matrix3 matBaseScaling;
    matBaseScaling.MakeNull();

    Vector3 vTmpRow;

    EnumNodes();
    pNode = EnumNextNode();
    while( pNode != NULL ) {
        iNodeIndex = pNode->GetIndex();
        const Vector3 & vDelta = m_hPose.arrDeltas[iNodeIndex];
        const Vector3 & vWeightedDelta = ( vDelta * m_hPose.arrWeights[iNodeIndex] );
        matBaseScaling.GetRow( vTmpRow, 0 );
        matBaseScaling.SetRow( 0, vTmpRow + (vDelta * vWeightedDelta.X) );
        matBaseScaling.GetRow( vTmpRow, 1 );
        matBaseScaling.SetRow( 1, vTmpRow + (vDelta * vWeightedDelta.Y) );
        matBaseScaling.GetRow( vTmpRow, 2 );
        matBaseScaling.SetRow( 2, vTmpRow + (vDelta * vWeightedDelta.Z) );
        pNode = EnumNextNode();
    }
    matBaseScaling.Invert( m_hPose.matBaseScaling );

    // Rotation & Scaling
    m_hPose.matRotation.MakeIdentity();
    m_hPose.matScaling.MakeIdentity();
}
Example #10
0
/*
  Use the shape of node to create Bullet shape for the actor. ActorNode is the main Max node.
*/
btCollisionShape* MxActor::createShape(NxActorDesc& actorDesc, ccMaxNode* node, ccMaxNode* actorNode)
{
	actorDesc.localPose.IdentityMatrix();

	btCollisionShape* shape = NULL;

	const TimeValue t = ccMaxWorld::MaxTime();
	Matrix3 nodePose = node->PhysicsNodePoseTM;

//	MaxMsgBox(NULL, _T("createShape"), _T("Error"), MB_OK);

	int geomType = MxUserPropUtils::GetUserPropInt(m_node, "GeometryType",1);
	NxShapeType type = node->ShapeType;

	//first apply manual overrides
	switch (geomType)
	{
	case 2:
		{
			type = NX_SHAPE_SPHERE;
			break;
		}
	case 3:
		{
			type = NX_SHAPE_BOX;
			break;
		}
	case 4:
		{
			type = NX_SHAPE_CAPSULE;
			break;
		}
	case 5:
		{
			type = NX_SHAPE_CONVEX;
			break;
		}
	case 6:
		{
			type = NX_SHAPE_MESH;
			break;
		}
	default:
		{
			
		}
	};

	actorDesc.localPose = node->PhysicsNodePoseTM * actorNode->PhysicsNodePoseTMInv;

	switch (type)
	{
	case NX_SHAPE_SPHERE:
		{
			btScalar radius = node->PrimaryShapePara.Radius;
			shape = new btSphereShape(radius);
			break;
		};
	case NX_SHAPE_BOX:
		{
			//adjust for difference in pivot points between 3ds max and Bullet (Bullet uses the box center)
			Matrix3 offset;
			offset.IdentityMatrix();
			offset.SetTrans(2,node->PrimaryShapePara.BoxDimension.z());

			actorDesc.localPose = actorDesc.localPose * offset;

			shape = new btBoxShape(node->PrimaryShapePara.BoxDimension.absolute());

			break;
		}
	case NX_SHAPE_CAPSULE:
		{

			char bla[1024];
			sprintf(bla,"capsule not properly supported yet, radius=%f,height=%f",node->PrimaryShapePara.Radius,node->PrimaryShapePara.Height);
			MaxMsgBox(NULL, _T(bla), _T("Error"), MB_OK);

			shape = new btCapsuleShape(node->PrimaryShapePara.Radius,node->PrimaryShapePara.Height);
			break;
		}

	case NX_SHAPE_CONVEX:
		{
			if(m_proxyNode)
			{
				MaxMsgBox(NULL, _T("Error: convex shape proxy not supported (yet)"), _T("Error"), MB_OK);
				//d->meshData = MxUtils::nodeToNxConvexMesh(proxyMesh);
				//Matrix3 pose = nodePose * actorNode->PhysicsNodePoseTMInv;
				//d->localPose = MxMathUtils::MaxMatrixToNx(pose);
			}
			else
			{
				if(node->SimpleMesh.numFaces > 255)
				{
					MaxMsgBox(NULL, _T("Error: number of vertices in a convex shape should be less than 256"), _T("Error"), MB_OK);
					//warning/Error
				} else
				{

					BOOL needDel = FALSE;
					TriObject* tri = MxUtils::GetTriObjectFromNode(node->GetMaxNode(),0.f,needDel);
					if (tri)
					{
						int numVerts = tri->NumPoints();
						btConvexHullShape* convexHull = new btConvexHullShape();
						
						//for center of mass computation, simplify and assume mass is at the vertices
						btCompoundShape* compound = new btCompoundShape();
						btSphereShape sphere(0.1);
						btTransform tr;
						tr.setIdentity();
						btAlignedObjectArray<btScalar> masses;
						btScalar childMass = actorDesc.mass/(btScalar)numVerts;


						for (int i=0;i<numVerts;i++)
						{
							btVector3 pt(tri->GetPoint(i).x,tri->GetPoint(i).y,tri->GetPoint(i).z);
							convexHull->addPoint(pt);
							tr.setOrigin(pt);
							compound->addChildShape(tr,&sphere);
							masses.push_back(childMass);
						}
						
						btTransform principal;
						btVector3 inertia;
						compound->calculatePrincipalAxisTransform(&masses[0],principal,inertia);

						
						delete compound;

						btTransform principalInv = principal.inverse();
						compound = new btCompoundShape();
						compound->addChildShape(principalInv,convexHull);
						shape = compound;

						Matrix3 offset;
						bullet2Max(principal,offset);
						actorDesc.localPose = actorDesc.localPose * offset;


						if (needDel)
							delete tri;
					}
					
					

				}
				//d->meshData = MxUtils::nodeToNxConvexMesh(node->SimpleMesh);
				//Matrix3 pose = nodePose * actorNode->PhysicsNodePoseTMInv;
				//d->localPose = MxMathUtils::MaxMatrixToNx(pose);
			}
			break;
		}
	case 	NX_SHAPE_MESH:
		{

			

			BOOL needDel = FALSE;
			TriObject* tri = MxUtils::GetTriObjectFromNode(node->GetMaxNode(),0.f,needDel);

			if (tri)
			{
				int numVerts = tri->NumPoints();
				btTriangleMesh* meshInterface = new btTriangleMesh();
				Mesh& mesh = tri->GetMesh();

				if (mesh.getNumFaces()>0)
				{
					for (int i=0;i<mesh.getNumFaces();i++)
					{
						Point3 p0=tri->GetPoint(mesh.faces[i].v[0]);
						Point3 p1=tri->GetPoint(mesh.faces[i].v[1]);
						Point3 p2=tri->GetPoint(mesh.faces[i].v[2]);

						meshInterface->addTriangle( btVector3(p0.x,p0.y,p0.z),btVector3(p1.x,p1.y,p1.z),btVector3(p2.x,p2.y,p2.z));
					}

					
					if (actorDesc.mass>0)
					{
//						MaxMsgBox(NULL, _T("btGImpactMeshShape"), _T("Error"), MB_OK);

						btGImpactMeshShape* trimesh = new btGImpactMeshShape(meshInterface);
						shape = trimesh;

					} else
					{

//						MaxMsgBox(NULL, _T("btBvhTriangleMeshShape"), _T("Error"), MB_OK);
						btBvhTriangleMeshShape* trimesh = new btBvhTriangleMeshShape(meshInterface,true);
						shape = trimesh;
					}
					
					
				} else
				{
					MaxMsgBox(NULL, _T("Error: no faces"), _T("Error"), MB_OK);
				}
				if (needDel)
					delete tri;
				
			} else
			{
				MaxMsgBox(NULL, _T("Error: couldn't GetTriObjectFromNode"), _T("Error"), MB_OK);
			}

			break;
		}

	default:
		{
			MaxMsgBox(NULL, _T("unknown shape type"), _T("Error"), MB_OK);
		}
	};


#if 0
	NxShapeDesc* pd = NULL;
	NxShapeType type = node->ShapeType;
	PxSimpleMesh proxyMesh;
	Matrix3 nodePose = node->PhysicsNodePoseTM;
	if(m_proxyNode)
	{
		// for proxy, using mesh
		//type = NX_SHAPE_MESH;
		proxyMesh.clone(node->SimpleMesh);
		Point3 pos = nodePose.GetRow(3);
		pos = pos + ProxyDistance;
		nodePose.SetRow(3, pos);
	}
	if((type == NX_SHAPE_MESH) && (Interactivity != RB_STATIC))
	{
		type = NX_SHAPE_CONVEX;
	}
	//
	/*
	bool NeedCCDSkeleton = (Interactivity != RB_STATIC) && (MxUserPropUtils::GetUserPropBool(node->GetMaxNode(), "EnableCCD", false));
	if(NeedCCDSkeleton) 
	{
		NxPhysicsSDK* psdk = gPluginData->getPhysicsSDK();
		psdk->setParameter(NX_CONTINUOUS_CD, 1);
		psdk->setParameter(NX_CCD_EPSILON, 0.01f);
	}
	*/


	// create CCD skeleton for the shape
	//TODO("implement CCD skeleton creation");
	PX_CCD_SKELETON ccdType = (PX_CCD_SKELETON) MxUserPropUtils::GetUserPropInt(node->GetMaxNode(), "px_shape_ccdtype", 1);
	switch(type)
	{
	
	default:
		if (gCurrentstream) gCurrentstream->printf("Unable to create a shape of node \"%s\", unknown shape type: %d.\n", node->GetMaxNode()->GetName(), type);
		return false;
	}
	// load property settings and material things.
	//LoadShapeProperties(*pd, node->GetMaxNode());
	//CCD flag

	pd->name = node->GetMaxNode()->GetName();
	pd->userData = node;
	//
	bool isvalid = pd->isValid();
	actorDesc.shapes.push_back(pd);
#endif

	return shape;
}
Example #11
0
void UnwrapMod::fnGizmoCenter()
{
	//get our tm
	//set the tm scale



	TimeValue t = GetCOREInterface()->GetTime();



	
	//get our selection
	Box3 bounds;
	bounds.Init();
	//get the bounding box
	Point3 pnorm(0.0f,0.0f,0.0f);
	int ct = 0;
	for (int ldID = 0; ldID < mMeshTopoData.Count(); ldID++)
	{
		MeshTopoData *ld = mMeshTopoData[ldID];
		Matrix3 tm = mMeshTopoData.GetNodeTM(t,ldID);

		for (int k = 0; k < ld->GetNumberFaces(); k++) 
		{
			if (ld->GetFaceSelected(k))
			{
				// Grap the three points, xformed
				int pcount = 3;
				//				if (gfaces[k].flags & FLAG_QUAD) pcount = 4;
				pcount = ld->GetFaceDegree(k);//gfaces[k]->count;

				Point3 temp_point[4];
				for (int j=0; j<pcount; j++) 
				{
					int index = ld->GetFaceGeomVert(k,j);//gfaces[k]->t[j];
					bounds += ld->GetGeomVert(index) * tm; //gverts.d[index].p * tm;
					if (j < 4)
						temp_point[j] = ld->GetGeomVert(index) * tm; //gverts.d[index].p;
				}
				pnorm += Normalize(temp_point[1]-temp_point[0]^temp_point[2]-temp_point[1]);
				ct++;
			}
		}	
	}


	if (ct == 0) return;

	theHold.Begin();
	SuspendAnimate();
	AnimateOff();
	pnorm = pnorm / (float) ct;//gfaces.Count();
	

	//if just a primary axis set the tm;
	Point3 center = bounds.Center();
	// build the scale



	//get our tm
	Matrix3 tm(1);
	tm = *fnGetGizmoTM();
	Matrix3 initialTM = tm;

	Point3 vec2;
	vec2 = Normalize(tm.GetRow(0)); 
	tm.SetRow(0,vec2);

	vec2 = Normalize(tm.GetRow(1)) ;
	tm.SetRow(1,vec2);

	vec2 = Normalize(tm.GetRow(2)); 
	tm.SetRow(2,vec2);

	tm.SetRow(3,center);


 	Matrix3 itm = Inverse(tm);
	//find our x and y scale
	Box3 localBounds;
	localBounds.Init();
	for (int ldID = 0; ldID < mMeshTopoData.Count(); ldID++)
	{
		MeshTopoData *ld = mMeshTopoData[ldID];
		Matrix3 tm = mMeshTopoData.GetNodeTM(t,ldID);

		for (int k = 0; k < ld->GetNumberFaces(); k++) 
		{
			if (ld->GetFaceSelected(k))
			{		// Grap the three points, xformed
				int pcount = 3;
				//				if (gfaces[k].flags & FLAG_QUAD) pcount = 4;
				pcount = ld->GetFaceDegree(k);//gfaces[k]->count;

				Point3 temp_point[4];
				for (int j=0; j<pcount; j++) 
				{
					int index = ld->GetFaceGeomVert(k,j);//gfaces[k]->t[j];
					Point3 p = ld->GetGeomVert(index) * tm * itm;//gverts.d[index].p * tm * itm;
					localBounds += p;

		//			if (fabs(p.x) > xmax) xmax = fabs(p.x);
		//			if (fabs(p.y) > ymax) ymax = fabs(p.y);
		//			if (fabs(p.z) > zmax) zmax = fabs(p.z);
				}
			}
		}
	}

	if ((fnGetMapMode() == PLANARMAP) || (fnGetMapMode() == PELTMAP))
		center = localBounds.Center() * tm;
	else if (fnGetMapMode() == CYLINDRICALMAP)
	{
		Point3 zvec = initialTM.GetRow(2);
		
//		center = center * tm;

		center = localBounds.Center() * tm - (zvec * 0.5f);
		

	}


	initialTM.SetRow(3,center);


	Matrix3 ptm(1), id(1);
	initialTM = initialTM ;
	SetXFormPacket tmpck(initialTM,ptm);
	tmControl->SetValue(t,&tmpck,TRUE,CTRL_RELATIVE);

	ResumeAnimate();

	if ((fnGetMapMode() == PLANARMAP) || (fnGetMapMode() == CYLINDRICALMAP) || (fnGetMapMode() == SPHERICALMAP) || (fnGetMapMode() == BOXMAP))
		ApplyGizmo();

	theHold.Accept(GetString(IDS_MAPPING_FIT));
	fnGetGizmoTM();
	if (ip) ip->RedrawViews(ip->GetTime());

}
Example #12
0
void UnwrapMod::fnAlignAndFit(int axis)
{



	//get our selection
	Box3 bounds;
	bounds.Init();
	//get the bounding box
	Point3 pnorm(0.0f,0.0f,0.0f);
	int ct = 0;
	TimeValue t = GetCOREInterface()->GetTime();
	for (int ldID = 0; ldID < mMeshTopoData.Count(); ldID++)
	{
		MeshTopoData *ld = mMeshTopoData[ldID];
		Matrix3 tm = mMeshTopoData.GetNodeTM(t,ldID);
		for (int k = 0; k < ld->GetNumberFaces(); k++) 
		{
			if (ld->GetFaceSelected(k))
			{
					// Grap the three points, xformed
				int pcount = 3;
					//				if (gfaces[k].flags & FLAG_QUAD) pcount = 4;
				pcount = ld->GetFaceDegree(k);//gfaces[k]->count;

				Point3 temp_point[4];
				for (int j=0; j<pcount; j++) 
				{
					int index = ld->GetFaceGeomVert(k,j);//gfaces[k]->t[j];
					bounds += ld->GetGeomVert(index) *tm;//gverts.d[index].p;
					if (j < 4)
						temp_point[j] = ld->GetGeomVert(index);//gverts.d[index].p;
				}
				pnorm += VectorTransform(Normalize(temp_point[1]-temp_point[0]^temp_point[2]-temp_point[1]),tm);
				ct++;
			}
		}	
	}

	if (ct == 0) return;

	theHold.Begin();
	SuspendAnimate();
	AnimateOff();

	pnorm = pnorm / (float) ct;
	Matrix3 tm(1);
	
	//if just a primary axis set the tm;
	Point3 center = bounds.Center();
		// build the scale
	Point3 scale(bounds.Width().x ,bounds.Width().y , bounds.Width().z);
	if (scale.x == 0.0f) scale.x = 1.0f;
	if (scale.y == 0.0f) scale.y = 1.0f;
 	if (scale.z == 0.0f) scale.z = 1.0f;
	
 	if (axis == 0) // x axi
	{

  		tm.SetRow(0,Point3(0.0f,-scale.y,0.0f));
		tm.SetRow(1,Point3(0.0f,0.0f,scale.z));
		tm.SetRow(2,Point3(scale.x,0.0f,0.0f));
		if ((fnGetMapMode() == PLANARMAP) || (fnGetMapMode() == PELTMAP)  || (fnGetMapMode() == SPHERICALMAP) || (fnGetMapMode() == BOXMAP))
			tm.SetRow(3,center);
		else if (fnGetMapMode() == CYLINDRICALMAP)
		{
			center.x = bounds.pmin.x;
			tm.SetRow(3,center);
		}		

		Matrix3 ptm(1), id(1);
		tm = tm ;
		SetXFormPacket tmpck(tm,ptm);
		tmControl->SetValue(t,&tmpck,TRUE,CTRL_RELATIVE);
	}
	else if (axis == 1) // y axi
	{
  		tm.SetRow(0,Point3(scale.x,0.0f,0.0f));
 		tm.SetRow(1,Point3(0.0f,0.0f,scale.z));
		tm.SetRow(2,Point3(0.0f,scale.y,0.0f));
		if ((fnGetMapMode() == PLANARMAP) || (fnGetMapMode() == PELTMAP)|| (fnGetMapMode() == SPHERICALMAP) || (fnGetMapMode() == BOXMAP))
			tm.SetRow(3,center);
		else if (fnGetMapMode() == CYLINDRICALMAP)
		{
			center.y = bounds.pmin.y;
			tm.SetRow(3,center);
		}
		

		Matrix3 ptm(1), id(1);
		tm = tm;
		SetXFormPacket tmpck(tm,ptm);
		tmControl->SetValue(t,&tmpck,TRUE,CTRL_RELATIVE);
	}
	else if (axis == 2) //z axi
	{
		tm.SetRow(0,Point3(scale.x,0.0f,0.0f));
		tm.SetRow(1,Point3(0.0f,scale.y,0.0f));
		tm.SetRow(2,Point3(0.0f,0.0f,scale.z));
		if ((fnGetMapMode() == PLANARMAP) || (fnGetMapMode() == PELTMAP)|| (fnGetMapMode() == SPHERICALMAP) || (fnGetMapMode() == BOXMAP))
			tm.SetRow(3,center);
		else if (fnGetMapMode() == CYLINDRICALMAP)
		{
			center.z = bounds.pmin.z;
			tm.SetRow(3,center);
		}
		

		Matrix3 ptm(1), id(1);
		tm = tm;
		SetXFormPacket tmpck(tm,ptm);
		tmControl->SetValue(t,&tmpck,TRUE,CTRL_RELATIVE);
	}
	else if (axis == 3) // normal
	{
		int numberOfSelectionGroups = 0;
		for (int ldID = 0; ldID < mMeshTopoData.Count(); ldID++)
		{
			MeshTopoData *ld = mMeshTopoData[ldID];
			if (ld->GetFaceSelection().NumberSet())
				numberOfSelectionGroups++;
		}
		if ((fnGetMapMode() == PLANARMAP) || (fnGetMapMode() == PELTMAP) || (numberOfSelectionGroups > 1))
		{
			//get our tm
			Matrix3 tm;
			UnwrapMatrixFromNormal(pnorm,tm);
 			Matrix3 itm = Inverse(tm);
			//find our x and y scale
			float xmax = 0.0f;
			float ymax = 0.0f;
			float zmax = 0.0f;
			Box3 localBounds;
			localBounds.Init();
			for (int ldID = 0; ldID < mMeshTopoData.Count(); ldID++)
			{
				MeshTopoData *ld = mMeshTopoData[ldID];
				Matrix3 tm = mMeshTopoData.GetNodeTM(t,ldID);
				for (int k = 0; k < ld->GetNumberFaces(); k++) 
				{
					if (ld->GetFaceSelected(k))
					{
							// Grap the three points, xformed
						int pcount = 3;
							//				if (gfaces[k].flags & FLAG_QUAD) pcount = 4;
						pcount = ld->GetFaceDegree(k);//gfaces[k]->count;

						Point3 temp_point[4];
						for (int j=0; j<pcount; j++) 
						{
							int index = ld->GetFaceGeomVert(k,j);//gfaces[k]->t[j];
							Point3 p = ld->GetGeomVert(index) * tm * itm;//gverts.d[index].p * itm;
							localBounds += p;
						}
					}
				}
			}

//			center = localBounds.Center();
			xmax = localBounds.pmax.x - localBounds.pmin.x;
			ymax = localBounds.pmax.y - localBounds.pmin.y;
			zmax = localBounds.pmax.z - localBounds.pmin.z;

			if (xmax < 0.001f)
				xmax = 1.0f;
			if (ymax < 0.001f)
				ymax = 1.0f;
			if (zmax < 0.001f)
				zmax = 1.0f;

			Point3 vec;
			vec = Normalize(tm.GetRow(0)) * xmax;
			tm.SetRow(0,vec);

			vec = Normalize(tm.GetRow(1)) * ymax;
			tm.SetRow(1,vec);

			vec = Normalize(tm.GetRow(2)) * zmax;
			tm.SetRow(2,vec);


			tm.SetRow(3,center);
			

			Matrix3 ptm(1), id(1);
			tm = tm ;
			SetXFormPacket tmpck(tm,ptm);
			tmControl->SetValue(t,&tmpck,TRUE,CTRL_RELATIVE);
		}		
		else if ((fnGetMapMode() == CYLINDRICALMAP) || (fnGetMapMode() == SPHERICALMAP)|| (fnGetMapMode() == BOXMAP))
		{

			for (int ldID = 0; ldID < mMeshTopoData.Count(); ldID++)
			{


				//get our first 2 rings
				Tab<int> openEdges;
				Tab<int> startRing;
				Tab<int> endRing;

				MeshTopoData *ld =  mMeshTopoData[ldID];

				//skip any local data that has no selections
				if (ld->GetFaceSelection().NumberSet() == 0)
					continue;

				Matrix3 nodeTM = mMeshTopoData.GetNodeTM(t,ldID);

				for (int i = 0; i < ld->GetNumberGeomEdges(); i++)//TVMaps.gePtrList.Count(); i++)
				{
					int numberSelectedFaces = 0;
					int ct = ld->GetGeomEdgeNumberOfConnectedFaces(i);//TVMaps.gePtrList[i]->faceList.Count();
					for (int j = 0; j < ct; j++)
					{
						int faceIndex = ld->GetGeomEdgeConnectedFace(i,j);//TVMaps.gePtrList[i]->faceList[j];
						if (ld->GetFaceSelected(faceIndex))//fsel[faceIndex])
							numberSelectedFaces++;
					}
					if (numberSelectedFaces == 1)
					{
						openEdges.Append(1,&i,1000);
						
					}
				}

				GetOpenEdges(ld,openEdges, startRing);
				GetOpenEdges(ld,openEdges, endRing);
				Point3 zVec = pnorm;

				Point3 centerS(0.0f,0.0f,0.0f), centerE;
				if ((startRing.Count() != 0) && (endRing.Count() != 0))
				{
					//get the center start
					Box3 BoundsS, BoundsE;
					BoundsS.Init();
					BoundsE.Init();

					//get the center end
					for (int i = 0; i < startRing.Count(); i++)
					{
						int eIndex = startRing[i];
						int a = ld->GetGeomEdgeVert(eIndex,0);//TVMaps.gePtrList[eIndex]->a;
						int b = ld->GetGeomEdgeVert(eIndex,1);//TVMaps.gePtrList[eIndex]->b;

						BoundsS += ld->GetGeomVert(a) * nodeTM;//TVMaps.geomPoints[a];
						BoundsS += ld->GetGeomVert(b) * nodeTM;//TVMaps.geomPoints[b];
					}


					for (int i = 0; i < endRing.Count(); i++)
					{
						int eIndex = endRing[i];
						int a = ld->GetGeomEdgeVert(eIndex,0);//TVMaps.gePtrList[eIndex]->a;
						int b = ld->GetGeomEdgeVert(eIndex,1);//TVMaps.gePtrList[eIndex]->b;

						BoundsE += ld->GetGeomVert(a) * nodeTM;//TVMaps.geomPoints[a];
						BoundsE += ld->GetGeomVert(b) * nodeTM;//TVMaps.geomPoints[b];
					}

					
					centerS = BoundsS.Center();
					centerE = BoundsE.Center();
					//create the vec
					zVec = centerE - centerS;

				}
				else if ((startRing.Count() != 0) && (endRing.Count() == 0))
				{
					//get the center start
					Box3 BoundsS;
					BoundsS.Init();
					

					//get the center end
					for (int i = 0; i < startRing.Count(); i++)
					{
						int eIndex = startRing[i];
						int a =  ld->GetGeomEdgeVert(eIndex,0);//TVMaps.gePtrList[eIndex]->a;
						int b =  ld->GetGeomEdgeVert(eIndex,1);//TVMaps.gePtrList[eIndex]->b;

						BoundsS += ld->GetGeomVert(a) * nodeTM;//TVMaps.geomPoints[a];
						BoundsS += ld->GetGeomVert(b) * nodeTM;//TVMaps.geomPoints[b];
					}

					centerS = BoundsS.Center();
					

					int farthestPoint= -1;
					Point3 fp;
					float farthestDist= 0.0f;
					for (int k=0; k < ld->GetNumberFaces(); k++) 
					{
						if (ld->GetFaceSelected(k))
						{
								// Grap the three points, xformed
							int pcount = 3;
								//				if (gfaces[k].flags & FLAG_QUAD) pcount = 4;
							pcount = ld->GetFaceDegree(k);//gfaces[k]->count;

							
							for (int j=0; j<pcount; j++) 
							{
								int index = ld->GetFaceGeomVert(k,j);//gfaces[k]->t[j];
								
								Point3 p = ld->GetGeomVert(index)* nodeTM;//gverts.d[index].p;
								float d = LengthSquared(p-centerS);
								if ((d > farthestDist) || (farthestPoint == -1))
								{
									farthestDist = d;
									farthestPoint = index;
									fp = p;
								}							
							}
						}
					}

					
					
					centerE = fp;
					//create the vec
					zVec = centerE - centerS;

				}
				else
				{
					zVec = Point3(0.0f,0.0f,1.0f);
				}


				//get our tm
				Matrix3 tm;
				UnwrapMatrixFromNormal(zVec,tm);
				tm.SetRow(3,centerS);
 				Matrix3 itm = Inverse(tm);
				//find our x and y scale
				float xmax = 0.0f;
				float ymax = 0.0f;
				float zmax = 0.0f;
				Box3 localBounds;
				localBounds.Init();
				for (int k = 0; k < ld->GetNumberFaces(); k++)//gfaces.Count(); k++) 
				{
					if (ld->GetFaceSelected(k))
					{
							// Grap the three points, xformed
						int pcount = 3;
							//				if (gfaces[k].flags & FLAG_QUAD) pcount = 4;
						pcount = ld->GetFaceDegree(k);//gfaces[k]->count;

						Point3 temp_point[4];
						for (int j=0; j<pcount; j++) 
						{
							int index = ld->GetFaceGeomVert(k,j);//gfaces[k]->t[j];
							Point3 p = ld->GetGeomVert(index) * nodeTM * itm;//gverts.d[index].p * itm;
							localBounds += p;
						}
					}
				}

				center = localBounds.Center() * tm;

				if (fnGetMapMode() == CYLINDRICALMAP)
				{
					if ((startRing.Count() == 0) && (endRing.Count() == 0))
					{
						centerS = center;
						centerS.z = localBounds.pmin.z;					
					}
					else
					{

						centerS = centerS * itm;
						centerS.z = localBounds.pmin.z;
						centerS = centerS * tm;
					}
				}
				else if ((fnGetMapMode() == SPHERICALMAP) || (fnGetMapMode() == BOXMAP))
				{
					centerS = center;
				}

				Point3 bc = localBounds.Center();
				bc.z = localBounds.pmin.z;
				bc = bc * tm;

				xmax = localBounds.pmax.x - localBounds.pmin.x;
				ymax = localBounds.pmax.y - localBounds.pmin.y;
				zmax = localBounds.pmax.z - localBounds.pmin.z;

				Point3 vec;
				vec = Normalize(tm.GetRow(0)) * xmax;
				tm.SetRow(0,vec);

				vec = Normalize(tm.GetRow(1)) * ymax;
				tm.SetRow(1,vec);

				vec = Normalize(tm.GetRow(2)) * zmax;
				tm.SetRow(2,vec);


				
				tm.SetRow(3,centerS);
				

				Matrix3 ptm(1), id(1);
				tm = tm;
				SetXFormPacket tmpck(tm,ptm);
				tmControl->SetValue(t,&tmpck,TRUE,CTRL_RELATIVE);
			}
			
		}
	}
	ResumeAnimate();

	if ((fnGetMapMode() == PLANARMAP) || (fnGetMapMode() == CYLINDRICALMAP) || (fnGetMapMode() == SPHERICALMAP) || (fnGetMapMode() == BOXMAP))
		ApplyGizmo();

	theHold.Accept(GetString(IDS_MAPPING_ALIGN));

	fnGetGizmoTM();

	if (ip) ip->RedrawViews(ip->GetTime());

}
Example #13
0
void UnwrapMod::fnGizmoAlignToView()
{

	if (ip == NULL) return;

	ViewExp& vpt = ip->GetActiveViewExp();
	if (!vpt.IsAlive()) return;
 
	//get our tm
	//set the tm scale
	theHold.Begin();
	SuspendAnimate();
	AnimateOff();
	TimeValue t = GetCOREInterface()->GetTime();
	


	// Viewport tm
	Matrix3 vtm;
	vpt.GetAffineTM(vtm);
	vtm = Inverse(vtm);

	// Node tm
	Matrix3 ntm(1);// = nodeList[0]->GetObjectTM(ip->GetTime());

	Matrix3 destTM = vtm * Inverse(ntm);
	//get our tm
	
	
	Matrix3 initialTM = *fnGetGizmoTM();


	

	Point3 center = Normalize(initialTM.GetRow(3)); 
	initialTM.SetRow(3,center);

	for (int i = 0; i < 3; i++)
	{
		Point3 vec = destTM.GetRow(i);
		float l  = Length(initialTM.GetRow(i));
		vec = Normalize(vec) * l;
		initialTM.SetRow(i,vec);
	}



	initialTM.SetRow(3,center);


	Matrix3 ptm(1), id(1);
	initialTM = initialTM ;
	SetXFormPacket tmpck(initialTM,ptm);
	tmControl->SetValue(t,&tmpck,TRUE,CTRL_RELATIVE);

	ResumeAnimate();

	fnGizmoFit();

	if ((fnGetMapMode() == PLANARMAP) || (fnGetMapMode() == CYLINDRICALMAP)  || (fnGetMapMode() == SPHERICALMAP) || (fnGetMapMode() == BOXMAP))
		ApplyGizmo();

	theHold.Accept(GetString(IDS_MAPPING_ALIGNTOVIEW));
	fnGetGizmoTM();
	if (ip) ip->RedrawViews(ip->GetTime());

}
Example #14
0
void SGP_MaxInterface::GetTracks( int nNodeCount, INode** nodes, Track** tracks )
{
	StartProgressInfo(_M("Get node track..."));

	TimeValue nStartTick = GetStartTick();
	TimeValue nEndTick = GetEndTick();
	int nTickPerFrame = GetTickPerFrame();
	int nFrameCount = 0;

	for( TimeValue t = nStartTick; t <= nEndTick; t += nTickPerFrame )
		nFrameCount++;

	for( int i = 0; i < nNodeCount; i++ )
	{
		tracks[i]->vectorVisible.resize( nFrameCount );
		tracks[i]->vectorTrans.resize( nFrameCount );
		tracks[i]->vectorRot.resize( nFrameCount );
		tracks[i]->vectorScale.resize( nFrameCount );

		Matrix3 matrix = nodes[i]->GetObjTMAfterWSM ( 0 );
		bool bMirror = DotProd ( CrossProd ( matrix.GetRow ( 0 ), matrix.GetRow ( 1 ) ), matrix.GetRow ( 2 ) ) < 0.0 ? true : false;
		tracks[i]->bMirror = bMirror;
	}
	TimeValue t = nStartTick;
	for( int nFrameId = 0; nFrameId < nFrameCount; nFrameId++, t += nTickPerFrame )
	{
		SetProgressInfo( 100.0f*nFrameId/nFrameCount );

		for( int nNodeId = 0; nNodeId < nNodeCount; nNodeId++ )
		{
			INode* pNode = nodes[nNodeId];
			Track* pTrack = tracks[nNodeId];

			Matrix3 tm = pNode->GetNodeTM(t);

			// The coordinate system of 3DMax9 is Right-X Up-Z Screenin-Y
			// But coordinate system of SGP Engine is like D3D Right-X Up-Y Screenin-Z
			// Node Transform Matrix should be swaped.
			/*
			If your matrix looks like this:
			{ rx, ry, rz, 0 }  
			{ ux, uy, uz, 0 }  
			{ lx, ly, lz, 0 }  
			{ px, py, pz, 1 }
			To change it from left to right or right to left, flip it like this:
			{ rx, rz, ry, 0 }  
			{ lx, lz, ly, 0 }  
			{ ux, uz, uy, 0 }  
			{ px, pz, py, 1 }
			*/
			Point3 Row0 = tm.GetRow(0);
			Point3 Row1 = tm.GetRow(1);
			Point3 Row2 = tm.GetRow(2);
			Point3 Row3 = tm.GetRow(3);
			sgp::swapVariables( Row0.y,  Row0.z );
			sgp::swapVariables( Row1.x,  Row2.x );
			sgp::swapVariables( Row1.y,  Row2.z );
			sgp::swapVariables( Row1.z,  Row2.y );
			sgp::swapVariables( Row3.y,  Row3.z );
			tm.SetRow(0, Row0);
			tm.SetRow(1, Row1);
			tm.SetRow(2, Row2);
			tm.SetRow(3, Row3);


			Point3 trans;
			Quat quat;
			Point3 scale;

			{
				// calculate the translation component
				Point3 p;
				p = tm.GetTrans();

				trans.x = p.x;
				trans.y = p.y;
				trans.z = p.z;

				scale.x = tm.GetRow(0).Length();
				scale.y = tm.GetRow(1).Length();
				scale.z = tm.GetRow(2).Length();

				tm.NoScale();

				// calculate the rotation component
				Quat q(tm);
				if( tracks[nNodeId]->bMirror )
				{
					float m[4][3];
					memcpy( m, &tm, sizeof(float)*4*3 );

					m[0][0] *= -1;
					m[1][0] *= -1;
					m[2][0] *= -1;
	
					Matrix3 mm(m);

					Quat q0(mm);
					q = q0;
				}

				quat.x = q.x;
				quat.y = q.y;
				quat.z = q.z;
				quat.w = q.w;
			}


			pTrack->vectorTrans.getReference(nFrameId) = trans;
			pTrack->vectorRot.getReference(nFrameId) = quat;
			pTrack->vectorScale.getReference(nFrameId) = scale;

			float fv = pNode->GetVisibility( t );
			if( fv == 0 )
				pTrack->vectorVisible.getReference(nFrameId) = false;
			else
				pTrack->vectorVisible.getReference(nFrameId) = true;
		}
	}
	StopProgressInfo();
}
Example #15
0
void Import::ApplyModifiers (dScene& scene, const MaxNodeChache& maxNodeCache)
{
    dScene::Iterator iter (scene);
    for (iter.Begin(); iter; iter ++) {
        dScene::dTreeNode* meshNode = iter.GetNode();
        dNodeInfo* info = scene.GetInfoFromNode(meshNode);
        if (info->IsType(dGeometryNodeInfo::GetRttiType())) {
            dScene::dTreeNode* skinModifierNode = NULL;
            for (void* ptr = scene.GetFirstChild(meshNode); ptr; ptr = scene.GetNextChild(meshNode, ptr)) {
                dScene::dTreeNode* node = scene.GetNodeFromLink(ptr);
                dNodeInfo* info = scene.GetInfoFromNode(node);
                if (info->GetTypeId() == dGeometryNodeSkinModifierInfo::GetRttiType()) {
                    skinModifierNode = node;
                    break;
                }
            }

            if (skinModifierNode) {
                //create a skin modifier and add it
                Modifier* skinMod = (Modifier*) CreateInstance(OSM_CLASS_ID, SKIN_CLASSID);
                ISkinImportData* iskinImport = (ISkinImportData*) skinMod->GetInterface(I_SKINIMPORTDATA);
                INode* maxNode = maxNodeCache.Find(meshNode)->GetInfo();
                _ASSERTE (maxNode);

                IDerivedObject *derob = NULL;
                Object* obj = maxNode->GetObjectRef();
                if(obj->SuperClassID() != GEN_DERIVOB_CLASS_ID)
                {
                    derob = CreateDerivedObject(obj);
                    maxNode->SetObjectRef(derob);
                } else {
                    derob = (IDerivedObject*) obj;
                }
                derob->AddModifier(skinMod);

                dGeometryNodeSkinModifierInfo* skinModifier = (dGeometryNodeSkinModifierInfo*) scene.GetInfoFromNode(skinModifierNode);

                dMatrix matrix (skinModifier->m_shapeBindMatrix);
                Matrix3 bindPoseMatrix;
                bindPoseMatrix.SetRow (0, *((Point3*) &matrix[0]));
                bindPoseMatrix.SetRow (1, *((Point3*) &matrix[1]));
                bindPoseMatrix.SetRow (2, *((Point3*) &matrix[2]));
                bindPoseMatrix.SetRow (3, *((Point3*) &matrix[3]));
                iskinImport->SetSkinTm(maxNode, bindPoseMatrix, bindPoseMatrix);

                int maxNodeCount = 0;
                INode* maxNodes[1024];

                for (void* ptr = scene.GetFirstChild(skinModifierNode); ptr; ptr = scene.GetNextChild(skinModifierNode, ptr)) {
                    dScene::dTreeNode* boneNode = scene.GetNodeFromLink(ptr);
                    INode* skelBone = maxNodeCache.Find(boneNode)->GetInfo();
                    maxNodes[maxNodeCount] = skelBone;
                    maxNodeCount ++;
                    skelBone->SetBoneNodeOnOff(TRUE, 0);
                    skelBone->BoneAsLine(TRUE);
                    skelBone->ShowBone(1);
                    if (iskinImport->AddBoneEx(skelBone, TRUE)) {
                        dSceneNodeInfo* sceneNode = (dSceneNodeInfo*) scene.GetInfoFromNode(boneNode);
                        dMatrix matrix (sceneNode->GetTransform());
                        Matrix3 bindPoseMatrix;
                        bindPoseMatrix.SetRow (0, *((Point3*) &matrix[0]));
                        bindPoseMatrix.SetRow (1, *((Point3*) &matrix[1]));
                        bindPoseMatrix.SetRow (2, *((Point3*) &matrix[2]));
                        bindPoseMatrix.SetRow (3, *((Point3*) &matrix[3]));
                        iskinImport->SetBoneTm(skelBone, bindPoseMatrix, bindPoseMatrix);
                    }
                }

                // must evaluate the node after adding bones
                maxNode->EvalWorldState(0);

                for (int i = 0; i < skinModifier->m_vertexCount; i ++) {
                    Tab<float> weightList;
                    Tab<INode*> boneNodeList;
                    for (int j = 0; j < 4; j ++) {
                        if (skinModifier->m_vertexWeights[i][j] > 1.0e-5f) {
                            int boneIndex = skinModifier->m_boneWeightIndex[i].m_index[j];
                            INode *skelBone = maxNodes[boneIndex];
                            _ASSERTE (skelBone);
                            boneNodeList.Append (1, &skelBone);
                            weightList.Append (1, &skinModifier->m_vertexWeights[i][j]);
                        }
                    }
                    iskinImport->AddWeights(maxNode, i, boneNodeList, weightList);
                }
            }
        }
    }
}