[dali_2.3.21] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-physics / third-party / bullet3 / src / Bullet3Serialize / Bullet2FileLoader / b3BulletFile.cpp
1 /*
2 bParse
3 Copyright (c) 2006-2010 Erwin Coumans  http://gamekit.googlecode.com
4
5 This software is provided 'as-is', without any express or implied warranty.
6 In no event will the authors be held liable for any damages arising from the use of this software.
7 Permission is granted to anyone to use this software for any purpose,
8 including commercial applications, and to alter it and redistribute it freely,
9 subject to the following restrictions:
10
11 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13 3. This notice may not be removed or altered from any source distribution.
14 */
15
16 #include "b3BulletFile.h"
17 #include "b3Defines.h"
18 #include "b3DNA.h"
19
20 #if !defined(__CELLOS_LV2__) && !defined(__MWERKS__)
21 #include <memory.h>
22 #endif
23 #include <string.h>
24
25 // 32 && 64 bit versions
26 #ifdef B3_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
27 #ifdef _WIN64
28 extern char b3s_bulletDNAstr64[];
29 extern int b3s_bulletDNAlen64;
30 #else
31 extern char b3s_bulletDNAstr[];
32 extern int b3s_bulletDNAlen;
33 #endif  //_WIN64
34 #else   //B3_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
35
36 extern char b3s_bulletDNAstr64[];
37 extern int b3s_bulletDNAlen64;
38 extern char b3s_bulletDNAstr[];
39 extern int b3s_bulletDNAlen;
40
41 #endif  //B3_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
42
43 using namespace bParse;
44
45 b3BulletFile::b3BulletFile()
46         : bFile("", "BULLET ")
47 {
48         mMemoryDNA = new bDNA();  //this memory gets released in the bFile::~bFile destructor,@todo not consistent with the rule 'who allocates it, has to deallocate it"
49
50         m_DnaCopy = 0;
51
52 #ifdef B3_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
53 #ifdef _WIN64
54         m_DnaCopy = (char*)b3AlignedAlloc(b3s_bulletDNAlen64, 16);
55         memcpy(m_DnaCopy, b3s_bulletDNAstr64, b3s_bulletDNAlen64);
56         mMemoryDNA->init(m_DnaCopy, b3s_bulletDNAlen64);
57 #else   //_WIN64
58         m_DnaCopy = (char*)b3AlignedAlloc(b3s_bulletDNAlen, 16);
59         memcpy(m_DnaCopy, b3s_bulletDNAstr, b3s_bulletDNAlen);
60         mMemoryDNA->init(m_DnaCopy, b3s_bulletDNAlen);
61 #endif  //_WIN64
62 #else   //B3_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
63         if (VOID_IS_8)
64         {
65                 m_DnaCopy = (char*)b3AlignedAlloc(b3s_bulletDNAlen64, 16);
66                 memcpy(m_DnaCopy, b3s_bulletDNAstr64, b3s_bulletDNAlen64);
67                 mMemoryDNA->init(m_DnaCopy, b3s_bulletDNAlen64);
68         }
69         else
70         {
71                 m_DnaCopy = (char*)b3AlignedAlloc(b3s_bulletDNAlen, 16);
72                 memcpy(m_DnaCopy, b3s_bulletDNAstr, b3s_bulletDNAlen);
73                 mMemoryDNA->init(m_DnaCopy, b3s_bulletDNAlen);
74         }
75 #endif  //B3_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
76 }
77
78 b3BulletFile::b3BulletFile(const char* fileName)
79         : bFile(fileName, "BULLET ")
80 {
81         m_DnaCopy = 0;
82 }
83
84 b3BulletFile::b3BulletFile(char* memoryBuffer, int len)
85         : bFile(memoryBuffer, len, "BULLET ")
86 {
87         m_DnaCopy = 0;
88 }
89
90 b3BulletFile::~b3BulletFile()
91 {
92         if (m_DnaCopy)
93                 b3AlignedFree(m_DnaCopy);
94
95         while (m_dataBlocks.size())
96         {
97                 char* dataBlock = m_dataBlocks[m_dataBlocks.size() - 1];
98                 delete[] dataBlock;
99                 m_dataBlocks.pop_back();
100         }
101 }
102
103 // ----------------------------------------------------- //
104 void b3BulletFile::parseData()
105 {
106         //      printf ("Building datablocks");
107         //      printf ("Chunk size = %d",CHUNK_HEADER_LEN);
108         //      printf ("File chunk size = %d",ChunkUtils::getOffset(mFlags));
109
110         const bool brokenDNA = (mFlags & FD_BROKEN_DNA) != 0;
111
112         //const bool swap = (mFlags&FD_ENDIAN_SWAP)!=0;
113
114         mDataStart = 12;
115
116         char* dataPtr = mFileBuffer + mDataStart;
117
118         bChunkInd dataChunk;
119         dataChunk.code = 0;
120
121         //dataPtr += ChunkUtils::getNextBlock(&dataChunk, dataPtr, mFlags);
122         int seek = getNextBlock(&dataChunk, dataPtr, mFlags);
123
124         if (mFlags & FD_ENDIAN_SWAP)
125                 swapLen(dataPtr);
126
127         //dataPtr += ChunkUtils::getOffset(mFlags);
128         char* dataPtrHead = 0;
129
130         while (dataChunk.code != B3_DNA1)
131         {
132                 if (!brokenDNA || (dataChunk.code != B3_QUANTIZED_BVH_CODE))
133                 {
134                         // one behind
135                         if (dataChunk.code == B3_SDNA) break;
136                         //if (dataChunk.code == DNA1) break;
137
138                         // same as (BHEAD+DATA dependency)
139                         dataPtrHead = dataPtr + ChunkUtils::getOffset(mFlags);
140                         if (dataChunk.dna_nr >= 0)
141                         {
142                                 char* id = readStruct(dataPtrHead, dataChunk);
143
144                                 // lookup maps
145                                 if (id)
146                                 {
147                                         m_chunkPtrPtrMap.insert(dataChunk.oldPtr, dataChunk);
148                                         mLibPointers.insert(dataChunk.oldPtr, (bStructHandle*)id);
149
150                                         m_chunks.push_back(dataChunk);
151                                         // block it
152                                         //bListBasePtr *listID = mMain->getListBasePtr(dataChunk.code);
153                                         //if (listID)
154                                         //      listID->push_back((bStructHandle*)id);
155                                 }
156
157                                 if (dataChunk.code == B3_SOFTBODY_CODE)
158                                 {
159                                         m_softBodies.push_back((bStructHandle*)id);
160                                 }
161
162                                 if (dataChunk.code == B3_RIGIDBODY_CODE)
163                                 {
164                                         m_rigidBodies.push_back((bStructHandle*)id);
165                                 }
166
167                                 if (dataChunk.code == B3_DYNAMICSWORLD_CODE)
168                                 {
169                                         m_dynamicsWorldInfo.push_back((bStructHandle*)id);
170                                 }
171
172                                 if (dataChunk.code == B3_CONSTRAINT_CODE)
173                                 {
174                                         m_constraints.push_back((bStructHandle*)id);
175                                 }
176
177                                 if (dataChunk.code == B3_QUANTIZED_BVH_CODE)
178                                 {
179                                         m_bvhs.push_back((bStructHandle*)id);
180                                 }
181
182                                 if (dataChunk.code == B3_TRIANLGE_INFO_MAP)
183                                 {
184                                         m_triangleInfoMaps.push_back((bStructHandle*)id);
185                                 }
186
187                                 if (dataChunk.code == B3_COLLISIONOBJECT_CODE)
188                                 {
189                                         m_collisionObjects.push_back((bStructHandle*)id);
190                                 }
191
192                                 if (dataChunk.code == B3_SHAPE_CODE)
193                                 {
194                                         m_collisionShapes.push_back((bStructHandle*)id);
195                                 }
196
197                                 //              if (dataChunk.code == GLOB)
198                                 //              {
199                                 //                      m_glob = (bStructHandle*) id;
200                                 //              }
201                         }
202                         else
203                         {
204                                 //printf("unknown chunk\n");
205
206                                 mLibPointers.insert(dataChunk.oldPtr, (bStructHandle*)dataPtrHead);
207                         }
208                 }
209                 else
210                 {
211                         printf("skipping B3_QUANTIZED_BVH_CODE due to broken DNA\n");
212                 }
213
214                 dataPtr += seek;
215
216                 seek = getNextBlock(&dataChunk, dataPtr, mFlags);
217                 if (mFlags & FD_ENDIAN_SWAP)
218                         swapLen(dataPtr);
219
220                 if (seek < 0)
221                         break;
222         }
223 }
224
225 void b3BulletFile::addDataBlock(char* dataBlock)
226 {
227         m_dataBlocks.push_back(dataBlock);
228 }
229
230 void b3BulletFile::writeDNA(FILE* fp)
231 {
232         bChunkInd dataChunk;
233         dataChunk.code = B3_DNA1;
234         dataChunk.dna_nr = 0;
235         dataChunk.nr = 1;
236 #ifdef B3_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
237         if (VOID_IS_8)
238         {
239 #ifdef _WIN64
240                 dataChunk.len = b3s_bulletDNAlen64;
241                 dataChunk.oldPtr = b3s_bulletDNAstr64;
242                 fwrite(&dataChunk, sizeof(bChunkInd), 1, fp);
243                 fwrite(b3s_bulletDNAstr64, b3s_bulletDNAlen64, 1, fp);
244 #else
245                 b3Assert(0);
246 #endif
247         }
248         else
249         {
250 #ifndef _WIN64
251                 dataChunk.len = b3s_bulletDNAlen;
252                 dataChunk.oldPtr = b3s_bulletDNAstr;
253                 fwrite(&dataChunk, sizeof(bChunkInd), 1, fp);
254                 fwrite(b3s_bulletDNAstr, b3s_bulletDNAlen, 1, fp);
255 #else   //_WIN64
256                 b3Assert(0);
257 #endif  //_WIN64
258         }
259 #else   //B3_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
260         if (VOID_IS_8)
261         {
262                 dataChunk.len = b3s_bulletDNAlen64;
263                 dataChunk.oldPtr = b3s_bulletDNAstr64;
264                 fwrite(&dataChunk, sizeof(bChunkInd), 1, fp);
265                 fwrite(b3s_bulletDNAstr64, b3s_bulletDNAlen64, 1, fp);
266         }
267         else
268         {
269                 dataChunk.len = b3s_bulletDNAlen;
270                 dataChunk.oldPtr = b3s_bulletDNAstr;
271                 fwrite(&dataChunk, sizeof(bChunkInd), 1, fp);
272                 fwrite(b3s_bulletDNAstr, b3s_bulletDNAlen, 1, fp);
273         }
274 #endif  //B3_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
275 }
276
277 void b3BulletFile::parse(int verboseMode)
278 {
279 #ifdef B3_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
280         if (VOID_IS_8)
281         {
282 #ifdef _WIN64
283
284                 if (m_DnaCopy)
285                         delete m_DnaCopy;
286                 m_DnaCopy = (char*)b3AlignedAlloc(b3s_bulletDNAlen64, 16);
287                 memcpy(m_DnaCopy, b3s_bulletDNAstr64, b3s_bulletDNAlen64);
288                 parseInternal(verboseMode, (char*)b3s_bulletDNAstr64, b3s_bulletDNAlen64);
289 #else
290                 b3Assert(0);
291 #endif
292         }
293         else
294         {
295 #ifndef _WIN64
296
297                 if (m_DnaCopy)
298                         delete m_DnaCopy;
299                 m_DnaCopy = (char*)b3AlignedAlloc(b3s_bulletDNAlen, 16);
300                 memcpy(m_DnaCopy, b3s_bulletDNAstr, b3s_bulletDNAlen);
301                 parseInternal(verboseMode, m_DnaCopy, b3s_bulletDNAlen);
302 #else
303                 b3Assert(0);
304 #endif
305         }
306 #else   //B3_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
307         if (VOID_IS_8)
308         {
309                 if (m_DnaCopy)
310                         delete m_DnaCopy;
311                 m_DnaCopy = (char*)b3AlignedAlloc(b3s_bulletDNAlen64, 16);
312                 memcpy(m_DnaCopy, b3s_bulletDNAstr64, b3s_bulletDNAlen64);
313                 parseInternal(verboseMode, m_DnaCopy, b3s_bulletDNAlen64);
314         }
315         else
316         {
317                 if (m_DnaCopy)
318                         delete m_DnaCopy;
319                 m_DnaCopy = (char*)b3AlignedAlloc(b3s_bulletDNAlen, 16);
320                 memcpy(m_DnaCopy, b3s_bulletDNAstr, b3s_bulletDNAlen);
321                 parseInternal(verboseMode, m_DnaCopy, b3s_bulletDNAlen);
322         }
323 #endif  //B3_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
324
325         //the parsing will convert to cpu endian
326         mFlags &= ~FD_ENDIAN_SWAP;
327
328         int littleEndian = 1;
329         littleEndian = ((char*)&littleEndian)[0];
330
331         mFileBuffer[8] = littleEndian ? 'v' : 'V';
332 }
333
334 // experimental
335 int b3BulletFile::write(const char* fileName, bool fixupPointers)
336 {
337         FILE* fp = fopen(fileName, "wb");
338         if (fp)
339         {
340                 char header[B3_SIZEOFBLENDERHEADER];
341                 memcpy(header, m_headerString, 7);
342                 int endian = 1;
343                 endian = ((char*)&endian)[0];
344
345                 if (endian)
346                 {
347                         header[7] = '_';
348                 }
349                 else
350                 {
351                         header[7] = '-';
352                 }
353                 if (VOID_IS_8)
354                 {
355                         header[8] = 'V';
356                 }
357                 else
358                 {
359                         header[8] = 'v';
360                 }
361
362                 header[9] = '2';
363                 header[10] = '7';
364                 header[11] = '5';
365
366                 fwrite(header, B3_SIZEOFBLENDERHEADER, 1, fp);
367
368                 writeChunks(fp, fixupPointers);
369
370                 writeDNA(fp);
371
372                 fclose(fp);
373         }
374         else
375         {
376                 printf("Error: cannot open file %s for writing\n", fileName);
377                 return 0;
378         }
379         return 1;
380 }
381
382 void b3BulletFile::addStruct(const char* structType, void* data, int len, void* oldPtr, int code)
383 {
384         bParse::bChunkInd dataChunk;
385         dataChunk.code = code;
386         dataChunk.nr = 1;
387         dataChunk.len = len;
388         dataChunk.dna_nr = mMemoryDNA->getReverseType(structType);
389         dataChunk.oldPtr = oldPtr;
390
391         ///Perform structure size validation
392         short* structInfo = mMemoryDNA->getStruct(dataChunk.dna_nr);
393         int elemBytes;
394         elemBytes = mMemoryDNA->getLength(structInfo[0]);
395         //      int elemBytes = mMemoryDNA->getElementSize(structInfo[0],structInfo[1]);
396         assert(len == elemBytes);
397
398         mLibPointers.insert(dataChunk.oldPtr, (bStructHandle*)data);
399         m_chunks.push_back(dataChunk);
400 }