Bullet Collision Detection & Physics Library: bFile.cpp Source File

Bullet Collision Detection & Physics Library

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

bFile.cpp
Go to the documentation of this file.
1 /*
2 bParse
3 Copyright (c) 2006-2009 Charlie C & 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 #include "bFile.h"
16 #include "bCommon.h"
17 #include "bChunk.h"
18 #include "bDNA.h"
19 #include <math.h>
20 #include <string.h>
21 #include <stdlib.h>
22 #include "bDefines.h"
23 #include "LinearMath/btSerializer.h"
24 #include "LinearMath/btAlignedAllocator.h"
25 #include "LinearMath/btMinMax.h"
26
27 #define SIZEOFBLENDERHEADER 12
28 #define MAX_ARRAY_LENGTH 512
29 using namespace bParse;
30 #define MAX_STRLEN 1024
31
32 const char* getCleanName(const char* memName, char* buffer)
33 {
34 int slen = strlen(memName);
35 assert(slen<MAX_STRLEN);
36 slen=btMin(slen,MAX_STRLEN);
37 for (int i=0;i<slen;i++)
38 {
39 if (memName[i]==']'||memName[i]=='[')
40 {
41 buffer[i] = 0;//'_';
42 } else
43 {
44 buffer[i] = memName[i];
45 }
46 }
47 buffer[slen]=0;
48 return buffer;
49 }
50
51
52 int numallocs = 0;
53
54 // ----------------------------------------------------- //
55 bFile::bFile(const char *filename, const char headerString[7])
56 : mOwnsBuffer(true),
57 mFileBuffer(0),
58 mFileLen(0),
59 mVersion(0),
60 mDataStart(0),
61 mFileDNA(0),
62 mMemoryDNA(0),
63 mFlags(FD_INVALID)
64 {
65 for (int i=0;i<7;i++)
66 {
67 m_headerString[i] = headerString[i];
68 }
69
70 FILE *fp = fopen(filename, "rb");
71 if (fp)
72 {
73 fseek(fp, 0L, SEEK_END);
74 mFileLen = ftell(fp);
75 fseek(fp, 0L, SEEK_SET);
76
77 mFileBuffer = (char*)malloc(mFileLen+1);
78 fread(mFileBuffer, mFileLen, 1, fp);
79
80 fclose(fp);
81
82 //
83 parseHeader();
84
85 }
86 }
87
88 // ----------------------------------------------------- //
89 bFile::bFile( char *memoryBuffer, int len, const char headerString[7])
90 : mOwnsBuffer(false),
91 mFileBuffer(0),
92 mFileLen(0),
93 mVersion(0),
94 mDataStart(0),
95 mFileDNA(0),
96 mMemoryDNA(0),
97 mFlags(FD_INVALID)
98 {
99 for (int i=0;i<7;i++)
100 {
101 m_headerString[i] = headerString[i];
102 }
103 mFileBuffer = memoryBuffer;
104 mFileLen = len;
105
106 parseHeader();
107
108 }
109
110
111 // ----------------------------------------------------- //
112 bFile::~bFile()
113 {
114 if (mOwnsBuffer && mFileBuffer)
115 {
116 free(mFileBuffer);
117 mFileBuffer = 0;
118 }
119
120
121 delete mMemoryDNA;
122 delete mFileDNA;
123 }
124
125
126
127
128
129 // ----------------------------------------------------- //
130 void bFile::parseHeader()
131 {
132 if (!mFileLen || !mFileBuffer)
133 return;
134
135 char *blenderBuf = mFileBuffer;
136 char header[SIZEOFBLENDERHEADER+1] ;
137 memcpy(header, blenderBuf, SIZEOFBLENDERHEADER);
138 header[SIZEOFBLENDERHEADER]='\0';
139
140 if (strncmp(header, m_headerString, 6)!=0)
141 {
142 memcpy(header, m_headerString, SIZEOFBLENDERHEADER);
143 return;
144 }
145
146 if (header[6] == 'd')
147 {
148 mFlags |= FD_DOUBLE_PRECISION;
149 }
150
151 char *ver = header+9;
152 mVersion = atoi(ver);
153 if (mVersion <= 241)
154 {
155 //printf("Warning, %d not fully tested : <= 242\n", mVersion);
156 }
157
158 int littleEndian= 1;
159 littleEndian= ((char*)&littleEndian)[0];
160
161 // swap ptr sizes...
162 if (header[7]=='-')
163 {
164 mFlags |= FD_FILE_64;
165 if (!VOID_IS_8)
166 mFlags |= FD_BITS_VARIES;
167 }
168 else if (VOID_IS_8) mFlags |= FD_BITS_VARIES;
169
170 // swap endian...
171 if (header[8]=='V')
172 {
173 if (littleEndian ==1)
174 mFlags |= FD_ENDIAN_SWAP;
175 }
176 else
177 if (littleEndian==0)
178 mFlags |= FD_ENDIAN_SWAP;
179
180
181 mFlags |= FD_OK;
182 }
183
184 // ----------------------------------------------------- //
185 bool bFile::ok()
186 {
187 return (mFlags &FD_OK)!=0;
188 }
189
190 void bFile::setFileDNA(int verboseMode, char* dnaBuffer, int dnaLen)
191 {
192 mFileDNA = new bDNA();
193
195 mFileDNA->init((char*)dnaBuffer, dnaLen, (mFlags & FD_ENDIAN_SWAP)!=0);
196
197 if (verboseMode & FD_VERBOSE_DUMP_DNA_TYPE_DEFINITIONS)
198 mFileDNA->dumpTypeDefinitions();
199 }
200
201 // ----------------------------------------------------- //
202 void bFile::parseInternal(int verboseMode, char* memDna,int memDnaLength)
203 {
204 if ( (mFlags &FD_OK) ==0)
205 return;
206
207 if (mFlags & FD_FILEDNA_IS_MEMDNA)
208 {
209 setFileDNA(verboseMode,memDna,memDnaLength);
210 }
211
212 if (mFileDNA==0)
213 {
214 char *blenderData = mFileBuffer;
215 bChunkInd dna;
216 dna.oldPtr = 0;
217
218 char *tempBuffer = blenderData;
219 for (int i=0; i<mFileLen; i++)
220 {
221 // looking for the data's starting position
222 // and the start of SDNA decls
223
224 if (!mDataStart && strncmp(tempBuffer, "REND", 4)==0)
225 mDataStart = i;
226
227 if (strncmp(tempBuffer, "DNA1", 4)==0)
228 {
229 // read the DNA1 block and extract SDNA
230 if (getNextBlock(&dna, tempBuffer, mFlags) > 0)
231 {
232 if (strncmp((tempBuffer + ChunkUtils::getOffset(mFlags)), "SDNANAME", 8) ==0)
233 dna.oldPtr = (tempBuffer + ChunkUtils::getOffset(mFlags));
234 else dna.oldPtr = 0;
235 }
236 else dna.oldPtr = 0;
237 }
238 // Some Bullet files are missing the DNA1 block
239 // In Blender it's DNA1 + ChunkUtils::getOffset() + SDNA + NAME
240 // In Bullet tests its SDNA + NAME
241 else if (strncmp(tempBuffer, "SDNANAME", 8) ==0)
242 {
243 dna.oldPtr = blenderData + i;
244 dna.len = mFileLen-i;
245
246 // Also no REND block, so exit now.
247 if (mVersion==276) break;
248 }
249
250 if (mDataStart && dna.oldPtr) break;
251 tempBuffer++;
252 }
253 if (!dna.oldPtr || !dna.len)
254 {
255 //printf("Failed to find DNA1+SDNA pair\n");
256 mFlags &= ~FD_OK;
257 return;
258 }
259
260
261 mFileDNA = new bDNA();
262
263
265 mFileDNA->init((char*)dna.oldPtr, dna.len, (mFlags & FD_ENDIAN_SWAP)!=0);
266
267
268 if (mVersion==276)
269 {
270 int i;
271 for (i=0;i<mFileDNA->getNumNames();i++)
272 {
273 if (strcmp(mFileDNA->getName(i),"int")==0)
274 {
275 mFlags |= FD_BROKEN_DNA;
276 }
277 }
278 if ((mFlags&FD_BROKEN_DNA)!=0)
279 {
280 //printf("warning: fixing some broken DNA version\n");
281 }
282 }
283
284
285
286 if (verboseMode & FD_VERBOSE_DUMP_DNA_TYPE_DEFINITIONS)
287 mFileDNA->dumpTypeDefinitions();
288 }
289 mMemoryDNA = new bDNA();
290 int littleEndian= 1;
291 littleEndian= ((char*)&littleEndian)[0];
292
293 mMemoryDNA->init(memDna,memDnaLength,littleEndian==0);
294
295
296
297
299 if (mMemoryDNA->getNumNames() != mFileDNA->getNumNames())
300 {
301 mFlags |= FD_VERSION_VARIES;
302 //printf ("Warning, file DNA is different than built in, performance is reduced. Best to re-export file with a matching version/platform");
303 }
304
305 // as long as it kept up to date it will be ok!!
306 if (mMemoryDNA->lessThan(mFileDNA))
307 {
308 //printf ("Warning, file DNA is newer than built in.");
309 }
310
311
312 mFileDNA->initCmpFlags(mMemoryDNA);
313
314 parseData();
315
316 resolvePointers(verboseMode);
317
318 updateOldPointers();
319
320
321 }
322
323
324
325 // ----------------------------------------------------- //
326 void bFile::swap(char *head, bChunkInd& dataChunk, bool ignoreEndianFlag)
327 {
328 char *data = head;
329 short *strc = mFileDNA->getStruct(dataChunk.dna_nr);
330
331
332
333 const char s[] = "SoftBodyMaterialData";
334 int szs = sizeof(s);
335 if (strncmp((char*)&dataChunk.code,"ARAY",4)==0)
336 {
337 short *oldStruct = mFileDNA->getStruct(dataChunk.dna_nr);
338 char *oldType = mFileDNA->getType(oldStruct[0]);
339 if (strncmp(oldType,s,szs)==0)
340 {
341 return;
342 }
343 }
344
345
346 int len = mFileDNA->getLength(strc[0]);
347
348 for (int i=0; i<dataChunk.nr; i++)
349 {
350 swapStruct(dataChunk.dna_nr, data,ignoreEndianFlag);
351 data+=len;
352 }
353 }
354
355 void bFile::swapLen(char *dataPtr)
356 {
357 const bool VOID_IS_8 = ((sizeof(void*)==8));
358 if (VOID_IS_8)
359 {
360 if (mFlags &FD_BITS_VARIES)
361 {
362 bChunkPtr4*c = (bChunkPtr4*) dataPtr;
363 if ((c->code & 0xFFFF)==0)
364 c->code >>=16;
365 SWITCH_INT(c->len);
366 SWITCH_INT(c->dna_nr);
367 SWITCH_INT(c->nr);
368 } else
369 {
370 bChunkPtr8* c = (bChunkPtr8*) dataPtr;
371 if ((c->code & 0xFFFF)==0)
372 c->code >>=16;
373 SWITCH_INT(c->len);
374 SWITCH_INT(c->dna_nr);
375 SWITCH_INT(c->nr);
376
377 }
378 } else
379 {
380 if (mFlags &FD_BITS_VARIES)
381 {
382 bChunkPtr8*c = (bChunkPtr8*) dataPtr;
383 if ((c->code & 0xFFFF)==0)
384 c->code >>=16;
385 SWITCH_INT(c->len);
386 SWITCH_INT(c->dna_nr);
387 SWITCH_INT(c->nr);
388
389 } else
390 {
391 bChunkPtr4* c = (bChunkPtr4*) dataPtr;
392 if ((c->code & 0xFFFF)==0)
393 c->code >>=16;
394 SWITCH_INT(c->len);
395
396 SWITCH_INT(c->dna_nr);
397 SWITCH_INT(c->nr);
398
399 }
400 }
401
402 }
403
404
405 void bFile::swapDNA(char* ptr)
406 {
407 bool swap = ((mFlags & FD_ENDIAN_SWAP)!=0);
408
409 int offset = (mFlags & FD_FILE_64)? 24 : 20;
410 char* data = &ptr[offset];
411
412 // void bDNA::init(char *data, int len, bool swap)
413 int *intPtr=0;short *shtPtr=0;
414 char *cp = 0;int dataLen =0;long nr=0;
415 intPtr = (int*)data;
416
417 /*
418 SDNA (4 bytes) (magic number)
419 NAME (4 bytes)
420 <nr> (4 bytes) amount of names (int)
421 <string>
422 <string>
423 */
424
425 if (strncmp(data, "SDNA", 4)==0)
426 {
427 // skip ++ NAME
428 intPtr++;
429 intPtr++;
430 } else
431 {
432
433 if (strncmp(data+4, "SDNA", 4)==0)
434 {
435 // skip ++ NAME
436 intPtr++;
437 intPtr++;
438 intPtr++;
439 }
440 }
441
442
443
444
445 // Parse names
446 if (swap)
447 dataLen = ChunkUtils::swapInt(*intPtr);
448 else
449 dataLen = *intPtr;
450
451 *intPtr = ChunkUtils::swapInt(*intPtr);
452 intPtr++;
453
454 cp = (char*)intPtr;
455 int i;
456 for ( i=0; i<dataLen; i++)
457 {
458 while (*cp)cp++;
459 cp++;
460 }
461
462
463 {
464 nr= (long)cp;
465 //long mask=3;
466 nr= ((nr+3)&~3)-nr;
467 while (nr--)
468 {
469 cp++;
470 }
471 }
472
473
474 /*
475 TYPE (4 bytes)
476 <nr> amount of types (int)
477 <string>
478 <string>
479 */
480
481 intPtr = (int*)cp;
482 assert(strncmp(cp, "TYPE", 4)==0); intPtr++;
483
484 if (swap)
485 dataLen = ChunkUtils::swapInt(*intPtr);
486 else
487 dataLen = *intPtr;
488
489 *intPtr = ChunkUtils::swapInt(*intPtr);
490
491 intPtr++;
492
493 cp = (char*)intPtr;
494 for ( i=0; i<dataLen; i++)
495 {
496 while (*cp)cp++;
497 cp++;
498 }
499
500 {
501 nr= (long)cp;
502 // long mask=3;
503 nr= ((nr+3)&~3)-nr;
504 while (nr--)
505 {
506 cp++;
507 }
508 }
509
510
511 /*
512 TLEN (4 bytes)
513 <len> (short) the lengths of types
514 <len>
515 */
516
517 // Parse type lens
518 intPtr = (int*)cp;
519 assert(strncmp(cp, "TLEN", 4)==0); intPtr++;
520
521
522 shtPtr = (short*)intPtr;
523 for ( i=0; i<dataLen; i++, shtPtr++)
524 {
525 //??????if (swap)
526 shtPtr[0] = ChunkUtils::swapShort(shtPtr[0]);
527 }
528
529 if (dataLen & 1)
530 shtPtr++;
531
532 /*
533 STRC (4 bytes)
534 <nr> amount of structs (int)
535 <typenr>
536 <nr_of_elems>
537 <typenr>
538 <namenr>
539 <typenr>
540 <namenr>
541 */
542
543 intPtr = (int*)shtPtr;
544 cp = (char*)intPtr;
545 assert(strncmp(cp, "STRC", 4)==0);
546 intPtr++;
547
548 if (swap)
549 dataLen = ChunkUtils::swapInt(*intPtr);
550 else
551 dataLen = *intPtr;
552
553 *intPtr = ChunkUtils::swapInt(*intPtr);
554
555 intPtr++;
556
557
558 shtPtr = (short*)intPtr;
559 for ( i=0; i<dataLen; i++)
560 {
561
562 //if (swap)
563 {
564 int len = shtPtr[1];
565
566 shtPtr[0]= ChunkUtils::swapShort(shtPtr[0]);
567 shtPtr[1]= ChunkUtils::swapShort(shtPtr[1]);
568
569 shtPtr+= 2;
570
571 for (int a=0; a<len; a++, shtPtr+=2)
572 {
573 shtPtr[0]= ChunkUtils::swapShort(shtPtr[0]);
574 shtPtr[1]= ChunkUtils::swapShort(shtPtr[1]);
575 }
576 }
577 // else
578 // shtPtr+= (2*shtPtr[1])+2;
579 }
580
581 }
582
583 void bFile::writeFile(const char* fileName)
584 {
585 FILE* f = fopen(fileName,"wb");
586 fwrite(mFileBuffer,1,mFileLen,f);
587 fclose(f);
588 }
589
590 void bFile::preSwap()
591 {
592
593 const bool brokenDNA = (mFlags&FD_BROKEN_DNA)!=0;
594 //FD_ENDIAN_SWAP
595 //byte 8 determines the endianness of the file, little (v) versus big (V)
596 int littleEndian= 1;
597 littleEndian= ((char*)&littleEndian)[0];
598
599
600 if (mFileBuffer[8]=='V')
601 {
602 mFileBuffer[8]='v';
603 }
604 else
605 {
606 mFileBuffer[8]='V';
607 }
608
609
610
611
612
613
614 mDataStart = 12;
615
616 char *dataPtr = mFileBuffer+mDataStart;
617
618 bChunkInd dataChunk;
619 dataChunk.code = 0;
620 bool ignoreEndianFlag = true;
621
622 //we always want to swap here
623
624 int seek = getNextBlock(&dataChunk, dataPtr, mFlags);
625 //dataPtr += ChunkUtils::getOffset(mFlags);
626 char *dataPtrHead = 0;
627
628 while (1)
629 {
630 // one behind
631 if (dataChunk.code == SDNA || dataChunk.code==DNA1 || dataChunk.code == TYPE || dataChunk.code == TLEN || dataChunk.code==STRC)
632 {
633
634 swapDNA(dataPtr);
635 break;
636 } else
637 {
638 //if (dataChunk.code == DNA1) break;
639 dataPtrHead = dataPtr+ChunkUtils::getOffset(mFlags);
640
641 swapLen(dataPtr);
642 if (dataChunk.dna_nr>=0)
643 {
644 swap(dataPtrHead, dataChunk,ignoreEndianFlag);
645 } else
646 {
647 printf("unknown chunk\n");
648 }
649 }
650
651 // next please!
652 dataPtr += seek;
653
654 seek = getNextBlock(&dataChunk, dataPtr, mFlags);
655 if (seek < 0)
656 break;
657 }
658
659 if (mFlags & FD_ENDIAN_SWAP)
660 {
661 mFlags &= ~FD_ENDIAN_SWAP;
662 } else
663 {
664 mFlags |= FD_ENDIAN_SWAP;
665 }
666
667
668
669 }
670
671
672 // ----------------------------------------------------- //
673 char* bFile::readStruct(char *head, bChunkInd& dataChunk)
674 {
675 bool ignoreEndianFlag = false;
676
677 if (mFlags & FD_ENDIAN_SWAP)
678 swap(head, dataChunk, ignoreEndianFlag);
679
680
681
682 if (!mFileDNA->flagEqual(dataChunk.dna_nr))
683 {
684 // Ouch! need to rebuild the struct
685 short *oldStruct,*curStruct;
686 char *oldType, *newType;
687 int oldLen, curLen, reverseOld;
688
689
690 oldStruct = mFileDNA->getStruct(dataChunk.dna_nr);
691 oldType = mFileDNA->getType(oldStruct[0]);
692
693 oldLen = mFileDNA->getLength(oldStruct[0]);
694
695 if ((mFlags&FD_BROKEN_DNA)!=0)
696 {
697 if ((strcmp(oldType,"btQuantizedBvhNodeData")==0)&&oldLen==20)
698 {
699 return 0;
700 }
701 if ((strcmp(oldType,"btShortIntIndexData")==0))
702 {
703 int allocLen = 2;
704 char *dataAlloc = new char[(dataChunk.nr*allocLen)+1];
705 memset(dataAlloc, 0, (dataChunk.nr*allocLen)+1);
706 short* dest = (short*) dataAlloc;
707 const short* src = (short*) head;
708 for (int i=0;i<dataChunk.nr;i++)
709 {
710 dest[i] = src[i];
711 if (mFlags &FD_ENDIAN_SWAP)
712 {
713 SWITCH_SHORT(dest[i]);
714 }
715 }
716 addDataBlock(dataAlloc);
717 return dataAlloc;
718 }
719 }
720
721
722
724 if (strcmp("Link",oldType)!=0)
725 {
726 reverseOld = mMemoryDNA->getReverseType(oldType);
727
728 if ((reverseOld!=-1))
729 {
730 // make sure it's here
731 //assert(reverseOld!= -1 && "getReverseType() returned -1, struct required!");
732
733 //
734 curStruct = mMemoryDNA->getStruct(reverseOld);
735 newType = mMemoryDNA->getType(curStruct[0]);
736 curLen = mMemoryDNA->getLength(curStruct[0]);
737
738
739
740 // make sure it's the same
741 assert((strcmp(oldType, newType)==0) && "internal error, struct mismatch!");
742
743
744 numallocs++;
745 // numBlocks * length
746
747 int allocLen = (curLen);
748 char *dataAlloc = new char[(dataChunk.nr*allocLen)+1];
749 memset(dataAlloc, 0, (dataChunk.nr*allocLen));
750
751 // track allocated
752 addDataBlock(dataAlloc);
753
754 char *cur = dataAlloc;
755 char *old = head;
756 for (int block=0; block<dataChunk.nr; block++)
757 {
758 bool fixupPointers = true;
759 parseStruct(cur, old, dataChunk.dna_nr, reverseOld, fixupPointers);
760 mLibPointers.insert(old,(bStructHandle*)cur);
761
762 cur += curLen;
763 old += oldLen;
764 }
765 return dataAlloc;
766 }
767 } else
768 {
769 //printf("Link found\n");
770 }
771 } else
772 {
773 //#define DEBUG_EQUAL_STRUCTS
774 #ifdef DEBUG_EQUAL_STRUCTS
775 short *oldStruct;
776 char *oldType;
777 oldStruct = mFileDNA->getStruct(dataChunk.dna_nr);
778 oldType = mFileDNA->getType(oldStruct[0]);
779 printf("%s equal structure, just memcpy\n",oldType);
780 #endif //
781 }
782
783
784 char *dataAlloc = new char[(dataChunk.len)+1];
785 memset(dataAlloc, 0, dataChunk.len+1);
786
787
788 // track allocated
789 addDataBlock(dataAlloc);
790
791 memcpy(dataAlloc, head, dataChunk.len);
792 return dataAlloc;
793
794 }
795
796
797 // ----------------------------------------------------- //
798 void bFile::parseStruct(char *strcPtr, char *dtPtr, int old_dna, int new_dna, bool fixupPointers)
799 {
800 if (old_dna == -1) return;
801 if (new_dna == -1) return;
802
803 //disable this, because we need to fixup pointers/ListBase
804 if (0)//mFileDNA->flagEqual(old_dna))
805 {
806 short *strc = mFileDNA->getStruct(old_dna);
807 int len = mFileDNA->getLength(strc[0]);
808
809 memcpy(strcPtr, dtPtr, len);
810 return;
811 }
812
813 // Ok, now build the struct
814 char *memType, *memName, *cpc, *cpo;
815 short *fileStruct, *filePtrOld, *memoryStruct, *firstStruct;
816 int elementLength, size, revType, old_nr, new_nr, fpLen;
817 short firstStructType;
818
819
820 // File to memory lookup
821 memoryStruct = mMemoryDNA->getStruct(new_dna);
822 fileStruct = mFileDNA->getStruct(old_dna);
823 firstStruct = fileStruct;
824
825
826 filePtrOld = fileStruct;
827 firstStructType = mMemoryDNA->getStruct(0)[0];
828
829 // Get number of elements
830 elementLength = memoryStruct[1];
831 memoryStruct+=2;
832
833 cpc = strcPtr; cpo = 0;
834 for (int ele=0; ele<elementLength; ele++, memoryStruct+=2)
835 {
836 memType = mMemoryDNA->getType(memoryStruct[0]);
837 memName = mMemoryDNA->getName(memoryStruct[1]);
838
839
840 size = mMemoryDNA->getElementSize(memoryStruct[0], memoryStruct[1]);
841 revType = mMemoryDNA->getReverseType(memoryStruct[0]);
842
843 if (revType != -1 && memoryStruct[0]>=firstStructType && memName[0] != '*')
844 {
845 cpo = getFileElement(firstStruct, memName, memType, dtPtr, &filePtrOld);
846 if (cpo)
847 {
848 int arrayLen = mFileDNA->getArraySizeNew(filePtrOld[1]);
849 old_nr = mFileDNA->getReverseType(memType);
850 new_nr = revType;
851 fpLen = mFileDNA->getElementSize(filePtrOld[0], filePtrOld[1]);
852 if (arrayLen==1)
853 {
854 parseStruct(cpc, cpo, old_nr, new_nr,fixupPointers);
855 } else
856 {
857 char* tmpCpc = cpc;
858 char* tmpCpo = cpo;
859
860 for (int i=0;i<arrayLen;i++)
861 {
862 parseStruct(tmpCpc, tmpCpo, old_nr, new_nr,fixupPointers);
863 tmpCpc += size/arrayLen;
864 tmpCpo += fpLen/arrayLen;
865 }
866 }
867 cpc+=size;
868 cpo+=fpLen;
869 }
870 else
871 cpc+=size;
872 }
873 else
874 {
875 getMatchingFileDNA(fileStruct, memName, memType, cpc, dtPtr,fixupPointers);
876 cpc+=size;
877 }
878
879 }
880 }
881
882
883 // ----------------------------------------------------- //
884 static void getElement(int arrayLen, const char *cur, const char *old, char *oldPtr, char *curData)
885 {
886 #define getEle(value, current, type, cast, size, ptr)\
887 if (strcmp(current, type)==0)\
888 {\
889 value = (*(cast*)ptr);\
890 ptr += size;\
891 }
892
893 #define setEle(value, current, type, cast, size, ptr)\
894 if (strcmp(current, type)==0)\
895 {\
896 (*(cast*)ptr) = (cast)value;\
897 ptr += size;\
898 }
899 double value = 0.0;
900
901 for (int i=0; i<arrayLen; i++)
902 {
903 getEle(value, old, "char", char, sizeof(char), oldPtr);
904 setEle(value, cur, "char", char, sizeof(char), curData);
905 getEle(value, old, "short", short, sizeof(short), oldPtr);
906 setEle(value, cur, "short", short, sizeof(short), curData);
907 getEle(value, old, "ushort", unsigned short, sizeof(unsigned short), oldPtr);
908 setEle(value, cur, "ushort", unsigned short, sizeof(unsigned short), curData);
909 getEle(value, old, "int", int, sizeof(int), oldPtr);
910 setEle(value, cur, "int", int, sizeof(int), curData);
911 getEle(value, old, "long", int, sizeof(int), oldPtr);
912 setEle(value, cur, "long", int, sizeof(int), curData);
913 getEle(value, old, "float", float, sizeof(float), oldPtr);
914 setEle(value, cur, "float", float, sizeof(float), curData);
915 getEle(value, old, "double", double, sizeof(double), oldPtr);
916 setEle(value, cur, "double", double, sizeof(double), curData);
917 }
918 }
919
920
921 // ----------------------------------------------------- //
922 void bFile::swapData(char *data, short type, int arraySize,bool ignoreEndianFlag)
923 {
924 if (ignoreEndianFlag || (mFlags &FD_ENDIAN_SWAP))
925 {
926 if (type == 2 || type == 3)
927 {
928 short *sp = (short*)data;
929 for (int i=0; i<arraySize; i++)
930 {
931 sp[0] = ChunkUtils::swapShort(sp[0]);
932 sp++;
933 }
934 }
935 if (type>3 && type <8)
936 {
937 char c;
938 char *cp = data;
939 for (int i=0; i<arraySize; i++)
940 {
941 c = cp[0];
942 cp[0] = cp[3];
943 cp[3] = c;
944 c = cp[1];
945 cp[1] = cp[2];
946 cp[2] = c;
947 cp+=4;
948 }
949 }
950 }
951 }
952
953
954
955 void bFile::safeSwapPtr(char *dst, const char *src)
956 {
957 int ptrFile = mFileDNA->getPointerSize();
958 int ptrMem = mMemoryDNA->getPointerSize();
959
960 if (!src && !dst)
961 return;
962
963
964 if (ptrFile == ptrMem)
965 {
966 memcpy(dst, src, ptrMem);
967 }
968 else if (ptrMem==4 && ptrFile==8)
969 {
970 btPointerUid* oldPtr = (btPointerUid*)src;
971 btPointerUid* newPtr = (btPointerUid*)dst;
972
973 if (oldPtr->m_uniqueIds[0] == oldPtr->m_uniqueIds[1])
974 {
975 //Bullet stores the 32bit unique ID in both upper and lower part of 64bit pointers
976 //so it can be used to distinguish between .blend and .bullet
977 newPtr->m_uniqueIds[0] = oldPtr->m_uniqueIds[0];
978 } else
979 {
980 //deal with pointers the Blender .blend style way, see
981 //readfile.c in the Blender source tree
982 long64 longValue = *((long64*)src);
983 //endian swap for 64bit pointer otherwise truncation will fail due to trailing zeros
984 if (mFlags & FD_ENDIAN_SWAP)
985 SWITCH_LONGINT(longValue);
986 *((int*)dst) = (int)(longValue>>3);
987 }
988
989 }
990 else if (ptrMem==8 && ptrFile==4)
991 {
992 btPointerUid* oldPtr = (btPointerUid*)src;
993 btPointerUid* newPtr = (btPointerUid*)dst;
994 if (oldPtr->m_uniqueIds[0] == oldPtr->m_uniqueIds[1])
995 {
996 newPtr->m_uniqueIds[0] = oldPtr->m_uniqueIds[0];
997 newPtr->m_uniqueIds[1] = 0;
998 } else
999 {
1000 *((long64*)dst)= *((int*)src);
1001 }
1002 }
1003 else
1004 {
1005 printf ("%d %d\n", ptrFile,ptrMem);
1006 assert(0 && "Invalid pointer len");
1007 }
1008
1009
1010 }
1011
1012
1013 // ----------------------------------------------------- //
1014 void bFile::getMatchingFileDNA(short* dna_addr, const char* lookupName, const char* lookupType, char *strcData, char *data, bool fixupPointers)
1015 {
1016 // find the matching memory dna data
1017 // to the file being loaded. Fill the
1018 // memory with the file data...
1019
1020 int len = dna_addr[1];
1021 dna_addr+=2;
1022
1023 for (int i=0; i<len; i++, dna_addr+=2)
1024 {
1025 const char* type = mFileDNA->getType(dna_addr[0]);
1026 const char* name = mFileDNA->getName(dna_addr[1]);
1027
1028
1029
1030 int eleLen = mFileDNA->getElementSize(dna_addr[0], dna_addr[1]);
1031
1032 if ((mFlags&FD_BROKEN_DNA)!=0)
1033 {
1034 if ((strcmp(type,"short")==0)&&(strcmp(name,"int")==0))
1035 {
1036 eleLen = 0;
1037 }
1038 }
1039
1040 if (strcmp(lookupName, name)==0)
1041 {
1042 //int arrayLenold = mFileDNA->getArraySize((char*)name.c_str());
1043 int arrayLen = mFileDNA->getArraySizeNew(dna_addr[1]);
1044 //assert(arrayLenold == arrayLen);
1045
1046 if (name[0] == '*')
1047 {
1048 // cast pointers
1049 int ptrFile = mFileDNA->getPointerSize();
1050 int ptrMem = mMemoryDNA->getPointerSize();
1051 safeSwapPtr(strcData,data);
1052
1053 if (fixupPointers)
1054 {
1055 if (arrayLen > 1)
1056 {
1057 //void **sarray = (void**)strcData;
1058 //void **darray = (void**)data;
1059
1060 char *cpc, *cpo;
1061 cpc = (char*)strcData;
1062 cpo = (char*)data;
1063
1064 for (int a=0; a<arrayLen; a++)
1065 {
1066 safeSwapPtr(cpc, cpo);
1067 m_pointerFixupArray.push_back(cpc);
1068 cpc += ptrMem;
1069 cpo += ptrFile;
1070 }
1071 }
1072 else
1073 {
1074 if (name[1] == '*')
1075 m_pointerPtrFixupArray.push_back(strcData);
1076 else
1077 m_pointerFixupArray.push_back(strcData);
1078 }
1079 }
1080 else
1081 {
1082 // printf("skipped %s %s : %x\n",type.c_str(),name.c_str(),strcData);
1083 }
1084
1085 }
1086
1087 else if (strcmp(type, lookupType)==0)
1088 memcpy(strcData, data, eleLen);
1089 else
1090 getElement(arrayLen, lookupType, type, data, strcData);
1091
1092 // --
1093 return;
1094 }
1095 data+=eleLen;
1096 }
1097 }
1098
1099
1100 // ----------------------------------------------------- //
1101 char* bFile::getFileElement(short *firstStruct, char *lookupName, char *lookupType, char *data, short **foundPos)
1102 {
1103 short *old = firstStruct;//mFileDNA->getStruct(old_nr);
1104 int elementLength = old[1];
1105 old+=2;
1106
1107 for (int i=0; i<elementLength; i++, old+=2)
1108 {
1109 char* type = mFileDNA->getType(old[0]);
1110 char* name = mFileDNA->getName(old[1]);
1111 int len = mFileDNA->getElementSize(old[0], old[1]);
1112
1113 if (strcmp(lookupName, name)==0)
1114 {
1115 if (strcmp(type, lookupType)==0)
1116 {
1117 if (foundPos)
1118 *foundPos = old;
1119 return data;
1120 }
1121 return 0;
1122 }
1123 data+=len;
1124 }
1125 return 0;
1126 }
1127
1128
1129 // ----------------------------------------------------- //
1130 void bFile::swapStruct(int dna_nr, char *data,bool ignoreEndianFlag)
1131 {
1132 if (dna_nr == -1) return;
1133
1134 short *strc = mFileDNA->getStruct(dna_nr);
1135 //short *firstStrc = strc;
1136
1137 int elementLen= strc[1];
1138 strc+=2;
1139
1140 short first = mFileDNA->getStruct(0)[0];
1141
1142 char *buf = data;
1143 for (int i=0; i<elementLen; i++, strc+=2)
1144 {
1145 char *type = mFileDNA->getType(strc[0]);
1146 char *name = mFileDNA->getName(strc[1]);
1147
1148 int size = mFileDNA->getElementSize(strc[0], strc[1]);
1149 if (strc[0] >= first && name[0]!='*')
1150 {
1151 int old_nr = mFileDNA->getReverseType(type);
1152 int arrayLen = mFileDNA->getArraySizeNew(strc[1]);
1153 if (arrayLen==1)
1154 {
1155 swapStruct(old_nr,buf,ignoreEndianFlag);
1156 } else
1157 {
1158 char* tmpBuf = buf;
1159 for (int i=0;i<arrayLen;i++)
1160 {
1161 swapStruct(old_nr,tmpBuf,ignoreEndianFlag);
1162 tmpBuf+=size/arrayLen;
1163 }
1164 }
1165 }
1166 else
1167 {
1168 //int arrayLenOld = mFileDNA->getArraySize(name);
1169 int arrayLen = mFileDNA->getArraySizeNew(strc[1]);
1170 //assert(arrayLenOld == arrayLen);
1171 swapData(buf, strc[0], arrayLen,ignoreEndianFlag);
1172 }
1173 buf+=size;
1174 }
1175 }
1176
1177 void bFile::resolvePointersMismatch()
1178 {
1179 // printf("resolvePointersStructMismatch\n");
1180
1181 int i;
1182
1183 for (i=0;i< m_pointerFixupArray.size();i++)
1184 {
1185 char* cur = m_pointerFixupArray.at(i);
1186 void** ptrptr = (void**) cur;
1187 void* ptr = *ptrptr;
1188 ptr = findLibPointer(ptr);
1189 if (ptr)
1190 {
1191 //printf("Fixup pointer!\n");
1192 *(ptrptr) = ptr;
1193 } else
1194 {
1195 // printf("pointer not found: %x\n",cur);
1196 }
1197 }
1198
1199
1200 for (i=0; i<m_pointerPtrFixupArray.size(); i++)
1201 {
1202 char* cur= m_pointerPtrFixupArray.at(i);
1203 void** ptrptr = (void**)cur;
1204
1205 bChunkInd *block = m_chunkPtrPtrMap.find(*ptrptr);
1206 if (block)
1207 {
1208 int ptrMem = mMemoryDNA->getPointerSize();
1209 int ptrFile = mFileDNA->getPointerSize();
1210
1211
1212 int blockLen = block->len / ptrFile;
1213
1214 void *onptr = findLibPointer(*ptrptr);
1215 if (onptr)
1216 {
1217 char *newPtr = new char[blockLen * ptrMem];
1218 addDataBlock(newPtr);
1219 memset(newPtr, 0, blockLen * ptrMem);
1220
1221 void **onarray = (void**)onptr;
1222 char *oldPtr = (char*)onarray;
1223
1224 int p = 0;
1225 while (blockLen-- > 0)
1226 {
1227 btPointerUid dp = {{0}};
1228 safeSwapPtr((char*)dp.m_uniqueIds, oldPtr);
1229
1230 void **tptr = (void**)(newPtr + p * ptrMem);
1231 *tptr = findLibPointer(dp.m_ptr);
1232
1233 oldPtr += ptrFile;
1234 ++p;
1235 }
1236
1237 *ptrptr = newPtr;
1238 }
1239 }
1240 }
1241 }
1242
1243
1245 void bFile::resolvePointersChunk(const bChunkInd& dataChunk, int verboseMode)
1246 {
1247 bParse::bDNA* fileDna = mFileDNA ? mFileDNA : mMemoryDNA;
1248
1249 short int* oldStruct = fileDna->getStruct(dataChunk.dna_nr);
1250 short oldLen = fileDna->getLength(oldStruct[0]);
1251 //char* structType = fileDna->getType(oldStruct[0]);
1252
1253 char* cur = (char*)findLibPointer(dataChunk.oldPtr);
1254 for (int block=0; block<dataChunk.nr; block++)
1255 {
1256 resolvePointersStructRecursive(cur,dataChunk.dna_nr, verboseMode,1);
1257 cur += oldLen;
1258 }
1259 }
1260
1261
1262 int bFile::resolvePointersStructRecursive(char *strcPtr, int dna_nr, int verboseMode,int recursion)
1263 {
1264
1265 bParse::bDNA* fileDna = mFileDNA ? mFileDNA : mMemoryDNA;
1266
1267 char* memType;
1268 char* memName;
1269 short firstStructType = fileDna->getStruct(0)[0];
1270
1271
1272 char* elemPtr= strcPtr;
1273
1274 short int* oldStruct = fileDna->getStruct(dna_nr);
1275
1276 int elementLength = oldStruct[1];
1277 oldStruct+=2;
1278
1279 int totalSize = 0;
1280
1281 for (int ele=0; ele<elementLength; ele++, oldStruct+=2)
1282 {
1283
1284 memType = fileDna->getType(oldStruct[0]);
1285 memName = fileDna->getName(oldStruct[1]);
1286
1287
1288
1289 int arrayLen = fileDna->getArraySizeNew(oldStruct[1]);
1290 if (memName[0] == '*')
1291 {
1292 if (arrayLen > 1)
1293 {
1294 void **array= (void**)elemPtr;
1295 for (int a=0; a<arrayLen; a++)
1296 {
1297 if (verboseMode & FD_VERBOSE_EXPORT_XML)
1298 {
1299 for (int i=0;i<recursion;i++)
1300 {
1301 printf(" ");
1302 }
1303 //skip the *
1304 printf("<%s type=\"pointer\"> ",&memName[1]);
1305 printf("%d ", array[a]);
1306 printf("</%s>\n",&memName[1]);
1307 }
1308
1309 array[a] = findLibPointer(array[a]);
1310 }
1311 }
1312 else
1313 {
1314 void** ptrptr = (void**) elemPtr;
1315 void* ptr = *ptrptr;
1316 if (verboseMode & FD_VERBOSE_EXPORT_XML)
1317 {
1318 for (int i=0;i<recursion;i++)
1319 {
1320 printf(" ");
1321 }
1322 printf("<%s type=\"pointer\"> ",&memName[1]);
1323 printf("%d ", ptr);
1324 printf("</%s>\n",&memName[1]);
1325 }
1326 ptr = findLibPointer(ptr);
1327
1328 if (ptr)
1329 {
1330 // printf("Fixup pointer at 0x%x from 0x%x to 0x%x!\n",ptrptr,*ptrptr,ptr);
1331 *(ptrptr) = ptr;
1332 if (memName[1] == '*' && ptrptr && *ptrptr)
1333 {
1334 // This will only work if the given **array is continuous
1335 void **array= (void**)*(ptrptr);
1336 void *np= array[0];
1337 int n=0;
1338 while (np)
1339 {
1340 np= findLibPointer(array[n]);
1341 if (np) array[n]= np;
1342 n++;
1343 }
1344 }
1345 } else
1346 {
1347 // printf("Cannot fixup pointer at 0x%x from 0x%x to 0x%x!\n",ptrptr,*ptrptr,ptr);
1348 }
1349 }
1350 } else
1351 {
1352 int revType = fileDna->getReverseType(oldStruct[0]);
1353 if (oldStruct[0]>=firstStructType) //revType != -1 &&
1354 {
1355 char cleanName[MAX_STRLEN];
1356 getCleanName(memName,cleanName);
1357
1358 int arrayLen = fileDna->getArraySizeNew(oldStruct[1]);
1359 int byteOffset = 0;
1360
1361 if (verboseMode & FD_VERBOSE_EXPORT_XML)
1362 {
1363 for (int i=0;i<recursion;i++)
1364 {
1365 printf(" ");
1366 }
1367
1368 if (arrayLen>1)
1369 {
1370 printf("<%s type=\"%s\" count=%d>\n",cleanName,memType, arrayLen);
1371 } else
1372 {
1373 printf("<%s type=\"%s\">\n",cleanName,memType);
1374 }
1375 }
1376
1377 for (int i=0;i<arrayLen;i++)
1378 {
1379 byteOffset += resolvePointersStructRecursive(elemPtr+byteOffset,revType, verboseMode,recursion+1);
1380 }
1381 if (verboseMode & FD_VERBOSE_EXPORT_XML)
1382 {
1383 for (int i=0;i<recursion;i++)
1384 {
1385 printf(" ");
1386 }
1387 printf("</%s>\n",cleanName);
1388 }
1389 } else
1390 {
1391 //export a simple type
1392 if (verboseMode & FD_VERBOSE_EXPORT_XML)
1393 {
1394
1395 if (arrayLen>MAX_ARRAY_LENGTH)
1396 {
1397 printf("too long\n");
1398 } else
1399 {
1400 //printf("%s %s\n",memType,memName);
1401
1402 bool isIntegerType = (strcmp(memType,"char")==0) || (strcmp(memType,"int")==0) || (strcmp(memType,"short")==0);
1403
1404 if (isIntegerType)
1405 {
1406 const char* newtype="int";
1407 int dbarray[MAX_ARRAY_LENGTH];
1408 int* dbPtr = 0;
1409 char* tmp = elemPtr;
1410 dbPtr = &dbarray[0];
1411 if (dbPtr)
1412 {
1413 char cleanName[MAX_STRLEN];
1414 getCleanName(memName,cleanName);
1415
1416 int i;
1417 getElement(arrayLen, newtype,memType, tmp, (char*)dbPtr);
1418 for (i=0;i<recursion;i++)
1419 printf(" ");
1420 if (arrayLen==1)
1421 printf("<%s type=\"%s\">",cleanName,memType);
1422 else
1423 printf("<%s type=\"%s\" count=%d>",cleanName,memType,arrayLen);
1424 for (i=0;i<arrayLen;i++)
1425 printf(" %d ",dbPtr[i]);
1426 printf("</%s>\n",cleanName);
1427 }
1428 } else
1429 {
1430 const char* newtype="double";
1431 double dbarray[MAX_ARRAY_LENGTH];
1432 double* dbPtr = 0;
1433 char* tmp = elemPtr;
1434 dbPtr = &dbarray[0];
1435 if (dbPtr)
1436 {
1437 int i;
1438 getElement(arrayLen, newtype,memType, tmp, (char*)dbPtr);
1439 for (i=0;i<recursion;i++)
1440 printf(" ");
1441 char cleanName[MAX_STRLEN];
1442 getCleanName(memName,cleanName);
1443
1444 if (arrayLen==1)
1445 {
1446 printf("<%s type=\"%s\">",memName,memType);
1447 }
1448 else
1449 {
1450 printf("<%s type=\"%s\" count=%d>",cleanName,memType,arrayLen);
1451 }
1452 for (i=0;i<arrayLen;i++)
1453 printf(" %f ",dbPtr[i]);
1454 printf("</%s>\n",cleanName);
1455 }
1456 }
1457 }
1458
1459 }
1460 }
1461 }
1462
1463 int size = fileDna->getElementSize(oldStruct[0], oldStruct[1]);
1464 totalSize += size;
1465 elemPtr+=size;
1466
1467 }
1468
1469 return totalSize;
1470 }
1471
1472
1474 void bFile::resolvePointers(int verboseMode)
1475 {
1476 bParse::bDNA* fileDna = mFileDNA ? mFileDNA : mMemoryDNA;
1477
1478 //char *dataPtr = mFileBuffer+mDataStart;
1479
1480 if (1) //mFlags & (FD_BITS_VARIES | FD_VERSION_VARIES))
1481 {
1482 resolvePointersMismatch();
1483 }
1484
1485 {
1486
1487 if (verboseMode & FD_VERBOSE_EXPORT_XML)
1488 {
1489 printf("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
1490 int numitems = m_chunks.size();
1491 printf("<bullet_physics version=%d itemcount = %d>\n", btGetVersion(), numitems);
1492 }
1493 for (int i=0;i<m_chunks.size();i++)
1494 {
1495 const bChunkInd& dataChunk = m_chunks.at(i);
1496
1497 if (!mFileDNA || fileDna->flagEqual(dataChunk.dna_nr))
1498 {
1499 //dataChunk.len
1500 short int* oldStruct = fileDna->getStruct(dataChunk.dna_nr);
1501 char* oldType = fileDna->getType(oldStruct[0]);
1502
1503 if (verboseMode & FD_VERBOSE_EXPORT_XML)
1504 printf(" <%s pointer=%d>\n",oldType,dataChunk.oldPtr);
1505
1506 resolvePointersChunk(dataChunk, verboseMode);
1507
1508 if (verboseMode & FD_VERBOSE_EXPORT_XML)
1509 printf(" </%s>\n",oldType);
1510 } else
1511 {
1512 //printf("skipping mStruct\n");
1513 }
1514 }
1515 if (verboseMode & FD_VERBOSE_EXPORT_XML)
1516 {
1517 printf("</bullet_physics>\n");
1518 }
1519 }
1520
1521
1522 }
1523
1524
1525 // ----------------------------------------------------- //
1526 void* bFile::findLibPointer(void *ptr)
1527 {
1528
1529 bStructHandle** ptrptr = getLibPointers().find(ptr);
1530 if (ptrptr)
1531 return *ptrptr;
1532 return 0;
1533 }
1534
1535
1536 void bFile::updateOldPointers()
1537 {
1538 int i;
1539
1540 for (i=0;i<m_chunks.size();i++)
1541 {
1542 bChunkInd& dataChunk = m_chunks[i];
1543 dataChunk.oldPtr = findLibPointer(dataChunk.oldPtr);
1544 }
1545 }
1546 void bFile::dumpChunks(bParse::bDNA* dna)
1547 {
1548 int i;
1549
1550 for (i=0;i<m_chunks.size();i++)
1551 {
1552 bChunkInd& dataChunk = m_chunks[i];
1553 char* codeptr = (char*)&dataChunk.code;
1554 char codestr[5] = {codeptr[0],codeptr[1],codeptr[2],codeptr[3],0};
1555
1556 short* newStruct = dna->getStruct(dataChunk.dna_nr);
1557 char* typeName = dna->getType(newStruct[0]);
1558 printf("%3d: %s ",i,typeName);
1559
1560 printf("code=%s ",codestr);
1561
1562 printf("ptr=%p ",dataChunk.oldPtr);
1563 printf("len=%d ",dataChunk.len);
1564 printf("nr=%d ",dataChunk.nr);
1565 if (dataChunk.nr!=1)
1566 {
1567 printf("not 1\n");
1568 }
1569 printf("\n");
1570
1571
1572
1573
1574 }
1575
1576 #if 0
1577 IDFinderData ifd;
1578 ifd.success = 0;
1579 ifd.IDname = NULL;
1580 ifd.just_print_it = 1;
1581 for (i=0; i<bf->m_blocks.size(); ++i)
1582 {
1583 BlendBlock* bb = bf->m_blocks[i];
1584 printf("tag='%s'\tptr=%p\ttype=%s\t[%4d]", bb->tag, bb,bf->types[bb->type_index].name,bb->m_array_entries_.size());
1585 block_ID_finder(bb, bf, &ifd);
1586 printf("\n");
1587 }
1588 #endif
1589
1590 }
1591
1592
1593 void bFile::writeChunks(FILE* fp, bool fixupPointers)
1594 {
1595 bParse::bDNA* fileDna = mFileDNA ? mFileDNA : mMemoryDNA;
1596
1597 for (int i=0;i<m_chunks.size();i++)
1598 {
1599 bChunkInd& dataChunk = m_chunks.at(i);
1600
1601 // Ouch! need to rebuild the struct
1602 short *oldStruct,*curStruct;
1603 char *oldType, *newType;
1604 int curLen, reverseOld;
1605
1606 oldStruct = fileDna->getStruct(dataChunk.dna_nr);
1607 oldType = fileDna->getType(oldStruct[0]);
1608 //int oldLen = fileDna->getLength(oldStruct[0]);
1610 reverseOld = mMemoryDNA->getReverseType(oldType);
1611
1612
1613 if ((reverseOld!=-1))
1614 {
1615 // make sure it's here
1616 //assert(reverseOld!= -1 && "getReverseType() returned -1, struct required!");
1617 //
1618 curStruct = mMemoryDNA->getStruct(reverseOld);
1619 newType = mMemoryDNA->getType(curStruct[0]);
1620 // make sure it's the same
1621 assert((strcmp(oldType, newType)==0) && "internal error, struct mismatch!");
1622
1623
1624 curLen = mMemoryDNA->getLength(curStruct[0]);
1625 dataChunk.dna_nr = reverseOld;
1626 if (strcmp("Link",oldType)!=0)
1627 {
1628 dataChunk.len = curLen * dataChunk.nr;
1629 } else
1630 {
1631 // printf("keep length of link = %d\n",dataChunk.len);
1632 }
1633
1634 //write the structure header
1635 fwrite(&dataChunk,sizeof(bChunkInd),1,fp);
1636
1637
1638
1639 short int* curStruct1;
1640 curStruct1 = mMemoryDNA->getStruct(dataChunk.dna_nr);
1641 assert(curStruct1 == curStruct);
1642
1643 char* cur = fixupPointers ? (char*)findLibPointer(dataChunk.oldPtr) : (char*)dataChunk.oldPtr;
1644
1645 //write the actual contents of the structure(s)
1646 fwrite(cur,dataChunk.len,1,fp);
1647 } else
1648 {
1649 printf("serious error, struct mismatch: don't write\n");
1650 }
1651 }
1652
1653 }
1654
1655
1656 // ----------------------------------------------------- //
1657 int bFile::getNextBlock(bChunkInd *dataChunk, const char *dataPtr, const int flags)
1658 {
1659 bool swap = false;
1660 bool varies = false;
1661
1662 if (flags &FD_ENDIAN_SWAP)
1663 swap = true;
1664 if (flags &FD_BITS_VARIES)
1665 varies = true;
1666
1667 if (VOID_IS_8)
1668 {
1669 if (varies)
1670 {
1671 bChunkPtr4 head;
1672 memcpy(&head, dataPtr, sizeof(bChunkPtr4));
1673
1674
1675 bChunkPtr8 chunk;
1676
1677 chunk.code = head.code;
1678 chunk.len = head.len;
1679 chunk.m_uniqueInts[0] = head.m_uniqueInt;
1680 chunk.m_uniqueInts[1] = 0;
1681 chunk.dna_nr = head.dna_nr;
1682 chunk.nr = head.nr;
1683
1684 if (swap)
1685 {
1686 if ((chunk.code & 0xFFFF)==0)
1687 chunk.code >>=16;
1688
1689 SWITCH_INT(chunk.len);
1690 SWITCH_INT(chunk.dna_nr);
1691 SWITCH_INT(chunk.nr);
1692 }
1693
1694
1695 memcpy(dataChunk, &chunk, sizeof(bChunkInd));
1696 }
1697 else
1698 {
1699 bChunkPtr8 c;
1700 memcpy(&c, dataPtr, sizeof(bChunkPtr8));
1701
1702 if (swap)
1703 {
1704 if ((c.code & 0xFFFF)==0)
1705 c.code >>=16;
1706
1707 SWITCH_INT(c.len);
1708 SWITCH_INT(c.dna_nr);
1709 SWITCH_INT(c.nr);
1710 }
1711
1712 memcpy(dataChunk, &c, sizeof(bChunkInd));
1713 }
1714 }
1715 else
1716 {
1717 if (varies)
1718 {
1719 bChunkPtr8 head;
1720 memcpy(&head, dataPtr, sizeof(bChunkPtr8));
1721
1722
1723 bChunkPtr4 chunk;
1724 chunk.code = head.code;
1725 chunk.len = head.len;
1726
1727 if (head.m_uniqueInts[0]==head.m_uniqueInts[1])
1728 {
1729 chunk.m_uniqueInt = head.m_uniqueInts[0];
1730 } else
1731 {
1732 long64 oldPtr =0;
1733 memcpy(&oldPtr, &head.m_uniqueInts[0], 8);
1734 if (swap)
1735 SWITCH_LONGINT(oldPtr);
1736 chunk.m_uniqueInt = (int)(oldPtr >> 3);
1737 }
1738
1739
1740 chunk.dna_nr = head.dna_nr;
1741 chunk.nr = head.nr;
1742
1743 if (swap)
1744 {
1745 if ((chunk.code & 0xFFFF)==0)
1746 chunk.code >>=16;
1747
1748 SWITCH_INT(chunk.len);
1749 SWITCH_INT(chunk.dna_nr);
1750 SWITCH_INT(chunk.nr);
1751 }
1752
1753 memcpy(dataChunk, &chunk, sizeof(bChunkInd));
1754 }
1755 else
1756 {
1757 bChunkPtr4 c;
1758 memcpy(&c, dataPtr, sizeof(bChunkPtr4));
1759
1760 if (swap)
1761 {
1762 if ((c.code & 0xFFFF)==0)
1763 c.code >>=16;
1764
1765 SWITCH_INT(c.len);
1766 SWITCH_INT(c.dna_nr);
1767 SWITCH_INT(c.nr);
1768 }
1769 memcpy(dataChunk, &c, sizeof(bChunkInd));
1770 }
1771 }
1772
1773 if (dataChunk->len < 0)
1774 return -1;
1775
1776 #if 0
1777 print ("----------");
1778 print (dataChunk->code);
1779 print (dataChunk->len);
1780 print (dataChunk->old);
1781 print (dataChunk->dna_nr);
1782 print (dataChunk->nr);
1783 #endif
1784 return (dataChunk->len+ChunkUtils::getOffset(flags));
1785 }
1786
1787
1788
1789 //eof
bParse::bChunkPtr8::len
int len
Definition: bChunk.h:52
btAlignedObjectArray::push_back
void push_back(const T &_Val)
Definition: btAlignedObjectArray.h:274
bParse::bFile::resolvePointersChunk
void resolvePointersChunk(const bChunkInd &dataChunk, int verboseMode)
this loop only works fine if the Blender DNA structure of the file matches the headerfiles ...
Definition: bFile.cpp:1245
setEle
#define setEle(value, current, type, cast, size, ptr)
bDNA.h
bParse::bFile::m_pointerPtrFixupArray
btAlignedObjectArray< char * > m_pointerPtrFixupArray
Definition: bFile.h:67
bParse::bFile::getNextBlock
int getNextBlock(bChunkInd *dataChunk, const char *dataPtr, const int flags)
Definition: bFile.cpp:1657
btPointerUid::m_uniqueIds
int m_uniqueIds[2]
Definition: btSerializer.h:138
bParse::bDNA::getArraySizeNew
int getArraySizeNew(short name)
Definition: bDNA.h:41
bParse::FD_FILEDNA_IS_MEMDNA
Definition: bFile.h:37
bParse::bChunkPtr4::code
int code
Definition: bChunk.h:37
bParse::bChunkInd::nr
int nr
Definition: bChunk.h:68
bParse::bFile::mMemoryDNA
bDNA * mMemoryDNA
Definition: bFile.h:64
bParse::bDNA::lessThan
bool lessThan(bDNA *other)
Definition: bDNA.cpp:44
btAlignedObjectArray::at
const T & at(int n) const
Definition: btAlignedObjectArray.h:160
bParse::bFile::readStruct
char * readStruct(char *head, class bChunkInd &chunk)
Definition: bFile.cpp:673
bParse::bFile::parseData
virtual void parseData()=0
bParse::bFile::parseInternal
virtual void parseInternal(int verboseMode, char *memDna, int memDnaLength)
Definition: bFile.cpp:202
getElement
static void getElement(int arrayLen, const char *cur, const char *old, char *oldPtr, char *curData)
Definition: bFile.cpp:884
bParse::bChunkInd::len
int len
Definition: bChunk.h:66
bParse::bChunkInd
Definition: bChunk.h:62
size
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
bParse::bDNA::getName
char * getName(int ind)
Definition: bDNA.cpp:50
bParse::bFile::addDataBlock
virtual void addDataBlock(char *dataBlock)=0
bParse::bFile::mFileBuffer
char * mFileBuffer
Definition: bFile.h:55
btPointerUid::m_ptr
void * m_ptr
Definition: btSerializer.h:137
bParse::bChunkInd::dna_nr
int dna_nr
Definition: bChunk.h:68
bParse::bFile::swapDNA
void swapDNA(char *ptr)
Definition: bFile.cpp:405
SDNA
#define SDNA
Definition: bDefines.h:111
bParse::FD_VERSION_VARIES
Definition: bFile.h:34
bParse::bDNA::dumpTypeDefinitions
void dumpTypeDefinitions()
Definition: bDNA.cpp:547
bParse::bChunkPtr8::m_uniqueInts
int m_uniqueInts[2]
Definition: bChunk.h:56
bParse::bFile::dumpChunks
void dumpChunks(bDNA *dna)
Definition: bFile.cpp:1546
TYPE
#define TYPE
Definition: bDefines.h:112
btAlignedAllocator.h
bParse::FD_FILE_64
Definition: bFile.h:32
bParse::bFile::resolvePointersStructRecursive
int resolvePointersStructRecursive(char *strcPtr, int old_dna, int verboseMode, int recursion)
Definition: bFile.cpp:1262
STRC
#define STRC
Definition: bDefines.h:114
bFile.h
bParse::bChunkPtr4::m_uniqueInt
int m_uniqueInt
Definition: bChunk.h:41
bParse::bChunkPtr4
Definition: bChunk.h:33
bParse::bFile::bFile
bFile(const char *filename, const char headerString[7])
Definition: bFile.cpp:55
bParse::bDNA::getNumNames
int getNumNames() const
Definition: bDNA.h:53
bParse::FD_BROKEN_DNA
Definition: bFile.h:36
bParse::bDNA::initCmpFlags
void initCmpFlags(bDNA *memDNA)
Definition: bDNA.cpp:172
SIZEOFBLENDERHEADER
#define SIZEOFBLENDERHEADER
Definition: bFile.cpp:27
bParse::bFile::swapLen
void swapLen(char *dataPtr)
Definition: bFile.cpp:355
bParse::bChunkPtr8::code
int code
Definition: bChunk.h:52
bParse::bStructHandle
Definition: bCommon.h:33
DNA1
#define DNA1
Definition: bDefines.h:107
bParse::ChunkUtils::swapInt
static int swapInt(int inte)
Definition: bChunk.cpp:37
SWITCH_LONGINT
#define SWITCH_LONGINT(a)
Definition: bDefines.h:131
bParse::bFile::preSwap
void preSwap()
Definition: bFile.cpp:590
bParse::bChunkPtr8::dna_nr
int dna_nr
Definition: bChunk.h:58
bParse::FD_ENDIAN_SWAP
Definition: bFile.h:31
btAlignedObjectArray::size
int size() const
return the number of elements in the array
Definition: btAlignedObjectArray.h:155
MAX_STRLEN
#define MAX_STRLEN
Definition: bFile.cpp:30
bParse::FD_OK
Definition: bFile.h:29
bParse::bChunkPtr4::nr
int nr
Definition: bChunk.h:44
bParse::bChunkInd::oldPtr
void * oldPtr
Definition: bChunk.h:67
bParse::bChunkPtr8
Definition: bChunk.h:48
bParse::VOID_IS_8
const bool VOID_IS_8
Definition: bChunk.h:89
btPointerUid
Definition: btSerializer.h:133
bParse::bFile::m_pointerFixupArray
btAlignedObjectArray< char * > m_pointerFixupArray
Definition: bFile.h:66
bParse::FD_VERBOSE_DUMP_DNA_TYPE_DEFINITIONS
Definition: bFile.h:43
bParse::bChunkInd::code
int code
Definition: bChunk.h:66
bParse::bFile::resolvePointers
void resolvePointers(int verboseMode)
Resolve pointers replaces the original pointers in structures, and linked lists by the new in-memory ...
Definition: bFile.cpp:1474
bParse::bDNA::getPointerSize
int getPointerSize()
Definition: bDNA.cpp:133
bParse::bFile::swapStruct
void swapStruct(int dna_nr, char *data, bool ignoreEndianFlag)
Definition: bFile.cpp:1130
btHashMap::insert
void insert(const Key &key, const Value &value)
Definition: btHashMap.h:269
bParse::bFile::parseStruct
void parseStruct(char *strcPtr, char *dtPtr, int old_dna, int new_dna, bool fixupPointers)
Definition: bFile.cpp:798
bParse::bFile::mFlags
int mFlags
Definition: bFile.h:77
SWITCH_INT
#define SWITCH_INT(a)
Definition: bDefines.h:118
btGetVersion
int btGetVersion()
Definition: btScalar.h:33
bParse::bFile::safeSwapPtr
void safeSwapPtr(char *dst, const char *src)
Definition: bFile.cpp:955
btMinMax.h
getCleanName
const char * getCleanName(const char *memName, char *buffer)
Definition: bFile.cpp:32
bParse::bFile::parseHeader
virtual void parseHeader()
Definition: bFile.cpp:130
bParse::FD_DOUBLE_PRECISION
Definition: bFile.h:35
bChunk.h
bParse::bFile::writeFile
void writeFile(const char *fileName)
Definition: bFile.cpp:583
bParse::bFile::mFileLen
int mFileLen
Definition: bFile.h:56
btHashMap::find
const Value * find(const Key &key) const
Definition: btHashMap.h:406
bCommon.h
bParse::bFile::~bFile
virtual ~bFile()
Definition: bFile.cpp:112
TLEN
#define TLEN
Definition: bDefines.h:113
bParse::bFile::mDataStart
int mDataStart
Definition: bFile.h:62
bParse::bChunkPtr8::nr
int nr
Definition: bChunk.h:58
bParse::bFile::getLibPointers
bPtrMap & getLibPointers()
Definition: bFile.h:137
bParse::bFile::mVersion
int mVersion
Definition: bFile.h:57
getEle
#define getEle(value, current, type, cast, size, ptr)
bParse::FD_INVALID
Definition: bFile.h:28
bParse::bFile::m_chunks
btAlignedObjectArray< bChunkInd > m_chunks
Definition: bFile.h:69
bParse::bFile::setFileDNA
virtual void setFileDNA(int verboseMode, char *buffer, int len)
Definition: bFile.cpp:190
bParse::FD_VERBOSE_EXPORT_XML
Definition: bFile.h:42
bParse
Definition: btBulletWorldImporter.h:29
bParse::bDNA
Definition: bDNA.h:32
bParse::bDNA::getStruct
short * getStruct(int ind)
Definition: bDNA.cpp:66
bDefines.h
numallocs
int numallocs
Definition: bFile.cpp:52
bParse::bFile::getMatchingFileDNA
void getMatchingFileDNA(short *old, const char *lookupName, const char *lookupType, char *strcData, char *data, bool fixupPointers)
Definition: bFile.cpp:1014
bParse::bDNA::init
void init(char *data, int len, bool swap=false)
Definition: bDNA.cpp:349
bParse::bFile::writeChunks
virtual void writeChunks(FILE *fp, bool fixupPointers)
Definition: bFile.cpp:1593
bParse::bDNA::flagEqual
bool flagEqual(int dna_nr)
Definition: bDNA.cpp:118
bParse::bChunkPtr4::len
int len
Definition: bChunk.h:38
bParse::FD_BITS_VARIES
Definition: bFile.h:33
bParse::bFile::findLibPointer
void * findLibPointer(void *ptr)
Definition: bFile.cpp:1526
bParse::bFile::swapData
void swapData(char *data, short type, int arraySize, bool ignoreEndianFlag)
Definition: bFile.cpp:922
bParse::bFile::m_headerString
char m_headerString[7]
Definition: bFile.h:52
bParse::bDNA::getElementSize
int getElementSize(short type, short name)
Definition: bDNA.h:46
bParse::bFile::getFileElement
char * getFileElement(short *firstStruct, char *lookupName, char *lookupType, char *data, short **foundPos)
Definition: bFile.cpp:1101
bParse::ChunkUtils::swapShort
static short swapShort(short sht)
Definition: bChunk.cpp:30
bParse::bFile::mFileDNA
bDNA * mFileDNA
Definition: bFile.h:63
bParse::bFile::swap
void swap(char *head, class bChunkInd &ch, bool ignoreEndianFlag)
Definition: bFile.cpp:326
btMin
const T & btMin(const T &a, const T &b)
Definition: btMinMax.h:23
bParse::bChunkPtr4::dna_nr
int dna_nr
Definition: bChunk.h:43
bParse::bFile::mLibPointers
bPtrMap mLibPointers
Definition: bFile.h:60
SWITCH_SHORT
#define SWITCH_SHORT(a)
Definition: bDefines.h:125
bParse::bFile::ok
bool ok()
Definition: bFile.cpp:185
bParse::bFile::updateOldPointers
void updateOldPointers()
Definition: bFile.cpp:1536
long64
#define long64
Definition: bChunk.h:20
bParse::bDNA::getReverseType
int getReverseType(short type)
Definition: bDNA.cpp:82
bParse::bFile::m_chunkPtrPtrMap
btHashMap< btHashPtr, bChunkInd > m_chunkPtrPtrMap
Definition: bFile.h:70
bParse::bDNA::getLength
short getLength(int ind)
Definition: bDNA.cpp:74
bParse::bFile::mOwnsBuffer
bool mOwnsBuffer
Definition: bFile.h:54
MAX_ARRAY_LENGTH
#define MAX_ARRAY_LENGTH
Definition: bFile.cpp:28
bParse::bDNA::getType
char * getType(int ind)
Definition: bDNA.cpp:58
bParse::ChunkUtils::getOffset
static int getOffset(int flags)
Definition: bChunk.cpp:51
btSerializer.h
bParse::bFile::resolvePointersMismatch
void resolvePointersMismatch()
Definition: bFile.cpp:1177