Esempio n. 1
0
bool XMLElement::SetMatrix3(const String& name, const Matrix3& value)
{
    return SetAttribute(name, value.ToString());
}
Esempio n. 2
0
int ScubaObjCreateCallBack::proc(ViewExp *vpt,int msg, int point, int flags, IPoint2 m, Matrix3& mat ) {

	if ( ! vpt || ! vpt->IsAlive() )
	{
		// why are we here
		DbgAssert(!_T("Invalid viewport!"));
		return FALSE;
	}

#ifdef _3D_CREATE
	DWORD snapdim = SNAP_IN_3D;
#else
	DWORD snapdim = SNAP_IN_PLANE;
#endif

#ifdef _OSNAP
	if (msg == MOUSE_FREEMOVE)
	{
		vpt->SnapPreview(m,m,NULL, snapdim);
	}
#endif

	if (msg==MOUSE_POINT||msg==MOUSE_MOVE) {
		switch(point) {
			case 0:
				ob->suspendSnap = TRUE;				
				sp0 = m;				
				p[0] = vpt->SnapPoint(m,m,NULL,snapdim);
				mat.SetTrans(p[0]); // Set Node's transform				
				ob->pblock->SetValue(PB_RADIUS,0,0.01f);
				ob->pblock->SetValue(PB_HEIGHT,0,0.01f);
				ob->increate=TRUE;
				break;
			case 1: 
				mat.IdentityMatrix();
				//mat.PreRotateZ(HALFPI);
				sp1 = m;							   
				p[1] = vpt->SnapPoint(m,m,NULL,snapdim);
				if (ob->dlgCreateMeth) {	
					// radius	
					r = Length(p[1]-p[0]);
					mat.SetTrans(p[0]);
				} else {
					// diameter
					Point3 center = (p[0]+p[1])/float(2);
					r = Length(center-p[0]);
					mat.SetTrans(center);  // Modify Node's transform
					}
				
				ob->pblock->SetValue(PB_RADIUS,0,r);
				ob->pblock->SetValue(PB_HEIGHT,0,2.0f*r);
				ob->pmapParam->Invalidate();

				if (flags&MOUSE_CTRL) {
					float ang = (float)atan2(p[1].y-p[0].y,p[1].x-p[0].x);
					mat.PreRotateZ(ob->ip->SnapAngle(ang));
					}

				if (msg==MOUSE_POINT) {
					if (Length(m-sp0)<3 ||
						Length(p[1]-p[0])<0.1f) {	
						ob->increate=FALSE;
						return CREATE_ABORT;
						} h=2.0f*r;
					}
				break;
			case 2:
				{
#ifdef _OSNAP
				float h1 = vpt->SnapLength(vpt->GetCPDisp(p[1],Point3(0,0,1),sp1,m,TRUE));
#else
				float h1 = vpt->SnapLength(vpt->GetCPDisp(p[1],Point3(0,0,1),sp1,m));
#endif
				float hmin=2.0f*r;
				h1+=(h1<0.0f?-hmin:hmin);
				ob->pblock->SetValue(PB_HEIGHT,0,h1);
				ob->pmapParam->Invalidate();
				if (msg==MOUSE_POINT) {					
					ob->suspendSnap = FALSE;
					ob->increate=FALSE;
					return (Length(m-sp0)<3)?CREATE_ABORT:CREATE_STOP;
					}
				}
				break; 
			}
		}
	else
	if (msg == MOUSE_ABORT) {	
		ob->increate=FALSE;		
		return CREATE_ABORT;
		}

	return TRUE;
	}
Esempio n. 3
0
/*
====================
Save
====================
*/
int G3DSExport::Save(const Str& path)
{	
	//////////////////////////////////////////////////////////////////////////
	// merge the skin
	//////////////////////////////////////////////////////////////////////////
	
	struct PRIMITIVE
	{
		Str name;
		Str texture;
		std::vector<INode*>bones;
		std::vector<Matrix3>transforms;
		std::vector<VPTNIW>vertexes;
		std::vector<unsigned int>indexes;
		Box3 box;
		int AddBone(const INode* node, const Matrix3& mat)
		{
			std::vector<INode*>::iterator it = std::find(bones.begin(), bones.end(), node);
			if(it==bones.end()) { bones.push_back((INode*)node); transforms.push_back(mat); return bones.size()-1; }
			return it - bones.begin();
		}
	};

	// get all of the textures
	std::vector<Str>textures;
	for(std::vector<SKIN>::iterator it = mSkins.begin(); it != mSkins.end(); ++it)
	{
		if(std::find(textures.begin(),textures.end(),it->texture) == textures.end())
		{
			textures.push_back(it->texture);
		}
	}

	// merge all of the skin to the primitive by the textures
	std::vector<PRIMITIVE>primitives;
	for(int i = 0; i < textures.size(); i++)
	{
		PRIMITIVE primitive;
		primitive.texture = textures[i];
		for(int j = 0; j < mSkins.size(); j++)
		{
			SKIN& skin = mSkins[j];
			if(skin.texture != primitive.texture) continue;
			if(primitive.name.size() == 0) primitive.name = skin.name;

			// get the start vertex
			int start_vertex = primitive.vertexes.size();

			// set all of the vertexes
			for(int k = 0; k < skin.vertexes.size(); k++ )
			{
				VPTNIS& v1 = skin.vertexes[k];
				VPTNIW v2;
				v2.position[0] = v1.pos.x;
				v2.position[1] = v1.pos.y;
				v2.position[2] = v1.pos.z;
				v2.texcoord[0] = v1.uv.x;
				v2.texcoord[1] = v1.uv.y;
				v2.normal[0] = v1.normal.x;
				v2.normal[1] = v1.normal.y;
				v2.normal[2] = v1.normal.z;
				v2.index[0] = primitive.AddBone(skin.bones[skin.weights[v1.index].index[2]], skin.transforms[skin.weights[v1.index].index[2]]);
				v2.index[1] = primitive.AddBone(skin.bones[skin.weights[v1.index].index[1]], skin.transforms[skin.weights[v1.index].index[1]]);
				v2.index[2] = primitive.AddBone(skin.bones[skin.weights[v1.index].index[0]], skin.transforms[skin.weights[v1.index].index[0]]);
				v2.weight[0] = skin.weights[v1.index].weight[2];
				v2.weight[1] = skin.weights[v1.index].weight[1];
				v2.weight[2] = skin.weights[v1.index].weight[0];
				primitive.vertexes.push_back(v2);
			}

			// set the index
			for(int k = 0; k < skin.triangles.size(); k++)
			{
				TRIANGLE& tri = skin.triangles[k];
				primitive.indexes.push_back(start_vertex + tri.index1[0]);
				primitive.indexes.push_back(start_vertex + tri.index1[1]);
				primitive.indexes.push_back(start_vertex + tri.index1[2]);
			}

			// set the box
			primitive.box += skin.box;
		}

		// there is a 75 bone limit for each skinned object.
		if(primitive.bones.size()>75) { G3DAssert("There are more %d bones in the primitive and the texture is %s.",primitive.bones.size(), textures[i].c_str()); return 1; }

		// add the primitive to the table
		primitives.push_back(primitive);
	}

	//////////////////////////////////////////////////////////////////////////
	// save the skin
	//////////////////////////////////////////////////////////////////////////
	
	// open the skin file to save it
	FILE *output = fopen(path.c_str(), "wb");
	if(output==NULL) { G3DAssert("Can`t open the file : %s.", path.c_str()); return 1; }

	// begin to write the skin	
	fprintf( output, "<skeletal_mesh>\n" );

	// write all of the primitives
	for(int i = 0; i < primitives.size(); i++)
	{
		PRIMITIVE& primitive = primitives[i];

		// begin to write the primitive
		fprintf(output, "<primitive type=\"PT_TRIANGLES\">\n");

		// wirte all of the vertexes
		fprintf(output, "<vertex format=\"VT_3F VT_2F VT_3F VT_3F VT_3F\">\n");
		for(int j = 0; j < primitive.vertexes.size(); j++)
		{
			VPTNIW& v =  primitive.vertexes[j];
			fprintf(output,	"%f %f %f %f %f %f %f %f %f %f %f %f %f %f\n",
				v.position[0], v.position[1], v.position[2], 
				v.texcoord[0], v.texcoord[1],
				v.normal[0], v.normal[1], v.normal[2], 
				v.index[0], v.index[1], v.index[2],
				v.weight[0], v.weight[1], v.weight[2]
				);
		}
		fprintf(output, "</vertex>\n");

		// wirte all of the indexes
		fprintf(output, "<index stride=\"%d\">\n", primitive.vertexes.size()<=0xFFFF ? sizeof(unsigned short) : sizeof(unsigned int));
		for(int j = 0; j < primitive.indexes.size(); j++ ) fprintf(output, "%u ", primitive.indexes[j]);
		fprintf( output, "</index>\n" );

		// wirte the bones
		for(int j = 0; j < primitive.bones.size(); j++)
		{
			Str node_name = primitive.bones[j]->GetName();			
			Matrix3 m = primitive.transforms[j];
			Point3 r0 = m.GetRow(0); Point3 r1 = m.GetRow(1); Point3 r2 = m.GetRow(2); Point3 r3 = m.GetRow(3);
			fprintf(output, "<bone name=\"%s\">\n", node_name.c_str());
			fprintf(output, "%f %f %f %f\n", r0.x, r0.y, r0.z, 0.0);
			fprintf(output, "%f %f %f %f\n", r1.x, r1.y, r1.z, 0.0);
			fprintf(output, "%f %f %f %f\n", r2.x, r2.y, r2.z, 0.0);
			fprintf(output, "%f %f %f %f\n", r3.x, r3.y, r3.z, 1.0);
			fprintf(output, "</bone>\n" );
		}

		// write the shader info
		fprintf(output, "<shader name=\"shader/skeletal.xml\">\n");
		fprintf(output, "<constant name=\"gVP\" type = \"CT_MATRIX\">\n 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 \n </constant>\n");
		fprintf(output, "<constant name=\"gWorld\" type = \"CT_MATRIX\">\n 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 \n </constant>\n");
		fprintf(output, "<constant name=\"gBones\" type = \"CT_VECTOR_ARRAY\">\n 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 \n </constant>\n");
		fprintf(output, "<constant name=\"gBaseTex\" type = \"CT_TEXTURE\">\n %s\n </constant>\n", primitive.texture.c_str());
		fprintf(output, "</shader>\n" );

		// write the primitive box
		fprintf( output, "<bounding_box>\n %f %f %f %f %f %f\n </bounding_box>\n", 
			primitive.box.Min().x, primitive.box.Min().y, primitive.box.Min().z, primitive.box.Max().x, primitive.box.Max().y, primitive.box.Max().z );

		// end to write the primitive 
		fprintf(output, "</primitive>\n");
	}

	// end to wirte the skin
	fprintf(output, "</skeletal_mesh>\n");

	// close file
	fclose(output);	

	return 1;
}
Esempio n. 4
0
void BombMod::ModifyObject(
		TimeValue t, ModContext &mc, ObjectState *os, INode *node)
	{	
	BombObject *bobj = GetWSMObject(t);

   if (bobj && nodeRef && (bobj->ClassID() == Class_ID(BOMB_OBJECT_CLASS_ID,0))) {
		assert(os->obj->IsSubClassOf(triObjectClassID));
		TriObject *triOb = (TriObject *)os->obj;
		Interval valid = FOREVER;

		if (os->GetTM()) {
			Matrix3 tm = *(os->GetTM());
			for (int i=0; i<triOb->GetMesh().getNumVerts(); i++) {
				triOb->GetMesh().verts[i] = triOb->GetMesh().verts[i] * tm;
				}			
			os->obj->UpdateValidity(GEOM_CHAN_NUM,os->tmValid());
			os->SetTM(NULL,FOREVER);
			}
		
		if (waitPostLoad) {
			valid.SetInstant(t);
			triOb->UpdateValidity(GEOM_CHAN_NUM,valid);
			triOb->UpdateValidity(TOPO_CHAN_NUM,valid);
			return;
			}		

		Matrix3 tm;		
		TimeValue det  = bobj->GetDetonation(t,valid);	
		float strength = bobj->GetStrength(t,valid) * STRENGTH_CONSTANT;
		float grav     = bobj->GetGravity(t,valid);		
		float chaos    = bobj->GetChaos(t,valid);
		float chaosBase = (float(1)-chaos/2);
		float rotSpeed = bobj->GetSpin(t,valid) * TWOPI/float(TIME_TICKSPERSEC);
		int minClust = bobj->GetMinFrag(t,valid), maxClust = bobj->GetMaxFrag(t,valid);
		if (minClust<1) minClust = 1;
		if (maxClust<1) maxClust = 1;
		int clustVar = maxClust-minClust+1;
		float falloff = bobj->GetFalloff(t,valid);
		int useFalloff = bobj->GetFalloffOn(t,valid);
		int seed = bobj->GetSeed(t,valid);		

		//tm = nodeRef->GetNodeTM(t,&valid);		
		tm = nodeRef->GetObjectTM(t,&valid);
		
		if (t<det) {
			valid.Set(TIME_NegInfinity,det-1);
			triOb->UpdateValidity(GEOM_CHAN_NUM,valid);
			triOb->UpdateValidity(TOPO_CHAN_NUM,valid);
			triOb->PointsWereChanged();		
			return;		
			}

		float dt = float(t-det);
		valid.SetInstant(t);

		int n0=0,n1=1,n2=2,nv;
		Point3 v, p0, p1, g(0.0f,0.0f,grav*GRAVITY_CONSTANT);
		Tab<Point3> l_newVerts ; 

		Face *f = triOb->GetMesh().faces;
		float dot;		

		Mesh &mesh = triOb->GetMesh();

		// First, segment the faces.
		srand((unsigned int)seed);		
		Tab<DWORD> vclust;
		Tab<DWORD> vmap;
		Tab<Point3> nverts;
		vclust.SetCount(mesh.getNumVerts());
		vmap.SetCount(mesh.getNumVerts());		
		int numClust = 0;

		if (minClust==1 && maxClust==1) {
			// Simple case... 1 face per cluster
			nv = triOb->GetMesh().getNumFaces() * 3;
			l_newVerts.SetCount(nv);
			vclust.SetCount(nv);
			for (int i=0; i<nv; i++) {
				vclust[i] = i/3;
				}
         for (int i=0,j=0; i<mesh.getNumFaces(); i++) {
				l_newVerts[j]   = mesh.verts[mesh.faces[i].v[0]];
				l_newVerts[j+1] = mesh.verts[mesh.faces[i].v[1]];
				l_newVerts[j+2] = mesh.verts[mesh.faces[i].v[2]];
				mesh.faces[i].v[0] = j;
				mesh.faces[i].v[1] = j+1;
				mesh.faces[i].v[2] = j+2;
				j += 3;
				}
			numClust = triOb->GetMesh().getNumFaces();
		} else {
			// More complex case... clusters are randomely sized
			for (int i=0; i<mesh.getNumVerts(); i++) {
				vclust[i] = UNDEFINED;
				vmap[i] = i;
				}
			int cnum = 0;
         for (int i=0; i<mesh.getNumFaces(); ) {
				int csize = int(Rand1()*float(clustVar)+float(minClust));
				if (i+csize>mesh.getNumFaces()) {
					csize = mesh.getNumFaces()-i;					
					}
				
				// Make sure each face in the cluster has at least 2 verts in common with another face.
				BOOL verified = FALSE;
				while (!verified) {
					verified = TRUE;
					if (csize<2) break;

					for (int j=0; j<csize; j++) {
						BOOL match = FALSE;
						for (int k=0; k<csize; k++) {
							if (k==j) continue;
							int common = 0;
							for (int i1=0; i1<3; i1++) {
								for (int i2=0; i2<3; i2++) {
									if (mesh.faces[i+j].v[i1]==
										mesh.faces[i+k].v[i2]) common++;
									}
								}
							if (common>=2) {
								match = TRUE;
								break;
								}
							}
						if (!match) {
							csize = j;
							verified = FALSE; // Have to check again
							break;
							}
						}
					}
				if (csize==0) csize = 1;

				// Clear the vert map
				for (int j=0; j<mesh.getNumVerts(); j++) vmap[j] = UNDEFINED;			

				// Go through the cluster and remap verts.
            for (int j=0;j<csize; j++) {
					for (int k=0; k<3; k++) {
						if (vclust[mesh.faces[i+j].v[k]]==UNDEFINED) {
							vclust[mesh.faces[i+j].v[k]] = cnum;
						} else
						if (vclust[mesh.faces[i+j].v[k]]!=(DWORD)cnum) {
							if (vmap[mesh.faces[i+j].v[k]]==UNDEFINED) {
								vclust.Append(1,(DWORD*)&cnum,50);
								nverts.Append(1,&mesh.verts[mesh.faces[i+j].v[k]],50);
								mesh.faces[i+j].v[k] =
									vmap[mesh.faces[i+j].v[k]] = 
										mesh.getNumVerts()+nverts.Count()-1;
							} else {
								mesh.faces[i+j].v[k] =
									vmap[mesh.faces[i+j].v[k]];
								}
							}
						}
					}
				
				cnum++;
				numClust++;
				i += csize;
				}

			nv = mesh.getNumVerts() + nverts.Count();
			l_newVerts.SetCount(nv);

         int i;
			for (i=0; i<mesh.getNumVerts(); i++) 
				l_newVerts[i] = mesh.verts[i];
			for (   ; i<mesh.getNumVerts()+nverts.Count(); i++) 
				l_newVerts[i] = nverts[i-mesh.getNumVerts()];

		}

		// Find the center of all clusters
		Tab<Point3> clustCent;
		Tab<DWORD> clustCounts;
		clustCent.SetCount(numClust);
		clustCounts.SetCount(numClust);
		for (int i=0; i<numClust; i++) {
			clustCent[i]   = Point3(0,0,0);
			clustCounts[i] = 0;
			}
      for (int i=0; i<nv; i++) {
			if (vclust[i]==UNDEFINED) continue;
			clustCent[vclust[i]] += l_newVerts[i];
			clustCounts[vclust[i]]++;
			}

		// Build transformations for all clusters
		Tab<Matrix3> mats;
		mats.SetCount(numClust);
		srand((unsigned int)seed);
      for (int i=0; i<numClust; i++) {
			if (clustCounts[i]) clustCent[i] /= float(clustCounts[i]);

			v   = clustCent[i] - tm.GetTrans();
			float u = 1.0f;
			if (useFalloff) {
				u = 1.0f - Length(v)/falloff;
				if (u<0.0f) u = 0.0f;
				}
			dot = DotProd(v,v);
			if (dot==0.0f) dot = 0.000001f;
			v  = v / dot * strength * u;
			v.x *= chaosBase + chaos * Rand1();
			v.y *= chaosBase + chaos * Rand1();
			v.z *= chaosBase + chaos * Rand1();
			p1 = v*dt + 0.5f*g*dt*dt; // projectile motion

			// Set rotation
			Point3 axis;
			axis.x = -1.0f + 2.0f*Rand1();
			axis.y = -1.0f + 2.0f*Rand1();
			axis.z = -1.0f + 2.0f*Rand1();
			axis = Normalize(axis);
			float angle = dt*rotSpeed*(chaosBase + chaos * Rand1())*u;
			Quat q = QFromAngAxis(angle, axis);
			q.MakeMatrix(mats[i]);
			
			mats[i].PreTranslate(-clustCent[i]);
			mats[i].Translate(clustCent[i]+p1);			
			}

		// Now transform the clusters
      for (int i=0; i<nv; i++) {
			if (vclust[i]==UNDEFINED) continue;
			l_newVerts[i] = l_newVerts[i] * mats[vclust[i]];
			}
			
		triOb->UpdateValidity(GEOM_CHAN_NUM,valid);
		triOb->UpdateValidity(TOPO_CHAN_NUM,valid);
		triOb->PointsWereChanged();		

		triOb->GetMesh().setNumVerts(nv,FALSE,TRUE);

		//assign the new vertices to the mesh
      for ( int i=0; i < nv; i++)
			triOb->GetMesh().setVert( i,l_newVerts[i]);
		}		 
	}
