Пример #1
0
        public static void ChangeMaterialInBoxRelative(MyVoxelMap voxelMap, Vector3 relativeMin, Vector3 relativeMax, MyMwcVoxelMaterialsEnum material)
        {
            BoundingBox boundingBox = voxelMap.WorldAABB;

            //  Get min and max cell coordinate where camera bounding box can fit
            MyMwcVector3Int cellCoordMin = voxelMap.GetVoxelCoordinateFromMeters(boundingBox.Min);
            MyMwcVector3Int cellCoordMax = voxelMap.GetVoxelCoordinateFromMeters(boundingBox.Max);

            //  Fix min and max cell coordinates so they don't overlap the voxelmap
            voxelMap.FixVoxelCoord(ref cellCoordMin);
            voxelMap.FixVoxelCoord(ref cellCoordMax);

            cellCoordMin.X = (int)(cellCoordMax.X * relativeMin.X);
            cellCoordMin.Y = (int)(cellCoordMax.Y * relativeMin.Y);
            cellCoordMin.Z = (int)(cellCoordMax.Z * relativeMin.Z);

            cellCoordMax.X = (int)(cellCoordMax.X * relativeMax.X);
            cellCoordMax.Y = (int)(cellCoordMax.Y * relativeMax.Y);
            cellCoordMax.Z = (int)(cellCoordMax.Z * relativeMax.Z);

            MyMwcVector3Int cellCoord;

            for (cellCoord.X = cellCoordMin.X; cellCoord.X <= cellCoordMax.X; cellCoord.X++)
            {
                for (cellCoord.Y = cellCoordMin.Y; cellCoord.Y <= cellCoordMax.Y; cellCoord.Y++)
                {
                    for (cellCoord.Z = cellCoordMin.Z; cellCoord.Z <= cellCoordMax.Z; cellCoord.Z++)
                    {
                        voxelMap.SetVoxelMaterialAndIndestructibleContent(material, 0, ref cellCoord);
                    }
                }
            }

            voxelMap.InvalidateCache(cellCoordMin, cellCoordMax);
            voxelMap.CalcAverageDataCellMaterials();

            //MyVoxelMaps.RecalcVoxelMaps();
        }
