Example #1
0
        protected static void AddFastBuildModelWithSubparts(ref MatrixD matrix, List <MatrixD> matrices, List <string> models, MyCubeBlockDefinition blockDefinition)
        {
            if (string.IsNullOrEmpty(blockDefinition.Model))
            {
                return;
            }

            matrices.Add(matrix);
            models.Add(blockDefinition.Model);
            var data = new MyEntitySubpart.Data();

            MyCubeBlockDefinition subBlockDefinition;
            MatrixD subBlockMatrix;
            Vector3 dummyPosition;

            MyModel modelData = MyModels.GetModelOnlyData(blockDefinition.Model);

            foreach (var dummy in modelData.Dummies)
            {
                if (MyEntitySubpart.GetSubpartFromDummy(blockDefinition.Model, dummy.Key, dummy.Value, ref data))
                {
                    MatrixD mCopy = MatrixD.Multiply(data.InitialTransform, matrix);
                    matrices.Add(mCopy);
                    models.Add(data.File);
                }
                else if (MyFakes.ENABLE_SUBBLOCKS &&
                         MyCubeBlock.GetSubBlockDataFromDummy(blockDefinition, dummy.Key, dummy.Value, false, out subBlockDefinition, out subBlockMatrix, out dummyPosition))
                {
                    if (!string.IsNullOrEmpty(subBlockDefinition.Model))
                    {
                        // Repair subblock matrix to have int axes (because preview renderer does not allow such non integer rotation).
                        Vector3I forward    = Vector3I.Round(Vector3.DominantAxisProjection(subBlockMatrix.Forward));
                        Vector3I invForward = Vector3I.One - Vector3I.Abs(forward);
                        Vector3I right      = Vector3I.Round(Vector3.DominantAxisProjection((Vector3)subBlockMatrix.Right * invForward));
                        Vector3I up;
                        Vector3I.Cross(ref right, ref forward, out up);

                        subBlockMatrix.Forward = forward;
                        subBlockMatrix.Right   = right;
                        subBlockMatrix.Up      = up;

                        MatrixD mCopy = MatrixD.Multiply(subBlockMatrix, matrix);
                        matrices.Add(mCopy);
                        models.Add(subBlockDefinition.Model);
                    }
                }
            }
        }
Example #2
0
        public void RotateAsteroid(VRageMath.Quaternion quaternion)
        {
            var sourceFile = SourceVoxelFilepath ?? VoxelFilepath;

            var asteroid = new MyVoxelMap();

            asteroid.Load(sourceFile, SpaceEngineersCore.Resources.GetDefaultMaterialName(), true);

            var newAsteroid = new MyVoxelMap();
            var transSize   = Vector3I.Transform(asteroid.Size, quaternion);
            var newSize     = Vector3I.Abs(transSize);

            newAsteroid.Init(Vector3D.Zero, newSize, SpaceEngineersCore.Resources.GetDefaultMaterialName());

            Vector3I coords;

            for (coords.Z = 0; coords.Z < asteroid.Size.Z; coords.Z++)
            {
                for (coords.Y = 0; coords.Y < asteroid.Size.Y; coords.Y++)
                {
                    for (coords.X = 0; coords.X < asteroid.Size.X; coords.X++)
                    {
                        byte   volume = 0xff;
                        string cellMaterial;

                        asteroid.GetVoxelMaterialContent(ref coords, out cellMaterial, out volume);

                        var newCoord = Vector3I.Transform(coords, quaternion);
                        // readjust the points, as rotation occurs arround 0,0,0.
                        newCoord.X = newCoord.X < 0 ? newCoord.X - transSize.X : newCoord.X;
                        newCoord.Y = newCoord.Y < 0 ? newCoord.Y - transSize.Y : newCoord.Y;
                        newCoord.Z = newCoord.Z < 0 ? newCoord.Z - transSize.Z : newCoord.Z;
                        newAsteroid.SetVoxelContent(volume, ref newCoord);
                        newAsteroid.SetVoxelMaterialAndIndestructibleContent(cellMaterial, 0xff, ref newCoord);
                    }
                }
            }

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

            newAsteroid.Save(tempfilename);

            SourceVoxelFilepath = tempfilename;
        }
