예제 #1
0
        public static Vector3I TransformNormal(Vector3I value, ref MatrixI transformation)
        {
            Vector3I vectori;

            TransformNormal(ref value, ref transformation, out vectori);
            return(vectori);
        }
예제 #2
0
        public static Vector3I TransformNormal(Vector3I value, ref MatrixI transformation)
        {
            Vector3I result;

            TransformNormal(ref value, ref transformation, out result);
            return(result);
        }
예제 #3
0
 public static void Transform(ref Vector3I value, ref MatrixI matrix, out Vector3I result)
 {
     result = value.X * Base6Directions.GetIntVector(matrix.Right) +
              value.Y * Base6Directions.GetIntVector(matrix.Up) +
              value.Z * Base6Directions.GetIntVector(matrix.Backward) +
              matrix.Translation;
 }
예제 #4
0
 IMyCubeGrid IMyCubeGrid.MergeGrid_CopyPaste(IMyCubeGrid gridToMerge, VRageMath.MatrixI mergeTransform)
 {
     if (gridToMerge is MyCubeGrid)
     {
         return(MergeGrid_CopyPaste(gridToMerge as MyCubeGrid, mergeTransform));
     }
     return(null);
 }
예제 #5
0
        public static void Invert(ref MatrixI matrix, out MatrixI result)
        {
            result = new MatrixI();

            switch (matrix.Right)
            {
            case Base6Directions.Direction.Up: result.Up = Base6Directions.Direction.Right; break;

            case Base6Directions.Direction.Down: result.Up = Base6Directions.Direction.Left; break;

            case Base6Directions.Direction.Backward: result.Backward = Base6Directions.Direction.Right; break;

            case Base6Directions.Direction.Forward: result.Backward = Base6Directions.Direction.Left; break;

            default:
                result.Right = matrix.Right;
                break;
            }

            switch (matrix.Up)
            {
            case Base6Directions.Direction.Right: result.Right = Base6Directions.Direction.Up; break;

            case Base6Directions.Direction.Left: result.Right = Base6Directions.Direction.Down; break;

            case Base6Directions.Direction.Backward: result.Backward = Base6Directions.Direction.Up; break;

            case Base6Directions.Direction.Forward: result.Backward = Base6Directions.Direction.Down; break;

            default:
                result.Up = matrix.Up;
                break;
            }

            switch (matrix.Backward)
            {
            case Base6Directions.Direction.Right: result.Right = Base6Directions.Direction.Backward; break;

            case Base6Directions.Direction.Left: result.Right = Base6Directions.Direction.Forward; break;

            case Base6Directions.Direction.Up: result.Up = Base6Directions.Direction.Backward; break;

            case Base6Directions.Direction.Down: result.Up = Base6Directions.Direction.Forward; break;

            default:
                result.Backward = matrix.Backward;
                break;
            }

            Vector3I.TransformNormal(ref matrix.Translation, ref result, out result.Translation);
            result.Translation = -result.Translation;
        }
        public bool GetMissingBlocks(out MatrixI transform, List<int> multiBlockIndices)
        {
            // Fill missing indices.
            Debug.Assert(multiBlockIndices.Count == 0);
            for (int i = 0; i < MultiBlockDefinition.BlockDefinitions.Length; ++i)
            {
                if (!Blocks.Any(b => b.MultiBlockIndex == i))
                    multiBlockIndices.Add(i);
            }

            // ...and return transform
            return GetTransform(out transform);
        }
예제 #7
0
        public static void Multiply(ref MatrixI leftMatrix, ref MatrixI rightMatrix, out MatrixI result)
        {
            result = default(MatrixI);
            Vector3I right = leftMatrix.RightVector;
            Vector3I up = leftMatrix.UpVector;
            Vector3I backward = leftMatrix.BackwardVector;
            Vector3I newRight, newUp, newBackward;

            Vector3I.TransformNormal(ref right, ref rightMatrix, out newRight);
            Vector3I.TransformNormal(ref up, ref rightMatrix, out newUp);
            Vector3I.TransformNormal(ref backward, ref rightMatrix, out newBackward);
            Vector3I.Transform(ref leftMatrix.Translation, ref rightMatrix, out result.Translation);
            result.RightVector    = newRight;
            result.UpVector       = newUp;
            result.BackwardVector = newBackward;
        }
