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

Revision 2111, 6.9 KB checked in by mattausch, 17 years ago (diff)
Line 
1#include "ObjMeshData.h"
2#include "ObjReader.h"
3
4
5ObjMeshData::ObjMeshData()
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
13ObjMeshData::~ObjMeshData()
14{
15}
16
17void ObjMeshData::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 ObjMeshData::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 *ObjMeshData::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 *ObjMeshData::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
96
97int ObjMeshData::getNextFaceSize(int start)
98{
99        for (int i=start; i < icnt; i++)
100        {
101                if (indices[i] < 0.f) return i - start;
102        }
103        return icnt - start;
104}
105
106
107Ogre::Real *ObjMeshData::expandFaceSetIndices(Ogre::Real *indices, int icnt, int *icntOut)
108{
109        if (indices[icnt-1] >= 0.0)
110                *icntOut = (icnt+1 - 3*(getSeparatorCnt(indices, icnt)+1))*3;
111        else
112                *icntOut = (icnt - 3*getSeparatorCnt(indices, icnt))*3;
113        Ogre::Real *indOut = new Ogre::Real[*icntOut];
114
115        int index = 0, size = 0;
116        for (int i=0; i < icnt; i++)
117        {
118                if ((size = getNextFaceSize(i)) < 3) break;
119                for (int j=0; j < size-2; j++)
120                {
121                        indOut[index] = indices[i]; index++;
122                        indOut[index] = indices[i+1+j]; index++;
123                        indOut[index] = indices[i+2+j]; index++;
124                }
125                i = i + size;
126        }
127        return indOut;
128}
129
130ObjMeshData *ObjMeshData::expand()
131{
132        using namespace Ogre;
133
134        ObjMeshData *mDataOut = new ObjMeshData();
135
136        mDataOut->boundingBox = calcBoundingBox();
137        if ((vertices == NULL) || (vcnt <= 0) || (indices == NULL) || (icnt <= 0))
138        {
139                if (IVReader::IVLog != NULL)
140                {
141                        std::string message = "Expand-Error: ((vertices == NULL) || (vcnt <= 0) || (indices == NULL) || (icnt <= 0))";
142                        IVReader::IVLog->logMessage(message);
143                }
144       
145                return mDataOut;
146        }
147        bool nOk, tOk, niOk, tiOk, nperv, tperv;
148        nOk = ((normals != NULL) && (ncnt > 0));
149        tOk = ((texCoords != NULL) && (tcnt > 0));
150        nperv = (ncnt == vcnt) && (nicnt != icnt);
151        tperv = (tcnt*3 == vcnt*2) && (ticnt != icnt);
152
153        if ((nOk && !nperv) || (tOk && !tperv))
154        {
155                niOk = ((normalIndices != NULL) && (nicnt == icnt));
156                tiOk = ((texCoordIndices != NULL) && (ticnt == icnt));
157
158                if (!nperv && nOk && !niOk) nOk = false;
159                if (!tperv && tOk && !tiOk) tOk = false;
160
161                int sepcnt = getSeparatorCnt(indices, icnt);
162                mDataOut->icnt = icnt;
163                mDataOut->vcnt = (icnt - sepcnt)*3;
164                mDataOut->vertices = new Real[mDataOut->vcnt];
165
166                if (nOk)
167                {
168                        mDataOut->ncnt = mDataOut->vcnt;
169                        mDataOut->normals = new Real[mDataOut->ncnt];
170                }
171                if (tOk)
172                {
173                        mDataOut->tcnt = (icnt - sepcnt)*2;
174                        mDataOut->texCoords = new Real[mDataOut->tcnt];
175                }
176                mDataOut->indices = new Real[mDataOut->icnt];
177
178                int index = 0;
179                for (int i=0; i < icnt; i++)
180                {
181                        if (indices[i] >= 0.f)
182                        {
183                                mDataOut->vertices[index*3]   = vertices[(int)indices[i]*3];
184                                mDataOut->vertices[index*3+1] = vertices[(int)indices[i]*3+1];
185                                mDataOut->vertices[index*3+2] = vertices[(int)indices[i]*3+2];
186
187                                if (nOk)
188                                {
189                                        if (nperv)
190                                        {
191                                                mDataOut->normals[index*3]   = normals[(int)indices[i]*3];
192                                                mDataOut->normals[index*3+1] = normals[(int)indices[i]*3+1];
193                                                mDataOut->normals[index*3+2] = normals[(int)indices[i]*3+2];
194                                        }
195                                        else
196                                        {
197                                                mDataOut->normals[index*3]   = normals[(int)normalIndices[i]*3];
198                                                mDataOut->normals[index*3+1] = normals[(int)normalIndices[i]*3+1];
199                                                mDataOut->normals[index*3+2] = normals[(int)normalIndices[i]*3+2];
200                                        }
201                                }
202                                if (tOk)
203                                {
204                                        if (tperv)
205                                        {
206                                                mDataOut->texCoords[index*2]   = texCoords[(int)indices[i]*2];
207                                                mDataOut->texCoords[index*2+1] = texCoords[(int)indices[i]*2+1];
208                                        }
209                                        else
210                                        {
211                                                mDataOut->texCoords[index*2]   = texCoords[(int)texCoordIndices[i]*2];
212                                                mDataOut->texCoords[index*2+1] = texCoords[(int)texCoordIndices[i]*2+1];
213                                        }
214                                }
215
216                                mDataOut->indices[i] = index;
217                                index++;
218                        }
219                        else mDataOut->indices[i] = indices[i];
220                }
221        }
222        else
223        {
224                mDataOut->icnt = icnt;
225                mDataOut->indices = new Real[mDataOut->icnt];
226                memcpy(mDataOut->indices, indices, mDataOut->icnt*sizeof(Real));
227
228                mDataOut->vcnt = vcnt;
229                mDataOut->vertices = new Real[mDataOut->vcnt];
230                memcpy(mDataOut->vertices, vertices, mDataOut->vcnt*sizeof(Real));
231
232                if (nOk)
233                {
234                        mDataOut->ncnt = ncnt;
235                        mDataOut->normals = new Real[mDataOut->ncnt];
236                        memcpy(mDataOut->normals, normals, mDataOut->ncnt*sizeof(Real));
237                }
238                if (tOk)
239                {
240                        mDataOut->tcnt = tcnt;
241                        mDataOut->texCoords = new Real[mDataOut->tcnt];
242                        memcpy(mDataOut->texCoords, texCoords, mDataOut->tcnt*sizeof(Real));
243                }
244
245        }
246
247        int icntNew = 0;
248        Real *indicesNew = NULL;
249        mDataOut->roType = roType;
250
251        if (mDataOut->roType == IV_ROT_TRIANGLE_STRIP) 
252        {       
253                indicesNew = expandTriangleStripIndices(mDataOut->indices, mDataOut->icnt, &icntNew);
254        }
255        else if (mDataOut->roType == IV_ROT_FACE_SET)
256        {
257                indicesNew = expandFaceSetIndices(mDataOut->indices, mDataOut->icnt, &icntNew);
258        }
259        else
260        {
261                return mDataOut;
262        }
263        delete [] mDataOut->indices;
264        mDataOut->indices = indicesNew;
265        mDataOut->icnt = icntNew;
266
267        return mDataOut;
268}
Note: See TracBrowser for help on using the repository browser.