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