2 #include "TopologyTransform.h"
3 #include <Cry3DEngine/IIndexedMesh.h>
4 #include "TopologyBuilder.h"
8 CTopologyGraph
* CTopologyTransform::TransformToTopology(Vec3
*pVertices
, vtx_idx
*indices
, int faces
)
10 if (pVertices
== NULL
|| indices
== 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
]];
19 for (std::vector
<Vec3
>::iterator it
=verticeList
.begin(), end
=verticeList
.end(); it
!=end
; ++it
)
23 idx
=(int)(&*it
-&verticeList
[0]);
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
++)
50 builder
.begin_facet();
53 index
= newIndices
[ j
+ 3*i
];
54 builder
.add_vertex_to_facet(index
) ;
58 builder
.end_surface();
60 pMap
->compute_normals();
61 pMap
->compute_vertex_tangent();
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
);
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
++)
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
);
112 builder
.end_surface(false);
116 pMap
->compute_normals();
117 pMap
->compute_vertex_tangent();
122 for (int i
=0;i
<posCount
;i
++)
124 CVertex
* vertex
= builder
.vertex(i
);
127 std::shared_ptr
<CTexVertex
>& texVertex
= vertex
->halfedge()->tex_vertex();
129 if (texVertex
== NULL
)
134 texVertex
->set_normal(normals
[i
]);
137 if(pOutTangents
!= NULL
)
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
);
157 void CTopologyTransform::FillMesh( CTopologyGraph
* pPolygon
, IStatObj
*pObject
)
159 IIndexedMesh
*pMesh
= pObject
->GetIndexedMesh();
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
;
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)));
202 for(CTopologyGraph::Facet_iterator it
=(pPolygon
)->facets_begin();it
!=(pPolygon
)->facets_end(); it
++,i
++)
204 CHalfedge
* jt
= (*it
)->halfedge() ;
208 int id
= vertex_id
[jt
->vertex()];
210 pIndices
[3*i
+ k
] = id
;
213 } while(jt
!= (*it
)->halfedge()) ;
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();
236 subset
.nFirstIndexId
= 0;
237 subset
.nNumIndices
= faceCount
* 3;
238 subset
.nFirstVertId
= 0;
239 subset
.nNumVerts
= vertexCount
;
241 subset
.nMatFlags
= 0;
242 subset
.fRadius
=100.0f
;
244 subset
.fTexelDensity
=tarea
/area
;
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
);
255 pObject
->SetBBoxMin(pMesh
->GetBBox().min
);
256 pObject
->SetBBoxMax(pMesh
->GetBBox().max
);
258 pObject
->Invalidate(true);