Example #1
0
        private string GetDirectionString()
        {
            var cockpit = MySession.ControlledEntity as MyCockpit;

            if (cockpit != null)
            {
                Quaternion cockpitOrientation;
                cockpit.Orientation.GetQuaternion(out cockpitOrientation);
                var thrustDir = Vector3I.Transform(ThrustForwardVector, Quaternion.Inverse(cockpitOrientation));
                if (thrustDir.X == 1)
                {
                    return(MyTexts.GetString(MySpaceTexts.Thrust_Left));
                }
                else if (thrustDir.X == -1)
                {
                    return(MyTexts.GetString(MySpaceTexts.Thrust_Right));
                }
                else if (thrustDir.Y == 1)
                {
                    return(MyTexts.GetString(MySpaceTexts.Thrust_Down));
                }
                else if (thrustDir.Y == -1)
                {
                    return(MyTexts.GetString(MySpaceTexts.Thrust_Up));
                }
                else if (thrustDir.Z == 1)
                {
                    return(MyTexts.GetString(MySpaceTexts.Thrust_Forward));
                }
                else if (thrustDir.Z == -1)
                {
                    return(MyTexts.GetString(MySpaceTexts.Thrust_Back));
                }
            }
            return(null);
        }
        private void CopyTriangle(MyNavigationTriangle otherTri, Vector3I triPosition, ref MatrixI transform)
        {
            Vector3 newA, newB, newC;

            otherTri.GetTransformed(ref transform, out newA, out newB, out newC);

            if (MyFakes.NAVMESH_PRESUMES_DOWNWARD_GRAVITY)
            {
                Vector3 n = Vector3.Cross(newC - newA, newB - newA);
                n.Normalize();
                if (Vector3.Dot(n, Base6Directions.GetVector(Base6Directions.Direction.Up)) < 0.7f)
                {
                    return;                                                                                 // Slightly lower than sqrt(2)/2 = 45 deg
                }
            }

            Vector3I.Transform(ref triPosition, ref transform, out triPosition);

            // This is not an error - we need to swap C and B from the navmesh,
            // because they will be swapped again when the triangle is added
            var tri = AddTriangleInternal(newA, newC, newB);

            RegisterTriangleInternal(tri, ref triPosition);
        }
        private void MergeFromAnotherMesh(MyGridNavigationMesh otherMesh, ref MatrixI transform)
        {
            ProfilerShort.Begin("MergeFromAnotherMesh");
            m_mergeHelper.Clear();

            // Save the cubes from the other mesh that are touching cubes of this mesh into a helper set.
            // Also put the touched cubes from this mesh into the set.
            foreach (var position in otherMesh.m_smallTriangleRegistry.Keys)
            {
                bool add = false;
                foreach (var direction in Base6Directions.IntDirections)
                {
                    // CH: TODO: We query the grid so far, but in the future, we should make sure that the access is thread-safe
                    Vector3I pos = Vector3I.Transform(position + direction, transform);
                    if (m_cubeSet.Contains(ref pos))             // Test the transformed position...
                    {
                        m_mergeHelper.Add(position + direction); // ... but add the original one
                        add = true;
                    }
                }
                if (add)
                {
                    m_mergeHelper.Add(position);
                }
            }

            foreach (var entry in otherMesh.m_smallTriangleRegistry)
            {
                Vector3I originalCube = entry.Key;
                Vector3I tformedCube; Vector3I.Transform(ref originalCube, ref transform, out tformedCube);

                // If the cube is one of the touching cubes, we have to intersect the touching triangles
                if (m_mergeHelper.Contains(originalCube))
                {
                    // Take the touching pairs one by one and calculate triangulation of the disjoint union of the opposing faces
                    // Remove the opposing faces from the old block
                    // Add the triangulation to the mesh
                    // Add the rest of the navmesh from this block to the mesh

                    m_tmpTriangleList.Clear();

                    // CH: TODO. Just remove the triangles now
                    foreach (var direction in Base6Directions.EnumDirections)
                    {
                        Vector3I directionVec = Base6Directions.GetIntVector((int)direction);
                        Base6Directions.Direction tformedDirection = transform.GetDirection(direction);
                        Vector3I tformedFlippedVec = Base6Directions.GetIntVector((int)Base6Directions.GetFlippedDirection(tformedDirection));

                        // Remove face triangles from this mesh
                        if (m_mergeHelper.Contains(originalCube + directionVec))
                        {
                            List <int> triList = null;
                            if (m_smallTriangleRegistry.TryGetValue(tformedCube - tformedFlippedVec, out triList))
                            {
                                foreach (var index in triList)
                                {
                                    var triangle = GetTriangle(index);
                                    // CH: TODO: This will probably be expensive. Could we precalculate it?
                                    if (IsFaceTriangle(triangle, tformedCube - tformedFlippedVec, tformedFlippedVec))
                                    {
                                        m_tmpTriangleList.Add(new KeyValuePair <MyNavigationTriangle, Vector3I>(triangle, tformedCube - tformedFlippedVec));
                                    }
                                }
                            }
                        }
                    }

                    foreach (var triangle in m_tmpTriangleList)
                    {
                        RemoveTriangle(triangle.Key, triangle.Value);
                    }
                    m_tmpTriangleList.Clear();

                    int debugCounter = 0;

                    // CH: TODO: optimize this (actually whole this method)
                    foreach (var triangleIndex in entry.Value)
                    {
                        var      triangle    = otherMesh.GetTriangle(triangleIndex);
                        Vector3I pos         = entry.Key;
                        bool     addTriangle = true;
                        foreach (var direction in Base6Directions.EnumDirections)
                        {
                            Vector3I dirvec = Base6Directions.GetIntVector((int)direction);
                            if (m_mergeHelper.Contains(pos + dirvec) && IsFaceTriangle(triangle, pos, dirvec))
                            {
                                addTriangle = false;
                                break;
                            }
                        }

                        if (addTriangle)
                        {
                            if (debugCounter == 5)
                            {
                            }
                            CopyTriangle(triangle, pos, ref transform);
                            debugCounter++;
                        }
                    }
                }
                // Otherwise, we just transform the triangles from the other mesh and add them to this mesh
                else
                {
                    foreach (var triangleIndex in entry.Value)
                    {
                        var triangle = otherMesh.GetTriangle(triangleIndex);
                        CopyTriangle(triangle, entry.Key, ref transform);
                        //if (triangleIndex > 1) break;
                    }
                }
            }

            m_mergeHelper.Clear();
            ProfilerShort.End();
        }
        /// <summary>
        /// Check if other block can be added to area of multiblock.
        /// </summary>
        public bool CanAddBlock(ref Vector3I otherGridPositionMin, ref Vector3I otherGridPositionMax, MyBlockOrientation otherOrientation, MyCubeBlockDefinition otherDefinition)
        {
            MatrixI transform;

            if (!GetTransform(out transform))
            {
                return(true);
            }

            try
            {
                // Calculate other block position in multiblock space.
                MatrixI invTransform;
                MatrixI.Invert(ref transform, out invTransform);

                Vector3I otherPositionInMultiBlockMinTmp = Vector3I.Transform(otherGridPositionMin, ref invTransform);
                Vector3I otherPositionInMultiBlockMaxTmp = Vector3I.Transform(otherGridPositionMax, ref invTransform);
                Vector3I otherPositionInMultiBlockMin    = Vector3I.Min(otherPositionInMultiBlockMinTmp, otherPositionInMultiBlockMaxTmp);
                Vector3I otherPositionInMultiBlockMax    = Vector3I.Max(otherPositionInMultiBlockMinTmp, otherPositionInMultiBlockMaxTmp);

                // Check intersection with AABB of whole multiblock
                if (!Vector3I.BoxIntersects(ref MultiBlockDefinition.Min, ref MultiBlockDefinition.Max, ref otherPositionInMultiBlockMin, ref otherPositionInMultiBlockMax))
                {
                    return(true);
                }

                // Other block rotation in multiblock space.
                MatrixI otherRotation = new MatrixI(otherOrientation);
                MatrixI otherRotationInMultiBlock;
                MatrixI.Multiply(ref otherRotation, ref invTransform, out otherRotationInMultiBlock);
                MyBlockOrientation otherOrientationInMultiBlock = new MyBlockOrientation(otherRotationInMultiBlock.Forward, otherRotationInMultiBlock.Up);

                // Multiblock part (block) definitions in the same position.
                m_tmpPartDefinitions.Clear();
                foreach (var partDefinition in MultiBlockDefinition.BlockDefinitions)
                {
                    if (Vector3I.BoxIntersects(ref partDefinition.Min, ref partDefinition.Max, ref otherPositionInMultiBlockMin, ref otherPositionInMultiBlockMax))
                    {
                        if (otherPositionInMultiBlockMin == otherPositionInMultiBlockMax && partDefinition.Min == partDefinition.Max) // Size = 1
                        {
                            m_tmpPartDefinitions.Add(partDefinition);
                        }
                        else
                        {
                            return(false);
                        }
                    }
                }

                if (m_tmpPartDefinitions.Count == 0)
                {
                    return(true);
                }

                // Check if multiblock part blocks and other block can be added together
                bool canAdd = true;
                foreach (var partDefinition in m_tmpPartDefinitions)
                {
                    MyCubeBlockDefinition blockDefinition;
                    if (MyDefinitionManager.Static.TryGetCubeBlockDefinition(partDefinition.Id, out blockDefinition) && blockDefinition != null)
                    {
                        canAdd &= MyCompoundCubeBlock.CanAddBlocks(blockDefinition, new MyBlockOrientation(partDefinition.Forward, partDefinition.Up),
                                                                   otherDefinition, otherOrientationInMultiBlock);
                        if (!canAdd)
                        {
                            break;
                        }
                    }
                }

                return(canAdd);
            }
            finally
            {
                m_tmpPartDefinitions.Clear();
            }
        }
        private static bool IntersectsInternalExpensive(ref PartFromPrefab partA, ref MatrixI transformA, ref MatrixI invTransformA, ref PartFromPrefab partB, ref MatrixI transformB, ref MatrixI invTransformB, bool testOptional)
        {
            using (partA.LockSharedUsing())
                using (partB.LockSharedUsing())
                {
                    var reservedAAll = Utilities.TransformBoundingBox(partA.ReservedSpace, ref transformA);
                    var reservedBAll = Utilities.TransformBoundingBox(partB.ReservedSpace, ref transformB);

                    var reservedA = new List <MyTuple <ReservedSpace, BoundingBox> >(partA.m_reservedSpaces.Count);
                    // ReSharper disable once LoopCanBeConvertedToQuery (preserve ref)
                    foreach (var aabb in partA.m_reservedSpaces)
                    {
                        if (!aabb.IsOptional || testOptional)
                        {
                            reservedA.Add(MyTuple.Create(aabb, Utilities.TransformBoundingBox(aabb.Box, ref transformA)));
                        }
                    }

                    var reservedB = new List <MyTuple <ReservedSpace, BoundingBox> >(partB.m_reservedSpaces.Count);
                    // ReSharper disable once LoopCanBeConvertedToQuery (preserve ref)
                    foreach (var aabb in partB.m_reservedSpaces)
                    {
                        if (!aabb.IsOptional || testOptional)
                        {
                            reservedB.Add(MyTuple.Create(aabb, Utilities.TransformBoundingBox(aabb.Box, ref transformB)));
                        }
                    }

                    // Reserved spaces intersect?
                    if (partA.m_reservedSpaces.Count > 0 && partB.m_reservedSpaces.Count > 0 && reservedAAll.Intersects(reservedBAll))
                    {
                        if (reservedA.Any(x => reservedB.Any(y => !y.Item1.IsShared && !x.Item1.IsShared && x.Item2.Intersects(y.Item2))))
                        {
                            return(true);
                        }
                    }

                    var blockAAll = Utilities.TransformBoundingBox(partA.BoundingBox, ref transformA);
                    var blockBAll = Utilities.TransformBoundingBox(partB.BoundingBox, ref transformB);

                    // Block spaces intersect with reserved space?
                    if (partA.m_reservedSpaces.Count > 0 && reservedAAll.Intersects(blockBAll))
                    {
                        foreach (var aabb in reservedA)
                        {
                            var min = Vector3I.Floor(Vector3.Max(aabb.Item2.Min, blockBAll.Min));
                            var max = Vector3I.Ceiling(Vector3.Min(aabb.Item2.Max, blockBAll.Max));
                            for (var vi = new Vector3I_RangeIterator(ref min, ref max); vi.IsValid(); vi.MoveNext())
                            {
                                if (partB.CubeExists(Vector3I.Transform(vi.Current, invTransformB)))
                                {
                                    return(true);
                                }
                            }
                        }
                    }
                    if (partB.m_reservedSpaces.Count > 0 && reservedBAll.Intersects(blockAAll))
                    {
                        foreach (var aabb in reservedB)
                        {
                            var min = Vector3I.Floor(Vector3.Max(aabb.Item2.Min, blockAAll.Min));
                            var max = Vector3I.Ceiling(Vector3.Min(aabb.Item2.Max, blockAAll.Max));
                            for (var vi = new Vector3I_RangeIterator(ref min, ref max); vi.IsValid(); vi.MoveNext())
                            {
                                if (partA.CubeExists(Vector3I.Transform(vi.Current, invTransformA)))
                                {
                                    return(true);
                                }
                            }
                        }
                    }

                    // Block space intersects with block space?
                    if (!blockAAll.Intersects(blockBAll))
                    {
                        return(false);
                    }
                    if (partA.m_blocks.Count < partB.m_blocks.Count)
                    {
                        foreach (var pos in partA.m_blocks.Keys)
                        {
                            if (partB.CubeExists(Vector3I.Transform(Vector3I.Transform(pos, ref transformA), ref invTransformB)))
                            {
                                return(true);
                            }
                        }
                    }
                    else
                    {
                        foreach (var pos in partB.m_blocks.Keys)
                        {
                            if (partA.CubeExists(Vector3I.Transform(Vector3I.Transform(pos, ref transformB), ref invTransformA)))
                            {
                                return(true);
                            }
                        }
                    }
                    return(false);
                }
        }
