private 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;
            }

            return(offsetCenter);
        }
Exemplo n.º 2
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);
        }
Exemplo n.º 3
0
 internal override void OnTransformed(ref MatrixI transform)
 {
     foreach (KeyValuePair <ushort, MySlimBlock> pair in this.m_mapIdToBlock)
     {
         pair.Value.Transform(ref transform);
     }
 }
Exemplo n.º 4
0
        /// <summary>
        /// Registers the given room as a possibility if it isn't already registered.
        /// </summary>
        /// <param name="transform"></param>
        /// <param name="part"></param>
        private RoomMeta RegisterKey(MatrixI transform, PartFromPrefab part)
        {
            var      key = new RoomKey(transform, part);
            RoomMeta room;

            if (!m_openRooms.TryGetValue(key, out room))
            {
                var ent = new ProceduralRoom();
                ent.Init(transform, part);
                m_openRooms[key] = room = new RoomMeta(ent);
            }
            else if (room.Nonce == m_nonce)
            {
                return(room);
            }
            room.Nonce    = m_nonce;
            room.InFactor = 0;
            foreach (var mount in room.Room.MountPoints)
            {
                var other = mount.AttachedToIn(m_construction);
                if (other == null)
                {
                    continue;
                }
                room.InFactor++;
                m_possibleRooms.Add(other, room);
            }
            return(room);
        }
Exemplo n.º 5
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);
        }
Exemplo n.º 6
0
 internal override void OnTransformed(ref MatrixI transform)
 {
     foreach (var pair in m_blocks)
     {
         pair.Value.Transform(ref transform);
     }
 }
        public static bool Intersects(ref PartFromPrefab partA, ref MatrixI transformA, ref MatrixI invTransformA, ref PartFromPrefab partB, ref MatrixI transformB, ref MatrixI invTransformB, bool testOptional, bool testQuick = false)
        {
            var cheapResult = IntersectsInternalCheap(ref partA, ref transformA, ref invTransformA, ref partB, ref transformB, ref invTransformB, testOptional);

            switch (cheapResult)
            {
            case CheapIntersection.Yes:
                return(true);

            case CheapIntersection.No:
                return(false);

            case CheapIntersection.Maybe:
            default:
                break;
            }
            if (testQuick)
            {
                return(true);
            }

            MatrixI abTransform;

            MatrixI.Multiply(ref transformA, ref invTransformB, out abTransform);
            var  key = new IntersectKey(partA, partB, abTransform, testOptional);
            bool result;

            // ReSharper disable once ConvertIfStatementToReturnStatement
            // TODO when threading cause a wait when another thread is preparing this cache value?
            if (IntersectionCache.TryGet(key, out result))
            {
                return(result);
            }
            return(IntersectionCache.Store(key, IntersectsInternalExpensive(ref partA, ref transformA, ref invTransformA, ref partB, ref transformB, ref invTransformB, testOptional)));
        }
 public IntersectKey(PartFromPrefab partA, PartFromPrefab partB, MatrixI transformAB, bool testOptional)
 {
     m_partA        = partA;
     m_partB        = partB;
     m_transformAB  = transformAB;
     m_testOptional = testOptional;
 }
        /// <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);
        }
Exemplo n.º 10
0
        public static MatrixI Multiply(MatrixI left, MatrixI right)
        {
            MatrixI result;

            MatrixI.Multiply(ref left, ref right, out result);
            return(result);
        }
Exemplo n.º 11
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);
        }
        private static Vector3I ComputePositionInGrid(MatrixI localMatrix, MyCubeBlockDefinition blockDefinition, Vector3I min)
        {
            Vector3I center   = blockDefinition.Center;
            Vector3I vector3I = blockDefinition.Size - 1;
            Vector3I value;

            Vector3I.TransformNormal(ref vector3I, ref localMatrix, out value);
            Vector3I a;

            Vector3I.TransformNormal(ref center, ref localMatrix, out a);
            Vector3I vector3I2 = Vector3I.Abs(value);
            Vector3I result    = a + min;

            if (value.X != vector3I2.X)
            {
                result.X += vector3I2.X;
            }
            if (value.Y != vector3I2.Y)
            {
                result.Y += vector3I2.Y;
            }
            if (value.Z != vector3I2.Z)
            {
                result.Z += vector3I2.Z;
            }

            return(result);
        }
Exemplo n.º 13
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);
                }
            }
        }
Exemplo n.º 14
0
        public static BoundingBox TransformBoundingBox(BoundingBox box, ref MatrixI matrix)
        {
            Vector3 a, b;

            Vector3.Transform(ref box.Min, ref matrix, out a);
            Vector3.Transform(ref box.Max, ref matrix, out b);
            return(new BoundingBox(Vector3.Min(a, b), Vector3.Max(a, b)));
        }