Example #3
0
        // Contributed by Conrad "Redshift" Morgan
        protected static IEnumerable<Vector3I> LineEnumerator(Vector3I a, Vector3I b) {
            Vector3I pixel = a;
            Vector3I d = b - a;
            Vector3I inc = new Vector3I(Math.Sign(d.X),
                                        Math.Sign(d.Y),
                                        Math.Sign(d.Z));
            d = d.Abs();
            Vector3I d2 = d * 2;

            int x, y, z;
            if ((d.X >= d.Y) && (d.X >= d.Z)) {
                x = 0;
                y = 1;
                z = 2;
            } else if ((d.Y >= d.X) && (d.Y >= d.Z)) {
                x = 1;
                y = 2;
                z = 0;
            } else {
                x = 2;
                y = 0;
                z = 1;
            }

            int err1 = d2[y] - d[x];
            int err2 = d2[z] - d[x];
            for (int i = 0; i < d[x]; i++) {
                yield return pixel;
                if (err1 > 0) {
                    pixel[y] += inc[y];
                    err1 -= d2[x];
                }
                if (err2 > 0) {
                    pixel[z] += inc[z];
                    err2 -= d2[x];
                }
                err1 += d2[y];
                err2 += d2[z];
                pixel[x] += inc[x];
            }

            yield return b;
        }
        /// <summary>
        /// Checks if blocks are neigbors to block(s) in aabbForNeighbors.
        /// </summary>
        private static void CheckNeighborBlocks(MySlimBlock block, BoundingBoxD aabbForNeighbors, MyCubeGrid cubeGrid, List <MySlimBlock> blocks)
        {
            var      compositeTransformToGrid = block.CubeGrid.WorldMatrix * cubeGrid.PositionComp.WorldMatrixNormalizedInv;
            var      aabbForNeighborsInGrid   = aabbForNeighbors.TransformFast(ref compositeTransformToGrid);
            Vector3I start   = Vector3I.Round(cubeGrid.GridSizeR * aabbForNeighborsInGrid.Min);
            Vector3I end     = Vector3I.Round(cubeGrid.GridSizeR * aabbForNeighborsInGrid.Max);
            Vector3I startIt = Vector3I.Min(start, end);
            Vector3I endIt   = Vector3I.Max(start, end);

            for (int slimBlockIndex = blocks.Count - 1; slimBlockIndex >= 0; --slimBlockIndex)
            {
                var  slimBlock = blocks[slimBlockIndex];
                bool found     = false;

                Vector3I_RangeIterator itBlockInGridPos = new Vector3I_RangeIterator(ref slimBlock.Min, ref slimBlock.Max);
                var posInGrid = itBlockInGridPos.Current;
                for (; itBlockInGridPos.IsValid(); itBlockInGridPos.GetNext(out posInGrid))
                {
                    Vector3I_RangeIterator itBlockPos = new Vector3I_RangeIterator(ref startIt, ref endIt);
                    var pos = itBlockPos.Current;
                    for (; itBlockPos.IsValid(); itBlockPos.GetNext(out pos))
                    {
                        Vector3I diff = Vector3I.Abs(posInGrid - pos);
                        if (pos == posInGrid || diff.X + diff.Y + diff.Z == 1)
                        {
                            found = true;
                            break;
                        }
                    }

                    if (found)
                    {
                        break;
                    }
                }

                if (!found)
                {
                    blocks.RemoveAt(slimBlockIndex);
                }
            }
        }
        protected void DrawBuildingStepsCount(Vector3I?startBuild, Vector3I?startRemove, Vector3I?continueBuild, ref Matrix localMatrixAdd)
        {
            var startPosition = startBuild ?? startRemove;

            if (startPosition != null && continueBuild != null)
            {
                Vector3I rotatedSize;
                Vector3I.TransformNormal(ref CurrentBlockDefinition.Size, ref localMatrixAdd, out rotatedSize);
                rotatedSize = Vector3I.Abs(rotatedSize);

                int      stepCount;
                Vector3I stepDelta;
                Vector3I counter;

                ComputeSteps(startPosition.Value, continueBuild.Value, startBuild.HasValue ? rotatedSize : Vector3I.One, out stepDelta, out counter, out stepCount);
                m_cubeCountStringBuilder.Clear();
                m_cubeCountStringBuilder.Append("  ");
                m_cubeCountStringBuilder.AppendInt32(stepCount);

                MyGuiManager.DrawString(MyFontEnum.White, m_cubeCountStringBuilder, new Vector2(0.5f, 0.5f), 1.5f);
            }
        }
Example #6
0
        static DeformationTable CreateTable(Vector3I normal)
        {
            DeformationTable result = new DeformationTable();

            result.Normal = normal;

            Vector3I centerBone = new Vector3I(1, 1, 1);
            var      absNormal  = Vector3I.Abs(normal);
            var      mask       = new Vector3I(1, 1, 1) - absNormal;

            mask *= 2;

            for (int x = -mask.X; x <= mask.X; x++)
            {
                for (int y = -mask.Y; y <= mask.Y; y++)
                {
                    for (int z = -mask.Z; z <= mask.Z; z++)
                    {
                        var offset = new Vector3I(x, y, z);

                        float maxOffset = Math.Max(Math.Abs(z), Math.Max(Math.Abs(x), Math.Abs(y)));
                        float ratio     = 1;
                        if (maxOffset > 1)
                        {
                            ratio = 0.3f;
                        }

                        float    moveDist = ratio * MyGridConstants.DEFORMATION_TABLE_BASE_MOVE_DIST;
                        Vector3I offsetA  = centerBone + new Vector3I(x, y, z) + normal;
                        result.OffsetTable.Add(offsetA, -normal * moveDist);

                        result.MinOffset = Vector3I.Min(result.MinOffset, offset);
                        result.MaxOffset = Vector3I.Max(result.MaxOffset, offset);
                    }
                }
            }
            return(result);
        }
Example #7
0
        private int GetBlockTotalEstimate()
        {
            Vector3I nabs = normal.Abs();

            return(Math.Max(Math.Max(nabs.X, nabs.Y), nabs.Z) / 2);
        }
