示例#1
0
        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);
        }
示例#2
0
        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);
        }
示例#3
0
        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();
        }
示例#4
0
 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);
     }
 }
示例#5
0
        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;
        }
示例#6
0
 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);
         }
     }
 }
示例#7
0
        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();
        }
示例#10
0
        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);
                }
            }
        }
示例#15
0
        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();
        }
        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();
            }
        }
示例#18
0
        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();
        }
示例#19
0
        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();
        }