Example #6
0
        private MyCubeGrid DetectTouchingGrid(MySlimBlock block)
        {
            MyCubeGrid grid2;

            if (MyCubeBuilder.Static.DynamicMode)
            {
                return(null);
            }
            if (block == null)
            {
                return(null);
            }
            if (block.FatBlock is MyCompoundCubeBlock)
            {
                using (List <MySlimBlock> .Enumerator enumerator = (block.FatBlock as MyCompoundCubeBlock).GetBlocks().GetEnumerator())
                {
                    while (true)
                    {
                        if (enumerator.MoveNext())
                        {
                            MySlimBlock current = enumerator.Current;
                            MyCubeGrid  grid    = this.DetectTouchingGrid(current);
                            if (grid == null)
                            {
                                continue;
                            }
                            grid2 = grid;
                        }
                        else
                        {
                            return(null);
                        }
                        break;
                    }
                    return(grid2);
                }
            }
            else
            {
                BoundingBoxD xd;
                block.GetWorldBoundingBox(out xd, false);
                xd.Inflate((double)(block.CubeGrid.GridSize / 2f));
                m_tmpNearEntities.Clear();
                Sandbox.Game.Entities.MyEntities.GetElementsInBox(ref xd, m_tmpNearEntities);
                MyCubeBlockDefinition.MountPoint[] buildProgressModelMountPoints = block.BlockDefinition.GetBuildProgressModelMountPoints(block.BuildLevelRatio);
                try
                {
                    int num2 = 0;
                    while (true)
                    {
                        if (num2 >= m_tmpNearEntities.Count)
                        {
                            break;
                        }
                        MyCubeGrid objA = m_tmpNearEntities[num2] as MyCubeGrid;
                        if (((objA != null) && (!ReferenceEquals(objA, block.CubeGrid) && ((objA.Physics != null) && (objA.Physics.Enabled && objA.IsStatic)))) && (objA.GridSizeEnum == block.CubeGrid.GridSizeEnum))
                        {
                            Vector3I gridOffset = objA.WorldToGridInteger(base.m_pastePosition);
                            if (objA.CanMergeCubes(block.CubeGrid, gridOffset))
                            {
                                Quaternion quaternion;
                                MatrixI    transformation = objA.CalculateMergeTransform(block.CubeGrid, gridOffset);
                                new MyBlockOrientation(transformation.GetDirection(block.Orientation.Forward), transformation.GetDirection(block.Orientation.Up)).GetQuaternion(out quaternion);
                                Vector3I position = Vector3I.Transform(block.Position, transformation);
                                if (MyCubeGrid.CheckConnectivity(objA, block.BlockDefinition, buildProgressModelMountPoints, ref quaternion, ref position))
                                {
                                    return(objA);
                                }
                            }
                        }
                        num2++;
                    }
                }
                finally
                {
                    m_tmpNearEntities.Clear();
                }
                return(null);
            }
            return(grid2);
        }
