Inheritance: LoaderTempSceneObject
Esempio n. 1
0
 /// <summary>
 /// Adds a mesh to this transform
 /// </summary>
 /// <param name="_Mesh">The mesh to add</param>
 /// <remarks>This will transform into referenced shapes in the JSON file</remarks>
 public void AddMesh( LoaderTempMesh _Mesh )
 {
     m_Meshes.Add( _Mesh );
 }
Esempio n. 2
0
        /// <summary>
        /// Creates a Cirrus mesh node
        /// </summary>
        /// <param name="_Scene"></param>
        /// <param name="_FBXMesh"></param>
        /// <returns></returns>
        protected Scene.Nodes.Mesh CreateMesh( FBXImporter.NodeMesh _FBXMesh, Scene.Nodes.Node _Parent )
        {
            // Create a temporary mesh that will be optimized later, when all meshes have been loaded
            LoaderTempMesh	TempMesh = new LoaderTempMesh( this, _FBXMesh.Name );

            if ( m_bGenerateBoundingBoxes )
                TempMesh.BoundingBox = new WMath.BoundingBox( m_ScaleFactor * _FBXMesh.BoundingBox.m_Min, m_ScaleFactor * _FBXMesh.BoundingBox.m_Max );

            // Handle pivot & reset X-Form
            if ( m_bResetXForm )
                TempMesh.Pivot = _FBXMesh.Pivot;	// Storing the mesh's pivot will have the effect of composing vertices with that matrix, actually performing the "reset X-Form" operation
            // 			else
            // 				Transform.Pivot = _FBXNode.Pivot;	// Storing the mesh's pivot here will simply compose the mesh's transform with its pivot

            // Setup compulsory vertices and triangles
            Point[]	SourceVertices = _FBXMesh.Vertices;
            Point[]	ScaledVertices = new Point[SourceVertices.Length];
            for ( int VertexIndex=0; VertexIndex < _FBXMesh.VerticesCount; VertexIndex++ )
                ScaledVertices[VertexIndex] = m_ScaleFactor * SourceVertices[VertexIndex];

            TempMesh.SetVertices( ScaledVertices );
            TempMesh.SetFaces( _FBXMesh.Triangles );

            // Setup all the possible recognized layers
            foreach ( FBXImporter.Layer Layer in _FBXMesh.Layers )
                foreach ( FBXImporter.LayerElement LE in Layer.Elements )
                {
                    switch ( LE.ElementType )
                    {
                        case FBXImporter.LayerElement.ELEMENT_TYPE.MATERIAL:
                        case FBXImporter.LayerElement.ELEMENT_TYPE.UV:
                        case FBXImporter.LayerElement.ELEMENT_TYPE.NORMAL:
                        case FBXImporter.LayerElement.ELEMENT_TYPE.TANGENT:
                        case FBXImporter.LayerElement.ELEMENT_TYPE.BINORMAL:
                        case FBXImporter.LayerElement.ELEMENT_TYPE.VERTEX_COLOR:
                        case FBXImporter.LayerElement.ELEMENT_TYPE.SMOOTHING:
                            TempMesh.AddLayerElement( LE );
                            break;

                        default:
                            break;	// Other types are not supported (or irrelevant)...
                    }
                }

            // Build un-optimized primitives
            TempMesh.BuildPrimitives();

            // Create the final scene mesh and tie it to our temporary mesh
            FBX.Scene.Nodes.Mesh	Mesh = m_Scene.CreateMesh( _FBXMesh.Name, _Parent, _FBXMesh.LocalTransform );
            m_TempMesh2FinalMesh[TempMesh] = Mesh;

            // Add some properties
            Mesh.Visible = _FBXMesh.Visible;

            // 			FBXImporter.ObjectProperty	PropertyCastShadow = _FBXMesh.FindUserProperty( "CastShadow" );
            // 			Mesh.CastShadow = PropertyCastShadow != null ? (bool) PropertyCastShadow.Value : true;
            Mesh.CastShadow = true;
            Mesh.ReceiveShadow = true;

            return Mesh;
        }
Esempio n. 3
0
        /// <summary>
        /// Replaces a layer element from this mesh by a reference to another element from another mesh
        /// </summary>
        /// <param name="_LayerElementSource">The source layer element to replace</param>
        /// <param name="_OwnerMesh">The mesh that owns the referenced layer element</param>
        /// <param name="_LayerElementReference">The layer element to reference in place of our own layer element</param>
        public void ReplaceLayerElementByAReference( FBXImporter.LayerElement _LayerElementSource, LoaderTempMesh _OwnerMesh, FBXImporter.LayerElement _LayerElementReference )
        {
            m_LayerElements.Remove( _LayerElementSource );

            ReferenceLayerElement	RLE = new ReferenceLayerElement();
                                    RLE.m_Owner = _OwnerMesh;
                                    RLE.m_LayerElement = _LayerElementReference;

            m_LayerElementsReference.Add( RLE );
        }
