bool CTriangleObj::saveMeshWavefrontObj(const char *fname, const double *matrix) { int i; Vector3d *pVertex = new Vector3d[m_nVertexCount]; assert(pVertex!=NULL); for (i=0; i<m_nVertexCount; i++) TransformVertex3dToVertex3d(m_pVertex[i], matrix, &pVertex[i].x); vector<OglMaterial> mats; std::string objname = GetObjectName(); if (objname.empty()) objname+="defaultname"; Vector3f *pNormal = m_pVertexNorm; if (pNormal==NULL){ ComputeVertexNormals(); pNormal = m_pVertexNorm; assert(pNormal!=NULL); } vector<Vector3f> texCoords; unsigned int faceMatIndex[2], nFaceMatIndex=0; const Vector3i *pTexIndex = NULL; const bool r = writeOBJFile(fname, objname, mats, pVertex, m_nVertexCount, pNormal, m_nVertexCount, texCoords, (const Vector3i*)m_pPolygon, m_nPolygonCount, pTexIndex, faceMatIndex, nFaceMatIndex); delete [] pVertex; return r; }
Solid *ConstructHalfEdge_ModelFromOBJ_WStatus( char *FileName ) { struct _Model *m; FILE *file; Solid *s; int i; /* open the file */ file = fopen(FileName, "r"); if (!file) return NULL; /* load the OBJ, unitize it, compute facet normals, etc */ m = (struct _Model *) malloc( sizeof( struct _Model ) ); memset( m, 0, sizeof( struct _Model ) ); m->file = strdup( FileName ); ReadOBJFirstPass( m, file ); rewind(file); ReadOBJSecondPass( m, file ); Unitize_Model( m ); ComputeFacetNormals( m ); ComputeVertexNormals( m ); fclose( file ); s = SolidNew( ); for (i=0; i< m->numVertices; i++) VertexConstructN( &s, m->vertexPos[3*i+0], m->vertexPos[3*i+1], m->vertexPos[3*i+2], m->normList[3*i+0], m->normList[3*i+1], m->normList[3*i+2] ); printf(" (-) Constructing faces (%8.4f%% done)...", 0.0f ); fflush( stdout ); for (i=0; i< m->numTriangles; i++) { Vertex *va = VertexListIndex( s, m->triVertexIndex[3*i+0] ); Vertex *vb = VertexListIndex( s, m->triVertexIndex[3*i+1] ); Vertex *vc = VertexListIndex( s, m->triVertexIndex[3*i+2] ); FaceConstruct( &s, va, vb, vc); if (i%1000 == 0) { printf("\r (-) Constructing faces (%8.4f%% done)...", 100.0f*((float)i/m->numTriangles) ); fflush( stdout ); } } printf("\r (-) Constructing faces (%8.4f%% done)...\n", 100.0f ); fflush( stdout ); EdgeListConstructVerbose(&s, m->numTriangles); return s; }
Solid *ConstructHalfEdge_ModelFromOBJ( char *FileName ) { struct _Model *m; FILE *file; Solid *s; int i; /* open the file */ file = fopen(FileName, "r"); if (!file) return NULL; /* load the OBJ, unitize it, compute facet normals, etc */ m = (struct _Model *) malloc( sizeof( struct _Model ) ); memset( m, 0, sizeof( struct _Model ) ); m->file = strdup( FileName ); ReadOBJFirstPass( m, file ); rewind(file); ReadOBJSecondPass( m, file ); Unitize_Model( m ); ComputeFacetNormals( m ); ComputeVertexNormals( m ); fclose( file ); s = SolidNew( ); for (i=0; i< m->numVertices; i++) VertexConstructN( &s, m->vertexPos[3*i+0], m->vertexPos[3*i+1], m->vertexPos[3*i+2], m->normList[3*i+0], m->normList[3*i+1], m->normList[3*i+2] ); for (i=0; i< m->numTriangles; i++) { Vertex *va = VertexListIndex( s, m->triVertexIndex[3*i+0] ); Vertex *vb = VertexListIndex( s, m->triVertexIndex[3*i+1] ); Vertex *vc = VertexListIndex( s, m->triVertexIndex[3*i+2] ); FaceConstruct( &s, va, vb, vc); } EdgeListConstruct(&s); return s; }
void RenderMesh::ConvertFaces(Mesh *Mesh, int MatIndex, Tab<Vert3> &Verts, Tab<Face3> &Faces, bool NegScale) { Face3 TmpFace; Vert3 TmpVert; BitArray Written; int i,j,k,NumFace; int NumUV,UVCount,Index; int NumVert,Count,VIndex; Face *aFace; Tab<BasisVert> FNormals; Tab<VNormal> Normals; UVVert *UVVert; TVFace *UVFace; Point3 S,T,SxT; unsigned long Sg; bool useMeshNorms = false; if(NegScale) { gVIndex[0] = 2; gVIndex[1] = 1; gVIndex[2] = 0; } else { gVIndex[0] = 0; gVIndex[1] = 1; gVIndex[2] = 2; } // Do we have an EditNormal modifier present - if so we use those normals instead. // We only use this if they have been applied on a face with smoothing groups, otherwise // it messes up the tangent space calculation. Probably not the most obtmized route, but it // works... MeshNormalSpec * meshNorm = Mesh->GetSpecifiedNormals(); if(meshNorm && meshNorm->GetNumNormals()) useMeshNorms = true; NumFace = 0; for(i=0; i < Mesh->getNumFaces(); i++) { if(!Mesh->faces[i].Hidden()) { Index = Mesh->getFaceMtlIndex(i) + 1; if(Index == MatIndex || MatIndex == 0) { NumFace++; } } } NumVert = Mesh->getNumVerts(); Verts.SetCount(NumVert); Faces.SetCount(NumFace); if(NumVert == 0 || NumFace == 0) { return; } ComputeVertexNormals(Mesh,FNormals,Normals,NegScale); Written.SetSize(Mesh->getNumVerts()); Written.ClearAll(); NumUV = Mesh->getNumMaps(); if(NumUV) { Count = 0; if(NumUV > MAX_TMUS + 1) { NumUV = MAX_TMUS + 1; } for(i=0; i < Mesh->getNumFaces(); i++) { aFace = &Mesh->faces[i]; TmpFace.m_Num[0] = aFace->v[gVIndex[0]]; TmpFace.m_Num[1] = aFace->v[gVIndex[1]]; TmpFace.m_Num[2] = aFace->v[gVIndex[2]]; Sg = aFace->smGroup; for(j=0; j < 3; j++) { VIndex = aFace->v[gVIndex[j]]; TmpVert.m_Pos = Mesh->verts[VIndex]; if(Sg) { if(useMeshNorms) { int normID = meshNorm->Face(i).GetNormalID(gVIndex[j]); TmpVert.m_Normal = meshNorm->Normal(normID).Normalize(); Normals[VIndex].GetNormal(Sg,S,T,SxT); } else TmpVert.m_Normal = Normals[VIndex].GetNormal(Sg,S,T,SxT); TmpVert.m_S = S; TmpVert.m_T = T; TmpVert.m_SxT = SxT; } else { TmpVert.m_Normal = FNormals[i].m_Normal; TmpVert.m_S = FNormals[i].m_S; TmpVert.m_T = FNormals[i].m_T; TmpVert.m_SxT = FNormals[i].m_SxT; } UVCount = 0; TmpVert.m_Sg = Sg; for(k=0;k<m_MapChannels.Count();k++) { int index = m_MapChannels[k]; if(Mesh->getNumMapVerts(index)) { UVVert = Mesh->mapVerts(index); UVFace = Mesh->mapFaces(index); TmpVert.m_UV[k].x = UVVert[UVFace[i].t[gVIndex[j]]].x; TmpVert.m_UV[k].y = UVVert[UVFace[i].t[gVIndex[j]]].y; } else { TmpVert.m_UV[k].x = 0.0f; TmpVert.m_UV[k].y = 0.0f; } } if(Written[VIndex]) { if((Sg == 0) || (Verts[VIndex].m_Sg != TmpVert.m_Sg) || (!UVVertEqual(Verts[VIndex].m_UV[0],TmpVert.m_UV[0]))) { TmpFace.m_Num[j] = Verts.Count(); Verts.Append(1,&TmpVert,10); } } else { Verts[VIndex] = TmpVert; Written.Set(VIndex); } } if(!Mesh->faces[i].Hidden()) { Index = Mesh->getFaceMtlIndex(i) + 1; if(Index == MatIndex || MatIndex == 0) { Faces[Count++] = TmpFace; } } } } else { for(i=0; i < Mesh->getNumFaces(); i++) { aFace = &Mesh->faces[i]; Faces[i].m_Num[0] = aFace->v[gVIndex[0]]; Faces[i].m_Num[1] = aFace->v[gVIndex[1]]; Faces[i].m_Num[2] = aFace->v[gVIndex[2]]; for(j=0; j < 3; j++) { VIndex = aFace->v[gVIndex[j]]; Verts[VIndex].m_Pos = Mesh->verts[VIndex]; Verts[VIndex].m_Normal = Normals[VIndex].GetNormal(aFace->smGroup,S,T,SxT); Verts[VIndex].m_S = Point3(0.0f,0.0f,0.0f); Verts[VIndex].m_T = Point3(0.0f,0.0f,0.0f); Verts[VIndex].m_SxT = Point3(0.0f,0.0f,0.0f); for(k=0; k < MAX_TMUS; k++) { Verts[VIndex].m_UV[k].x = 0.0f; Verts[VIndex].m_UV[k].y = 0.0f; } } } } Verts.Shrink(); }
//-- // // Analysis // //-- bool MultiresolutionMesh::Analysis(int) { // // HSI // #ifdef _HSI_COLOR_ std::vector<Vector3d> color_backup; if( ColorNumber() == VertexNumber() ) { color_backup = colors; Vector3d tmp_hsi; for( int i=0; i<ColorNumber(); i++ ) { Rgb2Hsi( Color(i), tmp_hsi ); Color(i) = tmp_hsi; } } #endif // // RGB 2 Grayscale // #ifdef _RGB_2_GRAYSCALE_ std::vector<Vector3d> color_backup; if( ColorNumber() == VertexNumber() ) { color_backup = colors; double tmp; for( int i=0; i<ColorNumber(); i++ ) { tmp = (Color(i)[0]+Color(i)[1]+Color(i)[2])/3.0; Color(i) = tmp; } } #endif // Initialize member variables current_level_number = -1; levels.clear(); mean_curvature.clear(); gaussian_curvature.clear(); texture.Reset(); vertex_map.clear(); edge_list.clear(); // Initialize normals ComputeFaceNormals(); ComputeVertexNormals(); // Initialize progressive decomposition BeginProgressiveDecomposition(); // Initialize curvatures // mean_curvature.resize( VertexNumber() ); // gaussian_curvature.resize( VertexNumber() ); // ComputeMeanCurvature(); // ComputeGaussianCurvature(); // Initialize texture if( (TextureNumber()!=0) && (TextureName().empty()==false) ) { use_texture = texture.ReadFile( TextureName() ); } else { use_texture = false; } if( ColorNumber() == VertexNumber() ) { use_color = true; } else { use_color = false; } use_normal = true; // permutation.assign(VertexNumber(), -1); // map.assign( VertexNumber(), -1); // Initialize vertex map // This table indicates on which vertex each vertex has collapsed to vertex_map.resize( VertexNumber() ); for( int i=0; i<VertexNumber(); i++ ) { vertex_map[i] = i; } // std::cout<<bounding_box.Center()<<std::endl; // for( int i=0; i<VertexNumber(); i++ ) { // if( // Vertex(i)[0]>-0.01 && // Vertex(i)[2]>-0.01 && // Vertex(i)[0]<0.01 && // Vertex(i)[2]<0.01 // ) // std::cout<<i<<" "<<Vertex(i)<<std::endl; // } ConstPairContractionIterator itp; ConstNeighborIterator itn; std::vector<bool> locked_vertices(VertexNumber(), false); // levels.resize( base_level ); current_level_number = 0; //-- Test -- //int vnum = VertexNumber(); //timer.Reset(); //timer.Start(); //test<<current_level_number<<'\t'<<vnum<<endl; //-- #ifdef _OUTPUT_LEVELS_ // Write the finest level statistics std::ofstream level_stats_file("levels.log"); level_stats_file<<current_level_number<<'\t'<<ValidVertexNumber()<<'\t'<<ValidFaceNumber()<<std::endl; // Write the finest level mesh (the initial mesh) char filename[255]; sprintf(filename,"level%02d.wrl",current_level_number); WriteFile(filename); #endif // // Create the levels of details // while( 1 ) { // Add a new level levels.push_back( ResolutionLevel() ); // // Select the odd vertices // Remove the odd vertices // Lock the neighbors // Odd vertices are a set of independent vertices selected to be removed // The remaining (even) vertices compose the next coarse level // while( !pair_contractions.empty() ) { #ifdef _TEST_PLAN_ // Lock one predefined vertex locked_vertices[1844] = true; // plan-20000 // locked_vertices[30670] = true; // plan-irregulier #endif // Get pair contraction with minimum cost PairContraction pair = MinimumPairContraction(); // Remove pair from contraction candidate list RemovePairContraction( pair.Candidate() ); // Do not perform bad contraction until the level of detail is very low if( pair.Cost()>=invalid_contraction_penalty && current_level_number<15 ) { locked_vertices[pair.Candidate()] = true; continue; } // Test to see if after the pair contraction, // one vertex has a valence of 3 // This case screws up the predict operator itn = NeighborVertices(pair.Candidate()).begin(); while( itn != NeighborVertices(pair.Candidate()).end() ) { if(current_level_number<15 && NeighborVertexNumber(*itn)==4 && FindNeighborVertex(pair.Target(), *itn) && !IsBorderVertex(*itn)) { locked_vertices[pair.Candidate()] = true; } ++itn; } if( locked_vertices[pair.Candidate()] ) continue; // Map the candidate to the target vertex_map[pair.Candidate()] = pair.Target(); // Lock the selected vertex and its neighbors // valid_vertices[pair.Candidate()] = false; // Collapse candidate Collapse( pair ); // Update normals UpdateNormals( pair ); // Update quadrics UpdateQuadrics(pair); // Update pair cost of surronding vertices if( pair.Target() >= 0 ) { // Compute neighbor vertex cost itn = NeighborVertices(pair.Target()).begin(); while( itn != NeighborVertices(pair.Target()).end() ) { if( locked_vertices[*itn] == false ) { RemovePairContraction(*itn); ComputeEdgeCostAtVertex(*itn); } ++itn; } } // Lock the neighborhood of the selected vertex itn = NeighborVertices(pair.Candidate()).begin(); while( itn != NeighborVertices(pair.Candidate()).end() ) { // If the vertex is not already locked if( locked_vertices[*itn] == false ) { // Remove its pair contraction estimation RemovePairContraction(*itn); // Lock it locked_vertices[*itn] = true; } // Next neighbor ++itn; } // Record pair contraction levels[current_level_number].pair_contractions.push_front( pair ); } // bool left = false; int left_vertex_number = 0; // Compute new edge collapse pairs for(int i=0; i<VertexNumber(); i++ ) { if( valid_vertices[i] == false ) continue; left_vertex_number++; locked_vertices[i] = false; ComputeEdgeCostAtVertex(i); } // Update the normals ComputeProgressiveFaceNormals(); ComputeProgressiveVertexNormals(); // Next level current_level_number++; #ifdef _OUTPUT_LEVELS_ // Write the current level statistics level_stats_file<<current_level_number<<'\t'<<ValidVertexNumber()<<'\t'<<ValidFaceNumber()<<std::endl; // Write the current level mesh sprintf(filename,"level%02d.wrl",current_level_number); WriteFile(filename); #endif // Is there any vertex left ? // if( left_vertex_number == 0 ) break; // if( left_vertex_number < 100 ) break; if( left_vertex_number < 10 ) break; } // End the progressive decomposition EndProgressiveDecomposition(); // Reset locked_vertices.clear(); // // Go back the initial fine level // Reconstruct all levels // while( current_level_number > 0 ) { // Next level current_level_number--; // Insert odd vertices itp = levels[current_level_number].pair_contractions.begin(); while( itp != levels[current_level_number].pair_contractions.end() ) { // Expand candidate of current pair contraction Expand( *itp ); // Next pair contraction ++itp; } } // Update the normals ComputeProgressiveFaceNormals(); ComputeProgressiveVertexNormals(); for( int i=0; i<(int)levels.size(); i++ ) { levels[i].Resize( VertexNumber() ); } // // Compute the details // while( current_level_number < LevelNumber() ) { // // Predict odd vertices // itp = levels[current_level_number].pair_contractions.begin(); while( itp != levels[current_level_number].pair_contractions.end() ) { // Compute wavelet coefficient PredictVertex( itp->Candidate(), ODD_VERTEX ); // Invalidate the odd vertex valid_vertices[itp->Candidate()] = false; #ifdef _TEST_PLAN_ // Null the details levels[current_level_number].geometric_details[itp->Candidate()] = 0; #endif // Next pair contraction ++itp; } // // Predict even vertices // for(int i=0; i<VertexNumber(); i++ ) { // Valid vertex ? if( valid_vertices[i] == false ) continue; // Predict even vertex PredictVertex( i, EVEN_VERTEX ); #ifdef _TEST_PLAN_ // Null the details levels[current_level_number].geometric_details[i] = 0; #endif } // // Simplify // Removed odd vertices to go to next coarse level // itp = levels[current_level_number].pair_contractions.begin(); while( itp != levels[current_level_number].pair_contractions.end() ) { // Collapse candidate Collapse( *itp ); // Next Pair contrction ++itp; } // Update the normals ComputeProgressiveFaceNormals(); ComputeProgressiveVertexNormals(); // Go to the next coarse level current_level_number++; } // Test plan #ifdef _TEST_PLAN_ Vertex(1844)[1] = -1.0; // plan-2000 // Vertex(30670)[1] = -1.0; // plan-irregulier char filename[255]; sprintf(filename,"plan-base.wrl"); WriteFile(filename); #endif //-- Test -- //timer.Stop(); //test<<VertexNumber()<<'\t'<<vnum<<'\t'<<((double)VertexNumber()/vnum - 1.0)*100.0<<'\t'<<timer.Total()<<'\t'<<memory<<endl; //-- // // HSI // /* #ifdef _HSI_COLOR_ if( ColorNumber() == VertexNumber() ) { colors = color_backup; } #endif */ return true; }
SI_Error SMDEnvelope::Write ( FILE* l_fptr, int rigid, SMDNodeList* in_pNodeList ) { CSIBCVector3D* l_pPosition = NULL; CSIBCVector3D* l_pNormal = NULL; CSIBCVector2D* l_pUV = NULL; XSI::Primitive l_pPrim = m_pModel.GetActivePrimitive(); if ( !l_pPrim.IsValid() ) return SI_ERR_ERROR_MSG; XSI::Application app; XSI::UIToolkit kit = app.GetUIToolkit(); XSI::ProgressBar m_pBar = kit.GetProgressBar(); m_pBar.PutMaximum( 100 ); m_pBar.PutMinimum( 1 ); m_pBar.PutStep( 1 ); m_pBar.PutValue( 1 ); m_pBar.PutCaption( L"Writing vertex data..." ); m_pBar.PutStatusText( L"" ); m_pBar.PutVisible( true ); // // Get default texture name // char l_szDefaultTextureName[MAX_PATH]; XSI::OGLTexture l_pDefaultTexture = m_pModel.GetMaterial().GetOGLTexture(); if ( !l_pDefaultTexture.IsValid() ) { XSILogMessage ( "Material on enveloped mesh has no texture!", XSI::siErrorMsg ); sprintf ( l_szDefaultTextureName, "default.tga" ); } else { W2AHelper2 ( l_szDefaultTextureName, l_pDefaultTexture.GetFullName().GetWideString() ); char l_szTextureFile[MAX_PATH]; char l_szTextureExt[MAX_PATH]; _splitpath ( l_szDefaultTextureName, NULL, NULL, l_szTextureFile, l_szTextureExt ); sprintf ( l_szDefaultTextureName, "%s%s", l_szTextureFile, l_szTextureExt ); } XSI::Geometry l_pGeo = l_pPrim.GetGeometry(); XSI::CPointRefArray l_pPoints = l_pGeo.GetPoints(); XSI::PolygonMesh l_pPolyMesh = l_pGeo; XSI::CPointRefArray pointRefArray(l_pPolyMesh.GetPoints()); XSI::MATH::CVector3Array positionArray(pointRefArray.GetPositionArray()); XSI::CPolygonNodeRefArray nodeRefArray(l_pPolyMesh.GetNodes()); XSI::MATH::CVector3Array normalArray(nodeRefArray.GetNormalArray()); //Take care of the UV's XSI::CRefArray clusterRefArray; l_pPolyMesh.GetClusters().Filter(XSI::siSampledPointCluster,XSI::CStringArray(),L"",clusterRefArray); XSI::Cluster samplePointClusterUV; XSI::CRefArray uvClusterPropertiesRefArray; int i; for(i=0;i < clusterRefArray.GetCount(); i++) { XSI::Cluster cluster(clusterRefArray[i]); if(cluster.GetProperties().Filter(XSI::siClsUVSpaceTxtType,XSI::CStringArray(), L"",uvClusterPropertiesRefArray) == XSI::CStatus::OK) { samplePointClusterUV = cluster; break; } } XSI::ClusterProperty uvProp(uvClusterPropertiesRefArray[0]); XSI::CClusterPropertyElementArray uvElementArray = uvProp.GetElements(); XSI::CDoubleArray uvValueArray = uvElementArray.GetArray(); long lnbUV= (long)(uvValueArray.GetCount() / 3); // // Make sure that UVs are present // if ( !samplePointClusterUV.IsValid() ) { XSILogMessage ( "Invalid .SMD: Enveloped mesh doesn't have any UVs.", XSI::siErrorMsg ); return SI_ERR_ERROR_MSG; } m_pBar.PutCaption( L"Analyzing clusters..." ); m_pBar.PutStatusText( L"" ); m_pBar.PutVisible( true ); SMDNode* in_pNode = in_pNodeList->GetByName ( m_pModel.GetFullName() ); CSIBCArray < CSIBCVector3D > l_pVertexNormals; ComputeVertexNormals ( l_pVertexNormals, l_pGeo ); XSI::CRefArray allClusters; l_pPolyMesh.GetClusters().Filter(L"poly",XSI::CStringArray(),L"",allClusters); CSIBCArray<MateriaList> matList; for (int c=0;c<allClusters.GetCount();c++) { XSI::Cluster Thecluster = allClusters[c]; XSI::Material l_pMat = Thecluster.GetMaterial(); XSI::OGLTexture l_pTexture = l_pMat.GetOGLTexture(); matList.Extend(1); if ( !l_pTexture.IsValid() ) { char mess[1024]; sprintf ( mess, "Cluster #%d has no texture! Bypassing.", c); XSILogMessage ( mess, XSI::siErrorMsg ); continue; } W2AHelper2 ( matList[matList.GetUsed()-1].texture, l_pTexture.GetFullName().GetWideString() ); char l_szTextureFile[MAX_PATH]; char l_szTextureExt[MAX_PATH]; _splitpath ( matList[matList.GetUsed()-1].texture, NULL, NULL, l_szTextureFile, l_szTextureExt ); sprintf ( matList[matList.GetUsed()-1].texture, "%s%s", l_szTextureFile, l_szTextureExt ); XSI::CClusterElementArray clusterElementArray = Thecluster.GetElements(); XSI::CLongArray values(clusterElementArray.GetArray()); long countPolyIndices = values.GetCount(); matList[matList.GetUsed()-1].polyIndices.Extend(countPolyIndices); for (int v=0;v<countPolyIndices;v++) { matList[matList.GetUsed()-1].polyIndices[v] = values[v]; } } XSI::CTriangleRefArray tris = l_pPolyMesh.GetTriangles(); m_pBar.PutCaption( L"Processing geometry..." ); m_pBar.PutStatusText( L"" ); m_pBar.PutVisible( true ); long progress_value = 0; long last_progress_value = 0; int vindex = 0; int vii = 0; for (int v=0;v<tris.GetCount();v++) { progress_value = (long)(((float)v / (float)tris.GetCount()) * 100.0f); if ( progress_value != last_progress_value ) { last_progress_value = progress_value; m_pBar.PutValue ( progress_value ); if ( m_pBar.IsCancelPressed() ) { if ( MessageBox ( NULL, "Cancelling the export will create a corrupted SMD file.\n\n Are you sure?", "Cancel Export", MB_YESNO|MB_ICONWARNING ) == IDYES ) { break; } else { m_pBar.PutVisible( true ); } } } XSI::Triangle tri = tris[v]; char* textureName = l_szDefaultTextureName; long polyI = tri.GetPolygonIndex(); for (int p=0;p<matList.GetUsed();p++) { bool found = false; for (int h=0;h<matList[p].polyIndices.GetUsed();h++) { if ( matList[p].polyIndices[h] == polyI ) { textureName = matList[p].texture; found = true; break; } } if ( found ) break; } for (int i=0;i<3;i++) { // // Build a vertex // CSIBCVector3D l_vPosition = CSIBCVector3D( (float)tri.GetPositionArray()[i].GetX(), (float)tri.GetPositionArray()[i].GetY(), (float)tri.GetPositionArray()[i].GetZ() ); XSI::CTriangleVertexRefArray vRef = tri.GetPoints(); XSI::TriangleVertex l_vTriangleVertex = vRef[i]; CSIBCVector3D l_vNormal = CSIBCVector3D ( (float)l_vTriangleVertex.GetNormal().GetX(), (float)l_vTriangleVertex.GetNormal().GetY(), (float)l_vTriangleVertex.GetNormal().GetZ() ); //if ( SMDType == 1 ) //{ // l_vNormal = l_pVertexNormals [ l_pVertexList[vii] ]; //} if (( SMDType == 0 ) || ( SMDType == 1 )) { CSIBCMatrix4x4 l_pResult = in_pNode->GetMatrix(); l_pResult.Multiply ( l_vPosition, l_vPosition ); l_pResult.Multiply ( l_vNormal, l_vNormal ); l_vNormal = l_vNormal.Normalize(); } XSI::CTriangleVertexRefArray l_TriRef = tri.GetPoints(); XSI::CUVArray l_vuvArray = l_TriRef.GetUVArray(); XSI::CUV l_uv = l_vuvArray[i]; int c = l_vuvArray.GetCount(); long vertexIndex = tri.GetIndexArray()[i]; CSIBCVector2D l_vUV; l_vUV.m_fX = (float)l_uv.u; l_vUV.m_fY = (float)l_uv.v; // // Build weight list // SMDVertex* l_pWeights = m_pVertexList[vertexIndex]; // not sure the line above works correclty, if not, uncomment // the code below //for (int w=0;w<m_pVertexList.GetUsed();w++) //{ // if ( m_pVertexList[w]->GetIndex() == vertexIndex ) // { // l_pWeights = m_pVertexList[w]; // break; // // } //} vii++; // // Now output // // XSI::OGLTexture l_pTexture = useMat.GetOGLTexture(); if ( vindex == 0 ) { fprintf ( l_fptr, "%s\n", textureName ); } if ( !rigid ) { CSIBCString l_szWeight; l_szWeight.Concat ( l_pWeights->GetNumWeights() ); l_szWeight.Concat (" "); for (int f=0;f<l_pWeights->GetNumWeights();f++) { l_szWeight.Concat ( l_pWeights->GetWeight(f)->m_iBoneID ); l_szWeight.Concat (" "); l_szWeight.Concat ( l_pWeights->GetWeight(f)->m_fWeight ); l_szWeight.Concat (" "); } fprintf ( l_fptr, "0 %f %f %f %f %f %f %f %f %s\n", l_vPosition.m_fX, l_vPosition.m_fY, l_vPosition.m_fZ, l_vNormal.m_fX, l_vNormal.m_fY, l_vNormal.m_fZ, l_vUV.m_fX, l_vUV.m_fY, l_szWeight.GetText()); } else { fprintf ( l_fptr, "%d %f %f %f %f %f %f %f %f \n", l_pWeights->GetWeight(0)->m_iBoneID, l_vPosition.m_fX, l_vPosition.m_fY, l_vPosition.m_fZ, l_vNormal.m_fX, l_vNormal.m_fY, l_vNormal.m_fZ, l_vUV.m_fX, l_vUV.m_fY ); } vindex++; if ( vindex == 3 ) vindex = 0; } } return SI_SUCCESS; }