예제 #8
0
        public void CopyTo(MyGridSkeleton target, MatrixI transformationMatrix, MyCubeGrid targetGrid)
        {
            Vector3I oldPosition, newPosition;
            Vector3 oldBone, newBone;

            // transformationMatrix is in cube coordinates, so change it to bone coords
            MatrixI BoneOriginToGridOrigin = new MatrixI(new Vector3I(1, 1, 1), Base6Directions.Direction.Forward, Base6Directions.Direction.Up);
            MatrixI GridOriginToBoneOrigin = new MatrixI(new Vector3I(-1, -1, -1), Base6Directions.Direction.Forward, Base6Directions.Direction.Up);

            transformationMatrix.Translation = transformationMatrix.Translation * BoneDensity;

            MatrixI tmp;
            MatrixI.Multiply(ref GridOriginToBoneOrigin, ref transformationMatrix, out tmp);
            MatrixI.Multiply(ref tmp, ref BoneOriginToGridOrigin, out transformationMatrix);

            Matrix orientation;
            transformationMatrix.GetBlockOrientation().GetMatrix(out orientation);

            foreach (var bone in Bones)
            {
                oldPosition = bone.Key;
                Vector3I.Transform(ref oldPosition, ref transformationMatrix, out newPosition);
                Vector3 transformedBone = Vector3.Transform(bone.Value, orientation);

                if (target.Bones.TryGetValue(newPosition, out oldBone))
                {
                    newBone = (oldBone + transformedBone) * 0.5f;
                    target.Bones[newPosition] = newBone;
                }
                else
                {
                    target.Bones[newPosition] = transformedBone;
                }

                Vector3I cubePosition = newPosition / BoneDensity;
  
                for (int i = -1; i <= 1; i++)
                    for (int j = -1; j <= 1; j++)
                        for (int k = -1; k <= 1; k++)
                        {
                            targetGrid.SetCubeDirty(cubePosition + new Vector3I(i, j, k));
                        }

            }
        }
예제 #9
0
        public static MatrixI CreateRotation(Base6Directions.Direction oldA, Base6Directions.Direction oldB, Base6Directions.Direction newA, Base6Directions.Direction newB)
        {
            Debug.Assert(Base6Directions.GetAxis(oldA) != Base6Directions.GetAxis(oldB), "Original vectors must not lie in line!");
            Debug.Assert(Base6Directions.GetAxis(newA) != Base6Directions.GetAxis(newB), "Transformed vectors must not lie in line!");

            MatrixI newMatrix = new MatrixI();

            newMatrix.Translation = Vector3I.Zero;

            Base6Directions.Direction oldC = Base6Directions.GetCross(oldA, oldB);
            Base6Directions.Direction newC = Base6Directions.GetCross(newA, newB);

            newMatrix.SetDirection(oldA, newA);
            newMatrix.SetDirection(oldB, newB);
            newMatrix.SetDirection(oldC, newC);

            return(newMatrix);
        }
        public bool GetTransform(out MatrixI transform)
        {
            transform = default(MatrixI);

            if (Blocks.Count != 0)
            {
                var refBlock = Blocks.First();
                Debug.Assert(refBlock.MultiBlockIndex < MultiBlockDefinition.BlockDefinitions.Length);
                if (refBlock.MultiBlockIndex < MultiBlockDefinition.BlockDefinitions.Length)
                {
                    var refBlockDefInfo = MultiBlockDefinition.BlockDefinitions[refBlock.MultiBlockIndex];
                    transform = MatrixI.CreateRotation(refBlockDefInfo.Forward, refBlockDefInfo.Up, refBlock.Orientation.Forward, refBlock.Orientation.Up);
                    transform.Translation = refBlock.Position - Vector3I.TransformNormal(refBlockDefInfo.Min, ref transform);
                    return true;
                }
            }

            return false;
        }
예제 #11
0
        public static void Invert(ref MatrixI matrix, out MatrixI result)
        {
            result = new MatrixI();

            switch (matrix.Right)
            {
                case Base6Directions.Direction.Up: result.Up = Base6Directions.Direction.Right; break;
                case Base6Directions.Direction.Down: result.Up = Base6Directions.Direction.Left; break;
                case Base6Directions.Direction.Backward: result.Backward = Base6Directions.Direction.Right; break;
                case Base6Directions.Direction.Forward: result.Backward = Base6Directions.Direction.Left; break;
                default:
                    result.Right = matrix.Right;
                    break;
            }

            switch (matrix.Up)
            {
                case Base6Directions.Direction.Right: result.Right = Base6Directions.Direction.Up; break;
                case Base6Directions.Direction.Left: result.Right = Base6Directions.Direction.Down; break;
                case Base6Directions.Direction.Backward: result.Backward = Base6Directions.Direction.Up; break;
                case Base6Directions.Direction.Forward: result.Backward = Base6Directions.Direction.Down; break;
                default:
                    result.Up = matrix.Up;
                    break;
            }

            switch (matrix.Backward)
            {
                case Base6Directions.Direction.Right: result.Right = Base6Directions.Direction.Backward; break;
                case Base6Directions.Direction.Left: result.Right = Base6Directions.Direction.Forward; break;
                case Base6Directions.Direction.Up: result.Up = Base6Directions.Direction.Backward; break;
                case Base6Directions.Direction.Down: result.Up = Base6Directions.Direction.Forward; break;
                default:
                    result.Backward = matrix.Backward;
                    break;
            }

            Vector3I.TransformNormal(ref matrix.Translation, ref result, out result.Translation);
            result.Translation = -result.Translation;
        }
