private static void EnqueueHistory(MyVoxelDataRequest request) { using (m_historyLock.AcquireExclusiveUsing()) { if (UnculledRequestHistory.Count >= MAX_UNCULLED_HISTORY) { UnculledRequestHistory.Dequeue(); } request.Target = null; UnculledRequestHistory.Enqueue(request); } MyConcurrentHashSet <Vector3I> sizes; if (!KnownLodSizes.TryGetValue(request.Lod, out sizes)) { sizes = new MyConcurrentHashSet <Vector3I>(); if (!KnownLodSizes.TryAdd(request.Lod, sizes)) { sizes = KnownLodSizes[request.Lod]; } } sizes.Add(request.maxInLod - request.minInLod + Vector3I.One); }
public bool TryGetUniformValue(out byte uniformValue) { MyStorageData filteredValueBuffer = FilteredValueBuffer; MyVoxelDataRequest request = new MyVoxelDataRequest { Target = null, Offset = Vector3I.Zero, Lod = this.m_cell.Lod, MinInLod = this.m_cell.CoordInLod, MaxInLod = this.m_cell.CoordInLod, RequestedData = this.m_dataType.ToFlags() }; this.m_provider.ReadRange(ref request, true); if ((request.Flags & MyVoxelRequestFlags.EmptyData) > 0) { uniformValue = (this.m_dataType == MyStorageDataTypeEnum.Material) ? ((byte)0xff) : ((byte)0); return(true); } if ((this.m_dataType != MyStorageDataTypeEnum.Content) || ((request.Flags & MyVoxelRequestFlags.FullContent) <= 0)) { uniformValue = 0; return(false); } uniformValue = 0xff; return(true); }
public void ReadOcclusion(ref MyVoxelDataRequest req) { ProfilerShort.Begin("Occlusion Computation"); req.Flags = req.RequestFlags & (MyVoxelRequestFlags.SurfaceMaterial | MyVoxelRequestFlags.ConsiderContent); Vector3I minInLod = req.minInLod; Vector3I maxInLod = req.maxInLod; var target = req.Target; float lodVoxelSize = 1 << req.Lod; // We don't bother determining where the surface is if we don't have the normal. bool assignToSurface = req.RequestFlags.HasFlags(MyVoxelRequestFlags.SurfaceMaterial); bool useContent = req.RequestFlags.HasFlags(MyVoxelRequestFlags.ConsiderContent); // Prepare coefficient cache m_planetShape.PrepareCache(); Vector3I combinedOffset = -minInLod + req.Offset; Vector3I v = new Vector3I(); for (v.Z = minInLod.Z; v.Z <= maxInLod.Z; ++v.Z) { for (v.Y = minInLod.Y; v.Y <= maxInLod.Y; ++v.Y) { for (v.X = minInLod.X; v.X <= maxInLod.X; ++v.X) { Vector3I coords = v; var write = v + combinedOffset; var writeLinear = target.ComputeLinear(ref write); if ((assignToSurface && target.Material(writeLinear) != 0) || (useContent && target.Content(writeLinear) == 0)) { target.Content(writeLinear, 0); continue; } Vector3 localPos = coords * lodVoxelSize; var occlusion = GetOcclusionForPosition(ref localPos, lodVoxelSize); target[MyStorageDataTypeEnum.Occlusion][writeLinear] = occlusion; } } } ProfilerShort.End(); }
public void ReadRange(MyStorageData target, MyStorageDataTypeFlags dataType, ref Vector3I writeOffset, int lodIndex, ref Vector3I minInLod, ref Vector3I maxInLod) { if (!this.Closed) { MyVoxelDataRequest req = new MyVoxelDataRequest { Target = target, Offset = writeOffset, RequestedData = dataType, Lod = lodIndex, MinInLod = minInLod, MaxInLod = maxInLod }; this.ReadRange(ref req, false); } }
void IMyOctreeLeafNode.ReadRange(MyStorageData target, MyStorageDataTypeFlags types, ref Vector3I writeOffset, int lodIndex, ref Vector3I minInLod, ref Vector3I maxInLod, ref MyVoxelRequestFlags flags) { int num = this.m_cell.Lod - lodIndex; Vector3I vectori = this.m_cell.CoordInLod << num; MyVoxelDataRequest request = new MyVoxelDataRequest { Target = target, Offset = writeOffset, Lod = lodIndex, MinInLod = (Vector3I)(minInLod + vectori), MaxInLod = (Vector3I)(maxInLod + vectori), RequestFlags = flags, RequestedData = types }; this.m_provider.ReadRange(ref request, false); flags = request.Flags; }
public unsafe void ReadRange(ref MyVoxelDataRequest req, bool detectOnly = false) { if (!this.Closed) { if (req.RequestedData.Requests(MyStorageDataTypeEnum.Content)) { this.Shape.ReadContentRange(ref req, detectOnly); MyVoxelRequestFlags *flagsPtr1 = (MyVoxelRequestFlags *)ref req.RequestFlags; *((int *)flagsPtr1) |= 2; } if (!req.Flags.HasFlags(MyVoxelRequestFlags.EmptyData)) { if (req.RequestedData.Requests(MyStorageDataTypeEnum.Material)) { this.Material.ReadMaterialRange(ref req, detectOnly); } } else if (!detectOnly && req.RequestedData.Requests(MyStorageDataTypeEnum.Material)) { req.Target.BlockFill(MyStorageDataTypeEnum.Material, req.MinInLod, req.MaxInLod, 0xff); } } }
void IMyOctreeLeafNode.ReadRange(MyStorageData target, MyStorageDataTypeFlags types, ref Vector3I writeOffset, int lodIndex, ref Vector3I minInLod, ref Vector3I maxInLod, ref MyVoxelRequestFlags flags) { var lodShift = m_cell.Lod - lodIndex; var leafMinInLod = m_cell.CoordInLod << lodShift; var min = minInLod + leafMinInLod; var max = maxInLod + leafMinInLod; AssertRangeIsInside(lodIndex, ref min, ref max); ProfilerShort.Begin("MyProviderLeaf.ReadRange"); MyVoxelDataRequest req = new MyVoxelDataRequest() { Target = target, Offset = writeOffset, Lod = lodIndex, minInLod = min, maxInLod = max, RequestFlags = flags, RequestedData = types }; m_provider.ReadRange(ref req); flags = req.Flags; ProfilerShort.End(); }
public void ReadOcclusion(ref MyVoxelDataRequest req) { ProfilerShort.Begin("Occlusion Computation"); req.Flags = req.RequestFlags & (MyVoxelRequestFlags.SurfaceMaterial | MyVoxelRequestFlags.ConsiderContent); Vector3I minInLod = req.minInLod; Vector3I maxInLod = req.maxInLod; var target = req.Target; float lodVoxelSize = 1 << req.Lod; // We don't bother determining where the surface is if we don't have the normal. bool assignToSurface = req.RequestFlags.HasFlags(MyVoxelRequestFlags.SurfaceMaterial) && req.RequestedData.Requests(MyStorageDataTypeEnum.Material); bool useContent = req.RequestFlags.HasFlags(MyVoxelRequestFlags.ConsiderContent); // Prepare coefficient cache m_planetShape.PrepareCache(); Vector3I combinedOffset = -minInLod + req.Offset; Vector3I v = new Vector3I(); for (v.Z = minInLod.Z; v.Z <= maxInLod.Z; ++v.Z) { for (v.Y = minInLod.Y; v.Y <= maxInLod.Y; ++v.Y) { for (v.X = minInLod.X; v.X <= maxInLod.X; ++v.X) { Vector3I coords = v; var write = v + combinedOffset; var writeLinear = target.ComputeLinear(ref write); if ((assignToSurface && target.Material(writeLinear) != 0) || (useContent && target.Content(writeLinear) == 0)) { target.Content(writeLinear, 0); continue; } Vector3 localPos = coords * lodVoxelSize; var occlusion = GetOcclusionForPosition(ref localPos, lodVoxelSize); target[MyStorageDataTypeEnum.Occlusion][writeLinear] = occlusion; } } } ProfilerShort.End(); }
public void ReadMaterialRange(ref MyVoxelDataRequest req) { byte biome; ProfilerShort.Begin("MaterialComputation"); req.Flags = req.RequestFlags & (MyVoxelRequestFlags.SurfaceMaterial | MyVoxelRequestFlags.ConsiderContent); Vector3I minInLod = req.minInLod; Vector3I maxInLod = req.maxInLod; var target = req.Target; float lodVoxelSize = 1 << req.Lod; MyVoxelRequestFlags usedFlags = 0; bool computeOcclusion = req.RequestedData.Requests(MyStorageDataTypeEnum.Occlusion); // We don't bother determining where the surface is if we don't have the normal. bool assignToSurface = req.RequestFlags.HasFlags(MyVoxelRequestFlags.SurfaceMaterial); bool useContent = req.RequestFlags.HasFlags(MyVoxelRequestFlags.ConsiderContent); // Prepare coefficient cache m_planetShape.PrepareCache(); // Here we will compute which rules match the requested range and apply those. if (m_biomes != null) { if (req.SizeLinear > 125) { BoundingBox rbox = new BoundingBox((Vector3)minInLod * lodVoxelSize, (Vector3)maxInLod * lodVoxelSize); PrepareRulesForBoxInternal(ref rbox); } else if (!m_rangeClean || m_providerForRules != this) { CleanRules(); } } Vector3I combinedOffset = -minInLod + req.Offset; Vector3I v = new Vector3I(); for (v.Z = minInLod.Z; v.Z <= maxInLod.Z; ++v.Z) { for (v.Y = minInLod.Y; v.Y <= maxInLod.Y; ++v.Y) { for (v.X = minInLod.X; v.X <= maxInLod.X; ++v.X) { Vector3I coords = v; var write = v + combinedOffset; var writeLinear = target.ComputeLinear(ref write); if ((assignToSurface && target.Material(writeLinear) != 0) || (useContent && target.Content(writeLinear) == 0)) { if (computeOcclusion) { // Prevent empty voxels from affecting occlusion. target.Content(writeLinear, 0); } target.Material(writeLinear, MyVoxelConstants.NULL_MATERIAL); continue; } MyVoxelMaterialDefinition mat = null; byte occlusion = (byte)(computeOcclusion ? 255 : 0); // flag that we want occlusion. Vector3 localPos = coords * lodVoxelSize; mat = GetMaterialForPosition(ref localPos, lodVoxelSize, out biome, ref occlusion); if (mat == null) mat = MyDefinitionManager.Static.GetVoxelMaterialDefinition(0); target.Material(writeLinear, mat.Index); if (computeOcclusion) { target[MyStorageDataTypeEnum.Occlusion][writeLinear] = occlusion; } } } } ProfilerShort.End(); }
public unsafe void ReadMaterialRange(ref MyVoxelDataRequest req, bool detectOnly = false) { Vector3I vectori4; req.Flags = req.RequestFlags & MyVoxelRequestFlags.RequestFlags; Vector3I minInLod = req.MinInLod; Vector3I maxInLod = req.MaxInLod; float lodSize = 1 << (req.Lod & 0x1f); bool flag = req.RequestFlags.HasFlags(MyVoxelRequestFlags.SurfaceMaterial); bool flag2 = req.RequestFlags.HasFlags(MyVoxelRequestFlags.ConsiderContent); bool preciseOrePositions = req.RequestFlags.HasFlags(MyVoxelRequestFlags.PreciseOrePositions); this.m_planetShape.PrepareCache(); if (this.m_biomes != null) { if (req.SizeLinear > 0x7d) { BoundingBox request = new BoundingBox((Vector3)(minInLod * lodSize), (Vector3)(maxInLod * lodSize)); this.PrepareRulesForBoxInternal(ref request); } else if (!m_rangeClean || !ReferenceEquals(CachedProvider, this)) { this.CleanRules(); } } Vector3 vector = (minInLod + 0.5f) * lodSize; Vector3 pos = vector; Vector3I vectori3 = (Vector3I)(-minInLod + req.Offset); if (detectOnly) { vectori4.Z = minInLod.Z; while (vectori4.Z <= maxInLod.Z) { vectori4.Y = minInLod.Y; while (true) { if (vectori4.Y > maxInLod.Y) { float *singlePtr3 = (float *)ref pos.Z; singlePtr3[0] += lodSize; pos.Y = vector.Y; int *numPtr3 = (int *)ref vectori4.Z; numPtr3[0]++; break; } vectori4.X = minInLod.X; while (true) { byte num2; if (vectori4.X > maxInLod.X) { float *singlePtr2 = (float *)ref pos.Y; singlePtr2[0] += lodSize; pos.X = vector.X; int *numPtr2 = (int *)ref vectori4.Y; numPtr2[0]++; break; } MyVoxelMaterialDefinition definition = this.GetMaterialForPosition(ref pos, lodSize, out num2, preciseOrePositions); if ((definition != null) && (definition.Index != 0xff)) { return; } float *singlePtr1 = (float *)ref pos.X; singlePtr1[0] += lodSize; int *numPtr1 = (int *)ref vectori4.X; numPtr1[0]++; } } } MyVoxelRequestFlags *flagsPtr1 = (MyVoxelRequestFlags *)ref req.Flags; *((int *)flagsPtr1) |= 8; } else { bool flag4 = true; MyStorageData target = req.Target; vectori4.Z = minInLod.Z; while (true) { while (true) { if (vectori4.Z <= maxInLod.Z) { vectori4.Y = minInLod.Y; break; } if (flag4) { MyVoxelRequestFlags *flagsPtr2 = (MyVoxelRequestFlags *)ref req.Flags; *((int *)flagsPtr2) |= 8; } return; } while (true) { if (vectori4.Y > maxInLod.Y) { float *singlePtr6 = (float *)ref pos.Z; singlePtr6[0] += lodSize; pos.Y = vector.Y; int *numPtr6 = (int *)ref vectori4.Z; numPtr6[0]++; break; } vectori4.X = minInLod.X; Vector3I p = (Vector3I)(vectori4 + vectori3); int linearIdx = target.ComputeLinear(ref p); while (true) { if (vectori4.X <= maxInLod.X) { byte num4; if ((!flag || (target.Material(linearIdx) == 0)) && (!flag2 || (target.Content(linearIdx) != 0))) { byte num5; MyVoxelMaterialDefinition definition2 = this.GetMaterialForPosition(ref pos, lodSize, out num5, preciseOrePositions); num4 = (definition2 != null) ? definition2.Index : ((byte)0xff); } else { num4 = 0xff; } target.Material(linearIdx, num4); flag4 &= num4 == 0xff; linearIdx += target.StepLinear; float *singlePtr4 = (float *)ref pos.X; singlePtr4[0] += lodSize; int *numPtr4 = (int *)ref vectori4.X; numPtr4[0]++; continue; } else { float *singlePtr5 = (float *)ref pos.Y; singlePtr5[0] += lodSize; pos.X = vector.X; int *numPtr5 = (int *)ref vectori4.Y; numPtr5[0]++; } break; } } } } }
public void ReadRange(ref MyVoxelDataRequest req) { if (req.RequestedData.Requests(MyStorageDataTypeEnum.Content)) ReadContentRange(req.Target, ref req.Offset, req.Lod, ref req.minInLod, ref req.maxInLod); else ReadMaterialRange(req.Target, ref req.Offset, req.Lod, ref req.minInLod, ref req.maxInLod); req.Flags = req.RequestFlags & (MyVoxelRequestFlags.RequestFlags); }
public void ReadRange(ref MyVoxelDataRequest req) { if (Closed) { Debug.Fail("Storage closed!"); return; } if (req.RequestedData.Requests(MyStorageDataTypeEnum.Content)) { Shape.ReadContentRange(ref req); } if (req.RequestedData.Requests(MyStorageDataTypeEnum.Material)) { Material.ReadMaterialRange(ref req); } // If only occlusion is requested else if (req.RequestedData.Requests(MyStorageDataTypeEnum.Occlusion)) { Material.ReadOcclusion(ref req); } }
public void ReadRange(MyStorageData target, MyStorageDataTypeFlags dataType, ref Vector3I writeOffset, int lodIndex, ref Vector3I minInLod, ref Vector3I maxInLod) { if (Closed) { Debug.Fail("Storage closed!"); return; } MyVoxelDataRequest request = new MyVoxelDataRequest() { Target = target, Offset = writeOffset, RequestedData = dataType, Lod = lodIndex, minInLod = minInLod, maxInLod = maxInLod }; ReadRange(ref request); }
public void ReadRange(ref MyVoxelDataRequest req) { if (Closed) { Debug.Fail("Storage closed!"); return; } if (req.RequestedData.Requests(MyStorageDataTypeEnum.Content)) { Shape.ReadContentRange(ref req); req.RequestFlags |= MyVoxelRequestFlags.ConsiderContent; } if (req.Flags.HasFlags(MyVoxelRequestFlags.EmptyContent)) { if (req.RequestedData.Requests(MyStorageDataTypeEnum.Material)) req.Target.BlockFill(MyStorageDataTypeEnum.Material, req.minInLod, req.maxInLod, MyVoxelConstants.NULL_MATERIAL); if (req.RequestedData.Requests(MyStorageDataTypeEnum.Occlusion)) req.Target.BlockFill(MyStorageDataTypeEnum.Occlusion, req.minInLod, req.maxInLod, 0); } else { if (req.RequestedData.Requests(MyStorageDataTypeEnum.Material)) { Material.ReadMaterialRange(ref req); } // If only occlusion is requested else if (req.RequestedData.Requests(MyStorageDataTypeEnum.Occlusion)) { Material.ReadOcclusion(ref req); } } }
private static void EnqueueHistory(MyVoxelDataRequest request) { using (m_historyLock.AcquireExclusiveUsing()) { if (UnculledRequestHistory.Count >= MAX_UNCULLED_HISTORY) { UnculledRequestHistory.Dequeue(); } request.Target = null; UnculledRequestHistory.Enqueue(request); } MyConcurrentHashSet<Vector3I> sizes; if (!KnownLodSizes.TryGetValue(request.Lod, out sizes)) { sizes = new MyConcurrentHashSet<Vector3I>(); if (!KnownLodSizes.TryAdd(request.Lod, sizes)) { sizes = KnownLodSizes[request.Lod]; } } sizes.Add(request.maxInLod - request.minInLod + Vector3I.One); }
internal void ReadContentRange(ref MyVoxelDataRequest req) { if (Closed) return; float lodVoxelSize = (1 << req.Lod) * MyVoxelConstants.VOXEL_SIZE_IN_METRES; Vector3I min = req.minInLod; Vector3I max = req.maxInLod; ProfilerShort.Begin("Distance field computation"); try { Vector3I v = min; Vector3 localPos = v * lodVoxelSize - m_translation; Vector3 localPosStart = localPos; BoundingBox request = new BoundingBox(localPos, localPos + (max - min) * lodVoxelSize); request.Inflate(lodVoxelSize); MyVoxelRequestFlags flags = 0; ContainmentType cont = ContainmentType.Intersects; bool intersects; if (!req.Flags.HasFlag(MyVoxelRequestFlags.DoNotCheck)) { BoundingSphere sphere = new BoundingSphere( Vector3.Zero, OuterRadius + lodVoxelSize); sphere.Intersects(ref request, out intersects); if (!intersects) { cont = ContainmentType.Disjoint; goto end; } sphere.Radius = InnerRadius - lodVoxelSize; ContainmentType ct; sphere.Contains(ref request, out ct); if (ct == ContainmentType.Contains) { cont = ct; goto end; } cont = IntersectBoundingBoxInternal(ref request, lodVoxelSize); if (cont != ContainmentType.Intersects) goto end; } bool hit = false; // store request history EnqueueHistory(req); // Setup cache for current map; PrepareCache(); var writeOffsetLoc = req.Offset - min; for (v.Z = min.Z; v.Z <= max.Z; ++v.Z) { for (v.Y = min.Y; v.Y <= max.Y; ++v.Y) { v.X = min.X; var write2 = v + writeOffsetLoc; var write = req.Target.ComputeLinear(ref write2); for (; v.X <= max.X; ++v.X) { float signedDist = SignedDistanceLocal(localPos, lodVoxelSize) / lodVoxelSize; var fillRatio = MathHelper.Clamp(-signedDist, -1f, 1f) * 0.5f + 0.5f; byte content = (byte)(fillRatio * MyVoxelConstants.VOXEL_CONTENT_FULL); if (content != 0) { hit = true; } req.Target.Content(write, content); write += req.Target.StepLinear; localPos.X += lodVoxelSize; } localPos.Y += lodVoxelSize; localPos.X = localPosStart.X; } localPos.Z += lodVoxelSize; localPos.Y = localPosStart.Y; } if (!hit) { PruningStats.Miss(); } else { PruningStats.Hit(); } CullStats.Miss(); return; end: ; CullStats.Hit(); if (cont == ContainmentType.Disjoint) { if (req.RequestFlags.HasFlag(MyVoxelRequestFlags.ContentChecked)) { flags |= MyVoxelRequestFlags.EmptyContent | MyVoxelRequestFlags.ContentCheckedDeep | MyVoxelRequestFlags.ContentChecked; } else { req.Target.BlockFillContent(req.Offset, req.Offset + max - min, MyVoxelConstants.VOXEL_CONTENT_EMPTY); } } else if (cont == ContainmentType.Contains) { if (req.RequestFlags.HasFlag(MyVoxelRequestFlags.ContentChecked)) { flags |= MyVoxelRequestFlags.FullContent | MyVoxelRequestFlags.ContentCheckedDeep | MyVoxelRequestFlags.ContentChecked; } else { req.Target.BlockFillContent(req.Offset, req.Offset + max - min, MyVoxelConstants.VOXEL_CONTENT_FULL); } } req.Flags = flags; PruningStats.Hit(); } finally { ProfilerShort.End(); } }
public void ReadMaterialRange(ref MyVoxelDataRequest req) { byte biome; ProfilerShort.Begin("MaterialComputation"); req.Flags = req.RequestFlags & (MyVoxelRequestFlags.SurfaceMaterial | MyVoxelRequestFlags.ConsiderContent); Vector3I minInLod = req.minInLod; Vector3I maxInLod = req.maxInLod; var target = req.Target; float lodVoxelSize = 1 << req.Lod; MyVoxelRequestFlags usedFlags = 0; bool computeOcclusion = req.RequestedData.Requests(MyStorageDataTypeEnum.Occlusion); // We don't bother determining where the surface is if we don't have the normal. bool assignToSurface = req.RequestFlags.HasFlags(MyVoxelRequestFlags.SurfaceMaterial); bool useContent = req.RequestFlags.HasFlags(MyVoxelRequestFlags.ConsiderContent); // Prepare coefficient cache m_planetShape.PrepareCache(); // Here we will compute which rules match the requested range and apply those. if (m_biomes != null) { if (req.SizeLinear > 125) { BoundingBox rbox = new BoundingBox((Vector3)minInLod * lodVoxelSize, (Vector3)maxInLod * lodVoxelSize); PrepareRulesForBoxInternal(ref rbox); } else if (!m_rangeClean || m_providerForRules != this) { CleanRules(); } } Vector3I combinedOffset = -minInLod + req.Offset; Vector3I v = new Vector3I(); for (v.Z = minInLod.Z; v.Z <= maxInLod.Z; ++v.Z) { for (v.Y = minInLod.Y; v.Y <= maxInLod.Y; ++v.Y) { for (v.X = minInLod.X; v.X <= maxInLod.X; ++v.X) { Vector3I coords = v; var write = v + combinedOffset; var writeLinear = target.ComputeLinear(ref write); if ((assignToSurface && target.Material(writeLinear) != 0) || (useContent && target.Content(writeLinear) == 0)) { if (computeOcclusion) { // Prevent empty voxels from affecting occlusion. target.Content(writeLinear, 0); } target.Material(writeLinear, MyVoxelConstants.NULL_MATERIAL); continue; } MyVoxelMaterialDefinition mat = null; byte occlusion = (byte)(computeOcclusion ? 255 : 0); // flag that we want occlusion. Vector3 localPos = coords * lodVoxelSize; mat = GetMaterialForPosition(ref localPos, lodVoxelSize, out biome, ref occlusion); if (mat == null) { mat = MyDefinitionManager.Static.GetVoxelMaterialDefinition(0); } target.Material(writeLinear, mat.Index); if (computeOcclusion) { target[MyStorageDataTypeEnum.Occlusion][writeLinear] = occlusion; } } } } ProfilerShort.End(); }
internal void ReadContentRange(ref MyVoxelDataRequest req) { if (Closed) { return; } float lodVoxelSize = (1 << req.Lod) * MyVoxelConstants.VOXEL_SIZE_IN_METRES; Vector3I min = req.minInLod; Vector3I max = req.maxInLod; ProfilerShort.Begin("Distance field computation"); try { Vector3I v = min; Vector3 localPos = v * lodVoxelSize - m_translation; Vector3 localPosStart = localPos; BoundingBox request = new BoundingBox(localPos, localPos + (max - min) * lodVoxelSize); request.Inflate(lodVoxelSize); MyVoxelRequestFlags flags = 0; ContainmentType cont = ContainmentType.Intersects; bool intersects; if (!req.Flags.HasFlags(MyVoxelRequestFlags.DoNotCheck)) { BoundingSphere sphere = new BoundingSphere( Vector3.Zero, OuterRadius + lodVoxelSize); sphere.Intersects(ref request, out intersects); if (!intersects) { cont = ContainmentType.Disjoint; goto end; } sphere.Radius = InnerRadius - lodVoxelSize; ContainmentType ct; sphere.Contains(ref request, out ct); if (ct == ContainmentType.Contains) { cont = ct; goto end; } cont = IntersectBoundingBoxInternal(ref request, lodVoxelSize); if (cont != ContainmentType.Intersects) { goto end; } } bool hit = false; // store request history EnqueueHistory(req); // Setup cache for current map; PrepareCache(); var writeOffsetLoc = req.Offset - min; for (v.Z = min.Z; v.Z <= max.Z; ++v.Z) { for (v.Y = min.Y; v.Y <= max.Y; ++v.Y) { v.X = min.X; var write2 = v + writeOffsetLoc; var write = req.Target.ComputeLinear(ref write2); for (; v.X <= max.X; ++v.X) { float signedDist = SignedDistanceLocal(localPos, lodVoxelSize) / lodVoxelSize; var fillRatio = MathHelper.Clamp(-signedDist, -1f, 1f) * 0.5f + 0.5f; byte content = (byte)(fillRatio * MyVoxelConstants.VOXEL_CONTENT_FULL); if (content != 0) { hit = true; } req.Target.Content(write, content); write += req.Target.StepLinear; localPos.X += lodVoxelSize; } localPos.Y += lodVoxelSize; localPos.X = localPosStart.X; } localPos.Z += lodVoxelSize; localPos.Y = localPosStart.Y; } if (!hit) { PruningStats.Miss(); } else { PruningStats.Hit(); } CullStats.Miss(); return; end :; CullStats.Hit(); if (cont == ContainmentType.Disjoint) { if (req.RequestFlags.HasFlags(MyVoxelRequestFlags.ContentChecked)) { flags |= MyVoxelRequestFlags.EmptyContent | MyVoxelRequestFlags.ContentCheckedDeep | MyVoxelRequestFlags.ContentChecked; } else { req.Target.BlockFillContent(req.Offset, req.Offset + max - min, MyVoxelConstants.VOXEL_CONTENT_EMPTY); } } else if (cont == ContainmentType.Contains) { if (req.RequestFlags.HasFlags(MyVoxelRequestFlags.ContentChecked)) { flags |= MyVoxelRequestFlags.FullContent | MyVoxelRequestFlags.ContentCheckedDeep | MyVoxelRequestFlags.ContentChecked; } else { req.Target.BlockFillContent(req.Offset, req.Offset + max - min, MyVoxelConstants.VOXEL_CONTENT_FULL); } } req.Flags = flags; PruningStats.Hit(); } finally { ProfilerShort.End(); } }
private void ReadFromProvider(MyStorageData target, MyStorageDataTypeFlags types, ref Vector3I writeOffset, int lodIndex, ref Vector3I min, ref Vector3I max, ref MyVoxelRequestFlags flags) { ProfilerShort.Begin("MyProviderLeaf.ReadRange"); MyVoxelDataRequest req = new MyVoxelDataRequest() { Target = target, Offset = writeOffset, Lod = lodIndex, minInLod = min, maxInLod = max, RequestFlags = flags, RequestedData = types }; DataProvider.ReadRange(ref req); flags = req.Flags; ProfilerShort.End(); }