Beispiel #1
0
        public override void DoWork()
        {
            ProfilerShort.Begin("MyPrecalcJobMerge.DoWork");
            try
            {
                if (m_isCancelled)
                {
                    return;
                }

                double largestDistance = double.MinValue;

                m_metadata.Cell      = m_args.Cell;
                m_metadata.LocalAabb = BoundingBox.CreateInvalid();

                m_metadata.PositionOffset = Vector3D.MaxValue;
                foreach (var metadata in m_args.LodMeshMetadata)
                {
                    m_metadata.LocalAabb.Include(metadata.LocalAabb);

                    // Find the smallest offset
                    m_metadata.PositionOffset = Vector3D.Min(m_metadata.PositionOffset, metadata.PositionOffset);
                }

                if (m_isCancelled)
                {
                    return;
                }

                var inputBatches     = m_args.InBatches;
                int totalVertexCount = 0;

                foreach (MyClipmapCellBatch inputBatch in inputBatches)
                {
                    totalVertexCount += inputBatch.Vertices.Length;
                }
                int  currentMesh   = 0;
                int  currentBatch  = 0;
                uint currentVertex = 0;

                if (m_isCancelled)
                {
                    return;
                }

                for (int meshIndex = currentMesh; meshIndex < m_args.LodMeshMetadata.Count; ++meshIndex, ++currentMesh)
                {
                    var meshScale      = m_args.LodMeshMetadata[meshIndex].PositionScale;
                    var meshOffset     = m_args.LodMeshMetadata[meshIndex].PositionOffset;
                    var relativeOffset = meshOffset - m_metadata.PositionOffset;
                    for (int batchIndex = 0; batchIndex < m_args.LodMeshMetadata[meshIndex].BatchCount; ++batchIndex, ++currentBatch)
                    {
                        int material0 = inputBatches[currentBatch].Material0, material1 = inputBatches[currentBatch].Material1, material2 = inputBatches[currentBatch].Material2;
                        int batchMaterial = MyMaterialHelper.GetMaterialIndex(material0, material1, material2);

                        MyMaterialHelper materialHelper = null;
                        if (!m_materialHelperMappings.TryGetValue(batchMaterial, out materialHelper))
                        {
                            materialHelper = MyMaterialHelper.Allocate();
                            materialHelper.Init(material0, material1, material2);
                            m_materialHelperMappings.Add(batchMaterial, materialHelper);
                        }

                        var  inputVertices = inputBatches[currentBatch].Vertices;
                        uint vertexOffset  = (uint)materialHelper.GetCurrentVertexIndex();
                        for (int vertexIndex = 0; vertexIndex < inputVertices.Length; ++vertexIndex, ++currentVertex)
                        {
                            Vector3D position      = inputVertices[vertexIndex].Position;
                            Vector3D positionMorph = inputVertices[vertexIndex].PositionMorph;

                            position      *= meshScale;
                            position      += relativeOffset;
                            positionMorph *= meshScale;
                            positionMorph += relativeOffset;

                            double newDistance = Math.Max(position.AbsMax(), positionMorph.AbsMax());
                            largestDistance = Math.Max(largestDistance, newDistance);

                            materialHelper.AddVertex(ref inputVertices[vertexIndex], ref position, ref positionMorph);
                        }

                        var inputBatchIndices = inputBatches[currentBatch].Indices;
                        for (int indexIndex = 0; indexIndex < inputBatchIndices.Length; ++indexIndex)
                        {
                            materialHelper.AddIndex(inputBatchIndices[indexIndex] + vertexOffset);
                        }
                    }

                    if (m_isCancelled)
                    {
                        m_outBatches.SetSize(0);
                        return;
                    }
                }

                foreach (var materialHelper in m_materialHelperMappings.Values)
                {
                    m_outBatches.Add(MyMaterialHelper.CreateBatch(materialHelper, largestDistance));
                    materialHelper.Release();
                }
                m_materialHelperMappings.Clear();

                m_metadata.PositionScale = Vector3.One * (float)largestDistance;
                m_metadata.BatchCount    = m_outBatches.Count;
            }
            finally
            {
                foreach (var materialHelper in m_materialHelperMappings.Values)
                {
                    materialHelper.Release();
                }

                m_materialHelperMappings.Clear();

                ProfilerShort.End();
            }
        }