예제 #12
0
        private void AddBlock(MySlimBlock block)
        {
            Vector3I start = block.Min;
            Vector3I end = block.Max;
            for (var it = new Vector3I.RangeIterator(ref start, ref end); it.IsValid(); it.GetNext(out start))
            {
                Debug.Assert(!m_cubeSet.Contains(ref start));
                m_cubeSet.Add(ref start);
            }

            MatrixI transform = new MatrixI(block.Position, block.Orientation.Forward, block.Orientation.Up);
            MergeFromAnotherMesh(block.BlockDefinition.NavigationDefinition.Mesh, ref transform);
        }
예제 #13
0
        internal void Transform(ref MatrixI transform)
        {
            Vector3I tMin;
            Vector3I tMax;
            Vector3I tPos;
            Vector3I.Transform(ref this.Min, ref transform, out tMin);
            Vector3I.Transform(ref this.Max, ref transform, out tMax);
            Vector3I.Transform(ref this.Position, ref transform, out tPos);
            Vector3I forward = Base6Directions.GetIntVector(transform.GetDirection(this.Orientation.Forward));
            Vector3I up = Base6Directions.GetIntVector(transform.GetDirection(this.Orientation.Up));

            Debug.Assert(Vector3I.Dot(ref forward, ref up) == 0);

            this.InitOrientation(ref forward, ref up);

            this.Min = Vector3I.Min(tMin, tMax);
            this.Max = Vector3I.Max(tMin, tMax);
            this.Position = tPos;

            if (FatBlock != null)
                FatBlock.OnTransformed(ref transform);
        }
예제 #14
0
        public static Vector3I ComputePositionInGrid(MatrixI localMatrix, MyCubeBlockDefinition blockDefinition, Vector3I min)
        {
            var center = blockDefinition.Center;
            var sizeMinusOne = blockDefinition.Size - 1;
            Vector3I rotatedBlockSize;
            Vector3I rotatedCenter;
            Vector3I.TransformNormal(ref sizeMinusOne, ref localMatrix, out rotatedBlockSize);
            Vector3I.TransformNormal(ref center, ref localMatrix, out rotatedCenter);
            var trueSize = Vector3I.Abs(rotatedBlockSize);
            var offsetCenter = rotatedCenter + min;

            if (rotatedBlockSize.X != trueSize.X) offsetCenter.X += trueSize.X;
            if (rotatedBlockSize.Y != trueSize.Y) offsetCenter.Y += trueSize.Y;
            if (rotatedBlockSize.Z != trueSize.Z) offsetCenter.Z += trueSize.Z;

            //Debug.Assert(Position == offsetCenter);
            return offsetCenter;
            //return Position;
        }
예제 #15
0
        protected static bool CheckConnectivityOnGrid(MySlimBlock block, ref MatrixI transform, ref MyGridPlacementSettings settings, MyCubeGrid hitGrid)
        {
            Vector3I position;
            Vector3I.Transform(ref block.Position, ref transform, out position);

            Vector3I forward = Base6Directions.GetIntVector(transform.GetDirection(block.Orientation.Forward));
            Vector3I up = Base6Directions.GetIntVector(transform.GetDirection(block.Orientation.Up));
            MyBlockOrientation blockOrientation = new MyBlockOrientation(Base6Directions.GetDirection(forward), Base6Directions.GetDirection(up));
            Quaternion rotation;
            blockOrientation.GetQuaternion(out rotation);
			var blockDefinition = block.BlockDefinition;
            return MyCubeGrid.CheckConnectivity(hitGrid, blockDefinition, blockDefinition.GetBuildProgressModelMountPoints(block.BuildLevelRatio), ref rotation, ref position);
        }
