Ejemplo n.º 1
0
        /// <summary>
        /// Gets all cubes which are affected by bone.
        /// </summary>
        /// <param name="onlyExisting">Returns only cubes which were added to skeleton.</param>
        public void GetAffectedCubes(Vector3I cube, Vector3I boneOffset, List <Vector3I> resultList, MyCubeGrid grid)
        {
            Debug.Assert(BoneDensity == 2, "This algorithm requires BoneDensity to be 2");

            Vector3I dist = boneOffset - Vector3I.One;
            Vector3I sign = Vector3I.Sign(dist);

            dist *= sign;

            Vector3I offset;

            for (offset.X = 0; offset.X <= dist.X; offset.X++)
            {
                for (offset.Y = 0; offset.Y <= dist.Y; offset.Y++)
                {
                    for (offset.Z = 0; offset.Z <= dist.Z; offset.Z++)
                    {
                        var targetCube = cube + offset * sign;
                        if (grid.CubeExists(targetCube))
                        {
                            resultList.Add(targetCube);
                        }
                    }
                }
            }
        }
Ejemplo n.º 2
0
        public static void ComputeSteps(Vector3I start, Vector3I end, Vector3I rotatedSize, out Vector3I stepDelta, out Vector3I counter, out int stepCount)
        {
            var offset = end - start;

            stepDelta = Vector3I.Sign(offset) * rotatedSize;
            counter   = Vector3I.Abs(end - start) / rotatedSize + Vector3I.One;
            stepCount = counter.Size;
        }
Ejemplo n.º 3
0
        public static void ComputeSteps(Vector3I start, Vector3I end, Vector3I rotatedSize, out Vector3I stepDelta, out Vector3I counter, out int stepCount)
        {
            Vector3I vectori = end - start;

            stepDelta = Vector3I.Sign(vectori) * rotatedSize;
            counter   = (Vector3I)((Vector3I.Abs(end - start) / rotatedSize) + Vector3I.One);
            stepCount = counter.Size;
        }
Ejemplo n.º 4
0
        protected bool GetCubeAddAndRemovePositions(Vector3I intersectedCube, bool placingSmallGridOnLargeStatic, out Vector3I addPos, out Vector3I addDir, out Vector3I removePos)
        {
            bool result = false;

            addPos    = new Vector3I();
            addDir    = new Vector3I();
            removePos = new Vector3I();

            MatrixD worldInv = MatrixD.Invert(CurrentGrid.WorldMatrix);

            Vector3D intersectionPos;

            addPos = intersectedCube;
            addDir = Vector3I.Forward;

            Vector3D rayStart = Vector3D.Transform(IntersectionStart, worldInv);
            Vector3D rayDir   = Vector3D.Normalize(Vector3D.TransformNormal(IntersectionDirection, worldInv));

            RayD r = new RayD(rayStart, rayDir);

            for (int i = 0; i < 100; ++i) // Limit iterations to 100
            {
                var cubeBb = GetCubeBoundingBox(addPos);
                if (!placingSmallGridOnLargeStatic && cubeBb.Contains(rayStart) == ContainmentType.Contains)
                {
                    break;
                }

                double?dist = cubeBb.Intersects(r);
                if (!dist.HasValue)
                {
                    break;
                }

                removePos = addPos;

                intersectionPos = rayStart + rayDir * dist.Value;
                Vector3  center = removePos * CurrentGrid.GridSize;
                Vector3I dirInt = Vector3I.Sign(Vector3.DominantAxisProjection(intersectionPos - center));

                addPos = removePos + dirInt;
                addDir = dirInt;
                result = true;

                if (!CurrentGrid.CubeExists(addPos))
                {
                    break;
                }
            }

            Debug.Assert(!result || addDir != Vector3I.Zero, "Direction vector cannot be zero");
            return(result);
        }
