protected override void UpdateGridTransformations()
        {
            MatrixD worldMatrix = m_projector.WorldMatrix;

            if (m_firstUpdateAfterNewBlueprint || m_oldProjectorRotation != m_projector.ProjectionRotation || m_oldProjectorOffset != m_projector.ProjectionOffset || !m_oldProjectorMatrix.EqualsFast(ref worldMatrix))
            {
                m_firstUpdateAfterNewBlueprint = false;
                m_oldProjectorRotation         = m_projector.ProjectionRotation;
                m_oldProjectorMatrix           = worldMatrix;
                m_oldProjectorOffset           = m_projector.ProjectionOffset;

                // Update rotation based on projector settings
                Quaternion rotation       = m_projector.ProjectionRotationQuaternion;
                Matrix     rotationMatrix = Matrix.CreateFromQuaternion(rotation);
                worldMatrix = Matrix.Multiply(rotationMatrix, worldMatrix);

                // Update PreviewGrids
                for (int i = 0; i < PreviewGrids.Count; i++)
                {
                    // ensure the first block touches the projector base at (0,0,0) projector offset config
                    MySlimBlock firstBlock    = PreviewGrids[i].CubeBlocks.First();
                    Vector3D    firstBlockPos = MyCubeGrid.GridIntegerToWorld(PreviewGrids[i].GridSize, firstBlock.Position, worldMatrix);

                    Vector3D delta = firstBlockPos - m_projector.WorldMatrix.Translation;

                    // Re-adjust position
                    Vector3D projectionOffset = m_projector.GetProjectionTranslationOffset();
                    projectionOffset         = Vector3D.Transform(projectionOffset, m_projector.WorldMatrix.GetOrientation());
                    worldMatrix.Translation -= delta + projectionOffset;

                    PreviewGrids[i].PositionComp.SetWorldMatrix(worldMatrix);
                }
            }
        }
        protected override void UpdateGridTransformations()
        {
            MatrixD originalOrientation = Matrix.Multiply(base.GetFirstGridOrientationMatrix(), m_projector.WorldMatrix);
            var     invRotation         = Matrix.Invert(CopiedGrids[0].PositionAndOrientation.Value.GetMatrix()).GetOrientation();
            MatrixD orientationDelta    = invRotation * originalOrientation; // matrix from original orientation to new orientation

            for (int i = 0; i < PreviewGrids.Count; i++)
            {
                MatrixD worldMatrix2 = CopiedGrids[i].PositionAndOrientation.Value.GetMatrix();                         //get original rotation and position
                var     offset       = worldMatrix2.Translation - CopiedGrids[0].PositionAndOrientation.Value.Position; //calculate offset to first pasted grid
                m_copiedGridOffsets[i] = Vector3D.TransformNormal(offset, orientationDelta);                            // Transform the offset to new orientation
                if (!AnyCopiedGridIsStatic)
                {
                    worldMatrix2 = worldMatrix2 * orientationDelta;              //correct rotation
                }
                Vector3D translation = m_pastePosition + m_copiedGridOffsets[i]; //correct position

                worldMatrix2.Translation = Vector3.Zero;
                worldMatrix2             = Matrix.Orthogonalize(worldMatrix2);
                worldMatrix2.Translation = translation + Vector3D.Transform(m_projector.GetProjectionTranslationOffset(), m_projector.WorldMatrix.GetOrientation());

                PreviewGrids[i].PositionComp.SetWorldMatrix(worldMatrix2);// Set the corrected position
            }
        }