Esempio n. 4
0
        /// <summary>
        /// Attempts to merge this mesh with the provided master mesh
        /// If the provided mesh can be used as a master for this mesh then the identical layer elements are "shared by reference"
        ///  and the layer elements that differ are kept in this mesh and added as external elements to the master mesh.
        /// 
        /// In the end, only the master meshes will be optimized, and this mesh's data along with them so all is left is to retrieve
        ///  the optimized referenced data from the master mesh and make them our own.
        /// </summary>
        /// <returns>True if the merge was successful</returns>
        public bool MergeWithMasterMesh( LoaderTempMesh _Master )
        {
            if ( !_Master.IsMaster )
                return	false;	// Not a master mesh...

            // 1] Compare vertex, faces & primitives counts (easy comparisons first)
            if ( m_Vertices.Length != _Master.m_Vertices.Length )
                return	false;	// Not identical !
            if ( m_Faces.Length != _Master.m_Faces.Length )
                return	false;	// Not identical !
            if ( m_Primitives.Count != _Master.m_Primitives.Count )
                return	false;	// Not identical !

            // 2] Compare each primitive's vertex & faces count
            for ( int PrimitiveIndex=0; PrimitiveIndex < m_Primitives.Count; PrimitiveIndex++ )
            {
                Primitive	P0 = m_Primitives[PrimitiveIndex];
                Primitive	P1 = _Master.m_Primitives[PrimitiveIndex];

                if ( P0.FacesCount != P1.FacesCount )
                    return	false;	// Not identical !
            }

            // 3] Compare the vertices one by one
            for ( int VertexIndex=0; VertexIndex < m_Vertices.Length; VertexIndex++ )
            {
                Point	V0 = m_Vertices[VertexIndex];
                Point	V1 = _Master.m_Vertices[VertexIndex];
                if ( V0 != V1 )
                    return	false;
            }

            // 4] Compare the faces one by one
            for ( int FaceIndex=0; FaceIndex < m_Faces.Length; FaceIndex++ )
            {
                FBXImporter.NodeMesh.Triangle	F0 = m_Faces[FaceIndex];
                FBXImporter.NodeMesh.Triangle	F1 = _Master.m_Faces[FaceIndex];
                if ( F0.Vertex0 != F1.Vertex0 || F0.Vertex1 != F1.Vertex1 || F0.Vertex2 != F1.Vertex2 )
                    return	false;
            }

            //////////////////////////////////////////////////////////////////////////
            // At this point, the 2 meshes are deemed identical (up to the point of Vertices and Faces at least)
            //////////////////////////////////////////////////////////////////////////

            // Make this mesh a slave
            m_MasterMesh = _Master;

            // 5] Compare each of our Layer Elements to the master's and merge them
            //	_ Layer Elements that are identical to the master will be replaced by references to the master's
            //	_ Layer Elements that are different will be kept and will be added as external elements to the master
            //
            FBXImporter.LayerElement[]	LayerElements = m_LayerElements.ToArray();
            foreach ( FBXImporter.LayerElement LE0 in LayerElements )
            {
                FBXImporter.LayerElement	LE1 = null;
                foreach ( FBXImporter.LayerElement MasterLE in _Master.m_LayerElements )
                    if ( LE0.Compare( MasterLE ) )
                    {	// Found a match !
                        LE1 = MasterLE;
                        break;
                    }

                if ( LE1 != null )
                {	// We found a matching layer element in the master mesh!
                    // Now, we simply replace our own element by a reference to the master's element
                    ReplaceLayerElementByAReference( LE0, _Master, LE1 );
                }
                else
                {	// We couldn't find a matching layer element!
                    // That means this layer element is unique to our instance so we add it as an external element in the master mesh
                    // When the master mesh will be consolidated, it will take our elements into account as well...
                    _Master.AddExternalLayerElement( this, LE0 );
                }
            }

            return	true;
        }
