Imported Upstream version 2.81
[platform/upstream/libbullet.git] / Demos / Gpu2dDemo / oecakeLoader.cpp
1 #include "oecakeLoader.h"
2 #include <stdio.h> //printf debugging
3 #include <stdlib.h>
4
5
6
7
8 btCompoundShape* shiftTransform(btCompoundShape* boxCompound,btScalar mass,btTransform& shift)
9 {
10         btTransform principal;
11         btVector3 principalInertia;
12         btScalar* masses = new btScalar[boxCompound->getNumChildShapes()];
13         for (int j=0;j<boxCompound->getNumChildShapes();j++)
14         {
15                 //evenly distribute mass
16                 masses[j]=mass/boxCompound->getNumChildShapes();
17         }
18
19
20         boxCompound->calculatePrincipalAxisTransform(masses,principal,principalInertia);
21
22
23         ///create a new compound with world transform/center of mass properly aligned with the principal axis
24
25         ///non-recursive compound shapes perform better
26         //#define USE_RECURSIVE_COMPOUND 1
27 #ifdef USE_RECURSIVE_COMPOUND
28
29         btCompoundShape* newCompound = new btCompoundShape();
30         newCompound->addChildShape(principal.inverse(),boxCompound);
31         m_collisionShapes.push_back(newCompound);
32
33         btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);
34         btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,newCompound,principalInertia);
35
36 #else
37 #ifdef CHANGE_COMPOUND_INPLACE
38         for (int i=0;i<boxCompound->getNumChildShapes();i++)
39         {
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);
43         }
44         if (isDynamic)
45                 boxCompound->calculateLocalInertia(mass,localInertia);
46         btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);
47         btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,boxCompound,localInertia);
48 #else
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++)
52         {
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));
56         }
57
58
59
60 #endif
61
62 #endif//USE_RECURSIVE_COMPOUND
63
64         shift = principal;
65         return newBoxCompound;
66 }
67
68
69 void BasicOECakeReader::addParticle(int materialType, int pIndex, int pColor, float pPosX, float pPosY,float radius)
70 {
71         //determine that we have a new shape?
72         if (m_particlePositions.size())
73         {
74                 if (
75                         (materialType != m_materialType)
76                          ||
77                          (pIndex != m_particleObjectIndex)
78                         )
79                 {
80                         convertParticleGroup();
81                 }
82         }
83         
84
85         //add to array
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);
91
92 }
93
94 void    BasicOECakeReader::convertParticleGroup()
95 {
96         printf("found a particle group of %d particles\n",m_particlePositions.size());
97         if (m_particlePositions.size()>0)
98         {
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();
102         }
103 }
104
105 void    BasicOECakeReader::addNewCollisionShape(int numParticles, btVector3* particlePositions, btScalar* radii, int materialType, int objectIndex,int color )
106 {
107         //create Bullet stuff
108         btCompoundShape* colShape = 0;
109         btScalar mass;
110
111         bool addConstraint = false;
112
113
114         if (materialType&0x800000)
115         {
116                 addConstraint = true;
117         }
118         
119         if ((materialType & 0x20000) ||(materialType & 0x12))
120         {
121                 mass = 1.f;
122         } else
123         {
124                         mass = 0.f;
125         }
126         btTransform     startTransform;
127         startTransform.setIdentity();
128
129         int numCurSpheres = 0;
130
131         {
132                 
133         
134                 btTransform localTrans;
135                 localTrans.setIdentity();
136
137                 //static
138                 btCompoundShape* compound = new btCompoundShape();
139                 
140                 for (int i=0;i<numParticles;i++)
141                 {
142                         numCurSpheres++;
143                         localTrans.setOrigin(particlePositions[i]);
144                         btSphereShape* particle = new btSphereShape(radii[i]);
145                         compound->addChildShape(localTrans,particle);
146                         if (mass==0.f && (numCurSpheres>=7))
147                         {
148                                 createBodyForCompoundShape(compound,false,startTransform,mass);
149                                 compound = new btCompoundShape();
150                                 numCurSpheres = 0;
151                         }
152                 }
153                 if (mass)
154                 {
155                         //shift the center of mass, based on all spheres
156                         btCompoundShape* newCompound = shiftTransform(compound,mass,startTransform);
157                         colShape = newCompound;
158                 } else
159                 {
160                         //use unmodified
161                         colShape = compound;
162                 }
163         }
164
165         btDefaultMotionState* myMotionState  = 0;
166
167         if (colShape && numCurSpheres)
168         {
169                 createBodyForCompoundShape(colShape,addConstraint,startTransform,mass);
170         }
171 }
172
173
174
175 int BasicOECakeReader::processLine(char * buffer, int size)
176 {
177         int numBytesRead  = 0;
178
179         if (buffer[0] == 'p') 
180         {
181                 int materialType;
182                 int     particleObjectIndex;
183                 int particleColor;
184                 int dummy1;
185                 float particlePosX;
186                 float particlePosY;
187
188                 if (sscanf (buffer, "p %x %x %x %x %f %f", &materialType,&particleObjectIndex,&dummy1, &particleColor,  &particlePosX, &particlePosY) == 6)
189                 {
190                         addParticle(materialType,particleObjectIndex,particleColor,particlePosX,particlePosY);
191                 }
192                 else
193                 {
194                         printf("ERROR: invalid line (%s)\n", buffer);
195                 }
196         }
197         
198         while (*buffer != '\n' && size != 0)
199         {
200                 buffer++;
201                 numBytesRead++;
202         }
203
204         
205         if (buffer[0]==0x0a)
206         {
207                 buffer++;
208                 numBytesRead++;
209         }
210         
211
212         return numBytesRead;
213 }
214
215 bool BasicOECakeReader::processFile(char * fileName)
216 {
217         FILE * fp = fopen(fileName, "rb");
218         if (fp == NULL)
219         {
220                 printf("ERROR: file(%s) not found", fileName);
221                 return false;
222         }
223
224         int size;
225         if (fseek(fp, 0, SEEK_END) || (size = ftell(fp)) == EOF || fseek(fp, 0, SEEK_SET)) 
226         {
227                 printf("ERROR: problem reading file(%s)", fileName);
228                 fclose(fp);
229                 return false;
230         }
231         else
232         {
233                 rewind (fp);
234                 char * buffer = (char *) malloc(size+1);
235                 memset(buffer,0,size);
236                 
237                 if (fread(buffer,1,size,fp) != size)
238                 {
239                         printf("Error reading file %s!\n",fileName);
240                         fclose(fp);
241                         return false;
242                 }
243
244                 int totalBytesRead = 0;
245
246                 while(totalBytesRead<size)
247                 {
248                         int remainingSize = size-totalBytesRead;
249                         if (remainingSize<1229)
250
251                         {
252                                 printf("..");
253                         }
254
255                         
256                         totalBytesRead +=processLine(&buffer[totalBytesRead],remainingSize);
257                 }
258         }
259
260         convertParticleGroup();
261
262         fclose(fp);
263         return false;
264 }