예제 #16
0
        /// <summary>
        /// Converts the given block with the given matrix for static grid.
        /// </summary>
        private static void ConvertRotatedGridBlockToStatic(ref MatrixI transform, MyObjectBuilder_CubeBlock origBlock)
        {
            MyDefinitionId defId = new MyDefinitionId(origBlock.TypeId, origBlock.SubtypeName);
            MyCubeBlockDefinition blockDefinition;
            MyDefinitionManager.Static.TryGetCubeBlockDefinition(defId, out blockDefinition);
            if (blockDefinition == null)
                return;

            // Orientation quaternion is not setup in origblock
            MyBlockOrientation origOrientation = origBlock.BlockOrientation;
            Vector3I origMin = origBlock.Min;
            Vector3I origMax;
            MySlimBlock.ComputeMax(blockDefinition, origOrientation, ref origMin, out origMax);

            Vector3I tMin;
            Vector3I tMax;
            Vector3I.Transform(ref origMin, ref transform, out tMin);
            Vector3I.Transform(ref origMax, ref transform, out tMax);
            Base6Directions.Direction forward = transform.GetDirection(origOrientation.Forward);
            Base6Directions.Direction up = transform.GetDirection(origOrientation.Up);

            // Write data
            MyBlockOrientation newBlockOrientation = new MyBlockOrientation(forward, up);
            Quaternion rotationQuat;
            newBlockOrientation.GetQuaternion(out rotationQuat);
            origBlock.Orientation = rotationQuat;
            origBlock.Min = Vector3I.Min(tMin, tMax);
        }
예제 #17
0
        public void GetTransformed(ref MatrixI tform, out Vector3 newA, out Vector3 newB, out Vector3 newC)
        {
            var e = m_navMesh.Mesh.GetFace(m_triIndex).GetVertexEnumerator();

            e.MoveNext();
            newA = e.Current;
            Vector3.Transform(ref newA, ref tform, out newA);

            e.MoveNext();
            newB = e.Current;
            Vector3.Transform(ref newB, ref tform, out newB);

            e.MoveNext();
            newC = e.Current;
            Vector3.Transform(ref newC, ref tform, out newC);

            Debug.Assert(e.MoveNext() == false);
        }
예제 #18
0
 private static void OnMergeGridSuccess(MySyncGrid sync, ref MergeMsg msg, MyNetworkClient sender)
 {
     MyCubeGrid grid = null;
     if (MyEntities.TryGetEntityById<MyCubeGrid>(msg.OtherEntityId, out grid))
     {
         Vector3I gridOffset = msg.GridOffset;
         MatrixI transform = new MatrixI(msg.GridOffset, msg.GridForward, msg.GridUp);
         sync.Entity.MergeGridInternal(grid, ref transform);
     }
 }
예제 #19
0
 public static void Multiply(ref MatrixI leftMatrix, ref MatrixI rightMatrix, out MatrixI result)
 {
     result = default(MatrixI);
     Vector3I right    = leftMatrix.RightVector;
     Vector3I up       = leftMatrix.UpVector;
     Vector3I backward = leftMatrix.BackwardVector;
     Vector3I newRight, newUp, newBackward;
     Vector3I.TransformNormal(ref right,    ref rightMatrix, out newRight);
     Vector3I.TransformNormal(ref up,       ref rightMatrix, out newUp);
     Vector3I.TransformNormal(ref backward, ref rightMatrix, out newBackward);
     Vector3I.Transform(ref leftMatrix.Translation, ref rightMatrix, out result.Translation);
     result.RightVector    = newRight;
     result.UpVector       = newUp;
     result.BackwardVector = newBackward;
 }
        public unsafe static void CalculateBlockDepthBias(this MyRenderComponent renderComponent, MyCubeBlock block)
        {
            if (block.Hierarchy != null)
            {
                var parentCompound = block.Hierarchy.Parent.Entity as MyCompoundCubeBlock;
                if (parentCompound != null)
                {
                    const int offsetCount = 64;
                    bool* offsets = stackalloc bool[offsetCount];

                    foreach (var block2 in parentCompound.GetBlocks())
                    {
                        if (block2.FatBlock != null && block2.FatBlock != block)
                        {
                            var cubeBlockRender = block2.FatBlock.Render as MyRenderComponentBase;
                            if (cubeBlockRender != null)
                                offsets[cubeBlockRender.DepthBias] = true;
                        }
                    }

                    int preferedOffset = 0;
                    var modelStorage = renderComponent.ModelStorage as VRage.Game.Models.MyModel;
                    if (modelStorage != null)
                    {
                        Vector3 blockCenterLocal = modelStorage.BoundingSphere.Center;
                        MatrixI blockOrientation = new MatrixI(block.SlimBlock.Orientation);
                        Vector3 blockCenter = new Vector3();
                        Vector3.Transform(ref blockCenterLocal, ref blockOrientation, out blockCenter);
                        if (blockCenter.LengthSquared() > 0.5f)
                        {
                            if (Math.Abs(blockCenter.X) > Math.Abs(blockCenter.Y))
                            {
                                if (Math.Abs(blockCenter.X) > Math.Abs(blockCenter.Z))
                                {
                                    preferedOffset = blockCenter.X > 0 ? 2 : 4;
                                }
                                else
                                {
                                    preferedOffset = blockCenter.Z > 0 ? 10 : 12;
                                }
                            }
                            else
                            {
                                if (Math.Abs(blockCenter.Z) > Math.Abs(blockCenter.Y))
                                {
                                    preferedOffset = blockCenter.Z > 0 ? 10 : 12;
                                }
                                else
                                {
                                    preferedOffset = blockCenter.Y > 0 ? 6 : 8;
                                }
                            }
                        }
                    }

                    for (int offsetIndex = preferedOffset; offsetIndex < offsetCount; ++offsetIndex)
                    {
                        if (!offsets[offsetIndex])
                        {
                            renderComponent.DepthBias = (byte)offsetIndex;
                            break;
                        }
                    }
                }
            }
        }