Example #8
0
        protected static void AddFastBuildModelWithSubparts(ref MatrixD matrix, List <MatrixD> matrices, List <string> models, MyCubeBlockDefinition blockDefinition, float gridScale)
        {
            if (string.IsNullOrEmpty(blockDefinition.Model))
            {
                return;
            }

            matrices.Add(matrix);
            models.Add(blockDefinition.Model);
            var data = new MyEntitySubpart.Data();

            MyCubeBlockDefinition subBlockDefinition;
            MatrixD subBlockMatrix;
            Vector3 dummyPosition;

            MyModel modelData = VRage.Game.Models.MyModels.GetModelOnlyData(blockDefinition.Model);

            modelData.Rescale(gridScale);
            foreach (var dummy in modelData.Dummies)
            {
                if (MyEntitySubpart.GetSubpartFromDummy(blockDefinition.Model, dummy.Key, dummy.Value, ref data))
                {
                    // Rescale model
                    var model = VRage.Game.Models.MyModels.GetModelOnlyData(data.File);
                    if (model != null)
                    {
                        model.Rescale(gridScale);
                    }

                    MatrixD mCopy = MatrixD.Multiply(data.InitialTransform, matrix);
                    matrices.Add(mCopy);
                    models.Add(data.File);
                }
                else if (MyFakes.ENABLE_SUBBLOCKS &&
                         MyCubeBlock.GetSubBlockDataFromDummy(blockDefinition, dummy.Key, dummy.Value, false, out subBlockDefinition, out subBlockMatrix, out dummyPosition))
                {
                    if (!string.IsNullOrEmpty(subBlockDefinition.Model))
                    {
                        // Rescale model
                        var model = VRage.Game.Models.MyModels.GetModelOnlyData(subBlockDefinition.Model);
                        if (model != null)
                        {
                            model.Rescale(gridScale);
                        }

                        // Repair subblock matrix to have int axes (because preview renderer does not allow such non integer rotation).
                        Vector3I forward    = Vector3I.Round(Vector3.DominantAxisProjection(subBlockMatrix.Forward));
                        Vector3I invForward = Vector3I.One - Vector3I.Abs(forward);
                        Vector3I right      = Vector3I.Round(Vector3.DominantAxisProjection((Vector3)subBlockMatrix.Right * invForward));
                        Vector3I up;
                        Vector3I.Cross(ref right, ref forward, out up);

                        subBlockMatrix.Forward = forward;
                        subBlockMatrix.Right   = right;
                        subBlockMatrix.Up      = up;

                        MatrixD mCopy = MatrixD.Multiply(subBlockMatrix, matrix);
                        matrices.Add(mCopy);
                        models.Add(subBlockDefinition.Model);
                    }
                }
            }

            // Precache models for generated blocks
            if (MyFakes.ENABLE_GENERATED_BLOCKS && !blockDefinition.IsGeneratedBlock && blockDefinition.GeneratedBlockDefinitions != null)
            {
                foreach (var generatedBlockDefId in blockDefinition.GeneratedBlockDefinitions)
                {
                    MyCubeBlockDefinition generatedBlockDef;
                    if (MyDefinitionManager.Static.TryGetCubeBlockDefinition(generatedBlockDefId, out generatedBlockDef))
                    {
                        var model = VRage.Game.Models.MyModels.GetModelOnlyData(generatedBlockDef.Model);
                        if (model != null)
                        {
                            model.Rescale(gridScale);
                        }
                    }
                }
            }
        }
        public override void Draw()
        {
            base.Draw();

            //VRageRender.MyRenderProxy.DebugDrawAABB(m_cubeBuilderAABB, Vector3.One, 1, 1, false);

            if (BlockCreationIsActivated)
            {
                MyHud.Crosshair.Position = MyHudCrosshair.ScreenCenter;
            }

            if (IsActivated)
            {
                if (DynamicMode)
                {
                    CurrentGrid     = null;
                    CurrentVoxelMap = null;
                }
                else
                {
                    ChoosePlacementObject();
                }
            }

            if (ShipCreationIsActivated)
            {
                m_shipCreationClipboard.Update();
                ShipCreationClipboard.CalculateRotationHints(m_rotationHints, m_rotationHintRotating);
            }
            else if (CopyPasteIsActivated)
            {
                Clipboard.CalculateRotationHints(m_rotationHints, m_rotationHintRotating);
            }
            else if (CopyPasteFloatingObjectIsActivated)
            {
                FloatingObjectClipboard.CalculateRotationHints(m_rotationHints, m_rotationHintRotating);
            }
            else if (MultiBlockCreationIsActivated)
            {
                m_multiBlockCreationClipboard.CalculateRotationHints(m_rotationHints, false);
            }

            if (!BuildInputValid || MultiBlockCreationIsActivated || ShipCreationIsActivated || CopyPasteIsActivated || CopyPasteFloatingObjectIsActivated)
            {
                m_renderData.ClearInstanceData();
                m_renderData.UpdateRenderInstanceData();
                m_renderData.UpdateRenderEntitiesData(CurrentGrid != null ? CurrentGrid.WorldMatrix : MatrixD.Identity, UseTransparency);

                if (!ShipCreationIsActivated && !CopyPasteIsActivated && !MultiBlockCreationIsActivated)
                {
                    m_rotationHints.Clear();
                    VRageRender.MyRenderProxy.RemoveBillboardViewProjection(0);
                }

                if (MyFakes.ENABLE_DEBUG_DRAW_TEXTURE_NAMES)
                {
                    DebugDrawModelTextures();
                }

                if (MultiBlockCreationIsActivated)
                {
                    UpdateBlockInfoHud();
                }

                return;
            }
            var startPosition = m_gizmo.SpaceDefault.m_startBuild ?? m_gizmo.SpaceDefault.m_startRemove;

            if (startPosition != null && m_gizmo.SpaceDefault.m_continueBuild != null)
            {
                Vector3I rotatedSize;
                Vector3I.TransformNormal(ref CurrentBlockDefinition.Size, ref m_gizmo.SpaceDefault.m_localMatrixAdd, out rotatedSize);
                rotatedSize = Vector3I.Abs(rotatedSize);

                int      stepCount;
                Vector3I stepDelta;
                Vector3I counter;

                ComputeSteps(startPosition.Value, m_gizmo.SpaceDefault.m_continueBuild.Value,
                             m_gizmo.SpaceDefault.m_startBuild.HasValue ? rotatedSize : Vector3I.One, out stepDelta, out counter, out stepCount);
                m_cubeCountStringBuilder.Clear();
                m_cubeCountStringBuilder.Append("  ");
                m_cubeCountStringBuilder.AppendInt32(stepCount);

                MyGuiManager.DrawString(MyFontEnum.White, m_cubeCountStringBuilder, new Vector2(0.5f, 0.5f), 1.5f);
            }

            bool addPos    = m_gizmo.SpaceDefault.m_startBuild.HasValue;
            bool removePos = false;

            if (DynamicMode)
            {
                Vector3D freePlacementIntersectionPoint = GetFreeSpacePlacementPosition(out m_gizmo.SpaceDefault.m_dynamicBuildAllowed);
                m_gizmo.SpaceDefault.m_worldMatrixAdd.Translation = freePlacementIntersectionPoint;

                addPos = true;
            }
            else
            {
                if (m_gizmo.SpaceDefault.m_startBuild == null && m_gizmo.SpaceDefault.m_startRemove == null)
                {
                    if (!FreezeGizmo)
                    {
                        float gridSize = MyDefinitionManager.Static.GetCubeSize(CurrentBlockDefinition.CubeSize);
                        addPos = GetAddAndRemovePositions(gridSize, PlacingSmallGridOnLargeStatic, out m_gizmo.SpaceDefault.m_addPos, out m_gizmo.SpaceDefault.m_addPosSmallOnLarge, out m_gizmo.SpaceDefault.m_addDir,
                                                          out m_gizmo.SpaceDefault.m_removePos, out m_gizmo.SpaceDefault.m_removeBlock, out m_gizmo.SpaceDefault.m_blockIdInCompound);
                    }

                    if (addPos)
                    {
                        if (PlacingSmallGridOnLargeStatic)
                        {
                            m_gizmo.SpaceDefault.m_localMatrixAdd.Translation = m_gizmo.SpaceDefault.m_addPosSmallOnLarge.Value;
                        }
                        else
                        {
                            m_gizmo.SpaceDefault.m_localMatrixAdd.Translation = m_gizmo.SpaceDefault.m_addPos;
                        }

                        if (CurrentGrid != null)
                        {
                            m_gizmo.SpaceDefault.m_worldMatrixAdd = m_gizmo.SpaceDefault.m_localMatrixAdd * CurrentGrid.WorldMatrix;
                        }
                        else
                        {
                            m_gizmo.SpaceDefault.m_worldMatrixAdd = m_gizmo.SpaceDefault.m_localMatrixAdd;
                        }
                        Debug.Assert(!m_gizmo.SpaceDefault.m_worldMatrixAdd.IsNan(), "Invalid gizmo matrix");

                        if (m_gizmo.SpaceDefault.m_removeBlock != null)
                        {
                            removePos = true;
                        }
                    }
                }
            }

            bool buildingDisabledByCockpit = MySession.ControlledEntity != null && MySession.ControlledEntity is MyCockpit && !DeveloperSpectatorIsBuilding;

            //bool buildingDisabledByCockpit = true;
            if (!buildingDisabledByCockpit)
            {
                if (IsInSymmetrySettingMode)
                {
                    m_gizmo.SpaceDefault.m_continueBuild = null;
                    addPos    = false;
                    removePos = false;

                    if (m_gizmo.SpaceDefault.m_removeBlock != null)
                    {
                        var min = (m_gizmo.SpaceDefault.m_removeBlock.Min * CurrentGrid.GridSize);
                        var max = (m_gizmo.SpaceDefault.m_removeBlock.Max * CurrentGrid.GridSize);

                        Vector3 center = (min + max) * 0.5f;

                        Color color = DrawSymmetryPlane(m_symmetrySettingMode, CurrentGrid, center);

                        DrawSemiTransparentBox(CurrentGrid, m_gizmo.SpaceDefault.m_removeBlock, color.ToVector4());
                    }
                }

                if (CurrentGrid != null && (UseSymmetry || IsInSymmetrySettingMode))
                {
                    if (CurrentGrid.XSymmetryPlane != null)
                    {
                        Vector3 center = CurrentGrid.XSymmetryPlane.Value * CurrentGrid.GridSize;
                        DrawSymmetryPlane(CurrentGrid.XSymmetryOdd ? MySymmetrySettingModeEnum.XPlaneOdd : MySymmetrySettingModeEnum.XPlane, CurrentGrid, center);
                    }

                    if (CurrentGrid.YSymmetryPlane != null)
                    {
                        Vector3 center = CurrentGrid.YSymmetryPlane.Value * CurrentGrid.GridSize;
                        DrawSymmetryPlane(CurrentGrid.YSymmetryOdd ? MySymmetrySettingModeEnum.YPlaneOdd : MySymmetrySettingModeEnum.YPlane, CurrentGrid, center);
                    }

                    if (CurrentGrid.ZSymmetryPlane != null)
                    {
                        Vector3 center = CurrentGrid.ZSymmetryPlane.Value * CurrentGrid.GridSize;
                        DrawSymmetryPlane(CurrentGrid.ZSymmetryOdd ? MySymmetrySettingModeEnum.ZPlaneOdd : MySymmetrySettingModeEnum.ZPlane, CurrentGrid, center);
                    }
                }
            }

            UpdateGizmos(addPos, removePos, true);

            m_renderData.UpdateRenderInstanceData();

            if (DynamicMode || CurrentVoxelMap != null)
            {
                MatrixD  drawMatrix = m_gizmo.SpaceDefault.m_worldMatrixAdd;
                Vector3D rotatedModelOffset;
                Vector3D.TransformNormal(ref CurrentBlockDefinition.ModelOffset, ref drawMatrix, out rotatedModelOffset);

                drawMatrix.Translation = drawMatrix.Translation + rotatedModelOffset;

                m_renderData.UpdateRenderEntitiesData(drawMatrix, UseTransparency);
            }
            else
            {
                m_renderData.UpdateRenderEntitiesData(CurrentGrid != null ? CurrentGrid.WorldMatrix : MatrixD.Identity, UseTransparency);
            }

            UpdateBlockInfoHud();

            DebugDraw();
        }
        /// <summary>
        /// Casts preview grids aabbs and get shortest distance. Returns shortest intersection or null.
        /// </summary>
        protected Vector3D?GetFreeSpacePlacementPositionGridAabbs(bool copyPaste, out bool buildAllowed)
        {
            Vector3D?freePlacementIntersectionPoint = null;

            buildAllowed = true;

            float gridSize = PreviewGrids[0].GridSize;

            double shortestDistance = double.MaxValue;
            double?currentRayInts   = MyCubeBuilder.GetCurrentRayIntersection();

            if (currentRayInts.HasValue)
            {
                shortestDistance = currentRayInts.Value;
            }

            Vector3D worldRefPointOffset = Vector3D.Zero;

            if (copyPaste)
            {
                Matrix firstGridOrientation = GetFirstGridOrientationMatrix();
                worldRefPointOffset = Vector3.TransformNormal(m_dragPointToPositionLocal, firstGridOrientation);
            }

            Vector3D worldRefPoint = PreviewGrids[0].GridIntegerToWorld(Vector3I.Zero);

            foreach (var grid in PreviewGrids)
            {
                Vector3 halfExt  = grid.PositionComp.LocalAABB.HalfExtents;
                Vector3 minLocal = grid.Min * grid.GridSize - Vector3.Half * grid.GridSize;
                Vector3 maxLocal = grid.Max * grid.GridSize + Vector3.Half * grid.GridSize;

                MatrixD gridWorlTransform = MatrixD.Identity;
                gridWorlTransform.Translation = 0.5f * (minLocal + maxLocal);
                gridWorlTransform             = gridWorlTransform * grid.WorldMatrix;

                Vector3I size       = grid.Max - grid.Min + Vector3I.One;
                Vector3  sizeOffset = Vector3I.Abs((size % 2) - Vector3I.One) * 0.5 * grid.GridSize;
                sizeOffset = Vector3.TransformNormal(sizeOffset, grid.WorldMatrix);
                Vector3D offset = gridWorlTransform.Translation + worldRefPointOffset - worldRefPoint /*- sizeOffset*/;// Vector3.Zero;// gridWorlTransform.Translation + worldRefPointOffset - worldRefPoint;

                HkShape shape = new HkBoxShape(halfExt);

                Vector3D rayStart = MyCubeBuilder.IntersectionStart + offset;
                double   castPlaneDistanceToRayStart = DistanceFromCharacterPlane(ref rayStart);
                rayStart -= castPlaneDistanceToRayStart * MyCubeBuilder.IntersectionDirection;

                Vector3D rayEnd = MyCubeBuilder.IntersectionStart + (m_dragDistance - castPlaneDistanceToRayStart) * MyCubeBuilder.IntersectionDirection + offset;
                MatrixD  matrix = gridWorlTransform;
                matrix.Translation = rayStart;

                try
                {
                    float?dist = MyPhysics.CastShape(rayEnd, shape, ref matrix, MyPhysics.CollisionLayers.CollisionLayerWithoutCharacter);
                    if (dist.HasValue && dist.Value != 0f)
                    {
                        Vector3D intersectionPoint = rayStart + dist.Value * (rayEnd - rayStart);

                        const bool debugDraw = true;
                        if (debugDraw)
                        {
                            Color        green     = Color.Green;
                            BoundingBoxD localAABB = new BoundingBoxD(-halfExt, halfExt);
                            localAABB.Inflate(0.03f);
                            MatrixD drawMatrix = matrix;
                            drawMatrix.Translation = intersectionPoint;
                            MySimpleObjectDraw.DrawTransparentBox(ref drawMatrix, ref localAABB, ref green, MySimpleObjectRasterizer.Wireframe, 1, 0.04f);
                        }

                        double fixedDistance = DistanceFromCharacterPlane(ref intersectionPoint) - castPlaneDistanceToRayStart;
                        if (fixedDistance <= 0)
                        {
                            fixedDistance    = 0;
                            shortestDistance = 0;
                            buildAllowed     = false;
                            break;
                        }

                        if (fixedDistance < shortestDistance)
                        {
                            shortestDistance = fixedDistance;
                        }
                    }
                    else
                    {
                        buildAllowed = false;
                    }
                }
                finally
                {
                    shape.RemoveReference();
                }
            }

            if (shortestDistance != 0 && shortestDistance < m_dragDistance)
            {
                freePlacementIntersectionPoint = MyCubeBuilder.IntersectionStart + shortestDistance * MyCubeBuilder.IntersectionDirection;
            }
            else
            {
                buildAllowed = false;
            }

            return(freePlacementIntersectionPoint);
        }
        // ReSharper restore InconsistentNaming
        public void DebugDraw(bool force = false)
        {
            force |= ForceDebugDraw;
            if (!force && !Settings.DebugDraw)
            {
                return;
            }
            var transform = Grid.WorldMatrix;
            var gridSize  = Grid.GridSize;

            foreach (var room in Construction.Rooms)
            {
                if (force || Settings.DebugDrawBlocks)
                {
                    var localAABB = new BoundingBoxD((room.BoundingBox.Min - 0.5f) * gridSize, (room.BoundingBox.Max + 0.5f) * gridSize);
                    MySimpleObjectDraw.DrawTransparentBox(ref transform, ref localAABB, ref DebugColorBlocksTotal, MySimpleObjectRasterizer.Wireframe, 1, .02f);
                }
                if (force || Settings.DebugDrawReservedTotal && room.Part.ReservedSpaces.Any())
                {
                    var temp    = Utilities.TransformBoundingBox(room.Part.ReservedSpace, room.Transform);
                    var tmpAABB = new BoundingBoxD((temp.Min - 0.5f) * gridSize, (temp.Max + 0.5f) * gridSize);
                    MySimpleObjectDraw.DrawTransparentBox(ref transform, ref tmpAABB, ref DebugColorReservedSpaceTotal, MySimpleObjectRasterizer.Wireframe, 1, .02f);
                }
                if (force || Settings.DebugDrawReserved)
                {
                    foreach (var rs in room.Part.ReservedSpaces)
                    {
                        var temp    = Utilities.TransformBoundingBox(rs.Box, room.Transform);
                        var tmpAABB = new BoundingBoxD(temp.Min * gridSize, (temp.Max + 1) * gridSize);
                        tmpAABB = tmpAABB.Inflate(-0.02);
                        Color color;
                        if (rs.IsShared && rs.IsOptional)
                        {
                            color = DebugColorReservedSpaceBoth;
                        }
                        else if (rs.IsShared)
                        {
                            color = DebugColorReservedSpaceShared;
                        }
                        else if (rs.IsOptional)
                        {
                            color = DebugColorReservedSpaceOptional;
                        }
                        else
                        {
                            color = DebugColorReservedSpace;
                        }
                        MySimpleObjectDraw.DrawTransparentBox(ref transform, ref tmpAABB, ref color, MySimpleObjectRasterizer.Wireframe, 1, .005f);
                    }
                }
                // ReSharper disable once InvertIf
                if (force || Settings.DebugDrawMountPoints)
                {
                    foreach (var mount in room.MountPoints)
                    {
                        foreach (var block in mount.MountPoint.Blocks)
                        {
                            var anchorLoc = (Vector3)block.AnchorLocation;
                            var opposeLoc = (Vector3)(block.AnchorLocation + (block.MountDirection * 2));
                            opposeLoc += 0.5f * Vector3.Abs(Vector3I.One - Vector3I.Abs(block.MountDirection)); // hacky way to get perp. components
                            anchorLoc -= 0.5f * Vector3.Abs(Vector3I.One - Vector3I.Abs(block.MountDirection));

                            var anchor  = gridSize * Vector3.Transform(anchorLoc, room.Transform.GetFloatMatrix());
                            var oppose  = gridSize * Vector3.Transform(opposeLoc, room.Transform.GetFloatMatrix());
                            var tmpAABB = new BoundingBoxD(Vector3.Min(anchor, oppose), Vector3.Max(anchor, oppose));
                            MySimpleObjectDraw.DrawTransparentBox(ref transform, ref tmpAABB, ref DebugColorMountPoint, MySimpleObjectRasterizer.Solid, 1, .02f);
                        }
                    }
                }
            }
        }
        private new void FixSnapTransformationBase6()
        {
            Debug.Assert(CopiedGrids.Count > 0);
            if (CopiedGrids.Count == 0)
            {
                return;
            }

            var hitGrid = m_hitEntity as MyCubeGrid;

            if (hitGrid == null)
            {
                return;
            }

            // Fix rotation of the first pasted grid
            Matrix hitGridRotation  = hitGrid.WorldMatrix.GetOrientation();
            Matrix firstRotation    = PreviewGrids[0].WorldMatrix.GetOrientation();
            Matrix newFirstRotation = Matrix.AlignRotationToAxes(ref firstRotation, ref hitGridRotation);
            Matrix rotationDelta    = Matrix.Invert(firstRotation) * newFirstRotation;

            foreach (var grid in PreviewGrids)
            {
                Matrix rotation = grid.WorldMatrix.GetOrientation();
                rotation = rotation * rotationDelta;
                Matrix rotationInv = Matrix.Invert(rotation);

                Vector3D position = m_pastePosition;

                MatrixD newWorld = MatrixD.CreateWorld(position, rotation.Forward, rotation.Up);
                Debug.Assert(newWorld.GetOrientation().IsRotation());
                grid.PositionComp.SetWorldMatrix(newWorld);
            }

            bool smallOnLargeGrid = hitGrid.GridSizeEnum == MyCubeSize.Large && PreviewGrids[0].GridSizeEnum == MyCubeSize.Small;

            if (smallOnLargeGrid)
            {
                Vector3 pasteOffset = TransformLargeGridHitCoordToSmallGrid(m_hitPos, hitGrid.PositionComp.WorldMatrixNormalizedInv, hitGrid.GridSize);
                m_pastePosition = hitGrid.GridIntegerToWorld(pasteOffset);
            }
            else
            {
                // Find a collision-free position for the first paste grid along the raycast normal
                Vector3I collisionTestStep        = Vector3I.Round(m_hitNormal);
                Vector3I pasteOffset              = hitGrid.WorldToGridInteger(m_pastePosition);
                Vector3I previewGridMin           = PreviewGrids[0].Min;
                Vector3I previewGridMax           = PreviewGrids[0].Max;
                Vector3I previewGridSize          = previewGridMax - previewGridMin + Vector3I.One;
                Vector3D previewGridSizeInWorld   = Vector3D.TransformNormal((Vector3D)previewGridSize, PreviewGrids[0].WorldMatrix);
                Vector3I previewGridSizeInHitGrid = Vector3I.Abs(Vector3I.Round(Vector3D.TransformNormal(previewGridSizeInWorld, hitGrid.PositionComp.WorldMatrixNormalizedInv)));

                int attemptsCount = Math.Abs(Vector3I.Dot(ref collisionTestStep, ref previewGridSizeInHitGrid));
                Debug.Assert(attemptsCount > 0);
                int i;

                for (i = 0; i < attemptsCount; ++i)
                {
                    if (hitGrid.CanMergeCubes(PreviewGrids[0], pasteOffset))
                    {
                        break;
                    }
                    pasteOffset += collisionTestStep;
                }

                if (i == attemptsCount)
                {
                    pasteOffset = hitGrid.WorldToGridInteger(m_pastePosition);
                }

                m_pastePosition = hitGrid.GridIntegerToWorld(pasteOffset);
            }

            // Move all the grids according to the collision-free position of the first one
            for (int i = 0; i < PreviewGrids.Count; ++i)
            {
                var     grid   = PreviewGrids[i];
                MatrixD matrix = grid.WorldMatrix;
                matrix.Translation = m_pastePosition + Vector3.Transform(m_copiedGridOffsets[i], rotationDelta);
                grid.PositionComp.SetWorldMatrix(matrix);
            }

            if (MyDebugDrawSettings.DEBUG_DRAW_COPY_PASTE)
            {
                MyRenderProxy.DebugDrawLine3D(m_hitPos, m_hitPos + m_hitNormal, Color.Red, Color.Green, false);
            }
        }