Example #7
0
        private static void GetMultiMatches(IReadOnlyList <PartMountPointBlock> mine, IReadOnlyList <PartMountPointBlock> other, HashSet <MatrixI> cache)
        {
            cache.Clear();
            var match = Math.Min(mine.Count, other.Count);

            if (match == mine.Count)
            {
                foreach (var ot in other)
                {
                    mine[0].GetTransforms(ot, cache);
                }
                MatrixI inv;
                cache.RemoveWhere(x =>
                {
                    MatrixI.Invert(ref x, out inv);
                    for (var i = 1; i < mine.Count; i++)
                    {
                        var loc      = Vector3I.Transform(mine[i].MountLocation, ref inv);
                        var contains = false;
                        foreach (var y in other)
                        {
                            var opposLoc = y.AnchorLocation;
                            if (opposLoc != loc)
                            {
                                continue;
                            }
                            contains = true;
                            break;
                        }
                        if (!contains)
                        {
                            return(true);
                        }
                    }
                    return(false);
                });
            }
            else
            {
                foreach (var mi in mine)
                {
                    mi.GetTransforms(other[0], cache);
                }
                cache.RemoveWhere(x =>
                {
                    for (var i = 1; i < other.Count; i++)
                    {
                        var loc      = Vector3I.Transform(other[i].MountLocation, ref x);
                        var contains = false;
                        foreach (var y in mine)
                        {
                            var opposLoc = y.AnchorLocation;
                            if (opposLoc != loc)
                            {
                                continue;
                            }
                            contains = true;
                            break;
                        }
                        if (!contains)
                        {
                            return(true);
                        }
                    }
                    return(false);
                });
            }
        }
 public Vector3I GridToPrefab(Vector3I gridPos)
 {
     return(Vector3I.Transform(gridPos, ref m_invTransform));
 }
        private MyCubeGrid DetectTouchingGrid(MySlimBlock block)
        {
            if (MyCubeBuilder.Static.DynamicMode)
            {
                return(null);
            }

            if (block == null)
            {
                return(null);
            }

            if (block.FatBlock is MyCompoundCubeBlock)
            {
                foreach (var blockInCompound in (block.FatBlock as MyCompoundCubeBlock).GetBlocks())
                {
                    MyCubeGrid touchingGrid = DetectTouchingGrid(blockInCompound);
                    if (touchingGrid != null)
                    {
                        return(touchingGrid);
                    }
                }

                return(null);
            }

            ProfilerShort.Begin("MultiBlockClipboard: DetectMerge");

            float        gridSize = block.CubeGrid.GridSize;
            BoundingBoxD aabb;

            block.GetWorldBoundingBox(out aabb);
            // Inflate by half cube, so it will intersect for sure when there's anything
            aabb.Inflate(gridSize / 2);

            m_tmpNearEntities.Clear();
            MyEntities.GetElementsInBox(ref aabb, m_tmpNearEntities);

            var mountPoints = block.BlockDefinition.GetBuildProgressModelMountPoints(block.BuildLevelRatio);

            try
            {
                for (int i = 0; i < m_tmpNearEntities.Count; i++)
                {
                    var grid = m_tmpNearEntities[i] as MyCubeGrid;
                    if (grid != null && grid != block.CubeGrid && grid.Physics != null && grid.Physics.Enabled && grid.IsStatic && grid.GridSizeEnum == block.CubeGrid.GridSizeEnum)
                    {
                        Vector3I gridOffset = grid.WorldToGridInteger(m_pastePosition);
                        if (!grid.CanMergeCubes(block.CubeGrid, gridOffset))
                        {
                            continue;
                        }

                        MatrixI transform = grid.CalculateMergeTransform(block.CubeGrid, gridOffset);
                        Base6Directions.Direction forward        = transform.GetDirection(block.Orientation.Forward);
                        Base6Directions.Direction up             = transform.GetDirection(block.Orientation.Up);
                        MyBlockOrientation        newOrientation = new MyBlockOrientation(forward, up);
                        Quaternion newRotation;
                        newOrientation.GetQuaternion(out newRotation);
                        Vector3I newPosition = Vector3I.Transform(block.Position, transform);

                        if (!MyCubeGrid.CheckConnectivity(grid, block.BlockDefinition, mountPoints, ref newRotation, ref newPosition))
                        {
                            continue;
                        }

                        return(grid);
                    }
                }
            }
            finally
            {
                m_tmpNearEntities.Clear();
                ProfilerShort.End();
            }

            return(null);
        }