Exemplo n.º 15
0
        private void FixCubeFace(ref Vector3I pos, ref Vector3I dir)
        {
            if (m_cubeSet.Contains(ref pos))
            {
                // TODO: In the future, we'll have to remove the face's triangles
                // TODO: Cash the neighboring blocks in real-time and then perform the mesh modification on another thread
                var cubeBlock = m_grid.GetCubeBlock(pos);

                var compound = cubeBlock.FatBlock as MyCompoundCubeBlock;
                if (compound != null)
                {
                    var         blocks     = compound.GetBlocks();
                    MySlimBlock firstBlock = null;
                    foreach (var subblock in blocks)
                    {
                        if (subblock.BlockDefinition.NavigationDefinition != null)
                        {
                            firstBlock = subblock;
                            break;
                        }
                    }

                    if (firstBlock != null)
                    {
                        cubeBlock = firstBlock;
                    }
                }

                if (cubeBlock.BlockDefinition.NavigationDefinition == null)
                {
                    return;
                }

                MatrixI  transform = new MatrixI(cubeBlock.Position, cubeBlock.Orientation.Forward, cubeBlock.Orientation.Up);
                MatrixI  invTform; MatrixI.Invert(ref transform, out invTform);
                Vector3I meshPos; Vector3I.Transform(ref pos, ref invTform, out meshPos);
                Vector3I faceDir; Vector3I.TransformNormal(ref dir, ref invTform, out faceDir);

                var neighborMesh = cubeBlock.BlockDefinition.NavigationDefinition.Mesh;
                if (neighborMesh == null)
                {
                    return;
                }

                List <int> list;
                if (neighborMesh.m_smallTriangleRegistry.TryGetValue(meshPos, out list))
                {
                    foreach (var triIndex in list)
                    {
                        var triangle = neighborMesh.GetTriangle(triIndex);
                        if (IsFaceTriangle(triangle, meshPos, faceDir))
                        {
                            CopyTriangle(triangle, meshPos, ref transform);
                        }
                    }
                }
            }
        }
        private 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;
        }
Exemplo n.º 17
0
        private Vector3I ComputeMax(MyObjectBuilder_CubeBlock cube)
        {
            MyCubeBlockDefinition definition = MyDefinitionManager.Static.GetCubeBlockDefinition(cube.GetId());
            Vector3I result = definition.Size - 1;
            MatrixI  matrix = new MatrixI(cube.BlockOrientation);

            Vector3I.TransformNormal(ref result, ref matrix, out result);
            Vector3I.Abs(ref result, out result);
            return(cube.Min + result);
        }
Exemplo n.º 18
0
 public bool GetMissingBlocks(out MatrixI transform, List <int> multiBlockIndices)
 {
     for (int i = 0; i < this.MultiBlockDefinition.BlockDefinitions.Length; i++)
     {
         if (!this.Blocks.Any <MySlimBlock>(b => (b.MultiBlockIndex == i)))
         {
             multiBlockIndices.Add(i);
         }
     }
     return(this.GetTransform(out transform));
 }
        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));
            }
        }
Exemplo n.º 20
0
        public static IMyTerminalBlock GetBlockFromReferenceAndPosition(IMyTerminalBlock reference, Vector3I position)
        {
            var      matrix = new MatrixI(reference.Orientation);
            var      pos    = new Vector3I(-position.X, position.Y, -position.Z);
            Vector3I transformed;

            Vector3I.Transform(ref pos, ref matrix, out transformed);
            transformed += reference.Position;
            var slim = reference.CubeGrid.GetCubeBlock(transformed);

            return(slim == null ? null : slim.FatBlock as IMyTerminalBlock);
        }
Exemplo n.º 21
0
 public void GetTransformed(ref MatrixI tform, out Vector3 newA, out Vector3 newB, out Vector3 newC)
 {
     MyWingedEdgeMesh.FaceVertexEnumerator vertexEnumerator = this.m_navMesh.Mesh.GetFace(this.m_triIndex).GetVertexEnumerator();
     vertexEnumerator.MoveNext();
     newA = vertexEnumerator.Current;
     Vector3.Transform(ref newA, ref tform, out newA);
     vertexEnumerator.MoveNext();
     newB = vertexEnumerator.Current;
     Vector3.Transform(ref newB, ref tform, out newB);
     vertexEnumerator.MoveNext();
     newC = vertexEnumerator.Current;
     Vector3.Transform(ref newC, ref tform, out newC);
 }