Esempio n. 5
0
void CopyMatrixToArray ( Matrix3& myMatrix, GLfloat a[9] )
{
	for(int i=0;i<9;++i)
		a[i] = myMatrix.getData(i);
}
Esempio n. 6
0
inline void right_cauchy_green_deformation_tensor(
        const Matrix3<T>& F, Matrix3<T>& C)
{
    C = F.transpose() * F;
}
Esempio n. 7
0
Mesh*
TriObject::GetRenderMesh(TimeValue t, INode *inode, View &view, BOOL& needDelete)
{
	if (mDisableDisplacement || !(view.flags & RENDER_MESH_DISPLACEMENT_MAP)) {
		needDelete = FALSE;
		return &mesh;
	}
	// need to check the mesh and see if any face has a matId the requires displacment mapping
	BOOL needDisp = FALSE;

	// Get the material
	Mtl* pMtl = inode ? inode->GetMtl() : NULL;

	if (pMtl) {
		// does the mesh as a whole need it
		if (pMtl->Requirements(mesh.mtlIndex)&MTLREQ_DISPLACEMAP)
			needDisp = TRUE;

		if (!needDisp) {
			for (int f = 0; f < mesh.numFaces; f++) {
				if (pMtl->Requirements(mesh.getFaceMtlIndex(f))&MTLREQ_DISPLACEMAP) {
					needDisp = TRUE;
					break;
				}
			}
		}

		if (needDisp) {
            if (mesh.getNumFaces() == 0)
                return &mesh;

			Matrix3 otm;
			if (inode)
				otm = inode->GetObjectTM(t);
			else
				otm.IdentityMatrix();
			GetGTessFunction();
			if (mSubDivideDisplacement && psGTessFunc) {
				// if we have a material that does displacement mapping and if we can do it
				Mesh *pMesh = new Mesh();
				needDelete = TRUE;
				(*psGTessFunc)((void *)&mesh, MAX_MESH, &otm, pMesh, NULL,
								&mDispApprox, &view, pMtl, FALSE, mSplitMesh);
				needDelete = TRUE;
				return pMesh;
			} else {
				Mesh *pMesh = new Mesh(mesh);
				needDelete = TRUE;

                BOOL hasUVs = pMesh->tvFace != NULL;
				pMesh->buildRenderNormals();

				// now displace the verts
				BitArray vertsSet;
				vertsSet.SetSize(pMesh->numVerts);

				for (int f = 0; f < pMesh->numFaces; f++) {
					Face *pFace = &pMesh->faces[f];
					TVFace *pTVFace = &pMesh->tvFace[f];
					int matid = pFace->getMatID();
					for (int v = 0; v < 3; v++) {
						int vidx = pFace->v[v];
						if (vertsSet[vidx])
							continue; // displace only once
						Point3 norm = pMesh->getNormal(vidx);
						norm.Normalize();
						Point3& vert = pMesh->getVert(vidx);

						UVVert uvvert;
                        if (hasUVs)
                            uvvert = pMesh->getTVert(pTVFace->t[v]);
                        else {
                            uvvert.x = 0.0;
                            uvvert.y = 0.0;
                        }

						pMesh->buildBoundingBox();
						Box3 bbox = pMesh->getBoundingBox();
						float dispScale = Length(bbox.pmax - bbox.pmin)/10.0f;

						float disp = GetDisp(pMtl, pMesh, f, pFace->getMatID(), vert, uvvert.x, uvvert.y, otm) * dispScale;
						vert += (norm * disp);
						vertsSet.Set(vidx);
					}
				}
				return pMesh;
			}
		}
	}

	needDelete = FALSE;
	return &mesh;
}
Esempio n. 8
0
    ErrorCode EvalSet::evaluate_reverse(EvalFcn eval, JacobianFcn jacob, InsideFcn inside_f,
                                        const double *posn, const double *verts, const int nverts, 
                                        const int ndim, const double iter_tol, const double inside_tol, 
                                        double *work, double *params, int *inside) {
        // TODO: should differentiate between epsilons used for
        // Newton Raphson iteration, and epsilons used for curved boundary geometry errors
        // right now, fix the tolerance used for NR
      const double error_tol_sqr = iter_tol*iter_tol;
      CartVect *cvparams = reinterpret_cast<CartVect*>(params);
      const CartVect *cvposn = reinterpret_cast<const CartVect*>(posn);

        // initialize to center of element
      *cvparams = CartVect(-.4);
  
      CartVect new_pos;
        // evaluate that first guess to get a new position
      ErrorCode rval = (*eval)(cvparams->array(), verts, ndim, 
                               3, // hardwire to num_tuples to 3 since the field is coords
                               work, new_pos.array());
      if (MB_SUCCESS != rval) return rval;
      
        // residual is diff between old and new pos; need to minimize that
      CartVect res = new_pos - *cvposn;
      Matrix3 J;
      int dum, *tmp_inside = (inside ? inside : &dum);

      int iters=0;
        // while |res| larger than tol
      while (res % res > error_tol_sqr) {
        if(++iters>10) {
            // if we haven't converged but we're outside, that's defined as success
          *tmp_inside = (*inside_f)(params, ndim, inside_tol);
          if (!(*tmp_inside)) return MB_SUCCESS;
          else return MB_FAILURE;
        }

          // get jacobian at current params
        rval = (*jacob)(cvparams->array(), verts, nverts, ndim, work, J[0]);
        double det = J.determinant();
        if (det < std::numeric_limits<double>::epsilon()) {
          *tmp_inside = (*inside_f)(params, ndim, inside_tol);
          if (!(*tmp_inside)) return MB_SUCCESS;
          else return MB_INDEX_OUT_OF_RANGE;
        }

          // new params tries to eliminate residual
        *cvparams -= J.inverse(1.0/det) * res;

          // get the new forward-evaluated position, and its difference from the target pt
        rval = (*eval)(params, verts, ndim, 
                       3, // hardwire to num_tuples to 3 since the field is coords
                       work, new_pos.array());
        if (MB_SUCCESS != rval) return rval;
        res = new_pos - *cvposn;
      }

      if (inside)
        *inside = (*inside_f)(params, ndim, inside_tol);

      return MB_SUCCESS;
    }// Map::evaluate_reverse()
