/// <summary> /// Convert from FBX /// </summary> /// <param name="_Scene"></param> public Scene( FBX.Scene.Scene _Scene ) { // Create materials FBX.Scene.Materials.MaterialParameters[] SourceMaterials = _Scene.MaterialParameters; foreach ( FBX.Scene.Materials.MaterialParameters SourceMaterial in SourceMaterials ) m_Materials.Add( new Material( SourceMaterial, MapMaterial ) ); // Create nodes if ( _Scene.RootNode != null ) m_RootNode = new Node( this, _Scene.RootNode ); }
/// <summary> /// Converts a FBX file into a temp scene representation (which may already contain meshes and materials, don't care) /// </summary> /// <param name="_FileName">The name of the FBX file to load</param> /// <param name="_Scene">The cirrus scene into which we should store the data</param> /// <param name="_ScaleFactor">The scale factor to apply to the entire scene /// By default, internal MAX units can be considered as centimeters so if you create a scene whose dimensions of a one meter box are 100x100x100, you /// will want to use a scale factor of 0.01. /// FBX offers the possibility of scaling but does a shitty job at it as it doesn't even rescale other dimensions like near/far clips or ranges for lights /// and camera, which plain sucks.</param> /// <param name="_Materials">An optional materials database containing informations about materials required by the scene</param> public void Load( FileInfo _FileName, FBX.Scene.Scene _Scene, float _ScaleFactor, MaterialsDatabase _Materials ) { if ( _FileName == null ) throw new Exception( "Invalid file name!" ); if ( !_FileName.Exists ) throw new Exception( "Scene file \"" + _FileName + "\" does not exist!" ); if ( _Scene == null ) throw new Exception( "Invalid Scene to load into!" ); m_Scene = _Scene; m_TempMesh2FinalMesh.Clear(); m_ScaleFactor = _ScaleFactor; m_MaterialsDatabase = _Materials; FBXImporter.Scene FBXScene = null; try { FBXScene = new FBXImporter.Scene(); FBXScene.Load( _FileName.FullName ); // Process materials ProcessMaterials( FBXScene.Materials ); // Process the scene nodes RecurseProcessNode( FBXScene.RootNode, null ); // Attach camera & light targets PostProcessNodes( m_Scene.RootNode ); // Build actual optimized and consolidated meshes BuildConsolidatedMeshes(); // Propagate state once so Local2World matrices are up to date m_Scene.RootNode.PropagateState(); } catch ( Exception _e ) { throw new Exception( "An error occurred while importing the FBX file \"" + _FileName + "\"!", _e ); } finally { FBXScene.Dispose(); } }
/// <summary> /// Loads a FBX file into a temp scene representation (which may already contain meshes and materials, don't care) /// </summary> /// <param name="_FileName">The name of the FBX file to load</param> /// <param name="_Scene">The cirrus scene into which we should store the data</param> public void Load( FileInfo _FileName, FBX.Scene.Scene _Scene ) { Load( _FileName, _Scene, 1.0f, null ); }
public Node( Scene _Owner, FBX.Scene.Nodes.Node _Node ) { m_Owner = _Owner; m_Owner.m_Nodes.Add( this ); if ( _Node is FBX.Scene.Nodes.Mesh ) m_Type = TYPE.MESH; else if ( _Node is FBX.Scene.Nodes.Camera ) m_Type = TYPE.CAMERA; else if ( _Node is FBX.Scene.Nodes.Light ) m_Type = TYPE.LIGHT; else { // Isolate locators as probes if ( _Node.Name.ToLower().IndexOf( "locator" ) != -1 ) m_Type = TYPE.PROBE; } m_Local2Parent.FromMatrix4( _Node.Local2Parent ); // Build children FBX.Scene.Nodes.Node[] Children = _Node.Children; m_Children = new Node[Children.Length]; for ( int ChildIndex=0; ChildIndex < Children.Length; ChildIndex++ ) { FBX.Scene.Nodes.Node SourceChild = Children[ChildIndex]; Node Child = null; switch ( SourceChild.NodeType ) { case FBX.Scene.Nodes.Node.NODE_TYPE.NODE: Child = new Node( _Owner, SourceChild ); break; case FBX.Scene.Nodes.Node.NODE_TYPE.LIGHT: Child = new Light( _Owner, SourceChild ); break; case FBX.Scene.Nodes.Node.NODE_TYPE.CAMERA: Child = new Camera( _Owner, SourceChild ); break; case FBX.Scene.Nodes.Node.NODE_TYPE.MESH: Child = new Mesh( _Owner, SourceChild ); break; } m_Children[ChildIndex] = Child; } }
public Primitive( Mesh _Owner, FBX.Scene.Nodes.Mesh.Primitive _Primitive ) { m_Owner = _Owner; m_MaterialID = (ushort) _Primitive.MaterialParms.ID; m_Faces = new Face[_Primitive.FacesCount]; m_Vertices = new Vertex[_Primitive.VerticesCount]; // Retrieve streams FBX.Scene.Nodes.Mesh.Primitive.VertexStream.USAGE[] Usages = { FBX.Scene.Nodes.Mesh.Primitive.VertexStream.USAGE.POSITION, FBX.Scene.Nodes.Mesh.Primitive.VertexStream.USAGE.NORMAL, FBX.Scene.Nodes.Mesh.Primitive.VertexStream.USAGE.TANGENT, FBX.Scene.Nodes.Mesh.Primitive.VertexStream.USAGE.BITANGENT, FBX.Scene.Nodes.Mesh.Primitive.VertexStream.USAGE.TEXCOORDS, }; FBX.Scene.Nodes.Mesh.Primitive.VertexStream[][] Streams = new FBX.Scene.Nodes.Mesh.Primitive.VertexStream[Usages.Length][]; for ( int UsageIndex=0; UsageIndex < Usages.Length; UsageIndex++ ) { Streams[UsageIndex] = _Primitive.FindStreamsByUsage( Usages[UsageIndex] ); if ( Streams[UsageIndex].Length == 0 ) throw new Exception( "No stream for usage " + Usages[UsageIndex] + "! Can't complete target vertex format!" ); } // Build local space bounding box float3 Temp = new float3(); WMath.Vector[] VertexPositions = Streams[0][0].Content as WMath.Vector[]; foreach ( WMath.Vector VertexPosition in VertexPositions ) { Temp.FromVector3( VertexPosition ); m_BBoxMin.Min( Temp ); m_BBoxMax.Max( Temp ); } // Build faces int FaceIndex = 0; foreach ( FBX.Scene.Nodes.Mesh.Primitive.Face F in _Primitive.Faces ) { m_Faces[FaceIndex].V0 = F.V0; m_Faces[FaceIndex].V1 = F.V1; m_Faces[FaceIndex].V2 = F.V2; FaceIndex++; } // Build vertices for ( int VertexIndex=0; VertexIndex < m_Vertices.Length; VertexIndex++ ) { for ( int UsageIndex=0; UsageIndex < Usages.Length; UsageIndex++ ) { FBX.Scene.Nodes.Mesh.Primitive.VertexStream.USAGE Usage = Usages[UsageIndex]; switch ( Usage ) { case FBX.Scene.Nodes.Mesh.Primitive.VertexStream.USAGE.POSITION: { float3[] Stream = Streams[UsageIndex][0].Content as float3[]; m_Vertices[VertexIndex].P = Stream[VertexIndex]; break; } case FBX.Scene.Nodes.Mesh.Primitive.VertexStream.USAGE.NORMAL: { float3[] Stream = Streams[UsageIndex][0].Content as float3[]; m_Vertices[VertexIndex].N = Stream[VertexIndex]; break; } case FBX.Scene.Nodes.Mesh.Primitive.VertexStream.USAGE.TANGENT: { float3[] Stream = Streams[UsageIndex][0].Content as float3[]; m_Vertices[VertexIndex].G = Stream[VertexIndex]; break; } case FBX.Scene.Nodes.Mesh.Primitive.VertexStream.USAGE.BITANGENT: { float3[] Stream = Streams[UsageIndex][0].Content as float3[]; m_Vertices[VertexIndex].B = Stream[VertexIndex]; break; } case FBX.Scene.Nodes.Mesh.Primitive.VertexStream.USAGE.TEXCOORDS: { float2[] Stream = Streams[UsageIndex][0].Content as float2[]; m_Vertices[VertexIndex].T = Stream[VertexIndex]; break; } } } } }
public Mesh( Scene _Owner, FBX.Scene.Nodes.Node _Node ) : base(_Owner, _Node) { FBX.Scene.Nodes.Mesh _Mesh = _Node as FBX.Scene.Nodes.Mesh; m_Primitives = new Primitive[_Mesh.PrimitivesCount]; int PrimitiveIndex = 0; foreach ( FBX.Scene.Nodes.Mesh.Primitive SourcePrimitive in _Mesh.Primitives ) m_Primitives[PrimitiveIndex++] = new Primitive( this, SourcePrimitive ); }
public Material( FBX.Scene.Materials.MaterialParameters _SourceMaterial, MaterialMapperDelegate _Mapper ) { float3 Temp = new float3(); FBX.Scene.Materials.MaterialParameters.Parameter P = null; m_ID = (ushort) _SourceMaterial.ID; // Get diffuse color + texture ID P = _SourceMaterial.Find( "DiffuseColor" ); if ( P != null ) { Temp.FromVector3( P.AsFloat3.Value ); m_DiffuseColor = Temp; } P = _SourceMaterial.Find( "DiffuseTexture" ); m_DiffuseTextureID = _Mapper( P != null ? P.AsTexture2D : null ); // Get specular color + texture ID + exponent P = _SourceMaterial.Find( "SpecularColor" ); if ( P != null ) { Temp.FromVector3( P.AsFloat3.Value ); m_SpecularColor = Temp; } P = _SourceMaterial.Find( "SpecularTexture" ); m_SpecularTextureID = _Mapper( P != null ? P.AsTexture2D : null ); P = _SourceMaterial.Find( "SpecularExponent" ); if ( P != null ) { Temp.FromVector3( P.AsFloat3.Value ); m_SpecularExponent = Temp; } // Get noral map ID P = _SourceMaterial.Find( "NormalTexture" ); m_NormalTextureID = _Mapper( P != null ? P.AsTexture2D : null ); // Get emissive P = _SourceMaterial.Find( "EmissiveColor" ); if ( P != null ) { Temp.FromVector3( P.AsFloat3.Value ); m_EmissiveColor = Temp; } }
public Light( Scene _Owner, FBX.Scene.Nodes.Node _Node ) : base(_Owner, _Node) { FBX.Scene.Nodes.Light _Light = _Node as FBX.Scene.Nodes.Light; m_LightType = (LIGHT_TYPE) _Light.Type; m_Color.FromVector3( _Light.Color ); m_Intensity = _Light.Intensity; m_HotSpot = _Light.HotSpot; m_ConeAngle = _Light.ConeAngle; }
public Camera( Scene _Owner, FBX.Scene.Nodes.Node _Node ) : base(_Owner, _Node) { FBX.Scene.Nodes.Camera _Camera = _Node as FBX.Scene.Nodes.Camera; m_FOV = _Camera.FOV; }
private ushort MapMaterial( FBX.Scene.Materials.MaterialParameters.ParameterTexture2D _Texture ) { if ( _Texture == null ) return (ushort) 0xFFFF; // if ( _Texture.Value.URL.IndexOf( "pata_diff_colo.tga" ) != -1 ) // return 0; return (ushort) _Texture.Value.ID; }