~ubuntu-branches/ubuntu/wily/opencollada/wily-proposed

« back to all changes in this revision

Viewing changes to dae23ds/src/DAE23dsMeshAccessor.cpp

  • Committer: Package Import Robot
  • Author(s): Matteo F. Vescovi
  • Date: 2015-05-14 17:23:27 UTC
  • Revision ID: package-import@ubuntu.com-20150514172327-f862u8envms01fra
Tags: upstream-0.1.0~20140703.ddf8f47+dfsg1
ImportĀ upstreamĀ versionĀ 0.1.0~20140703.ddf8f47+dfsg1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    Copyright (c) 2009 NetAllied Systems GmbH
 
3
 
 
4
    This file is part of dae23ds.
 
5
        
 
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
 
9
*/
 
10
 
 
11
#include "DAE23dsStableHeaders.h"
 
12
#include "DAE23dsMeshAccessor.h"
 
13
 
 
14
 
 
15
namespace DAE23ds
 
16
{
 
17
 
 
18
    //------------------------------
 
19
        MeshAccessor::MeshAccessor( const COLLADAFW::Mesh* mesh )
 
20
                : mMesh( mesh )
 
21
                , mMeshPrimitiveCount( mesh->getMeshPrimitives().getCount() )
 
22
                , mMeshPrimitiveTrianglesCount( new size_t[mMeshPrimitiveCount] )
 
23
                , mTrianglesCount( calculateTrianglesCount() )
 
24
                , mCurrentPrimitiveIndex(0)
 
25
                , mCurrentStripFanIndex(0)
 
26
                , mCurrentTriangleInTriStripFanIndex(0)
 
27
        {
 
28
 
 
29
        }
 
30
 
 
31
    //------------------------------
 
32
        MeshAccessor::~MeshAccessor()
 
33
        {
 
34
                delete[] mMeshPrimitiveTrianglesCount;
 
35
        }
 
36
 
 
37
        //------------------------------
 
38
        size_t MeshAccessor::calculateTrianglesCount() const
 
39
        {
 
40
                size_t trianglesCount = 0;
 
41
                const COLLADAFW::MeshPrimitiveArray& meshPrimitives = mMesh->getMeshPrimitives();
 
42
                size_t meshPrimitivesCount = meshPrimitives.getCount();
 
43
 
 
44
                for ( size_t i = 0; i < meshPrimitivesCount; ++i)
 
45
                {
 
46
                        const COLLADAFW::MeshPrimitive* meshPrimitive = meshPrimitives[i];
 
47
                        size_t primitiveTrianglesCount = calculateMeshPrimitiveTriangleCount(meshPrimitive);
 
48
                        trianglesCount += primitiveTrianglesCount;
 
49
                        mMeshPrimitiveTrianglesCount[i] = primitiveTrianglesCount;
 
50
                }
 
51
                return trianglesCount;
 
52
        }
 
53
 
 
54
        //------------------------------
 
55
        size_t MeshAccessor::calculateMeshPrimitiveTriangleCount(const COLLADAFW::MeshPrimitive* meshPrimitive) const
 
56
        {
 
57
                size_t trianglesCount = 0;
 
58
 
 
59
                switch ( meshPrimitive->getPrimitiveType() )
 
60
                {
 
61
                case COLLADAFW::MeshPrimitive::TRIANGLES:
 
62
                        {
 
63
                                const COLLADAFW::UIntValuesArray& positionsIndices = meshPrimitive->getPositionIndices();
 
64
                                size_t positionsIndicesCount = positionsIndices.getCount();
 
65
                                trianglesCount = positionsIndicesCount/3;
 
66
                                break;
 
67
                        }
 
68
                case COLLADAFW::MeshPrimitive::TRIANGLE_STRIPS:
 
69
                        {
 
70
                                const COLLADAFW::Tristrips* tristrips = (const COLLADAFW::Tristrips*)meshPrimitive;
 
71
                                const COLLADAFW::UIntValuesArray& faceVertexCountArray = tristrips->getGroupedVerticesVertexCountArray();
 
72
 
 
73
                                for ( size_t k = 0, count = faceVertexCountArray.getCount(); k < count; ++k)
 
74
                                {
 
75
                                        trianglesCount += (faceVertexCountArray[k] - 2);
 
76
                                }
 
77
                                break;
 
78
                        }
 
79
                case COLLADAFW::MeshPrimitive::TRIANGLE_FANS:
 
80
                        {
 
81
                                const COLLADAFW::Trifans* trifans = (const COLLADAFW::Trifans*)meshPrimitive;
 
82
                                const COLLADAFW::UIntValuesArray& faceVertexCountArray = trifans->getGroupedVerticesVertexCountArray();
 
83
 
 
84
                                for ( size_t k = 0, count = faceVertexCountArray.getCount(); k < count; ++k)
 
85
                                {
 
86
                                        trianglesCount += (faceVertexCountArray[k] - 2);
 
87
                                }
 
88
                                break;
 
89
                        }
 
90
                }
 
91
                return trianglesCount;
 
92
        }
 
93
 
 
94
        //------------------------------
 
95
        MeshAccessor::TriangleType MeshAccessor::getTriangle( size_t n ) const
 
96
        {
 
97
                assert( n < mTrianglesCount );
 
98
 
 
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 )
 
104
                {
 
105
                        triangleIndex += mMeshPrimitiveTrianglesCount[++meshPrimitiveIndex];
 
106
                }
 
107
                triangleIndex -= mMeshPrimitiveTrianglesCount[meshPrimitiveIndex];
 
108
 
 
109
                size_t indexInPrimitive = n - triangleIndex;
 
110
                const COLLADAFW::MeshPrimitive* meshPrimitive = mMesh->getMeshPrimitives()[meshPrimitiveIndex];
 
111
 
 
112
                COLLADAFW::MaterialId materialId = meshPrimitive->getMaterialId();
 
113
 
 
114
                mCurrentPrimitiveIndex = meshPrimitiveIndex;
 
115
 
 
116
                const COLLADAFW::UIntValuesArray& positionsIndices = meshPrimitive->getPositionIndices();
 
117
 
 
118
                switch ( meshPrimitive->getPrimitiveType() )
 
119
                {
 
120
                case COLLADAFW::MeshPrimitive::TRIANGLES:
 
121
                        {
 
122
                                size_t firstIndex = indexInPrimitive * 3;
 
123
                                TriangleType triangle(positionsIndices[firstIndex], positionsIndices[firstIndex+1],positionsIndices[firstIndex+2], materialId);
 
124
                                mCurrentStripFanIndex = 0;
 
125
                                mCurrentTriangleInTriStripFanIndex = indexInPrimitive;
 
126
                                return triangle;
 
127
                        }
 
128
                case COLLADAFW::MeshPrimitive::TRIANGLE_STRIPS:
 
129
                        {
 
130
                                const COLLADAFW::Tristrips* tristrips = (const COLLADAFW::Tristrips*)meshPrimitive;
 
131
                                const COLLADAFW::UIntValuesArray& faceVertexCountArray = tristrips->getGroupedVerticesVertexCountArray();
 
132
 
 
133
                                //find the correct tristrip
 
134
                                size_t triangleIndex = faceVertexCountArray[0] - 2 ;
 
135
                                size_t tristripIndex = 0;
 
136
                                while ( triangleIndex < indexInPrimitive + 1 )
 
137
                                {
 
138
                                        triangleIndex += faceVertexCountArray[++tristripIndex] - 2;
 
139
                                }
 
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 )
 
146
                                {
 
147
                                        return TriangleType(positionsIndices[firstIndex], positionsIndices[firstIndex+1],positionsIndices[firstIndex+2], materialId);
 
148
                                }
 
149
                                else
 
150
                                {
 
151
                                        return TriangleType(positionsIndices[firstIndex], positionsIndices[firstIndex+2],positionsIndices[firstIndex+1], materialId);
 
152
                                }
 
153
                        }
 
154
                case COLLADAFW::MeshPrimitive::TRIANGLE_FANS:
 
155
                        {
 
156
                                const COLLADAFW::Trifans* trifans = (const COLLADAFW::Trifans*)meshPrimitive;
 
157
                                const COLLADAFW::UIntValuesArray& faceVertexCountArray = trifans->getGroupedVerticesVertexCountArray();
 
158
 
 
159
                                //find the correct trifan
 
160
                                size_t triangleIndex = faceVertexCountArray[0] - 2 ;
 
161
                                size_t trisfanIndex = 0;
 
162
                                while ( triangleIndex < indexInPrimitive + 1 )
 
163
                                {
 
164
                                        triangleIndex += faceVertexCountArray[++trisfanIndex] - 2;
 
165
                                }
 
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;
 
171
                                return triangle;
 
172
                        }
 
173
                default:
 
174
                        assert(false);
 
175
                        return TriangleType(0, 0, 0, 0);
 
176
                }
 
