Beispiel #1
0
        /// <summary>
        /// Builds a consolidated vertex
        /// </summary>
        /// <param name="_Face">The face referencing this vertex</param>
        /// <param name="_FaceVertexIndex">The index of the vertex in that face</param>
        /// <param name="_VertexIndex">The index of the vertex to build</param>
        /// <returns></returns>
        protected ConsolidatedVertex BuildConsolidatedVertex( ConsolidatedFace _Face, int _FaceVertexIndex, int _VertexIndex )
        {
            ConsolidatedVertex	Result = new ConsolidatedVertex();

            // Setup its smoothing group
            Result.m_SmoothingGroups = _Face.SmoothingGroups;

            // Setup informations
            for ( int LayerElementIndex=0; LayerElementIndex < m_CollapsedLayerElements.Length; LayerElementIndex++ )
            {
                FBXImporter.LayerElement	Element = m_CollapsedLayerElements[LayerElementIndex];
                LoaderTempMesh				OwnerMesh = m_CollapsedLayerElementMeshes[LayerElementIndex];

                if ( Element.MappingType != FBXImporter.LayerElement.MAPPING_TYPE.BY_EDGE )
                {
                    // Translate information
                    VERTEX_INFO_TYPE	InfoType = VERTEX_INFO_TYPE.UNKNOWN;
                    switch ( Element.ElementType )
                    {
                        case FBXImporter.LayerElement.ELEMENT_TYPE.POSITION:
                            InfoType = VERTEX_INFO_TYPE.POSITION;
                            break;
                        case FBXImporter.LayerElement.ELEMENT_TYPE.NORMAL:
                            InfoType = VERTEX_INFO_TYPE.NORMAL;
                            break;
                        case FBXImporter.LayerElement.ELEMENT_TYPE.BINORMAL:
                            InfoType = VERTEX_INFO_TYPE.BINORMAL;
                            break;
                        case FBXImporter.LayerElement.ELEMENT_TYPE.TANGENT:
                            InfoType = VERTEX_INFO_TYPE.TANGENT;
                            break;
                        case FBXImporter.LayerElement.ELEMENT_TYPE.UV:
                            InfoType = VERTEX_INFO_TYPE.TEXCOORD2D;
                            break;
                        case FBXImporter.LayerElement.ELEMENT_TYPE.VERTEX_COLOR:
                            InfoType = VERTEX_INFO_TYPE.COLOR_HDR;
                            break;
                    }

                    if ( InfoType == VERTEX_INFO_TYPE.UNKNOWN )
                        continue;	// Not supported...

                    // Fill the info
                    ConsolidatedVertex.VertexInfo	Info = new ConsolidatedVertex.VertexInfo();
                                                    Info.m_Owner = OwnerMesh;
                                                    Info.m_SourceLayerElement = Element;
                                                    Info.m_Type = InfoType;
                                                    Info.m_Index = Element.Index;

                    object[]	Data = Element.ToArray();
                    switch ( Element.MappingType )
                    {
                        case	FBXImporter.LayerElement.MAPPING_TYPE.BY_CONTROL_POINT:
                            Info.m_Value = Data[_VertexIndex];
                            break;

                        case	FBXImporter.LayerElement.MAPPING_TYPE.BY_TRIANGLE:
                            Info.m_Value = Data[_Face.Index];
                            break;

                        case	FBXImporter.LayerElement.MAPPING_TYPE.BY_TRIANGLE_VERTEX:
                            Info.m_Value = Data[3*_Face.Index + _FaceVertexIndex];
                            break;

                        case	FBXImporter.LayerElement.MAPPING_TYPE.ALL_SAME:
                            Info.m_Value = Data[0];
                            break;
                    }

                    Result.m_Infos.Add( Info );

                    // Special treatment for position, normal, tangent & binormal...
                    switch ( InfoType )
                    {
                        case	VERTEX_INFO_TYPE.POSITION:
                            Result.m_PositionInfo = Info;
                            break;
                        case	VERTEX_INFO_TYPE.NORMAL:
                            Result.m_NormalInfo = Info;
                            break;
                        case	VERTEX_INFO_TYPE.TANGENT:
                            Result.m_TangentInfo = Info;
                            break;
                        case	VERTEX_INFO_TYPE.BINORMAL:
                            Result.m_BinormalInfo = Info;
                            break;
                    }
                }
            }

            return	Result;
        }