Example #10
0
        private void MergeFromAnotherMesh(MyGridNavigationMesh otherMesh, ref MatrixI transform)
        {
            int num;

            m_mergeHelper.Clear();
            foreach (Vector3I vectori in otherMesh.m_smallTriangleRegistry.Keys)
            {
                bool       flag          = false;
                Vector3I[] intDirections = Base6Directions.IntDirections;
                num = 0;
                while (true)
                {
                    if (num >= intDirections.Length)
                    {
                        if (flag)
                        {
                            m_mergeHelper.Add(vectori);
                        }
                        break;
                    }
                    Vector3I vectori2 = intDirections[num];
                    Vector3I position = Vector3I.Transform((Vector3I)(vectori + vectori2), (MatrixI)transform);
                    if (this.m_cubeSet.Contains(ref position))
                    {
                        m_mergeHelper.Add(vectori + vectori2);
                        flag = true;
                    }
                    num++;
                }
            }
            using (Dictionary <Vector3I, List <int> > .Enumerator enumerator2 = otherMesh.m_smallTriangleRegistry.GetEnumerator())
            {
                while (true)
                {
                    while (true)
                    {
                        if (enumerator2.MoveNext())
                        {
                            Vector3I vectori5;
                            KeyValuePair <Vector3I, List <int> > current = enumerator2.Current;
                            Vector3I key = current.Key;
                            Vector3I.Transform(ref key, ref transform, out vectori5);
                            if (m_mergeHelper.Contains(key))
                            {
                                m_tmpTriangleList.Clear();
                                Base6Directions.Direction[] enumDirections = Base6Directions.EnumDirections;
                                num = 0;
                                while (true)
                                {
                                    if (num < enumDirections.Length)
                                    {
                                        Base6Directions.Direction direction = enumDirections[num];
                                        Vector3I intVector = Base6Directions.GetIntVector((int)direction);
                                        Vector3I vectori7  = Base6Directions.GetIntVector((int)Base6Directions.GetFlippedDirection(transform.GetDirection(direction)));
                                        if (m_mergeHelper.Contains(key + intVector))
                                        {
                                            List <int> list = null;
                                            if (this.m_smallTriangleRegistry.TryGetValue(vectori5 - vectori7, out list))
                                            {
                                                foreach (int num3 in list)
                                                {
                                                    MyNavigationTriangle triangle = base.GetTriangle(num3);
                                                    if (this.IsFaceTriangle(triangle, vectori5 - vectori7, vectori7))
                                                    {
                                                        m_tmpTriangleList.Add(new KeyValuePair <MyNavigationTriangle, Vector3I>(triangle, vectori5 - vectori7));
                                                    }
                                                }
                                            }
                                        }
                                        num++;
                                        continue;
                                    }
                                    foreach (KeyValuePair <MyNavigationTriangle, Vector3I> pair2 in m_tmpTriangleList)
                                    {
                                        this.RemoveTriangle(pair2.Key, pair2.Value);
                                    }
                                    m_tmpTriangleList.Clear();
                                    int num2 = 0;
                                    foreach (int num4 in current.Value)
                                    {
                                        MyNavigationTriangle triangle     = otherMesh.GetTriangle(num4);
                                        Vector3I             cubePosition = current.Key;
                                        bool flag2 = true;
                                        enumDirections = Base6Directions.EnumDirections;
                                        num            = 0;
                                        while (true)
                                        {
                                            if (num < enumDirections.Length)
                                            {
                                                Vector3I intVector = Base6Directions.GetIntVector((int)enumDirections[num]);
                                                if (!m_mergeHelper.Contains(cubePosition + intVector) || !this.IsFaceTriangle(triangle, cubePosition, intVector))
                                                {
                                                    num++;
                                                    continue;
                                                }
                                                flag2 = false;
                                            }
                                            if (flag2)
                                            {
                                                int num6 = num2;
                                                this.CopyTriangle(triangle, cubePosition, ref transform);
                                                num2++;
                                            }
                                            break;
                                        }
                                    }
                                }
                            }
                            foreach (int num5 in current.Value)
                            {
                                MyNavigationTriangle triangle = otherMesh.GetTriangle(num5);
                                this.CopyTriangle(triangle, current.Key, ref transform);
                            }
                        }
                        else
                        {
                            goto TR_0000;
                        }
                    }
                }
            }
TR_0000:
            m_mergeHelper.Clear();
        }
