void XsiExp::ExportMeshObject( INode * node, int indentLevel) { Object * obj = node->EvalWorldState(GetStaticFrame()).obj; if (!obj || obj->ClassID() == Class_ID(TARGET_CLASS_ID, 0)) { return; } TSTR indent = GetIndent(indentLevel); ExportNodeHeader(node, "Frame", indentLevel); ExportNodeTM(node, indentLevel); ExportMesh(node, GetStaticFrame(), indentLevel); }
void Exporter::ExportGeomObject(INode* node, int indentLevel) { ObjectState os = node->EvalWorldState(GetStaticFrame()); if (!os.obj) return; // Targets are actually geomobjects, but we will export them // from the camera and light objects, so we skip them here. if (os.obj->ClassID() == Class_ID(TARGET_CLASS_ID, 0)) return; ExportNodeHeader(node); ExportNodeTM(node, indentLevel,&rsm->mesh->mat); ExportMesh(node, GetStaticFrame(), indentLevel); ExportMaterial(node, indentLevel); }
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()); }
void Exporter::DumpUVGen(MaxStdMaterial *stdm,StdUVGen* uvGen, int indentLevel) { int mapType = uvGen->GetCoordMapping(0); TimeValue t = GetStaticFrame(); stdm->sina=sin(uvGen->GetAng(t)); stdm->cosa=cos(uvGen->GetAng(t)); stdm->uOffset=uvGen->GetUOffs(t); stdm->uTiling=uvGen->GetUScl(t); stdm->vOffset=uvGen->GetVOffs(t); stdm->vTiling=uvGen->GetVScl(t); }
void Exporter::ExportNodeTM(INode* node, int indentLevel,rmatrix *mat) { Matrix3 pivot = node->GetNodeTM(GetStaticFrame()); // Export TM inheritance flags DWORD iFlags = node->GetTMController()->GetInheritanceFlags(); Point3 row; row = pivot.GetRow(0); mat->_11=-row.x;mat->_12=row.y;mat->_13=row.z;mat->_14=0; row = pivot.GetRow(1); mat->_21=-row.x;mat->_22=row.y;mat->_23=row.z;mat->_24=0; row = pivot.GetRow(2); mat->_31=-row.x;mat->_32=row.y;mat->_33=row.z;mat->_34=0; row = pivot.GetRow(3); mat->_41=-row.x;mat->_42=row.y;mat->_43=row.z;mat->_44=1; *mat=MatrixInverse(*mat); }
// dump some global information. void XsiExp::ExportGlobalInfo() { // header and format fprintf(pStream, "xsi 0101txt 0032\n\n"); // coords fprintf(pStream, "SI_CoordinateSystem coord {\n\t1;\n\t0;\n\t1;\n\t0;\n\t2;\n\t5;\n}\n\n"); // angle? fprintf(pStream, "SI_Angle {\n\t0;\n}\n\n"); // camera fprintf(pStream, "SI_Camera Camera1 {\n\t-4.681479; 4.736986; 8.858665;;\n\t-0.145911; 0.062833; 0.049857;;\n\t0.000000;\n\t44.024410;\n\t0.100000;\n\t32768.000000;\n}\n\n"); // ambient light Color ambLight = ip->GetAmbient(GetStaticFrame(), FOREVER); fprintf(pStream, "SI_Ambience {\n\t%.6f; %.6f; %.6f;;\n}\n\n", ambLight.r, ambLight.g, ambLight.b); fprintf(pStream, "SI_Fog {\n\t0;\n\t0;\n\t0.157895; 0.225564; 0.270677;;\n\t20.000000;\n\t100.000000;\n}\n\n"); }
void XsiExp::ExportBoneObject( INode * node, int indentLevel) { Object * obj = node->EvalWorldState(GetStaticFrame()).obj; if (!obj || obj->ClassID() != Class_ID(BONE_CLASS_ID, 0)) { // reject non-bones return; } if (!node->GetParentNode() || node->GetParentNode()->IsRootNode()) { // bone matrices get passed to children // drop root bone return; } TSTR indent = GetIndent(indentLevel); ExportNodeHeader(node, "Frame", indentLevel); // export parent as this bone ExportNodeTM(node->GetParentNode(), indentLevel); }
void Exporter::ExportCameraObject(INode* node, int indentLevel) { RSCameraObject *pCO=new RSCameraObject; pCO->name=new char[strlen(node->GetName())+1]; strcpy(pCO->name,node->GetName()); INode* target = node->GetTarget(); ExportNodeTM(node, indentLevel,&pCO->tm); CameraState cs; TimeValue t = GetStaticFrame(); Interval valid = FOREVER; // Get animation range Interval animRange = ip->GetAnimRange(); ObjectState os = node->EvalWorldState(t); CameraObject *cam = (CameraObject *)os.obj; cam->EvalCameraState(t,valid,&cs); pCO->fov=cs.fov; #define TARGETFPS 60 TimeValue start = ip->GetAnimRange().Start(); TimeValue end = ip->GetAnimRange().End(); int delta = GetTicksPerFrame() * GetFrameRate() / TARGETFPS; Matrix3 tm; rsm->m_nCameraFrame=(end-start)/delta+1; Matrix3 *m=pCO->am=new Matrix3[rsm->m_nCameraFrame]; for (t=start; t<=end; t+=delta) { tm = node->GetNodeTM(t) * Inverse(node->GetParentTM(t)); *m=tm; m++; } rsm->m_CameraList.Add(pCO); }
void Exporter::ExportMesh(INode* node, TimeValue t, int indentLevel) { int i; Mtl* nodeMtl = node->GetMtl(); Matrix3 tm = node->GetObjTMAfterWSM(t); BOOL negScale = TMNegParity(tm); int vx1, vx2, vx3; TSTR indent; ObjectState os = node->EvalWorldState(t); if (!os.obj || os.obj->SuperClassID()!=GEOMOBJECT_CLASS_ID) { return; // Safety net. This shouldn't happen. } // Order of the vertices. Get 'em counter clockwise if the objects is // negatively scaled. if (negScale) { vx1 = 2; vx2 = 1; vx3 = 0; } else { vx1 = 0; vx2 = 1; vx3 = 2; } BOOL needDel; TriObject* tri = GetTriObjectFromNode(node, t, needDel); if (!tri) { return; } Mesh* mesh = &tri->mesh; mesh->buildNormals(); { // make vertices and faces rsm->mesh->nV=mesh->getNumVerts(); rsm->mesh->nF=mesh->getNumFaces(); rsm->mesh->ver=new rvertex[mesh->getNumVerts()]; rsm->mesh->face=new rface[mesh->getNumFaces()]; } // Export the vertices for (i=0; i<mesh->getNumVerts(); i++) { Point3 v = tm * mesh->verts[i]; rsm->mesh->ver[i].coord=rvector(v); rsm->mesh->ver[i].normal=rvector(0,0,0); } // To determine visibility of a face, get the vertices in clockwise order. // If the objects has a negative scaling, we must compensate for that by // taking the vertices counter clockwise for (i=0; i<mesh->getNumFaces(); i++) { rsm->mesh->face[i].a=(WORD)mesh->faces[i].v[vx1]; rsm->mesh->face[i].c=(WORD)mesh->faces[i].v[vx2]; rsm->mesh->face[i].b=(WORD)mesh->faces[i].v[vx3]; rsm->mesh->face[i].nMaterial=mesh->faces[i].getMatID(); } // Export face map texcoords if we have them... if (!CheckForAndExportFaceMap(nodeMtl, mesh, indentLevel+1)) { // If not, export standard tverts int numTVx = mesh->getNumTVerts(); if (numTVx) { rface *f=rsm->mesh->face; for (i=0; i<mesh->getNumFaces(); i++) { // dubble added TVFace *tvf=&mesh->tvFace[i]; f->u[0]=mesh->tVerts[tvf->t[vx1]].x; f->v[0]=1.0f-mesh->tVerts[tvf->t[vx1]].y; f->u[2]=mesh->tVerts[tvf->t[vx2]].x; f->v[2]=1.0f-mesh->tVerts[tvf->t[vx2]].y; f->u[1]=mesh->tVerts[tvf->t[vx3]].x; f->v[1]=1.0f-mesh->tVerts[tvf->t[vx3]].y; // good f++; // end of dubble added } } } { // Export mesh (face + vertex) normals Point3 fn; // Face normal Point3 vn; // Vertex normal int vert; Face* f; // Face and vertex normals. // In MAX a vertex can have more than one normal (but doesn't always have it). // This is depending on the face you are accessing the vertex through. // To get all information we need to export all three vertex normals // for every face. Matrix3 pivot = node->GetNodeTM(GetStaticFrame()); pivot.NoTrans(); for (i=0; i<mesh->getNumFaces(); i++) { f = &mesh->faces[i]; fn = mesh->getFaceNormal(i); rsm->mesh->face[i].normal=fn; vert = f->getVert(vx1); vn = GetVertexNormal(mesh, i, mesh->getRVertPtr(vert)); rsm->mesh->face[i].vnormals[0]=pivot*vn; rsm->mesh->ver[rsm->mesh->face[i].a].normal+=vn; vert = f->getVert(vx2); vn = GetVertexNormal(mesh, i, mesh->getRVertPtr(vert)); rsm->mesh->face[i].vnormals[2]=pivot*vn; rsm->mesh->ver[rsm->mesh->face[i].b].normal+=vn; vert = f->getVert(vx3); vn = GetVertexNormal(mesh, i, mesh->getRVertPtr(vert)); rsm->mesh->face[i].vnormals[1]=pivot*vn; rsm->mesh->ver[rsm->mesh->face[i].c].normal+=vn; } } if (needDel) { delete tri; } }
void Exporter::DumpMaterial(MaxMaterial *maxm,Mtl* mtl, int mtlID, int subNo, int indentLevel) { int i; TimeValue t = GetStaticFrame(); if (!mtl) return; // for(i=0;i<indentLevel;i++) { log(" "); } // log("material %s adding. type : ",mtl->GetName()); // We know the Standard material, so we can get some extra info if (mtl->ClassID() == Class_ID(DMTL_CLASS_ID, 0)) { // top level & standard material // log("standard \n"); StdMat* std = (StdMat*)mtl; MaxStdMaterial *stdm=new MaxStdMaterial; strcpy(stdm->name,mtl->GetName()); stdm->Ambient=rvector(std->GetAmbient(t)); stdm->Ambient.x=-stdm->Ambient.x; stdm->Diffuse=rvector(std->GetDiffuse(t)); stdm->Diffuse.x=-stdm->Diffuse.x; stdm->Specular=rvector(std->GetSpecular(t)); stdm->Specular.x=-stdm->Specular.x; // 축의 바뀜때문에 만들어 놓은.. 으흑.. stdm->TwoSide=std->GetTwoSided(); if(std->GetTransparencyType()==TRANSP_ADDITIVE) stdm->ShadeMode=RSSHADEMODE_ADD; else stdm->ShadeMode=RSSHADEMODE_NORMAL; if(rsm->MaxStdMaterialList.GetByName(stdm->name)==-1) // 이미 있는 standard material 이면 더하지 않음. { rsm->MaxStdMaterialList.Add(stdm); stdm->RMLIndex=rsm->MaxStdMaterialList.GetCount()-1; for (i=0; i<mtl->NumSubTexmaps(); i++) { Texmap* subTex = mtl->GetSubTexmap(i); float amt = 1.0f; if (subTex) { // If it is a standard material we can see if the map is enabled. if (mtl->ClassID() == Class_ID(DMTL_CLASS_ID, 0)) { if (!((StdMat*)mtl)->MapEnabled(i)) continue; amt = ((StdMat*)mtl)->GetTexmapAmt(i, 0); } DumpTexture(stdm, subTex, mtl->ClassID(), i, amt, indentLevel+1); } } } else { delete stdm; } maxm->nSubMaterial=1; maxm->SubMaterials=new int[1]; maxm->SubMaterials[0]=rsm->MaxStdMaterialList.GetByName(mtl->GetName()); } if (mtl->NumSubMtls() > 0) { // log("multi/sub ( count : %d )\n",mtl->NumSubMtls()); maxm->nSubMaterial=mtl->NumSubMtls(); maxm->SubMaterials=new int[maxm->nSubMaterial]; maxm->pSubMaterials=new MaxMaterial*[maxm->nSubMaterial]; for (i=0; i<mtl->NumSubMtls(); i++) { Mtl* subMtl = mtl->GetSubMtl(i); if (subMtl) { maxm->pSubMaterials[i]=new MaxMaterial; DumpMaterial(maxm->pSubMaterials[i],subMtl, 0, i, indentLevel+1); if(subMtl->ClassID() == Class_ID(DMTL_CLASS_ID, 0)) { maxm->SubMaterials[i]= rsm->MaxStdMaterialList.GetByName(subMtl->GetName()); } else maxm->SubMaterials[i]= maxm->pSubMaterials[i]->SubMaterials[0]; } else { maxm->pSubMaterials[i]=NULL; maxm->SubMaterials[i]=-1; } } } }
void XsiExp::DumpMaterial(Mtl * mtl, int mtlID, int subNo, int indentLevel) { if (!mtl) { return; } TSTR indent = GetIndent(indentLevel+1); if (mtl->NumSubMtls() > 0) { for (int i = 0; i < mtl->NumSubMtls(); i++) { Mtl* subMtl = mtl->GetSubMtl(i); if (subMtl) { DumpMaterial( subMtl, 0, i, indentLevel); } } } else { TimeValue t = GetStaticFrame(); // Note about material colors: // This is only the color used by the interactive renderer in MAX. // To get the color used by the scanline renderer, we need to evaluate // the material using the mtl->Shade() method. // Since the materials are procedural there is no real "diffuse" color for a MAX material // but we can at least take the interactive color. fprintf(pStream,"%sSI_Material {\n", indent.data()); fprintf(pStream,"%s\t%.6f;%.6f;%.6f;%.6f;;\n", indent.data(), mtl->GetDiffuse(t).r, mtl->GetDiffuse(t).g, mtl->GetDiffuse(t).b, 1.0 - mtl->GetXParency(t) ); fprintf(pStream,"%s\t%.6f;\n", indent.data(), mtl->GetShinStr(t) ); fprintf(pStream,"%s\t%.6f;%.6f;%.6f;;\n", indent.data(), mtl->GetSpecular(t).r, mtl->GetSpecular(t).g, mtl->GetSpecular(t).b ); fprintf(pStream,"%s\t%.6f;%.6f;%.6f;;\n", indent.data(), 0.0f, 0.0f, 0.0f); // emissive fprintf(pStream,"%s\t%.6f;\n", indent.data(), 0.0f); // ? fprintf(pStream,"%s\t%.6f;%.6f;%.6f;;\n\n", indent.data(), mtl->GetAmbient(t).r, mtl->GetAmbient(t).g, mtl->GetAmbient(t).b ); for (int i = 0; i < mtl->NumSubTexmaps(); i++) { Texmap * subTex = mtl->GetSubTexmap(i); float amt = 1.0f; if (subTex) { // If it is a standard material we can see if the map is enabled. if (mtl->ClassID() == Class_ID(DMTL_CLASS_ID, 0)) { if (!((StdMat*)mtl)->MapEnabled(i)) { continue; } amt = ((StdMat*)mtl)->GetTexmapAmt(i, 0); } DumpTexture(subTex, mtl->ClassID(), i, amt, indentLevel+1); } } fprintf(pStream,"%s}\n", indent.data()); } }
void XsiExp::ExportMesh( INode * node, TimeValue t, int indentLevel) { ObjectState os = node->EvalWorldState(t); if (!os.obj || os.obj->SuperClassID() != GEOMOBJECT_CLASS_ID) { return; // Safety net. This shouldn't happen. } BOOL needDel; TriObject * tri = GetTriObjectFromNode(node, t, needDel); if (!tri) { // no tri object return; } // prepare mesh Mesh * mesh = &tri->GetMesh(); mesh->buildNormals(); // object offset matrix; apply to verts // swap y and z; max to soft correction Matrix3 matrix(1); // translate matrix.PreTranslate( Point3( node->GetObjOffsetPos().x, node->GetObjOffsetPos().z, -node->GetObjOffsetPos().y)); // rotate AngAxis aa( node->GetObjOffsetRot()); float temp = aa.axis.z; aa.axis.z = -aa.axis.y; aa.axis.y = temp; PreRotateMatrix(matrix, Quat( aa)); // scale ScaleValue scale = node->GetObjOffsetScale(); aa.Set( scale.q); temp = aa.axis.z; aa.axis.z = -aa.axis.y; aa.axis.y = temp; scale.q.Set( aa); temp = scale.s.z; scale.s.z = scale.s.y; scale.s.y = temp; ApplyScaling(matrix, scale); // apply root transform matrix = matrix * topMatrix; // only rotation for normals AffineParts ap; Matrix3 rotMatrix(1); decomp_affine( matrix, &ap); PreRotateMatrix( rotMatrix, ap.q); // set winding order int vx1 = 0, vx2 = 1, vx3 = 2; if (TMNegParity( node->GetNodeTM(GetStaticFrame())) != TMNegParity( matrix) ) { // negative scaling; invert winding order and normal rotation vx1 = 2; vx2 = 1; vx3 = 0; rotMatrix = rotMatrix * Matrix3( Point3(-1,0,0), Point3(0,-1,0), Point3(0,0,-1), Point3(0,0,0)); } // header TSTR indent = GetIndent(indentLevel+1); fprintf(pStream, "%s%s %s {\n",indent.data(), "Mesh", FixupName(node->GetName())); // write number of verts int numLoop = mesh->getNumVerts(); fprintf(pStream, "%s\t%d;\n",indent.data(), numLoop); // write verts for (int i = 0; i < numLoop; i++) { Point3 v = mesh->verts[i]; float temp = v.z; v.z = -v.y; v.y = temp; v = matrix * v; fprintf(pStream, "%s\t%.6f;%.6f;%.6f;%s\n", indent.data(), v.x, v.y, v.z, i == numLoop - 1 ? ";\n" : ","); } // write number of faces numLoop = mesh->getNumFaces(); fprintf(pStream, "%s\t%d;\n", indent.data(), numLoop); // write faces for (i = 0; i < numLoop; i++) { fprintf(pStream, "%s\t3;%d,%d,%d;%s\n", indent.data(), mesh->faces[i].v[vx1], mesh->faces[i].v[vx2], mesh->faces[i].v[vx3], i == numLoop - 1 ? ";\n" : ","); } // face materials Mtl * nodeMtl = node->GetMtl(); int numMtls = !nodeMtl || !nodeMtl->NumSubMtls() ? 1 : nodeMtl->NumSubMtls(); // write face material list header fprintf(pStream, "%s\tMeshMaterialList {\n", indent.data()); // write number of materials fprintf(pStream, "%s\t\t%d;\n", indent.data(), numMtls); // write number of faces fprintf(pStream, "%s\t\t%d;\n", indent.data(), numLoop); // write face material indices (1 for each face) for (i = 0; i < numLoop; i++) { int index = numMtls ? mesh->faces[i].getMatID() % numMtls : 0; fprintf(pStream,"%s\t\t%d%s\n", indent.data(), index, i == numLoop - 1 ? ";\n" : ","); } // write the materials ExportMaterial( node, indentLevel+2); // verts close brace fprintf(pStream, "%s\t}\n\n",indent.data()); // write normals header fprintf(pStream, "%s\t%s {\n", indent.data(), "SI_MeshNormals"); // write number of normals fprintf(pStream, "%s\t\t%d;\n", indent.data(), numLoop * 3); // write normals (3 for each face) for (i = 0; i < numLoop; i++) { Face * f = &mesh->faces[i]; int vert = f->getVert(vx1); Point3 vn = GetVertexNormal(mesh, i, mesh->getRVertPtr(vert)); float temp = vn.z; vn.z = -vn.y; vn.y = temp; vn = rotMatrix * vn; fprintf(pStream,"%s\t\t%.6f;%.6f;%.6f;,\n", indent.data(), vn.x, vn.y, vn.z); vert = f->getVert(vx2); vn = GetVertexNormal(mesh, i, mesh->getRVertPtr(vert)); temp = vn.z; vn.z = -vn.y; vn.y = temp; vn = rotMatrix * vn; fprintf(pStream,"%s\t\t%.6f;%.6f;%.6f;,\n", indent.data(), vn.x, vn.y, vn.z); vert = f->getVert(vx3); vn = GetVertexNormal(mesh, i, mesh->getRVertPtr(vert)); temp = vn.z; vn.z = -vn.y; vn.y = temp; vn = rotMatrix * vn; fprintf(pStream,"%s\t\t%.6f;%.6f;%.6f;%s\n", indent.data(), vn.x, vn.y, vn.z, i == numLoop - 1 ? ";\n" : ","); } // write number of faces fprintf(pStream, "%s\t\t%d;\n", indent.data(), numLoop); // write faces for (i = 0; i < numLoop; i++) { fprintf(pStream, "%s\t\t%d;3;%d,%d,%d;%s\n", indent.data(), i, i * 3 + vx1, i * 3 + vx2, i * 3 + vx3, i == numLoop - 1 ? ";\n" : ","); } // normals close brace fprintf(pStream, "%s\t}\n\n",indent.data()); // texcoords if (nodeMtl && mesh && (nodeMtl->Requirements(-1) & MTLREQ_FACEMAP)) { // facemapping numLoop = mesh->getNumFaces() * 3; // write texture coords header fprintf(pStream, "%s\tSI_MeshTextureCoords {\n", indent.data()); // write number of texture coords fprintf(pStream, "%s\t\t%d;\n", indent.data(), numLoop); // write texture coords for (int i = 0; i < numLoop; i++) { Point3 tv[3]; Face * f = &mesh->faces[i]; make_face_uv( f, tv); fprintf(pStream, "%s\t\t%.6f;%.6f;,\n", indent.data(), tv[0].x, tv[0].y); fprintf(pStream, "%s\t\t%.6f;%.6f;,\n", indent.data(), tv[1].x, tv[1].y); fprintf(pStream, "%s\t\t%.6f;%.6f;%s\n", indent.data(), tv[2].x, tv[2].y, i == numLoop - 1 ? ";\n" : ","); } // write number of faces numLoop = mesh->getNumFaces(); fprintf(pStream, "%s\t\t%d;\n", indent.data(), numLoop); // write faces for (i = 0; i < numLoop; i++) { fprintf(pStream,"%s\t\t%d;3;%d,%d,%d;%s\n", indent.data(), i, mesh->tvFace[i].t[vx1], mesh->tvFace[i].t[vx2], mesh->tvFace[i].t[vx3], i == numLoop - 1 ? ";\n" : ","); } // texture coords close brace fprintf(pStream, "%s\t}\n\n", indent.data()); } else { numLoop = mesh->getNumTVerts(); if (numLoop) { // write texture coords header fprintf(pStream, "%s\tSI_MeshTextureCoords {\n", indent.data()); // write number of texture coords fprintf(pStream, "%s\t\t%d;\n", indent.data(), numLoop); // write texture coords for (i = 0; i < numLoop; i++) { UVVert tv = mesh->tVerts[i]; fprintf(pStream, "%s\t\t%.6f;%.6f;%s\n", indent.data(), tv.x, tv.y, i == numLoop - 1 ? ";\n" : ","); } // write number of faces numLoop = mesh->getNumFaces(); fprintf(pStream, "%s\t\t%d;\n", indent.data(), numLoop); // write faces for (i = 0; i < numLoop; i++) { fprintf(pStream,"%s\t\t%d;3;%d,%d,%d;%s\n", indent.data(), i, mesh->tvFace[i].t[vx1], mesh->tvFace[i].t[vx2], mesh->tvFace[i].t[vx3], i == numLoop - 1 ? ";\n" : ","); } // texture coords close brace fprintf(pStream, "%s\t}\n\n", indent.data()); } } /* // Export color per vertex info if (GetIncludeVertexColors()) { int numCVx = mesh->numCVerts; fprintf(pStream, "%s\t%s %d\n",indent.data(), ID_MESH_NUMCVERTEX, numCVx); if (numCVx) { fprintf(pStream,"%s\t%s {\n",indent.data(), ID_MESH_CVERTLIST); for (i=0; i<numCVx; i++) { Point3 vc = mesh->vertCol[i]; fprintf(pStream, "%s\t\t%s %d\t%s\n",indent.data(), ID_MESH_VERTCOL, i, Format(vc)); } fprintf(pStream,"%s\t}\n",indent.data()); fprintf(pStream, "%s\t%s %d\n",indent.data(), ID_MESH_NUMCVFACES, mesh->getNumFaces()); fprintf(pStream, "%s\t%s {\n",indent.data(), ID_MESH_CFACELIST); for (i=0; i<mesh->getNumFaces(); i++) { fprintf(pStream,"%s\t\t%s %d\t%d\t%d\t%d\n", indent.data(), ID_MESH_CFACE, i, mesh->vcFace[i].t[vx1], mesh->vcFace[i].t[vx2], mesh->vcFace[i].t[vx3]); } fprintf(pStream, "%s\t}\n",indent.data()); } } */ // Mesh close brace fprintf(pStream, "%s}\n",indent.data()); // dispose of tri object if (needDel) { delete tri; } }
// Get hold of the transform controllers for the node... void XsiExp::ExportAnimKeys( INode * node, int & animHit) { // Targets are actually geomobjects, but we will export them // from the camera and light objects, so we skip them here. // Object * obj = node->EvalWorldState(GetStaticFrame()).obj; if (!obj || obj->ClassID() == Class_ID( TARGET_CLASS_ID, 0)) { return; } TSTR indent = GetIndent(1); BOOL bPosAnim, bRotAnim, bScaleAnim, bDoKeys = FALSE; TCHAR * name = FixupName( node->GetName()); BOOL isBone = obj->ClassID() == Class_ID(BONE_CLASS_ID, 0) ? TRUE : FALSE; if (isBone) { // bone anims get passed to children if (!node->GetParentNode() || node->GetParentNode()->IsRootNode()) { // can't anim top bone return; } node = node->GetParentNode(); } // We can only export keys if all TM controllers are "known" to us. // The reason for that is that some controllers control more than what // they should. Consider a path position controller, if you turn on // follow and banking, this position controller will also control // rotation. If a node that had a path position controller also had a // TCB rotation controller, the TCB keys would not describe the whole // rotation of the node. // For that reason we will only export keys if all controllers // position, rotation and scale are linear, hybrid (bezier) or tcb. if (!GetAlwaysSample()) { Control* pC = node->GetTMController()->GetPositionController(); Control* rC = node->GetTMController()->GetRotationController(); Control* sC = node->GetTMController()->GetScaleController(); if (IsKnownController(pC) && IsKnownController(rC) && IsKnownController(sC)) { bDoKeys = TRUE; } } if (bDoKeys) { // Only dump the track header if any of the controllers have keys if (node->GetTMController()->GetPositionController()->NumKeys() > 1 || node->GetTMController()->GetRotationController()->NumKeys() > 1 || node->GetTMController()->GetScaleController()->NumKeys() > 1) { if (!animHit) { fprintf(pStream,"AnimationSet {\n"); animHit = TRUE; } fprintf(pStream,"%sAnimation anim-%s {\n", indent.data(), name ); indent = GetIndent(2); fprintf(pStream,"%s{frm-%s}\n", indent.data(), name ); DumpRotKeys( node, 1); DumpPosKeys( node, 1); DumpScaleKeys( node, 1); indent = GetIndent(1); fprintf(pStream,"%s}\n\n", indent.data()); } } else if (CheckForAnimation(node, bPosAnim, bRotAnim, bScaleAnim)) { if (!animHit) { fprintf(pStream,"AnimationSet {\n"); animHit = TRUE; } fprintf(pStream,"%sAnimation anim-%s {\n", indent.data(), name ); indent = GetIndent(2); fprintf(pStream,"%s{frm-%s}\n", indent.data(), name ); DumpRotKeys( node, 1); DumpPosKeys( node, 1); DumpScaleKeys( node, 1); fprintf(pStream,"%s}\n", indent.data()); } }
void AWDExporter::ExportMaterial( AWD *awd, awd_ncache *ncache, Mtl* mtl, int mtlID, int subNo) { TimeValue t = GetStaticFrame(); int i; BOOL usediffusemap = FALSE; const char *name = mtl->GetName(); int namelen = strlen( name ); AWDMaterial *material = new AWDMaterial( AWD_MATTYPE_COLOR, name, namelen ); AWDTexture *tex; for (i=0; i<mtl->NumSubTexmaps(); i++) { Texmap* subTex = mtl->GetSubTexmap(i); float amt = 1.0f; if (subTex) { // If it is a standard material we can see if the map is enabled. if (mtl->ClassID() == Class_ID(DMTL_CLASS_ID, 0)) { if (!((StdMat*)mtl)->MapEnabled(i)) continue; amt = ((StdMat*)mtl)->GetTexmapAmt(i, 0); } tex = ExportTexture(awd, ncache, subTex, mtl->ClassID(), i, material ); if( tex && i == ID_DI ) { usediffusemap = true; } } } if (mtl->ClassID() == Class_ID(DMTL_CLASS_ID, 0)) { StdMat* std = (StdMat*)mtl; material->color = get_awd_color( std->GetDiffuse(t), 1.0f ); } else { material->color = get_awd_color( mtl->GetDiffuse(), 1.0f ); } AWD_mat_type mattype; if( usediffusemap ) mattype = AWD_MATTYPE_BITMAP; else mattype = AWD_MATTYPE_COLOR; material->set_type( mattype ); awd_ncache_add(ncache, (InterfaceServer*)mtl, material); awd->add_material( material ); if (mtl->NumSubMtls() > 0) { for (i=0; i<mtl->NumSubMtls(); i++) { Mtl* subMtl = mtl->GetSubMtl(i); if (subMtl && mtlList.GetMtlID( subMtl ) == -1 ) { ExportMaterial(awd, ncache, subMtl, 0, i); } } } }
AWDTexture * AWDExporter::ExportTexture(AWD *awd, awd_ncache *ncache,Texmap* tex, Class_ID cid, int subNo, AWDMaterial * mat ) { AWDTexture *awd_tex; const char* name; int name_len; bool hasAlpha = false; MSTR path; awd_uint8 * buf; int buf_len; if (!tex) return NULL; if (tex->ClassID() != Class_ID(BMTEX_CLASS_ID, 0x00) ) return NULL; // texture already exist in cache awd_tex = (AWDTexture *)awd_ncache_get( ncache, tex ); if( awd_tex ) return awd_tex; BitmapTex *bmptex = (BitmapTex*)tex; MaxSDK::AssetManagement::AssetUser asset = bmptex->GetMap(); hasAlpha = bmptex->GetBitmap( GetStaticFrame() )->HasAlpha(); if( !asset.GetFullFilePath(path) ) { fprintf( logfile, " export !asset.GetFullFilePath(path) : %i \n", asset.GetType() ); fflush( logfile ); //return NULL; } fprintf( logfile, " export : %s \n", path ); fflush( logfile ); AWD_tex_type textype = EXTERNAL; if( GetIncludeMaps() && asset.GetType() == MaxSDK::AssetManagement::kBitmapAsset ) { const char * dot; dot = strrchr(path,'.'); if( !strcmp(dot, ".jpg")|| !strcmp(dot, ".JPG")|| !strcmp(dot, ".jpeg")|| !strcmp(dot, ".JPEG") ) { textype = EMBEDDED_JPEG; } else if ( !strcmp(dot, ".png")|| !strcmp(dot, ".PNG") ) { textype = EMBEDDED_PNG; } if( textype == 0 ) { fprintf( logfile, " export texture : %s \n", path ); fflush( logfile ); // try to extract data Bitmap *bmp = bmptex->GetBitmap( GetStaticFrame() ); BitmapInfo bi; MaxSDK::Util::Path *temppath; bi.SetWidth( bmp->Width() ); bi.SetHeight( bmp->Height() ); if( hasAlpha ) { bi.SetType( BMM_TRUE_32 ); bi.SetFlags( MAP_HAS_ALPHA ); path = "C:\\Users\\lepersp\\Desktop\\temp\\awdexporttempjpg.png"; textype = EMBEDDED_PNG; } else { bi.SetType( BMM_TRUE_24 ); path = "C:\\Users\\lepersp\\Desktop\\temp\\awdexporttempjpg.jpg"; textype = EMBEDDED_JPEG; } temppath = new MaxSDK::Util::Path( path ); bi.SetPath( *temppath ); bmp->OpenOutput( & bi ); bmp->Write( & bi ); bmp->Close(& bi); } if( path != NULL ) { size_t result; int fd; errno_t err = _sopen_s( &fd, path, _O_RDONLY|_O_BINARY, _SH_DENYNO, _S_IREAD ); if( err == 0 ) { struct stat *s; s = (struct stat *)malloc(sizeof(struct stat)); fstat(fd, s); buf_len = s->st_size; buf = (awd_uint8 *) malloc (buf_len * sizeof( awd_uint8 ) ); lseek(fd, 0, SEEK_SET); result = read(fd, buf, buf_len); if (result != buf_len) { textype = EXTERNAL; } _close( fd ); } else { textype = EXTERNAL; } } } name = tex->GetName(); name_len = strlen( name ); char* namecpy = (char*) malloc( name_len*sizeof( char ) ) ; strcpy( namecpy, name ); awd_tex = new AWDTexture( textype, namecpy, name_len ); if( textype != 0 ) { awd_tex->set_embed_data(buf, buf_len); } char * pathcpy = (char *) malloc( (path.length()+1) * sizeof( char ) ); strcpy( pathcpy, path.data() ); awd_tex->set_url( pathcpy, strlen( pathcpy ) ); awd->add_texture( awd_tex ); awd_ncache_add( ncache, tex, awd_tex ); if( subNo == ID_DI ) { mat->set_texture( awd_tex ); mat->alpha_blending = hasAlpha; } return awd_tex; }