예제 #21
0
 public static MyBlockOrientation Transform(ref MyBlockOrientation orientation, ref MatrixI transform)
 {
     Base6Directions.Direction forward = transform.GetDirection(orientation.Forward);
     Base6Directions.Direction up      = transform.GetDirection(orientation.Up);
     return(new MyBlockOrientation(forward, up));
 }
예제 #22
0
        internal void MergeGrid(MyCubeGrid gridToMerge, ref MatrixI transform)
        {
            var msg = new MergeMsg();
            msg.GridEntityId = Entity.EntityId;
            msg.OtherEntityId = gridToMerge.EntityId;
            msg.GridOffset = transform.Translation;
            msg.GridForward = transform.Forward;
            msg.GridUp = transform.Up;

            Sync.Layer.SendMessageToAll(ref msg);
        }
        /// <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();
            }
        }
        protected static bool TestBlockPlacementOnGrid(MySlimBlock block, ref MatrixI transform, ref MyGridPlacementSettings settings, MyCubeGrid hitGrid)
        {
            Vector3I positionMin;
            Vector3I.Transform(ref block.Min, ref transform, out positionMin);
            Vector3I positionMax;
            Vector3I.Transform(ref block.Max, ref transform, out positionMax);
            Vector3I min = Vector3I.Min(positionMin, positionMax);
            Vector3I max = Vector3I.Max(positionMin, positionMax);

            var forward = transform.GetDirection(block.Orientation.Forward);
            var up = transform.GetDirection(block.Orientation.Up);
            MyBlockOrientation blockOrientation = new MyBlockOrientation(forward, up);
            return hitGrid.CanPlaceBlock(min, max, blockOrientation, block.BlockDefinition, ref settings);
        }
        private void ProcessChangedGrid(MyCubeGrid newGrid)
        {
            Vector3I gridOffset = Vector3I.Round((m_grid.PositionComp.GetPosition() - newGrid.PositionComp.GetPosition()) / m_grid.GridSize);
            Vector3 fw = (Vector3)Vector3D.TransformNormal(m_grid.WorldMatrix.Forward, newGrid.PositionComp.WorldMatrixNormalizedInv);
            Vector3 up = (Vector3)Vector3D.TransformNormal(m_grid.WorldMatrix.Up, newGrid.PositionComp.WorldMatrixNormalizedInv);
            Base6Directions.Direction fwDir = Base6Directions.GetClosestDirection(fw);
            Base6Directions.Direction upDir = Base6Directions.GetClosestDirection(up);
            if (upDir == fwDir) upDir = Base6Directions.GetPerpendicular(fwDir);
            MatrixI transform = new MatrixI(ref gridOffset, fwDir, upDir);

            MyGridInfo gridInfo = new MyGridInfo();
            gridInfo.Grid = newGrid;
            gridInfo.Transform = transform;

            m_splitGridInfos.Add(gridInfo);

            // Remove from split grid
            if (m_removeLocationsForGridSplits.Count > 0)
            {
                List<int> indexesToRemove = new List<int>();

                for (int i = 0; i < m_removeLocationsForGridSplits.Count; ++i)
                {
                    MyGeneratedBlockLocation location = m_removeLocationsForGridSplits[i];
                    Debug.Assert(location.GeneratedBlockType != MyStringId.NullOrEmpty);
                    RemoveBlock(location, gridInfo, location.GeneratedBlockType);
                }
            }

            // Add to split grid
            List<MySlimBlock> newGridBlocks = new List<MySlimBlock>();
            m_addLocations.RemoveWhere(delegate(MyGeneratedBlockLocation loc)
            {
                if (loc.RefBlock != null && loc.RefBlock.CubeGrid == newGrid)
                {
                    newGridBlocks.Add(loc.RefBlock);
                    return true;
                }
                return false;
            });

            foreach (var newGridBlock in newGridBlocks) 
            {
                Debug.Assert(newGrid == newGridBlock.CubeGrid);
                newGridBlock.CubeGrid.AdditionalModelGenerators.ForEach(g => g.UpdateAfterGridSpawn(newGridBlock));
            }
        }
