1 #include "oecakeLoader.h"
2 #include <stdio.h> //printf debugging
8 btCompoundShape* shiftTransform(btCompoundShape* boxCompound,btScalar mass,btTransform& shift)
10 btTransform principal;
11 btVector3 principalInertia;
12 btScalar* masses = new btScalar[boxCompound->getNumChildShapes()];
13 for (int j=0;j<boxCompound->getNumChildShapes();j++)
15 //evenly distribute mass
16 masses[j]=mass/boxCompound->getNumChildShapes();
20 boxCompound->calculatePrincipalAxisTransform(masses,principal,principalInertia);
23 ///create a new compound with world transform/center of mass properly aligned with the principal axis
25 ///non-recursive compound shapes perform better
26 //#define USE_RECURSIVE_COMPOUND 1
27 #ifdef USE_RECURSIVE_COMPOUND
29 btCompoundShape* newCompound = new btCompoundShape();
30 newCompound->addChildShape(principal.inverse(),boxCompound);
31 m_collisionShapes.push_back(newCompound);
33 btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);
34 btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,newCompound,principalInertia);
37 #ifdef CHANGE_COMPOUND_INPLACE
38 for (int i=0;i<boxCompound->getNumChildShapes();i++)
40 btTransform newChildTransform = principal.inverse()*boxCompound->getChildTransform(i);
41 ///updateChildTransform is really slow, because it re-calculates the AABB each time. todo: add option to disable this update
42 boxCompound->updateChildTransform(i,newChildTransform);
45 boxCompound->calculateLocalInertia(mass,localInertia);
46 btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);
47 btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,boxCompound,localInertia);
49 ///creation is faster using a new compound to store the shifted children
50 btCompoundShape* newBoxCompound = new btCompoundShape();
51 for (int i=0;i<boxCompound->getNumChildShapes();i++)
53 btTransform newChildTransform = principal.inverse()*boxCompound->getChildTransform(i);
54 ///updateChildTransform is really slow, because it re-calculates the AABB each time. todo: add option to disable this update
55 newBoxCompound->addChildShape(newChildTransform,boxCompound->getChildShape(i));
62 #endif//USE_RECURSIVE_COMPOUND
65 return newBoxCompound;
69 void BasicOECakeReader::addParticle(int materialType, int pIndex, int pColor, float pPosX, float pPosY,float radius)
71 //determine that we have a new shape?
72 if (m_particlePositions.size())
75 (materialType != m_materialType)
77 (pIndex != m_particleObjectIndex)
80 convertParticleGroup();
86 m_materialType = materialType;
87 m_particleObjectIndex = pIndex;
88 m_particleColor = pColor;
89 m_particlePositions.push_back(btVector3(pPosX,pPosY,0.));
90 m_particleRadii.push_back(radius);
94 void BasicOECakeReader::convertParticleGroup()
96 printf("found a particle group of %d particles\n",m_particlePositions.size());
97 if (m_particlePositions.size()>0)
99 addNewCollisionShape(m_particlePositions.size(),&m_particlePositions[0],&m_particleRadii[0],m_materialType,m_particleObjectIndex,m_particleColor);
100 m_particlePositions.clear();
101 m_particleRadii.clear();
105 void BasicOECakeReader::addNewCollisionShape(int numParticles, btVector3* particlePositions, btScalar* radii, int materialType, int objectIndex,int color )
107 //create Bullet stuff
108 btCompoundShape* colShape = 0;
111 bool addConstraint = false;
114 if (materialType&0x800000)
116 addConstraint = true;
119 if ((materialType & 0x20000) ||(materialType & 0x12))
126 btTransform startTransform;
127 startTransform.setIdentity();
129 int numCurSpheres = 0;
134 btTransform localTrans;
135 localTrans.setIdentity();
138 btCompoundShape* compound = new btCompoundShape();
140 for (int i=0;i<numParticles;i++)
143 localTrans.setOrigin(particlePositions[i]);
144 btSphereShape* particle = new btSphereShape(radii[i]);
145 compound->addChildShape(localTrans,particle);
146 if (mass==0.f && (numCurSpheres>=7))
148 createBodyForCompoundShape(compound,false,startTransform,mass);
149 compound = new btCompoundShape();
155 //shift the center of mass, based on all spheres
156 btCompoundShape* newCompound = shiftTransform(compound,mass,startTransform);
157 colShape = newCompound;
165 btDefaultMotionState* myMotionState = 0;
167 if (colShape && numCurSpheres)
169 createBodyForCompoundShape(colShape,addConstraint,startTransform,mass);
175 int BasicOECakeReader::processLine(char * buffer, int size)
177 int numBytesRead = 0;
179 if (buffer[0] == 'p')
182 int particleObjectIndex;
188 if (sscanf (buffer, "p %x %x %x %x %f %f", &materialType,&particleObjectIndex,&dummy1, &particleColor, &particlePosX, &particlePosY) == 6)
190 addParticle(materialType,particleObjectIndex,particleColor,particlePosX,particlePosY);
194 printf("ERROR: invalid line (%s)\n", buffer);
198 while (*buffer != '\n' && size != 0)
215 bool BasicOECakeReader::processFile(char * fileName)
217 FILE * fp = fopen(fileName, "rb");
220 printf("ERROR: file(%s) not found", fileName);
225 if (fseek(fp, 0, SEEK_END) || (size = ftell(fp)) == EOF || fseek(fp, 0, SEEK_SET))
227 printf("ERROR: problem reading file(%s)", fileName);
234 char * buffer = (char *) malloc(size+1);
235 memset(buffer,0,size);
237 if (fread(buffer,1,size,fp) != size)
239 printf("Error reading file %s!\n",fileName);
244 int totalBytesRead = 0;
246 while(totalBytesRead<size)
248 int remainingSize = size-totalBytesRead;
249 if (remainingSize<1229)
256 totalBytesRead +=processLine(&buffer[totalBytesRead],remainingSize);
260 convertParticleGroup();