Example #13
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 #14
0
        private static void CheckNeighborBlocks(MySlimBlock block, BoundingBoxD aabbForNeighbors, MyCubeGrid cubeGrid, List <MySlimBlock> blocks)
        {
            MatrixD      m        = block.CubeGrid.WorldMatrix * cubeGrid.PositionComp.WorldMatrixNormalizedInv;
            BoundingBoxD xd2      = aabbForNeighbors.TransformFast(ref m);
            Vector3I     vectori  = Vector3I.Round((Vector3D)(cubeGrid.GridSizeR * xd2.Max));
            Vector3I     vectori1 = Vector3I.Round((Vector3D)(cubeGrid.GridSizeR * xd2.Min));
            Vector3I     start    = Vector3I.Min(vectori1, vectori);
            Vector3I     end      = Vector3I.Max(vectori1, vectori);
            int          index    = blocks.Count - 1;

            while (true)
            {
                bool flag;
                while (true)
                {
                    if (index < 0)
                    {
                        return;
                    }
                    MySlimBlock block2 = blocks[index];
                    flag = false;
                    Vector3I_RangeIterator iterator = new Vector3I_RangeIterator(ref block2.Min, ref block2.Max);
                    Vector3I current = iterator.Current;
                    while (true)
                    {
                        if (!iterator.IsValid())
                        {
                            break;
                        }
                        Vector3I_RangeIterator iterator2 = new Vector3I_RangeIterator(ref start, ref end);
                        Vector3I next = iterator2.Current;
                        while (true)
                        {
                            if (iterator2.IsValid())
                            {
                                Vector3I vectori6 = Vector3I.Abs(current - next);
                                if ((next != current) && (((vectori6.X + vectori6.Y) + vectori6.Z) != 1))
                                {
                                    iterator2.GetNext(out next);
                                    continue;
                                }
                                flag = true;
                            }
                            if (flag)
                            {
                                break;
                            }
                            else
                            {
                                iterator.GetNext(out current);
                            }
                            break;
                        }
                    }
                    break;
                }
                if (!flag)
                {
                    blocks.RemoveAt(index);
                }
                index--;
            }
        }