예제 #26
0
        /// <summary>
        /// Converts the given grid to static with the world matrix. Instead of grid (which must have identity rotation for static grid) we transform blocks in the grid.
        /// </summary>
        /// <param name="originalGrid">grid to be transformed</param>
        /// <param name="worldMatrix">target world transform</param>
        private static void ConvertGridBuilderToStatic(MyObjectBuilder_CubeGrid originalGrid, MatrixD worldMatrix)
        {
            originalGrid.IsStatic = true;
            originalGrid.PositionAndOrientation = new MyPositionAndOrientation(originalGrid.PositionAndOrientation.Value.Position, Vector3.Forward, Vector3.Up);

            Vector3 fw = (Vector3)worldMatrix.Forward;
            Vector3 up = (Vector3)worldMatrix.Up;
            Base6Directions.Direction fwDir = Base6Directions.GetClosestDirection(fw);
            Base6Directions.Direction upDir = Base6Directions.GetClosestDirection(up);
            if (upDir == fwDir) 
                upDir = Base6Directions.GetPerpendicular(fwDir);
            MatrixI transform = new MatrixI(Vector3I.Zero, fwDir, upDir);

            // Blocks in static grid - must be recreated for static grid with different orientation and position
            foreach (var origBlock in originalGrid.CubeBlocks)
            {
                if (origBlock is MyObjectBuilder_CompoundCubeBlock)
                {
                    var origBlockCompound = origBlock as MyObjectBuilder_CompoundCubeBlock;
                    ConvertRotatedGridCompoundBlockToStatic(ref transform, origBlockCompound);
                    for (int i = 0; i < origBlockCompound.Blocks.Length; ++i)
                    {
                        var origBlockInCompound = origBlockCompound.Blocks[i];
                        ConvertRotatedGridBlockToStatic(ref transform, origBlockInCompound);
                    }
                }
                else
                {
                    ConvertRotatedGridBlockToStatic(ref transform, origBlock);
                }
            }
        }
예제 #27
0
        /// <summary>
        /// Fills rotation table for topology. Any arbitrary 90deg. rotation can then be converted to one unique rotation
        /// </summary>
        /// <param name="topology"></param>
        /// <param name="male">Tile which normal is tested to find unique rotations. If -1, all rotations are allowed</param>
        private static void FillRotationsForTopology(MyCubeTopology topology, int mainTile)
        {
            Vector3[] normals = new Vector3[m_allPossible90rotations.Length];

            m_uniqueTopologyRotationTable[(int)topology] = new MatrixI[m_allPossible90rotations.Length];

            for (int i = 0; i < m_allPossible90rotations.Length; i++)
            {
                int normalFound = -1;
                if (mainTile != -1)
                {
                    Vector3 transformedNormal;
                    Vector3.TransformNormal(ref m_tileTable[(int)topology].Tiles[mainTile].Normal, ref m_allPossible90rotations[i], out transformedNormal);
                    normals[i] = transformedNormal;
                    for (int j = 0; j < i; j++)
                    {
                        if (Vector3.Dot(normals[j], transformedNormal) > 0.98f)
                        {
                            normalFound = j;
                            break;
                        }
                    }
                }

                if (normalFound != -1)
                {
                    m_uniqueTopologyRotationTable[(int)topology][i] = m_uniqueTopologyRotationTable[(int)topology][normalFound];
                }
                else
                {
                    m_uniqueTopologyRotationTable[(int)topology][i] = m_allPossible90rotations[i];
                }
            }
        }