bool PFOperatorSimpleSpeed::Proceed(IObject* pCont, 
									 PreciseTimeValue timeStart, 
									 PreciseTimeValue& timeEnd,
									 Object* pSystem,
									 INode* pNode,
									 INode* actionNode,
									 IPFIntegrator* integrator)
{
	// acquire all necessary channels, create additional if needed
	IParticleChannelNewR* chNew = GetParticleChannelNewRInterface(pCont);
	if(chNew == NULL) return false;
	IParticleChannelPTVR* chTime = GetParticleChannelTimeRInterface(pCont);
	if(chTime == NULL) return false;
	IParticleChannelAmountR* chAmount = GetParticleChannelAmountRInterface(pCont);
	if(chAmount == NULL) return false;
	// the position channel may not be present. For some option configurations it is okay
	IParticleChannelPoint3R* chPos = GetParticleChannelPositionRInterface(pCont);
	int iDir = _pblock()->GetInt(kSimpleSpeed_direction, timeStart);
	if ((chPos == NULL) && ((iDir == kSS_Icon_Center_Out) || (iDir == kSS_Icon_Arrow_Out)))
		return false;

	IChannelContainer* chCont;
	chCont = GetChannelContainerInterface(pCont);
	if (chCont == NULL) return false;

	// the channel of interest
	bool initSpeed = false;
	IParticleChannelPoint3W* chSpeed = (IParticleChannelPoint3W*)chCont->EnsureInterface(PARTICLECHANNELSPEEDW_INTERFACE,
																			ParticleChannelPoint3_Class_ID,
																			true, PARTICLECHANNELSPEEDR_INTERFACE,
																			PARTICLECHANNELSPEEDW_INTERFACE, true,
																			actionNode, (Object*)NULL, &initSpeed);
	IParticleChannelPoint3R* chSpeedR = GetParticleChannelSpeedRInterface(pCont);
	if ((chSpeed == NULL) || (chSpeedR == NULL)) return false;

	// there are no new particles
	if (chNew->IsAllOld()) return true;

	float fUPFScale = 1.0f/TIME_TICKSPERSEC; // conversion units per seconds to units per tick
	Point3 pt3SpeedVec;
	RandGenerator* prg = randLinker().GetRandGenerator(pCont);
	int iQuant = chAmount->Count();
	bool wasIgnoringEmitterTMChange = IsIgnoringEmitterTMChange();
	if (!wasIgnoringEmitterTMChange) SetIgnoreEmitterTMChange();
	for(int i = 0; i < iQuant; i++) {
		if(chNew->IsNew(i)) { // apply only to new particles
			TimeValue tv = chTime->GetValue(i).TimeValue();
			Matrix3 nodeTM = pNode->GetObjectTM(tv);
			float fSpeedParam = fUPFScale * GetPFFloat(pblock(), kSimpleSpeed_speed, tv);
			// change speed in user selected direction
			switch(iDir) {
				case kSS_Along_Icon_Arrow: {
						// icon arrow appears to be in the negative z direction
						pt3SpeedVec = -Normalize(nodeTM.GetRow(2));
					}
					break;
				case kSS_Icon_Center_Out: {
						Point3 pt3IconCenter = nodeTM.GetTrans();
						Point3 pt3PartPos = chPos->GetValue(i);
						pt3SpeedVec = Normalize(pt3PartPos - pt3IconCenter);
					}
					break;
				case kSS_Icon_Arrow_Out: {
						Point3 pt3PartPos = chPos->GetValue(i);
						Point3 pt3ArrowVec = nodeTM.GetRow(2);
						Point3 pt3Tmp = CrossProd(pt3PartPos - nodeTM.GetTrans(), pt3ArrowVec);
						pt3SpeedVec = Normalize(CrossProd(pt3ArrowVec, pt3Tmp));
					}
					break;
				case kSS_Rand_3D: {
						pt3SpeedVec = RandSphereSurface(prg);
					}
					break;
				case kSS_Rand_Horiz: {
						float fAng = TWOPI * prg->Rand01();
						// establish x, y coordinates of random angle, z component zero
						float x = cos(fAng); float y = sin(fAng); float z = 0.0f;
						pt3SpeedVec = Point3(x, y, z);
					}
					break;
				case kSS_Inherit_Prev: {
						if (initSpeed) 
							pt3SpeedVec = Point3::Origin;
						else
							pt3SpeedVec = Normalize(chSpeedR->GetValue(i));
					}
					break;
			}
			// account for reverse check box
			int iRev = _pblock()->GetInt(kSimpleSpeed_reverse, 0);
			float fDirMult = iRev > 0 ? -1.f : 1.f;
			// calculate variation
			float fVar = fUPFScale * GetPFFloat(pblock(), kSimpleSpeed_variation, tv);
			if(fVar > 0.f)
				fSpeedParam = fSpeedParam + fVar * prg->Rand11();
			pt3SpeedVec = fDirMult * fSpeedParam * pt3SpeedVec;
			// calculate divergence
			float fDiv = GetPFFloat(pblock(), kSimpleSpeed_divergence, tv);
			pt3SpeedVec = DivergeVectorRandom(pt3SpeedVec, prg, fDiv);

			chSpeed->SetValue(i, pt3SpeedVec);
		}
	}
	if (!wasIgnoringEmitterTMChange) ClearIgnoreEmitterTMChange();

	return true;
}
Esempio n. 10
0
bool AlembicCamera::Save(double time, bool bLastFrame)
{
    TimeValue ticks = GetTimeValueFromFrame(time);

    Object *obj = mMaxNode->EvalWorldState(ticks).obj;
    if (mNumSamples == 0) {
        bForever = CheckIfObjIsValidForever(obj, ticks);
    }
    else {
        bool bNewForever = CheckIfObjIsValidForever(obj, ticks);
        if (bForever && bNewForever != bForever) {
            ESS_LOG_INFO("bForever has changed");
        }
    }
    bForever = false;

    SaveMetaData(mMaxNode, this);

    // Set the xform sample
    Matrix3 wm = mMaxNode->GetObjTMAfterWSM(ticks);
    if (mJob) {
        Point3 worldMaxPoint = wm.GetTrans();
        Abc::V3f alembicWorldPoint = ConvertMaxPointToAlembicPoint(worldMaxPoint);
        mJob->GetArchiveBBox().extendBy(alembicWorldPoint);
    }

    // check if the camera is animated
    if (mNumSamples > 0) {
        if (bForever) {
            return true;
        }
    }

    // Return a pointer to a Camera given an INode or return false if the node
    // cannot be converted to a Camera

    CameraObject *cam = NULL;

    if (obj->CanConvertToType(Class_ID(SIMPLE_CAM_CLASS_ID, 0))) {
        cam = reinterpret_cast<CameraObject *>(
                  obj->ConvertToType(ticks, Class_ID(SIMPLE_CAM_CLASS_ID, 0)));
    }
    else if (obj->CanConvertToType(Class_ID(LOOKAT_CAM_CLASS_ID, 0))) {
        cam = reinterpret_cast<CameraObject *>(
                  obj->ConvertToType(ticks, Class_ID(LOOKAT_CAM_CLASS_ID, 0)));
    }
    else {
        return false;
    }

    CameraState cs;
    Interval valid = FOREVER;
    cam->EvalCameraState(ticks, valid, &cs);
    float tDist = cam->GetTDist(ticks);
    float ratio = GetCOREInterface()->GetRendImageAspect();
    float aperatureWidth =
        GetCOREInterface()->GetRendApertureWidth();  // this may differ from the
    // imported value
    // unfortunately
    float focalLength =
        (float)((aperatureWidth / 2.0) /
                tan(cs.fov / 2.0));  // alembic wants this one in millimeters
    aperatureWidth /= 10.0f;         // convert to centimeters

    IMultiPassCameraEffect *pCameraEffect = cam->GetIMultiPassCameraEffect();

    Interval interval = FOREVER;

    BOOL bUseTargetDistance = FALSE;
    const int TARGET_DISTANCE = 0;
    pCameraEffect->GetParamBlockByID(0)->GetValue(TARGET_DISTANCE, ticks,
            bUseTargetDistance, interval);
    float fFocalDepth = 0.0f;
    const int FOCAL_DEPTH = 1;
    pCameraEffect->GetParamBlockByID(0)->GetValue(FOCAL_DEPTH, ticks, fFocalDepth,
            interval);

    // store the camera data
    mCameraSample.setNearClippingPlane(cs.hither);
    mCameraSample.setFarClippingPlane(cs.yon);
    // mCameraSample.setLensSqueezeRatio(ratio);

    // should set to 1.0 according the article "Maya to Softimage: Camera
    // Interoperability"
    mCameraSample.setLensSqueezeRatio(1.0);

    mCameraSample.setFocalLength(focalLength);
    mCameraSample.setHorizontalAperture(aperatureWidth);
    mCameraSample.setVerticalAperture(aperatureWidth / ratio);
    if (bUseTargetDistance) {
        mCameraSample.setFocusDistance(tDist);
    }
    else {
        mCameraSample.setFocusDistance(fFocalDepth);
    }

    // save the samples
    mCameraSchema.set(mCameraSample);

    mNumSamples++;

    // Note that the CamObject should only be deleted if the pointer to it is not
    // equal to the object pointer that called ConvertToType()
    if (cam != NULL && obj != cam) {
        delete cam;
        cam = NULL;
        return false;
    }

    return true;
}
Esempio n. 11
0
void perfMatrix3() {
    printf("Matrix3:\n");
    uint64 raw, opt, overhead, naive;

    // 0.5 million operations
    int n = 1024 * 1024 / 2;

    // Use two copies to avoid nice cache behavior
    Matrix3 A = Matrix3::fromAxisAngle(Vector3(1, 2, 1), 1.2f);
    Matrix3 B = Matrix3::fromAxisAngle(Vector3(0, 1, -1), .2f);
    Matrix3 C = Matrix3::zero();

    Matrix3 D = Matrix3::fromAxisAngle(Vector3(1, 2, 1), 1.2f);
    Matrix3 E = Matrix3::fromAxisAngle(Vector3(0, 1, -1), .2f);
    Matrix3 F = Matrix3::zero();

    int i;
    System::beginCycleCount(overhead);
    for (i = n - 1; i >= 0; --i) {
    }
    System::endCycleCount(overhead);

    System::beginCycleCount(raw);
    for (i = n - 1; i >= 0; --i) {
        C = A.transpose();
        F = D.transpose();
        C = B.transpose();
    }
    System::endCycleCount(raw);

    System::beginCycleCount(opt);
    for (i = n - 1; i >= 0; --i) {
        Matrix3::transpose(A, C);
        Matrix3::transpose(D, F);
        Matrix3::transpose(B, C);
    }
    System::endCycleCount(opt);

    raw -= overhead;
    opt -= overhead;

    printf(" Transpose Performance                       outcome\n");
    printf("     transpose(A, C): %g cycles/mul       %s\n\n", 
        (double)opt / (3*n), (opt/(3*n) < 400) ? " ok " : "FAIL");
    printf("   C = A.transpose(): %g cycles/mul       %s\n", 
        (double)raw / (3*n), (raw/(3*n) < 150) ? " ok " : "FAIL");
    printf("\n");
    /////////////////////////////////


    printf(" Matrix-Matrix Multiplication\n");
    System::beginCycleCount(raw);
    for (i = n - 1; i >= 0; --i) {
        C = A * B;
        F = D * E;
        C = A * D;
    }
    System::endCycleCount(raw);

    System::beginCycleCount(opt);
    for (i = n - 1; i >= 0; --i) {
        Matrix3::mul(A, B, C);
        Matrix3::mul(D, E, F);
        Matrix3::mul(A, D, C);
    }
    System::endCycleCount(opt);

    
    {
        float A[3][3], B[3][3], C[3][3], D[3][3], E[3][3], F[3][3];

        System::beginCycleCount(naive);
        for (i = n - 1; i >= 0; --i) {
            mul(A, B, C);
            mul(D, E, F);
            mul(A, D, C);
        }
        System::endCycleCount(naive);
    }

    raw -= overhead;
    opt -= overhead;
    
    printf("  mul(A, B, C)          %g cycles/mul     %s\n", (double)opt / (3*n), (opt/(3*n) < 250) ? " ok " : "FAIL");
    printf("     C = A * B          %g cycles/mul     %s\n", (double)raw / (3*n), (raw/(3*n) < 500) ? " ok " : "FAIL");
    printf("  naive for-loops       %g cycles/mul\n", (double)naive / (3*n));

    printf("\n\n");
}
Esempio n. 12
0
// Determine is the node has negative scaling.
// This is used for mirrored objects for example. They have a negative scale factor
// so when calculating the normal we should take the vertices counter clockwise.
// If we don't compensate for this the objects will be 'inverted'.
BOOL ElMaxPlugin::TMNegParity(Matrix3 &m)
{
	return (DotProd(CrossProd(m.GetRow(0), m.GetRow(1)), m.GetRow(2)) < 0.0f) ? 1 : 0;
}
Esempio n. 13
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();
}
Esempio n. 14
0
void NCLDebug::DrawMatrix(const Matrix3& mtx, const Vector3& position)
{
	DrawHairLine(position, position + mtx.GetCol(0), Vector4(1.0f, 0.0f, 0.0f, 1.0f));
	DrawHairLine(position, position + mtx.GetCol(1), Vector4(0.0f, 1.0f, 0.0f, 1.0f));
	DrawHairLine(position, position + mtx.GetCol(2), Vector4(0.0f, 0.0f, 1.0f, 1.0f));
}
void GridMapEditor::_duplicate_paste() {

	if (!selection.active)
		return;

	int idx = options->get_popup()->get_item_index(MENU_OPTION_DUPLICATE_SELECTS);
	bool reselect = options->get_popup()->is_item_checked( idx );



	List< __Item > items;

	Matrix3 rot;
	rot.set_orthogonal_index(selection.duplicate_rot);

	for(int i=selection.begin.x;i<=selection.end.x;i++) {

		for(int j=selection.begin.y;j<=selection.end.y;j++) {

			for(int k=selection.begin.z;k<=selection.end.z;k++) {

				int itm = node->get_cell_item(i,j,k);
				if (itm==GridMap::INVALID_CELL_ITEM)
					continue;
				int orientation = node->get_cell_item_orientation(i,j,k);
				__Item item;
				Vector3 rel=Vector3(i,j,k)-selection.begin;
				rel = rot.xform(rel);

				Matrix3 orm;
				orm.set_orthogonal_index(orientation);
				orm = rot * orm;

				item.pos=selection.begin+rel;
				item.item=itm;
				item.rot=orm.get_orthogonal_index();
				items.push_back(item);
			}

		}
	}

	Vector3 ofs=selection.current-selection.click;
	if (items.size()) {
		undo_redo->create_action("GridMap Duplicate Selection");
		for(List< __Item >::Element *E=items.front();E;E=E->next()) {
			__Item &it=E->get();
			Vector3 pos = it.pos+ofs;

			undo_redo->add_do_method(node,"set_cell_item",pos.x,pos.y,pos.z,it.item,it.rot);
			undo_redo->add_undo_method(node,"set_cell_item",pos.x,pos.y,pos.z,node->get_cell_item(pos.x,pos.y,pos.z),node->get_cell_item_orientation(pos.x,pos.y,pos.z));

		}
		undo_redo->commit_action();
	}


	if (reselect) {

		selection.begin+=ofs;
		selection.end+=ofs;
		selection.click=selection.begin;
		selection.current=selection.end;
		_validate_selection();
	}

}
Esempio n. 16
0
String ShaderCompilerGLES2::dump_node_code(SL::Node *p_node,int p_level,bool p_assign_left) {

	String code;

	switch(p_node->type) {

		case SL::Node::TYPE_PROGRAM: {

			SL::ProgramNode *pnode=(SL::ProgramNode*)p_node;

			code+=dump_node_code(pnode->body,p_level);
		} break;
		case SL::Node::TYPE_FUNCTION: {

		} break;
		case SL::Node::TYPE_BLOCK: {
			SL::BlockNode *bnode=(SL::BlockNode*)p_node;

			//variables
			for(Map<StringName,SL::DataType>::Element *E=bnode->variables.front();E;E=E->next()) {

				code+=_mktab(p_level)+_typestr(E->value())+" "+replace_string(E->key())+";"ENDL;
			}

			for(int i=0;i<bnode->statements.size();i++) {

				code+=_mktab(p_level)+dump_node_code(bnode->statements[i],p_level)+";"ENDL;
			}


		} break;
		case SL::Node::TYPE_VARIABLE: {
			SL::VariableNode *vnode=(SL::VariableNode*)p_node;
			if (type==ShaderLanguage::SHADER_MATERIAL_VERTEX) {

				if (vnode->name==vname_vertex && p_assign_left) {
					vertex_code_writes_vertex=true;
				}
			}
			if (type==ShaderLanguage::SHADER_MATERIAL_FRAGMENT) {

				if (vnode->name==vname_discard) {
					uses_discard=true;
				}
				if (vnode->name==vname_screen_uv) {
					uses_screen_uv=true;
				}
				if (vnode->name==vname_diffuse_alpha && p_assign_left) {
					uses_alpha=true;
				}
				if (vnode->name==vname_color_interp) {
					flags->use_color_interp=true;
				}
				if (vnode->name==vname_uv_interp) {
					flags->use_uv_interp=true;
				}
				if (vnode->name==vname_uv2_interp) {
					flags->use_uv2_interp=true;
				}
				if (vnode->name==vname_var1_interp) {
					flags->use_var1_interp=true;
				}
				if (vnode->name==vname_var2_interp) {
					flags->use_var2_interp=true;
				}
				if (vnode->name==vname_tangent_interp || vnode->name==vname_binormal_interp) {
					flags->use_tangent_interp=true;
				}

			}
			if (type==ShaderLanguage::SHADER_MATERIAL_LIGHT) {

				if (vnode->name==vname_light) {
					uses_light=true;
				}

			}

			code=replace_string(vnode->name);

		} break;
		case SL::Node::TYPE_CONSTANT: {
			SL::ConstantNode *cnode=(SL::ConstantNode*)p_node;
			switch(cnode->datatype) {


				case SL::TYPE_BOOL: code=cnode->value.operator bool()?"true":"false"; break;
				case SL::TYPE_FLOAT: code=_mknum(cnode->value); break; //force zeros, so GLSL doesn't confuse with integer.
				case SL::TYPE_VEC2: { Vector2 v = cnode->value; code="vec2("+_mknum(v.x)+", "+_mknum(v.y)+")"; } break;
				case SL::TYPE_VEC3: { Vector3 v = cnode->value; code="vec3("+_mknum(v.x)+", "+_mknum(v.y)+", "+_mknum(v.z)+")"; } break;
				case SL::TYPE_VEC4: { Plane v = cnode->value; code="vec4("+_mknum(v.normal.x)+", "+_mknum(v.normal.y)+", "+_mknum(v.normal.z)+", "+_mknum(v.d)+")"; } break;
				case SL::TYPE_MAT3: { Matrix3 x = cnode->value; code="mat3( vec3("+_mknum(x.get_axis(0).x)+", "+_mknum(x.get_axis(0).y)+", "+_mknum(x.get_axis(0).z)+"), vec3("+_mknum(x.get_axis(1).x)+", "+_mknum(x.get_axis(1).y)+", "+_mknum(x.get_axis(1).z)+"), vec3("+_mknum(x.get_axis(2).x)+", "+_mknum(x.get_axis(2).y)+", "+_mknum(x.get_axis(2).z)+"))"; } break;
				case SL::TYPE_MAT4: { Transform x = cnode->value; code="mat4( vec4("+_mknum(x.basis.get_axis(0).x)+", "+_mknum(x.basis.get_axis(0).y)+", "+_mknum(x.basis.get_axis(0).z)+",0.0), vec4("+_mknum(x.basis.get_axis(1).x)+", "+_mknum(x.basis.get_axis(1).y)+", "+_mknum(x.basis.get_axis(1).z)+",0.0), vec4("+_mknum(x.basis.get_axis(2).x)+", "+_mknum(x.basis.get_axis(2).y)+", "+_mknum(x.basis.get_axis(2).z)+",0.0), vec4("+_mknum(x.origin.x)+", "+_mknum(x.origin.y)+", "+_mknum(x.origin.z)+",1.0))"; } break;
				default: code="<error: "+Variant::get_type_name(cnode->value.get_type())+" ("+itos(cnode->datatype)+">";
			}

		} break;
		case SL::Node::TYPE_OPERATOR: {
			SL::OperatorNode *onode=(SL::OperatorNode*)p_node;


			switch(onode->op) {

				case SL::OP_ASSIGN_MUL: {


					if (onode->arguments[0]->get_datatype()==SL::TYPE_VEC3 && onode->arguments[1]->get_datatype()==SL::TYPE_MAT4) {

						String mul_l=dump_node_code(onode->arguments[0],p_level,true);
						String mul_r=dump_node_code(onode->arguments[1],p_level);
						code=mul_l+"=(vec4("+mul_l+",1.0)*("+mul_r+")).xyz";
						break;
					} else if (onode->arguments[0]->get_datatype()==SL::TYPE_MAT4 && onode->arguments[1]->get_datatype()==SL::TYPE_VEC3) {

						String mul_l=dump_node_code(onode->arguments[0],p_level,true);
						String mul_r=dump_node_code(onode->arguments[1],p_level);
						code=mul_l+"=(("+mul_l+")*vec4("+mul_r+",1.0)).xyz";
						break;
					} else if (onode->arguments[0]->get_datatype()==SL::TYPE_VEC2 && onode->arguments[1]->get_datatype()==SL::TYPE_MAT4) {

						String mul_l=dump_node_code(onode->arguments[0],p_level,true);
						String mul_r=dump_node_code(onode->arguments[1],p_level);
						code=mul_l+"=(vec4("+mul_l+",1.0,1.0)*("+mul_r+")).xy";
						break;
					} else if (onode->arguments[0]->get_datatype()==SL::TYPE_MAT4 && onode->arguments[1]->get_datatype()==SL::TYPE_VEC2) {

						String mul_l=dump_node_code(onode->arguments[0],p_level,true);
						String mul_r=dump_node_code(onode->arguments[1],p_level);
						code=mul_l+"=(("+mul_l+")*vec4("+mul_r+",1.0,1.0)).xy";
						break;
					} else if (onode->arguments[0]->get_datatype()==SL::TYPE_VEC2 && onode->arguments[1]->get_datatype()==SL::TYPE_MAT3) {
						String mul_l=dump_node_code(onode->arguments[0],p_level,true);
						String mul_r=dump_node_code(onode->arguments[1],p_level);
						code=mul_l+"=(("+mul_l+")*vec3("+mul_r+",1.0)).xy";
						break;
					}


				};
				case SL::OP_ASSIGN:
				case SL::OP_ASSIGN_ADD:
				case SL::OP_ASSIGN_SUB:
				case SL::OP_ASSIGN_DIV:
					code="("+dump_node_code(onode->arguments[0],p_level,true)+_opstr(onode->op)+dump_node_code(onode->arguments[1],p_level)+")";
					break;

				case SL::OP_MUL:

					if (onode->arguments[0]->get_datatype()==SL::TYPE_MAT4 && onode->arguments[1]->get_datatype()==SL::TYPE_VEC3) {

						code="("+dump_node_code(onode->arguments[0],p_level)+"*vec4("+dump_node_code(onode->arguments[1],p_level)+",1.0)).xyz";
						break;
					} else if (onode->arguments[0]->get_datatype()==SL::TYPE_VEC3 && onode->arguments[1]->get_datatype()==SL::TYPE_MAT4) {

						code="(vec4("+dump_node_code(onode->arguments[0],p_level)+",1.0)*"+dump_node_code(onode->arguments[1],p_level)+").xyz";
						break;
					} else if (onode->arguments[0]->get_datatype()==SL::TYPE_MAT4 && onode->arguments[1]->get_datatype()==SL::TYPE_VEC2) {

						code="("+dump_node_code(onode->arguments[0],p_level)+"*vec4("+dump_node_code(onode->arguments[1],p_level)+",1.0,1.0)).xyz";
						break;
					} else if (onode->arguments[0]->get_datatype()==SL::TYPE_VEC2 && onode->arguments[1]->get_datatype()==SL::TYPE_MAT4) {

						code="(vec4("+dump_node_code(onode->arguments[0],p_level)+",1.0,1.0)*"+dump_node_code(onode->arguments[1],p_level)+").xyz";
						break;
					} else if (onode->arguments[0]->get_datatype()==SL::TYPE_MAT3 && onode->arguments[1]->get_datatype()==SL::TYPE_VEC2) {

						code="("+dump_node_code(onode->arguments[0],p_level)+"*vec3("+dump_node_code(onode->arguments[1],p_level)+",1.0)).xy";
						break;
					} else if (onode->arguments[0]->get_datatype()==SL::TYPE_VEC2 && onode->arguments[1]->get_datatype()==SL::TYPE_MAT3) {

						code="(vec3("+dump_node_code(onode->arguments[0],p_level)+",1.0)*"+dump_node_code(onode->arguments[1],p_level)+").xy";
						break;
					}

				case SL::OP_ADD:
				case SL::OP_SUB:
				case SL::OP_DIV:
				case SL::OP_CMP_EQ:
				case SL::OP_CMP_NEQ:
				case SL::OP_CMP_LEQ:
				case SL::OP_CMP_GEQ:
				case SL::OP_CMP_LESS:
				case SL::OP_CMP_GREATER:
				case SL::OP_CMP_OR:
				case SL::OP_CMP_AND:
					//handle binary
					code="("+dump_node_code(onode->arguments[0],p_level)+_opstr(onode->op)+dump_node_code(onode->arguments[1],p_level)+")";
					break;
				case SL::OP_NEG:
				case SL::OP_NOT:
					//handle unary
					code=_opstr(onode->op)+dump_node_code(onode->arguments[0],p_level);
					break;
				case SL::OP_CONSTRUCT:
				case SL::OP_CALL: {
					String callfunc=dump_node_code(onode->arguments[0],p_level);


					code=callfunc+"(";
					/*if (callfunc=="mat4") {
						//fix constructor for mat4
						for(int i=1;i<onode->arguments.size();i++) {
							if (i>1)
								code+=", ";
								//transform
							code+="vec4( "+dump_node_code(onode->arguments[i],p_level)+(i==4?",1.0)":",0.0)");

						}
					} else*/ if (callfunc=="tex") {

						code="texture2D( "+dump_node_code(onode->arguments[1],p_level)+","+dump_node_code(onode->arguments[2],p_level)+")";
						break;
					} else if (callfunc=="texcube") {

						code="(textureCube( "+dump_node_code(onode->arguments[1],p_level)+",("+dump_node_code(onode->arguments[2],p_level)+")).xyz";
						break;
					} else if (callfunc=="texscreen") {
						//create the call to sample the screen, and clamp it
						uses_texscreen=true;
						code="(texture2D( texscreen_tex, min(("+dump_node_code(onode->arguments[1],p_level)+").xy*texscreen_screen_mult,texscreen_screen_mult))).rgb";
						//code="(texture2D( screen_texture, ("+dump_node_code(onode->arguments[1],p_level)+").xy).rgb";
						break;
					} else if (callfunc=="texpos") {
						//create the call to sample the screen, and clamp it
						uses_texpos=true;
						code="get_texpos("+dump_node_code(onode->arguments[1],p_level)+"";
//						code="get_texpos(gl_ProjectionMatrixInverse * texture2D( depth_texture, clamp(("+dump_node_code(onode->arguments[1],p_level)+").xy,vec2(0.0),vec2(1.0))*gl_LightSource[5].specular.zw+gl_LightSource[5].specular.xy)";
						//code="(texture2D( screen_texture, ("+dump_node_code(onode->arguments[1],p_level)+").xy).rgb";
						break;

					} else {

						for(int i=1;i<onode->arguments.size();i++) {
							if (i>1)
								code+=", ";
								//transform
							code+=dump_node_code(onode->arguments[i],p_level);

						}
					}
					code+=")";
					break;
				} break;
				default: {}
			}

		} break;
		case SL::Node::TYPE_CONTROL_FLOW: {
			SL::ControlFlowNode *cfnode=(SL::ControlFlowNode*)p_node;
			if (cfnode->flow_op==SL::FLOW_OP_IF) {

				code+="if ("+dump_node_code(cfnode->statements[0],p_level)+") {"ENDL;
				code+=dump_node_code(cfnode->statements[1],p_level+1);
				if (cfnode->statements.size()==3) {

					code+="} else {"ENDL;
					code+=dump_node_code(cfnode->statements[2],p_level+1);
				}

				code+="}"ENDL;

			} else if (cfnode->flow_op==SL::FLOW_OP_RETURN) {

				if (cfnode->statements.size()) {
					code="return "+dump_node_code(cfnode->statements[0],p_level);
				} else {
					code="return";
				}
			}

		} break;
		case SL::Node::TYPE_MEMBER: {
			SL::MemberNode *mnode=(SL::MemberNode*)p_node;
			String m;
			if (mnode->basetype==SL::TYPE_MAT4) {
				if (mnode->name=="x")
					m="[0]";
				else if (mnode->name=="y")
					m="[1]";
				else if (mnode->name=="z")
					m="[2]";
				else if (mnode->name=="w")
					m="[3]";

			} else if (mnode->basetype==SL::TYPE_MAT3) {
				if (mnode->name=="x")
					m="[0]";
				else if (mnode->name=="y")
					m="[1]";
				else if (mnode->name=="z")
					m="[2]";

			} else {
				m="."+mnode->name;
			}
			code=dump_node_code(mnode->owner,p_level)+m;

		} break;
	}

	return code;

}
void  GridMapEditor::_menu_option(int p_option) {


	switch(p_option) {

		case MENU_OPTION_CONFIGURE: {

			
		} break;
		case MENU_OPTION_LOCK_VIEW: {

			int index=options->get_popup()->get_item_index(MENU_OPTION_LOCK_VIEW);
			lock_view=!options->get_popup()->is_item_checked(index);

			options->get_popup()->set_item_checked(index,lock_view);
		} break;
		case MENU_OPTION_CLIP_DISABLED:
		case MENU_OPTION_CLIP_ABOVE:
		case MENU_OPTION_CLIP_BELOW: {

			clip_mode=ClipMode(p_option-MENU_OPTION_CLIP_DISABLED);
			for(int i=0;i<3;i++) {

				int index=options->get_popup()->get_item_index(MENU_OPTION_CLIP_DISABLED+i);
				options->get_popup()->set_item_checked(index,i==clip_mode);

			}

			_update_clip();
		} break;
		case MENU_OPTION_X_AXIS:
		case MENU_OPTION_Y_AXIS:
		case MENU_OPTION_Z_AXIS: {

			int new_axis = p_option-MENU_OPTION_X_AXIS;
			for(int i=0;i<3;i++) {
				int idx=options->get_popup()->get_item_index(MENU_OPTION_X_AXIS+i);
				options->get_popup()->set_item_checked(idx,i==new_axis);
			}
			edit_axis=Vector3::Axis(new_axis);
			update_grid();
			_update_clip();

		} break;
		case MENU_OPTION_CURSOR_ROTATE_Y: {
			Matrix3 r;
			if (input_action==INPUT_DUPLICATE) {

				r.set_orthogonal_index(selection.duplicate_rot);
				r.rotate(Vector3(0,1,0),Math_PI/2.0);
				selection.duplicate_rot=r.get_orthogonal_index();
				_update_duplicate_indicator();
				break;
			}
			r.set_orthogonal_index(cursor_rot);
			r.rotate(Vector3(0,1,0),Math_PI/2.0);
			cursor_rot=r.get_orthogonal_index();
			_update_cursor_transform();
		} break;
		case MENU_OPTION_CURSOR_ROTATE_X: {
			Matrix3 r;
			if (input_action==INPUT_DUPLICATE) {

				r.set_orthogonal_index(selection.duplicate_rot);
				r.rotate(Vector3(1,0,0),Math_PI/2.0);
				selection.duplicate_rot=r.get_orthogonal_index();
				_update_duplicate_indicator();
				break;
			}

			r.set_orthogonal_index(cursor_rot);
			r.rotate(Vector3(1,0,0),Math_PI/2.0);
			cursor_rot=r.get_orthogonal_index();
			_update_cursor_transform();
		} break;
		case MENU_OPTION_CURSOR_ROTATE_Z: {
			Matrix3 r;
			if (input_action==INPUT_DUPLICATE) {

				r.set_orthogonal_index(selection.duplicate_rot);
				r.rotate(Vector3(0,0,1),Math_PI/2.0);
				selection.duplicate_rot=r.get_orthogonal_index();
				_update_duplicate_indicator();
				break;
			}

			r.set_orthogonal_index(cursor_rot);
			r.rotate(Vector3(0,0,1),Math_PI/2.0);
			cursor_rot=r.get_orthogonal_index();
			_update_cursor_transform();
		} break;
		case MENU_OPTION_CURSOR_BACK_ROTATE_Y: {
			Matrix3 r;
			r.set_orthogonal_index(cursor_rot);
			r.rotate(Vector3(0,1,0),-Math_PI/2.0);
			cursor_rot=r.get_orthogonal_index();
			_update_cursor_transform();
		} break;
		case MENU_OPTION_CURSOR_BACK_ROTATE_X: {
			Matrix3 r;
			r.set_orthogonal_index(cursor_rot);
			r.rotate(Vector3(1,0,0),-Math_PI/2.0);
			cursor_rot=r.get_orthogonal_index();
			_update_cursor_transform();
		} break;
		case MENU_OPTION_CURSOR_BACK_ROTATE_Z: {
			Matrix3 r;
			r.set_orthogonal_index(cursor_rot);
			r.rotate(Vector3(0,0,1),-Math_PI/2.0);
			cursor_rot=r.get_orthogonal_index();
			_update_cursor_transform();
		} break;
		case MENU_OPTION_CURSOR_CLEAR_ROTATION: {

			if (input_action==INPUT_DUPLICATE) {


				selection.duplicate_rot=0;
				_update_duplicate_indicator();
				break;
			}

			cursor_rot=0;
			_update_cursor_transform();
		} break;


		case MENU_OPTION_DUPLICATE_SELECTS: {
			int idx = options->get_popup()->get_item_index(MENU_OPTION_DUPLICATE_SELECTS);
			options->get_popup()->set_item_checked( idx, !options->get_popup()->is_item_checked( idx ) );
		} break;
		case MENU_OPTION_SELECTION_MAKE_AREA:
		case MENU_OPTION_SELECTION_MAKE_EXTERIOR_CONNECTOR: {

			if (!selection.active)
				break;
			int area = node->get_unused_area_id();
			Error err = node->create_area(area,AABB(selection.begin,selection.end-selection.begin+Vector3(1,1,1)));
			if (err!=OK) {


			}
			if (p_option==MENU_OPTION_SELECTION_MAKE_EXTERIOR_CONNECTOR) {

				node->area_set_exterior_portal(area,true);
			}
			_update_areas_display();
			update_areas();


		} break;
		case MENU_OPTION_REMOVE_AREA: {
			if (selected_area<1)
				return;
			node->erase_area(selected_area);
			_update_areas_display();
			update_areas();
		} break;
		case MENU_OPTION_SELECTION_CLEAR: {
			if (!selection.active)
				return;

			_delete_selection();


		} break;


	}
}
Esempio n. 18
0
std::string LuxMaxUtils::getMaxNodeTransform(INode* node)
{
	LuxMaxUtils *lmutil;
	std::string tmpTrans = "";
	Matrix3 nodeTransformPos = node->GetObjTMAfterWSM(GetCOREInterface()->GetTime());
	Matrix3 nodeTransformRot = nodeTransformPos;
	Matrix3 nodeTransformScale = nodeTransformPos;

	nodeTransformRot.NoTrans();
	nodeTransformScale.NoTrans();
	nodeTransformScale.NoRot();

	nodeTransformRot = nodeTransformRot * nodeTransformScale;

	tmpTrans.append(floatToString(nodeTransformRot.GetColumn(0).x));
	tmpTrans.append(" ");
	tmpTrans.append(floatToString(nodeTransformRot.GetColumn(1).x));
	tmpTrans.append(" ");
	tmpTrans.append(floatToString(nodeTransformRot.GetColumn(2).x));
	tmpTrans.append(" ");
	tmpTrans.append("0 ");

	tmpTrans.append(floatToString(nodeTransformRot.GetColumn(0).y));
	tmpTrans.append(" ");
	tmpTrans.append(floatToString(nodeTransformRot.GetColumn(1).y));
	tmpTrans.append(" ");
	tmpTrans.append(floatToString(nodeTransformRot.GetColumn(2).y));
	tmpTrans.append(" ");
	tmpTrans.append("0 ");

	tmpTrans.append(floatToString(nodeTransformRot.GetColumn(0).z));
	tmpTrans.append(" ");
	tmpTrans.append(floatToString(nodeTransformRot.GetColumn(1).z));
	tmpTrans.append(" ");
	tmpTrans.append(floatToString(nodeTransformRot.GetColumn(2).z));
	tmpTrans.append(" ");
	tmpTrans.append("0 ");

	tmpTrans.append(floatToString(nodeTransformPos.GetTrans().x));
	tmpTrans.append(" ");
	tmpTrans.append(floatToString(nodeTransformPos.GetTrans().y));
	tmpTrans.append(" ");
	tmpTrans.append(floatToString(nodeTransformPos.GetTrans().z));
	tmpTrans.append(" 1.0");

	return tmpTrans;
}
bool PlasmaImport::IImportObject(plSceneObject *obj, ImpInterface *imp)
{
    if (!obj->getDrawInterface().isLoaded())
        return false;

    plDrawInterface* draw = plDrawInterface::Convert(obj->getDrawInterface()->getObj());
    plCoordinateInterface* coord = NULL;
    if (obj->getCoordInterface().Exists())
        coord = plCoordinateInterface::Convert(obj->getCoordInterface()->getObj());

    TriObject *maxObj = CreateNewTriObject();
    Mesh *msh = &maxObj->GetMesh();

    std::vector<Point3> vertexList;
    std::vector<int> indexList;

    if (!maxObj)
        return false;

    // read the object from PRP
    for (size_t i = 0; i < draw->getNumDrawables(); i++)
    {
        if (draw->getDrawableKey(i) == -1)
            continue;

        plDrawableSpans* span = plDrawableSpans::Convert(draw->getDrawable(i)->getObj());
        plDISpanIndex di = span->getDIIndex(draw->getDrawableKey(i));
        if ((di.fFlags & plDISpanIndex::kMatrixOnly) != 0)
            continue;

        for (size_t idx = 0; idx < di.fIndices.size(); idx++)
        {
            plIcicle* ice = (plIcicle*)span->getSpan(di.fIndices[idx]);
            std::vector<plGBufferVertex> verts = span->getVerts(ice);
            std::vector<unsigned short> indices = span->getIndices(ice);

            for (size_t j = 0; j < verts.size(); j++)
            {
                hsVector3 pos;
                if (coord != NULL)
                    pos = coord->getLocalToWorld().multPoint(verts[j].fPos) * 10.0f;
                else
                    pos = ice->getLocalToWorld().multPoint(verts[j].fPos) * 10.0f;
                vertexList.push_back(Point3(pos.X, pos.Y, pos.Z));
            }
            
            indexList.insert(indexList.end(), indices.begin(), indices.end());
        }
    }
    
    //create the Mesh
    msh->setNumVerts(vertexList.size());
    msh->setNumFaces(indexList.size()/3);
    for (size_t i = 0; i < vertexList.size(); i++)
        msh->setVert(i, vertexList[i]);

    for (size_t i = 0; i < indexList.size()/3; i++)
    {
        int v1, v2, v3;
        v1 = indexList[3*i];
        v2 = indexList[3*i+1];
        v3 = indexList[3*i+2];

        msh->faces[i].setVerts(v1, v2, v3);
        msh->faces[i].setEdgeVisFlags(1,1,1); //we asume we have Triangles obnly
    }

    msh->buildNormals();
    msh->buildBoundingBox();
    msh->InvalidateEdgeList();

    //Add Object To Scene
    ImpNode *node = imp->CreateNode();
    Matrix3 tm;
    tm.IdentityMatrix();
    node->Reference(maxObj);
    node->SetTransform(0,tm);
    imp->AddNodeToScene(node);
    node->SetName(obj->getKey()->getName());
    imp->RedrawViews();

    return true;
}
Esempio n. 20
0
	void Matrix3::Multiply(const Matrix3& other, Matrix3* result) const
	{
		Matrix3 tempResult;
		tempResult.SetElem(0, (m_Elems[0] * other.GetElem(0)) +
							   (m_Elems[1] * other.GetElem(3)) +
							   (m_Elems[2] * other.GetElem(6)));
		tempResult.SetElem(1, (m_Elems[0] * other.GetElem(1)) +
							   (m_Elems[1] * other.GetElem(4)) +
							   (m_Elems[2] * other.GetElem(7)));
		tempResult.SetElem(2, (m_Elems[0] * other.GetElem(2)) +
							   (m_Elems[1] * other.GetElem(5)) +
							   (m_Elems[2] * other.GetElem(8)));
		tempResult.SetElem(3, (m_Elems[3] * other.GetElem(0)) +
							   (m_Elems[4] * other.GetElem(3)) +
							   (m_Elems[5] * other.GetElem(6)));
		tempResult.SetElem(4, (m_Elems[3] * other.GetElem(1)) +
							   (m_Elems[4] * other.GetElem(4)) +
							   (m_Elems[5] * other.GetElem(7)));
		tempResult.SetElem(5, (m_Elems[3] * other.GetElem(2)) +
							   (m_Elems[4] * other.GetElem(5)) +
							   (m_Elems[5] * other.GetElem(8)));
		tempResult.SetElem(6, (m_Elems[6] * other.GetElem(0)) +
							   (m_Elems[7] * other.GetElem(3)) +
							   (m_Elems[8] * other.GetElem(6)));
		tempResult.SetElem(7, (m_Elems[6] * other.GetElem(1)) +
							   (m_Elems[7] * other.GetElem(4)) +
							   (m_Elems[8] * other.GetElem(7)));
		tempResult.SetElem(8, (m_Elems[6] * other.GetElem(2)) +
							   (m_Elems[7] * other.GetElem(5)) +
							   (m_Elems[8] * other.GetElem(8)));
		(*result) = tempResult;
	}
