internal void SetLod(InstancingId instancingId, int index, int lod)
        {
            MySingleInstance instance;
            var instanceLodId = new MyInstanceLodId {
                Id = instancingId, InstanceIndex = index
            };

            if (m_instances.TryGetValue(instanceLodId, out instance) && instance.CurrentLod != lod)
            {
                MyLodTransitionData transition;
                if (m_activeTransitions.TryGetValue(instanceLodId, out transition))
                {
                    if (transition.IsProxyToInstance)
                    {
                        instance.CurrentLod = lod;
                        instance.IsDirty    = true;
                    }
                }
                else
                {
                    transition                      = MyObjectPoolManager.Allocate <MyLodTransitionData>();
                    transition.Delta                = instance.CurrentLod > lod ? -0.1f : 0.1f;
                    transition.Time                 = 0.0f;
                    transition.IsProxyToInstance    = false;
                    transition.StartDistanceSquared = (float)(MyEnvironment.CameraPosition - instance.Position).LengthSquared();
                    m_activeTransitions.Add(instanceLodId, transition);
                    instance.IsDirty = true;
                }
            }
        }
        /// <returns>Returns true if the item is in transition</returns>
        bool SetDelta(InstancingId id, int index, float delta, float startDistanceSquared)
        {
            var key = new MyInstanceLodId {
                Id = id, InstanceIndex = index
            };
            MyLodTransitionData data;

            if (m_activeTransitions.TryGetValue(key, out data))
            {
                data.Delta                = delta;
                data.Time                 = 0;
                data.IsProxyToInstance    = true;
                data.StartDistanceSquared = startDistanceSquared;
                return(true);
            }
            else
            {
                data                      = MyObjectPoolManager.Allocate <MyLodTransitionData>();
                data.Time                 = 0.0f;
                data.Delta                = delta;
                data.IsProxyToInstance    = true;
                data.StartDistanceSquared = startDistanceSquared;
                m_activeTransitions.Add(key, data);
                return(false);
            }
        }
        void SetAlphaForProxies(MyInstanceLodId id, MyLodTransitionData data)
        {
            ProfilerShort.Begin("SetAlphaForProxies");
            var instance = m_instances[id];

            if (data.IsProxyToInstance)
            {
                float value      = GetAlphaForTime(data.Time, data.Delta > 0);
                float otherValue = GetAlphaForTime(data.Time, data.Delta < 0);

                var lod = instance.Lods[instance.CurrentLod];
                foreach (var proxy in lod.RenderableProxies)
                {
                    proxy.CommonObjectData.CustomAlpha = value;
                }
            }
            else
            {
                float valueForStartLod = GetAlphaForTime(data.Time, true);
                float valueForEndLod   = GetAlphaForTime(data.Time, false);

                var startLod = instance.Lods[instance.CurrentLod];
                var endLod   = instance.Lods[instance.CurrentLod + Math.Sign(data.Delta)];
                foreach (var renderableProxy in startLod.RenderableProxies)
                {
                    renderableProxy.CommonObjectData.CustomAlpha = valueForStartLod;
                }
                foreach (var renderableProxy in endLod.RenderableProxies)
                {
                    renderableProxy.CommonObjectData.CustomAlpha = valueForEndLod;
                }
            }
            ProfilerShort.End();
        }
        internal void SetLod(InstancingId id, int index, int lod)
        {
            MySingleInstance instance;
            var key = new MyInstanceLodId {
                Id = id, InstanceIndex = index
            };

            if (m_instances.TryGetValue(key, out instance) && instance.CurrentLod != lod)
            {
                MyLodTransitionData transition;
                if (m_activeTransitions.TryGetValue(key, out transition))
                {
                    if (transition.IsProxyToInstance)
                    {
                        instance.CurrentLod = lod;
                        instance.IsDirty    = true;
                    }
                }
                else
                {
                    transition                   = new MyLodTransitionData();
                    transition.Delta             = instance.CurrentLod > lod ? -0.1f : 0.1f;
                    transition.Time              = 0.0f;
                    transition.IsProxyToInstance = false;
                    m_activeTransitions.Add(key, transition);
                    instance.IsDirty = true;
                }
            }
        }
        internal void AddInstanceLod(InstancingId id, int index, MyRenderableProxy[][] newProxies, ulong[][] newSortingKeys, BoundingBoxD aabb, Vector3D position)
        {
            ProfilerShort.Begin("AddInstanceLod");

            if (!SetDelta(id, index, -0.1f, (float)(MyEnvironment.CameraPosition - position).LengthSquared()))
            {
                MyInstanceLodId key = new MyInstanceLodId {
                    Id = id, InstanceIndex = index
                };

                MySingleInstance instance = MySingleInstance.Allocate();

                Array.Resize(ref instance.Lods, newProxies.Length);
                instance.Position = position;

                for (int lodIndex = 0; lodIndex < newProxies.Length; ++lodIndex)
                {
                    MyUtils.Init(ref instance.Lods[lodIndex]);
                    MySingleInstanceLod lod = instance.Lods[lodIndex];

                    if (lod.RenderableProxies != null && lod.RenderableProxies.Length == newProxies[lodIndex].Length)
                    {
                        Array.Copy(newProxies[lodIndex], lod.RenderableProxies, lod.RenderableProxies.Length);
                    }
                    else
                    {
                        lod.RenderableProxies = newProxies[lodIndex];
                    }

                    lod.SortingKeys = newSortingKeys[lodIndex];

                    if (lodIndex < newProxies.Length - 1)
                    {
                        int lodTransitionProxiesCount = newProxies[lodIndex].Length + newProxies[lodIndex + 1].Length;

                        Array.Resize(ref lod.RenderableProxiesForLodTransition, lodTransitionProxiesCount);
                        Array.Copy(newProxies[lodIndex], lod.RenderableProxiesForLodTransition, newProxies[lodIndex].Length);
                        Array.Copy(newProxies[lodIndex + 1], 0, lod.RenderableProxiesForLodTransition, newProxies[lodIndex].Length, newProxies[lodIndex + 1].Length);

                        int sortingKeysLength = newSortingKeys[lodIndex].Length + newSortingKeys[lodIndex + 1].Length;
                        Array.Resize(ref lod.SortingKeysForLodTransition, sortingKeysLength);
                        Array.Copy(newSortingKeys[lodIndex], lod.SortingKeysForLodTransition, newSortingKeys.Length);
                        Array.Copy(newSortingKeys[lodIndex + 1], 0, lod.SortingKeysForLodTransition, newSortingKeys.Length, newSortingKeys[lodIndex + 1].Length);
                    }
                }

                instance.CurrentLod = 0;

                instance.CullProxy = MyObjectPoolManager.Allocate <MyCullProxy>();

                instance.BtreeProxy = MyScene.DynamicRenderablesDBVH.AddProxy(ref aabb, instance.CullProxy, 0);
                m_instances.Add(key, instance);

                instance.IsDirty = true;
            }
            ProfilerShort.End();
        }
        void RemoveTransition(MyInstanceLodId instanceLodId)
        {
            MyLodTransitionData transitionData = null;

            if (m_activeTransitions.TryGetValue(instanceLodId, out transitionData))
            {
                MyObjectPoolManager.Deallocate(transitionData);
                m_activeTransitions.Remove(instanceLodId);
            }
        }
        internal void AddInstanceLod(InstancingId id, int index, MyRenderableProxy[][] newProxies, ulong[][] newSortingKeys, BoundingBoxD aabb)
        {
            VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("AddInstanceLod");
            if (!SetDelta(id, index, -0.1f))
            {
                MyInstanceLodId key = new MyInstanceLodId {
                    Id = id, InstanceIndex = index
                };

                MySingleInstance instance = new MySingleInstance();
                instance.Lods = new MySingleInstanceLod[newProxies.Length];

                for (int i = 0; i < newProxies.Length; i++)
                {
                    MySingleInstanceLod lod = new MySingleInstanceLod();
                    lod.RenderableProxies = newProxies[i];
                    lod.SortingKeys       = newSortingKeys[i];

                    if (i < newProxies.Length - 1)
                    {
                        lod.RenderableProxiesForLodTransition = new MyRenderableProxy[newProxies[i].Length + newProxies[i + 1].Length];
                        for (int j = 0; j < newProxies[i].Length; j++)
                        {
                            lod.RenderableProxiesForLodTransition[j] = newProxies[i][j];
                        }
                        for (int j = 0; j < newProxies[i + 1].Length; j++)
                        {
                            lod.RenderableProxiesForLodTransition[j + newProxies[i].Length] = newProxies[i + 1][j];
                        }

                        lod.SortingKeysForLodTransition = new ulong[newSortingKeys[i].Length + newSortingKeys[i + 1].Length];
                        for (int j = 0; j < newSortingKeys[i].Length; j++)
                        {
                            lod.SortingKeysForLodTransition[j] = newSortingKeys[i][j];
                        }
                        for (int j = 0; j < newSortingKeys[i + 1].Length; j++)
                        {
                            lod.SortingKeysForLodTransition[j + newSortingKeys[i].Length] = newSortingKeys[i + 1][j];
                        }
                    }

                    instance.Lods[i] = lod;
                }

                instance.CurrentLod = 0;

                instance.CullProxy = MyProxiesFactory.CreateCullProxy();

                instance.BtreeProxy = MyScene.RenderablesDBVH.AddProxy(ref aabb, instance.CullProxy, 0);
                m_instances.Add(key, instance);

                instance.IsDirty = true;
            }
            VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
        }
        internal bool IsFar(InstancingId id, int index)
        {
            var key = new MyInstanceLodId {
                Id = id, InstanceIndex = index
            };
            MyLodTransitionData data;

            if (m_activeTransitions.TryGetValue(key, out data))
            {
                if (data.IsProxyToInstance)
                {
                    return(data.Delta > 0.0f);
                }
            }
            return(MyInstancing.Instancings.Data[id.Index].VisibilityMask[index]);
        }
        internal bool IsFar(InstancingId id, int index)
        {
            bool isFar = false;
            var  key   = new MyInstanceLodId {
                Id = id, InstanceIndex = index
            };
            MyLodTransitionData data;

            if (m_activeTransitions.TryGetValue(key, out data) && data.IsProxyToInstance)
            {
                isFar = data.Delta > 0.0f;
            }
            else
            {
                isFar = MyInstancing.Instancings.Data[id.Index].VisibilityMask[index];
            }

            return(isFar);
        }
        /// <returns>Returns true if the item is in transition</returns>
        bool SetDelta(InstancingId id, int index, float delta)
        {
            var key = new MyInstanceLodId {
                Id = id, InstanceIndex = index
            };
            MyLodTransitionData data;

            if (m_activeTransitions.TryGetValue(key, out data))
            {
                data.Delta             = delta;
                data.Time              = 0;
                data.IsProxyToInstance = true;
                return(true);
            }
            else
            {
                data = new MyLodTransitionData {
                    Time = 0.0f, Delta = delta, IsProxyToInstance = true
                };
                m_activeTransitions.Add(key, data);
                return(false);
            }
        }
 internal void SetLod(InstancingId id, int index, int lod)
 {
     MySingleInstance instance;
     var key = new MyInstanceLodId { Id = id, InstanceIndex = index };
     if (m_instances.TryGetValue(key, out instance) && instance.CurrentLod != lod)
     {
         MyLodTransitionData transition;
         if (m_activeTransitions.TryGetValue(key, out transition))
         {
             if (transition.IsProxyToInstance)
             {
                 instance.CurrentLod = lod;
                 instance.IsDirty = true;
             }
         }
         else
         {
             transition = new MyLodTransitionData();
             transition.Delta = instance.CurrentLod > lod ? -0.1f : 0.1f;
             transition.Time = 0.0f;
             transition.IsProxyToInstance = false;
             m_activeTransitions.Add(key, transition);
             instance.IsDirty = true;
         }
     }
 }
 internal bool IsFar(InstancingId id, int index)
 {
     var key = new MyInstanceLodId { Id = id, InstanceIndex = index };
     MyLodTransitionData data;
     if (m_activeTransitions.TryGetValue(key, out data))
     {
         if (data.IsProxyToInstance)
         {
             return data.Delta > 0.0f;
         }
     }
     return MyInstancing.Instancings.Data[id.Index].VisibilityMask[index];
 }
 /// <returns>Returns true if the item is in transition</returns>
 bool SetDelta(InstancingId id, int index, float delta)
 {
     var key = new MyInstanceLodId { Id = id, InstanceIndex = index };
     MyLodTransitionData data;
     if (m_activeTransitions.TryGetValue(key, out data))
     {
         data.Delta = delta;
         data.Time = 0;
         data.IsProxyToInstance = true;
         return true;
     }
     else
     {
         data = new MyLodTransitionData { Time = 0.0f, Delta = delta, IsProxyToInstance = true };
         m_activeTransitions.Add(key, data);
         return false;
     }
 }
        internal void AddInstanceLod(InstancingId id, int index, MyRenderableProxy[][] newProxies, ulong[][] newSortingKeys, BoundingBoxD aabb)
        {
            VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("AddInstanceLod");
            if (!SetDelta(id, index, -0.1f))
            {
                MyInstanceLodId key = new MyInstanceLodId { Id = id, InstanceIndex = index };

                MySingleInstance instance = new MySingleInstance();
                instance.Lods = new MySingleInstanceLod[newProxies.Length];

                for (int i = 0; i < newProxies.Length; i++)
                {
                    MySingleInstanceLod lod = new MySingleInstanceLod();
                    lod.RenderableProxies = newProxies[i];
                    lod.SortingKeys = newSortingKeys[i];

                    if (i < newProxies.Length - 1)
                    {
                        lod.RenderableProxiesForLodTransition = new MyRenderableProxy[newProxies[i].Length + newProxies[i + 1].Length];
                        for (int j = 0; j < newProxies[i].Length; j++)
                        {
                            lod.RenderableProxiesForLodTransition[j] = newProxies[i][j];
                        }
                        for (int j = 0; j < newProxies[i + 1].Length; j++)
                        {
                            lod.RenderableProxiesForLodTransition[j + newProxies[i].Length] = newProxies[i + 1][j];
                        }

                        lod.SortingKeysForLodTransition = new ulong[newSortingKeys[i].Length + newSortingKeys[i + 1].Length];
                        for (int j = 0; j < newSortingKeys[i].Length; j++)
                        {
                            lod.SortingKeysForLodTransition[j] = newSortingKeys[i][j];
                        }
                        for (int j = 0; j < newSortingKeys[i + 1].Length; j++)
                        {
                            lod.SortingKeysForLodTransition[j + newSortingKeys[i].Length] = newSortingKeys[i + 1][j];
                        }
                    }

                    instance.Lods[i] = lod;
                }
                
                instance.CurrentLod = 0;

                instance.CullProxy = MyProxiesFactory.CreateCullProxy();

                instance.BtreeProxy = MyScene.RenderablesDBVH.AddProxy(ref aabb, instance.CullProxy, 0);
                m_instances.Add(key, instance);

                instance.IsDirty = true;
            }
            VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
        }
        void SetAlphaForProxies(MyInstanceLodId id, MyLodTransitionData data)
        {
            var instance = m_instances[id];
            if (data.IsProxyToInstance)
            {
                float value = GetAlphaForTime(data.Time, data.Delta > 0);
                float otherValue = GetAlphaForTime(data.Time, data.Delta < 0);

                var lod = instance.Lods[instance.CurrentLod];
                foreach (var proxy in lod.RenderableProxies)
                {
                    proxy.ObjectData.CustomAlpha = value;
                }
            }
            else
            {
                float valueForStartLod = GetAlphaForTime(data.Time, true);
                float valueForEndLod = GetAlphaForTime(data.Time, false);

                var startLod = instance.Lods[instance.CurrentLod];
                var endLod = instance.Lods[instance.CurrentLod + Math.Sign(data.Delta)];
                foreach (var proxy in startLod.RenderableProxies)
                {
                    proxy.ObjectData.CustomAlpha = valueForStartLod;
                }
                foreach (var proxy in endLod.RenderableProxies)
                {
                    proxy.ObjectData.CustomAlpha = valueForEndLod;
                }
            }
        }