Example #11
0
        public override bool Invoke(ulong steamId, long playerId, string messageText)
        {
            if (messageText.StartsWith("/rotateroid ", StringComparison.InvariantCultureIgnoreCase))
            {
                var match = Regex.Match(messageText, @"/rotateroid\s{1,}(?<Key>.+){1,}\s{1,}(?<X>[+-]?((\d+(\.\d*)?)|(\.\d+)))\s{1,}(?<Y>[+-]?((\d+(\.\d*)?)|(\.\d+)))\s{1,}(?<Z>[+-]?((\d+(\.\d*)?)|(\.\d+)))", RegexOptions.IgnoreCase);
                if (match.Success)
                {
                    var rotateVector = new Vector3(
                        double.Parse(match.Groups["X"].Value, CultureInfo.InvariantCulture),
                        double.Parse(match.Groups["Y"].Value, CultureInfo.InvariantCulture),
                        double.Parse(match.Groups["Z"].Value, CultureInfo.InvariantCulture));
                    var searchName = match.Groups["Key"].Value;

                    var          currentAsteroidList = new List <IMyVoxelBase>();
                    IMyVoxelBase originalAsteroid    = null;
                    MyAPIGateway.Session.VoxelMaps.GetInstances(currentAsteroidList, v => v.StorageName.Equals(searchName, StringComparison.InvariantCultureIgnoreCase));
                    if (currentAsteroidList.Count == 1)
                    {
                        originalAsteroid = currentAsteroidList[0];
                    }
                    else
                    {
                        MyAPIGateway.Session.VoxelMaps.GetInstances(currentAsteroidList, v => v.StorageName.IndexOf(searchName, StringComparison.InvariantCultureIgnoreCase) >= 0);

                        if (currentAsteroidList.Count == 1)
                        {
                            originalAsteroid = currentAsteroidList[0];
                        }
                    }

                    List <IMyVoxelBase> asteroidCache = CommandAsteroidsList.GetAsteroidCache(steamId);
                    int index;
                    if (searchName.Substring(0, 1) == "#" && Int32.TryParse(searchName.Substring(1), out index) && index > 0 && index <= asteroidCache.Count)
                    {
                        originalAsteroid = asteroidCache[index - 1];
                    }

                    if (originalAsteroid == null)
                    {
                        MyAPIGateway.Utilities.SendMessage(steamId, "Cannot find asteroid", string.Format("'{0}'", searchName));
                        return(true);
                    }

                    var quaternion = Quaternion.CreateFromYawPitchRoll(rotateVector.X / (180 / MathHelper.Pi), rotateVector.Y / (180 / MathHelper.Pi), rotateVector.Z / (180 / MathHelper.Pi));
                    var oldStorage = originalAsteroid.Storage;

                    var oldCache = new MyStorageData();
                    oldCache.Resize(oldStorage.Size);
                    oldStorage.ReadRange(oldCache, MyStorageDataTypeFlags.ContentAndMaterial, 0, Vector3I.Zero, oldStorage.Size - 1);

                    var transSize   = Vector3I.Transform(oldStorage.Size, quaternion);
                    var newSize     = Vector3I.Abs(transSize);
                    var newName     = Support.CreateUniqueStorageName(originalAsteroid.StorageName);
                    var newVoxelMap = Support.CreateNewAsteroid(newName, newSize, originalAsteroid.PositionLeftBottomCorner);

                    var cache = new MyStorageData();
                    var min   = Vector3I.Zero;
                    var max   = newSize - 1;
                    cache.Resize(min, max);

                    Vector3I p;
                    for (p.Z = 0; p.Z < oldStorage.Size.Z; ++p.Z)
                    {
                        for (p.Y = 0; p.Y < oldStorage.Size.Y; ++p.Y)
                        {
                            for (p.X = 0; p.X < oldStorage.Size.X; ++p.X)
                            {
                                var content  = oldCache.Content(ref p);
                                var material = oldCache.Material(ref p);

                                var newP = Vector3I.Transform(p, quaternion);
                                // readjust the points, as rotation occurs arround 0,0,0.
                                newP.X = newP.X < 0 ? newP.X - transSize.X - 1 : newP.X;
                                newP.Y = newP.Y < 0 ? newP.Y - transSize.Y - 1 : newP.Y;
                                newP.Z = newP.Z < 0 ? newP.Z - transSize.Z - 1 : newP.Z;

                                cache.Content(ref newP, content);
                                cache.Material(ref newP, material);
                            }
                        }
                    }

                    newVoxelMap.Storage.WriteRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, min, max);
                    MyAPIGateway.Entities.RemoveEntity((IMyEntity)originalAsteroid);

                    // Invalidate the cache, to force user to select again to prevent possible corruption by using an old cache.
                    asteroidCache.Clear();
                    return(true);
                }
            }

            return(false);
        }