Ejemplo n.º 5
0
        protected bool GetCubeAddAndRemovePositions(Vector3I intersectedCube, bool placingSmallGridOnLargeStatic, out Vector3I addPos, out Vector3I addDir, out Vector3I removePos)
        {
            bool flag = false;

            addPos    = new Vector3I();
            addDir    = new Vector3I();
            removePos = new Vector3I();
            MatrixD worldMatrixInvScaled = this.CurrentGrid.PositionComp.WorldMatrixInvScaled;

            addPos = intersectedCube;
            addDir = Vector3I.Forward;
            Vector3D position  = Vector3D.Transform(IntersectionStart, worldMatrixInvScaled);
            Vector3D direction = Vector3D.Normalize(Vector3D.TransformNormal(IntersectionDirection, worldMatrixInvScaled));
            RayD     ray       = new RayD(position, direction);
            int      num       = 0;

            while (true)
            {
                if (num < 100)
                {
                    BoundingBoxD cubeBoundingBox = this.GetCubeBoundingBox(addPos);
                    if (placingSmallGridOnLargeStatic || (cubeBoundingBox.Contains(position) != ContainmentType.Contains))
                    {
                        double?nullable = cubeBoundingBox.Intersects(ray);
                        if (nullable != null)
                        {
                            removePos = addPos;
                            Vector3I vectori = Vector3I.Sign(Vector3.DominantAxisProjection((Vector3)((position + (direction * nullable.Value)) - (removePos * this.CurrentGrid.GridSize))));
                            addPos = (Vector3I)(removePos + vectori);
                            addDir = vectori;
                            if (this.CurrentGrid.CubeExists(addPos))
                            {
                                num++;
                                continue;
                            }
                            flag = true;
                        }
                    }
                }
                return(flag);
            }
        }
        // Math magic by Whiplash
        internal static void BresenhamLineDraw(Vector3I start, Vector3I end, List <Vector3I> points)
        {
            points.Clear();
            points.Add(start);
            Vector3I delta = end - start;
            Vector3I step  = Vector3I.Sign(delta);

            delta *= step;
            int max = delta.AbsMax();

            if (max == delta.X)
            {
                int p1 = 2 * delta.Y - delta.X;
                int p2 = 2 * delta.Z - delta.X;
                while (start.X != end.X)
                {
                    start.X += step.X;
                    if (p1 >= 0)
                    {
                        start.Y += step.Y;
                        p1      -= 2 * delta.X;
                    }

                    if (p2 >= 0)
                    {
                        start.Z += step.Z;
                        p2      -= 2 * delta.X;
                    }
                    p1 += 2 * delta.Y;
                    p2 += 2 * delta.Z;
                    points.Add(start);
                }
            }
            else if (max == delta.Y)
            {
                int p1 = 2 * delta.X - delta.Y;
                int p2 = 2 * delta.Z - delta.Y;
                while (start.Y != end.Y)
                {
                    start.Y += step.Y;
                    if (p1 >= 0)
                    {
                        start.X += step.X;
                        p1      -= 2 * delta.Y;
                    }

                    if (p2 >= 0)
                    {
                        start.Z += step.Z;
                        p2      -= 2 * delta.Y;
                    }
                    p1 += 2 * delta.X;
                    p2 += 2 * delta.Z;
                    points.Add(start);
                }
            }
            else
            {
                int p1 = 2 * delta.X - delta.Z;
                int p2 = 2 * delta.Y - delta.Z;
                while (start.Z != end.Z)
                {
                    start.Z += step.Z;
                    if (p1 >= 0)
                    {
                        start.X += step.X;
                        p1      -= 2 * delta.Z;
                    }

                    if (p2 >= 0)
                    {
                        start.Y += step.Y;
                        p2      -= 2 * delta.Z;
                    }
                    p1 += 2 * delta.X;
                    p2 += 2 * delta.Y;
                    points.Add(start);
                }
            }
        }
