Example #1
0
        internal static unsafe void UpdateVertexBuffer(InstancingId id)
        {
            var info = id.Info;

            if (info.VisibleCapacity == 0)
                return;

            fixed(byte *ptr = info.Data)
            {
                IVertexBuffer buffer = Data[id.Index].VB;

                if (buffer == null)
                {
                    Data[id.Index].VB = MyManagers.Buffers.CreateVertexBuffer(
                        info.DebugName, info.VisibleCapacity, info.Stride,
                        new IntPtr(ptr), SharpDX.Direct3D11.ResourceUsage.Dynamic);
                }
                else if (buffer.ElementCount < info.VisibleCapacity ||
                         buffer.Description.StructureByteStride != info.Stride)
                {
                    MyManagers.Buffers.Resize(Data[id.Index].VB, info.VisibleCapacity, info.Stride, new IntPtr(ptr));
                }
                else
                {
                    var mapping = MyMapping.MapDiscard(MyImmediateRC.RC, buffer);
                    mapping.WriteAndPosition(info.Data, info.VisibleCapacity * info.Stride);
                    mapping.Unmap();
                }
            }
        }
Example #2
0
 internal static void Remove(uint GID, InstancingId id)
 {
     Debug.Assert(IdIndex.ContainsKey(GID), "Removing instance that doesn't exist");
     RemoveResource(id);
     IdIndex.Remove(GID);
     Instancings.Free(id.Index);
 }
Example #3
0
        internal static unsafe void UpdateGeneric(InstancingId id, List <MyInstanceData> instanceData, int capacity)
        {
            Debug.Assert(id.Info.Type == MyRenderInstanceBufferType.Generic, "Wrong type of instance buffer for instancing!");

            capacity = instanceData.Count;

            if (capacity != Instancings.Data[id.Index].TotalCapacity)
            {
                Vector3[] positions = new Vector3[capacity];
                bool[]    mask      = new bool[capacity];
                for (int arrayIndex = 0; arrayIndex < capacity; ++arrayIndex)
                {
                    positions[arrayIndex] = new Vector3(instanceData[arrayIndex].m_row0.ToVector4().W, instanceData[arrayIndex].m_row1.ToVector4().W, instanceData[arrayIndex].m_row2.ToVector4().W);
                    mask[arrayIndex]      = true;
                }

                Instancings.Data[id.Index].VisibleCapacity         = capacity;
                Instancings.Data[id.Index].Positions               = positions;
                Instancings.Data[id.Index].VisibilityMask          = mask;
                Instancings.Data[id.Index].NonVisibleInstanceCount = 0;
            }

            Instancings.Data[id.Index].TotalCapacity = capacity;
            Instancings.Data[id.Index].InstanceData  = instanceData.ToArray();

            RebuildGeneric(id);
            MyInstanceLodComponent.ClearInvalidInstances(id);
        }