Esempio n. 5
0
        /// <summary>
        /// Adds a layer element from another (slave) mesh
        /// </summary>
        /// <param name="_OwnerMesh">The mesh owning the layer element to add</param>
        /// <param name="_LayerElement">The external layer element</param>
        public void AddExternalLayerElement( LoaderTempMesh _OwnerMesh, FBXImporter.LayerElement _LayerElement )
        {
            ExternalLayerElement	ELE = new ExternalLayerElement();
                                    ELE.m_Owner = _OwnerMesh;
                                    ELE.m_LayerElement = _LayerElement;

            m_LayerElementsExternal.Add( ELE );

            // Add this mesh to our list of slave meshes
            if ( m_SlaveMesh2Registered.ContainsKey( _OwnerMesh ) )
                return;	// Already registered!

            m_SlaveMeshes.Add( _OwnerMesh );
            m_SlaveMesh2Registered[_OwnerMesh] = true;
        }
Esempio n. 6
0
 public Primitive( LoaderTempMesh _OwnerMesh, SceneLoader _Owner, string _Name, FBXImporter.Material _Material )
     : base(_Owner, _Name)
 {
     m_OwnerMesh = _OwnerMesh;
     m_Material = _Material;
     // 				if ( m_Material == null )
     // 					throw new Exception( "Invalid material for primitive \"" + _Name + "\"!" );
 }
