コード例 #1
0
ファイル: SceneLoader.cs プロジェクト: vr3d/GodComplex
        /// <summary>
        /// Optimizes the existing meshes and build the primitives necessary for runtime display
        /// This will attempt to compact identical meshes and also consolidate mesh primitives
        /// </summary>
        protected void  BuildConsolidatedMeshes()
        {
            // 1] Retrieve all existing meshes and compact identical instances
            List <LoaderTempMesh> CompactedMeshes = new List <LoaderTempMesh>();

            foreach (LoaderTempMesh M in m_TempMesh2FinalMesh.Keys)
            {
                // Check the existing meshes to see if they might be a master to this mesh
                if (m_bCompactIdenticalMeshes)
                {
                    foreach (LoaderTempMesh MasterMesh in CompactedMeshes)
                    {
                        if (M.MergeWithMasterMesh(MasterMesh))
                        {
                            break;                              // We found this mesh's master!
                        }
                    }
                }
                CompactedMeshes.Add(M);
            }

            // 2] Consolidate master meshes
//			WMath.Global.PushEpsilon( 1e-3f );	// Use this new epsilon for float comparisons in the Math library...

            foreach (LoaderTempMesh M in CompactedMeshes)
            {
                M.PerformConsolidation();
            }

//			WMath.Global.PopEpsilon();

            // 3] Rebuild slave meshes from consolidated meshes
            foreach (LoaderTempMesh M in CompactedMeshes)
            {
                M.RebuildFromMasterMesh();
            }


            // 4] Convert the mesh into a clean consolidated mesh
            PrimitiveBuilder Builder = new PrimitiveBuilder();
            foreach (LoaderTempMesh M in CompactedMeshes)
            {
                Scene.Nodes.Mesh TargetMesh = m_TempMesh2FinalMesh[M];

                // Setup basic mesh infos
                TargetMesh.BBox = M.BoundingBox;

                // I know it's a bit of a lousy approximation for the b-sphere but we can always refine it later...
                TargetMesh.BSphere = new BoundingSphere(M.BoundingBox.Center, 0.5f * M.BoundingBox.Dim.Magnitude());

                // Build primitives
                int PrimitiveIndex = 0;
                foreach (LoaderTempMesh.Primitive P in M.ConsolidatedPrimitives)
                {
                    if (P.Material == null)
                    {
                        throw new Exception("Primitive \"" + P.Name + "\" has no assigned material!");
                    }

                    Scene.Materials.MaterialParameters MatParams = m_Material2Parameters[P.Material];

//                  if ( !m_Material2Technique.ContainsKey( P.Material ) )
//                      continue;	// Un-supported...

                    // Create the temporary builder that will handle the primitive conversion
                    Builder.CreatePrimitive(P, TargetMesh, M.Name + "." + PrimitiveIndex++, MatParams);
                }
            }
        }
コード例 #2
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);
        }