Example #4
0
        internal unsafe static InstancingId Create(uint GID, MyRenderInstanceBufferType type, string debugName)
        {
            var id = new InstancingId {
                Index = Instancings.Allocate()
            };

            Instancings.Data[id.Index] = new MyInstancingInfo
            {
                Type      = type,
                DebugName = debugName
            };

            MyArrayHelpers.Reserve(ref Data, id.Index + 1);
            Data[id.Index] = new MyInstancingData {
                VB = VertexBufferId.NULL
            };

            if (type == MyRenderInstanceBufferType.Cube)
            {
                Instancings.Data[id.Index].Layout = MyVertexLayouts.GetLayout(new MyVertexInputComponent(MyVertexInputComponentType.CUBE_INSTANCE, 2, MyVertexInputComponentFreq.PER_INSTANCE));
                Instancings.Data[id.Index].Stride = sizeof(MyVertexFormatCubeInstance);
            }
            else
            {
                Instancings.Data[id.Index].Layout = MyVertexLayouts.GetLayout(new MyVertexInputComponent(MyVertexInputComponentType.GENERIC_INSTANCE, 2, MyVertexInputComponentFreq.PER_INSTANCE));
                Instancings.Data[id.Index].Stride = sizeof(MyVertexFormatGenericInstance);
            }

            Debug.Assert(!IdIndex.ContainsKey(GID), "Creating instance with ID that already exists!");
            IdIndex.Add(GID, id);

            return(id);
        }
        /// <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);
            }
        }
        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 static unsafe void UpdateGeneric(InstancingId id, List <MyInstanceData> instanceData, int capacity)
        {
            Debug.Assert(id.Info.Type == MyRenderInstanceBufferType.Generic);

            capacity = instanceData.Count;

            if (capacity != Instancings.Data[id.Index].TotalCapacity)
            {
                bool[]    mask      = new bool[capacity];
                Vector3[] positions = new Vector3[capacity];
                for (int i = 0; i < capacity; i++)
                {
                    mask[i]      = true;
                    positions[i] = new Vector3(instanceData[i].m_row0.ToVector4().W, instanceData[i].m_row1.ToVector4().W, instanceData[i].m_row2.ToVector4().W);
                }

                Instancings.Data[id.Index].VisibilityMask = mask;
                Instancings.Data[id.Index].Positions      = positions;
            }

            Instancings.Data[id.Index].TotalCapacity = capacity;
            Instancings.Data[id.Index].InstanceData  = instanceData.ToArray();

            RebuildGeneric(id);
        }
        internal static unsafe void UpdateGeneric(InstancingId id, List <MyInstanceData> instanceData, int capacity)
        {
            Debug.Assert(id.Info.Type == MyRenderInstanceBufferType.Generic);

            var info = id.Info;

            var byteSize = info.Stride * capacity;

            if (Instancings.Data[id.Index].Data == null)
            {
                Instancings.Data[id.Index].Data = new byte[byteSize];
            }
            else
            {
                MyArrayHelpers.Reserve(ref Instancings.Data[id.Index].Data, byteSize);
            }

            var list = instanceData.ToArray();

            fixed(void *src = list)
            {
                fixed(void *dst = Instancings.Data[id.Index].Data)
                {
                    SharpDX.Utilities.CopyMemory(new IntPtr(dst), new IntPtr(src), info.Stride * list.Length);
                }
            }

            Instancings.Data[id.Index].Capacity = capacity;
            UpdateVertexBuffer(id);
        }
        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;
                }
            }
        }
 internal static void ClearInvalidInstances(InstancingId id)
 {
     foreach (var component in MyComponentFactory <MyInstanceLodComponent> .GetAll())
     {
         component.ClearInstances(id);
     }
 }
        internal unsafe static InstancingId Create(uint GID, MyRenderInstanceBufferType type, string debugName)
        {
            var id = new InstancingId { Index = Instancings.Allocate() };

            Instancings.Data[id.Index] = new MyInstancingInfo
            {
                Type = type,
                DebugName = debugName
            };

            MyArrayHelpers.Reserve(ref Data, id.Index + 1);
            Data[id.Index] = new MyInstancingData
            {
                VB = VertexBufferId.NULL
            };

            if(type == MyRenderInstanceBufferType.Cube)
            {
                Instancings.Data[id.Index].Layout = MyVertexLayouts.GetLayout(new MyVertexInputComponent(MyVertexInputComponentType.CUBE_INSTANCE, 2, MyVertexInputComponentFreq.PER_INSTANCE));
                Instancings.Data[id.Index].Stride = sizeof(MyVertexFormatCubeInstance);
            }
            else
            {
                Instancings.Data[id.Index].Layout = MyVertexLayouts.GetLayout(new MyVertexInputComponent(MyVertexInputComponentType.GENERIC_INSTANCE, 2, MyVertexInputComponentFreq.PER_INSTANCE));
                Instancings.Data[id.Index].Stride = sizeof(MyVertexFormatGenericInstance);
            }

            IdIndex[GID] = id;

            return id;
        }
 internal void Clear()
 {
     WorldMatrix           = MatrixD.Zero;
     CommonObjectData      = default(MyObjectDataCommon);
     NonVoxelObjectData    = MyObjectDataNonVoxel.Invalid;
     VoxelCommonObjectData = MyObjectDataVoxelCommon.Invalid;
     Mesh             = LodMeshId.NULL;
     MergedMesh       = MyMergedLodMeshId.NULL;
     Instancing       = InstancingId.NULL;
     DepthShaders     = MyMaterialShadersBundleId.NULL;
     Shaders          = MyMaterialShadersBundleId.NULL;
     ForwardShaders   = MyMaterialShadersBundleId.NULL;
     DrawSubmesh      = default(MyDrawSubmesh);
     PerMaterialIndex = 0;
     SectionSubmeshes = null;
     InstanceCount    = 0;
     StartInstance    = 0;
     SkinningMatrices = null;
     Type             = MyMaterialType.OPAQUE;
     Flags            = 0;
     Lod          = 0;
     ObjectBuffer = null;
     Parent       = null;
     Material     = MyStringId.NullOrEmpty;
 }