Example #12
0
        public bool CanAddBlock(ref Vector3I otherGridPositionMin, ref Vector3I otherGridPositionMax, MyBlockOrientation otherOrientation, MyCubeBlockDefinition otherDefinition)
        {
            MatrixI xi;
            bool    flag2;

            if (!this.GetTransform(out xi))
            {
                return(true);
            }
            try
            {
                MatrixI xi2;
                MatrixI.Invert(ref xi, out xi2);
                Vector3I vectori1 = Vector3I.Transform(otherGridPositionMin, ref xi2);
                Vector3I vectori  = Vector3I.Transform(otherGridPositionMax, ref xi2);
                Vector3I minB     = Vector3I.Min(vectori1, vectori);
                Vector3I maxB     = Vector3I.Max(vectori1, vectori);
                if (Vector3I.BoxIntersects(ref this.MultiBlockDefinition.Min, ref this.MultiBlockDefinition.Max, ref minB, ref maxB))
                {
                    MatrixI xi4;
                    MatrixI leftMatrix = new MatrixI(otherOrientation);
                    MatrixI.Multiply(ref leftMatrix, ref xi2, out xi4);
                    MyBlockOrientation orientation = new MyBlockOrientation(xi4.Forward, xi4.Up);
                    m_tmpPartDefinitions.Clear();
                    MyMultiBlockDefinition.MyMultiBlockPartDefinition[] blockDefinitions = this.MultiBlockDefinition.BlockDefinitions;
                    int index = 0;
                    while (true)
                    {
                        if (index < blockDefinitions.Length)
                        {
                            MyMultiBlockDefinition.MyMultiBlockPartDefinition item = blockDefinitions[index];
                            if (Vector3I.BoxIntersects(ref item.Min, ref item.Max, ref minB, ref maxB))
                            {
                                if (!(minB == maxB))
                                {
                                    break;
                                }
                                if (!(item.Min == item.Max))
                                {
                                    break;
                                }
                                m_tmpPartDefinitions.Add(item);
                            }
                            index++;
                            continue;
                        }
                        if (m_tmpPartDefinitions.Count == 0)
                        {
                            flag2 = true;
                        }
                        else
                        {
                            bool flag = true;
                            foreach (MyMultiBlockDefinition.MyMultiBlockPartDefinition definition2 in m_tmpPartDefinitions)
                            {
                                MyCubeBlockDefinition definition3;
                                if (!MyDefinitionManager.Static.TryGetCubeBlockDefinition(definition2.Id, out definition3))
                                {
                                    continue;
                                }
                                if (definition3 != null)
                                {
                                    flag &= MyCompoundCubeBlock.CanAddBlocks(definition3, new MyBlockOrientation(definition2.Forward, definition2.Up), otherDefinition, orientation);
                                    if (!flag)
                                    {
                                        break;
                                    }
                                }
                            }
                            flag2 = flag;
                        }
                        return(flag2);
                    }
                    flag2 = false;
                }
                else
                {
                    flag2 = true;
                }
            }
            finally
            {
                m_tmpPartDefinitions.Clear();
            }
            return(flag2);
        }