Esempio n. 21
0
ColMesh* RBExport::GetColMesh( INode* node )
{
    ObjectState os      = node->EvalWorldState( m_CurTime );
    Object*     pObject = os.obj;
    if (!pObject) 
    {
        Warn( "Could not evaluate object state. Collision mesh %s was skipped.", node->GetName() );
        return NULL;
    }

    Matrix3 nodeTM          = node->GetNodeTM( m_CurTime );
    Matrix3 nodeTMAfterWSM  = node->GetObjTMAfterWSM( m_CurTime );
    Matrix3 mOffs           = nodeTMAfterWSM*Inverse( nodeTM );

    //  triangulate
    TriObject* pTriObj = NULL;
    if (pObject->CanConvertToType( Class_ID( TRIOBJ_CLASS_ID, 0 ) )) 
    { 
        pTriObj = (TriObject*)pObject->ConvertToType( m_CurTime, Class_ID( TRIOBJ_CLASS_ID, 0 ) );
    }
    bool bReleaseTriObj = (pTriObj != pObject);
    if (!pTriObj) 
    {
        Warn( "Could not triangulate mesh in node. Collision mesh %s was skipped.", node->GetName() );
        return NULL;
    }

    //  ensure, that vertex winding direction in polygon is CCW
    Matrix3 objTM = node->GetObjTMAfterWSM( m_CurTime );
    bool bNegScale = (DotProd( CrossProd( objTM.GetRow(0), objTM.GetRow(1) ), objTM.GetRow(2) ) >= 0.0);

    int vx[3];
    vx[0] = bNegScale ? 2 : 0;
    vx[1] = bNegScale ? 1 : 1;
    vx[2] = bNegScale ? 0 : 2;

    Mesh& mesh = pTriObj->GetMesh();

    //  some cosmetics
    mesh.RemoveDegenerateFaces();
    mesh.RemoveIllegalFaces();
    
    //  create collision mesh
    ColMesh* pMesh = new ColMesh();
    
    int numPri  = mesh.getNumFaces();
    int numVert = mesh.numVerts;

    //  copy vertices
    for (int i = 0; i < numVert; i++)
    {
        Point3 pt   = mesh.verts[i];
        pt = mOffs.PointTransform( pt );
        pt = c_FlipTM.PointTransform( pt );
        pMesh->AddVertex( Vec3( pt.x, pt.y, pt.z ) );
    }

    //  loop on mesh faces
    for (int i = 0; i < numPri; i++)
    {
        Face& face = mesh.faces[i];
        pMesh->AddPoly( face.v[vx[0]], face.v[vx[1]], face.v[vx[2]] );
    }

    Msg( LogType_Stats, "Physics collision trimesh has %d vertices and %d faces.", numVert, numPri );

    return pMesh;
} // RBExport::GetColMesh
SimulatedObject * MainEngine::makeSimulatedObject3D(TypeObject _typeObject)
{
    SimulatedObject * simulatedObject = new SimulatedObject();
    simulatedObject->setTypeObject(_typeObject);
    simulatedObject->setMass(MASS);
    simulatedObject->setRestitution(COEF_RESTITUTION);
    simulatedObject->setPosition(POSITION_X, POSITION_Y, POSITION_Z);
    simulatedObject->setLinearDamping(COEF_LINEAR_DAMPING);
    simulatedObject->setAngularDamping(COEF_ANGULAR_DAMPING);
    simulatedObject->setCanSleep(CAN_AWAKE);
    simulatedObject->setAwake();
    simulatedObject->setSelected(true);

    switch (_typeObject) {
        case SPHERE:
        {
            simulatedObject->setMode(TRIANGLE_STRIP);
            simulatedObject->setRadius(0.1f);
            simulatedObject->addAllVectors(this->createSphere(simulatedObject->getPosition(), simulatedObject->getRadius()));
            
            Matrix3 tensor;
            real coeff = 0.4f*simulatedObject->getMass() * simulatedObject->getRadius()*simulatedObject->getRadius();
            tensor.setInertiaTensorCoeffs(coeff,coeff,coeff);
            simulatedObject->setInertiaTensor(tensor);

            break;
        }
        case BOX:
        {
            simulatedObject->setHalfSize(0.1f, 0.1f, 0.1f);
            simulatedObject->addAllVectors(this->createBox(simulatedObject->getPosition(), simulatedObject->getHalfSize()));

            Matrix3 tensor;
            tensor.setBlockInertiaTensor(simulatedObject->getHalfSize(), simulatedObject->getMass());
            simulatedObject->setInertiaTensor(tensor);

            break;
        }
        case PLAN:
        {
            simulatedObject->setSelected(false);
            simulatedObject->setPosition(0.0f, 0.0f, 0.0f);
            simulatedObject->setMass(0.0f);
            simulatedObject->setFriction(COEF_FRICTION);
            simulatedObject->setMode(LINES);
            simulatedObject->setColorAux(0, 0, 0, 0);
            simulatedObject->setHalfSize(3.0f, 0.0f, 3.0f);
            simulatedObject->addAllVectors(this->createPlan(simulatedObject->getPosition()));            
            break;
        }
            
        case PYRAMID:
            simulatedObject->setHalfSize(0.05f, 0.05f, 0.05f);
            simulatedObject->addAllVectors(this->createTriangleWithSquareBase(simulatedObject->getPosition(), simulatedObject->getHalfSize()));
            break;

//        case TRIANGLE_TRIANGULAR_BASE:
//            simulatedObject->setHalfSize(0.1f, 0.1f, 0.1f);
//            simulatedObject->addAllVectors(this->createTriangleWithTriangularBase(simulatedObject->getPosition(), simulatedObject->getHalfSize()));
//            break;


        case CONE:
            simulatedObject->setHalfSize(1.01f, 1.01f, 1.01f);
            simulatedObject->addAllVectors(this->createCone(simulatedObject->getPosition(), simulatedObject->getHalfSize()));
            break;
            
        default:
            break;

    }
    
    if (simulatedObject->getMode() == -1) {
        simulatedObject->setMode(TRIANGLES);
    }

    return simulatedObject;
}
Esempio n. 23
0
// DIVISION A/B = A * (1/B) = A * Inverse(B)
Matrix3 Matrix3::operator/ ( const Matrix3& myMatrix ) const
{
	Matrix3 temp = myMatrix;

	return( *this * temp.Inverse() );
}
Esempio n. 24
0
Matrix3 Matrix3::scaled( const Vector3& p_scale ) const {

	Matrix3 m = *this;
	m.scale(p_scale);
	return m;
}
Esempio n. 25
0
//----------------------------------------------------------------------------
PX2::Transform SceneBuilder::GetLocalTransform (INode *node, TimeValue time)
{
	// 计算节点的本地变换。Max节点的变换方法提供的节点的世界变换,所以我们
	// 必须做一些操纵去获得节点的本地变换。

	Matrix3 maxLocal = node->GetObjTMAfterWSM(time) *
		Inverse(node->GetParentNode()->GetObjTMAfterWSM(time));

	// 分解变换
	AffineParts affParts;
	decomp_affine(maxLocal, &affParts);

	// Position
	bool isTranslationZero = 
		fabsf(affParts.t.x) < MIN_DIFFERENCE &&
		fabsf(affParts.t.y) < MIN_DIFFERENCE &&
		fabsf(affParts.t.z) < MIN_DIFFERENCE;

	// Rotation
	float qSign = (affParts.q.w >= 0.0f ? 1.0f : -1.0f);
	bool isRotationIndentity = 
		fabsf(qSign*affParts.q.w - 1.0f) < MIN_DIFFERENCE &&
		fabsf(affParts.q.x) < MIN_DIFFERENCE &&
		fabsf(affParts.q.y) < MIN_DIFFERENCE &&
		fabsf(affParts.q.z) < MIN_DIFFERENCE;

	// Reflect
	bool hasReflection = (affParts.f < 0.0f);

	// Uniform scale
	bool isScaleUniform = (fabsf(affParts.k.x - affParts.k.y)<MIN_DIFFERENCE &&
		fabsf(affParts.k.y - affParts.k.z)<MIN_DIFFERENCE);

	// Unity scale
	bool isScaleUnity = isScaleUniform &&
		fabsf(affParts.k.x - 1.0f) < MIN_DIFFERENCE;

	// Scale orientation is identity?
	float uSign = (affParts.u.w >= 0.0f ? 1.0f : -1.0f);
	bool isOrientIndentity = isScaleUniform || (
		fabsf(uSign*affParts.u.w - 1.0f) < MIN_DIFFERENCE &&
		fabsf(affParts.u.x) < MIN_DIFFERENCE &&
		fabsf(affParts.u.y) < MIN_DIFFERENCE &&
		fabsf(affParts.u.z) < MIN_DIFFERENCE);

	// 计算Phoenix2等价变换
	PX2::Transform local;

	if (!isTranslationZero)
	{
		local.SetTranslate(PX2::APoint(affParts.t.x, affParts.t.y,
			affParts.t.z));
	}

	if (hasReflection)
	{
		affParts.k *= -1.0f;
	}
	
	if (isScaleUniform)
	{
		// 矩阵的形式为R*(s*I),s是统一缩放矩阵。
		if (!isRotationIndentity)
		{
			PX2::HMatrix rot;
			PX2::HQuaternion(affParts.q.w, -affParts.q.x, -affParts.q.y,
				-affParts.q.z).ToRotationMatrix(rot);
			local.SetRotate(rot);
		}

		if (!isScaleUnity)
		{
			local.SetUniformScale(affParts.k.x);
		}
	}
	else if (isOrientIndentity)
	{
		if (!isRotationIndentity)
		{
			PX2::HMatrix rot;
			PX2::HQuaternion(affParts.q.w, -affParts.q.x, -affParts.q.y,
				-affParts.q.z).ToRotationMatrix(rot);
			local.SetRotate(rot);
		}

		local.SetScale(PX2::APoint(affParts.k.x, affParts.k.y, affParts.k.z));
	}
	else
	{
		PX2::Matrix3f mat(
			maxLocal.GetAddr()[0][0],
			maxLocal.GetAddr()[1][0],
			maxLocal.GetAddr()[2][0],
			maxLocal.GetAddr()[0][1],
			maxLocal.GetAddr()[1][1],
			maxLocal.GetAddr()[2][1],
			maxLocal.GetAddr()[0][2],
			maxLocal.GetAddr()[1][2],
			maxLocal.GetAddr()[2][2]);

		local.SetMatrix(PX2::HMatrix(mat));
	}

	return local;
}
Esempio n. 26
0
Matrix3 Matrix3::orthonormalized() const {

	Matrix3 c = *this;
	c.orthonormalize();
	return c;
}
Esempio n. 27
0
/*
====================
GatherSkin
====================
*/
void G3DSExport::GatherSkin(INode* i_node)
{
	SKIN skin;

	// get the name of the node
	skin.name = i_node->GetName();

	// get the skin interface
	Modifier *modifier = GetModifier(i_node,SKIN_CLASSID);
	ISkin* i_skin = (ISkin*)modifier->GetInterface(I_SKIN);
	MAX_CHECK(i_skin);

	// convert to the triangle type
	Mesh* i_mesh = NULL;
	Object* obj = i_node->EvalWorldState(mTime).obj;
	if(obj && ( obj->SuperClassID() == GEOMOBJECT_CLASS_ID ))
	{
		if(obj->CanConvertToType(Class_ID(TRIOBJ_CLASS_ID, 0))) 
		{ 
			TriObject *tri_obj = (TriObject*)obj->ConvertToType(mTime, Class_ID(TRIOBJ_CLASS_ID, 0)); MAX_CHECK(tri_obj);
			i_mesh = &tri_obj->mesh;
		}
	}
	MAX_CHECK(i_mesh&&i_mesh->getNumFaces()&&i_mesh->getNumVerts());

	// get the material
	skin.texture = "textures/default.tga";
	Mtl* mtl = i_node->GetMtl();
	if(mtl && (mtl->ClassID()==Class_ID(DMTL_CLASS_ID, 0)) && ((StdMat*)mtl)->MapEnabled(ID_DI)) 
	{
		Texmap *texmap = mtl->GetSubTexmap(ID_DI);
		if(texmap && texmap->ClassID() == Class_ID(BMTEX_CLASS_ID, 0x00))
		{
			skin.texture = UnifySlashes(((BitmapTex *)texmap)->GetMapName());
			if( !strstr( skin.texture.c_str(), mPath.c_str() ) )
			{
				G3DAssert("The material(%s) is error : the texture path(%s) is illegal!",mtl->GetName(), skin.texture.c_str());
			}
			else
			{
				skin.texture = strstr(skin.texture.c_str(),mPath.c_str()) + strlen(mPath.c_str());
			}
		}
	}

	// if it has uvs
	int map_count = i_mesh->getNumMaps();
	bool has_uvs = i_mesh->getNumTVerts() && i_mesh->tvFace;
	if(!(has_uvs&&map_count)) { G3DAssert("The skin(%s) has not the uv coordinates.",skin.name.c_str()); return; }

	// get the transform
	Matrix3 mesh_matrix = i_node->GetObjectTM(mTime);
	Matrix3 node_matrix = i_node->GetNodeTM(mTime);
	Matrix3 transform = mesh_matrix * Inverse(node_matrix);

	// get the points
	skin.points.assign(i_mesh->verts, i_mesh->verts+i_mesh->getNumVerts());

	// get the triangles
	for(int i = 0; i < i_mesh->getNumFaces(); i++)
	{
		Face& face = i_mesh->faces[i];

		TRIANGLE tri;		
		tri.smoothing = face.smGroup;
		for(int j = 0; j < 3; j++)
		{
			VPTNIS v;
			v.pos = transform * i_mesh->verts[face.v[j]];

			// get the uv
			UVVert * map_verts = i_mesh->mapVerts(1);
			TVFace * map_faces = i_mesh->mapFaces(1);
			v.uv = reinterpret_cast<Point2&>(map_verts[map_faces[i].t[j]]);
			v.uv.y = 1 - v.uv.y;

			// initialize the normal
			v.normal = Point3::Origin;

			// get the vertex index
			v.index = face.v[j];

			// get the smoothing group
			v.smoothing = face.smGroup;			

			// set the index for the triangle
			tri.index0[j] = v.index;

			// reassemble the vertex list
			tri.index1[j] = AddVertex(skin, v);
		}

		// add the triangle to the table
		skin.triangles.push_back(tri);
	}

	// build the index map
	for( int i = 0; i < skin.vertexes.size(); i++ )
	{
		skin.vertex_index_map[skin.vertexes[i].index].push_back(i);
	}

	// get the skin context data
	ISkinContextData* i_skin_context_data = i_skin->GetContextInterface(i_node);
	if(i_skin_context_data == NULL) { G3DAssert("The skin(%s) has not the weight.",skin.name.c_str()); return; }

	// gets the initial matrix of the skinned object 
	Matrix3 initial_object_transform;
	i_skin->GetSkinInitTM(i_node, initial_object_transform, true);

	// process the points
	int num_points = i_skin_context_data->GetNumPoints();
	for(int i = 0; i < num_points; i++)
	{
		MAX_CHECK(i < skin.points.size());

		VPIW viw;

		// get the initial point				
		viw.pos = initial_object_transform * skin.points[i];

		// process the weights		
		std::multimap< float, int > weights;

		// get the number of bones that control this vertex
		int num_bones = i_skin_context_data->GetNumAssignedBones(i);
		if(num_bones>0)
		{
			for (int j = 0; j < num_bones; j++)
			{
				Matrix3 transform;

				// get the assigned bone of the point 
				INode* i_bone_node = i_skin->GetBone(i_skin_context_data->GetAssignedBone(i, j));
				MAX_CHECK(i_bone_node != NULL);

				// get the weight of the bone
				float weight = i_skin_context_data->GetBoneWeight(i, j);

				// add the weight to the table
				weights.insert(std::make_pair(weight, AddBone(skin,i_bone_node)));
			}
		}
		else
		{
			// add the weight to the table
			weights.insert(std::make_pair(1.f, AddBone(skin,i_node)));
		}

		// recalculate the weights
		float weight0 = 0.f, weight1 = 0.f, weight2 = 0.f;
		int index0 = 0, index1 = 0, index2 = 0;
		std::multimap< float, int >::iterator it = weights.end();
		it--;
		weight0 = it->first;
		index0 = it->second;
		if(it != weights.begin())
		{
			it--;
			weight1 = it->first;
			index1 = it->second;
			if(it != weights.begin())
			{
				it--;
				weight2 = it->first;
				index2 = it->second;
			}
		}		
		float sum_weights = weight0 + weight1 + weight2;

		// store the skin weights	
		viw.weight[0]	= weight0/sum_weights;
		viw.index[0]	= index0;
		viw.weight[1]	= weight1/sum_weights;
		viw.index[1]	= index1;
		viw.weight[2]	= weight2/sum_weights;
		viw.index[2]	= index2;
		skin.weights.push_back(viw);
	}

	// get the initial transforms
	skin.transforms.resize(skin.bones.size());
	for(int i = 0; i < skin.bones.size(); i++)
	{
		INode* node = skin.bones[i];
		Matrix3 mat;
		if (SKIN_INVALID_NODE_PTR == i_skin->GetBoneInitTM( node, mat ))
		{
			if (SKIN_INVALID_NODE_PTR == i_skin->GetSkinInitTM( node, mat ))
			{
				mat.IdentityMatrix();
			}
		}
		skin.transforms[i] = Inverse(mat);
	}

	// there is a 75 bone limit for each skinned object.
	if(skin.bones.size()>75)
	{
		G3DAssert("There are more %d bones in the skin(%s).",skin.bones.size(), i_node->GetName());
		return;
	}

	// reset the skin vertex position
	for(int i = 0; i < skin.vertexes.size(); i++)
	{
		VPTNIS& v0 = skin.vertexes[i];
		VPIW& v1 = skin.weights[v0.index];
		v0.pos = v1.pos;
	}

	// build the normal space
	BuildNormal(skin);

	// calculate the bounding box	
	skin.box.Init();
	for(int i = 0; i < skin.vertexes.size(); i++)
	{
		Point3 pt = node_matrix * skin.vertexes[i].pos;
		skin.box += pt;
	}

	// add the skin to the table
	mSkins.push_back(skin);
}
Esempio n. 28
0
File: mesh.cpp Progetto: skopp/rush
//  Here we process mesh geometry for given node.
//  Vertices for the geometry from the all meshes of the scene are allocated in 
//  one big vertex pool. One vertex can occur several times in this pool, because
//  we add 3 new vertices for every face.
//  After all meshes in the scene are processed, this pool is collapsed to remove
//  duplicate vertices.
void RBExport::ProcessMesh( INode* node )
{
    if (!node->Renderable() || node->IsNodeHidden())
    {
        return;
    }
    
    ObjectState os      = node->EvalWorldState( m_CurTime );
    Object*     pObject = os.obj;
    if (!pObject) 
    {
        Warn( "Could not evaluate object state in node <%s>. Mesh was skipped.", node->GetName() );
        return;
    }
    Matrix3 nodeTM          = node->GetNodeTM( m_CurTime );
    Matrix3 nodeTMAfterWSM  = node->GetObjTMAfterWSM( m_CurTime );
    Matrix3 mOffs           = nodeTMAfterWSM*Inverse( nodeTM );

    //  triangulate
    TriObject* pTriObj = 0;
    if (pObject->CanConvertToType( Class_ID( TRIOBJ_CLASS_ID, 0 ) )) 
    { 
        pTriObj = (TriObject*)pObject->ConvertToType( m_CurTime, Class_ID( TRIOBJ_CLASS_ID, 0 ) );
    }
    bool bReleaseTriObj = (pTriObj != pObject);
    if (!pTriObj) 
    {
        Warn( "Could not triangulate mesh in node <%s>. Node was skipped", node->GetName() );
        return;
    }

    if (!MeshModStackIsValid( node ))
    {
        Warn( "Modifier stack for node %s should be collapsed or contain only Skin modifier.", 
                node->GetName() );
    }

    //  ensure, that vertex winding direction in polygon is CCW
    Matrix3 objTM = node->GetObjTMAfterWSM( m_CurTime );
    bool bNegScale = (DotProd( CrossProd( objTM.GetRow(0), objTM.GetRow(1) ), objTM.GetRow(2) ) >= 0.0);

    int vx[3];
    if (bNegScale) 
    {
        vx[0] = 0; 
        vx[1] = 1; 
        vx[2] = 2; 
    } 
    else 
    { 
        vx[0] = 2; 
        vx[1] = 1; 
        vx[2] = 0; 
    }

    Mesh& mesh = pTriObj->GetMesh();

    bool bHasTexCoord    = (mesh.numTVerts != 0);
    bool bHasVertexColor = (mesh.numCVerts != 0) && m_pConfig->m_bExportVertexColors;
    bool bHasNormal      = m_pConfig->m_bExportNormals; 
    bool bHasSkin        = ProcessSkin( node );

    //  some cosmetics
    BOOL res = mesh.RemoveDegenerateFaces();
    if (res) 
    {
        Spam( "Degenerate faces were fixed." );
    }

    res = mesh.RemoveIllegalFaces();
    if (res) 
    {
        Spam( "Degenerate indices were fixed." );
    }
    
    ExpNode* pExpNode = GetExportedNode( node );
    if (!pExpNode)
    {
        return;
    }

    int numPri     = mesh.getNumFaces();
    int numVert    = mesh.numVerts;

    //  initialize helper array for building vertices' 0-circles
    VertexPtrArray vertexEntry;
    vertexEntry.resize( numVert );
    memset( &vertexEntry[0], 0, sizeof( ExpVertex* )*numVert );

    Spam( "Original mesh has %d vertices and %d faces.", numVert, numPri );
    bool bHasVoidFaces = false;

    //  loop on mesh faces
    for (int i = 0; i < numPri; i++)
    {
        Face& face = mesh.faces[i];

        //  calculate face normal
        const Point3& v0 = mesh.verts[face.v[vx[0]]]; 
        const Point3& v1 = mesh.verts[face.v[vx[1]]]; 
        const Point3& v2 = mesh.verts[face.v[vx[2]]]; 
        Point3 normal = -Normalize( (v1 - v0)^(v2 - v1) ); 
        normal = mOffs.VectorTransform( normal );
        normal = c_FlipTM.VectorTransform( normal );

        //  loop on face vertices
        ExpVertex* pFaceVertex[3];
        for (int j = 0; j < 3; j++)
        {
            ExpVertex v;
            v.mtlID  = pExpNode->GetMaterialIdx( face.getMatID() );            
            v.nodeID = pExpNode->m_Index;

            if (v.mtlID < 0)
            {
                bHasVoidFaces = true;
            }
            
            //  extract vertex position and apply world-space modifier to it
            int vIdx    = face.v[vx[j]];
            Point3 pt   = mesh.verts[vIdx];
            pt = mOffs.PointTransform( pt );
            pt = c_FlipTM.PointTransform( pt );
            
            v.index = vIdx;
            v.pos   = Vec3( pt.x, pt.y, pt.z );
            //v.pos *= m_WorldScale;

            //  extract skinning info
            if (bHasSkin)
            {
                GetSkinInfo( v );
            }

            //  assign normal
            if (bHasNormal)
            {
                v.normal  = Vec3( normal.x, normal.y, normal.z );
                v.smGroup = face.smGroup;
            }
            
            //  extract vertex colors
            if (bHasVertexColor)    
            {
                const VertColor& vcol = mesh.vertCol[mesh.vcFace[i].t[vx[j]]];
                v.color = ColorToDWORD( Color( vcol.x, vcol.y, vcol.z ) );
            }

            //  extract texture coordinates
            if (bHasTexCoord)   
            {
                const Point3& texCoord = mesh.tVerts[mesh.tvFace[i].t[vx[j]]];
                v.uv.x = texCoord.x;
                v.uv.y = 1.0f - texCoord.y;

                //  second texture coordinate channel
                if (mesh.getNumMaps() > 1 && mesh.mapSupport( 2 ))
                {
                    UVVert* pUVVert = mesh.mapVerts( 2 );
                    TVFace* pTVFace = mesh.mapFaces( 2 );
                    if (pUVVert && pTVFace)
                    {
                        const Point3& tc2 = pUVVert[pTVFace[i].t[vx[j]]];
                        v.uv2.x = tc2.x;
                        v.uv2.y = 1.0f - tc2.y;
                    }
                }
            }

            //  allocate new vertex 
            pFaceVertex[j] = AddVertex( v );

            //  we want vertices in the 0-ring neighborhood to be linked into closed linked list
            if (vertexEntry[vIdx] == NULL) 
            {
                vertexEntry[vIdx] = pFaceVertex[j];
                pFaceVertex[j]->pNext = pFaceVertex[j];
            }
            else
            {
                vertexEntry[vIdx]->AddToZeroRing( pFaceVertex[j] );
            }
        }
        AddPolygon( pFaceVertex[0], pFaceVertex[1], pFaceVertex[2] );

        if (IsCanceled())
        {
            return;
        }
    }

    //  correct normals at vertices corresponding to smoothing groups
    SmoothNormals( vertexEntry );

    //  put vertices into set (this removes duplicate vertices)
    for (int i = 0; i < numVert; i++)
    {
        ExpVertex::ZeroRingIterator it( vertexEntry[i] );
        while (it)
        {
            VertexSet::iterator sIt = m_VertexSet.find( it );
            if (sIt == m_VertexSet.end())
            {
                m_VertexSet.insert( it );
            }
            else
            {
                it->pBase = (*sIt);
            }
            ++it;
        }
    }

    if (bReleaseTriObj) 
    {
        delete pTriObj;
    }

    if (bHasVoidFaces)
    {
        Warn( "Mesh %s has faces with no material assigned.", node->GetName() );
    }
} // RBExport::ProcessMesh
Esempio n. 29
0
void RigidBodyMotionSimulation::CreateObjects()
{
	for(int i = 0 ; i < 0 ; i++)
	{
		RigidBodyPtr body(new RigidBody());
		body->SetMass(1);
	//	Point3 newPos(0,20,30);
	
		Point3 newPos(30,10,0);
		body->SetPos(newPos);

		Matrix3 inertiaTensor;
		inertiaTensor.SetBlockInertiaTensor(Vector3(1,1,1), 1);
		body->SetInertiaTensor(inertiaTensor);

//		body->LoadModel("../../media/models/torus.obj");
		body->LoadModel("../../media/models/cube.obj");

		//matrix3 orientation = body->getorientation();
		//orientation.createrotationmatrixaboutxaxis(45, &orientation);
		//body->setorientation(orientation);
		
		Quaternion orientation;
		Vector3 rotationVec(1,1,1);
		orientation.RotateByVector(rotationVec);
		body->SetOrientation(orientation);


		body->CalculateInternals();

		//m_CollisionDetector->AddAABB(body->GetAABB());

		/*
		if(i==0)
		{
			body->AddForceAtBodyPoint(Vector3(10,10, 0),Point3(0,0,0));
		}
		else
		{
			body->AddForceAtBodyPoint(Vector3(-10,-10, 0),Point3(0,0,0));
		}
		*/
		body->AddForceAtBodyPoint(Vector3(0,-90,0),Point3(0,0,0));

		//body->CalculateInternals();
		m_RigidBodies.push_back(body);
	}

	m_Plane = new CollisionPlane();
	m_Plane->SetPoint(Point3(0,0,0));
	m_Plane->SetNormal(Vector3(0,1,0));

	m_Particle = new Particle();
	m_Particle->SetPos(Point3(0,10,1));
	m_Particle->SetVel(Vector3(0,-10,0));

	/*
	m_Triangle_0->SetPoint( Point3(1.0f,3.0f,0.0f), 0 );
	m_Triangle_0->SetPoint( Point3(2.0f,1.0f,0.0f), 1 );
	m_Triangle_0->SetPoint( Point3(2.0f,2.0f,0.0f), 2 );
	*/

	m_Triangle_0->SetPoint( Point3(0.3f,0.3f,0.0f), 0 );
	m_Triangle_0->SetPoint( Point3(1.3f,1.3f,0.0f), 1 );
	m_Triangle_0->SetPoint( Point3(2.3f,0.3f,0.0f), 2 );
	m_Triangle_0->CreateEdges();

//	m_Contact = new Contact();
}
Esempio n. 30
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);
                }
            }
        }
    }
}