void DxStdMtl2::Draw() { bool NegScale; if(!IsDxMaterialEnabled(map)) return; TimeValue m_T = GetCOREInterface()->GetTime(); NegScale = TMNegParity(mpMeshCache->GetActiveNode(m_CurCache)->GetObjTMAfterWSM(m_T)); Mtl * m_Mtl = mpMeshCache->GetActiveNode(m_CurCache)->GetMtl(); Color col = GetCOREInterface()->GetViewportBGColor(); D3DCOLOR bkgColor = col.toRGB(); if(!pd3dDevice) pd3dDevice = GetDevice(); int w =0, h =0; myGWindow->GetWindowDimension(w,h); SetRenderStates(); if(pEffectParser) { SetEffectData(); if(!pEffectParser->PreRender(pd3dDevice,mpMeshCache->GetActiveRenderMesh(m_CurCache),this,this,bkgColor, w,h)) { DrawError(); return; } if(!mpMeshCache->GetActiveRenderMesh(m_CurCache)->Evaluate(pd3dDevice, mpMeshCache->GetActiveMesh(m_CurCache),GetMatIndex(m_Mtl),NegScale)) return; if(!pEffectParser->Render(pd3dDevice,mpMeshCache->GetActiveRenderMesh(m_CurCache),techniqueName.data())) { DrawError(); return; } } //draw the object in Red WireFrame mode for testing purposes else { DrawError(); } }
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; } }
bool Exporter::splitMesh(INode *node, Mesh& mesh, FaceGroups &grps, TimeValue t, vector<Color4>& vertColors, bool noSplit) { Mtl* nodeMtl = node->GetMtl(); Matrix3 tm = node->GetObjTMAfterWSM(t); // Order of the vertices. Get 'em counter clockwise if the objects is // negatively scaled. int vi[3]; if (TMNegParity(tm)) { vi[0] = 2; vi[1] = 1; vi[2] = 0; } else { vi[0] = 0; vi[1] = 1; vi[2] = 2; } Matrix3 flip; flip.IdentityMatrix(); flip.Scale(Point3(1, -1, 1)); int nv = mesh.getNumVerts(); int nf = mesh.getNumFaces(); if (noSplit) { int nv = mesh.getNumVerts(); int nf = mesh.getNumFaces(); // Dont split the mesh at all. For debugging purposes. FaceGroup& grp = grps[0]; grp.vidx.resize(nv, -1); grp.verts.resize(nv); grp.faces.resize(nf); grp.uvs.resize(nv); grp.vnorms.resize(nv); grp.fidx.resize(nf); Matrix3 texm; getTextureMatrix(texm, getMaterial(node, 0)); texm *= flip; for (int face=0; face<nf; ++face) { grp.fidx[face] = face; for (int vi=0; vi<3; ++vi) { int idx = mesh.faces[face].getVert(vi); grp.faces[face][vi] = idx; // Calculate normal Point3 norm; #if VERSION_3DSMAX <= ((5000<<16)+(15<<8)+0) // Version 5 norm = getVertexNormal(&mesh, face, mesh.getRVertPtr(idx)); #else MeshNormalSpec *specNorms = mesh.GetSpecifiedNormals (); if (NULL != specNorms && specNorms->GetNumNormals() != 0) norm = specNorms->GetNormal(face, vi); else norm = getVertexNormal(&mesh, face, mesh.getRVertPtr(idx)); #endif Point3 uv; if (mesh.tVerts && mesh.tvFace) { uv = mesh.tVerts[ mesh.tvFace[ face ].t[ vi ]] * texm; uv.y += 1.0f; } if (grp.vidx[idx] == idx){ ASSERT(grp.verts[idx] == TOVECTOR3(mesh.getVert(idx))); //ASSERT(vg.norm == norm); //Point3 uv = mesh.getTVert(idx); //if (mesh.getNumTVerts() > 0) //{ // ASSERT(grp.uvs[idx].u == uv.x && grp.uvs[idx].v == uv.y); //} } else { grp.vidx[idx] = idx; grp.verts[idx] = TOVECTOR3(mesh.getVert(idx)); //grp.uvs[idx].u = uv.x; //grp.uvs[idx].v = uv.y; grp.vnorms[idx] = TOVECTOR3(norm); } } } for (int i=0; i<nv; ++i) { ASSERT(grp.vidx[i] != -1); } } else { int face, numSubMtls = nodeMtl?nodeMtl->NumSubMtls():0; for (face=0; face<mesh.getNumFaces(); face++) { int mtlID = (numSubMtls!=0) ? (mesh.faces[face].getMatID() % numSubMtls) : 0; Mtl *mtl = getMaterial(node, mtlID); Matrix3 texm; getTextureMatrix(texm, mtl); texm *= flip; FaceGroup& grp = grps[mtlID]; if (grp.uvMapping.size() == 0) // Only needs to be done once per face group { int nmaps = 0; int nmapsStart = max(1, mesh.getNumMaps() - (mesh.mapSupport(0) ? 1 : 0)); // Omit vertex color map. for (int ii = 1; ii <= nmapsStart; ii++) // Winnow out the unsupported maps. { if (!mesh.mapSupport(ii)) continue; grp.uvMapping[ii] = nmaps++; } grp.uvs.resize(nmaps == 0 ? 1 : nmaps); } if (nv > int(grp.verts.capacity())) { grp.vgrp.reserve(nv); grp.verts.reserve(nv); grp.vnorms.reserve(nv); for (int i=0; i<grp.uvs.size(); ++i) grp.uvs[i].reserve(nv); grp.vcolors.reserve(nv); grp.vidx.reserve(nv); } if (nf > int(grp.faces.capacity())) { grp.faces.reserve(nf); grp.fidx.reserve(nf); } Triangle tri; for (int i=0; i<3; i++) tri[i] = addVertex(grp, face, vi[i], &mesh, texm, vertColors); grp.faces.push_back(tri); if (grp.fidx.size() < nf) grp.fidx.resize(nf,-1); grp.fidx[face] = grp.faces.size() - 1; } } return true; }
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; } }