Пример #2
0
        } //CreateCylinder


        public static void CutOutCylinder(MyVoxelMap voxelMap, float radius1, float radius2, MyOrientedBoundingBox box, MyMwcVoxelMaterialsEnum? material, ref bool changed)
        {
            //box.HalfExtent x = radius1
            //box.HalfExtent y = length/2
            //box.HalfExtent z = radius2


            BoundingBox aabb = box.GetAABB();

            MyMwcVector3Int minCorner = voxelMap.GetVoxelCoordinateFromMeters(aabb.Min - new Vector3(MyVoxelConstants.VOXEL_SIZE_IN_METRES));
            MyMwcVector3Int maxCorner = voxelMap.GetVoxelCoordinateFromMeters(aabb.Max + new Vector3(MyVoxelConstants.VOXEL_SIZE_IN_METRES));

            voxelMap.FixVoxelCoord(ref minCorner);
            voxelMap.FixVoxelCoord(ref maxCorner);

            MyMwcVector3Int tempVoxelCoord;
            for (tempVoxelCoord.X = minCorner.X; tempVoxelCoord.X <= maxCorner.X; tempVoxelCoord.X++)
            {
                for (tempVoxelCoord.Y = minCorner.Y; tempVoxelCoord.Y <= maxCorner.Y; tempVoxelCoord.Y++)
                {
                    for (tempVoxelCoord.Z = minCorner.Z; tempVoxelCoord.Z <= maxCorner.Z; tempVoxelCoord.Z++)
                    {
                        Vector3 position = voxelMap.GetVoxelCenterPositionAbsolute(ref tempVoxelCoord);

                        //BoundingBox voxelAABB = new BoundingBox(position - new Vector3(MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF), position + new Vector3(MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF));

                        byte newContent = 0;

                        // Transform the point into box-local space and check against
                        // our extents.
                        Quaternion qinv = Quaternion.Conjugate(box.Orientation);
                        Vector3 plocal = Vector3.Transform(position - box.Center, qinv);

                        //MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF 

                        float distY = 0;
                        int sY = System.Math.Sign(plocal.Y);

                        if (sY > 0)
                        {
                            distY = plocal.Y - box.HalfExtent.Y;
                        }
                        else
                        {
                            distY = plocal.Y + box.HalfExtent.Y;
                        }

                        float distRatio = 1;
                        distRatio = MathHelper.Clamp((plocal.Y + box.HalfExtent.Y) / (2 * box.HalfExtent.Y), 0, 1);

                        int contentY = -1;

                        if (sY > 0)
                        {
                            if (distY > MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                            {
                                contentY = MyVoxelConstants.VOXEL_CONTENT_FULL;
                            }
                            else if (distY < -MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                            {
                                contentY = MyVoxelConstants.VOXEL_CONTENT_EMPTY;
                            }
                            else
                            {
                                //  This formula will work even if diff is positive or negative
                                //contentY = (byte)(MyVoxelConstants.VOXEL_ISO_LEVEL - distY / MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * MyVoxelConstants.VOXEL_ISO_LEVEL);
                                contentY = MyVoxelConstants.VOXEL_CONTENT_FULL - (byte)(MyVoxelConstants.VOXEL_ISO_LEVEL - distY / MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * MyVoxelConstants.VOXEL_ISO_LEVEL);
                            }
                        }
                        else
                        {
                            if (distY < -MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                            {
                                contentY = MyVoxelConstants.VOXEL_CONTENT_FULL;
                            }
                            else if (distY > MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                            {
                                contentY = MyVoxelConstants.VOXEL_CONTENT_EMPTY;
                            }
                            else
                            {
                                //  This formula will work even if diff is positive or negative
                                //contentY = MyVoxelConstants.VOXEL_CONTENT_FULL - (byte)(MyVoxelConstants.VOXEL_ISO_LEVEL - distY / MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * MyVoxelConstants.VOXEL_ISO_LEVEL);
                                contentY = (byte)(MyVoxelConstants.VOXEL_ISO_LEVEL - distY / MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * MyVoxelConstants.VOXEL_ISO_LEVEL);
                            }
                        }


                        Matrix boxMatrix = Matrix.CreateFromQuaternion(box.Orientation);
                        Vector3 hY1 = box.Center + boxMatrix.Up * box.HalfExtent.Y;
                        Vector3 hY2 = box.Center + boxMatrix.Down * box.HalfExtent.Y;

                        float dist = MyUtils.GetPointLineDistance(ref hY1, ref hY2, ref position);
                        float diff = dist - MathHelper.Lerp(radius2, radius1, distRatio);
                        //float diff = dist - box.HalfExtent.Z;

                        byte newContent2;
                        if (diff > MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                        {
                            newContent2 = MyVoxelConstants.VOXEL_CONTENT_FULL;
                        }
                        else if (diff < -MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                        {
                            newContent2 = MyVoxelConstants.VOXEL_CONTENT_EMPTY;
                        }
                        else
                        {
                            //  This formula will work even if diff is positive or negative
                            //newContent2 = (byte)(MyVoxelConstants.VOXEL_ISO_LEVEL - diff / MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * MyVoxelConstants.VOXEL_ISO_LEVEL);
                            newContent2 = (byte)(MyVoxelConstants.VOXEL_CONTENT_FULL - (int)(MyVoxelConstants.VOXEL_ISO_LEVEL - diff / MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * MyVoxelConstants.VOXEL_ISO_LEVEL));
                        }


                        newContent = (byte)System.Math.Max(contentY, newContent2);
                        //newContent = (byte)contentY; 

                        byte originalContent = voxelMap.GetVoxelContent(ref tempVoxelCoord);

                        if (newContent < originalContent)
                        {
                            voxelMap.SetVoxelContent(newContent, ref tempVoxelCoord);
                            if (material.HasValue)
                                voxelMap.SetVoxelMaterialAndIndestructibleContent(material.Value, 0, ref tempVoxelCoord);
                        }

                    }
                }
            }

            voxelMap.InvalidateCache(minCorner, maxCorner);
            voxelMap.CalcAverageDataCellMaterials();

        } //CutoutCylinder
Пример #3
0
        } //Create Cuboid


        public static void CutOutCuboid(MyVoxelMap voxelMap, MyCuboid cuboid, MyMwcVoxelMaterialsEnum? material)
        {
            BoundingBox aabb = cuboid.GetAABB();


            MyMwcVector3Int minCorner = voxelMap.GetVoxelCoordinateFromMeters(aabb.Min - new Vector3(MyVoxelConstants.VOXEL_SIZE_IN_METRES));
            MyMwcVector3Int maxCorner = voxelMap.GetVoxelCoordinateFromMeters(aabb.Max + new Vector3(MyVoxelConstants.VOXEL_SIZE_IN_METRES));

            voxelMap.FixVoxelCoord(ref minCorner);
            voxelMap.FixVoxelCoord(ref maxCorner);

            MyMwcVector3Int tempVoxelCoord;
            for (tempVoxelCoord.X = minCorner.X; tempVoxelCoord.X <= maxCorner.X; tempVoxelCoord.X++)
            {
                for (tempVoxelCoord.Y = minCorner.Y; tempVoxelCoord.Y <= maxCorner.Y; tempVoxelCoord.Y++)
                {
                    for (tempVoxelCoord.Z = minCorner.Z; tempVoxelCoord.Z <= maxCorner.Z; tempVoxelCoord.Z++)
                    {
                        Vector3 position = voxelMap.GetVoxelCenterPositionAbsolute(ref tempVoxelCoord);
                        BoundingBox voxelAABB = new BoundingBox(position - new Vector3(MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF), position + new Vector3(MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF));

                        bool isInside = true;

                        for (int i = 0; i < cuboid.Sides.Length; i++)
                        {
                            MyPlane side = cuboid.Sides[i].Plane;
                            float distance = MyUtils.GetDistanceFromPointToPlane(ref position, ref side);
                            if (distance > 0)
                            {
                                isInside = false;
                                break;
                            }
                        }

                        float minDistance = float.MaxValue;

                        for (int i = 0; i < cuboid.Sides.Length; i++)
                        {
                            MyQuad quad = new MyQuad();
                            quad.Point0 = cuboid.Sides[i].Lines[0].From;
                            quad.Point1 = cuboid.Sides[i].Lines[1].From;
                            quad.Point2 = cuboid.Sides[i].Lines[3].From;
                            quad.Point3 = cuboid.Sides[i].Lines[2].From;

                            float distance = MyUtils.GetDistancePointToQuad(ref position, ref quad);
                            if (distance < minDistance)
                            {
                                minDistance = distance;
                            }
                        }


                        byte newContent = 0;


                        if (isInside)
                        {
                            if (minDistance > MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                            {
                                newContent = MyVoxelConstants.VOXEL_CONTENT_EMPTY;
                            }
                            else
                            {
                                //  This formula will work even if diff is positive or negative
                                //newContent = MyVoxelConstants.VOXEL_CONTENT_EMPTY;
                                newContent = (byte)(MyVoxelConstants.VOXEL_ISO_LEVEL - minDistance / MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * MyVoxelConstants.VOXEL_ISO_LEVEL);
                                //newContent = (byte)(MyVoxelConstants.VOXEL_CONTENT_FULL - (byte)(MyVoxelConstants.VOXEL_ISO_LEVEL - minDistance / MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * MyVoxelConstants.VOXEL_ISO_LEVEL));
                            }
                        }
                        else
                        {
                            if (minDistance > MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                            {
                                newContent = MyVoxelConstants.VOXEL_CONTENT_FULL;
                            }
                            else
                            {
                                //newContent = MyVoxelConstants.VOXEL_CONTENT_FULL;
                                //  This formula will work even if diff is positive or negative
                                //newContent = (byte)(MyVoxelConstants.VOXEL_ISO_LEVEL - minDistance / MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * MyVoxelConstants.VOXEL_ISO_LEVEL);
                                newContent = (byte)(MyVoxelConstants.VOXEL_CONTENT_FULL - (byte)(MyVoxelConstants.VOXEL_ISO_LEVEL - minDistance / MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * MyVoxelConstants.VOXEL_ISO_LEVEL));
                            }
                        }

                        byte originalContent = voxelMap.GetVoxelContent(ref tempVoxelCoord);

                        if (newContent < originalContent)
                        {
                            voxelMap.SetVoxelContent(newContent, ref tempVoxelCoord);
                            if (material.HasValue)
                                voxelMap.SetVoxelMaterialAndIndestructibleContent(material.Value, 0, ref tempVoxelCoord);
                        }
                    }
                }
            }

            voxelMap.InvalidateCache(minCorner, maxCorner);
            voxelMap.CalcAverageDataCellMaterials();
        } //CutOut Cuboid
Пример #4
0
        public static void CutOutOrientedBox(MyVoxelMap voxelMap, MyOrientedBoundingBox box, ref bool changed)
        {
            BoundingBox aabb = box.GetAABB();

            MyMwcVector3Int minCorner = voxelMap.GetVoxelCoordinateFromMeters(aabb.Min - new Vector3(MyVoxelConstants.VOXEL_SIZE_IN_METRES));
            MyMwcVector3Int maxCorner = voxelMap.GetVoxelCoordinateFromMeters(aabb.Max + new Vector3(MyVoxelConstants.VOXEL_SIZE_IN_METRES));

            voxelMap.FixVoxelCoord(ref minCorner);
            voxelMap.FixVoxelCoord(ref maxCorner);

            System.Threading.Tasks.Parallel.For(minCorner.X, maxCorner.X, i =>
                {
                    System.Threading.Tasks.Parallel.For(minCorner.Y, maxCorner.Y, j =>
                        {
                            System.Threading.Tasks.Parallel.For(minCorner.Z, maxCorner.Z, k =>
                            {
                                MyMwcVector3Int tempVoxelCoord = new MyMwcVector3Int(i, j, k);
                                Vector3 position = voxelMap.GetVoxelCenterPositionAbsolute(ref tempVoxelCoord);
                                BoundingBox voxelAABB = new BoundingBox(position - new Vector3(MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF), position + new Vector3(MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF));

                                byte newContent = 0;
                                ContainmentType ct = box.Contains(ref voxelAABB);
                                if (ct == ContainmentType.Contains)
                                {
                                    newContent = MyVoxelConstants.VOXEL_CONTENT_EMPTY;
                                }
                                else
                                    if (ct == ContainmentType.Disjoint)
                                    {
                                        newContent = MyVoxelConstants.VOXEL_CONTENT_FULL;
                                    }
                                    else
                                    {

                                        // Transform the point into box-local space and check against
                                        // our extents.
                                        Quaternion qinv = Quaternion.Conjugate(box.Orientation);
                                        Vector3 plocal = Vector3.Transform(position - box.Center, qinv);

                                        //MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF 

                                        float distX = 0;
                                        float distY = 0;
                                        float distZ = 0;

                                        int sX = System.Math.Sign(plocal.X);
                                        int sY = System.Math.Sign(plocal.Y);
                                        int sZ = System.Math.Sign(plocal.Z);

                                        if (sX > 0)
                                        {
                                            distX = plocal.X - box.HalfExtent.X;
                                        }
                                        else
                                        {
                                            distX = plocal.X + box.HalfExtent.X;
                                        }

                                        if (sY > 0)
                                        {
                                            distY = plocal.Y - box.HalfExtent.Y;
                                        }
                                        else
                                        {
                                            distY = plocal.Y + box.HalfExtent.Y;
                                        }

                                        if (sZ > 0)
                                        {
                                            distZ = plocal.Z - box.HalfExtent.Z;
                                        }
                                        else
                                        {
                                            distZ = plocal.Z + box.HalfExtent.Z;
                                        }

                                        //float diff = (distX + distY + distZ) / 3;
                                        //float diff = (sX*sY*sZ) * System.Math.Min(System.Math.Min(distX,distY), distZ);

                                        int contentX;
                                        int contentY;
                                        int contentZ;

                                        if (sX < 0)
                                        {
                                            if (distX > MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                                            {
                                                contentX = MyVoxelConstants.VOXEL_CONTENT_EMPTY;
                                            }
                                            else if (distX < -MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                                            {
                                                contentX = MyVoxelConstants.VOXEL_CONTENT_FULL;
                                            }
                                            else
                                            {
                                                //  This formula will work even if diff is positive or negative
                                                contentX = MyVoxelConstants.VOXEL_CONTENT_FULL - (byte)(MyVoxelConstants.VOXEL_ISO_LEVEL - distX / MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * MyVoxelConstants.VOXEL_ISO_LEVEL);
                                            }
                                        }
                                        else
                                        {
                                            if (distX < -MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                                            {
                                                contentX = MyVoxelConstants.VOXEL_CONTENT_EMPTY;
                                            }
                                            else if (distX > MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                                            {
                                                contentX = MyVoxelConstants.VOXEL_CONTENT_FULL;
                                            }
                                            else
                                            {
                                                //  This formula will work even if diff is positive or negative
                                                contentX = (byte)(MyVoxelConstants.VOXEL_ISO_LEVEL - distX / MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * MyVoxelConstants.VOXEL_ISO_LEVEL);
                                            }
                                        }



                                        if (sY < 0)
                                        {
                                            if (distY > MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                                            {
                                                contentY = MyVoxelConstants.VOXEL_CONTENT_EMPTY;
                                            }
                                            else if (distY < -MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                                            {
                                                contentY = MyVoxelConstants.VOXEL_CONTENT_FULL;
                                            }
                                            else
                                            {
                                                //  This formula will work even if diff is positive or negative
                                                contentY = MyVoxelConstants.VOXEL_CONTENT_FULL - (byte)(MyVoxelConstants.VOXEL_ISO_LEVEL - distY / MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * MyVoxelConstants.VOXEL_ISO_LEVEL);
                                            }
                                        }
                                        else
                                        {
                                            if (distY < -MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                                            {
                                                contentY = MyVoxelConstants.VOXEL_CONTENT_EMPTY;
                                            }
                                            else if (distY > MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                                            {
                                                contentY = MyVoxelConstants.VOXEL_CONTENT_FULL;
                                            }
                                            else
                                            {
                                                //  This formula will work even if diff is positive or negative
                                                contentY = (byte)(MyVoxelConstants.VOXEL_ISO_LEVEL - distY / MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * MyVoxelConstants.VOXEL_ISO_LEVEL);
                                            }
                                        }


                                        if (sZ < 0)
                                        {
                                            if (distZ > MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                                            {
                                                contentZ = MyVoxelConstants.VOXEL_CONTENT_EMPTY;
                                            }
                                            else if (distZ < -MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                                            {
                                                contentZ = MyVoxelConstants.VOXEL_CONTENT_FULL;
                                            }
                                            else
                                            {
                                                //  This formula will work even if diff is positive or negative
                                                contentZ = MyVoxelConstants.VOXEL_CONTENT_FULL - (byte)(MyVoxelConstants.VOXEL_ISO_LEVEL - distZ / MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * MyVoxelConstants.VOXEL_ISO_LEVEL);
                                            }
                                        }
                                        else
                                        {
                                            if (distZ < -MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                                            {
                                                contentZ = MyVoxelConstants.VOXEL_CONTENT_EMPTY;
                                            }
                                            else if (distZ > MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                                            {
                                                contentZ = MyVoxelConstants.VOXEL_CONTENT_FULL;
                                            }
                                            else
                                            {
                                                //  This formula will work even if diff is positive or negative
                                                contentZ = (byte)(MyVoxelConstants.VOXEL_ISO_LEVEL - distZ / MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * MyVoxelConstants.VOXEL_ISO_LEVEL);
                                            }
                                        }

                                        //voxelMap.SetVoxelContent( (byte)((contentX + contentY + contentZ)/3.0f), ref tempVoxelCoord);
                                        newContent = (byte)(System.Math.Min(System.Math.Min(contentX, contentY), contentZ));
                                    }


                                byte originalContent = voxelMap.GetVoxelContent(ref tempVoxelCoord);

                                if (newContent < originalContent)
                                {
                                    voxelMap.SetVoxelContent(newContent, ref tempVoxelCoord, true);
                                    //changed = true;
                                }
                            });
                        });
                });

            /*
            for (tempVoxelCoord.X = minCorner.X; tempVoxelCoord.X <= maxCorner.X; tempVoxelCoord.X++)
            {
                for (tempVoxelCoord.Y = minCorner.Y; tempVoxelCoord.Y <= maxCorner.Y; tempVoxelCoord.Y++)
                {
                    for (tempVoxelCoord.Z = minCorner.Z; tempVoxelCoord.Z <= maxCorner.Z; tempVoxelCoord.Z++)
                    {
                        
                       
                    }
                }
            }*/

            changed = true;
            voxelMap.InvalidateCache(minCorner, maxCorner);
            voxelMap.CalcAverageDataCellMaterials();
        }