예제 #1
0
            internal void Update()
            {
                if (!IsUsed())
                {
                    return;
                }

                bool invalidateLod = false;

                foreach (var proxyIndex in m_dirtyProxyIndices)
                {
                    var cellProxy = m_mergedLodMeshProxies[proxyIndex];
                    if (MyMeshes.CanStartMerge(cellProxy.MeshId, 1))
                    {
                        Vector3I          mergeCell   = MyMeshes.GetVoxelInfo(cellProxy.MeshId).Coord;
                        int               divideIndex = GetDivideIndexFromMergeCell(ref mergeCell);
                        MyMergedLodMeshId mergedId    = MyMeshes.GetMergedLodMesh(cellProxy.MeshId, 0);
                        invalidateLod |= mergedId.Info.MergedLodMeshes.Count > 0;
                        mergedId.Info.PendingLodMeshes.UnionWith(mergedId.Info.MergedLodMeshes);
                        mergedId.Info.MergedLodMeshes.Clear();

                        TryCancelMergeJob(divideIndex, MeshId.NULL);
                        TryStartMergeJob(divideIndex, 1);
                    }
                }
                m_dirtyProxyIndices.Clear();
                if (invalidateLod)
                {
                    InvalidateAllMergedMeshesInLod();
                }
            }
            internal void UpdateMesh(MyRenderMessageUpdateMergedVoxelMesh updateMessage)
            {
                int divideIndex = GetDivideIndexFromMergeCell(ref updateMessage.Metadata.Cell.CoordInLod);

                // A job wasn't cancelled in time and made it here
                if (m_mergeJobs[divideIndex].CurrentWorkId != updateMessage.WorkId)
                {
                    return;
                }

                MyMergedLodMeshId mergedId = MyMeshes.GetMergedLodMesh(m_mergedLodMeshProxies[divideIndex].MeshId, 0);
                bool mergeSuccessful       = m_mergedLodMeshProxies[divideIndex].UpdateMergedMesh(updateMessage);

                if (mergeSuccessful)
                {
                    Debug.Assert(mergedId.Info.MergedLodMeshes.Count == 0, "Merging into an already merged mesh");
                    mergedId.Info.MergedLodMeshes.UnionWith(m_mergeJobs[divideIndex].LodMeshesBeingMerged);
                    SwitchMergeState(divideIndex, true);
                }
                else
                {
                    mergedId.Info.PendingLodMeshes.UnionWith(m_mergeJobs[divideIndex].LodMeshesBeingMerged);
                }

                ResetMerge(divideIndex);
            }
예제 #3
0
            internal bool OnAddedToScene(MyClipmapCellProxy cellProxy)
            {
                if (!IsUsed())
                {
                    return(false);
                }

                bool         lodAabbChanged = false;
                int          rootProxy      = m_boundingBoxes.GetRoot();
                BoundingBoxD lodAabbBefore  = BoundingBoxD.CreateInvalid();

                if (rootProxy != -1)
                {
                    lodAabbBefore = m_boundingBoxes.GetAabb(rootProxy);
                }

                BoundingBoxD cellAabb = (BoundingBoxD)cellProxy.LocalAabb;

                m_cellProxyToAabbProxy.Add(cellProxy, m_boundingBoxes.AddProxy(ref cellAabb, null, 0));

                if (rootProxy != -1)
                {
                    BoundingBoxD lodAabbAfter = m_boundingBoxes.GetAabb(rootProxy);
                    lodAabbChanged = lodAabbBefore.Equals(lodAabbAfter);
                }

                if (lodAabbChanged)
                {
                    InvalidateAllMergedMeshesInLod();
                }

                Vector3D translation = cellProxy.Translation;
                int      divideIndex = GetDivideIndex(ref translation);

                m_trackedActors[divideIndex].Add(cellProxy.Actor);

                MyMergedLodMeshId mergedLodMeshId = MyMeshes.GetMergedLodMesh(m_mergedLodMeshProxies[divideIndex].MeshId, 0);
                LodMeshId         lodMeshToMerge  = MyMeshes.GetLodMesh(cellProxy.MeshId, 0);
                bool mergedMesh = mergedLodMeshId.MergeLodMesh(lodMeshToMerge);

                if (mergedMesh)
                {
                    InvalidateAllMergedMeshesInLod();
                }

                TryCancelMergeJob(divideIndex, MeshId.NULL);
                bool startedMerge = TryStartMergeJob(divideIndex, 1000);

                bool shouldMarkDirty = !mergedMesh && !startedMerge;

                if (shouldMarkDirty)
                {
                    m_dirtyProxyIndices.Add(divideIndex);
                }

                return(shouldMarkDirty);
            }
 private void AssignLodMeshToProxy(MeshId mesh, MyRenderableProxy proxy)
 {
     if (MyMeshes.IsMergedVoxelMesh(mesh))
     {
         proxy.MergedMesh = MyMeshes.GetMergedLodMesh(mesh, 0);
     }
     else
     {
         proxy.Mesh = MyMeshes.GetLodMesh(mesh, 0);
     }
 }