Esempio n. 7
0
        public Scene.Nodes.Mesh.Primitive CreatePrimitive( LoaderTempMesh.Primitive _SourcePrimitive, Scene.Nodes.Mesh _ParentMesh, string _Name, Scene.Materials.MaterialParameters _MatParams )
        {
            m_SourcePrimitive = _SourcePrimitive;

            Scene.Nodes.Mesh.Primitive	Target = _ParentMesh.AddPrimitive( _Name, _MatParams, _SourcePrimitive.VerticesCount, _SourcePrimitive.FacesCount );

            // Build the primitive's triangles
            for ( int FaceIndex=0; FaceIndex < _SourcePrimitive.FacesCount; FaceIndex++ )
            {
                Target.Faces[FaceIndex].V0 = _SourcePrimitive.Faces[FaceIndex].V0.m_Index;
                Target.Faces[FaceIndex].V1 = _SourcePrimitive.Faces[FaceIndex].V1.m_Index;
                Target.Faces[FaceIndex].V2 = _SourcePrimitive.Faces[FaceIndex].V2.m_Index;
            }

            // Build the primitive's vertex streams
            int[]	StreamIndices = new int[8];
            foreach ( LoaderTempMesh.Primitive.VertexStream Stream in m_SourcePrimitive.VertexStreams )
            {
                Scene.Nodes.Mesh.Primitive.VertexStream.USAGE		Usage = Scene.Nodes.Mesh.Primitive.VertexStream.USAGE.UNKNOWN;
                Scene.Nodes.Mesh.Primitive.VertexStream.FIELD_TYPE	FieldType = Scene.Nodes.Mesh.Primitive.VertexStream.FIELD_TYPE.UNKNOWN;
                object												Content = null;

                switch ( Stream.StreamType )
                {
                    case LoaderTempMesh.VERTEX_INFO_TYPE.POSITION:
                        {
                            Usage = Scene.Nodes.Mesh.Primitive.VertexStream.USAGE.POSITION;
                            FieldType = Scene.Nodes.Mesh.Primitive.VertexStream.FIELD_TYPE.FLOAT3;
                            Vector[]	T = new Vector[_SourcePrimitive.VerticesCount];
                            Content = T;
                            for ( int i=0; i < _SourcePrimitive.VerticesCount; i++ )
                            {
                                T[i] = (Vector) (Stream.Stream[i] as WMath.Point);
                            }
                        }
             						break;
                    case LoaderTempMesh.VERTEX_INFO_TYPE.NORMAL:
                        {
                            Usage = Scene.Nodes.Mesh.Primitive.VertexStream.USAGE.NORMAL;
                            FieldType = Scene.Nodes.Mesh.Primitive.VertexStream.FIELD_TYPE.FLOAT3;
                            Vector[]	T = new Vector[_SourcePrimitive.VerticesCount];
                            Content = T;
                            for ( int i=0; i < _SourcePrimitive.VerticesCount; i++ )
                            {
                                T[i] = Stream.Stream[i] as WMath.Vector;
                            }
                        }
                        break;
                    case LoaderTempMesh.VERTEX_INFO_TYPE.TANGENT:
                        {
                            Usage = Scene.Nodes.Mesh.Primitive.VertexStream.USAGE.TANGENT;
                            FieldType = Scene.Nodes.Mesh.Primitive.VertexStream.FIELD_TYPE.FLOAT3;
                            Vector[]	T = new Vector[_SourcePrimitive.VerticesCount];
                            Content = T;
                            for ( int i=0; i < _SourcePrimitive.VerticesCount; i++ )
                            {
                                T[i] = Stream.Stream[i] as WMath.Vector;
                            }
                        }
                        break;
                    case LoaderTempMesh.VERTEX_INFO_TYPE.BINORMAL:
                        {
                            Usage = Scene.Nodes.Mesh.Primitive.VertexStream.USAGE.BITANGENT;
                            FieldType = Scene.Nodes.Mesh.Primitive.VertexStream.FIELD_TYPE.FLOAT3;
                            Vector[]	T = new Vector[_SourcePrimitive.VerticesCount];
                            Content = T;
                            for ( int i=0; i < _SourcePrimitive.VerticesCount; i++ )
                            {
                                T[i] = Stream.Stream[i] as WMath.Vector;
                            }
                        }
                        break;
                    case LoaderTempMesh.VERTEX_INFO_TYPE.TEXCOORD1D:
                        {
                            Usage = Scene.Nodes.Mesh.Primitive.VertexStream.USAGE.TEXCOORDS;
                            FieldType = Scene.Nodes.Mesh.Primitive.VertexStream.FIELD_TYPE.FLOAT;
                            float[]	T = new float[_SourcePrimitive.VerticesCount];
                            Content = T;
                            for ( int i=0; i < _SourcePrimitive.VerticesCount; i++ )
                            {
                                T[i] = (float) Stream.Stream[i];
                            }
                        }
                        break;
                    case LoaderTempMesh.VERTEX_INFO_TYPE.TEXCOORD2D:
                        {
                            Usage = Scene.Nodes.Mesh.Primitive.VertexStream.USAGE.TEXCOORDS;
                            FieldType = Scene.Nodes.Mesh.Primitive.VertexStream.FIELD_TYPE.FLOAT2;
                            Vector2D[]	T = new Vector2D[_SourcePrimitive.VerticesCount];
                            Content = T;
                            for ( int i=0; i < _SourcePrimitive.VerticesCount; i++ )
                            {
                                T[i] =  Stream.Stream[i] as WMath.Vector2D;
                                T[i].Y = 1.0f - T[i].Y;	// Here we must complement the V coordinate as MAX has the bad habit of inverting the Y axis of images!
                            }
                        }
                        break;
                    case LoaderTempMesh.VERTEX_INFO_TYPE.TEXCOORD3D:
                        {
                            Usage = Scene.Nodes.Mesh.Primitive.VertexStream.USAGE.TEXCOORDS;
                            FieldType = Scene.Nodes.Mesh.Primitive.VertexStream.FIELD_TYPE.FLOAT3;
                            Vector[]	T = new Vector[_SourcePrimitive.VerticesCount];
                            Content = T;
                            for ( int i=0; i < _SourcePrimitive.VerticesCount; i++ )
                            {
                                T[i] = Stream.Stream[i] as WMath.Vector;
                                T[i].Y = 1.0f - T[i].Y;	// Here we must complement the V coordinate as MAX has the bad habit of inverting the Y axis of images!
                            }
                        }
                        break;
                    case LoaderTempMesh.VERTEX_INFO_TYPE.COLOR_HDR:
                        {
                            Usage = Scene.Nodes.Mesh.Primitive.VertexStream.USAGE.COLOR_HDR;
                            FieldType = Scene.Nodes.Mesh.Primitive.VertexStream.FIELD_TYPE.FLOAT4;
                            Vector4D[]	T = new Vector4D[_SourcePrimitive.VerticesCount];
                            Content = T;
                            for ( int i=0; i < _SourcePrimitive.VerticesCount; i++ )
                            {
                                T[i] = Stream.Stream[i] as WMath.Vector4D;
                            }
                        }
             						break;
                }

                if (   Usage == Scene.Nodes.Mesh.Primitive.VertexStream.USAGE.UNKNOWN
                    || FieldType == Scene.Nodes.Mesh.Primitive.VertexStream.FIELD_TYPE.UNKNOWN )
                    continue;	// Unsupported... Should we throw?

                if ( Content == null )
                    throw new Exception( "Invalid content!" );

                int	StreamIndexIndex = (int) Usage - 1;	// Skip UNKNOWN usage and use the value as "stream type"
                int	StreamIndex = StreamIndices[StreamIndexIndex];
                StreamIndices[StreamIndexIndex]++;		// Increase stream index

                Target.AddVertexStream( Usage, FieldType, StreamIndex, Content );

                StreamIndex++;
            }

            return Target;
        }