1 /*
2 PLIB - A Suite of Portable Game Libraries
3 Copyright (C) 1998,2002 Steve Baker
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19 For further information visit http://plib.sourceforge.net
20
21 $Id: ssgLoadASE.cxx 1988 2004-10-29 22:41:37Z wolfram_kuss $
22 */
23
24 /****
25 * NAME
26 * ssgLoadASE -- ASE model loader
27 *
28 * DESCRIPTION
29 * ssgLoadASE will load an ASE model exported from 3dsmax using
30 * the standard ascii export v2.00 plugin.
31 *
32 * The material list and geometry objects are parsed and converted
33 * into an SSG scene graph. shape, light, camera, and helper
34 * nodes are ignored.
35 *
36 * If the geometry has vertex colours (pre-lit) then lighting is
37 * disabled for that leaf.
38 *
39 * mesh animation creates ssgSelector entities. transform
40 * animation creates ssgTransform entities with ssgTransformArray
41 * user_data. see the viewer example for details on controlling
42 * animation.
43 *
44 * NOTE: be sure you _reset the transform_ of the top-level object
45 * in 3dsmax before exporting transform animation.
46 *
47 * Please report any bugs to the author. Complete information about
48 * the ASE format can be found in the 3dsmax SDK source code.
49 *
50 * AUTHOR
51 * Dave McClurg <dpm@efn.org>
52 *
53 * CREATION DATE
54 * Feb-2000
55 *
56 * MODIFICATION HISTORY
57 * November 2000 - v1.1, Dave McClurg <dpm@efn.org>
58 * o support for transform animation samples
59 ****/
60
61 #include "ssgLocal.h"
62 #include "ssgParser.h"
63
64
65 #define u32 unsigned int
66 #define f32 float
67 #define cchar const char
68
69
70 static ssgLoaderOptions* current_options = NULL ;
71
72 struct aseVertexBuffer
73 {
74 bool use_flag ;
75 int index ;
76 sgVec3 v ;
77 sgVec2 tv ;
78 sgVec3 cv ;
79 } ;
80
81
82 struct aseFace
83 {
84 u32 v[3];
85 u32 tv[3];
86 u32 cv[3];
87 u32 sub_index;
88
89 // SAC: Additional vals to track normals for each face vertex.
90 // Since each vertex can supposedly have various normals if shared by two
91 // non-smoothed faces, we track them per face. I haven't checked this as
92 // good as I should have with smoothed & unsmoothed shapes :)
93 bool has_vertex_normals;
94 sgVec3 vn [3];
95 };
96
97
98 struct aseTransform
99 {
100 sgVec3 pos ;
101 sgVec3 axis ; // axis of rotation (unit vector)
102 f32 angle ; // angle of rotation in radians (always >0)
103 sgVec3 scale ;
104 } ;
105
106
107 struct aseMesh
108 {
109 u32 num_faces ;
110 u32 num_verts ;
111 u32 num_tverts ;
112 u32 num_cverts ;
113
114 aseFace* faces ;
115 sgVec3* verts ;
116 sgVec2* tverts ;
117 sgVec3* cverts ;
118
119 aseMesh();
120 ~aseMesh();
121 };
122
123
124 struct aseObject
125 {
126 enum Type { GEOM, HELPER, CAMERA } ;
127 int type ;
128 char* name ;
129 char* parent ;
130 bool inherit_pos [3] ;
131 sgVec3 pos ;
132 sgVec3 target ;
133 u32 mat_index ;
134 u32 num_tkeys ;
135 aseTransform* tkeys ;
136
137 enum { MAX_FRAMES = 256 };
138 aseMesh* mesh_list[ MAX_FRAMES ];
139 int mesh_count ;
140
141 aseObject( Type type );
142 ~aseObject();
143 };
144
145 struct aseMaterial
146 {
147 char* name ;
148 u32 mat_index ;
149 u32 sub_index ;
150 bool sub_flag ;
151
152 sgVec4 amb ;
153 sgVec4 diff ;
154 sgVec4 spec ;
155 f32 shine ;
156 f32 transparency ;
157
158 char* tfname ;
159 sgVec2 texrep ;
160 sgVec2 texoff ;
161 };
162
163
164 #define MAX_MATERIALS 1000
165 static aseMaterial** materials ;
166 static u32 num_materials ;
167
168 static u32 first_frame ;
169 static u32 last_frame ;
170 static u32 frame_speed ;
171 static u32 ticks_per_frame ;
172 static u32 num_frames=0 ;
173
174 static _ssgParserSpec parser_spec =
175 {
176 "\r\n\t ", // delim_chars_skipable
177 0, // delim_chars_non_skipable
178 NULL, // pre_processor
179 "{", // open_brace_chars
180 "}", // close_brace_chars
181 '"', // quote_char
182 0, // comment_char
183 0 // comment_string
184 } ;
185
186 static _ssgParser parser;
187 static ssgBranch* top_branch;
188
aseMesh()189 aseMesh::aseMesh()
190 {
191 memset(this,0,sizeof(aseMesh));
192 }
193
194
~aseMesh()195 aseMesh::~aseMesh()
196 {
197 delete[] faces;
198 delete[] verts;
199 delete[] tverts;
200 delete[] cverts;
201 }
202
203
aseObject(aseObject::Type _type)204 aseObject::aseObject( aseObject::Type _type )
205 {
206 memset(this,0,sizeof(aseObject));
207 type = _type ;
208 }
209
210
~aseObject()211 aseObject::~aseObject()
212 {
213 delete[] name;
214 delete[] parent;
215 delete[] tkeys;
216 for ( int i=0; i<MAX_FRAMES; i++ )
217 delete mesh_list [ i ] ;
218 memset(this,0,sizeof(aseObject));
219 }
220
221
count_sub_materials(u32 mat_index)222 static u32 count_sub_materials( u32 mat_index )
223 {
224 u32 count = 0 ;
225 for ( u32 i=0; i<num_materials; i++ )
226 {
227 aseMaterial* mat = materials[ i ] ;
228 if ( mat->mat_index == mat_index && mat->sub_flag )
229 count ++;
230 }
231 return count ;
232 }
233
234
find_material(u32 mat_index,u32 sub_index)235 static aseMaterial* find_material( u32 mat_index, u32 sub_index )
236 {
237 u32 i;
238
239 //find sub-material
240 for ( i=0; i<num_materials; i++ )
241 {
242 aseMaterial* mat = materials[ i ] ;
243 if ( mat->mat_index == mat_index && mat->sub_index == sub_index )
244 return(mat);
245 }
246
247 //just match material #
248 for ( i=0; i<num_materials; i++ )
249 {
250 aseMaterial* mat = materials[ i ] ;
251 if ( mat->mat_index == mat_index )
252 return(mat);
253 }
254
255 parser.error("unknown material #%d",mat_index);
256 return(0);
257 }
258
259
make_state(aseMaterial * mat,bool prelit)260 static ssgSimpleState* make_state( aseMaterial* mat, bool prelit )
261 {
262 if ( mat -> tfname != NULL)
263 {
264 ssgSimpleState *st = current_options -> createSimpleState ( mat -> tfname ) ;
265 if ( st != NULL )
266 return st ;
267 }
268
269 ssgSimpleState *st = new ssgSimpleState () ;
270
271 bool has_alpha = false ;
272
273 if (mat -> tfname != NULL)
274 {
275 ssgTexture* tex = current_options -> createTexture ( mat->tfname ) ;
276 has_alpha = tex -> hasAlpha () ;
277
278 st -> setTexture ( tex ) ;
279 st -> enable ( GL_TEXTURE_2D ) ;
280 }
281 else
282 {
283 st -> disable( GL_TEXTURE_2D ) ;
284 }
285
286 st -> disable ( GL_ALPHA_TEST ) ;
287
288 if ( sgCompareFloat ( mat -> transparency, 0.0f, 0.01f ) > 0 || has_alpha )
289 {
290 st -> enable ( GL_BLEND ) ;
291 st -> setTranslucent () ;
292 }
293 else
294 {
295 st -> disable ( GL_BLEND ) ;
296 st -> setOpaque () ;
297 }
298
299 if ( prelit )
300 {
301 st -> disable ( GL_LIGHTING ) ;
302 }
303 else
304 {
305 st -> setMaterial ( GL_AMBIENT, mat -> amb ) ;
306 st -> setMaterial ( GL_DIFFUSE, mat -> diff ) ;
307 st -> setMaterial ( GL_SPECULAR, mat -> spec ) ;
308 st -> setShininess ( mat -> shine ) ;
309 st -> disable ( GL_COLOR_MATERIAL ) ;
310 st -> setColourMaterial ( GL_AMBIENT_AND_DIFFUSE ) ;
311 st -> enable ( GL_LIGHTING ) ;
312 }
313
314 st -> setShadeModel ( GL_SMOOTH ) ;
315
316 return st ;
317 }
318
319
get_state(aseMaterial * mat,bool prelit)320 static ssgSimpleState* get_state( aseMaterial* mat, bool prelit )
321 {
322 // is material an ifl (image file list)
323 #ifdef UL_WIN32
324 if ( strnicmp ( "ifl_", mat -> name, 4 ) == 0 )
325 #else
326 if ( strncasecmp ( "ifl_", mat -> name, 4 ) == 0 )
327 #endif
328 {
329 u32 num_subs = count_sub_materials ( mat -> mat_index );
330 if ( num_subs < 2 )
331 parser.error("ifl material only has <2 frames: %s",mat -> name);
332
333 ssgStateSelector* selector = new ssgStateSelector ( num_subs ) ;
334 for ( u32 i=0; i<num_subs; i++ )
335 {
336 aseMaterial* mat2 = find_material ( mat -> mat_index, i ) ;
337 assert ( mat2 != NULL ) ;
338
339 ssgSimpleState* st = make_state ( mat2, prelit ) ;
340 selector -> setStep ( i, st ) ;
341 }
342 selector -> selectStep ( 0 ) ;
343 return selector ;
344 }
345 return make_state ( mat, prelit ) ;
346 }
347
348
parse_map(aseMaterial * mat)349 static int parse_map( aseMaterial* mat )
350 // return TRUE on success
351 {
352 char* token;
353 int startLevel = parser.level;
354 while ((token = parser.getLine( startLevel )) != NULL)
355 {
356 if (!strcmp(token,"*BITMAP"))
357 {
358 if ( mat->tfname != NULL )
359 parser.error("multiple textures for material: %s",mat->name);
360 else
361 {
362 char* fname;
363 if (! parser.parseString(fname, "bitmap filename") )
364 return FALSE;
365
366 //strip existing directory from fname
367 char* slash = strrchr ( fname, '/' ) ;
368 if ( !slash )
369 slash = strrchr ( fname, '\\' ) ; //for dos
370 if ( slash )
371 fname = slash + 1 ;
372
373 mat->tfname = ulStrDup ( fname ) ;
374 }
375 }
376 else if (!strcmp(token,"*UVW_U_TILING"))
377 {
378 if (! parser.parseFloat(mat->texrep[0], "tiling.u"))
379 return FALSE;
380 }
381 else if (!strcmp(token,"*UVW_V_TILING"))
382 {
383 if (! parser.parseFloat(mat->texrep[1], "tiling.v"))
384 return FALSE;
385 }
386 else if (!strcmp(token,"*UVW_U_OFFSET"))
387 {
388 if (! parser.parseFloat(mat->texoff[0] , "offset.u"))
389 return FALSE;
390 }
391 else if (!strcmp(token,"*UVW_V_OFFSET"))
392 {
393 if (! parser.parseFloat(mat->texoff[1] , "offset.v"))
394 return FALSE;
395 }
396 }
397 return TRUE;
398 }
399
400
parse_material(u32 mat_index,u32 sub_index,cchar * mat_name)401 static int parse_material( u32 mat_index, u32 sub_index, cchar* mat_name )
402 // return TRUE on success
403 {
404 if ( num_materials >= MAX_MATERIALS )
405 {
406 parser.error( "too many materials" );
407
408 // skip material definition
409 int startLevel = parser.level;
410 while (parser.getLine( startLevel ) != NULL)
411 ;
412 return TRUE; // go on parsing
413 }
414 aseMaterial* mat = new aseMaterial;
415 materials [ num_materials++ ] = mat ;
416
417 memset ( mat, 0, sizeof(aseMaterial) ) ;
418 mat->mat_index = mat_index ;
419 mat->sub_index = sub_index ;
420 mat->sub_flag = ( mat_name != 0 ) ;
421 mat->texrep[0] = 1.0f ;
422 mat->texrep[1] = 1.0f ;
423 mat->texoff[0] = 0.0f ;
424 mat->texoff[1] = 0.0f ;
425
426 char* token;
427 int startLevel = parser.level;
428 while ((token = parser.getLine( startLevel )) != NULL)
429 {
430 if (!strcmp(token,"*MATERIAL_NAME"))
431 {
432 char* name;
433 if (! parser.parseString(name, "mat name") )
434 return FALSE;
435
436 if ( mat->sub_flag )
437 {
438 char buff [ 256 ] ;
439 sprintf( buff, "%s, sub#%d", mat_name, sub_index );
440
441 mat->name = ulStrDup ( buff ) ;
442 }
443 else
444 mat->name = ulStrDup ( name ) ;
445 }
446 else if (!strcmp(token,"*MATERIAL_AMBIENT"))
447 {
448 if (! parser.parseFloat(mat->amb[ 0 ], "amb.r"))
449 return FALSE;
450 if (! parser.parseFloat(mat->amb[ 1 ], "amb.g"))
451 return FALSE;
452 if (! parser.parseFloat(mat->amb[ 2 ], "amb.b"))
453 return FALSE;
454 mat->amb[ 3 ] = 1.0f;
455 }
456 else if (!strcmp(token,"*MATERIAL_DIFFUSE"))
457 {
458 if (! parser.parseFloat(mat->diff[ 0 ], "diff.r"))
459 return FALSE;
460 if (! parser.parseFloat(mat->diff[ 1 ], "diff.g"))
461 return FALSE;
462 if (! parser.parseFloat(mat->diff[ 2 ], "diff.b"))
463 return FALSE;
464 mat->diff[ 3 ] = 1.0f;
465 }
466 else if (!strcmp(token,"*MATERIAL_SPECULAR"))
467 {
468 if (! parser.parseFloat(mat->spec[ 0 ], "spec.r"))
469 return FALSE;
470 if (! parser.parseFloat(mat->spec[ 1 ], "spec.g"))
471 return FALSE;
472 if (! parser.parseFloat(mat->spec[ 2 ], "spec.b"))
473 return FALSE;
474 mat->spec[ 3 ] = 1.0f;
475 }
476 else if (!strcmp(token,"*MATERIAL_SHINE"))
477 {
478 if (! parser.parseFloat(mat->shine, "shine"))
479 return FALSE;
480
481 // SAC: Shine seems off. If I load a 3ds of the same shape
482 // the shine is 256x as much and works better, so I'll tweak
483 // the val here :) I couldn't clarify the range used by
484 // MAX SDK anywhere in the docs (though this assumes 0 - 0.5).
485 // OpenGL is 0-128.
486 mat->shine = mat->shine * 256.0f;
487 if ( mat->shine > 128 )
488 mat->shine = 128;
489 }
490 else if (!strcmp(token,"*MATERIAL_TRANSPARENCY"))
491 {
492 if (! parser.parseFloat(mat->transparency, "transparency"))
493 return FALSE;
494 }
495 else if (!strcmp(token,"*MAP_DIFFUSE"))
496 {
497 //Need: what about MAP_GENERIC, MAP_AMBIENT, etc??
498 if (! parse_map( mat ))
499 return FALSE;
500 }
501 else if (!strcmp(token,"*SUBMATERIAL"))
502 {
503 u32 sub_index;
504 if (! parser.parseUInt(sub_index, "sub mat #"))
505 return FALSE;
506 if (! parse_material( mat_index, sub_index, mat->name ))
507 return FALSE;
508 }
509 }
510
511 //parser.message("material: %s (%s)",mat->name,mat->tfname);
512 return TRUE;
513 }
514
515
parse_material_list()516 static int parse_material_list()
517 // return TRUE on success
518 {
519 if ( num_materials )
520 parser.error("multiple material lists");
521
522 char* token;
523 int startLevel = parser.level;
524 while ((token = parser.getLine( startLevel )) != NULL)
525 {
526 if (!strcmp(token,"*MATERIAL"))
527 {
528 u32 mat_index;
529 if (! parser.parseUInt(mat_index, "mat #"))
530 return FALSE;
531 if (! parse_material( mat_index, 9999, NULL ))
532 return FALSE;
533 }
534 }
535 return TRUE;
536 }
537
538
parse_mesh(aseObject * obj)539 static int parse_mesh( aseObject* obj )
540 {
541 aseMesh* mesh = NULL ;
542 u32 mesh_face_normal_index = 0x7fffffff;
543 u32 mesh_face_normal_count = 0;
544
545 char* token;
546 int startLevel = parser.level;
547 while ((token = parser.getLine( startLevel )) != NULL)
548 {
549 if ( mesh == NULL )
550 {
551 u32 frame = aseObject::MAX_FRAMES ;
552
553 if (!strcmp(token,"*TIMEVALUE"))
554 {
555 u32 time;
556 if (! parser.parseUInt(time, "time"))
557 return FALSE;
558 frame = (time + (ticks_per_frame-1)) / ticks_per_frame - first_frame;
559 }
560 else
561 {
562 parser.error("missing *TIMEVALUE");
563 frame = aseObject::MAX_FRAMES ;
564 }
565
566 if ( frame >= aseObject::MAX_FRAMES || obj->mesh_list [ frame ] != NULL )
567 {
568 //ignore this mesh
569 while (parser.getLine( startLevel )) ;
570 return TRUE; // go on parsing
571 }
572
573 mesh = new aseMesh ;
574 obj->mesh_list [ frame ] = mesh ;
575 obj->mesh_count ++ ;
576 }
577 else if (!strcmp(token,"*MESH_NUMFACES"))
578 {
579 if (mesh -> faces)
580 parser.error("%s already seen",token);
581 else
582 {
583 if (! parser.parseUInt(mesh -> num_faces, "num_faces"))
584 return FALSE;
585 mesh -> faces = new aseFace[ mesh -> num_faces ];
586
587 // SAC: Help clear all the has_vertex_normals flags
588 memset ( mesh -> faces, 0, mesh -> num_faces * sizeof (aseFace) );
589 }
590 }
591 else if (!strcmp(token,"*MESH_NUMTVFACES"))
592 {
593 u32 ntfaces;
594 if (! parser.parseUInt(ntfaces, "ntfaces"))
595 return FALSE;
596 if (ntfaces != mesh -> num_faces)
597 parser.error("NUMTFACES(%d) != NUMFACES(%d)",ntfaces,mesh -> num_faces);
598 }
599 else if (!strcmp(token,"*MESH_NUMCVFACES"))
600 {
601 u32 ncfaces;
602 if (! parser.parseUInt(ncfaces, "ncfaces"))
603 return FALSE;
604 if (ncfaces != mesh -> num_faces)
605 parser.error("NUMCFACES(%d) != NUMFACES(%d)",ncfaces,mesh -> num_faces);
606 }
607 else if (!strcmp(token,"*MESH_NUMVERTEX"))
608 {
609 if (mesh -> verts)
610 parser.error("%s already seen",token);
611 else
612 {
613 if (! parser.parseUInt(mesh -> num_verts, "num_verts"))
614 return FALSE;
615 mesh -> verts = new sgVec3[ mesh -> num_verts ];
616 }
617 }
618 else if (!strcmp(token,"*MESH_NUMTVERTEX"))
619 {
620 if (mesh -> tverts)
621 parser.error("%s already seen",token);
622 else
623 {
624 if (! parser.parseUInt(mesh -> num_tverts, "num_tverts"))
625 return FALSE;
626 if (mesh -> num_tverts)
627 mesh -> tverts = new sgVec2[ mesh -> num_tverts ];
628 }
629 }
630 else if (!strcmp(token,"*MESH_NUMCVERTEX"))
631 {
632 if (mesh -> cverts)
633 parser.error("%s already seen",token);
634 else
635 {
636 if (! parser.parseUInt(mesh -> num_cverts, "num_cverts"))
637 return FALSE;
638 if (mesh -> num_cverts)
639 mesh -> cverts = new sgVec3[ mesh -> num_cverts ];
640 }
641 }
642 else if (!strcmp(token,"*MESH_FACE"))
643 {
644 u32 index;
645 // wk: The old parseInt converted a "3:" into 3,
646 // the new would give an error. Therefore I had to change this code:
647 char *my_endptr, *my_token = parser.parseToken("face #");
648 if (my_token[strlen(my_token)-1]==':')
649 my_token[strlen(my_token)-1]=0;
650
651 index = (unsigned int)(strtol( my_token, &my_endptr, 10));
652 if ( (my_endptr != NULL) && (*my_endptr != 0))
653 { parser.error("The field face # should contain an integer number but contains %s", my_token) ;
654 return FALSE;
655 }
656
657
658 if (index >= mesh -> num_faces)
659 parser.error("bad face #");
660 else
661 {
662 aseFace& face = mesh -> faces[ index ];
663
664 parser.expect("A:");
665 if (! parser.parseUInt(face.v[0], "face.v[0]"))
666 return FALSE;
667 parser.expect("B:");
668 if (! parser.parseUInt(face.v[1], "face.v[1]"))
669 return FALSE;
670 parser.expect("C:");
671 if (! parser.parseUInt(face.v[2], "face.v[2]"))
672 return FALSE;
673
674 //search for other flags
675 token = parser.parseToken(0);
676 while ( ! parser.eol )
677 {
678 if ( strcmp(token,"*MESH_MTLID") == 0 )
679 {
680 if (! parser.parseUInt(face.sub_index, "mat #"))
681 return FALSE;
682 }
683 token = parser.parseToken(0);
684 }
685 }
686 }
687 else if (!strcmp(token,"*MESH_TFACE"))
688 {
689 u32 index;
690 if (! parser.parseUInt(index, "tface #"))
691 return FALSE;
692 if (index >= mesh -> num_faces)
693 parser.error("bad tface #");
694 else
695 {
696 aseFace& face = mesh -> faces[ index ];
697
698 if (! parser.parseUInt(face.tv[0], "tface.tv[0]"))
699 return FALSE;
700 if (! parser.parseUInt(face.tv[1], "tface.tv[1]"))
701 return FALSE;
702 if (! parser.parseUInt(face.tv[2], "tface.tv[2]"))
703 return FALSE;
704 }
705 }
706 else if (!strcmp(token,"*MESH_CFACE"))
707 {
708 u32 index;
709 if (! parser.parseUInt(index, "cface #"))
710 return FALSE;
711 if (index >= mesh -> num_faces)
712 parser.error("bad cface #");
713 else
714 {
715 aseFace& face = mesh -> faces[ index ];
716
717 if (! parser.parseUInt(face.cv[0], "tface.cv[0]"))
718 return FALSE;
719 if (! parser.parseUInt(face.cv[1], "tface.cv[1]"))
720 return FALSE;
721 if (! parser.parseUInt(face.cv[2], "tface.cv[2]"))
722 return FALSE;
723 }
724 }
725 // SAC: START OF VERTEX NORMAL PARSING SECTION
726 // NOTE: Assumes that three correctly-ordered *MESH_VERTEXNORMAL lines
727 // come after each *MESH_FACENORMAL line. Which seems to be the case
728 // in current exporter
729 else if (!strcmp(token,"*MESH_FACENORMAL"))
730 {
731 if (! parser.parseUInt(mesh_face_normal_index, "face normal #"))
732 return FALSE;
733 mesh_face_normal_count = 0;
734 }
735 else if (!strcmp(token,"*MESH_VERTEXNORMAL"))
736 {
737 //int nverts = mesh -> num_verts;
738
739 if ( mesh_face_normal_index >= mesh -> num_faces )
740 parser.error("bad mesh_face_normal_index #");
741 if ( mesh_face_normal_count >= 3 )
742 parser.error("bad mesh_face_normal_count");
743
744 aseFace& face = mesh -> faces[ mesh_face_normal_index ];
745 sgVec3& vn = face . vn [ mesh_face_normal_count ];
746 face.has_vertex_normals = true;
747 u32 vertex_index;
748 if (! parser.parseUInt(vertex_index, "vertex normal #"))
749 return FALSE;
750 if ( face.v [mesh_face_normal_count] != vertex_index )
751 parser.error("bad MESH_VERTEXNORMAL entries out of order!");
752 if (! parser.parseFloat(vn[0], "vertexNormal.x"))
753 return FALSE;
754 if (! parser.parseFloat(vn[1], "vertexNormal.y"))
755 return FALSE;
756 if (! parser.parseFloat(vn[2], "vertexNormal.z"))
757 return FALSE;
758
759 // sgNormaliseVec3 ( vn ) ;
760 mesh_face_normal_count++;
761 }
762 // SAC: END OF VERTEX NORMAL PARSING SECTION
763 else if (!strcmp(token,"*MESH_VERTEX"))
764 {
765 u32 index;
766 if (! parser.parseUInt(index, "vertex #"))
767 return FALSE;
768 if (index >= mesh -> num_verts)
769 parser.error("bad vertex #");
770 else
771 {
772 sgVec3& vert = mesh -> verts[ index ];
773
774 if (! parser.parseFloat(vert[0], "vert.x"))
775 return FALSE;
776 if (! parser.parseFloat(vert[1], "vert.y"))
777 return FALSE;
778 if (! parser.parseFloat(vert[2], "vert.z"))
779 return FALSE;
780 }
781 }
782 else if (!strcmp(token,"*MESH_TVERT"))
783 {
784 u32 index;
785 if (! parser.parseUInt(index, "tvertex #"))
786 return FALSE;
787 if (index >= mesh -> num_tverts)
788 parser.error("bad tvertex #");
789 else
790 {
791 sgVec2& tvert = mesh -> tverts[ index ];
792
793 if (! parser.parseFloat(tvert[0], "tvert.x"))
794 return FALSE;
795 if (! parser.parseFloat(tvert[1], "tvert.y"))
796 return FALSE;
797 }
798 }
799 else if (!strcmp(token,"*MESH_VERTCOL"))
800 {
801 u32 index;
802 if (! parser.parseUInt(index, "cvertex #"))
803 return FALSE;
804 if (index >= mesh -> num_cverts)
805 parser.error("bad cvertex #");
806 else
807 {
808 sgVec3& cvert = mesh -> cverts[ index ];
809
810 if (! parser.parseFloat(cvert[0], "cvert.x"))
811 return FALSE;
812 if (! parser.parseFloat(cvert[1], "cvert.y"))
813 return FALSE;
814 if (! parser.parseFloat(cvert[2], "cvert.z"))
815 return FALSE;
816 }
817 }
818 }
819 return TRUE;
820 }
821
822
get_texcoord(aseMaterial * mat,sgVec2 tv)823 static void get_texcoord ( aseMaterial* mat, sgVec2 tv )
824 {
825 //invert Y coordinate
826 tv[1] = 1.0f - tv[1] ;
827
828 tv[0] *= mat->texrep[0] ;
829 tv[1] *= mat->texrep[1] ;
830 tv[0] += mat->texoff[0] ;
831 tv[1] += mat->texoff[1] ;
832 }
833
834
add_points(aseObject * obj,aseMesh * mesh)835 static ssgLeaf* add_points( aseObject* obj, aseMesh* mesh )
836 {
837 ssgVertexArray* vl = NULL ;
838
839 if ( obj->type == aseObject::CAMERA )
840 {
841 /* compute a normalized target vector */
842 sgVec3 target ;
843 sgCopyVec3 ( target, obj->target ) ;
844 sgSubVec3 ( target, obj->pos ) ;
845
846 SGfloat len = sgLengthVec3 ( target ) ;
847 if ( len == SG_ZERO )
848 {
849 vl = new ssgVertexArray ( 1 ) ;
850 vl -> add ( obj->pos ) ;
851 }
852 else
853 {
854 vl = new ssgVertexArray ( 2 ) ;
855
856 sgNormaliseVec3 ( target ) ;
857 sgAddVec3 ( target, obj->pos ) ;
858
859 vl -> add ( obj->pos ) ;
860 vl -> add ( target ) ;
861 }
862 }
863 else if ( mesh != NULL )
864 {
865 u32 num_verts = mesh -> num_verts ;
866 if ( num_verts == 0 )
867 return NULL;
868
869 vl = new ssgVertexArray ( num_verts ) ;
870
871 //pass the data to ssg
872 sgVec3* vert = mesh -> verts ;
873 for ( u32 i=0; i < num_verts; i++, vert++ )
874 vl -> add ( *vert ) ;
875 }
876 else
877 {
878 return NULL ;
879 }
880
881 ssgVtxTable* leaf = new ssgVtxTable ( GL_POINTS,
882 vl, NULL, NULL, NULL ) ;
883
884 if ( leaf != NULL )
885 {
886 // leaves with no faces are used for game logic
887 // and should not be culled and rendered
888 leaf -> clrTraversalMaskBits ( SSGTRAV_CULL ) ;
889 }
890
891 return ssgGetCurrentOptions () -> createLeaf ( leaf, obj -> name ) ;
892 }
893
894
add_mesh(aseObject * obj,aseMesh * mesh,u32 sub_index)895 static ssgLeaf* add_mesh( aseObject* obj, aseMesh* mesh, u32 sub_index )
896 {
897 u32 i ;
898
899 aseMaterial* mat = find_material ( obj->mat_index, sub_index ) ;
900 if ( mat == NULL )
901 return NULL ;
902
903 //compute number of faces for this sub-material
904 u32 num_faces = mesh -> num_faces ;
905 if ( mat->sub_flag )
906 {
907 num_faces = 0 ;
908 aseFace* face = mesh -> faces ;
909 for ( i=0; i<mesh -> num_faces; i++, face++ )
910 {
911 if ( face->sub_index == mat->sub_index )
912 num_faces ++ ;
913 }
914 }
915 if ( num_faces == 0 )
916 return NULL ;
917
918 if ( mesh -> cverts == NULL )
919 {
920 u32 num_verts = num_faces * 3 ;
921
922 //pass the data to ssg
923 ssgSimpleState* st = get_state ( mat, false ) ;
924 ssgColourArray* cl = new ssgColourArray ( 1 ) ;
925 ssgVertexArray* vl = new ssgVertexArray ( num_verts ) ;
926 ssgNormalArray* nl = new ssgNormalArray ( num_verts ) ;
927 ssgTexCoordArray* tl = 0 ;
928 if ( mesh -> tverts )
929 tl = new ssgTexCoordArray ( num_verts ) ;
930
931 //set the material colour
932 sgVec4 c ;
933 sgCopyVec3 ( c, mat -> diff ) ;
934 c[3] = 1.0f - mat -> transparency ;
935 cl -> add ( c ) ;
936
937 aseFace* face = mesh -> faces ;
938 for ( i=0; i<mesh -> num_faces; i++, face++ )
939 {
940 if ( mat->sub_flag && face->sub_index != mat->sub_index )
941 continue ;
942
943 sgVec3 n ;
944 sgMakeNormal ( n,
945 mesh -> verts[ face->v[0] ] ,
946 mesh -> verts[ face->v[1] ] ,
947 mesh -> verts[ face->v[2] ] ) ;
948
949 for ( u32 j=0; j<3; j++ )
950 {
951 vl -> add ( mesh -> verts[ face->v[j] ] ) ;
952
953 // SAC: If per-vertex normals were found, use 'em.
954 // Else use the face normal computed above
955 if ( face -> has_vertex_normals )
956 nl -> add ( face->vn [j] ) ;
957 else
958 nl -> add ( n ) ;
959
960 if ( mesh -> tverts )
961 {
962 sgVec2 tv ;
963 sgCopyVec2 ( tv, mesh -> tverts[ face->tv[j] ] ) ;
964 get_texcoord ( mat, tv ) ;
965 tl -> add ( tv ) ;
966 }
967 }
968 }
969
970 ssgVtxTable* leaf = new ssgVtxTable ( GL_TRIANGLES,
971 vl, nl, tl, cl ) ;
972 leaf -> setCullFace ( TRUE ) ;
973 leaf -> setState ( st ) ;
974 return current_options -> createLeaf ( leaf, obj->name ) ;
975 }
976
977 //allocate map_index array
978 int* map_index = new int [ mesh -> num_faces * 3 ] ;
979
980 //allocate the vertex list
981 u32 max_verts = mesh -> num_verts + mesh -> num_faces * 3 ;
982 aseVertexBuffer* vert_list = new aseVertexBuffer [ max_verts ] ;
983
984 //mark each vertex as *not* used
985 aseVertexBuffer* vert = vert_list ;
986 for ( i=0; i < max_verts; i++, vert++ )
987 {
988 vert -> use_flag = false ;
989 }
990
991 u32 extra_verts = 0 ;
992
993 //build the vertex list
994 aseFace* face = mesh -> faces ;
995 for ( i=0; i<mesh -> num_faces; i++, face++ )
996 {
997 if ( mat->sub_flag && face->sub_index != mat->sub_index )
998 continue ;
999
1000 for ( u32 j=0; j<3; j++ )
1001 {
1002 int k = i*3+j;
1003
1004 map_index [k] = face->v[j] ;
1005 vert = vert_list + map_index[k];
1006
1007 if ( vert -> use_flag )
1008 {
1009 //check for match
1010 bool match = true ;
1011 if ( mesh -> tverts &&
1012 sgCompareVec2 ( vert -> tv, mesh -> tverts[ face->tv[j] ], 0.0f ) != 0 )
1013 match = false ;
1014 else if ( mesh -> cverts &&
1015 sgCompareVec3 ( vert -> cv, mesh -> cverts[ face->cv[j] ], 0.0f ) != 0 )
1016 match = false ;
1017 if ( match )
1018 continue ; //texcoord and color matches other vertex
1019
1020 extra_verts ++ ;
1021
1022 map_index [k] = mesh -> num_verts + k ;
1023 vert = vert_list + map_index[k];
1024 }
1025
1026 //add the vertex
1027 vert -> use_flag = true;
1028 sgCopyVec3 ( vert -> v, mesh -> verts[ face->v[j] ] ) ;
1029 if ( mesh -> tverts )
1030 sgCopyVec2 ( vert -> tv, mesh -> tverts[ face->tv[j] ] ) ;
1031 if ( mesh -> cverts )
1032 sgCopyVec3 ( vert -> cv, mesh -> cverts[ face->cv[j] ] ) ;
1033 }
1034 }
1035
1036 //assign a unique index to each vertex
1037 int num_verts = 0 ;
1038 vert = vert_list;
1039 for ( i=0; i < max_verts; i++, vert++ )
1040 {
1041 if ( vert -> use_flag )
1042 vert -> index = num_verts ++;
1043 }
1044
1045 //if ( extra_verts > 0 )
1046 // ulSetError( UL_DEBUG, "%d verts; %d added", num_verts-extra_verts, extra_verts );
1047 //else
1048 // ulSetError( UL_DEBUG, "%d verts", num_verts );
1049
1050 //pass the data to ssg
1051 ssgSimpleState* st = get_state ( mat, ( mesh -> cverts != NULL ) ) ;
1052 ssgIndexArray* il = new ssgIndexArray ( num_faces * 3 ) ;
1053 ssgVertexArray* vl = new ssgVertexArray ( num_verts ) ;
1054 ssgTexCoordArray* tl = 0 ;
1055 ssgColourArray* cl = 0 ;
1056 if ( mesh -> tverts )
1057 tl = new ssgTexCoordArray ( num_verts ) ;
1058 if ( mesh -> cverts )
1059 cl = new ssgColourArray ( num_verts ) ;
1060
1061 //build the index list
1062 face = mesh -> faces ;
1063 for ( i=0; i<mesh -> num_faces; i++, face++ )
1064 {
1065 if ( mat->sub_flag && face->sub_index != mat->sub_index )
1066 continue ;
1067
1068 for ( u32 j=0; j<3; j++ )
1069 {
1070 int k = i*3+j;
1071 vert = vert_list + map_index[k];
1072
1073 if ( ! vert -> use_flag )
1074 ulSetError ( UL_FATAL, "internal error" ) ;
1075
1076 il -> add ( vert -> index ) ;
1077 }
1078 }
1079
1080 //copy the vertex lists
1081 vert = vert_list;
1082 for ( i=0; i < max_verts; i++, vert++ )
1083 {
1084 if ( vert -> use_flag )
1085 {
1086 vl -> add ( vert -> v ) ;
1087
1088 if ( mesh -> tverts )
1089 {
1090 sgVec2 tv ;
1091 sgCopyVec2 ( tv, vert -> tv ) ;
1092 get_texcoord ( mat, tv ) ;
1093 tl -> add ( tv ) ;
1094 }
1095
1096 if ( mesh -> cverts )
1097 {
1098 sgVec4 c ;
1099 sgCopyVec3 ( c, vert -> cv ) ;
1100 c[3] = 1.0f - mat -> transparency ;
1101
1102 cl -> add ( c ) ;
1103 }
1104 }
1105 }
1106
1107 delete[] vert_list ;
1108 delete[] map_index ;
1109
1110 ssgVtxArray* leaf = new ssgVtxArray ( GL_TRIANGLES,
1111 vl, NULL, tl, cl, il ) ;
1112 leaf -> setCullFace ( TRUE ) ;
1113 leaf -> setState ( st ) ;
1114 return current_options -> createLeaf ( leaf, obj -> name ) ;
1115 }
1116
1117
get_tkey(aseObject * obj,u32 time)1118 static aseTransform* get_tkey( aseObject* obj, u32 time )
1119 {
1120 if ( obj->tkeys == NULL )
1121 {
1122 obj->num_tkeys = 0;
1123 obj->tkeys = new aseTransform [ num_frames ] ;
1124
1125 //initialize
1126 aseTransform* tkey = obj->tkeys ;
1127 for ( u32 i=0; i<num_frames; i++, tkey++ )
1128 {
1129 sgSetVec3 ( tkey->pos, 0, 0, 0 ) ;
1130 sgSetVec3 ( tkey->axis, 0, 0, 1 ) ;
1131 tkey->angle = 0.0f ;
1132 sgSetVec3 ( tkey->scale, 1, 1, 1 ) ;
1133 }
1134 }
1135
1136 //compute frame number
1137 u32 frame = time / ticks_per_frame - first_frame;
1138 if ((time % ticks_per_frame) != 0 || frame >= num_frames)
1139 parser.error("bad time");
1140
1141 if ( frame+1 > obj->num_tkeys )
1142 obj->num_tkeys = frame+1;
1143
1144 return( &obj->tkeys[ frame ] );
1145 }
1146
1147 #define MAX_TKEY_PER_MESH 256
1148
parse_tkeys(aseObject * obj)1149 static int parse_tkeys( aseObject* obj )
1150 {
1151 bool match = false ;
1152 void *tkeys[MAX_TKEY_PER_MESH];
1153 int num_tkeys=0;
1154 char* token;
1155 int startLevel = parser.level;
1156 while ((token = parser.getLine( startLevel )) != NULL)
1157 {
1158 if (!strcmp(token,"*NODE_NAME"))
1159 {
1160 char* name;
1161 if (! parser.parseString(name, "obj name"))
1162 return FALSE;
1163 if ( obj->name && !strcmp(name,obj->name) )
1164 match = true ;
1165 }
1166 else if (match)
1167 {
1168 if (!strcmp(token,"*CONTROL_POS_SAMPLE"))
1169 {
1170 u32 time;
1171 if (! parser.parseUInt(time, "time"))
1172 return FALSE;
1173 aseTransform* tkey = get_tkey( obj, time );
1174
1175 if (! parser.parseFloat(tkey->pos[0], "pos.x"))
1176 return FALSE;
1177 if (! parser.parseFloat(tkey->pos[1], "pos.y"))
1178 return FALSE;
1179 if (! parser.parseFloat(tkey->pos[2], "pos.z"))
1180 return FALSE;
1181
1182 if ( obj->parent == NULL )
1183 {
1184 sgSubVec3 ( tkey->pos, obj->pos ) ;
1185 }
1186 else
1187 {
1188 for ( int i=0; i<3; i++ )
1189 {
1190 if ( obj->inherit_pos[i] )
1191 tkey->pos[i] -= obj->pos[i] ;
1192 }
1193 }
1194
1195 //copy the position forward
1196 for ( u32 i=obj->num_tkeys; i<num_frames; i++ )
1197 sgCopyVec3 ( obj->tkeys[ i ].pos, tkey->pos ) ;
1198 }
1199 else if (!strcmp(token,"*CONTROL_ROT_SAMPLE"))
1200 {
1201 u32 time;
1202 if (!parser.parseUInt(time, "time"))
1203 return FALSE;
1204 aseTransform* tkey = get_tkey( obj, time );
1205
1206 if (! parser.parseFloat(tkey->axis[0], "axis.x"))
1207 return FALSE;
1208 if (! parser.parseFloat(tkey->axis[1], "axis.y"))
1209 return FALSE;
1210 if (! parser.parseFloat(tkey->axis[2], "axis.z"))
1211 return FALSE;
1212 if (! parser.parseFloat(tkey->angle, "angle"))
1213 return FALSE;
1214 }
1215 else if (!strcmp(token,"*CONTROL_TCB_ROT_KEY"))
1216 {
1217 u32 time;
1218 if (!parser.parseUInt(time, "time"))
1219 return FALSE;
1220 aseTransform* tkey = new aseTransform;
1221 tkeys[num_tkeys++] = tkey;
1222 assert(num_tkeys < MAX_TKEY_PER_MESH);
1223 sgSetVec3 ( tkey->pos, 0, 0, 0 ) ; // "TCB": only rotation allowed :-/
1224 sgSetVec3 ( tkey->axis, 0, 0, 1 ) ;
1225 tkey->angle = 0.0f ;
1226 sgSetVec3 ( tkey->scale, 1, 1, 1 ) ;
1227
1228 // *CONTROL_TCB_ROT_KEY 160 -0.9949 -0.0914 0.0434 3.1336 0.0000 0.0000 0.0000 0.0000 0.0000
1229 if (! parser.parseFloat(tkey->axis[0], "axis.x"))
1230 return FALSE;
1231 if (! parser.parseFloat(tkey->axis[1], "axis.y"))
1232 return FALSE;
1233 if (! parser.parseFloat(tkey->axis[2], "axis.z"))
1234 return FALSE;
1235 if (! parser.parseFloat(tkey->angle, "angle"))
1236 return FALSE;
1237 float dummy;
1238 if (! parser.parseFloat(dummy, "tens"))
1239 return FALSE;
1240 if (! parser.parseFloat(dummy, "cont"))
1241 return FALSE;
1242 if (! parser.parseFloat(dummy, "bias"))
1243 return FALSE;
1244 if (! parser.parseFloat(dummy, "easeIn"))
1245 return FALSE;
1246 if (! parser.parseFloat(dummy, "easeOut"))
1247 return FALSE;
1248 }
1249 else if (!strcmp(token,"*CONTROL_SCALE_SAMPLE"))
1250 {
1251 u32 time;
1252 if (! parser.parseUInt(time, "time"))
1253 return FALSE;
1254 aseTransform* tkey = get_tkey( obj, time );
1255
1256 if (! parser.parseFloat(tkey->scale[0], "scale.x"))
1257 return FALSE;
1258 if (! parser.parseFloat(tkey->scale[1], "scale.y"))
1259 return FALSE;
1260 if (! parser.parseFloat(tkey->scale[2], "scale.z"))
1261 return FALSE;
1262 }
1263 }
1264 }
1265 if(num_tkeys)
1266 {
1267 obj->num_tkeys = num_tkeys;
1268 obj->tkeys = new aseTransform [ num_tkeys ] ;
1269 for(int i=0; i<num_tkeys; i++)
1270 obj->tkeys[i] = *((aseTransform *)tkeys[i]);
1271 }
1272 return TRUE;
1273 }
1274
1275
parse_object(aseObject::Type type)1276 static int parse_object( aseObject::Type type )
1277 {
1278 aseObject* obj = new aseObject ( type ) ;
1279
1280 char* token;
1281 int startLevel = parser.level;
1282 while ((token = parser.getLine( startLevel )) != NULL)
1283 {
1284 if (!strcmp(token,"*NODE_NAME"))
1285 {
1286 if ( !obj->name )
1287 {
1288 char* name;
1289 if (! parser.parseString(name, "obj name"))
1290 return FALSE;
1291
1292
1293 obj->name = ulStrDup ( name ) ;
1294 }
1295 }
1296 else if (!strcmp(token,"*NODE_PARENT"))
1297 {
1298 if ( !obj->parent )
1299 {
1300 char* name;
1301 if (! parser.parseString(name, "parent name"))
1302 return FALSE;
1303
1304
1305 obj->parent = ulStrDup ( name ) ;
1306 }
1307 }
1308 else if (!strcmp(token,"*NODE_TM"))
1309 {
1310 bool target = false ;
1311 bool match = false ;
1312 int startLevel = parser.level;
1313 while ((token = parser.getLine( startLevel )) != NULL)
1314 {
1315 if (!strcmp(token,"*NODE_NAME"))
1316 {
1317 char* name;
1318 if (! parser.parseString(name, "obj name"))
1319 return FALSE;
1320 if ( obj->name && !strcmp(name,obj->name) )
1321 match = true ;
1322 if ( strstr(name,".Target") != NULL )
1323 target = true ;
1324 }
1325 else if (match)
1326 {
1327 if (!strcmp(token,"*TM_POS"))
1328 {
1329 if (! parser.parseFloat(obj->pos[0], "pos.x"))
1330 return FALSE;
1331 if (! parser.parseFloat(obj->pos[1], "pos.y"))
1332 return FALSE;
1333 if (! parser.parseFloat(obj->pos[2], "pos.z"))
1334 return FALSE;
1335 sgCopyVec3 ( obj->target, obj->pos ) ;
1336 }
1337 else if (!strcmp(token,"*INHERIT_POS"))
1338 {
1339 int temp ;
1340 if (! parser.parseInt(temp, "inherit_pos.x"))
1341 return FALSE;
1342 obj->inherit_pos[0] = ( temp != 0 ) ;
1343 if (! parser.parseInt(temp, "inherit_pos.y"))
1344 return FALSE;
1345 obj->inherit_pos[1] = ( temp != 0 ) ;
1346 if (! parser.parseInt(temp, "inherit_pos.z"))
1347 return FALSE;
1348 obj->inherit_pos[2] = ( temp != 0 ) ;
1349 }
1350 }
1351 else if (target)
1352 {
1353 if (!strcmp(token,"*TM_POS"))
1354 {
1355 if (! parser.parseFloat(obj->target[0], "pos.x"))
1356 return FALSE;
1357 if (! parser.parseFloat(obj->target[1], "pos.y"))
1358 return FALSE;
1359 if (! parser.parseFloat(obj->target[2], "pos.z"))
1360 return FALSE;
1361 }
1362 }
1363 }
1364 }
1365 else if (!strcmp(token,"*MESH"))
1366 {
1367 if (! parse_mesh( obj ))
1368 return FALSE;
1369 }
1370 else if (!strcmp(token,"*MESH_ANIMATION"))
1371 {
1372 int startLevel = parser.level;
1373 while ((token = parser.getLine( startLevel )) != NULL)
1374 {
1375 if (!strcmp(token,"*MESH"))
1376 {
1377 if (! parse_mesh( obj ))
1378 return FALSE;
1379 }
1380 }
1381 }
1382 else if (!strcmp(token,"*TM_ANIMATION"))
1383 {
1384 if (! parse_tkeys( obj ))
1385 return FALSE;
1386 }
1387 else if (!strcmp(token,"*MATERIAL_REF"))
1388 {
1389 if (! parser.parseUInt(obj->mat_index, "mat #"))
1390 return FALSE;
1391 }
1392 }
1393
1394 //if ( obj->parent != NULL )
1395 // ulSetError( UL_DEBUG, "add_mesh: %s, parent=%s", obj->name, obj->parent ) ;
1396 //else
1397 // ulSetError( UL_DEBUG, "add_mesh: %s", obj->name ) ;
1398
1399 ssgEntity* mesh_entity = NULL ;
1400
1401 if ( obj->mesh_count > 1 )
1402 {
1403 //how many frames?
1404 int num_frames = 0 ;
1405 int i ;
1406 for ( i=0; i<aseObject::MAX_FRAMES; i++ )
1407 {
1408 aseMesh* mesh = obj->mesh_list [ i ] ;
1409 if ( mesh != NULL )
1410 num_frames ++ ;
1411 }
1412
1413 //allocate selector
1414 ssgSelector* selector = new ssgSelector ( num_frames ) ;
1415
1416 //init
1417 for ( i=0; i<aseObject::MAX_FRAMES; i++ )
1418 {
1419 aseMesh* mesh = obj->mesh_list [ i ] ;
1420 if ( mesh == NULL )
1421 continue ;
1422
1423 u32 num_subs = count_sub_materials ( obj->mat_index );
1424 if ( num_subs > 1 )
1425 {
1426 //break apart the mesh for each sub material
1427 ssgBranch* branch = new ssgBranch ;
1428 for ( u32 sub_index=0; sub_index<num_subs; sub_index++ )
1429 {
1430 ssgLeaf* leaf = add_mesh ( obj, mesh, sub_index );
1431 if ( leaf )
1432 branch -> addKid ( leaf ) ;
1433 }
1434 selector -> addKid ( branch ) ;
1435 }
1436 else
1437 {
1438 ssgLeaf* leaf = add_mesh ( obj, mesh, 0 ) ;
1439 if ( leaf )
1440 selector -> addKid ( leaf ) ;
1441 }
1442 }
1443
1444 selector -> selectStep ( 0 ) ;
1445 mesh_entity = current_options -> createSelector ( selector ) ;
1446 }
1447 else if ( obj->mesh_list [ 0 ] != NULL )
1448 {
1449 aseMesh* mesh = obj->mesh_list [ 0 ] ;
1450 ssgBranch* branch = new ssgBranch ;
1451
1452 u32 num_faces = mesh -> num_faces ;
1453 if ( num_faces == 0 )
1454 {
1455 ssgLeaf* leaf = add_points( obj, mesh ) ;
1456 if ( leaf )
1457 branch -> addKid ( leaf ) ;
1458 }
1459 else
1460 {
1461 u32 num_subs = count_sub_materials ( obj->mat_index );
1462 if ( num_subs > 1 )
1463 {
1464 //break apart the mesh for each sub material
1465 for ( u32 sub_index=0; sub_index<num_subs; sub_index++ )
1466 {
1467 ssgLeaf* leaf = add_mesh ( obj, mesh, sub_index );
1468 if ( leaf )
1469 branch -> addKid ( leaf ) ;
1470 }
1471 }
1472 else
1473 {
1474 ssgLeaf* leaf = add_mesh ( obj, mesh, 0 );
1475 if ( leaf )
1476 branch -> addKid ( leaf ) ;
1477 }
1478 }
1479
1480 mesh_entity = branch ;
1481 }
1482 else
1483 {
1484 ssgBranch* branch = new ssgBranch ;
1485 ssgLeaf* leaf = add_points( obj, NULL ) ;
1486 if ( leaf )
1487 branch -> addKid ( leaf ) ;
1488 mesh_entity = branch ;
1489 }
1490
1491 if ( mesh_entity != NULL )
1492 {
1493 //add to graph -- find parent branch
1494 ssgBranch* parent_branch ;
1495 if ( obj->parent )
1496 {
1497 ssgEntity* found = top_branch -> getByName ( obj->parent ) ;
1498 if ( found != NULL )
1499 {
1500 assert ( found -> isAKindOf ( ssgTypeBranch() ) ) ;
1501 parent_branch = (ssgBranch *) found ;
1502 }
1503 else
1504 {
1505 //parser.error("object %s: parent %s not seen",obj->name,obj->parent);
1506 parent_branch = top_branch ;
1507 }
1508 }
1509 else
1510 {
1511 parent_branch = top_branch ;
1512 }
1513
1514 if ( obj->num_tkeys > 0 )
1515 {
1516 ssgAnimTransform * at = new ssgAnimTransform;
1517 at->setNum( obj->num_tkeys );
1518
1519 /*
1520 Build the transforms
1521 */
1522 sgMat4 rmat;
1523 sgMakeIdentMat4 ( rmat ) ;
1524 at->setATransform ( rmat, 0);
1525
1526 for ( u32 i = 1 ; i < obj->num_tkeys ; i++ )
1527 {
1528 aseTransform* tkey = obj->tkeys + i ;
1529
1530 sgVec3 pos ;
1531 sgMat4 tmp ;
1532 sgMat4 mat ;
1533
1534 /*
1535 * compute rmat
1536 * the key rotation is additive to the last rotation
1537 */
1538 sgMakeRotMat4 ( tmp, -tkey->angle * SG_RADIANS_TO_DEGREES, tkey->axis ) ;
1539 sgPostMultMat4 ( rmat, tmp ) ;
1540
1541 /*
1542 * rotation is around the mesh pivot point (obj->pos)
1543 * translate -obj->pos
1544 */
1545 sgCopyVec3 ( pos, obj->pos ) ;
1546 sgNegateVec3 ( pos ) ;
1547 sgMakeTransMat4 ( mat, pos ) ;
1548
1549 /*
1550 * perform the rotation
1551 */
1552 sgPostMultMat4 ( mat, rmat ) ;
1553
1554 /*
1555 * translate obj->pos + tkey->pos
1556 */
1557 sgCopyVec3 ( pos, obj->pos ) ;
1558 sgAddVec3 ( pos, tkey->pos ) ;
1559 sgMakeTransMat4 ( tmp, pos ) ;
1560 sgPostMultMat4 ( mat, tmp ) ;
1561
1562 at->setATransform ( mat, i);
1563 }
1564 // insert the ssgAnimTransform into the scene graph:
1565 at-> addKid ( mesh_entity ) ;
1566 mesh_entity = at;
1567 }
1568
1569 parent_branch -> addKid ( mesh_entity ) ;
1570 mesh_entity -> setName ( obj->name ) ;
1571 }
1572
1573 delete obj ;
1574 return TRUE;
1575 }
1576
1577
parse()1578 static bool parse()
1579 {
1580 materials = new aseMaterial* [ MAX_MATERIALS ];
1581 if ( !materials )
1582 {
1583 parser.error("not enough memory");
1584 return false ;
1585 }
1586
1587 num_materials = 0 ;
1588
1589 first_frame = 0 ;
1590 last_frame = 0 ;
1591 frame_speed = 0 ;
1592 ticks_per_frame = 0 ;
1593 num_frames = 0 ;
1594
1595 bool firsttime = true;
1596 char* token;
1597 int startLevel = parser.level;
1598 while ((token = parser.getLine( startLevel )) != NULL)
1599 {
1600 if (firsttime)
1601 {
1602 if (strcmp(token,"*3DSMAX_ASCIIEXPORT"))
1603 {
1604 parser.error("not ASE format");
1605 return false ;
1606 }
1607 u32 version_number;
1608 if (! parser.parseUInt(version_number, "version number") )
1609 return false ;
1610 if ( version_number != 200)
1611 {
1612 parser.error("invalid %s version",token);
1613 return false ;
1614 }
1615 firsttime = false;
1616 }
1617 else if (!strcmp(token,"*SCENE"))
1618 {
1619 int startLevel = parser.level;
1620 while ((token = parser.getLine( startLevel )) != NULL)
1621 {
1622 if (!strcmp(token,"*SCENE_FIRSTFRAME"))
1623 {
1624 if (! parser.parseUInt(first_frame, "FIRSTFRAME #"))
1625 return FALSE;
1626 }
1627 else if (!strcmp(token,"*SCENE_LASTFRAME"))
1628 {
1629 if (! parser.parseUInt(last_frame, "LASTFRAME #"))
1630 return FALSE;
1631 num_frames = last_frame - first_frame + 1;
1632 }
1633 else if (!strcmp(token,"*SCENE_FRAMESPEED"))
1634 {
1635 if (! parser.parseUInt(frame_speed, "FRAMESPEED #"))
1636 return FALSE;
1637 }
1638 else if (!strcmp(token,"*SCENE_TICKSPERFRAME"))
1639 {
1640 if (! parser.parseUInt(ticks_per_frame, "TICKSPERFRAME #"))
1641 return FALSE;
1642 }
1643 }
1644 }
1645 else if (!strcmp(token,"*MATERIAL_LIST"))
1646 {
1647 if (! parse_material_list())
1648 return FALSE;
1649 }
1650 else if (!strcmp(token,"*GEOMOBJECT"))
1651 {
1652 if (! parse_object( aseObject::GEOM ))
1653 return FALSE;
1654 }
1655 else if (!strcmp(token,"*HELPEROBJECT"))
1656 {
1657 if (! parse_object( aseObject::HELPER ))
1658 return FALSE;
1659 }
1660 else if (!strcmp(token,"*CAMERAOBJECT"))
1661 {
1662 if (! parse_object( aseObject::CAMERA ))
1663 return FALSE;
1664 }
1665 }
1666 return true ;
1667 }
1668
1669
parse_free()1670 static void parse_free()
1671 {
1672 u32 i ;
1673 for ( i = 0 ; i < num_materials ; i++ )
1674 {
1675 delete [] materials[ i ] -> name ;
1676 delete [] materials[ i ] -> tfname ;
1677 delete materials[ i ] ;
1678 }
1679 delete[] materials ;
1680 materials = 0 ;
1681 }
1682
1683
ssgLoadASE(const char * fname,const ssgLoaderOptions * options)1684 ssgEntity *ssgLoadASE ( const char *fname, const ssgLoaderOptions* options )
1685 {
1686 ssgSetCurrentOptions ( (ssgLoaderOptions*)options ) ;
1687 current_options = ssgGetCurrentOptions () ;
1688
1689 top_branch = new ssgBranch ;
1690 if ( !parser.openFile( fname, &parser_spec ) )
1691 {
1692 delete top_branch ;
1693 return 0;
1694 }
1695 if ( !parse() )
1696 {
1697 delete top_branch ;
1698 top_branch = 0 ;
1699 }
1700 parse_free();
1701 parser.closeFile();
1702
1703 return top_branch ;
1704 }
1705