!B (Sandbox) (CE-21795) Importing models with multisubmaterials via fbx switches...
[CRYENGINE.git] / Code / Sandbox / Plugins / LodGeneratorPlugin / Util / TopologyTransform.cpp
blob85e0ced6314fc093a981da86339f3dd4030b3d8f
1 #include "StdAfx.h"
2 #include "TopologyTransform.h"
3 #include <Cry3DEngine/IIndexedMesh.h>
4 #include "TopologyBuilder.h"
6 namespace LODGenerator
8 CTopologyGraph* CTopologyTransform::TransformToTopology(Vec3 *pVertices, vtx_idx *indices, int faces)
10 if (pVertices == NULL || indices == NULL)
11 return NULL;
13 std::vector<Vec3> verticeList;
14 std::vector<int> newIndices;
15 for (int i=0; i<faces*3; i++)
17 Vec3 *v=&pVertices[indices[i]];
18 int idx=-1;
19 for (std::vector<Vec3>::iterator it=verticeList.begin(), end=verticeList.end(); it!=end; ++it)
21 if (*v==*it)
23 idx=(int)(&*it-&verticeList[0]);
24 break;
27 if (idx==-1)
29 Vec3 vert;
30 vert = *v;
31 idx= verticeList.size();
32 verticeList.push_back(vert);
34 newIndices.push_back(idx);
38 CTopologyGraph* pMap = new CTopologyGraph();
39 CTopologyBuilder builder(pMap);
41 builder.begin_surface();
42 for (int i=0;i<verticeList.size();i++)
44 builder.add_vertex(verticeList[i]);
47 for (int i=0;i<faces;i++)
49 int index = -1;
50 builder.begin_facet();
51 for (int j=0;j<3;j++)
53 index = newIndices[ j + 3*i];
54 builder.add_vertex_to_facet(index) ;
56 builder.end_facet();
58 builder.end_surface();
60 pMap->compute_normals();
61 pMap->compute_vertex_tangent();
63 return pMap;
67 CTopologyGraph* CTopologyTransform::TransformToTopology(IStatObj *pObject,bool bCalNormal)
69 IIndexedMesh* pIIndexedMesh = pObject->GetIndexedMesh(true);
70 pIIndexedMesh->RestoreFacesFromIndices();
72 int posCount,normalCount,tangentCount;
73 Vec3* const positions = pIIndexedMesh->GetMesh()->GetStreamPtr<Vec3>(CMesh::POSITIONS,&posCount);
74 Vec3* const normals = pIIndexedMesh->GetMesh()->GetStreamPtr<Vec3>(CMesh::NORMALS,&normalCount);
75 SMeshTangents *pOutTangents = pIIndexedMesh->GetMesh()->GetStreamPtr<SMeshTangents>(CMesh::TANGENTS,&tangentCount);
77 int texCount,faceCount,indexCount;
78 SMeshTexCoord* const texcoords = pIIndexedMesh->GetMesh()->GetStreamPtr<SMeshTexCoord>(CMesh::TEXCOORDS,&texCount);
79 SMeshFace* const faces = pIIndexedMesh->GetMesh()->GetStreamPtr<SMeshFace>(CMesh::FACES,&faceCount);
80 vtx_idx *pIndices= pIIndexedMesh->GetMesh()->GetStreamPtr<vtx_idx>(CMesh::INDICES,&indexCount);
82 ASSERT(posCount == normalCount == tangentCount);
84 if (posCount == 0)
85 return NULL;
87 CTopologyGraph* pMap = new CTopologyGraph();
88 CTopologyBuilder builder(pMap);
90 builder.begin_surface();
91 for (int i=0;i<posCount;i++)
93 builder.add_vertex(positions[i]);
96 for (int i=0;i<texCount;i++)
98 builder.add_tex_vertex(texcoords[i].GetUV()) ;
100 for (int i=0;i<faceCount;i++)
102 int index = -1;
103 builder.begin_facet();
104 for (int j=0;j<3;j++)
106 index = faces[i].v[j];
107 builder.add_vertex_to_facet(index);
108 builder.set_corner_tex_vertex(index);
110 builder.end_facet();
112 builder.end_surface(false);
114 if (bCalNormal)
116 pMap->compute_normals();
117 pMap->compute_vertex_tangent();
120 if(!bCalNormal)
122 for (int i=0;i<posCount;i++)
124 CVertex* vertex = builder.vertex(i);
125 if(vertex == NULL)
126 continue;
127 std::shared_ptr<CTexVertex>& texVertex = vertex->halfedge()->tex_vertex();
129 if (texVertex == NULL)
130 continue;
132 if(normals != NULL)
134 texVertex->set_normal(normals[i]);
137 if(pOutTangents != NULL)
139 Vec3 bn,t;
140 Vec4sf othert, otherb;
141 pOutTangents[i].ExportTo(othert, otherb);
142 PackingSNorm::tPackB2F(othert,t);
143 PackingSNorm::tPackB2F(otherb,bn);
145 texVertex->set_tangent(t);
146 texVertex->set_binormal(bn);
152 builder.clear();
154 return pMap;
157 void CTopologyTransform::FillMesh( CTopologyGraph* pPolygon, IStatObj *pObject )
159 IIndexedMesh *pMesh = pObject->GetIndexedMesh();
160 if (!pMesh)
161 pMesh=pObject->CreateIndexedMesh();
163 int vertexCount = pPolygon->size_of_vertices();
164 int faceCount = pPolygon->size_of_facets();
166 pMesh->FreeStreams();
167 pMesh->SetVertexCount(vertexCount);
168 pMesh->SetFaceCount(faceCount);
169 pMesh->SetIndexCount(faceCount*3);
170 pMesh->SetTexCoordCount(vertexCount);
171 pMesh->SetTangentCount(vertexCount);
173 Vec3* const positions = pMesh->GetMesh()->GetStreamPtr<Vec3>(CMesh::POSITIONS);
174 Vec3* const normals = pMesh->GetMesh()->GetStreamPtr<Vec3>(CMesh::NORMALS);
175 SMeshTangents *pOutTangents = pMesh->GetMesh()->GetStreamPtr<SMeshTangents>(CMesh::TANGENTS);
177 SMeshTexCoord* const texcoords = pMesh->GetMesh()->GetStreamPtr<SMeshTexCoord>(CMesh::TEXCOORDS);
178 SMeshFace* const faces = pMesh->GetMesh()->GetStreamPtr<SMeshFace>(CMesh::FACES);
179 vtx_idx *pIndices= pMesh->GetMesh()->GetStreamPtr<vtx_idx>(CMesh::INDICES);
181 std::map<CVertex*,int> vertex_id;
183 int i = 0;
184 for(CTopologyGraph::Vertex_iterator it=(pPolygon)->vertices_begin();it!=(pPolygon)->vertices_end(); it++,i++)
186 Vec3d vetex = (*it)->point();
187 CHalfedge* jt = (*it)->halfedge() ;
188 Vec3d normal = jt->tex_vertex()->normal();
189 Vec2d st = jt->tex_coord() ;
190 Vec3d tangent = jt->tex_vertex()->tangent();
191 Vec3d binormal = jt->tex_vertex()->binormal();
193 positions[i] = Vec3d(vetex.x,vetex.y,vetex.z);
194 normals[i] = Vec3d(normal.x,normal.y,normal.z);
195 texcoords[i] = SMeshTexCoord(st);
196 pOutTangents[i] = SMeshTangents(Vec4sf(PackingSNorm::tPackF2B(tangent.x), PackingSNorm::tPackF2B(tangent.y), PackingSNorm::tPackF2B(tangent.z), PackingSNorm::tPackS2B(1))
197 ,Vec4sf(PackingSNorm::tPackF2B(binormal.x), PackingSNorm::tPackF2B(binormal.y), PackingSNorm::tPackF2B(binormal.z), PackingSNorm::tPackS2B(1)));
199 vertex_id[*it] = i;
201 i = 0;
202 for(CTopologyGraph::Facet_iterator it=(pPolygon)->facets_begin();it!=(pPolygon)->facets_end(); it++,i++)
204 CHalfedge* jt = (*it)->halfedge() ;
205 int k = 0;
208 int id = vertex_id[jt->vertex()];
209 faces[i].v[k] = id;
210 pIndices[3*i + k] = id;
211 jt = jt->next() ;
212 k++;
213 } while(jt != (*it)->halfedge()) ;
214 ASSERT( k == 3);
217 float area=0.0f;
218 float tarea=0.0f;
219 for (int i=0; i< faceCount * 3; i+=3)
221 int idx0=pIndices[i+0];
222 int idx1=pIndices[i+1];
223 int idx2=pIndices[i+2];
224 Vec3d e0=positions[idx1]-positions[idx0];
225 Vec3d e1=positions[idx2]-positions[idx0];
226 Vec2d t0 = texcoords[idx0].GetUV();
227 Vec2d t1 = texcoords[idx1].GetUV();
228 Vec2d t2 = texcoords[idx2].GetUV();
229 Vec2d ta=Vec2d(t1.x-t0.x, t1.y-t0.y);
230 Vec2d tb=Vec2d(t2.x-t0.x, t2.y-t0.y);
231 area+=e0.Cross(e1).len();
232 tarea+=ta.Cross(tb);
235 SMeshSubset subset;
236 subset.nFirstIndexId = 0;
237 subset.nNumIndices = faceCount * 3;
238 subset.nFirstVertId = 0;
239 subset.nNumVerts = vertexCount;
240 subset.nMatID = 0;
241 subset.nMatFlags = 0;
242 subset.fRadius=100.0f;
243 if (area!=0.0f)
244 subset.fTexelDensity=tarea/area;
245 else
246 subset.fTexelDensity=1.0f;
248 pMesh->GetMesh()->m_subsets.push_back(subset);
250 pMesh->SetSubsetMaterialId(0,0);
251 pMesh->SetSubsetIndexVertexRanges(0,0,faceCount*3,0,vertexCount);
253 pMesh->CalcBBox();
255 pObject->SetBBoxMin(pMesh->GetBBox().min);
256 pObject->SetBBoxMax(pMesh->GetBBox().max);
258 pObject->Invalidate(true);