void Spinner::ExportMesh(FILE *f) { char name[MAX_PATH]; char subObjName[MAX_PATH]; WideCharToMultiByte(CP_ACP, 0, m_wzName, -1, name, MAX_PATH, NULL, NULL); std::vector<Vertex3D_NoTex2> transformedVertices; vector<HitObject*> dummyHitObj; const float height = m_ptable->GetSurfaceHeight(m_d.m_szSurface, m_d.m_vCenter.x, m_d.m_vCenter.y)*m_ptable->m_BG_scalez[m_ptable->m_BG_current_set]; m_posZ = height + m_d.m_height; GetHitShapes(dummyHitObj); if (m_d.m_fShowBracket) { strcpy_s(subObjName, name); strcat_s(subObjName, "Bracket"); WaveFrontObj_WriteObjectName(f, subObjName); fullMatrix.RotateZMatrix(ANGTORAD(m_d.m_rotation)); transformedVertices.resize(spinnerBracketNumVertices); for (int i = 0; i < spinnerBracketNumVertices; i++) { Vertex3Ds vert(spinnerBracket[i].x, spinnerBracket[i].y, spinnerBracket[i].z); vert = fullMatrix.MultiplyVector(vert); transformedVertices[i].x = vert.x*m_d.m_length + m_d.m_vCenter.x; transformedVertices[i].y = vert.y*m_d.m_length + m_d.m_vCenter.y; transformedVertices[i].z = vert.z*m_d.m_length*m_ptable->m_BG_scalez[m_ptable->m_BG_current_set] + m_posZ; vert = Vertex3Ds(spinnerBracket[i].nx, spinnerBracket[i].ny, spinnerBracket[i].nz); vert = fullMatrix.MultiplyVectorNoTranslate(vert); transformedVertices[i].nx = vert.x; transformedVertices[i].ny = vert.y; transformedVertices[i].nz = vert.z; transformedVertices[i].tu = spinnerBracket[i].tu; transformedVertices[i].tv = spinnerBracket[i].tv; } WaveFrontObj_WriteVertexInfo(f, transformedVertices.data(), spinnerBracketNumVertices); const Material * mat = m_ptable->GetMaterial(m_d.m_szMaterial); WaveFrontObj_WriteMaterial(m_d.m_szMaterial, NULL, mat); WaveFrontObj_UseTexture(f, m_d.m_szMaterial); WaveFrontObj_WriteFaceInfoList(f, spinnerBracketIndices, spinnerBracketNumFaces); WaveFrontObj_UpdateFaceOffset(spinnerBracketNumVertices); transformedVertices.clear(); } transformedVertices.resize(spinnerPlateNumVertices); vertexBuffer_spinneranimangle = -FLT_MAX; UpdatePlate(transformedVertices.data()); strcpy_s(subObjName, name); strcat_s(subObjName, "Plate"); WaveFrontObj_WriteObjectName(f, subObjName); WaveFrontObj_WriteVertexInfo(f, transformedVertices.data(), spinnerPlateNumVertices); WaveFrontObj_WriteFaceInfoList(f, spinnerPlateIndices, spinnerPlateNumFaces); WaveFrontObj_UpdateFaceOffset(spinnerPlateNumVertices); transformedVertices.clear(); }
// exporting a mesh to a Wavefront .OBJ file. The mesh is converted into right-handed coordinate system (VP uses left-handed) void WaveFrontObj_Save(const char *filename, const char *description, const Mesh& mesh) { FILE *f; /* f = fopen(filename, "wt"); fprintf_s(f,"const unsigned int hitTargetT2Vertices=%i;\n",mesh.NumVertices()); fprintf_s(f,"const unsigned int hitTargetT2NumFaces=%i;\n", mesh.NumIndices()); fprintf_s(f,"Vertex3D_NoTex2 hitTargetT2Mesh[%i]=\n{\n",mesh.NumVertices()); for (int i=0; i<mesh.NumVertices(); i++) { fprintf_s(f,"{ %ff,%ff,%ff, %ff,%ff,%ff, %ff,%ff},\n",mesh.m_vertices[i].x, mesh.m_vertices[i].y,mesh.m_vertices[i].z, mesh.m_vertices[i].nx, mesh.m_vertices[i].ny,mesh.m_vertices[i].nz, mesh.m_vertices[i].tu, mesh.m_vertices[i].tv); } fprintf_s(f,"};\nWORD hitTargetT2Indices[%i]=\n{\n ",mesh.NumIndices()); int ofs=0; for (int i=0; i<mesh.NumIndices(); i++) { fprintf_s(f,"%i,",mesh.m_indices[i]); ofs++; if (ofs==15) { ofs=0; fprintf_s(f,"\n "); } } fprintf_s(f,"\n};"); fclose(f); return; */ if (mesh.m_animationFrames.size() == 0) { f = WaveFrontObj_ExportStart(filename); if (!f) return; fprintf_s(f, "# Visual Pinball OBJ file\n"); fprintf_s(f, "# numVerts: %u numFaces: %u\n", (unsigned int)mesh.NumVertices(), (unsigned int)mesh.NumIndices()); WaveFrontObj_WriteObjectName(f, description); WaveFrontObj_WriteVertexInfo(f, mesh.m_vertices.data(), (unsigned int)mesh.m_vertices.size()); WaveFrontObj_WriteFaceInfoLong(f, mesh.m_indices); WaveFrontObj_ExportEnd(f); } else { string fname(filename); std::size_t pos = fname.find_last_of("."); string name = fname.substr(0, pos); char number[32] = { 0 }; for (unsigned int i = 0; i < mesh.m_animationFrames.size(); i++) { std::vector<Vertex3D_NoTex2> vertsTmp = mesh.m_vertices; for (unsigned int t = 0; t < mesh.NumVertices(); t++) { vertsTmp[t].x = mesh.m_animationFrames[i].m_frameVerts[t].x; vertsTmp[t].y = mesh.m_animationFrames[i].m_frameVerts[t].y; vertsTmp[t].z = mesh.m_animationFrames[i].m_frameVerts[t].z; vertsTmp[t].nx = mesh.m_animationFrames[i].m_frameVerts[t].nx; vertsTmp[t].ny = mesh.m_animationFrames[i].m_frameVerts[t].ny; vertsTmp[t].nz = mesh.m_animationFrames[i].m_frameVerts[t].nz; } sprintf_s(number, "%05u", i); fname = name + "_" + string(number) + ".obj"; f = WaveFrontObj_ExportStart(fname.c_str()); if (!f) return; fprintf_s(f, "# Visual Pinball OBJ file\n"); fprintf_s(f, "# numVerts: %u numFaces: %u\n", (unsigned int)mesh.NumVertices(), (unsigned int)mesh.NumIndices()); WaveFrontObj_WriteObjectName(f, description); WaveFrontObj_WriteVertexInfo(f, vertsTmp.data(), (unsigned int)mesh.m_vertices.size()); WaveFrontObj_WriteFaceInfoLong(f, mesh.m_indices); WaveFrontObj_ExportEnd(f); } } }
void Bumper::ExportMesh(FILE *f) { char name[MAX_PATH]; char subObjName[MAX_PATH]; WideCharToMultiByte(CP_ACP, 0, m_wzName, -1, name, MAX_PATH, NULL, NULL); m_baseHeight = m_ptable->GetSurfaceHeight(m_d.m_szSurface, m_d.m_vCenter.x, m_d.m_vCenter.y) * m_ptable->m_BG_scalez[m_ptable->m_BG_current_set]; m_fullMatrix.RotateZMatrix(ANGTORAD(m_d.m_orientation)); if (m_d.m_fBaseVisible) { Vertex3D_NoTex2 *base = new Vertex3D_NoTex2[bumperBaseNumVertices]; strcpy_s(subObjName, name); strcat_s(subObjName, "Base"); WaveFrontObj_WriteObjectName(f, subObjName); GenerateBaseMesh(base); WaveFrontObj_WriteVertexInfo(f, base, bumperBaseNumVertices); const Material * mat = m_ptable->GetMaterial(m_d.m_szBaseMaterial); WaveFrontObj_WriteMaterial(m_d.m_szBaseMaterial, NULL, mat); WaveFrontObj_UseTexture(f, m_d.m_szBaseMaterial); WaveFrontObj_WriteFaceInfoList(f, bumperBaseIndices, bumperBaseNumFaces); WaveFrontObj_UpdateFaceOffset(bumperBaseNumVertices); delete[] base; } if (m_d.m_fRingVisible) { Vertex3D_NoTex2 *ring = new Vertex3D_NoTex2[bumperRingNumVertices]; strcpy_s(subObjName, name); strcat_s(subObjName, "Ring"); WaveFrontObj_WriteObjectName(f, subObjName); GenerateRingMesh(ring); WaveFrontObj_WriteVertexInfo(f, ring, bumperRingNumVertices); WaveFrontObj_WriteFaceInfoList(f, bumperRingIndices, bumperRingNumFaces); WaveFrontObj_UpdateFaceOffset(bumperRingNumVertices); delete[] ring; } if (m_d.m_fSkirtVisible) { Vertex3D_NoTex2 *socket = new Vertex3D_NoTex2[bumperSocketNumVertices]; strcpy_s(subObjName, name); strcat_s(subObjName, "Socket"); WaveFrontObj_WriteObjectName(f, subObjName); GenerateSocketMesh(socket); WaveFrontObj_WriteVertexInfo(f, socket, bumperSocketNumVertices); const Material * mat = m_ptable->GetMaterial(m_d.m_szSkirtMaterial); WaveFrontObj_WriteMaterial(m_d.m_szSkirtMaterial, NULL, mat); WaveFrontObj_UseTexture(f, m_d.m_szSkirtMaterial); WaveFrontObj_WriteFaceInfoList(f, bumperSocketIndices, bumperSocketNumFaces); WaveFrontObj_UpdateFaceOffset(bumperSocketNumVertices); delete[] socket; } if (m_d.m_fCapVisible) { Vertex3D_NoTex2 *cap = new Vertex3D_NoTex2[bumperCapNumVertices]; strcpy_s(subObjName, name); strcat_s(subObjName, "Cap"); WaveFrontObj_WriteObjectName(f, subObjName); GenerateCapMesh(cap); WaveFrontObj_WriteVertexInfo(f, cap, bumperCapNumVertices); const Material * const mat = m_ptable->GetMaterial(m_d.m_szCapMaterial); WaveFrontObj_WriteMaterial(m_d.m_szCapMaterial, NULL, mat); WaveFrontObj_UseTexture(f, m_d.m_szCapMaterial); WaveFrontObj_WriteFaceInfoList(f, bumperCapIndices, bumperCapNumFaces); WaveFrontObj_UpdateFaceOffset(bumperCapNumVertices); delete[] cap; } }