Example #13
0
        static bool CanMergeCubes(IMyCubeBlock padA, IMyCubeBlock padB, Vector3I gridOffset, List <IMySlimBlock> blocksOverlapping, List <IMySlimBlock> weldPadsOverlapping)
        {
            blocksOverlapping.Clear();
            try
            {
                IMyCubeGrid gridA         = padA.CubeGrid;
                IMyCubeGrid gridB         = padB.CubeGrid;
                MyCubeGrid  internalGridB = (MyCubeGrid)gridB;

                MatrixI transform = gridA.CalculateMergeTransform(gridB, gridOffset);

                bool result = true;

                // check gridToMerge's blocks against grid's blocks
                foreach (IMySlimBlock slimGridB in internalGridB.GetBlocks()) // get blocks without intermediary lists
                {
                    if (slimGridB.FatBlock == padB)
                    {
                        continue;
                    }

                    // ignore all pads
                    //if(IsWeldPad(slimGridB.BlockDefinition.Id))
                    //    continue;

                    Vector3I     pos       = Vector3I.Transform(slimGridB.Position, transform);
                    IMySlimBlock slimGridA = gridA.GetCubeBlock(pos);

                    if (slimGridA != null)
                    {
                        if (slimGridA.FatBlock == padA)
                        {
                            continue;
                        }

                        // ignore all pads
                        //if(IsWeldPad(slimGridA.BlockDefinition.Id))
                        //    continue;

                        //MyAPIGateway.Utilities.ShowNotification($"{(master ? "master" : "slavetest")} :: {slimGrid1.BlockDefinition.ToString()} OVERLAPS {slimGrid2.BlockDefinition.ToString()}", 16);
                        //DebugDraw(slimGrid1.CubeGrid, slimGrid1.Min, slimGrid1.Max, Color.Red, master);
                        //DebugDraw(slimGrid2.CubeGrid, slimGrid2.Min, slimGrid2.Max, Color.Yellow, master);
                        //result = false;
                        //continue;

                        bool isWeldPadA = (slimGridA?.FatBlock?.GameLogic?.GetAs <WeldPad>() != null);
                        bool isWeldPadB = (slimGridB?.FatBlock?.GameLogic?.GetAs <WeldPad>() != null);

                        if (isWeldPadA || isWeldPadB)
                        {
                            if (isWeldPadA)
                            {
                                weldPadsOverlapping.Add(slimGridA);
                            }

                            if (isWeldPadB)
                            {
                                weldPadsOverlapping.Add(slimGridB);
                            }
                        }
                        else
                        {
                            blocksOverlapping.Add(slimGridA);
                            blocksOverlapping.Add(slimGridB);
                            result = false;
                        }

                        // allow more blocks to be found
                    }

                    //DebugDraw(grid1, pos, pos, Color.Blue, master);
                }

                return(result);
            }
            catch (Exception e)
            {
                Log.Error(e);
            }

            return(false);
        }
 public Vector3I PrefabToGrid(Vector3I prefabPos)
 {
     return(Vector3I.Transform(prefabPos, ref m_transform));
 }
        public static SerializableVector3UByte Transform(this SerializableVector3UByte value, Quaternion rotation)
        {
            var vector = Vector3I.Transform(new Vector3I(value.X - 127, value.Y - 127, value.Z - 127), rotation);

            return(new SerializableVector3UByte((byte)(vector.X + 127), (byte)(vector.Y + 127), (byte)(vector.Z + 127)));
        }
