/// <summary> /// Sets the model that this object was instanced from /// </summary> public ModelInstance( Model source ) { m_Source = source; // Set up the animation layers if ( source.Animations == null ) { return; } m_Layers = new AnimationLayer[ ( int )ModelPart.NumParts ]; for ( int layerIndex = 0; layerIndex < ( int )ModelPart.NumParts; ++layerIndex ) { m_ReferencePoints[ layerIndex ] = new ReferencePoint( ( ModelPart )layerIndex ); ModelMesh partMesh = source.GetPartMesh( ( ModelPart )layerIndex ); if ( partMesh == null ) { continue; } if ( source.Animations != null ) { // TODO: This assigns the entire animation set to each layer, which isn't correct (although it'll work OK) m_Layers[ layerIndex ] = new AnimationLayer( source.Animations, ( ModelPart )layerIndex ); } } }
/// <summary> /// Loads... stuff /// </summary> public override object Load( ISource source, LoadParameters parameters ) { parameters.CanCache = true; Vector3 scale = new Vector3 ( DynamicProperties.GetProperty( parameters.Properties, "scaleX", 1.0f ), DynamicProperties.GetProperty( parameters.Properties, "scaleY", 1.0f ), DynamicProperties.GetProperty( parameters.Properties, "scaleZ", 1.0f ) ); Matrix44 transform = new Matrix44( ); transform.Scale( scale.X, scale.Y, scale.Z ); // create the model Model model = new Model( ); // oh dear another md3 hack - directories mean articulated models, with skins and animations. Files // mean single objects if ( source is IFolder ) { // Load animations model.Animations = LoadAnimations( AnimationFile( source ) ); LoadNestedModel( model, source, transform ); } else { LoadObjectModel( model, source, transform ); } return model; }
/// <summary> /// Nests one model part's mesh inside another, using a named tag as a transform /// </summary> private static void NestMesh( Model model, ModelPart parent, ModelPart child, string tagName ) { model.GetPartMesh( parent ).AddNestedPart( child, model.GetPartMesh( parent ).GetTagIndex( tagName ) ); }
private static void LoadObjectModel( Model model, ISource source, Matrix44 transform ) { // Load the skin file for the current part IDictionary< string, ITexture2d > textureTable = LoadSkin( source, DefaultSkinFile( source, ModelPart.Weapon ) ); // Load the MD3 associated with the current part ModelMesh partMesh = LoadMd3( source, model, ModelPart.Weapon, transform, source, textureTable ); model.SetPartMesh( ModelPart.Weapon, partMesh ); model.SetRootMesh( partMesh ); }
private static void LoadNestedModel( Model model, ISource source, Matrix44 transform ) { // Run through all the parts for ( int partIndex = 0; partIndex < ( int )ModelPart.NumParts; ++partIndex ) { ModelPart curPart = ( ModelPart )partIndex; if ( curPart == ModelPart.Weapon ) { // The weapon does not have a related mesh, so just ignore... continue; } // Load the skin file for the current part IDictionary< string, ITexture2d > surfaceTextureTable = LoadSkin( source, DefaultSkinFile( source, curPart ) ); // Load the MD3 associated with the current part ModelMesh partMesh = LoadMd3( source, model, curPart, transform, MeshFile( source, curPart ), surfaceTextureTable ); model.SetPartMesh( curPart, partMesh ); } model.SetRootMesh( model.GetPartMesh( ModelPart.Lower ) ); NestMesh( model, ModelPart.Lower, ModelPart.Upper, "tag_torso" ); NestMesh( model, ModelPart.Upper, ModelPart.Head, "tag_head" ); NestMesh( model, ModelPart.Upper, ModelPart.Weapon, "tag_weapon" ); }
/// <summary> /// Loads an MD3 mesh resource from a stream /// </summary> private static ModelMesh LoadMd3( ISource source, Model model, ModelPart part, Matrix44 transform, ISource md3Source, IDictionary<string, ITexture2d> surfaceTextureTable ) { using ( Stream inputStream = OpenStream( md3Source ) ) { BinaryReader reader = new BinaryReader( inputStream ); // http://icculus.org/homepages/phaethon/q3a/formats/md3format.html // Make sure of the MD3 identity byte[] ident = reader.ReadBytes( 4 ); if ( ( ident[ 0 ] != 'I' ) || ( ident[ 1 ] != 'D' ) || ( ident[ 2 ] != 'P' ) || ( ident[ 3 ] != '3' ) ) { throw new ApplicationException( "Failed to load MD3 resource - stream did not start with 'IDP3' MD3 identifier" ); } // Read in header //int version = reader.ReadInt32( ); //string name = ReadString( reader, MaxPathLength ); //int flags = reader.ReadInt32( ); int numFrames = reader.ReadInt32( ); int numTags = reader.ReadInt32( ); int numSurfaces = reader.ReadInt32( ); //int numSkins = reader.ReadInt32( ); int framesOffset = reader.ReadInt32( ); int tagsOffset = reader.ReadInt32( ); int surfacesOffset = reader.ReadInt32( ); //int eofOffset = reader.ReadInt32( ); // TODO: Can load directly into mesh frame, tag and surface structures - don't do this intermediate step ModelMesh mesh = new ModelMesh( model, part ); ReadFrames( reader, framesOffset, numFrames, mesh, transform ); ReadTags( reader, tagsOffset, numTags, numFrames, mesh, transform ); ReadSurfaces( source, reader, surfacesOffset, numSurfaces, numFrames, mesh, surfaceTextureTable, transform ); // TODO: REMOVE. test frames string md3Name = md3Source.ToString( ); if ( md3Name.IndexOf( "Upper" ) != -1 ) { mesh.DefaultFrame = 151; } else if ( md3Name.IndexOf( "Head" ) != -1 ) { mesh.DefaultFrame = 0; } else { mesh.DefaultFrame = 0; } return mesh; } }
/// <summary> /// Constructor /// </summary> public ModelMesh( Model model, ModelPart part ) { m_Model = model; m_Part = part; }