Beispiel #2
0
            public float m_Weight = 0.0f; // The weight of this face (in our case, the angle of the face at the given vertex)

            #endregion Fields

            #region Constructors

            public SharedFace( ConsolidatedFace _Face, Point _V0, Point _V1, Point _V2 )
            {
                m_Face = _Face;

                // Retrieve the angle formed by the 2 vectors and use it as weight for this face's influence
                Vector	D0 = (_V1 - _V0).Normalize();
                Vector	D1 = (_V2 - _V0).Normalize();
                float	fDot = D0 | D1;
                m_Weight = (float) Math.Acos( fDot );
                if ( float.IsNaN( m_Weight ) )
                    m_Weight = 0.0f;	// Occurs when D0 & D1 are very very small or really close to each other (usually, degenerate faces so it's okay if we skip them anyway)
            }
Beispiel #3
0
        /// <summary>
        /// This builds the mesh primitives that we'll be able to use at runtime
        /// </summary>
        public void BuildPrimitives()
        {
            // 			if ( m_Owner.GenerateTriangleStrips )
            // 				throw new Exception( "Triangle Strips are not supported yet!" );

            // Setup the comparison flags used for consolidation
            ConsolidatedVertex.ms_CompareSmoothingGroups = m_Owner.ConsolidateSplitBySMG;
            ConsolidatedVertex.VertexInfo.ms_CompareUVs = m_Owner.ConsolidateSplitByUV;
            ConsolidatedVertex.VertexInfo.ms_CompareColors = m_Owner.ConsolidateSplitByColor;

            //////////////////////////////////////////////////////////////////////////
            // Reset X-Form
            if ( m_Pivot != null )
            {
                Point[]	NewVertices = new Point[m_Vertices.Length];
                for ( int VertexIndex=0; VertexIndex < m_Vertices.Length; VertexIndex++ )
                    NewVertices[VertexIndex] = m_Vertices[VertexIndex] * m_Pivot;

                m_Vertices = NewVertices;
            }

            //////////////////////////////////////////////////////////////////////////
            // Build the original list of consolidated faces
            List<ConsolidatedFace>	Faces = new List<ConsolidatedFace>();
            foreach ( FBXImporter.NodeMesh.Triangle T in m_Faces )
            {
                ConsolidatedFace	NewFace = new ConsolidatedFace();
                                    NewFace.Index = Faces.Count;
                                    NewFace.VertexIndex0 = T.Vertex0;
                                    NewFace.VertexIndex1 = T.Vertex1;
                                    NewFace.VertexIndex2 = T.Vertex2;

                Faces.Add( NewFace );
            }

            //////////////////////////////////////////////////////////////////////////
            // Attempt to retrieve smoothing groups & materials data
            foreach ( FBXImporter.LayerElement Element in m_LayerElements )
            {
                if ( Element.ElementType == FBXImporter.LayerElement.ELEMENT_TYPE.MATERIAL )
                {
                    if ( m_OverrideMaterial != null )
                        continue;	// Ignore specific material if we have an override...

                    // Retrieve the array of data
                    object[]	Data = Element.ToArray();
                    switch ( Element.MappingType )
                    {
                        case FBXImporter.LayerElement.MAPPING_TYPE.BY_TRIANGLE:
                            for ( int FaceIndex=0; FaceIndex < Faces.Count; FaceIndex++ )
                                Faces[FaceIndex].Material = (FBXImporter.Material) Data[FaceIndex];
                            break;

                        case FBXImporter.LayerElement.MAPPING_TYPE.ALL_SAME:
                            {
                                FBXImporter.Material	Mat = (FBXImporter.Material) Data[0];
                                foreach ( ConsolidatedFace F in Faces )
                                    F.Material = Mat;
                                break;
                            }

                        default:
                            throw new Exception( "Found a layer element of type \"MATERIAL\" with unsupported \"" + Element.MappingType + "\" mapping type!\r\n(Only BY_POLYGON & ALL_SAME mapping modes are supported!)" );
                    }
                }
                else if ( Element.ElementType == FBXImporter.LayerElement.ELEMENT_TYPE.SMOOTHING )
                {
                    // Retrieve the array of data
                    object[]	Data = Element.ToArray();
                    switch ( Element.MappingType )
                    {
                        case FBXImporter.LayerElement.MAPPING_TYPE.BY_TRIANGLE:
                            for ( int FaceIndex=0; FaceIndex < Faces.Count; FaceIndex++ )
                                Faces[FaceIndex].SmoothingGroups = (int) Data[FaceIndex];
                            break;

                        case FBXImporter.LayerElement.MAPPING_TYPE.ALL_SAME:
                            {
                                int	SMG = (int) Data[0];
                                foreach ( ConsolidatedFace F in Faces )
                                    F.SmoothingGroups = SMG;
                                break;
                            }

                        case FBXImporter.LayerElement.MAPPING_TYPE.BY_EDGE:
                            {
                                break;
                            }

                        default:
                            throw new Exception( "Found a layer element of type \"SMOOTHING\" with unsupported \"" + Element.MappingType + "\" mapping type!\r\n(Only BY_POLYGON & ALL_SAME mapping modes are supported!)" );
                    }
                }
            }

            //////////////////////////////////////////////////////////////////////////
            // Check if we have tangent space information
            TANGENT_SPACE_AVAILABILITY	TSAvailability = TANGENT_SPACE_AVAILABILITY.NOTHING;

            foreach ( FBXImporter.LayerElement Element in m_LayerElements )
                switch ( Element.ElementType )
                {
                    case FBXImporter.LayerElement.ELEMENT_TYPE.UV:
                        TSAvailability |= TANGENT_SPACE_AVAILABILITY.UVs;
                        break;

                    case FBXImporter.LayerElement.ELEMENT_TYPE.NORMAL:
                        TSAvailability |= TANGENT_SPACE_AVAILABILITY.NORMAL;
                        break;

                    case FBXImporter.LayerElement.ELEMENT_TYPE.TANGENT:
                        TSAvailability |= TANGENT_SPACE_AVAILABILITY.TANGENT;
                        break;

                    case FBXImporter.LayerElement.ELEMENT_TYPE.BINORMAL:
                        TSAvailability |= TANGENT_SPACE_AVAILABILITY.BINORMAL;
                        break;
                }

            if ( TSAvailability == TANGENT_SPACE_AVAILABILITY.NOTHING )
            {	// Can't generate !
                switch ( m_Owner.NoTangentSpaceAction )
                {
                    case SceneLoader.NO_TANGENT_SPACE_ACTION.THROW:
                        throw new Exception( "Can't generate Tangent Space because there is no texture coordinates!" );

                    case SceneLoader.NO_TANGENT_SPACE_ACTION.SKIP:
                        return;
                }
            }

            //////////////////////////////////////////////////////////////////////////
            // Build dummy layer elements for position, normal, tangent & binormal streams of data
            //
            m_LayerElementPosition = new FBXImporter.LayerElement( "Position", FBXImporter.LayerElement.ELEMENT_TYPE.POSITION, FBXImporter.LayerElement.MAPPING_TYPE.BY_CONTROL_POINT, 0 );
            m_LayerElementPosition.SetArrayOfData( m_Vertices );
            m_LayerElements.Insert( 0, m_LayerElementPosition );	// Make it first layer!

            m_LayerElementNormal = null;
            m_LayerElementTangent = null;
            m_LayerElementBiNormal = null;
            foreach ( FBXImporter.LayerElement LE in m_LayerElements )
            {
                if ( m_LayerElementNormal == null && LE.ElementType == FBXImporter.LayerElement.ELEMENT_TYPE.NORMAL )
                {	// Re-use the normals element
                    m_LayerElementNormal = LE;
                    m_LayerElementNormal.MappingType = LE.MappingType;// FBXImporter.LayerElement.MAPPING_TYPE.BY_TRIANGLE_VERTEX;
                    m_LayerElementNormal.ReferenceType = LE.ReferenceType;// FBXImporter.LayerElement.REFERENCE_TYPE.DIRECT;
                }
                else if ( m_LayerElementTangent == null && LE.ElementType == FBXImporter.LayerElement.ELEMENT_TYPE.TANGENT )
                {	// Re-use the tangents element
                    m_LayerElementTangent = LE;
                    m_LayerElementTangent.MappingType = LE.MappingType;// FBXImporter.LayerElement.MAPPING_TYPE.BY_TRIANGLE_VERTEX;
                    m_LayerElementTangent.ReferenceType = LE.ReferenceType;//FBXImporter.LayerElement.REFERENCE_TYPE.DIRECT;
                }
                else if ( m_LayerElementBiNormal == null && LE.ElementType == FBXImporter.LayerElement.ELEMENT_TYPE.BINORMAL )
                {	// Re-use the binormals element
                    m_LayerElementBiNormal = LE;
                    m_LayerElementBiNormal.MappingType = LE.MappingType;// FBXImporter.LayerElement.MAPPING_TYPE.BY_TRIANGLE_VERTEX;
                    m_LayerElementBiNormal.ReferenceType = LE.ReferenceType;//FBXImporter.LayerElement.REFERENCE_TYPE.DIRECT;
                }
            }

            if ( m_LayerElementNormal == null )
            {	// Create a new normals element that we'll need to generate
                m_LayerElementNormal = new FBXImporter.LayerElement( "Normal", FBXImporter.LayerElement.ELEMENT_TYPE.NORMAL, FBXImporter.LayerElement.MAPPING_TYPE.BY_TRIANGLE_VERTEX, 0 );
                m_LayerElements.Add( m_LayerElementNormal );
            }
            if ( m_Owner.GenerateTangentSpace && m_LayerElementTangent == null )
            {	// Create a new tangents element that we'll need to generate
                m_LayerElementTangent = new FBXImporter.LayerElement( "Tangent", FBXImporter.LayerElement.ELEMENT_TYPE.TANGENT, FBXImporter.LayerElement.MAPPING_TYPE.BY_TRIANGLE_VERTEX, 0 );
                m_LayerElements.Add( m_LayerElementTangent );
            }
            if ( m_Owner.GenerateTangentSpace && m_LayerElementBiNormal == null )
            {	// Create a new binormals element that we'll need to generate
                m_LayerElementBiNormal = new FBXImporter.LayerElement( "BiNormal", FBXImporter.LayerElement.ELEMENT_TYPE.BINORMAL, FBXImporter.LayerElement.MAPPING_TYPE.BY_TRIANGLE_VERTEX, 0 );
                m_LayerElements.Add( m_LayerElementBiNormal );
            }

            //////////////////////////////////////////////////////////////////////////
            // Generate missing data
            BuildTangentSpace( Faces, TSAvailability, m_Owner.GenerateTangentSpace );

            //////////////////////////////////////////////////////////////////////////
            // Build primitives based on referenced materials
            m_Primitives.Clear();

            Dictionary<FBXImporter.Material,Primitive>	Material2Primitive = new Dictionary<FBXImporter.Material,Primitive>();
            Primitive	DefaultPrimitive = null;

            for ( int FaceIndex=0; FaceIndex < Faces.Count; FaceIndex++ )
            {
                ConsolidatedFace	F = Faces[FaceIndex];
                Primitive			P = null;
                if ( F.Material == null )
                {	// Default material
                    if ( DefaultPrimitive == null )
                    {	// Create the default primitive
                        DefaultPrimitive = new Primitive( this, m_Owner, this.m_Name + "_Primitive" + m_Primitives.Count, null );
                        DefaultPrimitive.OverrideMaterial = m_OverrideMaterial;	// Setup the optional override material
                        m_Primitives.Add( DefaultPrimitive );
                    }

                    P = DefaultPrimitive;
                }
                else if ( !Material2Primitive.ContainsKey( F.Material ) )
                {	// New primitive!
                    P = new Primitive( this, m_Owner, this.m_Name + "_Primitive" + m_Primitives.Count, F.Material );
                    m_Primitives.Add( P );
                    Material2Primitive[F.Material] = P;
                }
                else
                    P = Material2Primitive[F.Material];

                P.AddFace( F );
            }
        }
Beispiel #4
0
 public void AddFace( ConsolidatedFace _Face )
 {
     m_Faces.Add( _Face );
 }