2
Copyright (c) 2009 NetAllied Systems GmbH
4
This file is part of dae23ds.
6
Licensed under the MIT Open Source License,
7
for details please see LICENSE file or the website
8
http://www.opensource.org/licenses/mit-license.php
11
#include "DAE23dsStableHeaders.h"
12
#include "DAE23dsMeshAccessor.h"
18
//------------------------------
19
MeshAccessor::MeshAccessor( const COLLADAFW::Mesh* mesh )
21
, mMeshPrimitiveCount( mesh->getMeshPrimitives().getCount() )
22
, mMeshPrimitiveTrianglesCount( new size_t[mMeshPrimitiveCount] )
23
, mTrianglesCount( calculateTrianglesCount() )
24
, mCurrentPrimitiveIndex(0)
25
, mCurrentStripFanIndex(0)
26
, mCurrentTriangleInTriStripFanIndex(0)
31
//------------------------------
32
MeshAccessor::~MeshAccessor()
34
delete[] mMeshPrimitiveTrianglesCount;
37
//------------------------------
38
size_t MeshAccessor::calculateTrianglesCount() const
40
size_t trianglesCount = 0;
41
const COLLADAFW::MeshPrimitiveArray& meshPrimitives = mMesh->getMeshPrimitives();
42
size_t meshPrimitivesCount = meshPrimitives.getCount();
44
for ( size_t i = 0; i < meshPrimitivesCount; ++i)
46
const COLLADAFW::MeshPrimitive* meshPrimitive = meshPrimitives[i];
47
size_t primitiveTrianglesCount = calculateMeshPrimitiveTriangleCount(meshPrimitive);
48
trianglesCount += primitiveTrianglesCount;
49
mMeshPrimitiveTrianglesCount[i] = primitiveTrianglesCount;
51
return trianglesCount;
54
//------------------------------
55
size_t MeshAccessor::calculateMeshPrimitiveTriangleCount(const COLLADAFW::MeshPrimitive* meshPrimitive) const
57
size_t trianglesCount = 0;
59
switch ( meshPrimitive->getPrimitiveType() )
61
case COLLADAFW::MeshPrimitive::TRIANGLES:
63
const COLLADAFW::UIntValuesArray& positionsIndices = meshPrimitive->getPositionIndices();
64
size_t positionsIndicesCount = positionsIndices.getCount();
65
trianglesCount = positionsIndicesCount/3;
68
case COLLADAFW::MeshPrimitive::TRIANGLE_STRIPS:
70
const COLLADAFW::Tristrips* tristrips = (const COLLADAFW::Tristrips*)meshPrimitive;
71
const COLLADAFW::UIntValuesArray& faceVertexCountArray = tristrips->getGroupedVerticesVertexCountArray();
73
for ( size_t k = 0, count = faceVertexCountArray.getCount(); k < count; ++k)
75
trianglesCount += (faceVertexCountArray[k] - 2);
79
case COLLADAFW::MeshPrimitive::TRIANGLE_FANS:
81
const COLLADAFW::Trifans* trifans = (const COLLADAFW::Trifans*)meshPrimitive;
82
const COLLADAFW::UIntValuesArray& faceVertexCountArray = trifans->getGroupedVerticesVertexCountArray();
84
for ( size_t k = 0, count = faceVertexCountArray.getCount(); k < count; ++k)
86
trianglesCount += (faceVertexCountArray[k] - 2);
91
return trianglesCount;
94
//------------------------------
95
MeshAccessor::TriangleType MeshAccessor::getTriangle( size_t n ) const
97
assert( n < mTrianglesCount );
99
mCurrentTriangleIndex = n;
100
//find the correct mesh primitive
101
size_t triangleIndex = mMeshPrimitiveTrianglesCount[0] ;
102
size_t meshPrimitiveIndex = 0;
103
while ( triangleIndex < n + 1 )
105
triangleIndex += mMeshPrimitiveTrianglesCount[++meshPrimitiveIndex];
107
triangleIndex -= mMeshPrimitiveTrianglesCount[meshPrimitiveIndex];
109
size_t indexInPrimitive = n - triangleIndex;
110
const COLLADAFW::MeshPrimitive* meshPrimitive = mMesh->getMeshPrimitives()[meshPrimitiveIndex];
112
COLLADAFW::MaterialId materialId = meshPrimitive->getMaterialId();
114
mCurrentPrimitiveIndex = meshPrimitiveIndex;
116
const COLLADAFW::UIntValuesArray& positionsIndices = meshPrimitive->getPositionIndices();
118
switch ( meshPrimitive->getPrimitiveType() )
120
case COLLADAFW::MeshPrimitive::TRIANGLES:
122
size_t firstIndex = indexInPrimitive * 3;
123
TriangleType triangle(positionsIndices[firstIndex], positionsIndices[firstIndex+1],positionsIndices[firstIndex+2], materialId);
124
mCurrentStripFanIndex = 0;
125
mCurrentTriangleInTriStripFanIndex = indexInPrimitive;
128
case COLLADAFW::MeshPrimitive::TRIANGLE_STRIPS:
130
const COLLADAFW::Tristrips* tristrips = (const COLLADAFW::Tristrips*)meshPrimitive;
131
const COLLADAFW::UIntValuesArray& faceVertexCountArray = tristrips->getGroupedVerticesVertexCountArray();
133
//find the correct tristrip
134
size_t triangleIndex = faceVertexCountArray[0] - 2 ;
135
size_t tristripIndex = 0;
136
while ( triangleIndex < indexInPrimitive + 1 )
138
triangleIndex += faceVertexCountArray[++tristripIndex] - 2;
140
triangleIndex -= (faceVertexCountArray[tristripIndex] - 2);
141
size_t firstIndex = indexInPrimitive + 2*tristripIndex;
142
mCurrentStripFanIndex = tristripIndex;
143
mCurrentTriangleInTriStripFanIndex = indexInPrimitive - triangleIndex;
144
mCurrentTrianglePositionsArrayIndex = triangleIndex + 2*tristripIndex;
145
if ( mCurrentTriangleInTriStripFanIndex % 2 == 0 )
147
return TriangleType(positionsIndices[firstIndex], positionsIndices[firstIndex+1],positionsIndices[firstIndex+2], materialId);
151
return TriangleType(positionsIndices[firstIndex], positionsIndices[firstIndex+2],positionsIndices[firstIndex+1], materialId);
154
case COLLADAFW::MeshPrimitive::TRIANGLE_FANS:
156
const COLLADAFW::Trifans* trifans = (const COLLADAFW::Trifans*)meshPrimitive;
157
const COLLADAFW::UIntValuesArray& faceVertexCountArray = trifans->getGroupedVerticesVertexCountArray();
159
//find the correct trifan
160
size_t triangleIndex = faceVertexCountArray[0] - 2 ;
161
size_t trisfanIndex = 0;
162
while ( triangleIndex < indexInPrimitive + 1 )
164
triangleIndex += faceVertexCountArray[++trisfanIndex] - 2;
166
triangleIndex -= (faceVertexCountArray[trisfanIndex] - 2);
167
size_t firstIndex = indexInPrimitive + 2*trisfanIndex;
168
TriangleType triangle(positionsIndices[triangleIndex + 2*trisfanIndex ], positionsIndices[firstIndex+1],positionsIndices[firstIndex+2], materialId);
169
mCurrentStripFanIndex = trisfanIndex;
170
mCurrentTriangleInTriStripFanIndex = indexInPrimitive - triangleIndex;
175
return TriangleType(0, 0, 0, 0);
179
//------------------------------
180
MeshAccessor::TriangleType MeshAccessor::getNextTriangle() const
182
mCurrentTriangleIndex++;
183
const COLLADAFW::MeshPrimitive* meshPrimitive = mMesh->getMeshPrimitives()[mCurrentPrimitiveIndex];
184
const COLLADAFW::UIntValuesArray& positionsIndices = meshPrimitive->getPositionIndices();
186
COLLADAFW::MaterialId materialId = meshPrimitive->getMaterialId();
188
switch ( meshPrimitive->getPrimitiveType() )
190
case COLLADAFW::MeshPrimitive::TRIANGLES:
192
size_t triangleCount = positionsIndices.getCount()/3;
193
if ( (mCurrentTriangleInTriStripFanIndex + 1) < triangleCount )
195
// use next in same triangle
197
mCurrentTriangleInTriStripFanIndex++;
198
size_t firstIndex = mCurrentTriangleInTriStripFanIndex * 3;
199
TriangleType triangle(positionsIndices[firstIndex], positionsIndices[firstIndex+1],positionsIndices[firstIndex+2], materialId);
204
return getTriangle( mCurrentTriangleIndex );
207
case COLLADAFW::MeshPrimitive::TRIANGLE_STRIPS:
209
const COLLADAFW::Tristrips* tristrips = (const COLLADAFW::Tristrips*)meshPrimitive;
210
const COLLADAFW::UIntValuesArray& faceVertexCountArray = tristrips->getGroupedVerticesVertexCountArray();
212
size_t triangleCount = faceVertexCountArray[mCurrentStripFanIndex] - 2;
214
if ( (mCurrentTriangleInTriStripFanIndex + 1) < triangleCount )
216
// use next in same triangle
218
mCurrentTriangleInTriStripFanIndex++;
219
size_t firstIndex = mCurrentTrianglePositionsArrayIndex + mCurrentTriangleInTriStripFanIndex;
220
if ( mCurrentTriangleInTriStripFanIndex % 2 == 0 )
222
return TriangleType(positionsIndices[firstIndex], positionsIndices[firstIndex+1],positionsIndices[firstIndex+2], materialId);
226
return TriangleType(positionsIndices[firstIndex], positionsIndices[firstIndex+2],positionsIndices[firstIndex+1], materialId);
231
if ( (mCurrentStripFanIndex + 1) < faceVertexCountArray.getCount() )
233
// take the next strip
234
mCurrentTrianglePositionsArrayIndex += faceVertexCountArray[mCurrentStripFanIndex];
235
mCurrentStripFanIndex++;
236
mCurrentTriangleInTriStripFanIndex = 0;
237
size_t firstIndex = mCurrentTrianglePositionsArrayIndex;
238
return TriangleType (positionsIndices[firstIndex], positionsIndices[firstIndex+1],positionsIndices[firstIndex+2], materialId);
242
return getTriangle( mCurrentTriangleIndex );
246
case COLLADAFW::MeshPrimitive::TRIANGLE_FANS:
248
const COLLADAFW::Trifans* trifans = (const COLLADAFW::Trifans*)meshPrimitive;
249
const COLLADAFW::UIntValuesArray& faceVertexCountArray = trifans->getGroupedVerticesVertexCountArray();
252
size_t triangleCount = faceVertexCountArray[mCurrentStripFanIndex] - 2;
254
if ( (mCurrentTriangleInTriStripFanIndex + 1) < triangleCount )
256
// use next in same triangle
258
mCurrentTriangleInTriStripFanIndex++;
259
size_t firstIndex = mCurrentTrianglePositionsArrayIndex + mCurrentTriangleInTriStripFanIndex;
260
TriangleType triangle(positionsIndices[mCurrentTrianglePositionsArrayIndex], positionsIndices[firstIndex+1],positionsIndices[firstIndex+2], materialId);
265
if ( (mCurrentStripFanIndex + 1) < faceVertexCountArray.getCount() )
267
// take the next strip
268
mCurrentTrianglePositionsArrayIndex += faceVertexCountArray[mCurrentStripFanIndex];
269
mCurrentStripFanIndex++;
270
mCurrentTriangleInTriStripFanIndex = 0;
271
size_t firstIndex = mCurrentTrianglePositionsArrayIndex;
272
TriangleType triangle(positionsIndices[mCurrentTrianglePositionsArrayIndex], positionsIndices[firstIndex+1],positionsIndices[firstIndex+2], materialId);
277
return getTriangle( mCurrentTriangleIndex );
283
return TriangleType(0, 0, 0, 0);
290
} // namespace DAE23ds