source: GTP/trunk/Lib/Vis/OnlineCullingCHC/ObjReader/src/ObjMeshData.cpp @ 2109

Revision 2109, 6.9 KB checked in by mattausch, 17 years ago (diff)
Line 
1#include "ivmeshdata.h"
2#include "ivreader.h"
3
4
5IVMeshData::IVMeshData()
6{
7        vertices = normals = texCoords = indices = normalIndices = texCoordIndices = NULL;
8        vcnt = ncnt = tcnt = icnt = nicnt = ticnt = 0;
9        roType = IV_ROT_INVALID;
10        boundingBox = NULL;
11}
12
13IVMeshData::~IVMeshData()
14{
15}
16
17void IVMeshData::collapse()
18{
19        if (indices != NULL)    delete [] indices;
20        if (vertices != NULL)   delete [] vertices;
21        if (normals != NULL)    delete [] normals;
22        if (texCoords != NULL)  delete [] texCoords;
23        if (normalIndices != NULL) delete [] normalIndices;
24        if (texCoordIndices != NULL) delete [] texCoordIndices;
25        if (boundingBox != NULL) delete boundingBox;
26        indices = vertices = normals = texCoords = normalIndices = texCoords = NULL;
27        boundingBox = NULL;
28}
29
30int IVMeshData::getSeparatorCnt(Ogre::Real *data, int end)
31{
32        int cnt = 0;
33        for (int i=0; i < end; i++) if (data[i] < 0.f) cnt++;
34        return cnt;
35}
36
37Ogre::AxisAlignedBox *IVMeshData::calcBoundingBox()
38{
39        if ((vertices == NULL) || (vcnt <=0))
40                return new Ogre::AxisAlignedBox(0, 0, 0, 0, 0, 0);
41
42        Ogre::Real x, y, z, minX, minY, minZ, maxX, maxY, maxZ;
43        minX = minY = minZ = 999999;
44        maxX = maxY = maxZ = -999999;
45       
46        for (int i=0; i<vcnt/3; i++)
47        {
48                x = vertices[i*3];
49                if (minX > x) minX = x; if (maxX < x) maxX = x;
50                y = vertices[i*3+1];
51                if (minY > y) minY = y; if (maxY < y) maxY = y;
52                z = vertices[i*3+2];
53                if (minZ > z) minZ = z; if (maxZ < z) maxZ = z;
54        }
55       
56        return new Ogre::AxisAlignedBox(minX, minY, minZ, maxX, maxY, maxZ);
57}
58
59
60Ogre::Real *IVMeshData::expandTriangleStripIndices(Ogre::Real *indices, int icnt, int *icntOut)
61{
62        if (indices[icnt-1] >= 0.0)
63                *icntOut = (icnt+1 - 3*(getSeparatorCnt(indices, icnt)+1))*3;
64        else
65                *icntOut = (icnt - 3*getSeparatorCnt(indices, icnt))*3;
66
67        Ogre::Real *indOut = new Ogre::Real[*icntOut];
68
69        int triangleCnt = 0, tc = 0;
70        for (int i=2; i < icnt; i++)
71        {
72                if (indices[i] >= 0)
73                {
74                        if (tc % 2 == 0)
75                        {
76                                indOut[triangleCnt*3]   = indices[i-2];
77                                indOut[triangleCnt*3+1] = indices[i-1];
78                                indOut[triangleCnt*3+2] = indices[i];
79                        }
80                        else
81                        {
82                                indOut[triangleCnt*3]   = indices[i];
83                                indOut[triangleCnt*3+1] = indices[i-1];
84                                indOut[triangleCnt*3+2] = indices[i-2];
85                        }
86                        triangleCnt++; tc++;
87                }
88                else
89                {
90                        i += 2; tc = 0;
91                }
92        }
93        return indOut;
94}       
95
96int IVMeshData::getNextFaceSize(int start)
97{
98        for (int i=start; i < icnt; i++)
99        {
100                if (indices[i] < 0.f) return i - start;
101        }
102        return icnt - start;
103}
104
105Ogre::Real *IVMeshData::expandFaceSetIndices(Ogre::Real *indices, int icnt, int *icntOut)
106{
107        if (indices[icnt-1] >= 0.0)
108                *icntOut = (icnt+1 - 3*(getSeparatorCnt(indices, icnt)+1))*3;
109        else
110                *icntOut = (icnt - 3*getSeparatorCnt(indices, icnt))*3;
111        Ogre::Real *indOut = new Ogre::Real[*icntOut];
112
113        int index = 0, size = 0;
114        for (int i=0; i < icnt; i++)
115        {
116                if ((size = getNextFaceSize(i)) < 3) break;
117                for (int j=0; j < size-2; j++)
118                {
119                        indOut[index] = indices[i]; index++;
120                        indOut[index] = indices[i+1+j]; index++;
121                        indOut[index] = indices[i+2+j]; index++;
122                }
123                i = i + size;
124        }
125        return indOut;
126}
127
128IVMeshData *IVMeshData::expand()
129{
130        using namespace Ogre;
131
132        IVMeshData *mDataOut = new IVMeshData();
133
134        mDataOut->boundingBox = calcBoundingBox();
135        if ((vertices == NULL) || (vcnt <= 0) || (indices == NULL) || (icnt <= 0))
136        {
137                if (IVReader::IVLog != NULL)
138                {
139                        std::string message = "Expand-Error: ((vertices == NULL) || (vcnt <= 0) || (indices == NULL) || (icnt <= 0))";
140                        IVReader::IVLog->logMessage(message);
141                }
142       
143                return mDataOut;
144        }
145        bool nOk, tOk, niOk, tiOk, nperv, tperv;
146        nOk = ((normals != NULL) && (ncnt > 0));
147        tOk = ((texCoords != NULL) && (tcnt > 0));
148        nperv = (ncnt == vcnt) && (nicnt != icnt);
149        tperv = (tcnt*3 == vcnt*2) && (ticnt != icnt);
150
151        if ((nOk && !nperv) || (tOk && !tperv))
152        {
153                niOk = ((normalIndices != NULL) && (nicnt == icnt));
154                tiOk = ((texCoordIndices != NULL) && (ticnt == icnt));
155
156                if (!nperv && nOk && !niOk) nOk = false;
157                if (!tperv && tOk && !tiOk) tOk = false;
158
159                int sepcnt = getSeparatorCnt(indices, icnt);
160                mDataOut->icnt = icnt;
161                mDataOut->vcnt = (icnt - sepcnt)*3;
162                mDataOut->vertices = new Real[mDataOut->vcnt];
163
164                if (nOk)
165                {
166                        mDataOut->ncnt = mDataOut->vcnt;
167                        mDataOut->normals = new Real[mDataOut->ncnt];
168                }
169                if (tOk)
170                {
171                        mDataOut->tcnt = (icnt - sepcnt)*2;
172                        mDataOut->texCoords = new Real[mDataOut->tcnt];
173                }
174                mDataOut->indices = new Real[mDataOut->icnt];
175
176                int index = 0;
177                for (int i=0; i < icnt; i++)
178                {
179                        if (indices[i] >= 0.f)
180                        {
181                                mDataOut->vertices[index*3]   = vertices[(int)indices[i]*3];
182                                mDataOut->vertices[index*3+1] = vertices[(int)indices[i]*3+1];
183                                mDataOut->vertices[index*3+2] = vertices[(int)indices[i]*3+2];
184
185                                if (nOk)
186                                {
187                                        if (nperv)
188                                        {
189                                                mDataOut->normals[index*3]   = normals[(int)indices[i]*3];
190                                                mDataOut->normals[index*3+1] = normals[(int)indices[i]*3+1];
191                                                mDataOut->normals[index*3+2] = normals[(int)indices[i]*3+2];
192                                        }
193                                        else
194                                        {
195                                                mDataOut->normals[index*3]   = normals[(int)normalIndices[i]*3];
196                                                mDataOut->normals[index*3+1] = normals[(int)normalIndices[i]*3+1];
197                                                mDataOut->normals[index*3+2] = normals[(int)normalIndices[i]*3+2];
198                                        }
199                                }
200                                if (tOk)
201                                {
202                                        if (tperv)
203                                        {
204                                                mDataOut->texCoords[index*2]   = texCoords[(int)indices[i]*2];
205                                                mDataOut->texCoords[index*2+1] = texCoords[(int)indices[i]*2+1];
206                                        }
207                                        else
208                                        {
209                                                mDataOut->texCoords[index*2]   = texCoords[(int)texCoordIndices[i]*2];
210                                                mDataOut->texCoords[index*2+1] = texCoords[(int)texCoordIndices[i]*2+1];
211                                        }
212                                }
213
214                                mDataOut->indices[i] = index;
215                                index++;
216                        }
217                        else mDataOut->indices[i] = indices[i];
218                }
219        }
220        else
221        {
222                mDataOut->icnt = icnt;
223                mDataOut->indices = new Real[mDataOut->icnt];
224                memcpy(mDataOut->indices, indices, mDataOut->icnt*sizeof(Real));
225
226                mDataOut->vcnt = vcnt;
227                mDataOut->vertices = new Real[mDataOut->vcnt];
228                memcpy(mDataOut->vertices, vertices, mDataOut->vcnt*sizeof(Real));
229
230                if (nOk)
231                {
232                        mDataOut->ncnt = ncnt;
233                        mDataOut->normals = new Real[mDataOut->ncnt];
234                        memcpy(mDataOut->normals, normals, mDataOut->ncnt*sizeof(Real));
235                }
236                if (tOk)
237                {
238                        mDataOut->tcnt = tcnt;
239                        mDataOut->texCoords = new Real[mDataOut->tcnt];
240                        memcpy(mDataOut->texCoords, texCoords, mDataOut->tcnt*sizeof(Real));
241                }
242
243        }
244
245        int icntNew = 0;
246        Real *indicesNew = NULL;
247        mDataOut->roType = roType;
248
249        if (mDataOut->roType == IV_ROT_TRIANGLE_STRIP) 
250        {       
251                indicesNew = expandTriangleStripIndices(mDataOut->indices, mDataOut->icnt, &icntNew);
252        }
253        else if (mDataOut->roType == IV_ROT_FACE_SET)
254        {
255                indicesNew = expandFaceSetIndices(mDataOut->indices, mDataOut->icnt, &icntNew);
256        }
257        else
258        {
259                return mDataOut;
260        }
261        delete [] mDataOut->indices;
262        mDataOut->indices = indicesNew;
263        mDataOut->icnt = icntNew;
264
265        return mDataOut;
266}
Note: See TracBrowser for help on using the repository browser.