Example #15
0
 protected static void AddFastBuildModelWithSubparts(ref MatrixD matrix, List <MatrixD> matrices, List <string> models, MyCubeBlockDefinition blockDefinition, float gridScale)
 {
     if (!string.IsNullOrEmpty(blockDefinition.Model))
     {
         matrices.Add(matrix);
         models.Add(blockDefinition.Model);
         MyEntitySubpart.Data outData = new MyEntitySubpart.Data();
         MyModel modelOnlyData        = MyModels.GetModelOnlyData(blockDefinition.Model);
         modelOnlyData.Rescale(gridScale);
         foreach (KeyValuePair <string, MyModelDummy> pair in modelOnlyData.Dummies)
         {
             MyCubeBlockDefinition definition;
             MatrixD xd;
             Vector3 vector;
             if (MyEntitySubpart.GetSubpartFromDummy(blockDefinition.Model, pair.Key, pair.Value, ref outData))
             {
                 MyModel model = MyModels.GetModelOnlyData(outData.File);
                 if (model != null)
                 {
                     model.Rescale(gridScale);
                 }
                 MatrixD item = MatrixD.Multiply(outData.InitialTransform, matrix);
                 matrices.Add(item);
                 models.Add(outData.File);
                 continue;
             }
             if (MyFakes.ENABLE_SUBBLOCKS && (MyCubeBlock.GetSubBlockDataFromDummy(blockDefinition, pair.Key, pair.Value, false, out definition, out xd, out vector) && !string.IsNullOrEmpty(definition.Model)))
             {
                 Vector3I vectori4;
                 MyModel  model2 = MyModels.GetModelOnlyData(definition.Model);
                 if (model2 != null)
                 {
                     model2.Rescale(gridScale);
                 }
                 Vector3I vectori  = Vector3I.Round(Vector3.DominantAxisProjection((Vector3)xd.Forward));
                 Vector3I vectori2 = Vector3I.One - Vector3I.Abs(vectori);
                 Vector3I vectori3 = Vector3I.Round(Vector3.DominantAxisProjection((Vector3)(xd.Right * vectori2)));
                 Vector3I.Cross(ref vectori3, ref vectori, out vectori4);
                 xd.Forward = (Vector3D)vectori;
                 xd.Right   = (Vector3D)vectori3;
                 xd.Up      = (Vector3D)vectori4;
                 MatrixD item = MatrixD.Multiply(xd, matrix);
                 matrices.Add(item);
                 models.Add(definition.Model);
             }
         }
         if ((MyFakes.ENABLE_GENERATED_BLOCKS && !blockDefinition.IsGeneratedBlock) && (blockDefinition.GeneratedBlockDefinitions != null))
         {
             foreach (MyDefinitionId id in blockDefinition.GeneratedBlockDefinitions)
             {
                 MyCubeBlockDefinition definition2;
                 if (MyDefinitionManager.Static.TryGetCubeBlockDefinition(id, out definition2))
                 {
                     MyModel model3 = MyModels.GetModelOnlyData(definition2.Model);
                     if (model3 != null)
                     {
                         model3.Rescale(gridScale);
                     }
                 }
             }
         }
     }
 }