예제 #28
0
        /// <summary>
        /// Transforms given compound block with matrix for static grid. Rotation of block is not changed.
        /// </summary>
        private static void ConvertRotatedGridCompoundBlockToStatic(ref MatrixI transform, MyObjectBuilder_CompoundCubeBlock origBlock)
        {
            MyDefinitionId defId = new MyDefinitionId(origBlock.TypeId, origBlock.SubtypeName);
            MyCubeBlockDefinition blockDefinition;
            MyDefinitionManager.Static.TryGetCubeBlockDefinition(defId, out blockDefinition);
            if (blockDefinition == null)
                return;

            // Orientation quaternion is not setup in origblock
            MyBlockOrientation origOrientation = origBlock.BlockOrientation;
            Vector3I origMin = origBlock.Min;
            Vector3I origMax;
            MySlimBlock.ComputeMax(blockDefinition, origOrientation, ref origMin, out origMax);

            Vector3I tMin;
            Vector3I tMax;
            Vector3I.Transform(ref origMin, ref transform, out tMin);
            Vector3I.Transform(ref origMax, ref transform, out tMax);

            // Write data
            origBlock.Min = Vector3I.Min(tMin, tMax);
        }
예제 #29
0
        public static void RequestMergingCopyPaste(List<MyObjectBuilder_EntityBase> grids, long mergingGridId, MatrixI mergingTransform)
        {
            if (Sync.IsServer)
            {
                MySyncCreate.SendEntitiesCreated(grids);

                MyEntity entity;
                MyEntities.TryGetEntityById(mergingGridId, out entity);

                MyCubeGrid grid = entity as MyCubeGrid;
                Debug.Assert(grid != null);
                if (grid == null) return;

                MyEntity entity2;
                MyEntities.TryGetEntityById(grids[0].EntityId, out entity2);

                MyCubeGrid mergingGrid = entity2 as MyCubeGrid;
                Debug.Assert(mergingGrid != null);
                if (mergingGrid == null) return;

                grid.MergeGrid_CopyPaste(mergingGrid, mergingTransform);
            }
            else
            {
                MySyncCreate.SendMergingCopyPasteRequest(grids, mergingGridId, mergingTransform);
            }
        }
예제 #30
0
        protected static bool TestBlockPlacementOnGrid(MySlimBlock block, ref MatrixI transform, ref MyGridPlacementSettings settings, MyCubeGrid hitGrid)
        {
            Vector3I positionMin;
            Vector3I.Transform(ref block.Min, ref transform, out positionMin);
            Vector3I positionMax;
            Vector3I.Transform(ref block.Max, ref transform, out positionMax);
            Vector3I min = Vector3I.Min(positionMin, positionMax);
            Vector3I max = Vector3I.Max(positionMin, positionMax);

            Vector3I forward = Base6Directions.GetIntVector(transform.GetDirection(block.Orientation.Forward));
            Vector3I up = Base6Directions.GetIntVector(transform.GetDirection(block.Orientation.Up));

            MyBlockOrientation blockOrientation = new MyBlockOrientation(Base6Directions.GetDirection(forward), Base6Directions.GetDirection(up));

            if (!hitGrid.CanAddCubes(min, max, blockOrientation, block.BlockDefinition))
                return false;

            return MyCubeGrid.TestPlacementAreaCube(hitGrid, ref settings, min, max, blockOrientation, block.BlockDefinition, ignoredEntity: hitGrid);
        }
예제 #31
0
        private static void SendMergingCopyPasteRequest(List<MyObjectBuilder_EntityBase> grids, long mergingGridId, MatrixI mergingTransform)
        {
            MergingCopyPasteCompressedMsg msg;
            if (!BuildCompressedMessage(grids, out msg.CreateMessage))
                return;

            msg.MergeGridId = mergingGridId;
            msg.MergeOffset = mergingTransform.Translation;
            msg.MergeForward = mergingTransform.Forward;
            msg.MergeUp = mergingTransform.Up;

            MySession.Static.SyncLayer.SendMessageToServer(ref msg);
        }
예제 #32
0
        private Vector3 ConstraintPositionInGridSpace()
        {
            var cubeCenter = (Max + Min) * CubeGrid.GridSize * 0.5f;
            Vector3 centerOffset = ConnectionPosition - cubeCenter;
            centerOffset = Vector3.DominantAxisProjection(centerOffset);

            MatrixI orientation = new MatrixI(Vector3I.Zero, this.Orientation.Forward, this.Orientation.Up);
            Vector3 outExtents;
            Vector3.Transform(ref centerOffset, ref orientation, out outExtents);

            return cubeCenter + centerOffset;
        }
