1 /* system headers */
2 #include <fstream>
3 #include <iostream>
4 #include <string>
5 #include <sstream>
6 #include <stack>
7 #include <vector>
8 #include <math.h>
9 #include <string.h>
10
11 typedef int foo;
12
13 #ifndef PI
14 # define PI (3.1415926535897932384626433832795f)
15 #endif
16 #ifndef TWO_PI
17 # define TWO_PI (2.0f*PI)
18 #endif
19
20
21 class Matrix3D
22 {
23 public:
Matrix3D()24 Matrix3D()
25 {
26 makeIdentity();
27 }
28
operator [](int index)29 float *operator[]( int index )
30 {
31 if ((index < 0) || (index >= 4))
32 throw std::exception();
33
34 return matrix[index];
35 }
36
makeIdentity()37 void makeIdentity()
38 {
39 memset( matrix, 0, sizeof( float ) * 4 * 4 );
40 for (int i = 0; i < 4; i++)
41 matrix[i][i] = 1.0f;
42 }
43
makeScale(float scaleX,float scaleY,float scaleZ)44 void makeScale( float scaleX, float scaleY, float scaleZ )
45 {
46 makeIdentity();
47 matrix[0][0] = scaleX;
48 matrix[1][1] = scaleY;
49 matrix[2][2] = scaleZ;
50
51 }
52
makeRotationZ(float angle)53 void makeRotationZ( float angle )
54 {
55 makeIdentity();
56 matrix[0][0] = (float)cos(angle);
57 matrix[0][1] = (float)-sin(angle);
58 matrix[1][0] = (float)sin(angle);
59 matrix[1][1] = (float)cos(angle);
60 }
61
makeTranslation(float xPos,float yPos,float zPos)62 void makeTranslation( float xPos, float yPos, float zPos )
63 {
64 makeIdentity();
65 matrix[0][3] = (float)xPos;
66 matrix[1][3] = (float)yPos;
67 matrix[2][3] = (float)zPos;
68 }
69
postMultiply(Matrix3D & inMatrix)70 void postMultiply( Matrix3D &inMatrix )
71 {
72 // this = this * matrix
73
74 float src[4][4];
75 memcpy( src, matrix, sizeof(float)*4*4 );
76
77 for (int y = 0; y < 4; y++)
78 {
79 for (int x = 0; x < 4; x++)
80 {
81 matrix[x][y] = src[0][y]*inMatrix.matrix[x][0] +
82 src[1][y]*inMatrix.matrix[x][1] +
83 src[2][y]*inMatrix.matrix[x][2] +
84 src[3][y]*inMatrix.matrix[x][3];
85 }
86 }
87
88 }
89
preMultiply(Matrix3D & inMatrix)90 void preMultiply( Matrix3D &inMatrix )
91 {
92 // this = matrix * this
93
94 float src[4][4];
95 memcpy( src, matrix, sizeof(float)*4*4 );
96
97 for (int y = 0; y < 4; y++)
98 {
99 for (int x = 0; x < 4; x++)
100 {
101 matrix[x][y] = inMatrix.matrix[0][y]*src[x][0] +
102 inMatrix.matrix[1][y]*src[x][1] +
103 inMatrix.matrix[2][y]*src[x][2] +
104 inMatrix.matrix[3][y]*src[x][3];
105 }
106 }
107 }
108 private:
109 float matrix[4][4];
110 friend class Point3D;
111 };
112
113 class Point3D
114 {
115 public:
Point3D()116 Point3D()
117 {
118 memset( points, 0, sizeof(float)*4 );
119 points[3] = 1.0f;
120 }
121
Point3D(float x,float y,float z)122 Point3D( float x, float y, float z )
123 {
124 setValue( x, y, z );
125 }
126
setValue(float x,float y,float z)127 void setValue( float x, float y, float z )
128 {
129 points[0] = x;
130 points[1] = y;
131 points[2] = z;
132 points[3] = 1.0f;
133 }
134
operator [](int index) const135 float operator[]( int index ) const
136 {
137 if ((index < 0) || (index >= 4))
138 throw std::exception();
139
140 return points[index];
141 }
142
transform(Matrix3D & matrix)143 void transform( Matrix3D &matrix )
144 {
145 float src[4];
146 memcpy( src, points, sizeof(float)*4 );
147
148 for (int x = 0; x < 4; x++)
149 {
150 points[x] = 0.0;
151 for (int y = 0; y < 4; y++)
152 points[x] += src[y] * matrix.matrix[x][y];
153 }
154
155 }
156
157 private:
158 float points[4];
159 };
160
161 class BZObject
162 {
163 public:
BZObject(std::string _type,float * _position,float * _size,float _rotation)164 BZObject( std::string _type, float *_position, float *_size, float _rotation )
165 {
166 this->type = _type;
167 this->position.setValue( _position[0], _position[1], _position[2] );
168 this->size.setValue( _size[0], _size[1], _size[2] );
169 this->rotation = _rotation;
170 }
171
isBox()172 bool isBox()
173 {
174 return type == "box";
175 }
176 public:
177
178 std::string type;
179 Point3D position;
180 Point3D size;
181 float rotation;
182 };
183
184
box(std::ofstream & bzw,Point3D & position,Point3D & size,float rotation,char * comment=NULL)185 void box( std::ofstream &bzw, Point3D &position, Point3D &size, float rotation, char *comment = NULL )
186 {
187 if (comment != NULL)
188 bzw << "#" << comment << std::endl;
189 bzw << "box" << std::endl;
190 bzw << "position " << position[0] << " " << position[1] << " " << position[2] << std::endl;
191 bzw << "size " << size[0] << " " << size[1] << " " << size[2] << std::endl;
192 bzw << "rotation " << rotation << std::endl;
193 bzw << "end" << std::endl;
194 bzw << std::endl;
195 }
196
pyramid(std::ofstream & bzw,Point3D & position,Point3D & size,float rotation,char * comment=NULL)197 void pyramid( std::ofstream &bzw, Point3D &position, Point3D &size, float rotation, char *comment = NULL )
198 {
199 if (comment != NULL)
200 bzw << "#" << comment << std::endl;
201 bzw << "pyramid" << std::endl;
202 bzw << "position " << position[0] << " " << position[1] << " " << position[2] << std::endl;
203 bzw << "size " << size[0] << " " << size[1] << " " << size[2] << std::endl;
204 bzw << "rotation " << rotation << std::endl;
205 bzw << "end" << std::endl;
206 bzw << std::endl;
207 }
208
generateObjects(std::ofstream & bzw,std::vector<BZObject * > objects,Matrix3D & posMatrix,Matrix3D & sizeMatrix,float rotation,int count)209 void generateObjects( std::ofstream &bzw, std::vector<BZObject *> objects, Matrix3D &posMatrix, Matrix3D &sizeMatrix,
210 float rotation, int count )
211 {
212 for (int cur = 0; cur < count; cur++)
213 {
214 for (std::vector<BZObject*>::iterator it = objects.begin(); it != objects.end(); it++)
215 {
216 BZObject *object = *it;
217 if (object->isBox())
218 box( bzw, object->position, object->size, object->rotation );
219 else
220 pyramid( bzw, object->position, object->size, object->rotation );
221
222 object->position.transform( posMatrix );
223 object->size.transform( sizeMatrix );
224 object->rotation += rotation;
225 }
226 }
227 }
228
229
230
parsebzwt(std::ifstream & bzwt,std::ofstream & bzw)231 void parsebzwt( std::ifstream &bzwt, std::ofstream &bzw )
232 {
233 enum { FREE, IN_TRANSFORM, IN_BOX, IN_PYRAMID, IN_MATRIX, IN_POSITION0, IN_POSITION1, IN_POSITION2, IN_SIZE0, IN_SIZE1, IN_SIZE2, IN_ROTATION,
234 IN_MATRIX_POSITION, IN_MATRIX_SIZE, IN_MATRIX_ROTATION, IN_ANGLE, IN_SCALE0, IN_SCALE1, IN_SCALE2, IN_TRANSLATE0, IN_TRANSLATE1, IN_TRANSLATE2, IN_COUNT
235 };
236 std::stack<int> stateStack;
237 std::string line, token;
238 int lineNo = 0;
239 int state = FREE;
240 float position[4];
241 float size[4];
242 float scale[4] = {0,0,0,0};
243 float translate[4] = {0,0,0,0};
244 float angle;
245
246 std::vector<BZObject *> objects;
247 Matrix3D posMatrix, sizeMatrix, tempMatrix;
248 float rotation = 0.0f;
249 int count = 0;
250
251 try
252 {
253 while (!bzwt.eof())
254 {
255 getline( bzwt, line );
256 lineNo++;
257
258 if (line.length() == 0) continue;
259 std::string::size_type start = line.find_first_not_of( " \t\n\r" );
260 if (start == std::string::npos) continue;
261 if (line.at(start) == '#') continue;
262
263 std::istringstream lineStream( line.c_str() );
264
265 while (!lineStream.eof())
266 {
267 lineStream >> token;
268 if (token.length() == 0)
269 break;
270
271 switch (state)
272 {
273 case FREE:
274 if (token == "transform")
275 {
276 state = IN_TRANSFORM;
277 posMatrix.makeIdentity();
278 sizeMatrix.makeIdentity();
279 count = 1;
280 rotation = 0.0f;
281 for (unsigned int i = 0; i < objects.size(); i++)
282 delete objects[i];
283 objects.clear();
284 }
285 else
286 throw "expecting transform";
287 break;
288
289 case IN_TRANSFORM:
290 memset( position, 0, sizeof(float)*4 );
291 memset( size, 0, sizeof(float)*4 );
292
293 if (token == "box")
294 state = IN_BOX;
295 else if (token == "pyramid")
296 state = IN_PYRAMID;
297 else if (token == "matrix")
298 state = IN_MATRIX;
299 else if (token == "count")
300 state = IN_COUNT;
301 else if (token == "end")
302 {
303 generateObjects( bzw, objects, posMatrix, sizeMatrix, rotation, count );
304 state = FREE;
305 }
306 else
307 throw "expecting transform subitem, or end";
308 break;
309
310 case IN_BOX:
311 if (token == "position")
312 {
313 state = IN_POSITION0;
314 stateStack.push( IN_BOX );
315 }
316 else if (token == "size")
317 {
318 state = IN_SIZE0;
319 stateStack.push( IN_BOX );
320 }
321 else if (token == "rotation")
322 {
323 state = IN_ROTATION;
324 stateStack.push( IN_BOX );
325 }
326 else if (token == "end")
327 {
328 BZObject *obj = new BZObject( std::string("box"), position, size, rotation );
329 objects.push_back( obj );
330 state = IN_TRANSFORM;
331 memset( position, 0, sizeof(float)*4 );
332 memset( size, 0, sizeof(float)*4 );
333 rotation = 0.0f;
334 }
335 else
336 throw "expecting transform subitem, or end";
337 break;
338
339 case IN_PYRAMID:
340 if (token == "position")
341 {
342 state = IN_POSITION0;
343 stateStack.push( IN_PYRAMID );
344 }
345 else if (token == "size")
346 {
347 state = IN_SIZE0;
348 stateStack.push( IN_PYRAMID );
349 }
350 else if (token == "rotation")
351 {
352 state = IN_ROTATION;
353 stateStack.push( IN_PYRAMID );
354 }
355 else if (token == "end")
356 {
357 state = IN_TRANSFORM;
358 BZObject *obj = new BZObject( std::string("pyramid"), position, size, rotation );
359 objects.push_back( obj );
360 state = IN_TRANSFORM;
361 memset( position, 0, sizeof(float)*4 );
362 memset( size, 0, sizeof(float)*4 );
363 rotation = 0.0f;
364 }
365 else
366 throw "expecting transform subitem, or end";
367 break;
368
369 case IN_MATRIX:
370 if (token == "position")
371 state = IN_MATRIX_POSITION;
372 else if (token == "size")
373 state = IN_MATRIX_SIZE;
374 else if (token == "rotation")
375 state = IN_MATRIX_ROTATION;
376 else if (token == "end")
377 state = IN_TRANSFORM;
378 else
379 throw "expecting transform matrix subitem, or end";
380 break;
381
382 case IN_COUNT:
383 count = atoi( token.c_str( ));
384 state = IN_TRANSFORM;
385 break;
386
387
388 case IN_POSITION0:
389 position[0] = (float)atof(token.c_str());
390 state = IN_POSITION1;
391 break;
392
393 case IN_POSITION1:
394 position[1] = (float)atof(token.c_str());
395 state = IN_POSITION2;
396 break;
397
398 case IN_POSITION2:
399 position[2] = (float)atof(token.c_str());
400 state = stateStack.top();
401 stateStack.pop();
402 break;
403
404
405 case IN_SIZE0:
406 size[0] = (float)atof(token.c_str());
407 state = IN_SIZE1;
408 break;
409
410 case IN_SIZE1:
411 size[1] = (float)atof(token.c_str());
412 state = IN_SIZE2;
413 break;
414
415 case IN_SIZE2:
416 size[2] = (float)atof(token.c_str());
417 state = stateStack.top();
418 stateStack.pop();
419 break;
420
421 case IN_ROTATION:
422 rotation = (float)atof(token.c_str());
423 state = stateStack.top();
424 stateStack.pop();
425 break;
426
427 case IN_MATRIX_POSITION:
428 if (token == "rotate")
429 {
430 stateStack.push( IN_MATRIX_POSITION );
431 state = IN_ANGLE;
432 }
433 else if (token == "scale")
434 {
435 stateStack.push( IN_MATRIX_POSITION );
436 state = IN_SCALE0;
437 }
438 else if (token == "translate")
439 {
440 stateStack.push( IN_MATRIX_POSITION );
441 state = IN_TRANSLATE0;
442 }
443 else if (token == "end")
444 state = IN_MATRIX;
445 else
446 throw "expecting a matrix operation, or end";
447 break;
448
449 case IN_MATRIX_SIZE:
450 if (token == "rotate")
451 {
452 stateStack.push( IN_MATRIX_SIZE );
453 state = IN_ANGLE;
454 }
455 else if (token == "scale")
456 {
457 stateStack.push( IN_MATRIX_SIZE );
458 state = IN_SCALE0;
459 }
460 else if (token == "translate")
461 {
462 stateStack.push( IN_MATRIX_SIZE );
463 state = IN_TRANSLATE0;
464 }
465 else if (token == "end")
466 state = IN_MATRIX;
467 else
468 throw "expecting a matrix operation, or end";
469 break;
470
471 case IN_MATRIX_ROTATION:
472 rotation = (float)atof( token.c_str( ));
473 state = IN_MATRIX;
474 break;
475
476 case IN_ANGLE:
477 angle = (float)atof( token.c_str( ));
478 state = stateStack.top();
479 stateStack.pop();
480 tempMatrix.makeRotationZ( (float)((angle * TWO_PI) / 360.0f) );
481 if (state == IN_MATRIX_POSITION)
482 posMatrix.postMultiply( tempMatrix );
483 else if (state == IN_MATRIX_SIZE)
484 sizeMatrix.postMultiply( tempMatrix );
485 break;
486
487 case IN_SCALE0:
488 scale[0] = (float)atof( token.c_str( ));
489 state = IN_SCALE1;
490 break;
491
492 case IN_SCALE1:
493 scale[1] = (float)atof( token.c_str( ));
494 state = IN_SCALE2;
495 break;
496
497 case IN_SCALE2:
498 scale[2] = (float)atof( token.c_str( ));
499 state = stateStack.top();
500 stateStack.pop();
501 tempMatrix.makeScale( scale[0], scale[1], scale[2] );
502 if (state == IN_MATRIX_POSITION)
503 posMatrix.postMultiply( tempMatrix );
504 else if (state == IN_MATRIX_SIZE)
505 sizeMatrix.postMultiply( tempMatrix );
506 break;
507
508 case IN_TRANSLATE0:
509 translate[0] = (float)atof( token.c_str( ));
510 state = IN_TRANSLATE1;
511 break;
512
513 case IN_TRANSLATE1:
514 translate[1] = (float)atof( token.c_str( ));
515 state = IN_TRANSLATE2;
516 break;
517
518 case IN_TRANSLATE2:
519 translate[2] = (float)atof( token.c_str( ));
520 state = stateStack.top();
521 stateStack.pop();
522 tempMatrix.makeTranslation( translate[0], translate[1], translate[2] );
523 if (state == IN_MATRIX_POSITION)
524 posMatrix.postMultiply( tempMatrix );
525 else if (state == IN_MATRIX_SIZE)
526 sizeMatrix.postMultiply( tempMatrix );
527 break;
528
529
530 default:
531 throw "UnHandled state";
532 break;
533
534 }
535 }
536 }
537 }
538 catch (std::exception &e)
539 {
540 std::cerr << "Parse error: line: " << lineNo << " " << e.what() << std::endl;
541 std::cerr << line << std::endl;
542 }
543
544 }
545
main(int argc,char ** argv)546 int main( int argc, char **argv )
547 {
548 if (argc != 3)
549 {
550 std::cout << "error invalid arguments" << std::endl;
551 std::cout << "\tbzwTransform inputName outputName" << std::endl;
552 return -1;
553 }
554
555 std::ifstream bzwt( argv[1] );
556
557 if (bzwt.is_open())
558 {
559 std::ofstream bzw( argv[2] );
560 if (bzw.is_open())
561 parsebzwt( bzwt, bzw );
562
563 bzwt.close();
564 }
565
566
567 return 0;
568 }
569
570
571 // Local Variables: ***
572 // mode: C++ ***
573 // tab-width: 4 ***
574 // c-basic-offset: 4 ***
575 // indent-tabs-mode: nil ***
576 // End: ***
577 // ex: shiftwidth=4 tabstop=4
578