indexing description: "Load a .x model with animation, ..." date: "$Date$" revision: "$Revision$" class EM3D_MODEL_X_FACTORY inherit EM3D_MODEL_FACTORY EM3D_X_PARSING_SUPPORT export {NONE} all end feature -- Load the model load_model_internal( a_filename: STRING ) is -- Load the model local file: PLAIN_TEXT_FILE actor, frame: EM3D_ACTOR name: STRING pos: INTEGER do create frames.make_default scene_manager.mesh_factory.load_mesh( a_filename ) create actor.make_by_parent( void ) create file.make_open_read( a_filename ) from file.start until file.end_of_file loop file.read_word if file.last_string.substring (1,2).is_equal ( "//") then file.read_line elseif file.last_string.is_equal ( "Frame" ) then if frame/=void then actor.add_child ( frame ) end frame := parse_frame( file ) end file.read_line end if actor.children.count>0 then actor.add_child( frame ) elseif frame/=void then actor := frame else -- frame=void -- We didn't find any frame, so we just add all the meshes from file.start until file.end_of_file loop file.read_word if file.last_string.substring (1,2).is_equal ( "//") then -- Nothing elseif file.last_string.is_equal ( "Mesh" ) then pos := file.position name := pos.out file.read_word -- Read the Mesh name from until file.last_string.is_equal( "{" ) loop name := file.last_string.twin file.read_word end file.go ( pos ) skip_block( file ) actor.attach_object( scene_manager.mesh_factory.new_mesh( a_filename+"#"+name ) ) end file.read_line end end from file.start until file.end_of_file loop file.read_word if file.last_string.substring (1,2).is_equal ( "//") then file.read_line elseif file.last_string.is_equal ( "AnimationSet" ) then name := file.position.out file.read_word -- Read the Mesh name from until file.last_string.is_equal( "{" ) loop name := file.last_string.twin file.read_word end actor.add_animation( parse_animation_set( file ), name ) end file.read_line end add_model( actor, a_filename ) end feature {NONE} -- Loading frames: DS_HASH_TABLE[ EM3D_ACTOR, STRING ] parse_frame( a_file: PLAIN_TEXT_FILE ): EM3D_ACTOR is -- Parse a frame local pos : INTEGER name: STRING do create result.make_by_parent ( void ) a_file.read_word -- Read the Frame name if not a_file.last_string.is_equal( "{" ) then frames.force ( result, a_file.last_string.twin ) a_file.read_word end from a_file.read_line; a_file.read_word until a_file.last_string.is_equal( "}" ) or a_file.end_of_file loop if a_file.last_string.substring (1,2).is_equal ( "//") then -- Nothign elseif a_file.last_string.is_equal ( "AnimationSet" ) then skip_block( a_file ) elseif a_file.last_string.is_equal ( "FrameTransformMatrix" ) then skip_to( a_file, '{' ) result.set_transformation( parse_matrix44( a_file ) ) skip_one( a_file, '}' ) elseif a_file.last_string.is_equal ( "Frame" ) then result.add_child( parse_frame( a_file ) ) elseif a_file.last_string.is_equal ( "Mesh" ) then pos := a_file.position name := pos.out a_file.read_word -- Read the Mesh name from until a_file.last_string.is_equal( "{" ) loop name := a_file.last_string.twin a_file.read_word end a_file.go ( pos ) skip_block( a_file ) result.attach_object( scene_manager.mesh_factory.new_mesh( a_file.name+"#"+name ) ) end a_file.read_line a_file.read_word end end parse_animation_set( a_file: PLAIN_TEXT_FILE ): EM3D_ANIMATION_SET is -- Parse a directx animation set local animation: EM3D_ANIMATION do create result.make from a_file.read_word until a_file.last_string.is_equal ( "}" ) loop if a_file.last_string.is_equal ( "//" ) then a_file.read_line elseif a_file.last_string.is_equal ( "Animation" ) then skip_to( a_file, '{' ) animation := parse_animation( a_file ) if animation/=void then result.add ( animation ) end end a_file.read_word end end parse_animation( a_file: PLAIN_TEXT_FILE ): EM3D_ANIMATION is -- Parse a directx animation do skip_to( a_file, '{' ) a_file.read_word skip_to( a_file, '}' ) if frames.has ( a_file.last_string ) then create result.make( frames.item ( a_file.last_string ) ) from a_file.read_word until a_file.last_string.is_equal ( "}" ) loop if a_file.last_string.is_equal ( "//" ) then a_file.read_line elseif a_file.last_string.is_equal ( "AnimationKey" ) then skip_to( a_file, '{' ) parse_animation_key( a_file, result ) end end end from a_file.read_word until a_file.last_string.is_equal ( "}" ) loop a_file.read_word end end parse_animation_key( a_file: PLAIN_TEXT_FILE; an_animation: EM3D_ANIMATION ) is -- Parse a directx animation key (a set of keys) local type: INTEGER count: INTEGER time: DOUBLE i: INTEGER do type := parse_integer ( a_file ) count := parse_integer ( a_file ) if type=4 then from i:=1 until i>count loop time := parse_double( a_file ) if parse_integer(a_file)=16 then -- Juhuu, we can read it in :) an_animation.add_key ( parse_matrix44 ( a_file ), time ) else skip_to ( a_file , ';') end skip ( a_file , ';') skip ( a_file , ',') i := i + 1 end end from a_file.read_word until a_file.last_string.is_equal ( "}" ) loop a_file.read_word end end end