예제 #5
0
        internal bool ShouldHaveFoliage()
        {
            var  mesh              = Owner.GetRenderable().GetModel();
            int  voxelLod          = MyMeshes.GetVoxelInfo(mesh).Lod;
            bool voxelMeshNotReady = voxelLod > LodLimit;

            if (voxelMeshNotReady)
            {
                return(false);
            }

            int partsNum;

            if (MyMeshes.IsMergedVoxelMesh(mesh))
            {
                partsNum = MyMeshes.GetMergedLodMesh(mesh, 0).Info.PartsNum;
            }
            else
            {
                partsNum = MyMeshes.GetLodMesh(mesh, 0).Info.PartsNum;
            }

            // only stream stones for lod0
            if (voxelLod > 0)
            {
                bool allStone = true;
                for (int i = 0; i < partsNum; i++)
                {
                    var triple = MyMeshes.GetVoxelPart(mesh, i).Info.MaterialTriple;
                    if (triple.I0 != -1 && MyVoxelMaterials1.Table[triple.I0].HasFoliage && MyVoxelMaterials1.Table[triple.I0].FoliageType == 0)
                    {
                        allStone = false;
                        break;
                    }
                    if (triple.I1 != -1 && MyVoxelMaterials1.Table[triple.I1].HasFoliage && MyVoxelMaterials1.Table[triple.I1].FoliageType == 0)
                    {
                        allStone = false;
                        break;
                    }
                    if (triple.I2 != -1 && MyVoxelMaterials1.Table[triple.I2].HasFoliage && MyVoxelMaterials1.Table[triple.I2].FoliageType == 0)
                    {
                        allStone = false;
                        break;
                    }
                }
                if (allStone)
                {
                    return(false);
                }
            }

            return(true);
        }
예제 #6
0
 internal static void AssignLodMeshToProxy(this MeshId meshId, MyRenderableProxy proxy)
 {
     Debug.Assert(proxy != null, "Proxy cannot be null!");
     if (MyMeshes.IsMergedVoxelMesh(meshId))
     {
         proxy.MergedMesh = MyMeshes.GetMergedLodMesh(meshId, 0);
     }
     else
     {
         proxy.Mesh = MyMeshes.GetLodMesh(meshId, 0);
     }
 }
예제 #7
0
        internal static int GetIndexCount(this MeshId meshId)
        {
            int indexCount = 0;

            if (MyMeshes.IsMergedVoxelMesh(meshId))
            {
                indexCount = MyMeshes.GetMergedLodMesh(meshId, 0).Info.IndicesNum;
            }
            else
            {
                indexCount = MyMeshes.GetLodMesh(meshId, 0).Info.IndicesNum;
            }

            return(indexCount);
        }