Example #13
0
        internal static unsafe void UpdateCube(InstancingId id, List <MyCubeInstanceData> instanceData, int capacity)
        {
            Debug.Assert(id.Info.Type == MyRenderInstanceBufferType.Cube);

            var info = id.Info;

            var byteSize = info.Stride * capacity;

            MyArrayHelpers.InitOrReserve(ref Instancings.Data[id.Index].Data, byteSize);

            fixed(void *dst = Instancings.Data[id.Index].Data)
            {
                MyVertexFormatCubeInstance *ptr = (MyVertexFormatCubeInstance *)dst;

                for (int i = 0; i < instanceData.Count; i++)
                {
                    fixed(byte *pSource = instanceData[i].RawBones())
                    {
                        for (int j = 0; j < MyRender11Constants.CUBE_INSTANCE_BONES_NUM * 4; j++)
                        {
                            ptr[i].bones[j] = pSource[j];
                        }
                    }

                    ptr[i].translationRotation = instanceData[i].m_translationAndRot;

                    var colorMaskHSV = instanceData[i].ColorMaskHSV;

                    ptr[i].colorMaskHSV = colorMaskHSV;
                }
            }

            Instancings.Data[id.Index].VisibleCapacity = capacity;
            UpdateVertexBuffer(id);
        }
        internal unsafe static void UpdateVertexBuffer(InstancingId id)
        {
            var info = id.Info;

            if (info.Capacity == 0)
            {
                return;
            }

            fixed(byte *ptr = info.Data)
            {
                if (Data[id.Index].VB == VertexBufferId.NULL)
                {
                    Data[id.Index].VB = MyHwBuffers.CreateVertexBuffer(info.Capacity, info.Stride, new IntPtr(ptr), info.DebugName);
                }
                else
                {
                    var vb = Data[id.Index].VB;
                    MyHwBuffers.ResizeVertexBuffer(vb, info.Capacity);

                    DataBox        srcBox    = new DataBox(new IntPtr(ptr));
                    ResourceRegion dstRegion = new ResourceRegion(0, 0, 0, info.Stride * info.Capacity, 1, 1);

                    MyRender11.ImmediateContext.UpdateSubresource(srcBox, vb.Buffer, 0, dstRegion);
                }
            }
        }
Example #15
0
 internal static void RemoveResource(InstancingId id)
 {
     if (Data[id.Index].VB != VertexBufferId.NULL)
     {
         MyHwBuffers.Destroy(Data[id.Index].VB);
         Data[id.Index].VB = VertexBufferId.NULL;
     }
 }
 internal static void Remove(uint GID, InstancingId id)
 {
     RemoveResource(id);
     IdIndex.Remove(GID);
     Instancings.Data[id.Index] = new MyInstancingInfo {
     };
     Instancings.Free(id.Index);
 }