Exemplo n.º 22
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));
                        }
                    }
                }
            }
        }
        public bool Intersects(PartFromPrefab other, MatrixI otherTransform, MatrixI otherITransform, bool testOptional, bool testQuick = false, ProceduralRoom ignore = null)
        {
            var bb     = Utilities.TransformBoundingBox(other.BoundingBoxBoth, otherTransform);
            var result = false;

            m_roomTree.Query((x) =>
            {
                var test = m_roomTree.GetUserData <ProceduralRoom>(x);
                var res  = test != ignore && test.Intersects(other, otherTransform, otherITransform, testOptional, testQuick);
                result   = res;
                return(!res);
            }, ref bb);
            return(result);
        }
Exemplo n.º 24
0
        public static void ComputeBlockMax(MyObjectBuilder_CubeBlock block, ref MyCubeBlockDefinition definition, out Vector3I max)
        {
            if (definition == null)
            {
                max = block.Min;
                return;
            }
            var size        = definition.Size - 1;
            var localMatrix = new MatrixI(new MyBlockOrientation(block.BlockOrientation.Forward, block.BlockOrientation.Up));

            Vector3I.TransformNormal(ref size, ref localMatrix, out size);
            Vector3I.Abs(ref size, out size);
            max = block.Min + size;
        }
Exemplo n.º 25
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);

            return(MyCubeGrid.CheckConnectivity(hitGrid, block.BlockDefinition, ref rotation, ref position));
        }
Exemplo n.º 26
0
        private void AddBlock(MySlimBlock block)
        {
            Vector3I min = block.Min;
            Vector3I max = block.Max;
            Vector3I_RangeIterator iterator = new Vector3I_RangeIterator(ref min, ref max);

            while (iterator.IsValid())
            {
                this.m_cubeSet.Add(ref min);
                iterator.GetNext(out min);
            }
            MatrixI transform = new MatrixI(block.Position, block.Orientation.Forward, block.Orientation.Up);

            this.MergeFromAnotherMesh(block.BlockDefinition.NavigationDefinition.Mesh, ref transform);
        }
Exemplo n.º 27
0
        public IEnumerable <MatrixI> GetTransform(PartMount otherMount)
        {
            HashSet <MatrixI> output;

            if (MountCache.TryGet(MyTuple.Create(otherMount, this), out output))
            {
                return(output?.Select(x =>
                {
                    MatrixI val;
                    MatrixI.Invert(ref x, out val);
                    return val;
                }));
            }
            return(MountCache.GetOrCreate(MyTuple.Create(this, otherMount), GetTransformInternal));
        }
        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));
        }
Exemplo n.º 29
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);
        }
        public void GetTransforms(PartMountPointBlock other, HashSet <MatrixI> cache)
        {
            var dirSelf  = Base6Directions.GetOppositeDirection(MountDirection6);
            var dirOther = other.MountDirection6;

            if (other.BiasDirection6.HasValue && BiasDirection6.HasValue)
            {
                // Simple case.  Only one possible transform.
                var tmp = new MatrixI();
                // Mount directions need to be aligned
                tmp.SetDirection(dirOther, dirSelf);
                // Bias directions must be aligned
                var biasSelf  = BiasDirection6.Value;
                var biasOther = other.BiasDirection6.Value;
                tmp.SetDirection(biasOther, biasSelf);
                // Final alignment
                tmp.SetDirection(Base6Directions.GetCross(dirOther, biasOther), Base6Directions.GetCross(dirSelf, biasSelf));
                // Check secondary alignment when present.  If it fails just return.  These will never work.
                if (other.SecondBiasDirection6.HasValue && SecondBiasDirection6.HasValue &&
                    tmp.GetDirection(other.SecondBiasDirection6.Value) != SecondBiasDirection6.Value)
                {
                    return;
                }
                tmp.Translation = AnchorLocation - Vector3I.TransformNormal(other.MountLocation, ref tmp);
                cache.Add(tmp);
                return;
            }

            // Complicated case.  4 possibilities
            // Perp. axis using +2
            // Base direction for axis (first entry) using ~1
            var dirSelfI  = ((int)dirSelf & ~1) + 2;
            var dirOtherI = ((int)dirOther & ~1) + 2;

            for (var i = 0; i < 4; i++)
            {
                var tmp = new MatrixI();
                tmp.SetDirection(dirOther, dirSelf);
                // Align one of the 4 perp. vectors with another perp vector
                var biasSelf  = Base6Directions.EnumDirections[dirSelfI % 6];
                var biasOther = Base6Directions.EnumDirections[(dirOtherI + i) % 6];
                tmp.SetDirection(biasOther, biasSelf);
                // Complete the matrix
                tmp.SetDirection(Base6Directions.GetCross(dirOther, biasOther), Base6Directions.GetCross(dirSelf, biasSelf));
                tmp.Translation = AnchorLocation - Vector3I.TransformNormal(other.MountLocation, ref tmp);
                cache.Add(tmp);
            }
        }