예제 #8
0
        internal static MyMeshBuffers GetMeshBuffers(this MeshId meshId)
        {
            MyMeshBuffers buffers;

            if (MyMeshes.IsMergedVoxelMesh(meshId))
            {
                buffers = MyMeshes.GetMergedLodMesh(meshId, 0).Buffers;
            }
            else
            {
                buffers = MyMeshes.GetLodMesh(meshId, 0).Buffers;
            }

            return(buffers);
        }
예제 #9
0
            internal bool OnDeleteCell(MyClipmapCellProxy cellProxy)
            {
                if (!IsUsed())
                {
                    return(false);
                }

                bool     unloadedCell = false;
                Vector3D translation  = cellProxy.Translation;
                int      divideIndex;

                if (TryGetDivideIndex(ref translation, out divideIndex))
                {
                    MyMergedLodMeshId mergedLodMeshId = MyMeshes.GetMergedLodMesh(m_mergedLodMeshProxies[divideIndex].MeshId, 0);
                    LodMeshId         lodMeshId       = MyMeshes.GetLodMesh(cellProxy.MeshId, 0);

                    bool unmergedMesh = mergedLodMeshId.UnmergeLodMesh(lodMeshId);
                    if (unmergedMesh)
                    {
                        InvalidateAllMergedMeshesInLod();
                    }

                    TryCancelMergeJob(divideIndex, cellProxy.MeshId);

                    cellProxy.Unload();
                    unloadedCell = true;

                    TryStartMergeJob(divideIndex, 1000);

                    if (unmergedMesh && unloadedCell)
                    {
                        m_dirtyProxyIndices.Add(divideIndex);
                    }

                    m_trackedActors[divideIndex].Remove(cellProxy.Actor);
                }

                int proxyId;

                if (m_cellProxyToAabbProxy.TryGetValue(cellProxy, out proxyId))
                {
                    m_boundingBoxes.RemoveProxy(m_cellProxyToAabbProxy[cellProxy]);
                    m_cellProxyToAabbProxy.Remove(cellProxy);
                }

                return(unloadedCell);
            }
예제 #10
0
            private void InvalidateAllMergedMeshesInLod()
            {
                // TODO: Redistribute actors
                for (int divideIndex = 0; divideIndex < m_lodDivisions; ++divideIndex)
                {
                    MyMergedLodMeshId mergedLodMeshId = MyMeshes.GetMergedLodMesh(m_mergedLodMeshProxies[divideIndex].MeshId, 0);
                    bool markDirty = mergedLodMeshId.Info.MergedLodMeshes.Count > 0;
                    mergedLodMeshId.Info.PendingLodMeshes.UnionWith(mergedLodMeshId.Info.MergedLodMeshes);
                    mergedLodMeshId.Info.MergedLodMeshes.Clear();
                    SwitchMergeState(divideIndex, false);

                    if (markDirty)
                    {
                        m_dirtyProxyIndices.Add(divideIndex);
                    }
                }
            }
예제 #11
0
            internal void DebugDrawCells()
            {
                if (!IsUsed())
                {
                    return;
                }

                foreach (var cellProxy in m_mergedLodMeshProxies)
                {
                    var mergedMeshId = MyMeshes.GetMergedLodMesh(cellProxy.MeshId, 0);
                    if (mergedMeshId.Info.MergedLodMeshes.Count <= 0)
                    {
                        continue;
                    }

                    BoundingBoxD worldAabb = cellProxy.LocalAabb.Transform(cellProxy.WorldMatrix);
                    MyRenderProxy.DebugDrawAABB(worldAabb, MyClipmap.LOD_COLORS[m_lod], 1.0f, 1.0f, false);
                }
            }