Example #17
0
 internal static void RemoveResource(InstancingId id)
 {
     if (Data[id.Index].VB != null)
     {
         MyManagers.Buffers.Dispose(Data[id.Index].VB);
     }
     Data[id.Index].VB = null;
 }
        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();
        }
        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 void RemoveInstanceLod(InstancingId id, int index)
        {
            VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("RemoveInstanceLod");
            Debug.Assert(m_instances.ContainsKey(new MyInstanceLodId {
                Id = id, InstanceIndex = index
            }), "Cannot remove instance");

            MyInstancing.Instancings.Data[id.Index].SetVisibility(index, true);
            m_dirtyInstances.Add(id);
            SetDelta(id, index, 0.1f);
            VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
        }
Example #21
0
        internal static unsafe void UpdateVertexBuffer(InstancingId id)
        {
            var info = id.Info;

            if (info.VisibleCapacity == 0)
                return;

            fixed(byte *ptr = info.Data)
            {
                MyHwBuffers.ResizeAndUpdateStaticVertexBuffer(ref Data[id.Index].VB, info.VisibleCapacity, info.Stride, new IntPtr(ptr), info.DebugName);
            }
        }
        void SetAlphaForInstance(InstancingId id, int index, float transitionTime)
        {
            float value = GetAlphaForTime(transitionTime, transitionTime < 0.0f);

            var instancing = MyInstancing.Instancings.Data[id.Index].InstanceData;

            if (instancing != null && instancing.Length > index)
            {
                var color = instancing[index].ColorMaskHSV.ToVector4();
                color.W = value;
                instancing[index].ColorMaskHSV = new HalfVector4(color);
                m_dirtyInstances.Add(id);
            }
        }
        internal void RemoveAllInstanceLods(InstancingId instancing)
        {
            foreach (var instance in m_instances)
            {
                if (instance.Key.Id == instancing)
                {
                    MyInstancing.Instancings.Data[instance.Key.Id.Index].SetVisibility(instance.Key.InstanceIndex, true);
                    SetAlphaForInstance(instance.Key.Id, instance.Key.InstanceIndex, 0);
                }
            }

            ClearInstances(instancing);

            Debug.Assert(MyInstancing.Instancings.Data[instancing.Index].NonVisibleInstanceCount == 0);
        }