Ejemplo n.º 7
0
        internal static bool BresenhamGridIntersection(MyCubeGrid grid, ref Vector3D worldStart, ref Vector3D worldEnd, out Vector3D?hitPos, MyCubeBlock weapon = null, GridAi ai = null)
        {
            var      start = grid.WorldToGridInteger(worldStart);
            var      end   = grid.WorldToGridInteger(worldEnd);
            Vector3I delta = end - start;
            Vector3I step  = Vector3I.Sign(delta);

            delta *= step;
            int max = delta.AbsMax();

            hitPos = null;

            var gMinX = grid.Min.X;
            var gMinY = grid.Min.Y;
            var gMinZ = grid.Min.Z;
            var gMaxX = grid.Max.X;
            var gMaxY = grid.Max.Y;
            var gMaxZ = grid.Max.Z;

            if (ai != null)
            {
                var dir        = (worldEnd - worldStart);
                var ray        = new RayD(ref worldStart, ref dir);
                var gridMatrix = ai.MyGrid.PositionComp.WorldMatrixRef;

                foreach (var sub in ai.SubGrids)
                {
                    if (sub == grid)
                    {
                        continue;
                    }
                    var subDist = sub.PositionComp.WorldVolume.Intersects(ray);
                    if (subDist.HasValue)
                    {
                        //var rotMatrix = Quaternion.CreateFromRotationMatrix(ai.MyGrid.WorldMatrix);
                        //var obb = new MyOrientedBoundingBoxD(ai.MyGrid.PositionComp.WorldAABB.Center, ai.MyGrid.PositionComp.LocalAABB.HalfExtents, rotMatrix);
                        var box = ai.MyGrid.PositionComp.LocalAABB;
                        var obb = new MyOrientedBoundingBoxD(box, gridMatrix);

                        Vector3D?ignoreHit;
                        if (obb.Intersects(ref ray) != null && BresenhamGridIntersection(sub, ref worldStart, ref worldEnd, out ignoreHit, weapon))
                        {
                            return(true);
                        }
                    }
                }
            }

            if (max == delta.X)
            {
                int p1 = 2 * delta.Y - delta.X;
                int p2 = 2 * delta.Z - delta.X;
                while (start.X != end.X)
                {
                    start.X += step.X;
                    if (p1 >= 0)
                    {
                        start.Y += step.Y;
                        p1      -= 2 * delta.X;
                    }

                    if (p2 >= 0)
                    {
                        start.Z += step.Z;
                        p2      -= 2 * delta.X;
                    }
                    p1 += 2 * delta.Y;
                    p2 += 2 * delta.Z;
                    var contained = gMinX <= start.X && start.X <= gMaxX && (gMinY <= start.Y && start.Y <= gMaxY) && (gMinZ <= start.Z && start.Z <= gMaxZ);
                    if (!contained)
                    {
                        return(false);
                    }

                    MyCube cube;
                    if (grid.TryGetCube(start, out cube) && cube.CubeBlock != weapon?.SlimBlock)
                    {
                        return(true);
                    }
                }
            }
            else if (max == delta.Y)
            {
                int p1 = 2 * delta.X - delta.Y;
                int p2 = 2 * delta.Z - delta.Y;
                while (start.Y != end.Y)
                {
                    start.Y += step.Y;
                    if (p1 >= 0)
                    {
                        start.X += step.X;
                        p1      -= 2 * delta.Y;
                    }

                    if (p2 >= 0)
                    {
                        start.Z += step.Z;
                        p2      -= 2 * delta.Y;
                    }
                    p1 += 2 * delta.X;
                    p2 += 2 * delta.Z;

                    var contained = gMinX <= start.X && start.X <= gMaxX && (gMinY <= start.Y && start.Y <= gMaxY) && (gMinZ <= start.Z && start.Z <= gMaxZ);
                    if (!contained)
                    {
                        return(false);
                    }

                    MyCube cube;
                    if (grid.TryGetCube(start, out cube) && cube.CubeBlock != weapon?.SlimBlock)
                    {
                        return(true);
                    }
                }
            }
            else
            {
                int p1 = 2 * delta.X - delta.Z;
                int p2 = 2 * delta.Y - delta.Z;
                while (start.Z != end.Z)
                {
                    start.Z += step.Z;
                    if (p1 >= 0)
                    {
                        start.X += step.X;
                        p1      -= 2 * delta.Z;
                    }

                    if (p2 >= 0)
                    {
                        start.Y += step.Y;
                        p2      -= 2 * delta.Z;
                    }
                    p1 += 2 * delta.X;
                    p2 += 2 * delta.Y;

                    var contained = gMinX <= start.X && start.X <= gMaxX && (gMinY <= start.Y && start.Y <= gMaxY) && (gMinZ <= start.Z && start.Z <= gMaxZ);
                    if (!contained)
                    {
                        return(false);
                    }

                    MyCube cube;
                    if (grid.TryGetCube(start, out cube) && cube.CubeBlock != weapon?.SlimBlock)
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
Ejemplo n.º 8
0
            public void Init(IMyCubeBlock startBlock, IMyCubeBlock endBlock)
            {
                IMyCubeGrid cubeGrid = startBlock.CubeGrid;
                Vector3I    start    = startBlock.Position;
                Vector3I    end      = endBlock.Position;
                Vector3I    size     = (Vector3I.Max(start, end) - Vector3I.Min(start, end)) + Vector3I.One;

                if (size.X != 1 && size.Y != 1 && size.Z != 1)
                {
                    throw new Exception("Blocks must be on a consistent plane.");
                }

                List <List <T> > rows = new List <List <T> >();
                Vector3I         inc  = Vector3I.Sign(end - start);
                Vector3I         v    = start;

                end += inc;
                int colSize = 0;

                if (inc.X == 0)
                {
                    for (v.Y = start.Y; v.Y != end.Y; v.Y += inc.Y)
                    {
                        List <T> col = new List <T>();
                        for (v.Z = start.Z; v.Z != end.Z; v.Z += inc.Z)
                        {
                            IMyCubeBlock temp = cubeGrid.GetCubeBlock(v)?.FatBlock;
                            if (temp is T && temp.Position == v)
                            {
                                T   b = (T)temp;
                                int y = (v.Z - start.Z) * inc.Z;
                                if (col.Count >= y)
                                {
                                    col.Add(b);
                                }
                                else
                                {
                                    col [y] = b;
                                }
                                //this.grid [coords.Y, coords.Z] = b;
                            }
                        }
                        colSize = Math.Max(col.Count, colSize);
                        int x = (v.Y - start.Y) * inc.Y;
                        if (rows.Count >= x)
                        {
                            rows.Add(col);
                        }
                        else
                        {
                            rows [x] = col;
                        }
                    }
                }
                else if (inc.Y == 0)
                {
                    for (v.X = start.X; v.X != end.X; v.X += inc.X)
                    {
                        List <T> col = new List <T>();
                        for (v.Z = start.Z; v.Z != end.Z; v.Z += inc.Z)
                        {
                            IMyCubeBlock temp = cubeGrid.GetCubeBlock(v)?.FatBlock;
                            if (temp is T && temp.Position == v)
                            {
                                T   b = (T)temp;
                                int y = (v.Z - start.Z) * inc.Z;
                                if (col.Count >= y)
                                {
                                    col.Add(b);
                                }
                                else
                                {
                                    col [y] = b;
                                }
                                //Vector3I coords = (v - start) * inc;
                                //this.grid [coords.X, coords.Z] = b;
                            }
                        }
                        colSize = Math.Max(col.Count, colSize);
                        int x = (v.X - start.X) * inc.X;
                        if (rows.Count >= x)
                        {
                            rows.Add(col);
                        }
                        else
                        {
                            rows [x] = col;
                        }
                    }
                }
                else
                {
                    for (v.X = start.X; v.X != end.X; v.X += inc.X)
                    {
                        List <T> col = new List <T>();
                        for (v.Y = start.Y; v.Y != end.Y; v.Y += inc.Y)
                        {
                            IMyCubeBlock temp = cubeGrid.GetCubeBlock(v)?.FatBlock;
                            if (temp is T && temp.Position == v)
                            {
                                T   b = (T)temp;
                                int y = (v.Y - start.Y) * inc.Y;
                                if (col.Count >= y)
                                {
                                    col.Add(b);
                                }
                                else
                                {
                                    col [y] = b;
                                }
                                //Vector3I coords = (v - start) * inc;
                                //this.grid [coords.X, coords.Y] = b;
                            }
                        }
                        colSize = Math.Max(col.Count, colSize);
                        int x = (v.X - start.X) * inc.X;
                        if (rows.Count >= x)
                        {
                            rows.Add(col);
                        }
                        else
                        {
                            rows [x] = col;
                        }
                    }
                }

                if (colSize == 0)
                {
                    throw new Exception("No blocks found.");
                }

                grid = new T [rows.Count, colSize];

                //StringBuilder sb = new StringBuilder();
                for (int y = 0; y < grid.GetLength(1); y++)
                {
                    for (int x = 0; x < grid.GetLength(0); x++)
                    {
                        List <T> col = rows [x];
                        if (y < col.Count)
                        {
                            grid [x, y] = col [y];
                        }
                        //if (block == null)
                        //    sb.Append("null ");
                        //else
                        //    sb.Append(block.CustomName).Append(' ');
                    }
                    //sb.AppendLine();
                }
                //me.GetSurface(0).WriteText(sb);

                Size = new Vector2I(grid.GetLength(0), grid.GetLength(1));
            }