예제 #12
0
            private bool TryCancelMergeJob(int divideIndex, MeshId meshIdToRemove)
            {
                bool canceled = false;

                if (m_mergeJobs[divideIndex].LodMeshesBeingMerged.Count > 0)
                {
                    // Send the cancel message
                    MyRenderProxy.CancelVoxelMeshMerge(m_parentClipmap.Id, m_mergeJobs[divideIndex].CurrentWorkId);

                    if (meshIdToRemove != MeshId.NULL)
                    {
                        m_mergeJobs[divideIndex].LodMeshesBeingMerged.Remove(MyMeshes.GetLodMesh(meshIdToRemove, 0));
                    }

                    // Put the canceled meshes back into the correct pending queue
                    var mergedId = MyMeshes.GetMergedLodMesh(m_mergedLodMeshProxies[divideIndex].MeshId, 0);
                    mergedId.Info.PendingLodMeshes.UnionWith(m_mergeJobs[divideIndex].LodMeshesBeingMerged);

                    ResetMerge(divideIndex);
                    canceled = true;
                }
                return(canceled);
            }
예제 #13
0
        internal static bool ShouldHaveFoliage(this MeshId mesh)
        {
            int partsNum;

            if (MyMeshes.IsMergedVoxelMesh(mesh))
            {
                partsNum = MyMeshes.GetMergedLodMesh(mesh, 0).Info.PartsNum;
            }
            else
            {
                partsNum = MyMeshes.GetLodMesh(mesh, 0).Info.PartsNum;
            }

            bool shouldHaveFoliage = false;

            for (int partIndex = 0; partIndex < partsNum; ++partIndex)
            {
                var triple = MyMeshes.GetVoxelPart(mesh, partIndex).Info.MaterialTriple;

                if (triple.I0 >= 0 && MyVoxelMaterials1.Table[triple.I0].HasFoliage)
                {
                    shouldHaveFoliage = true;
                    break;
                }
                if (triple.I1 >= 0 && MyVoxelMaterials1.Table[triple.I1].HasFoliage)
                {
                    shouldHaveFoliage = true;
                    break;
                }
                if (triple.I2 >= 0 && MyVoxelMaterials1.Table[triple.I2].HasFoliage)
                {
                    shouldHaveFoliage = true;
                    break;
                }
            }
            return(shouldHaveFoliage);
        }
예제 #14
0
            internal void ResetMeshes()
            {
                if (!IsUsed())
                {
                    return;
                }

                foreach (var mergedProxy in m_mergedLodMeshProxies)
                {
                    var mergedMeshId = MyMeshes.GetMergedLodMesh(mergedProxy.MeshId, 0);
                    mergedMeshId.Info.PendingLodMeshes.Clear();
                    mergedMeshId.Info.MergedLodMeshes.Clear();
                }

                for (int divideIndex = 0; divideIndex < m_lodDivisions; ++divideIndex)
                {
                    SwitchMergeState(divideIndex, false);
                    m_trackedActors[divideIndex].Clear();
                    ResetMerge(divideIndex);
                }
                m_boundingBoxes.Clear();
                m_cellProxyToAabbProxy.Clear();
                m_dirtyProxyIndices.Clear();
            }