예제 #33
0
        private static void OnMessageCompressedRequest(ref MergingCopyPasteCompressedMsg msg, MyNetworkClient sender)
        {
            MySandboxGame.Log.WriteLine("MergingCopyPasteCompressedMsg received");
            MySession.Static.SyncLayer.SendMessageToAllButOne(ref msg.CreateMessage, sender.SteamUserId);

            MyEntity firstEntity = OnMessageCompressedInternal(ref msg.CreateMessage);

            MyEntity entity;
            MyEntities.TryGetEntityById(msg.MergeGridId, out entity);

            MyCubeGrid grid = entity as MyCubeGrid;
            Debug.Assert(grid != null);
            if (grid == null) return;

            MyCubeGrid mergingGrid = firstEntity as MyCubeGrid;
            Debug.Assert(mergingGrid != null);
            if (mergingGrid == null) return;

            Vector3I offset = msg.MergeOffset;
            MatrixI mergeOffset = new MatrixI(ref offset, msg.MergeForward, msg.MergeUp);

            grid.MergeGrid_CopyPaste(mergingGrid, mergeOffset);
        }
예제 #34
0
        /// <summary>
        /// Called when block is destroyed before being removed from grid
        /// </summary>
        //public void OnDestroy()
        //{
        //    if (FatBlock != null)
        //    {
        //        Profiler.Begin("MySlimBlock.OnDestroy");
        //        FatBlock.OnDestroy();
        //        Profiler.End();
        //    }
        //}

        public static void ComputeMax(MyCubeBlockDefinition definition, MyBlockOrientation orientation, ref Vector3I min, out Vector3I max)
        {
            Vector3I size = definition.Size - 1;
            MatrixI localMatrix = new MatrixI(orientation);
            Vector3I.TransformNormal(ref size, ref localMatrix, out size);
            Vector3I.Abs(ref size, out size);
            max = min + size;
        }
예제 #35
0
 internal override void OnTransformed(ref MatrixI transform)
 {
     foreach (var pair in m_blocks)
     {
         pair.Value.Transform(ref transform);
     }
 }
예제 #36
0
        private bool IsRotationValid(MyBlockOrientation refOrientation, MyBlockOrientation orientation, MyBlockOrientation[] validRotations)
        {
            Debug.Assert(validRotations != null);

            // Ref matrix
            MatrixI localMatrix = new MatrixI(Vector3I.Zero, refOrientation.Forward, refOrientation.Up);
            MatrixI inverseMatrix;
            MatrixI.Invert(ref localMatrix, out inverseMatrix);
            Matrix inverseMatrixF = inverseMatrix.GetFloatMatrix();

            // Transform orientation to ref
            Base6Directions.Direction forward = Base6Directions.GetClosestDirection(Vector3.TransformNormal((Vector3)Base6Directions.GetIntVector(orientation.Forward), inverseMatrixF));
            Base6Directions.Direction up = Base6Directions.GetClosestDirection(Vector3.TransformNormal((Vector3)Base6Directions.GetIntVector(orientation.Up), inverseMatrixF));

            foreach (var validRotation in validRotations)
            {
                if (validRotation.Forward == forward && validRotation.Up == up)
                    return true;
            }

            return false;
        }
예제 #37
0
        public static MatrixI CreateRotation(Base6Directions.Direction oldA, Base6Directions.Direction oldB, Base6Directions.Direction newA, Base6Directions.Direction newB)
        {
            Debug.Assert(Base6Directions.GetAxis(oldA) != Base6Directions.GetAxis(oldB), "Original vectors must not lie in line!");
            Debug.Assert(Base6Directions.GetAxis(newA) != Base6Directions.GetAxis(newB), "Transformed vectors must not lie in line!");

            MatrixI newMatrix = new MatrixI();
            newMatrix.Translation = Vector3I.Zero;

            Base6Directions.Direction oldC = Base6Directions.GetCross(oldA, oldB);
            Base6Directions.Direction newC = Base6Directions.GetCross(newA, newB);

            newMatrix.SetDirection(oldA, newA);
            newMatrix.SetDirection(oldB, newB);
            newMatrix.SetDirection(oldC, newC);

            return newMatrix;
        }
예제 #38
0
 public static void TransformNormal(ref Vector3I normal, ref MatrixI matrix, out Vector3I result)
 {
     result = normal.X * Base6Directions.GetIntVector(matrix.Right) +
              normal.Y * Base6Directions.GetIntVector(matrix.Up) +
              normal.Z * Base6Directions.GetIntVector(matrix.Backward);
 }
예제 #39
0
        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);
        }