Example #24
0
        internal static unsafe void RebuildGeneric(InstancingId instancingId)
        {
            ProfilerShort.Begin("RebuildGeneric");
            Debug.Assert(instancingId.Info.Type == MyRenderInstanceBufferType.Generic);
            if (Instancings.Data[instancingId.Index].InstanceData == null)
            {
                ProfilerShort.End();
                Debug.Fail("Instance Data is null!");
                return;
            }

            var info = instancingId.Info;

            int capacity = Instancings.Data[instancingId.Index].InstanceData.Length;

            for (int maskIndex = 0; maskIndex < Instancings.Data[instancingId.Index].TotalCapacity; ++maskIndex)
            {
                if (!Instancings.Data[instancingId.Index].VisibilityMask[maskIndex])
                {
                    --capacity;
                }
            }

            var byteSize = info.Stride * capacity;

            MyArrayHelpers.InitOrReserve(ref Instancings.Data[instancingId.Index].Data, byteSize);

            fixed(void *src = Instancings.Data[instancingId.Index].InstanceData)
            {
                fixed(void *dst = Instancings.Data[instancingId.Index].Data)
                {
                    int currentIndex = 0;

                    for (int maskIndex = 0; maskIndex < Instancings.Data[instancingId.Index].TotalCapacity; ++maskIndex)
                    {
                        if (Instancings.Data[instancingId.Index].VisibilityMask[maskIndex])
                        {
                            SharpDX.Utilities.CopyMemory(new IntPtr(dst) + currentIndex * info.Stride, new IntPtr(src) + maskIndex * info.Stride, info.Stride);
                            ++currentIndex;
                        }
                    }
                }
            }

            Instancings.Data[instancingId.Index].VisibleCapacity = capacity;
            UpdateVertexBuffer(instancingId);
            ProfilerShort.End();
        }
        internal static unsafe void RebuildGeneric(InstancingId id)
        {
            VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("RebuildGeneric");
            Debug.Assert(id.Info.Type == MyRenderInstanceBufferType.Generic);
            var info = id.Info;

            int capacity = Instancings.Data[id.Index].InstanceData.Length;

            for (int i = 0; i < Instancings.Data[id.Index].TotalCapacity; i++)
            {
                if (!Instancings.Data[id.Index].VisibilityMask[i])
                {
                    capacity--;
                }
            }

            var byteSize = info.Stride * capacity;

            if (Instancings.Data[id.Index].Data == null)
            {
                Instancings.Data[id.Index].Data = new byte[byteSize];
            }
            else
            {
                MyArrayHelpers.Reserve(ref Instancings.Data[id.Index].Data, byteSize);
            }

            fixed(void *src = Instancings.Data[id.Index].InstanceData)
            {
                fixed(void *dst = Instancings.Data[id.Index].Data)
                {
                    int currentIndex = 0;

                    for (int i = 0; i < Instancings.Data[id.Index].TotalCapacity; i++)
                    {
                        if (Instancings.Data[id.Index].VisibilityMask[i])
                        {
                            SharpDX.Utilities.CopyMemory(new IntPtr(dst) + currentIndex * info.Stride, new IntPtr(src) + i * info.Stride, info.Stride);
                            currentIndex++;
                        }
                    }
                }
            }

            Instancings.Data[id.Index].VisibleCapacity = capacity;
            UpdateVertexBuffer(id);
            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 static unsafe void UpdateCube(InstancingId id, List <MyCubeInstanceData> instanceData, int capacity)
        {
            Debug.Assert(id.Info.Type == MyRenderInstanceBufferType.Cube);

            var info = id.Info;

            var byteSize = info.Stride * capacity;

            if (Instancings.Data[id.Index].Data == null)
            {
                Instancings.Data[id.Index].Data = new byte[byteSize];
            }
            else
            {
                MyArrayHelpers.Reserve(ref Instancings.Data[id.Index].Data, byteSize);
            }

            //var rawBuffer = new MyVertexFormatCubeInstance[m_capacity];

            fixed(void *dst = Instancings.Data[id.Index].Data)
            {
                MyVertexFormatCubeInstance *ptr = (MyVertexFormatCubeInstance *)dst;

                for (int i = 0; i < instanceData.Count; i++)
                {
                    fixed(byte *pSource = instanceData[i].RawBones())
                    {
                        for (int j = 0; j < MyRender11Constants.CUBE_INSTANCE_BONES_NUM * 4; j++)
                        {
                            ptr[i].bones[j] = pSource[j];
                        }
                    }

                    ptr[i].translationRotation = new HalfVector4(instanceData[i].m_translationAndRot);

                    var colorMaskHSV = instanceData[i].ColorMaskHSV;

                    //Vector3 color = MyRender11.ColorFromMask(new Vector3(colorMaskHSV.X, colorMaskHSV.Y, colorMaskHSV.Z));
                    ptr[i].colorMaskHSV = new HalfVector4(colorMaskHSV);
                }
            }

            Instancings.Data[id.Index].Capacity = capacity;
            UpdateVertexBuffer(id);
        }
        internal void RemoveInstanceLod(InstancingId id, int index)
        {
            ProfilerShort.Begin("RemoveInstanceLod");
            if (!m_instances.ContainsKey(new MyInstanceLodId {
                Id = id, InstanceIndex = index
            }))
            {
                // Can happen when the instance was removed manually by the game
                ProfilerShort.End();
                return;
            }

            MyInstancing.Instancings.Data[id.Index].SetVisibility(index, true);
            m_dirtyInstances.Add(id);
            SetDelta(id, index, 0.1f, (float)(MyEnvironment.CameraPosition - m_instances[new MyInstanceLodId {
                                                                                             Id = id, InstanceIndex = index
                                                                                         }].Position).LengthSquared());
            ProfilerShort.End();
        }
        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);
        }
        internal void ClearInstances(InstancingId id)
        {
            foreach (var instance in m_instances)
            {
                if (instance.Key.Id == id)
                {
                    m_instancesToRemove.Add(instance.Key);
                }
            }

            foreach (var instanceId in m_instancesToRemove)
            {
                RemoveAndReleaseInstance(m_instances[instanceId]);
                m_instances.Remove(instanceId);

                RemoveTransition(instanceId);
            }

            m_instancesToRemove.Clear();
        }
        private static void UpdateDecalPositions(InstancingId id, List <MyCubeInstanceData> instanceData, List <MyCubeInstanceDecalData> decals)
        {
            m_tmpDecalsUpdate.Clear();
            for (int it1 = 0; it1 < decals.Count; it1++)
            {
                MyCubeInstanceDecalData decal    = decals[it1];
                MyCubeInstanceData      cubeData = instanceData[decal.InstanceIndex];
                if (!cubeData.EnableSkinning)
                {
                    break;
                }

                MyDecalTopoData decalTopo;
                bool            found = MyScreenDecals.GetDecalTopoData(decal.DecalId, out decalTopo);
                if (!found)
                {
                    continue;
                }

                Matrix localCubeMatrix;
                Matrix skinningMatrix = cubeData.ConstructDeformedCubeInstanceMatrix(ref decalTopo.BoneIndices, ref decalTopo.BoneWeights, out localCubeMatrix);

                Matrix localCubeMatrixInv;
                Matrix.Invert(ref localCubeMatrix, out localCubeMatrixInv);

                // TODO: Optimization: it would be cool if we keep original cube coordiates local intersection
                // and avoid matrix inversion here. Refer to MyCubeGrid.GetIntersectionWithLine(), MyCubeGridHitInfo

                Matrix invBinding = decalTopo.MatrixBinding * localCubeMatrixInv;
                Matrix transform  = invBinding * skinningMatrix;

                m_tmpDecalsUpdate.Add(new MyDecalPositionUpdate()
                {
                    ID = decal.DecalId, Transform = transform
                });
            }

            MyScreenDecals.UpdateDecals(m_tmpDecalsUpdate);
        }
        internal static unsafe void UpdateGeneric(InstancingId id, List<MyInstanceData> instanceData, int capacity)
        {
            Debug.Assert(id.Info.Type == MyRenderInstanceBufferType.Generic);

            var info = id.Info;

            var byteSize = info.Stride * capacity;

            if(Instancings.Data[id.Index].Data == null)
            {
                Instancings.Data[id.Index].Data = new byte[byteSize];
            }
            else
            {
                MyArrayHelpers.Reserve(ref Instancings.Data[id.Index].Data, byteSize);
            }
            
            var list = instanceData.ToArray();

            fixed(void *src = list)
            {
                fixed (void* dst = Instancings.Data[id.Index].Data)
                {
                    SharpDX.Utilities.CopyMemory(new IntPtr(dst), new IntPtr(src), info.Stride * list.Length);
                }
            }

            Instancings.Data[id.Index].Capacity = capacity;
            UpdateVertexBuffer(id);
        }
 internal static void Remove(uint GID, InstancingId id)
 {
     RemoveResource(id);
     IdIndex.Remove(GID);
     Instancings.Data[id.Index] = new MyInstancingInfo { };
     Instancings.Free(id.Index);            
 }
 internal static void RemoveResource(InstancingId id)
 {
     if(Data[id.Index].VB != VertexBufferId.NULL)
     {
         MyHwBuffers.Destroy(Data[id.Index].VB);
         Data[id.Index].VB = VertexBufferId.NULL;
     }
 }
 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 Clear()
 {
     WorldMatrix = MatrixD.Zero;
     CommonObjectData = default(MyObjectDataCommon);
     NonVoxelObjectData = MyObjectDataNonVoxel.Invalid;
     VoxelCommonObjectData = MyObjectDataVoxelCommon.Invalid;
     Mesh = LodMeshId.NULL;
     MergedMesh = MyMergedLodMeshId.NULL;
     Instancing = InstancingId.NULL;
     DepthShaders = MyMaterialShadersBundleId.NULL;
     Shaders = MyMaterialShadersBundleId.NULL;
     ForwardShaders = MyMaterialShadersBundleId.NULL;
     DrawSubmesh = default(MyDrawSubmesh);
     PerMaterialIndex = 0;
     SectionSubmeshes = null;
     InstanceCount = 0;
     StartInstance = 0;
     SkinningMatrices = null;
     Type = MyMaterialType.OPAQUE;
     Flags = 0;
     Lod = 0;
     ObjectBuffer = null;
     Parent = null;
     Material = MyMeshMaterialId.NULL;
     UnusedMaterials = UnusedMaterials ?? new HashSet<string>();
     UnusedMaterials.Clear();
 }
        internal override void Construct()
        {
            base.Construct();

            Type = MyActorComponentEnum.Renderable;
            //m_mesh = null;
            m_lods = null;
            m_cullProxy = MyProxiesFactory.CreateCullProxy();
            m_btreeProxy = -1;

            Mesh = MeshId.NULL;
            Instancing = InstancingId.NULL;
            
            m_instanceCount = 0;
            m_startInstance = 0;

            m_isRenderedStandalone = true;

            m_keyColor = Vector3.One;
            m_objectDithering = 0;

            m_renderableProxiesForLodTransition = null;

            m_lodTransitionState = 0;
            m_lod = 0;

            m_voxelLod = -1;
            m_additionalFlags = 0;

            ModelProperties = new Dictionary<MyEntityMaterialKey, MyModelProperties>();
        }
        internal static unsafe void RebuildGeneric(InstancingId id)
        {
            VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("RebuildGeneric");
            Debug.Assert(id.Info.Type == MyRenderInstanceBufferType.Generic);
            var info = id.Info;

            int capacity = Instancings.Data[id.Index].InstanceData.Length;
            for (int i = 0; i < Instancings.Data[id.Index].TotalCapacity; i++)
            {
                if (!Instancings.Data[id.Index].VisibilityMask[i])
                {
                    capacity--;
                }
            }

            var byteSize = info.Stride * capacity;

            if (Instancings.Data[id.Index].Data == null)
            {
                Instancings.Data[id.Index].Data = new byte[byteSize];
            }
            else
            {
                MyArrayHelpers.Reserve(ref Instancings.Data[id.Index].Data, byteSize);
            }

            fixed (void* src = Instancings.Data[id.Index].InstanceData)
            {
                fixed (void* dst = Instancings.Data[id.Index].Data)
                {
                    int currentIndex = 0;
                    for (int i = 0; i < Instancings.Data[id.Index].TotalCapacity; i++)
                    {
                        if (Instancings.Data[id.Index].VisibilityMask[i])
                        {
                            SharpDX.Utilities.CopyMemory(new IntPtr(dst) + currentIndex * info.Stride, new IntPtr(src) + i * info.Stride, info.Stride);
                            currentIndex++;
                        }
                    }
                }
            }

            Instancings.Data[id.Index].VisibleCapacity = capacity;
            UpdateVertexBuffer(id);
            VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
        }
        internal static unsafe void UpdateCube(InstancingId id, List<MyCubeInstanceData> instanceData, int capacity)
        {
            Debug.Assert(id.Info.Type == MyRenderInstanceBufferType.Cube);

            var info = id.Info;

            var byteSize = info.Stride * capacity;

            if (Instancings.Data[id.Index].Data == null)
            {
                Instancings.Data[id.Index].Data = new byte[byteSize];
            }
            else
            {
                MyArrayHelpers.Reserve(ref Instancings.Data[id.Index].Data, byteSize);
            }

            //var rawBuffer = new MyVertexFormatCubeInstance[m_capacity];

            fixed (void* dst = Instancings.Data[id.Index].Data)
            {
                MyVertexFormatCubeInstance* ptr = (MyVertexFormatCubeInstance*) dst;

                for (int i = 0; i < instanceData.Count; i++)
                {
                    fixed (byte* pSource = instanceData[i].RawBones())
                    {
                        for (int j = 0; j < MyRender11Constants.CUBE_INSTANCE_BONES_NUM * 4; j++)
                            ptr[i].bones[j] = pSource[j];
                    }
                    ptr[i].translationRotation = new HalfVector4(instanceData[i].m_translationAndRot);

                    var colorMaskHSV = instanceData[i].ColorMaskHSV;
                    //Vector3 color = MyRender11.ColorFromMask(new Vector3(colorMaskHSV.X, colorMaskHSV.Y, colorMaskHSV.Z));
                    ptr[i].colorMaskHSV = new HalfVector4(colorMaskHSV);
                    
                }
            }
            

            Instancings.Data[id.Index].Capacity = capacity;
            UpdateVertexBuffer(id);
        }
        internal unsafe static void UpdateVertexBuffer(InstancingId id)
        {
            var info = id.Info;
            if (info.Capacity == 0)
            { 
                return;
            }

            fixed (byte* ptr = info.Data)
            {
                if(Data[id.Index].VB == VertexBufferId.NULL)
                {
                    Data[id.Index].VB = MyHwBuffers.CreateVertexBuffer(info.Capacity, info.Stride, new IntPtr(ptr), info.DebugName);
                }
                else
                {
                    var vb = Data[id.Index].VB;
                    MyHwBuffers.ResizeVertexBuffer(vb, info.Capacity);

                    DataBox srcBox = new DataBox(new IntPtr(ptr));
                    ResourceRegion dstRegion = new ResourceRegion(0, 0, 0, info.Stride * info.Capacity, 1, 1);

                    MyRender11.ImmediateContext.UpdateSubresource(srcBox, vb.Buffer, 0, dstRegion);
                }
            }
        }
        void SetAlphaForInstance(InstancingId id, int index, float transitionTime)
        {
            float value = GetAlphaForTime(transitionTime, transitionTime < 0.0f);

            var instancing = MyInstancing.Instancings.Data[id.Index].InstanceData;
            if (instancing != null)
            {
                var color = instancing[index].ColorMaskHSV.ToVector4();
                color.W = value;
                instancing[index].ColorMaskHSV = new HalfVector4(color);
                m_dirtyInstances.Add(id);
            }
        }
        internal static unsafe void UpdateGeneric(InstancingId id, List<MyInstanceData> instanceData, int capacity)
        {
            Debug.Assert(id.Info.Type == MyRenderInstanceBufferType.Generic);

            capacity = instanceData.Count;

            if (capacity != Instancings.Data[id.Index].TotalCapacity)
            {
                bool[] mask = new bool[capacity];
                Vector3[] positions = new Vector3[capacity];
                for (int i = 0; i < capacity; i++)
                {
                    mask[i] = true;
                    positions[i] = new Vector3(instanceData[i].m_row0.ToVector4().W, instanceData[i].m_row1.ToVector4().W, instanceData[i].m_row2.ToVector4().W);
                }
                
                Instancings.Data[id.Index].VisibilityMask = mask;
                Instancings.Data[id.Index].Positions = positions;
            }

            Instancings.Data[id.Index].TotalCapacity = capacity;
            Instancings.Data[id.Index].InstanceData = instanceData.ToArray();

            RebuildGeneric(id);
        }
        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 void SetInstancing(InstancingId instancing)
 {
     if(Instancing != instancing)
     {
         Instancing = instancing;
         m_owner.MarkRenderDirty();
     }
 }
        internal void RemoveInstanceLod(InstancingId id, int index)
        {
            VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("RemoveInstanceLod");
            Debug.Assert(m_instances.ContainsKey(new MyInstanceLodId { Id = id, InstanceIndex = index }), "Cannot remove instance");

            MyInstancing.Instancings.Data[id.Index].SetVisibility(index, true);
            m_dirtyInstances.Add(id);
            SetDelta(id, index, 0.1f);
            VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
        }