Example #16
0
        private void update_rendered_images(int limit)
        {
            int  count   = 0;
            char newchar = 'X';

            if (!shadows_baked)
            {
                limit = initial_limit;
            }
            if (coords_to_render.Count == 0)
            {
                //render_index=0;
                //show_damage=false;
                //damage_iterator=(damage_iterator+1)%4;
                //if (damage_iterator==0) show_damage=false;
                if (shadows_rendered)
                {
                    shadows_baked = true;
                }
                shadows_rendered = true;
            }
            if (shadows_rendered && !shadows_baked)
            {
                //The reason we're doing this is to avoid crazy render state dependency for a one-time function.
                bake_shadows();
                coords_to_render = new List <Vector3I>(coords_ship_full);
                return;
            }
            while (count < limit && coords_to_render.Count > 0)
            {
                count++;
                Vector3I testvec = coords_to_render[0];
                newchar = normal;
                if (!coords_ship_now.Contains(testvec))
                {
                    newchar = gone;
                }
                if (coords_terminal_now.Contains(testvec))
                {
                    if (!coords_terminal_working.Contains(testvec))
                    {
                        newchar = broken;
                    }
                    if (!coords_terminal_nothacked.Contains(testvec))
                    {
                        newchar = hacked;
                    }
                }
                for (int r = 0; r < 6; r++)
                {
                    Vector3I rotsize    = Vector3I.Abs(Rotate3I(shipSizeVector, r));
                    Vector3I rotscanned = Vector3I.Abs(Rotate3I(testvec - shipCoordMin, r));
                    Vector3I rotcursor  = Vector3I.Abs(Rotate3I(cursor_vec - shipCoordMin, r));
                    if (drawcursor && (
                            rotscanned.X == rotcursor.X || rotscanned.Y == rotcursor.Y))
                    {
                        newchar = cursor;
                    }
                    int  xyindex      = rotscanned.X + (rotsize.Y - rotscanned.Y) * (rotsize.X + 1);
                    char oldchar      = GetCharAt(rendered_images[r][0][rotscanned.Z], xyindex);
                    char oldchar_flat = GetCharAt(rendered_images[r][1][0], xyindex);
                    if (!shadows_rendered)
                    {
                        rendered_shadows[r][1][0] = ReplaceAt(rendered_shadows[r][1][0], xyindex, shadow);
                        continue;
                    }
                    for (int i = 0; i < 2; i++)
                    {
                        if (i == 1)
                        {
                            rendered_images[r][i][0] = ReplaceAt(rendered_images[r][i][0], xyindex, newchar);
                        }
                        if (i == 0)
                        {
                            rendered_images[r][i][rotscanned.Z] = ReplaceAt(rendered_images[r][i][rotscanned.Z], xyindex, newchar);
                        }
                    }
                }
                coords_to_render.Remove(testvec);
            }
        }