예제 #15
0
        internal unsafe void FillStreams()
        {
            bool alreadyFilled = m_streams != null && m_streams.Count > 0;

            if (alreadyFilled)
            {
                return;
            }

            var mesh = Owner.GetRenderable().GetModel();

            int voxelLod = MyMeshes.GetVoxelInfo(mesh).Lod;

            if (!Owner.IsVisible)
            {
                return;
            }

            int partsNum;

            if (MyMeshes.IsMergedVoxelMesh(mesh))
            {
                partsNum = MyMeshes.GetMergedLodMesh(mesh, 0).Info.PartsNum;
            }
            else
            {
                partsNum = MyMeshes.GetLodMesh(mesh, 0).Info.PartsNum;
            }

            m_streams = new Dictionary <int, MyFoliageStream>();

            // analyze
            for (int partIndex = 0; partIndex < partsNum; ++partIndex)
            {
                var partInfo = MyMeshes.GetVoxelPart(mesh, partIndex).Info;
                var triple   = partInfo.MaterialTriple;

                if (triple.I0 != -1 && MyVoxelMaterials1.Table[triple.I0].HasFoliage)
                {
                    PrepareStream(triple.I0, partInfo.IndexCount / 3, voxelLod);
                }
                if (triple.I1 != -1 && MyVoxelMaterials1.Table[triple.I1].HasFoliage)
                {
                    PrepareStream(triple.I1, partInfo.IndexCount / 3, voxelLod);
                }
                if (triple.I2 != -1 && MyVoxelMaterials1.Table[triple.I2].HasFoliage)
                {
                    PrepareStream(triple.I2, partInfo.IndexCount / 3, voxelLod);
                }
            }

            // prepare
            foreach (var stream in m_streams.Values)
            {
                stream.AllocateStreamOutBuffer(sizeof(Vector3) + sizeof(uint));
            }

            // analyze
            for (int partIndex = 0; partIndex < partsNum; partIndex++)
            {
                var partInfo = MyMeshes.GetVoxelPart(mesh, partIndex).Info;
                var triple   = partInfo.MaterialTriple;

                if (triple.I0 != -1 && MyVoxelMaterials1.Table[triple.I0].HasFoliage)
                {
                    FillStreamWithTerrainBatch(triple.I0, 0,
                                               partInfo.IndexCount, partInfo.StartIndex, 0);
                }
                if (triple.I1 != -1 && MyVoxelMaterials1.Table[triple.I1].HasFoliage)
                {
                    FillStreamWithTerrainBatch(triple.I1, 1,
                                               partInfo.IndexCount, partInfo.StartIndex, 0);
                }
                if (triple.I2 != -1 && MyVoxelMaterials1.Table[triple.I2].HasFoliage)
                {
                    FillStreamWithTerrainBatch(triple.I2, 2,
                                               partInfo.IndexCount, partInfo.StartIndex, 0);
                }
            }
        }