Example #16
0
        public void RotateAsteroid(Quaternion quaternion)
        {
            var sourceFile = SourceVoxelFilepath ?? VoxelFilepath;

            var asteroid = new MyVoxelMap();

            asteroid.Load(sourceFile);

            var newAsteroid = new MyVoxelMap();
            var newSize     = asteroid.Size;

            newAsteroid.Create(newSize, SpaceEngineersCore.Resources.GetDefaultMaterialIndex());

            Vector3I block;
            var      halfSize = asteroid.Storage.Size / 2;

            // Don't use anything smaller than 64 for smaller voxels, as it trashes the cache.
            var cacheSize     = new Vector3I(64);
            var halfCacheSize = new Vector3I(32); // This should only be used for the Transform, not the cache.

            // read the asteroid in chunks of 64 to avoid the Arithmetic overflow issue.
            for (block.Z = 0; block.Z < asteroid.Storage.Size.Z; block.Z += 64)
            {
                for (block.Y = 0; block.Y < asteroid.Storage.Size.Y; block.Y += 64)
                {
                    for (block.X = 0; block.X < asteroid.Storage.Size.X; block.X += 64)
                    {
                        #region source voxel

                        var cache = new MyStorageData();
                        cache.Resize(cacheSize);
                        // LOD1 is not detailed enough for content information on asteroids.
                        asteroid.Storage.ReadRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, 0, block, block + cacheSize - 1);

                        #endregion

                        #region target Voxel

                        // the block is a cubiod. The entire space needs to rotate, to be able to gauge where the new block position starts from.
                        var newBlockMin = Vector3I.Transform(block - halfSize, quaternion) + halfSize;
                        var newBlockMax = Vector3I.Transform(block + 64 - halfSize, quaternion) + halfSize;
                        var newBlock    = Vector3I.Min(newBlockMin, newBlockMax);

                        var newCache = new MyStorageData();
                        newCache.Resize(cacheSize);
                        newAsteroid.Storage.ReadRange(newCache, MyStorageDataTypeFlags.ContentAndMaterial, 0, newBlock, newBlock + cacheSize - 1);

                        #endregion

                        bool     changed = false;
                        Vector3I p;
                        for (p.Z = 0; p.Z < cacheSize.Z; ++p.Z)
                        {
                            for (p.Y = 0; p.Y < cacheSize.Y; ++p.Y)
                            {
                                for (p.X = 0; p.X < cacheSize.X; ++p.X)
                                {
                                    byte volume       = cache.Content(ref p);
                                    byte cellMaterial = cache.Material(ref p);

                                    var newP1 = Vector3I.Transform(p - halfCacheSize, quaternion) + halfCacheSize;
                                    var newP2 = Vector3I.Transform(p + 1 - halfCacheSize, quaternion) + halfCacheSize;
                                    var newP  = Vector3I.Min(newP1, newP2);

                                    newCache.Content(ref newP, volume);
                                    newCache.Material(ref newP, cellMaterial);
                                    changed = true;
                                }
                            }
                        }

                        if (changed)
                        {
                            newAsteroid.Storage.WriteRange(newCache, MyStorageDataTypeFlags.ContentAndMaterial, newBlock, newBlock + cacheSize - 1);
                        }
                    }
                }
            }


            var tempfilename = TempfileUtil.NewFilename(MyVoxelMap.V2FileExtension);
            newAsteroid.Save(tempfilename);

            SourceVoxelFilepath = tempfilename;
        }
Example #17
0
        public override void Remap(MyObjectBuilder_CubeGrid grid)
        {
            var transformCopy = LocalTransform;

            var minToMin = new Dictionary <Vector3I, Vector3I>(grid.CubeBlocks.Count * 3 / 2);

            foreach (var x in grid.CubeBlocks)
            {
                var      orig = (Vector3I)x.Min;
                var      cMin = orig;
                Vector3I cMax;
                BlockTransformations.ComputeBlockMax(x, out cMax);
                x.BlockOrientation.Forward = LocalTransform.GetDirection(x.BlockOrientation.Forward);
                x.BlockOrientation.Up      = LocalTransform.GetDirection(x.BlockOrientation.Up);
                Vector3I.Transform(ref cMin, ref transformCopy, out cMin);
                Vector3I.Transform(ref cMax, ref transformCopy, out cMax);
                minToMin[orig] = x.Min = Vector3I.Min(cMin, cMax);

                var proj = x as MyObjectBuilder_ProjectorBase;
                // Don't have to update the rotation; it is bound to the world matrix of the projector.
                if (proj != null)
                {
                    Vector3I.TransformNormal(ref proj.ProjectionOffset, ref transformCopy, out proj.ProjectionOffset);
                }
            }

            if (grid.BlockGroups != null)
            {
                foreach (var g in grid.BlockGroups)
                {
                    for (var i = 0; i < g.Blocks.Count; i++)
                    {
                        Vector3I tmpOut;
                        if (minToMin.TryGetValue(g.Blocks[i], out tmpOut))
                        {
                            g.Blocks[i] = tmpOut;
                        }
                        else
                        {
                            g.Blocks[i] = Vector3I.MaxValue; // sorta discards it?
                        }
                    }
                }
            }

            if (grid.ConveyorLines != null)
            {
                foreach (var l in grid.ConveyorLines)
                {
                    l.StartDirection = LocalTransform.GetDirection(l.StartDirection);
                    l.StartPosition  = Vector3I.Transform(l.StartPosition, ref transformCopy);

                    l.EndDirection = LocalTransform.GetDirection(l.EndDirection);
                    l.EndPosition  = Vector3I.Transform(l.EndPosition, ref transformCopy);

                    if (l.Sections == null)
                    {
                        continue;
                    }
                    for (var s = 0; s < l.Sections.Count; s++)
                    {
                        l.Sections[s] = new SerializableLineSectionInformation()
                        {
                            Direction = LocalTransform.GetDirection(l.Sections[s].Direction), Length = l.Sections[s].Length
                        }
                    }
                    ;
                }
            }
        }