177
        }
 
178
 
 
179
        //------------------------------
 
180
        MeshAccessor::TriangleType MeshAccessor::getNextTriangle() const
 
181
        {
 
182
                mCurrentTriangleIndex++;
 
183
                const COLLADAFW::MeshPrimitive* meshPrimitive = mMesh->getMeshPrimitives()[mCurrentPrimitiveIndex];
 
184
                const COLLADAFW::UIntValuesArray& positionsIndices = meshPrimitive->getPositionIndices();
 
185
 
 
186
                COLLADAFW::MaterialId materialId = meshPrimitive->getMaterialId();
 
187
 
 
188
                switch ( meshPrimitive->getPrimitiveType() )
 
189
                {
 
190
                case COLLADAFW::MeshPrimitive::TRIANGLES:
 
191
                        {
 
192
                                size_t triangleCount = positionsIndices.getCount()/3;
 
193
                                if ( (mCurrentTriangleInTriStripFanIndex + 1) < triangleCount )
 
194
                                {
 
195
                                        // use next in same triangle
 
196
 
 
197
                                        mCurrentTriangleInTriStripFanIndex++;
 
198
                                        size_t firstIndex = mCurrentTriangleInTriStripFanIndex * 3;
 
199
                                        TriangleType triangle(positionsIndices[firstIndex], positionsIndices[firstIndex+1],positionsIndices[firstIndex+2], materialId);
 
200
                                        return triangle;
 
201
                                }
 
202
                                else
 
203
                                {
 
204
                                        return getTriangle( mCurrentTriangleIndex );
 
205
                                }
 
206
                        }
 
207
                case COLLADAFW::MeshPrimitive::TRIANGLE_STRIPS:
 
208
                        {
 
209
                                const COLLADAFW::Tristrips* tristrips = (const COLLADAFW::Tristrips*)meshPrimitive;
 
210
                                const COLLADAFW::UIntValuesArray& faceVertexCountArray = tristrips->getGroupedVerticesVertexCountArray();
 
211
 
 
212
                                size_t triangleCount = faceVertexCountArray[mCurrentStripFanIndex] - 2;
 
213
 
 
214
                                if ( (mCurrentTriangleInTriStripFanIndex + 1) < triangleCount )
 
215
                                {
 
216
                                        // use next in same triangle
 
217
 
 
218
                                        mCurrentTriangleInTriStripFanIndex++;
 
219
                                        size_t firstIndex = mCurrentTrianglePositionsArrayIndex + mCurrentTriangleInTriStripFanIndex;
 
220
                                        if ( mCurrentTriangleInTriStripFanIndex % 2 == 0 )
 
221
                                        {
 
222
                                                return TriangleType(positionsIndices[firstIndex], positionsIndices[firstIndex+1],positionsIndices[firstIndex+2], materialId);
 
223
                                        }
 
224
                                        else
 
225
                                        {
 
226
                                                return TriangleType(positionsIndices[firstIndex], positionsIndices[firstIndex+2],positionsIndices[firstIndex+1], materialId);
 
227
                                        }
 
228
                                }
 
229
                                else
 
230
                                {
 
231
                                        if ( (mCurrentStripFanIndex + 1) < faceVertexCountArray.getCount() )
 
232
                                        {
 
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);
 
239
                                        }
 
240
                                        else
 
241
                                        {
 
242
                                                return getTriangle( mCurrentTriangleIndex );
 
243
                                        }
 
244
                                }
 
245
                        }
 
246
                case COLLADAFW::MeshPrimitive::TRIANGLE_FANS:
 
247
                        {
 
248
                                const COLLADAFW::Trifans* trifans = (const COLLADAFW::Trifans*)meshPrimitive;
 
249
                                const COLLADAFW::UIntValuesArray& faceVertexCountArray = trifans->getGroupedVerticesVertexCountArray();
 
250
 
 
251
 
 
252
                                size_t triangleCount = faceVertexCountArray[mCurrentStripFanIndex] - 2;
 
253
 
 
254
                                if ( (mCurrentTriangleInTriStripFanIndex + 1) < triangleCount )
 
255
                                {
 
256
                                        // use next in same triangle
 
257
 
 
258
                                        mCurrentTriangleInTriStripFanIndex++;
 
259
                                        size_t firstIndex = mCurrentTrianglePositionsArrayIndex + mCurrentTriangleInTriStripFanIndex;
 
260
                                        TriangleType triangle(positionsIndices[mCurrentTrianglePositionsArrayIndex], positionsIndices[firstIndex+1],positionsIndices[firstIndex+2], materialId);
 
261
                                        return triangle;
 
262
                                }
 
263
                                else
 
264
                                {
 
265
                                        if ( (mCurrentStripFanIndex + 1) < faceVertexCountArray.getCount() )
 
266
                                        {
 
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);
 
273
                                                return triangle;
 
274
                                        }
 
275
                                        else
 
276
                                        {
 
277
                                                return getTriangle( mCurrentTriangleIndex );
 
278
                                        }
 
279
                                }
 
280
                        }
 
281
                default:
 
282
                        assert(false);
 
283
                        return TriangleType(0, 0, 0, 0);
 
284
                }
 
285
 
 
286
 
 
287
        }
 
288
 
 
289
 
 
290
} // namespace DAE23ds