예제 #16
0
 internal static BoundingBox?GetBoundingBox(this MeshId meshId, int lod)
 {
     return(MyMeshes.IsMergedVoxelMesh(meshId) ? MyMeshes.GetMergedLodMesh(meshId, 0).Info.BoundingBox : MyMeshes.GetLodMesh(meshId, lod).Info.BoundingBox);
 }
        internal override bool RebuildLodProxy(int lodNum, bool skinningEnabled, MySkinningComponent skinning)
        {
            Debug.Assert(Mesh.Info.LodsNum == 1);

            MyRenderLod lod = null;

            int               partCount;
            LodMeshId         lodMesh       = new LodMeshId();
            MyMergedLodMeshId mergedLodMesh = new MyMergedLodMeshId();
            VertexLayoutId    vertexLayout;

            bool isMergedMesh = MyMeshes.IsMergedVoxelMesh(Mesh);

            if (!isMergedMesh)
            {
                if (!Owner.IsVisible)
                {
                    return(false);
                }

                lodMesh      = MyMeshes.GetLodMesh(Mesh, 0);
                vertexLayout = lodMesh.VertexLayout;
                partCount    = lodMesh.Info.PartsNum;
            }
            else
            {
                mergedLodMesh = MyMeshes.GetMergedLodMesh(Mesh, 0);
                if (mergedLodMesh.VertexLayout == VertexLayoutId.NULL || mergedLodMesh.Info.MergedLodMeshes.Count == 0)
                {
                    return(false);
                }

                partCount    = mergedLodMesh.Info.PartsNum;
                vertexLayout = mergedLodMesh.VertexLayout;
            }

            MyObjectPoolManager.Init(ref m_lods[lodNum]);
            lod = m_lods[lodNum];
            lod.VertexLayout1 = vertexLayout;

            // Hide proxies when they will already be rendered in a merged mesh
            if (!MyMeshes.IsLodMeshMerged(lodMesh))
            {
                AddToRenderables();
            }

            Debug.Assert(partCount > 0);

            lod.VertexShaderFlags = MyShaderUnifiedFlags.USE_VOXEL_DATA | MyShaderUnifiedFlags.USE_VOXEL_MORPHING | MyShaderUnifiedFlags.DITHERED;

            bool initializeProxies    = true; //isMergedMesh || !MyMeshes.IsLodMeshMerged(lodMesh);
            bool initializeDepthProxy = true; //!isMergedMesh && Num > 0;

            int numToInitialize = (initializeProxies ? partCount : 0) + (initializeDepthProxy ? 1 : 0);

            if (numToInitialize > 0)
            {
                lod.AllocateProxies(numToInitialize);
            }

            AnyDrawOutsideViewDistance = false;

            int constantBufferSize = GetConstantBufferSize(lod, skinningEnabled);

            if (initializeProxies)
            {
                for (int partIndex = 0; partIndex < partCount; partIndex++)
                {
                    CreateRenderableProxyForPart(lodNum, constantBufferSize, partIndex, partIndex, false);
                }
            }
            if (initializeDepthProxy)
            {
                CreateRenderableProxyForPart(lodNum, constantBufferSize, numToInitialize - 1, 0, true);
            }

            return(true);
        }
        private void CreateRenderableProxyForPart(MyRenderLod lod, int objectConstantsSize, int proxyIndex, int partIndex, bool shadowsOnly)
        {
            var partId    = MyMeshes.GetVoxelPart(Mesh, partIndex);
            var technique = partId.Info.MaterialTriple.IsMultimaterial() ? MyVoxelMesh.MULTI_MATERIAL_TAG : MyVoxelMesh.SINGLE_MATERIAL_TAG;

            if (shadowsOnly)
            {
                technique = MyVoxelMesh.SINGLE_MATERIAL_TAG;
            }

            lod.RenderableProxies[proxyIndex].WorldMatrix = Owner.WorldMatrix;
            //lod.RenderableProxies[p].ObjectData.LocalMatrix = m_owner.WorldMatrix;

            lod.RenderableProxies[proxyIndex].NonVoxelObjectData = MyObjectDataNonVoxel.Invalid;
            lod.RenderableProxies[proxyIndex].VoxelCommonObjectData.VoxelOffset         = m_voxelOffset;
            lod.RenderableProxies[proxyIndex].VoxelCommonObjectData.MassiveCenterRadius = Vector4.Zero; // Set in UpdateLodState
            lod.RenderableProxies[proxyIndex].VoxelCommonObjectData.VoxelScale          = m_voxelScale;


            AssignLodMeshToProxy(Mesh, lod.RenderableProxies[proxyIndex]);
            lod.RenderableProxies[proxyIndex].DepthShaders = MyMaterialShaders.Get(
                X.TEXT(MapTechniqueToShaderMaterial(technique)),
                X.TEXT(MyGeometryRenderer.DEFAULT_DEPTH_PASS),
                lod.VertexLayout1,
                lod.VertexShaderFlags | MyShaderUnifiedFlags.DEPTH_ONLY | MapTechniqueToShaderMaterialFlags(technique) | MyShaderUnifiedFlags.DITHERED);
            lod.RenderableProxies[proxyIndex].Shaders = MyMaterialShaders.Get(
                X.TEXT(MapTechniqueToShaderMaterial(technique)),
                X.TEXT(MyGeometryRenderer.DEFAULT_OPAQUE_PASS),
                lod.VertexLayout1,
                lod.VertexShaderFlags | MapTechniqueToShaderMaterialFlags(technique) | MyShaderUnifiedFlags.DITHERED);
            lod.RenderableProxies[proxyIndex].ForwardShaders = MyMaterialShaders.Get(
                X.TEXT(MapTechniqueToShaderMaterial(technique)),
                X.TEXT(MyGeometryRenderer.DEFAULT_FORWARD_PASS),
                lod.VertexLayout1,
                lod.VertexShaderFlags | MapTechniqueToShaderMaterialFlags(technique) | MyShaderUnifiedFlags.DITHERED);

            var partInfo = partId.Info;

            MyDrawSubmesh drawSubmesh;

            if (shadowsOnly)
            {
                MyMeshBuffers buffers;
                if (MyMeshes.IsMergedVoxelMesh(Mesh))
                {
                    buffers = MyMeshes.GetMergedLodMesh(Mesh, 0).Buffers;
                }
                else
                {
                    buffers = MyMeshes.GetLodMesh(Mesh, 0).Buffers;
                }

                drawSubmesh = new MyDrawSubmesh
                {
                    BaseVertex   = 0,
                    StartIndex   = 0,
                    IndexCount   = buffers.IB.Capacity,
                    BonesMapping = null,
                    MaterialId   = MyVoxelMaterials1.GetMaterialProxyId(partId.Info.MaterialTriple),
                    Flags        = MyDrawSubmesh.MySubmeshFlags.Depth
                };
            }
            else
            {
                drawSubmesh = new MyDrawSubmesh
                {
                    BaseVertex   = partInfo.BaseVertex,
                    StartIndex   = partInfo.StartIndex,
                    IndexCount   = partInfo.IndexCount,
                    BonesMapping = null,
                    MaterialId   = MyVoxelMaterials1.GetMaterialProxyId(partId.Info.MaterialTriple),
                    Flags        = MyDrawSubmesh.MySubmeshFlags.Gbuffer | MyDrawSubmesh.MySubmeshFlags.Forward
                };
            }

            lod.RenderableProxies[proxyIndex].DrawSubmesh      = drawSubmesh;
            lod.RenderableProxies[proxyIndex].SkinningMatrices = null;

            lod.RenderableProxies[proxyIndex].ObjectBuffer  = MyCommon.GetObjectCB(objectConstantsSize);
            lod.RenderableProxies[proxyIndex].InstanceCount = m_instanceCount;
            lod.RenderableProxies[proxyIndex].StartInstance = m_startInstance;
            lod.RenderableProxies[proxyIndex].Flags         = MapTechniqueToRenderableFlags(technique) | m_additionalFlags;
            lod.RenderableProxies[proxyIndex].Type          = MapTechniqueToMaterialType(technique);
            lod.RenderableProxies[proxyIndex].Parent        = this;
            lod.RenderableProxies[proxyIndex].Lod           = 0;
            lod.RenderableProxies[proxyIndex].Instancing    = m_instancing;

            AnyDrawOutsideViewDistance |= lod.RenderableProxies[proxyIndex].Flags.HasFlags(MyRenderableProxyFlags.DrawOutsideViewDistance);

            ulong sortingKey = 0;

            My64BitValueHelper.SetBits(ref sortingKey, 36, 2, (ulong)lod.RenderableProxies[proxyIndex].Type);
            My64BitValueHelper.SetBits(ref sortingKey, 32, 4, (ulong)drawSubmesh.MaterialId.Index);
            My64BitValueHelper.SetBits(ref sortingKey, 26, 6, (ulong)MyShaderMaterial.GetID(MapTechniqueToShaderMaterial(technique)));
            My64BitValueHelper.SetBits(ref sortingKey, 22, 4, (ulong)m_voxelLod);
            My64BitValueHelper.SetBits(ref sortingKey, 16, 6, (ulong)lod.VertexShaderFlags);
            //My64BitValueHelper.SetBits(ref sortingKey, 14, 6, (ulong)lod.VertexLayout1.Index);
            //My64BitValueHelper.SetBits(ref sortingKey, 0, 14, (ulong)m_owner.ID);

            lod.SortingKeys[proxyIndex] = sortingKey;
        }