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(); } } }
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); }
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); }
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; }
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); } } }
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); }
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(); }
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); }
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 RemoveResource(InstancingId id) { if(Data[id.Index].VB != VertexBufferId.NULL) { MyHwBuffers.Destroy(Data[id.Index].VB); Data[id.Index].VB = VertexBufferId.NULL; } }
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 SetInstancing(InstancingId instancing) { if(Instancing != instancing) { Instancing = instancing; m_owner.MarkRenderDirty(); } }