/// <summary> /// Inserts the provided consolidated vertex into the list of vertices /// If there already exists a matching vertex in the list of consolidated vertices, then this vertex is returned instead /// </summary> /// <param name="_ConsolidatedVertices">The list where to insert the vertex in case it does not already exist</param> /// <param name="_Dictionary">The dictionary yielding the list of consolidated vertices associated to each original position vertex (as the only forever common data of all vertices --consolidated or not-- is their position)</param> /// <param name="_OriginalVertexIndex">The index of the original position vertex</param> /// <param name="_Vertex">The consolidated vertex to insert</param> /// <returns>The inserted consolidated vertex</returns> protected ConsolidatedVertex InsertConsolidatedVertex( List<ConsolidatedVertex> _ConsolidatedVertices, Dictionary<int,List<ConsolidatedVertex>> _Dictionary, int _OriginalVertexIndex, ConsolidatedVertex _Vertex ) { // Check there already is a list of vertices if ( !_Dictionary.ContainsKey( _OriginalVertexIndex ) ) _Dictionary[_OriginalVertexIndex] = new List<ConsolidatedVertex>(); List<ConsolidatedVertex> ExistingVertices = _Dictionary[_OriginalVertexIndex]; if ( !m_OwnerMesh.m_Owner.ConsolidateMeshes ) { // Only check if there already is a vertex at this index if ( ExistingVertices.Count > 0 ) return ExistingVertices[0]; // Return the only vertex there will ever be at this index } else { // Check all existing vertices for a match foreach ( ConsolidatedVertex ExistingVertex in ExistingVertices ) if ( ExistingVertex.Compare( _Vertex ) ) return ExistingVertex; // There is a match! Use this vertex instead } // There was no match, so we insert the provided vertex _Vertex.m_Index = _ConsolidatedVertices.Count; _ConsolidatedVertices.Add( _Vertex ); ExistingVertices.Add( _Vertex ); return _Vertex; }
/// <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; }
/// <summary> /// Compares with another vertex /// </summary> /// <param name="_o"></param> /// <returns></returns> public bool Compare( ConsolidatedVertex _V ) { // Compare smoothing groups if ( ms_CompareSmoothingGroups && (_V.m_SmoothingGroups & m_SmoothingGroups) == 0 ) return false; if ( m_Infos.Count != _V.m_Infos.Count ) throw new Exception( "2 vertices from the same mesh have a different count of infos!" ); for ( int InfoIndex=0; InfoIndex < m_Infos.Count; InfoIndex++ ) { VertexInfo V0 = m_Infos[InfoIndex]; VertexInfo V1 = _V.m_Infos[InfoIndex]; if ( V0.m_Type != V1.m_Type ) throw new Exception( "2 vertices from the same mesh have infos at the same index but with different types!" ); if ( !V0.Compare( V1 ) ) return false; } return true; }