public StructureEntry( )
		{
			type = typeof( CubeBlockEntity );
			color = new Color( 0, 0, 0 );
			useOrientation = false;
			orientation = MyBlockOrientation.Identity;
			useSubTypeName = false;
			subTypeName = "";
		}
 public MyGeneratedBlockLocation(MySlimBlock refBlock, MyCubeBlockDefinition blockDefinition, Vector3I position, Vector3I forward, Vector3I up, ushort? blockIdInCompound = null, MyGridInfo gridInfo = null)
 {
     RefBlock = refBlock;
     BlockDefinition = blockDefinition;
     Position = position;
     Orientation = new MyBlockOrientation(Base6Directions.GetDirection(ref forward), Base6Directions.GetDirection(ref up));
     BlockIdInCompound = blockIdInCompound;
     GridInfo = gridInfo;
     GeneratedBlockType = MyStringId.NullOrEmpty;
 }
 public MyGeneratedBlockLocation(MySlimBlock refBlock, MyCubeBlockDefinition blockDefinition, Vector3I position, MyBlockOrientation orientation, ushort? blockIdInCompound = null, MyGridInfo gridInfo = null)
 {
     RefBlock = refBlock;
     BlockDefinition = blockDefinition;
     Position = position;
     Orientation = orientation;
     BlockIdInCompound = blockIdInCompound;
     GridInfo = gridInfo;
     GeneratedBlockType = MyStringId.NullOrEmpty;
 }
 public void Initialize(ref MyBlockBuildArea area, MyCubeBlockDefinition definition)
 {
     m_definition = definition;
     m_orientation = new MyBlockOrientation(area.OrientationForward, area.OrientationUp);
     m_posInGrid = area.PosInGrid;
     m_blockMin = area.BlockMin;
     m_blockMax = area.BlockMax;
     m_stepDelta = area.StepDelta;
     m_lookup.Clear();
 }
Esempio n. 5
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;
        }
        /// <summary>
        /// Checkes whether blocks A and B have matching mount point on one of their sides. Each block is given by its
        /// definition, rotation and position in grid. Position has to be relative to same center. Also, normal relative to block A specifies
        /// wall which is used for checking.
        /// </summary>
        public static bool CheckMountPointsForSide(List<MyCubeBlockDefinition.MountPoint> transormedA, ref MyBlockOrientation orientationA, ref Vector3I positionA, MyDefinitionId idA, ref Vector3I normalA,
                                                   List<MyCubeBlockDefinition.MountPoint> transormedB, ref MyBlockOrientation orientationB, ref Vector3I positionB, MyDefinitionId idB)
        {
            var offsetAB = positionB - positionA;

            var normalB = -normalA;
            for (int i = 0; i < transormedA.Count; ++i)
            {
				if(!transormedA[i].Enabled)
					continue;

                var mountPointA = transormedA[i];
                if (mountPointA.Normal != normalA)
                    continue;

                var minA = Vector3.Min(mountPointA.Start, mountPointA.End);
                var maxA = Vector3.Max(mountPointA.Start, mountPointA.End);

                minA -= offsetAB;
                maxA -= offsetAB;
                var bboxA = new BoundingBox(minA, maxA);

                for (int j = 0; j < transormedB.Count; ++j)
                {
					if(!transormedB[j].Enabled)
						continue;
                    var mountPointB = transormedB[j];
                    if (mountPointB.Normal != normalB)
                        continue;

                    // Skip mount points which exclude themselves (are not allowed to touch).
                    if (((mountPointA.ExclusionMask & mountPointB.PropertiesMask) != 0 || (mountPointA.PropertiesMask & mountPointB.ExclusionMask) != 0) &&
                        idA != idB)
                        continue;

                    var bboxB = new BoundingBox(Vector3.Min(mountPointB.Start, mountPointB.End), Vector3.Max(mountPointB.Start, mountPointB.End));
                    if (bboxA.Intersects(bboxB))
                        return true;
                }
            }

            return false;
        }
		public static bool CheckNeighborMountPointsForCompound(
			Vector3 currentMin, Vector3 currentMax, MyCubeBlockDefinition.MountPoint thisMountPoint, ref Vector3I thisMountPointTransformedNormal, MyCubeBlockDefinition thisDefinition,
			Vector3I neighborPosition, MyCubeBlockDefinition neighborDefinition, MyCubeBlockDefinition.MountPoint[] neighborMountPoints, MyBlockOrientation neighborOrientation,
			List<MyCubeBlockDefinition.MountPoint> otherMountPoints)
        {
			if (!thisMountPoint.Enabled)
				return false;

            var currentBox = new BoundingBox(currentMin - neighborPosition, currentMax - neighborPosition);

			TransformMountPoints(otherMountPoints, neighborDefinition, neighborMountPoints, ref neighborOrientation);

            foreach (var otherMountPoint in otherMountPoints)
            {
                // Skip mount points which exclude themselves (are not allowed to touch).
                if ((((thisMountPoint.ExclusionMask & otherMountPoint.PropertiesMask) != 0 ||
                      (thisMountPoint.PropertiesMask & otherMountPoint.ExclusionMask) != 0) &&
					thisDefinition.Id != neighborDefinition.Id) || !otherMountPoint.Enabled)
                    continue;

                // Check normals on compound side with the same direction (we are in the same block)
                if (MyFakes.ENABLE_TEST_BLOCK_CONNECTIVITY_CHECK && (thisMountPointTransformedNormal - otherMountPoint.Normal != Vector3I.Zero))
                    continue;

                var otherBox = new BoundingBox(Vector3.Min(otherMountPoint.Start, otherMountPoint.End), Vector3.Max(otherMountPoint.Start, otherMountPoint.End));
                if (currentBox.Intersects(otherBox))
                    return true;
            }

            return false;
        }
        internal static MyObjectBuilder_CubeBlock CreateBlockObjectBuilder(MyCubeBlockDefinition definition, Vector3I min, MyBlockOrientation orientation, long entityID, long owner, bool fullyBuilt)
        {
            MyObjectBuilder_CubeBlock objectBuilder = (MyObjectBuilder_CubeBlock)MyObjectBuilderSerializer.CreateNewObject(definition.Id);
            objectBuilder.BuildPercent = fullyBuilt ? 1 : MyComponentStack.MOUNT_THRESHOLD;
            objectBuilder.IntegrityPercent = fullyBuilt ? 1 : MyComponentStack.MOUNT_THRESHOLD;
            objectBuilder.EntityId = entityID;
            objectBuilder.Min = min;
            objectBuilder.BlockOrientation = orientation;

            if (definition.ContainsComputer())
            {
                objectBuilder.Owner = 0;
                objectBuilder.ShareMode = MyOwnershipShareModeEnum.All;
            }

            return objectBuilder;
        }
        private static bool TestPlacementAreaInternal(MyCubeGrid targetGrid,
           bool targetGridIsStatic,
           ref MyGridPlacementSettings settings,
           MyCubeBlockDefinition blockDefinition,
           MyBlockOrientation? blockOrientation,
           ref BoundingBoxD localAabb,
           MyEntity ignoredEntity,
           ref MatrixD worldMatrix,
           out MyCubeGrid touchingGrid,
           bool dynamicBuildMode = false,
           bool ignoreFracturedPieces = false,
           bool testVoxels = true)
        {
            ProfilerShort.Begin("TestPlacementAreaInternal");

            touchingGrid = null;

            float gridSize = targetGrid != null ? targetGrid.GridSize : (blockDefinition != null ? MyDefinitionManager.Static.GetCubeSize(blockDefinition.CubeSize) : MyDefinitionManager.Static.GetCubeSize(MyCubeSize.Large));
            bool isStatic = targetGridIsStatic;

            var worldAabb = localAabb.Transform(ref worldMatrix);

            bool entityOverlap = false;
            MyVoxelBase overlappedVoxelMap = null;
            bool touchingStaticGrid = false;
            foreach (var collison in m_physicsBoxQueryList)
            {
                var entity = collison.Body.GetEntity(0) as MyEntity;
                if (entity == null)
                    continue;

                if (ignoreFracturedPieces && (entity is MyFracturedPiece))
                    continue;

                if (entity.GetPhysicsBody().WeldInfo.Children.Count == 0 && ignoredEntity != null && (entity == ignoredEntity || entity.GetTopMostParent() == ignoredEntity))
                    continue;

                var body = entity.Physics;
                if (body != null && body.IsPhantom)
                    continue;

                var voxelMap = entity as MyVoxelBase;
                if (voxelMap != null)
                {
                    overlappedVoxelMap = voxelMap;
                    continue;
                }

                var grid = entity as MyCubeGrid;
				if (grid == null)
				{
					var subPart = entity as MyEntitySubpart;
					if (subPart != null)
					{
						grid = subPart.GetTopMostParent() as MyCubeGrid;
					}
				}

                if(entity.GetPhysicsBody().WeldInfo.Children.Count > 0)
                {
                    if(entity != ignoredEntity)
                    {
                        //Vector4 min,max;
                        //entity.Physics.GetShape().GetLocalAABB(0.05f, out min, out max);
                        //MyOrientedBoundingBoxD obb = new MyOrientedBoundingBoxD(new BoundingBoxD(new Vector3D(min.X, min.Y, min.Z), new Vector3D(max.X, max.Y, max.Z)), entity.WorldMatrix);
                        //MyRenderProxy.DebugDrawOBB(obb, Color.Green, 0.5f, false, false);
                        //obb = new MyOrientedBoundingBoxD(new BoundingBoxD(-m_lastQueryBox.HalfExtents, m_lastQueryBox.HalfExtents), m_lastQueryTransform);
                        //MyRenderProxy.DebugDrawOBB(obb, Color.Red, 0.5f, false, false);
                        if (TestQueryIntersection(entity.GetPhysicsBody().GetShape(), entity.WorldMatrix))
                        {
                            entityOverlap = true;
                            if(touchingGrid == null)
                                touchingGrid = entity as MyCubeGrid;
                            break;
                        }
                    }

                    foreach(var child in entity.GetPhysicsBody().WeldInfo.Children)
                    {
                        if(child.Entity == ignoredEntity)
                            continue;
                        if(TestQueryIntersection(child.WeldedRigidBody.GetShape(), child.Entity.WorldMatrix))
                        {
                            if (touchingGrid == null)
                                touchingGrid = child.Entity as MyCubeGrid;
                            entityOverlap = true;
                            break;
                        }
                    }
                    if (entityOverlap)
                        break;
                    continue;
                }

                if (grid != null && ((isStatic && grid.IsStatic)
                    || (MyFakes.ENABLE_DYNAMIC_SMALL_GRID_MERGING && !isStatic && !grid.IsStatic && blockDefinition != null && blockDefinition.CubeSize == grid.GridSizeEnum)
                    || (MyFakes.ENABLE_BLOCK_PLACEMENT_ON_VOXEL && isStatic && grid.IsStatic && blockDefinition != null && blockDefinition.CubeSize == grid.GridSizeEnum)))
                {
                    // Small on large (or large on small) always possible
                    if (isStatic == grid.IsStatic && gridSize != grid.GridSize)
                        continue;

                    // first check if world orientation is correct.
                    if(!IsOrientationsAligned(grid.WorldMatrix, worldMatrix))
                    {
                        entityOverlap = true;
                        continue;
                    }

                    TestGridPlacement(ref settings, ref worldMatrix, ref touchingGrid, gridSize, isStatic, ref localAabb, blockDefinition, blockOrientation, ref entityOverlap, ref touchingStaticGrid, grid);
                    if (entityOverlap)
                    {
                        break;
                    }
                    continue;
                }


                entityOverlap = true;
                break;
            }
            m_tmpResultList.Clear();
            m_physicsBoxQueryList.Clear();
            ProfilerShort.End();

            if (entityOverlap)
                return false;
            if (testVoxels)
                return TestVoxelOverlap(ref settings, ref localAabb, ref worldMatrix, ref worldAabb, ref overlappedVoxelMap, touchingStaticGrid);
            return true;
        }
 private static bool TestPlacementAreaInternal(MyCubeGrid targetGrid,
    ref MyGridPlacementSettings settings,
    MyCubeBlockDefinition blockDefinition,
    MyBlockOrientation? blockOrientation,
    ref BoundingBoxD localAabb,
    MyEntity ignoredEntity,
    ref MatrixD worldMatrix,
    out MyCubeGrid touchingGrid,
    bool dynamicBuildMode = false,
    bool ignoreFracturedPieces = false)
 {
     return TestPlacementAreaInternal(targetGrid, targetGrid != null ? targetGrid.IsStatic : !dynamicBuildMode,
         ref settings, blockDefinition, blockOrientation, ref localAabb, ignoredEntity, ref worldMatrix, out touchingGrid, dynamicBuildMode: dynamicBuildMode, ignoreFracturedPieces: ignoreFracturedPieces);
 }
        public static bool TestPlacementAreaCubeNoAABBInflate(
            MyCubeGrid targetGrid,
            ref MyGridPlacementSettings settings,
            Vector3I min,
            Vector3I max,
            MyBlockOrientation blockOrientation,
            MyCubeBlockDefinition blockDefinition,
            out MyCubeGrid touchingGrid,
            MyEntity ignoredEntity = null)
        {
            touchingGrid = null;

            var worldMatrix = targetGrid != null ? targetGrid.WorldMatrix : MatrixD.Identity;
            var gridSize = targetGrid != null ? targetGrid.GridSize : MyDefinitionManager.Static.GetCubeSize(MyCubeSize.Large);

            Vector3 halfExtents = ((max - min) * gridSize + gridSize) / 2;
            var matrix = MatrixD.CreateTranslation((max + min) * 0.5f * gridSize) * worldMatrix;
            var localAabb = BoundingBoxD.CreateInvalid();
            localAabb.Include(min * gridSize - gridSize / 2);
            localAabb.Include(max * gridSize + gridSize / 2);

            Vector3D translation = matrix.Translation;
            Quaternion rotation = Quaternion.CreateFromRotationMatrix(matrix);

            return TestBlockPlacementArea(targetGrid, ref settings, blockOrientation, blockDefinition, ref translation, ref rotation, ref halfExtents, ref localAabb, out touchingGrid, ignoredEntity);
        }
 public override void GetBlockPlacementMaterials(MyCubeBlockDefinition definition, Vector3I position, MyBlockOrientation orientation, MyCubeGrid grid)
 {
     ClearRequiredMaterials();
     GetMaterialsSimple(definition, m_materialList);
 }
Esempio n. 13
0
        private static void ConvertAllShapesToFractureComponentShapeBuilder(HkdBreakableShape shape, ref Matrix shapeRotation, MyBlockOrientation blockOrientation, HashSet<string> names, MyObjectBuilder_FractureComponentCubeBlock fractureComponentBuilder)
        {
            var name = shape.Name;
            if (names.Contains(name))
            {
                MyBlockOrientation shapeOrientation = new MyBlockOrientation(ref shapeRotation);
                if (shapeOrientation == blockOrientation)
                {
                    MyObjectBuilder_FractureComponentCubeBlock.FracturedShape builderShape = new MyObjectBuilder_FractureComponentBase.FracturedShape();
                    builderShape.Name = name;
                    builderShape.Fixed = MyDestructionHelper.IsFixed(shape);

                    fractureComponentBuilder.Shapes.Add(builderShape);
                }
            }

            if (shape.GetChildrenCount() > 0)
            {
                List<HkdShapeInstanceInfo> children = new List<HkdShapeInstanceInfo>();
                shape.GetChildren(children);
                foreach (var child in children) 
                {
                    var childShapeRotation = child.GetTransform();
                    ConvertAllShapesToFractureComponentShapeBuilder(child.Shape, ref childShapeRotation, blockOrientation, names, fractureComponentBuilder);
                }
            }

        }
Esempio n. 14
0
 static MyBlockOrientation()
 {
     Identity = new MyBlockOrientation(Base6Directions.Direction.Forward, Base6Directions.Direction.Up);
 }
Esempio n. 15
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));
 }
Esempio n. 16
0
        /// <summary>
        /// Initializes the orientation of the slim block according to the given forward and up vectors.
        /// Note that the resulting orientation can be different than the supplied orientation due to symmetries.
        /// This function chooses one canonical orientation for all orientations from one symetry equivalent group of orientations.
        /// </summary>
        public void InitOrientation(Base6Directions.Direction Forward, Base6Directions.Direction Up)
        {
            if (MyCubeGridDefinitions.GetCubeRotationOptions(BlockDefinition) == MyRotationOptionsEnum.None)
            {
                Orientation = MyBlockOrientation.Identity;
            }
            else
            {
                Orientation = new MyBlockOrientation(Forward, Up);
            }

            if (BlockDefinition.CubeDefinition != null)
            {
                //Ensure we have always only one distinct orientation use
                Orientation = MyCubeGridDefinitions.GetTopologyUniqueOrientation(BlockDefinition.CubeDefinition.CubeTopology, Orientation);
            }
        }
Esempio n. 17
0
 public MatrixI(MyBlockOrientation orientation) :
     this(Vector3I.Zero, orientation.Forward, orientation.Up)
 {
 }
Esempio n. 18
0
        private void UpdateGizmo_VoxelMap(MyCubeBuilderGizmo.MyGizmoSpaceProperties gizmoSpace, bool add, bool remove, bool draw)
        {
            Color green = new Color(Color.Green * 0.6f, 1f);
            Color red = new Color(Color.Red * 0.8f, 1);
            Color yellow = Color.Yellow;
            Color blue = Color.Blue;
            //Vector4 black = Color.Black.ToVector4();
            Color gray = Color.Gray;

            float gridSize = MyDefinitionManager.Static.GetCubeSize(CurrentBlockDefinition.CubeSize);

            Vector3 temp;
            Vector3D worldCenter = Vector3D.Zero;
            Vector3D worldPos = gizmoSpace.m_worldMatrixAdd.Translation;
            MatrixD drawMatrix = gizmoSpace.m_worldMatrixAdd;

            Color color = green;

            UpdateShowGizmoCube(gizmoSpace, gridSize);

            int posIndex = 0;
            for (temp.X = 0; temp.X < CurrentBlockDefinition.Size.X; temp.X++)
                for (temp.Y = 0; temp.Y < CurrentBlockDefinition.Size.Y; temp.Y++)
                    for (temp.Z = 0; temp.Z < CurrentBlockDefinition.Size.Z; temp.Z++)
                    {
                        color = gizmoSpace.m_buildAllowed ? green : gray;

                        Vector3I gridPosition = gizmoSpace.m_positions[posIndex++];
                        Vector3D tempWorldPos = gridPosition * gridSize;
                        if (!MyPerGameSettings.BuildingSettings.StaticGridAlignToCenter)
                            tempWorldPos -= 0.5 * gridSize;

                        worldCenter += tempWorldPos;

                        drawMatrix.Translation = tempWorldPos;

                        MyCubeGrid.GetCubeParts(CurrentBlockDefinition, gridPosition, gizmoSpace.m_localMatrixAdd.GetOrientation(), gridSize, gizmoSpace.m_cubeModelsTemp, gizmoSpace.m_cubeMatricesTemp, gizmoSpace.m_cubeNormals, gizmoSpace.m_patternOffsets);

                        if (gizmoSpace.m_showGizmoCube)
                        {
                            for (int i = 0; i < gizmoSpace.m_cubeMatricesTemp.Count; i++)
                            {
                                MatrixD modelMatrix = gizmoSpace.m_cubeMatricesTemp[i];
                                modelMatrix.Translation = tempWorldPos;
                                gizmoSpace.m_cubeMatricesTemp[i] = modelMatrix;
                            }

                            m_gizmo.AddFastBuildParts(gizmoSpace, CurrentBlockDefinition, null);
                            m_gizmo.UpdateGizmoCubeParts(gizmoSpace, m_renderData, ref MatrixD.Identity);
                        }
                    }


            //calculate world center for block model
            worldCenter /= CurrentBlockDefinition.Size.Size;
            drawMatrix.Translation = worldCenter;

            BoundingBoxD localAABB = new BoundingBoxD(-CurrentBlockDefinition.Size * gridSize * 0.5f, CurrentBlockDefinition.Size * gridSize * 0.5f);

            var settings = CurrentBlockDefinition.CubeSize == MyCubeSize.Large ? MyPerGameSettings.BuildingSettings.LargeStaticGrid : MyPerGameSettings.BuildingSettings.SmallStaticGrid;
            MyBlockOrientation blockOrientation = new MyBlockOrientation(ref Quaternion.Identity);
            bool placementTest = CheckValidBlockRotation(gizmoSpace.m_worldMatrixAdd, CurrentBlockDefinition.Direction, CurrentBlockDefinition.Rotation)
                && MyCubeGrid.TestBlockPlacementArea(CurrentBlockDefinition, blockOrientation, drawMatrix, ref settings, localAABB, false);
            gizmoSpace.m_buildAllowed &= placementTest;
            gizmoSpace.m_buildAllowed &= gizmoSpace.m_showGizmoCube;
            gizmoSpace.m_worldMatrixAdd = drawMatrix;

            if (MySession.Static.SurvivalMode && !DeveloperSpectatorIsBuilding)
            {
                BoundingBoxD gizmoBox = localAABB.Transform(ref drawMatrix);

                if (!MyCubeBuilderGizmo.DefaultGizmoCloseEnough(ref MatrixD.Identity, gizmoBox, gridSize, IntersectionDistance) || MySession.GetCameraControllerEnum() == MyCameraControllerEnum.Spectator)
                {
                    gizmoSpace.m_buildAllowed = false;
                    gizmoSpace.m_showGizmoCube = false;
                    gizmoSpace.m_removeBlock = null;
                    return;
                }

                if (!MySession.Static.SimpleSurvival && MySession.ControlledEntity is MyCharacter)
                {
                    gizmoSpace.m_buildAllowed &= (MySession.ControlledEntity as MyCharacter).CanStartConstruction(CurrentBlockDefinition);
                }

                if (MySession.Static.SimpleSurvival)
                {
                    gizmoSpace.m_buildAllowed &= CanBuildBlockSurvivalTime();
                }
            }


            //color = gizmoSpace.m_buildAllowed ? green : gray;
            color = Color.White;
            string lineMaterial = gizmoSpace.m_buildAllowed ? "GizmoDrawLine" : "GizmoDrawLineRed";

            if (gizmoSpace.SymmetryPlane == MySymmetrySettingModeEnum.Disabled)
            {
                MySimpleObjectDraw.DrawTransparentBox(ref drawMatrix,
                    ref localAABB, ref color, MySimpleObjectRasterizer.Wireframe, 1, 0.04f, lineMaterial: lineMaterial);

                m_rotationHints.CalculateRotationHints(drawMatrix, localAABB, !MyHud.MinimalHud && MySandboxGame.Config.RotationHints && draw && MyFakes.ENABLE_ROTATION_HINTS);
            }

            gizmoSpace.m_cubeMatricesTemp.Clear();
            gizmoSpace.m_cubeModelsTemp.Clear();

            if (gizmoSpace.m_showGizmoCube)
            {
                // Draw mount points of added cube block as yellow squares in neighboring cells.
                if (MyDebugDrawSettings.ENABLE_DEBUG_DRAW && MyDebugDrawSettings.DEBUG_DRAW_MOUNT_POINTS)
                {
                    DrawMountPoints(gridSize, CurrentBlockDefinition, ref drawMatrix);
                }

                AddFastBuildModels(gizmoSpace, MatrixD.Identity, gizmoSpace.m_cubeMatricesTemp, gizmoSpace.m_cubeModelsTemp, gizmoSpace.m_blockDefinition);

                Debug.Assert(gizmoSpace.m_cubeMatricesTemp.Count == gizmoSpace.m_cubeModelsTemp.Count);
                for (int i = 0; i < gizmoSpace.m_cubeMatricesTemp.Count; ++i)
                {
                    string model = gizmoSpace.m_cubeModelsTemp[i];
                    if (!string.IsNullOrEmpty(model))
                        m_renderData.AddInstance(MyModel.GetId(model), gizmoSpace.m_cubeMatricesTemp[i], ref MatrixD.Identity);
                }
            }

        }
        public static bool TestBlockPlacementArea(MyCubeBlockDefinition blockDefinition, MyBlockOrientation? blockOrientation, MatrixD worldMatrix, ref MyGridPlacementSettings settings, BoundingBoxD localAabb, bool dynamicBuildMode,
            MyEntity ignoredEntity = null)
        {
            ProfilerShort.Begin("TestStart");
            Vector3 halfExtents = localAabb.HalfExtents;
            halfExtents += settings.SearchHalfExtentsDeltaAbsolute; //this works for SE
            if (MyFakes.ENABLE_BLOCK_PLACING_IN_OCCUPIED_AREA)
                halfExtents -= new Vector3D(GRID_PLACING_AREA_FIX_VALUE);
            Vector3D translation = localAabb.Transform(ref worldMatrix).Center;
            Quaternion quaternion = Quaternion.CreateFromRotationMatrix(worldMatrix);
            quaternion.Normalize();
            ProfilerShort.End();

            ProfilerShort.Begin("Havok.GetPenetrationsBox");
            Debug.Assert(m_physicsBoxQueryList.Count == 0, "List not cleared");
            MyPhysics.GetPenetrationsBox(ref halfExtents, ref translation, ref quaternion, m_physicsBoxQueryList, MyPhysics.CollisionLayers.CharacterCollisionLayer);
            m_lastQueryBox.HalfExtents = halfExtents;
            m_lastQueryTransform = MatrixD.CreateFromQuaternion(quaternion);
            m_lastQueryTransform.Translation = translation;
            ProfilerShort.End();

            MyCubeGrid touchingGrid;
            return TestPlacementAreaInternal(null, ref settings, blockDefinition, blockOrientation, ref localAabb, ignoredEntity, ref worldMatrix, out touchingGrid, dynamicBuildMode: dynamicBuildMode);
        }
Esempio n. 20
0
        private void UpdateGizmo_Grid(MyCubeBuilderGizmo.MyGizmoSpaceProperties gizmoSpace, bool add, bool remove, bool draw)
        {
            Color green = new Color(Color.Green * 0.6f, 1f);
            Color red = new Color(Color.Red * 0.8f, 1);
            Color yellow = Color.Yellow;
            Color black = Color.Black;
            Color gray = Color.Gray;
            Color white = Color.White;

            if (add)
            {
                if (gizmoSpace.m_startBuild != null && gizmoSpace.m_continueBuild != null)
                {
                    gizmoSpace.m_buildAllowed = true;
                }

                if (PlacingSmallGridOnLargeStatic && gizmoSpace.m_positionsSmallOnLarge.Count == 0)
                    return;

                if (CurrentBlockDefinition != null)
                {
                    Matrix addOrientationMat = gizmoSpace.m_localMatrixAdd.GetOrientation();
                    MyBlockOrientation gizmoAddOrientation = new MyBlockOrientation(ref addOrientationMat);

                    if (!PlacingSmallGridOnLargeStatic)
                    {
                        gizmoSpace.m_buildAllowed &= CheckValidBlockRotation(gizmoSpace.m_localMatrixAdd, CurrentBlockDefinition.Direction, CurrentBlockDefinition.Rotation) 
                            && CurrentGrid.CanPlaceBlock(gizmoSpace.m_min, gizmoSpace.m_max, gizmoAddOrientation, gizmoSpace.m_blockDefinition);
                    }

                    if (!PlacingSmallGridOnLargeStatic && MySession.Static.SurvivalMode && !DeveloperSpectatorIsBuilding)
                    {
                        Vector3 localMin = (m_gizmo.SpaceDefault.m_min - new Vector3(0.5f)) * CurrentGrid.GridSize;
                        Vector3 localMax = (m_gizmo.SpaceDefault.m_max + new Vector3(0.5f)) * CurrentGrid.GridSize;
                        BoundingBoxD gizmoBox = new BoundingBoxD(localMin, localMax);

                        if (!MyCubeBuilderGizmo.DefaultGizmoCloseEnough(ref m_invGridWorldMatrix, gizmoBox, CurrentGrid.GridSize, IntersectionDistance) || MySession.GetCameraControllerEnum() == MyCameraControllerEnum.Spectator)
                        {
                            gizmoSpace.m_buildAllowed = false;
                            gizmoSpace.m_removeBlock = null;
                            return;
                        }
                        if (!MySession.Static.SimpleSurvival && MySession.ControlledEntity is MyCharacter)
                        {
                            gizmoSpace.m_buildAllowed &= (MySession.ControlledEntity as MyCharacter).CanStartConstruction(CurrentBlockDefinition);
                        }

                        if (MySession.Static.SimpleSurvival)
                        {
                            gizmoSpace.m_buildAllowed &= CanBuildBlockSurvivalTime();
                        }
                    }

                    // Check whether mount points match any of its neighbors (only if we can build here though).
                    if (gizmoSpace.m_buildAllowed)
                    {
                        Quaternion.CreateFromRotationMatrix(ref gizmoSpace.m_localMatrixAdd, out gizmoSpace.m_rotation);

                        if (gizmoSpace.SymmetryPlane == MySymmetrySettingModeEnum.Disabled && !PlacingSmallGridOnLargeStatic)
                            gizmoSpace.m_buildAllowed = MyCubeGrid.CheckConnectivity(CurrentGrid, CurrentBlockDefinition, ref gizmoSpace.m_rotation, ref gizmoSpace.m_centerPos);
                    }

                    Color color = green;

                    UpdateShowGizmoCube(gizmoSpace, CurrentGrid.GridSize);

                    // Disable building from cockpit
                    if (MySession.ControlledEntity != null && MySession.ControlledEntity is MyCockpit && !DeveloperSpectatorIsBuilding)
                    {
                        gizmoSpace.m_showGizmoCube = false;
                        return;
                    }

                    gizmoSpace.m_buildAllowed &= gizmoSpace.m_showGizmoCube;

                    Vector3 temp;
                    Vector3D worldCenter = Vector3D.Zero;
                    Vector3D worldPos = gizmoSpace.m_worldMatrixAdd.Translation;
                    MatrixD drawMatrix = gizmoSpace.m_worldMatrixAdd;

                    int posIndex = 0;
                    for (temp.X = 0; temp.X < CurrentBlockDefinition.Size.X; temp.X++)
                        for (temp.Y = 0; temp.Y < CurrentBlockDefinition.Size.Y; temp.Y++)
                            for (temp.Z = 0; temp.Z < CurrentBlockDefinition.Size.Z; temp.Z++)
                            {
                                color = gizmoSpace.m_buildAllowed ? green : gray;

                                if (PlacingSmallGridOnLargeStatic)
                                {
                                    float smallToLarge = MyDefinitionManager.Static.GetCubeSize(CurrentBlockDefinition.CubeSize) / CurrentGrid.GridSize;

                                    Vector3D gridPosition = gizmoSpace.m_positionsSmallOnLarge[posIndex++];
                                    Vector3I gridPositionInt = Vector3I.Round(gridPosition / smallToLarge);
                                    Vector3D tempWorldPos = Vector3D.Transform(gridPosition * CurrentGrid.GridSize, CurrentGrid.WorldMatrix);

                                    worldCenter += tempWorldPos;
                                    drawMatrix.Translation = tempWorldPos;

                                    MyCubeGrid.GetCubeParts(CurrentBlockDefinition, gridPositionInt, gizmoSpace.m_localMatrixAdd.GetOrientation(), CurrentGrid.GridSize, gizmoSpace.m_cubeModelsTemp, gizmoSpace.m_cubeMatricesTemp, gizmoSpace.m_cubeNormals, gizmoSpace.m_patternOffsets);

                                    if (gizmoSpace.m_showGizmoCube)
                                    {
                                        for (int i = 0; i < gizmoSpace.m_cubeMatricesTemp.Count; i++)
                                        {
                                            MatrixD modelMatrix = gizmoSpace.m_cubeMatricesTemp[i];
                                            modelMatrix.Translation *= smallToLarge;
                                            modelMatrix = modelMatrix * CurrentGrid.WorldMatrix;
                                            modelMatrix.Translation = tempWorldPos;
                                            gizmoSpace.m_cubeMatricesTemp[i] = modelMatrix;
                                        }

                                        m_gizmo.AddFastBuildParts(gizmoSpace, CurrentBlockDefinition, CurrentGrid);
                                        m_gizmo.UpdateGizmoCubeParts(gizmoSpace, m_renderData, ref m_invGridWorldMatrix);
                                    }
                                }
                                else
                                {
                                    Vector3I gridPosition = gizmoSpace.m_positions[posIndex++];
                                    Vector3D tempWorldPos = Vector3D.Transform(gridPosition * CurrentGrid.GridSize, CurrentGrid.WorldMatrix);

                                    worldCenter += tempWorldPos;
                                    drawMatrix.Translation = tempWorldPos;

                                    //if (temp == center)
                                    //{
                                    //    //if bigger block, show its center with black color
                                    //    if (CurrentBlockDefinition.Size.Size > 1)
                                    //        color = black;

                                    //    if (gizmoSpace.SymmetryPlane == MySymmetrySettingModeEnum.Disabled)
                                    //    {
                                    //        //VRageRender.MyRenderProxy.DebugDrawLine3D(tempWorldPos, tempWorldPos - worldDir * CurrentGrid.GridSize, Color.Purple, Color.Gray, false);
                                    //        //VRageRender.MyRenderProxy.DebugDrawAxis(drawMatrix, 2, false);
                                    //    }
                                    //}

                                    MyCubeGrid.GetCubeParts(CurrentBlockDefinition, gridPosition, gizmoSpace.m_localMatrixAdd.GetOrientation(), CurrentGrid.GridSize, gizmoSpace.m_cubeModelsTemp, gizmoSpace.m_cubeMatricesTemp, gizmoSpace.m_cubeNormals, gizmoSpace.m_patternOffsets);

                                    if (gizmoSpace.m_showGizmoCube)
                                    {
                                        for (int i = 0; i < gizmoSpace.m_cubeMatricesTemp.Count; i++)
                                        {
                                            MatrixD modelMatrix = gizmoSpace.m_cubeMatricesTemp[i] * CurrentGrid.WorldMatrix;
                                            modelMatrix.Translation = tempWorldPos;
                                            gizmoSpace.m_cubeMatricesTemp[i] = modelMatrix;
                                        }

                                        m_gizmo.AddFastBuildParts(gizmoSpace, CurrentBlockDefinition, CurrentGrid);
                                        m_gizmo.UpdateGizmoCubeParts(gizmoSpace, m_renderData, ref m_invGridWorldMatrix, CurrentBlockDefinition);
                                    }

                                    //for (int i = 0; i < gizmoSpace.m_gizmoCubeRenderIds.Count; i++)
                                    //{
                                    //    Matrix modelMatrix = gizmoSpace.m_gizmoCubeMatricesTemp[i];
                                    //    VRageRender.MyRenderProxy.UpdateRenderObject(gizmoSpace.m_gizmoCubeRenderIds[i], ref modelMatrix, false);
                                    //}

                                    //MySimpleObjectDraw.DrawTransparentBox(ref drawMatrix,
                                    //  ref box, ref color, MySimpleObjectRasterizer.Solid, 1, 0.04f);
                                }
                            }


                    //calculate world center for block model
                    worldCenter /= CurrentBlockDefinition.Size.Size;
                    drawMatrix.Translation = worldCenter;

                    float gridSize = PlacingSmallGridOnLargeStatic ? MyDefinitionManager.Static.GetCubeSize(CurrentBlockDefinition.CubeSize) : CurrentGrid.GridSize;
                    BoundingBoxD localAABB = new BoundingBoxD(-CurrentBlockDefinition.Size * gridSize * 0.5f, CurrentBlockDefinition.Size * gridSize * 0.5f);

                    if (PlacingSmallGridOnLargeStatic)
                    {
                        if (MySession.Static.SurvivalMode && !DeveloperSpectatorIsBuilding)
                        {
                            MatrixD invDrawMatrix = Matrix.Invert(drawMatrix);

                            if (!MyCubeBuilderGizmo.DefaultGizmoCloseEnough(ref invDrawMatrix, localAABB, gridSize, IntersectionDistance) || MySession.GetCameraControllerEnum() == MyCameraControllerEnum.Spectator)
                            {
                                gizmoSpace.m_buildAllowed = false;
                                gizmoSpace.m_removeBlock = null;
                                return;
                            }
                            if (!MySession.Static.SimpleSurvival && MySession.ControlledEntity is MyCharacter)
                            {
                                gizmoSpace.m_buildAllowed &= (MySession.ControlledEntity as MyCharacter).CanStartConstruction(CurrentBlockDefinition);
                            }

                            if (MySession.Static.SimpleSurvival)
                            {
                                gizmoSpace.m_buildAllowed &= CanBuildBlockSurvivalTime();
                            }
                        }

                        var settings = MyPerGameSettings.BuildingSettings.GetGridPlacementSettings(CurrentGrid);
                        // Orientation is identity (local), because it is represented in world matrix also.
                        MyBlockOrientation orientation = new MyBlockOrientation(ref Quaternion.Identity);
                        bool placementTest = CheckValidBlockRotation(gizmoSpace.m_localMatrixAdd, CurrentBlockDefinition.Direction, CurrentBlockDefinition.Rotation)
                            && MyCubeGrid.TestBlockPlacementArea(CurrentBlockDefinition, orientation, drawMatrix, ref settings, localAABB, false);
                        gizmoSpace.m_buildAllowed &= placementTest;

                        if (gizmoSpace.m_buildAllowed && gizmoSpace.SymmetryPlane == MySymmetrySettingModeEnum.Disabled)
                            gizmoSpace.m_buildAllowed
                                &= MyCubeGrid.CheckConnectivitySmallBlockToLargeGrid(CurrentGrid, CurrentBlockDefinition, ref gizmoSpace.m_rotation, ref gizmoSpace.m_addDir);

                        gizmoSpace.m_worldMatrixAdd = drawMatrix;
                    }

                    //color = gizmoSpace.m_buildAllowed ? green : gray;
                    color = Color.White;
                    string lineMaterial = gizmoSpace.m_buildAllowed ? "GizmoDrawLine" : "GizmoDrawLineRed";

                    if (gizmoSpace.SymmetryPlane == MySymmetrySettingModeEnum.Disabled)
                    {
                        MySimpleObjectDraw.DrawTransparentBox(ref drawMatrix,
                            ref localAABB, ref color, MySimpleObjectRasterizer.Wireframe, 1, 0.04f, lineMaterial: lineMaterial);

                        m_rotationHints.CalculateRotationHints(drawMatrix, localAABB, !MyHud.MinimalHud && MySandboxGame.Config.RotationHints && draw && MyFakes.ENABLE_ROTATION_HINTS);
                    }

                    gizmoSpace.m_cubeMatricesTemp.Clear();
                    gizmoSpace.m_cubeModelsTemp.Clear();

                    if (gizmoSpace.m_showGizmoCube)
                    {
                        // Draw mount points of added cube block as yellow squares in neighboring cells.
                        if (MyDebugDrawSettings.ENABLE_DEBUG_DRAW && MyDebugDrawSettings.DEBUG_DRAW_MOUNT_POINTS)
                        {
                            float cubeSize = MyDefinitionManager.Static.GetCubeSize(CurrentBlockDefinition.CubeSize);
                            if (!PlacingSmallGridOnLargeStatic)
                                cubeSize = CurrentGrid.GridSize;

                            DrawMountPoints(cubeSize, CurrentBlockDefinition, ref drawMatrix);
                        }

                        Vector3D rotatedModelOffset;
                        Vector3D.TransformNormal(ref CurrentBlockDefinition.ModelOffset, ref gizmoSpace.m_worldMatrixAdd, out rotatedModelOffset);

                        drawMatrix.Translation = worldCenter + rotatedModelOffset;

                        AddFastBuildModels(gizmoSpace, drawMatrix, gizmoSpace.m_cubeMatricesTemp, gizmoSpace.m_cubeModelsTemp, gizmoSpace.m_blockDefinition);

                        Debug.Assert(gizmoSpace.m_cubeMatricesTemp.Count == gizmoSpace.m_cubeModelsTemp.Count);
                        for (int i = 0; i < gizmoSpace.m_cubeMatricesTemp.Count; ++i)
                        {
                            string model = gizmoSpace.m_cubeModelsTemp[i];
                            if (!string.IsNullOrEmpty(model))
                                m_renderData.AddInstance(MyModel.GetId(model), gizmoSpace.m_cubeMatricesTemp[i], ref m_invGridWorldMatrix);
                        }
                    }
                }
            }

            if (gizmoSpace.m_startRemove != null && gizmoSpace.m_continueBuild != null)
            {
                gizmoSpace.m_buildAllowed = true;

                Vector3I stepDelta;
                Vector3I counter;
                int stepCount;
                ComputeSteps(gizmoSpace.m_startRemove.Value, gizmoSpace.m_continueBuild.Value, Vector3I.One, out stepDelta, out counter, out stepCount);

                var matrix = CurrentGrid.WorldMatrix;
                BoundingBoxD aabb = BoundingBoxD.CreateInvalid();
                aabb.Include((gizmoSpace.m_startRemove.Value * CurrentGrid.GridSize));
                aabb.Include((gizmoSpace.m_continueBuild.Value * CurrentGrid.GridSize));
                aabb.Min -= new Vector3(CurrentGrid.GridSize / 2.0f + 0.02f);
                aabb.Max += new Vector3(CurrentGrid.GridSize / 2.0f + 0.02f);

                MySimpleObjectDraw.DrawTransparentBox(ref matrix, ref aabb, ref white, MySimpleObjectRasterizer.Wireframe, counter, 0.04f, null, "GizmoDrawLineRed", true);
                Color faceColor = new Color(Color.Red * 0.2f, 0.3f);
                MySimpleObjectDraw.DrawTransparentBox(ref matrix, ref aabb, ref faceColor, MySimpleObjectRasterizer.Solid, 0, 0.04f, "Square", null, true);
            }
            else if (remove && gizmoSpace.m_showGizmoCube && ShowRemoveGizmo)
            {
                if (gizmoSpace.m_removeBlock != null)
                    DrawSemiTransparentBox(CurrentGrid, gizmoSpace.m_removeBlock, red, lineMaterial: "GizmoDrawLineRed");

                if (gizmoSpace.m_removeBlock != null && MyDebugDrawSettings.ENABLE_DEBUG_DRAW && MyDebugDrawSettings.DEBUG_DRAW_REMOVE_CUBE_COORDS)
                {
                    var block = gizmoSpace.m_removeBlock;
                    var grid = block.CubeGrid;
                    Matrix gridMatrix = grid.WorldMatrix;
                    Vector3 blockWorldPos = Vector3.Transform(block.Position * grid.GridSize, gridMatrix);

                    // Show forward-up
                    //if (block.FatBlock != null)
                    //{
                    //    MyRenderProxy.DebugDrawLine3D(block.FatBlock.WorldMatrix.Translation, block.FatBlock.WorldMatrix.Translation + block.FatBlock.WorldMatrix.Forward, Color.Red, Color.Red, false);
                    //    MyRenderProxy.DebugDrawLine3D(block.FatBlock.WorldMatrix.Translation, block.FatBlock.WorldMatrix.Translation + block.FatBlock.WorldMatrix.Up, Color.Green, Color.Green, false);
                    //}

                    MyRenderProxy.DebugDrawText3D(blockWorldPos, block.Position.ToString(), Color.White, 1.0f, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER);
                }
            }
            else
            {
                if (MySession.Static.SurvivalMode && (MySession.GetCameraControllerEnum() != MyCameraControllerEnum.Spectator || MyFinalBuildConstants.IS_OFFICIAL))
                {
                    Vector3 localMin = (m_gizmo.SpaceDefault.m_min - new Vector3(0.5f)) * CurrentGrid.GridSize;
                    Vector3 localMax = (m_gizmo.SpaceDefault.m_max + new Vector3(0.5f)) * CurrentGrid.GridSize;
                    BoundingBoxD gizmoBox = new BoundingBoxD(localMin, localMax);

                    if (!MyCubeBuilderGizmo.DefaultGizmoCloseEnough(ref m_invGridWorldMatrix, gizmoBox, CurrentGrid.GridSize, IntersectionDistance))
                    {
                        gizmoSpace.m_removeBlock = null;
                    }
                }
            }
        }
        private static void TestGridPlacement(ref MyGridPlacementSettings settings, ref MatrixD worldMatrix, ref MyCubeGrid touchingGrid, float gridSize, bool isStatic, ref BoundingBoxD localAABB, MyCubeBlockDefinition blockDefinition,
           MyBlockOrientation? blockOrientation, ref bool entityOverlap, ref bool touchingStaticGrid, MyCubeGrid grid)
        {
            var worldAabb = localAABB.Transform(ref worldMatrix);
            var invWorldMatrix = grid.PositionComp.WorldMatrixNormalizedInv;
            var otherLocalAabb = worldAabb.Transform(ref invWorldMatrix);

            Vector3D minToWorld = Vector3D.Transform(localAABB.Min, worldMatrix);
            Vector3D maxToWorld = Vector3D.Transform(localAABB.Max, worldMatrix);
            Vector3D tempMinLocal = Vector3D.Transform(minToWorld, invWorldMatrix);
            Vector3D tempMaxLocal = Vector3D.Transform(maxToWorld, invWorldMatrix);

            Vector3D otherMinLocal = Vector3D.Min(tempMinLocal, tempMaxLocal);
            Vector3D otherMaxLocal = Vector3D.Max(tempMinLocal, tempMaxLocal);

            var scaledMin = (otherMinLocal + gridSize / 2) / grid.GridSize;
            var scaledMax = (otherMaxLocal - gridSize / 2) / grid.GridSize;
            var tempMin = Vector3I.Round(scaledMin);
            var tempMax = Vector3I.Round(scaledMax);
            var min = Vector3I.Min(tempMin, tempMax);
            var max = Vector3I.Max(tempMin, tempMax);

            MyBlockOrientation? gridBlockOrientation = null;
            if (MyFakes.ENABLE_COMPOUND_BLOCKS && isStatic && grid.IsStatic && blockOrientation != null)
            {
                Matrix blockRotation;
                blockOrientation.Value.GetMatrix(out blockRotation);
                Matrix rotationInGrid = blockRotation * worldMatrix;
                rotationInGrid = rotationInGrid * invWorldMatrix;
                rotationInGrid.Translation = Vector3.Zero;

                Base6Directions.Direction forwardDir = Base6Directions.GetForward(ref rotationInGrid);
                Base6Directions.Direction upDir = Base6Directions.GetUp(ref rotationInGrid);
                if (Base6Directions.IsValidBlockOrientation(forwardDir, upDir))
                    gridBlockOrientation = new MyBlockOrientation(forwardDir, upDir);
            }

            if (!grid.CanAddCubes(min, max, gridBlockOrientation, blockDefinition))
            {
                entityOverlap = true;
                return;
            }

            if (settings.CanAnchorToStaticGrid && grid.IsTouchingAnyNeighbor(min, max))
            {
                touchingStaticGrid = true;
                if (touchingGrid == null)
                    touchingGrid = grid;
            }
        }
Esempio n. 22
0
        private void EnableGizmoSpace(MyGizmoSpaceEnum gizmoSpaceEnum, bool enable, Vector3I? planePos, bool isOdd, MyCubeBlockDefinition cubeBlockDefinition, MyCubeGrid cubeGrid)
        {
            var gizmoSpace = m_spaces[(int)gizmoSpaceEnum];
            gizmoSpace.Enabled = enable;

            if (enable)
            {
                if (planePos.HasValue)
                    gizmoSpace.SymmetryPlanePos = planePos.Value;
                gizmoSpace.SymmetryIsOdd = isOdd;
                gizmoSpace.m_buildAllowed = false;

                if (cubeBlockDefinition != null)
                {
                    Quaternion orientationQuat = gizmoSpace.LocalOrientation;
                    MyBlockOrientation blockOrientation = new MyBlockOrientation(ref orientationQuat);

                    Vector3I rotatedBlockSize;
                    MyCubeGridDefinitions.GetRotatedBlockSize(cubeBlockDefinition, ref gizmoSpace.m_localMatrixAdd, out rotatedBlockSize);

                    //integer local center of the cube
                    Vector3I center = cubeBlockDefinition.Center;

                    //integer rotated/world center of the cube
                    Vector3I rotatedCenter;
                    Vector3I.TransformNormal(ref center, ref gizmoSpace.m_localMatrixAdd, out rotatedCenter);

                    //offset to the cube to align exactly on intersected cube
                    Vector3I worldDir = new Vector3I(
                        Math.Sign(rotatedBlockSize.X) == Math.Sign(gizmoSpace.m_addDir.X) ? rotatedCenter.X : Math.Sign(gizmoSpace.m_addDir.X) * ((Math.Abs(rotatedBlockSize.X) - Math.Abs(rotatedCenter.X) - 1)),
                        Math.Sign(rotatedBlockSize.Y) == Math.Sign(gizmoSpace.m_addDir.Y) ? rotatedCenter.Y : Math.Sign(gizmoSpace.m_addDir.Y) * ((Math.Abs(rotatedBlockSize.Y) - Math.Abs(rotatedCenter.Y) - 1)),
                        Math.Sign(rotatedBlockSize.Z) == Math.Sign(gizmoSpace.m_addDir.Z) ? rotatedCenter.Z : Math.Sign(gizmoSpace.m_addDir.Z) * ((Math.Abs(rotatedBlockSize.Z) - Math.Abs(rotatedCenter.Z) - 1)));

                    gizmoSpace.m_positions.Clear();
                    gizmoSpace.m_positionsSmallOnLarge.Clear();

                    if (MyFakes.ENABLE_STATIC_SMALL_GRID_ON_LARGE && gizmoSpace.m_addPosSmallOnLarge != null) {
                        float smallToLarge = MyDefinitionManager.Static.GetCubeSize(cubeBlockDefinition.CubeSize) / cubeGrid.GridSize;

                        gizmoSpace.m_minSmallOnLarge = Vector3.MaxValue;
                        gizmoSpace.m_maxSmallOnLarge = Vector3.MinValue;
                        gizmoSpace.m_centerPosSmallOnLarge = gizmoSpace.m_addPosSmallOnLarge.Value + smallToLarge * worldDir;
                        gizmoSpace.m_buildAllowed = true;

                        Vector3I temp = new Vector3I();

                        for (temp.X = 0; temp.X < cubeBlockDefinition.Size.X; temp.X++)
                            for (temp.Y = 0; temp.Y < cubeBlockDefinition.Size.Y; temp.Y++)
                                for (temp.Z = 0; temp.Z < cubeBlockDefinition.Size.Z; temp.Z++) {
                                    Vector3I rotatedTemp;
                                    Vector3I centeredTemp = temp - center;
                                    Vector3I.TransformNormal(ref centeredTemp, ref gizmoSpace.m_localMatrixAdd, out rotatedTemp);

                                    Vector3 tempIntPos = gizmoSpace.m_addPosSmallOnLarge.Value + smallToLarge * (rotatedTemp + worldDir);
                                    gizmoSpace.m_minSmallOnLarge = Vector3.Min(tempIntPos, gizmoSpace.m_minSmallOnLarge);
                                    gizmoSpace.m_maxSmallOnLarge = Vector3.Max(tempIntPos, gizmoSpace.m_maxSmallOnLarge);

                                    // Commented out - small block can be placed in occupied large block areas 
                                    //if (!cubeGrid.CanAddCube(Vector3I.Round(tempIntPos), blockOrientation, null))
                                    //    gizmoSpace.m_buildAllowed = false;

                                    gizmoSpace.m_positionsSmallOnLarge.Add(tempIntPos);
                                }

                    }
                    else {
                        gizmoSpace.m_min = Vector3I.MaxValue;
                        gizmoSpace.m_max = Vector3I.MinValue;
                        gizmoSpace.m_centerPos = gizmoSpace.m_addPos + worldDir;
                        gizmoSpace.m_buildAllowed = true;

                        Vector3I temp = new Vector3I();

                        for (temp.X = 0; temp.X < cubeBlockDefinition.Size.X; temp.X++)
                            for (temp.Y = 0; temp.Y < cubeBlockDefinition.Size.Y; temp.Y++)
                                for (temp.Z = 0; temp.Z < cubeBlockDefinition.Size.Z; temp.Z++) {
                                    Vector3I rotatedTemp;
                                    Vector3I centeredTemp = temp - center;
                                    Vector3I.TransformNormal(ref centeredTemp, ref gizmoSpace.m_localMatrixAdd, out rotatedTemp);

                                    Vector3I tempIntPos = gizmoSpace.m_addPos + rotatedTemp + worldDir;
                                    gizmoSpace.m_min = Vector3I.Min(tempIntPos, gizmoSpace.m_min);
                                    gizmoSpace.m_max = Vector3I.Max(tempIntPos, gizmoSpace.m_max);

                                    if (cubeGrid != null && !cubeGrid.CanAddCube(tempIntPos, blockOrientation, cubeBlockDefinition))
                                        gizmoSpace.m_buildAllowed = false;

                                    gizmoSpace.m_positions.Add(tempIntPos);
                                }
                    }
                }

                if (gizmoSpace.SymmetryPlane != MySymmetrySettingModeEnum.Disabled)
                    MirrorGizmoSpace(gizmoSpace, m_spaces[(int)gizmoSpace.SourceSpace], gizmoSpace.SymmetryPlane, planePos.Value, isOdd, cubeBlockDefinition, cubeGrid);
            }
        }
        /// <summary>
        /// Fills passed lists with mount point data, which is transformed using orientation
        /// of the block.
        /// </summary>
        /// <param name="outMountPoints">Output buffer.</param>
		/// <param name="performCorrection">True when you want to have correction performed for when rotation of fractional values would have different result than integers.</param>
        public static void TransformMountPoints(List<MyCubeBlockDefinition.MountPoint> outMountPoints, MyCubeBlockDefinition def, MyCubeBlockDefinition.MountPoint[] mountPoints, ref MyBlockOrientation orientation)
        {
            Debug.Assert(outMountPoints != null);

            outMountPoints.Clear();

			if (mountPoints == null)
                return;

            Matrix rotation;
            orientation.GetMatrix(out rotation);

			var center = def.Center;
			for (int i = 0; i < mountPoints.Length; ++i)
            {
				var mountPoint = mountPoints[i];
                var mp = new MyCubeBlockDefinition.MountPoint();
				var centeredStart = mountPoint.Start - center;
				var centeredEnd = mountPoint.End - center;
				Vector3I.Transform(ref mountPoint.Normal, ref rotation, out mp.Normal);
                Vector3.Transform(ref centeredStart, ref rotation, out mp.Start);
                Vector3.Transform(ref centeredEnd, ref rotation, out mp.End);
				mp.ExclusionMask = mountPoint.ExclusionMask;
				mp.PropertiesMask = mountPoint.PropertiesMask;
				mp.Enabled = mountPoint.Enabled;

                // Correction of situations when 0.5 would get transformed to -0.5, resulting in different floor() (integer 0 is transformed to 0).
				var startICorrect = Vector3I.Floor(mountPoint.Start) - center;
				var endICorrect = Vector3I.Floor(mountPoint.End) - center;
                Vector3I.Transform(ref startICorrect, ref rotation, out startICorrect);
                Vector3I.Transform(ref endICorrect, ref rotation, out endICorrect);

                var startI = Vector3I.Floor(mp.Start);
                var endI = Vector3I.Floor(mp.End);
                var startCorrection = startICorrect - startI;
                var endCorrection = endICorrect - endI;

                mp.Start += startCorrection;
                mp.End += endCorrection;

                outMountPoints.Add(mp);
            }
        }
Esempio n. 24
0
        public void Build(MySlimBlock cubeBlock, long owner, long builder)
        {
            Quaternion quat = Quaternion.Identity;
            var orientation = cubeBlock.Orientation;

            Matrix local;
            orientation.GetMatrix(out local);
            var gridOrientation = m_clipboard.GetFirstGridOrientationMatrix();
            if (gridOrientation != Matrix.Identity)
            {
                var afterRotation = Matrix.Multiply(local, gridOrientation);
                orientation = new MyBlockOrientation(ref afterRotation);
            }

            Quaternion projQuat = Quaternion.Identity;
            Orientation.GetQuaternion(out projQuat);
            orientation.GetQuaternion(out quat);
            quat = Quaternion.Multiply(projQuat, quat);


            var projectorGrid = CubeGrid;
            var projectedGrid = cubeBlock.CubeGrid;

            Vector3I cubeMin = cubeBlock.FatBlock != null ? cubeBlock.FatBlock.Min : cubeBlock.Position;
            Vector3I cubeMax = cubeBlock.FatBlock != null ? cubeBlock.FatBlock.Max : cubeBlock.Position;

            Vector3I min = projectorGrid.WorldToGridInteger(projectedGrid.GridIntegerToWorld(cubeMin));
            Vector3I max = projectorGrid.WorldToGridInteger(projectedGrid.GridIntegerToWorld(cubeMax));
            Vector3I pos = projectorGrid.WorldToGridInteger(projectedGrid.GridIntegerToWorld(cubeBlock.Position));

            Vector3I projectedMin = new Vector3I(Math.Min(min.X, max.X), Math.Min(min.Y, max.Y), Math.Min(min.Z, max.Z));
            Vector3I projectedMax = new Vector3I(Math.Max(min.X, max.X), Math.Max(min.Y, max.Y), Math.Max(min.Z, max.Z));


            MyCubeGrid.MyBlockLocation location = new MyCubeGrid.MyBlockLocation(cubeBlock.BlockDefinition.Id, projectedMin, projectedMax, pos,
                quat, 0, owner, builder);

            MyObjectBuilder_CubeBlock objectBuilder = null;
            //Find original grid builder
            foreach (var blockBuilder in m_originalGridBuilder.CubeBlocks)
            {
                if (blockBuilder.Min == cubeMin && blockBuilder.GetId() == cubeBlock.BlockDefinition.Id)
                {
                    objectBuilder = (MyObjectBuilder_CubeBlock)blockBuilder.Clone();
                    objectBuilder.SetupForProjector();
                }
            }

            if (objectBuilder == null)
            {
                System.Diagnostics.Debug.Fail("Original object builder could not be found! (AlexFlorea)");
                objectBuilder = cubeBlock.GetObjectBuilder();
                location.EntityId = MyEntityIdentifier.AllocateId();
            }

            objectBuilder.ConstructionInventory = null;
            projectorGrid.BuildBlock(cubeBlock.ColorMaskHSV, location, objectBuilder);
            HideCube(cubeBlock);
        }
Esempio n. 25
0
        public BuildCheckResult CanBuild(MySlimBlock projectedBlock, bool checkHavokIntersections)
        {
            MyBlockOrientation blockOrientation = projectedBlock.Orientation;
            
            Matrix local;
            blockOrientation.GetMatrix(out local);
            var gridOrientation = (m_clipboard as MyGridClipboard).GetFirstGridOrientationMatrix();
            if (gridOrientation != Matrix.Identity)
            {
                var afterRotation = Matrix.Multiply(local, gridOrientation);
                blockOrientation = new MyBlockOrientation(ref afterRotation);
            }
            
            Quaternion blockOrientationQuat;
            blockOrientation.GetQuaternion(out blockOrientationQuat);

            Quaternion projQuat = Quaternion.Identity;
            Orientation.GetQuaternion(out projQuat);
            blockOrientationQuat = Quaternion.Multiply(projQuat, blockOrientationQuat);

            Vector3I projectedMin = CubeGrid.WorldToGridInteger(projectedBlock.CubeGrid.GridIntegerToWorld(projectedBlock.Min));
            Vector3I projectedMax = CubeGrid.WorldToGridInteger(projectedBlock.CubeGrid.GridIntegerToWorld(projectedBlock.Max));
            Vector3I blockPos = CubeGrid.WorldToGridInteger(projectedBlock.CubeGrid.GridIntegerToWorld(projectedBlock.Position));

            Vector3I min = new Vector3I(Math.Min(projectedMin.X, projectedMax.X), Math.Min(projectedMin.Y, projectedMax.Y), Math.Min(projectedMin.Z, projectedMax.Z));
            Vector3I max = new Vector3I(Math.Max(projectedMin.X, projectedMax.X), Math.Max(projectedMin.Y, projectedMax.Y), Math.Max(projectedMin.Z, projectedMax.Z));

            projectedMin = min;
            projectedMax = max;

            if (!CubeGrid.CanAddCubes(projectedMin, projectedMax))
            {
                return BuildCheckResult.IntersectedWithGrid;
            }

            MyGridPlacementSettings settings = new MyGridPlacementSettings();
            settings.Mode = MyGridPlacementSettings.SnapMode.OneFreeAxis;

            bool canBuild = true;
            if (checkHavokIntersections)
            {
                canBuild = MyCubeGrid.TestPlacementAreaCube(CubeGrid, ref settings, projectedMin, projectedMax, blockOrientation, projectedBlock.BlockDefinition, CubeGrid);
            }

            bool isConnected = MyCubeGrid.CheckConnectivity(this.CubeGrid, projectedBlock.BlockDefinition, ref blockOrientationQuat, ref blockPos);

            if (!canBuild)
            {
                return BuildCheckResult.IntersectedWithSomethingElse;
            }
            else
            {
                if (isConnected)
                {
                    if (CubeGrid.GetCubeBlock(blockPos) == null)
                    {
                        return BuildCheckResult.OK;
                    }
                    else
                    {
                        return BuildCheckResult.AlreadyBuilt;
                    }
                }
            }

            return BuildCheckResult.NotConnected;
        }
 public static bool TestBlockPlacementArea(
     MyCubeGrid targetGrid,
     ref MyGridPlacementSettings settings,
     MyBlockOrientation blockOrientation,
     MyCubeBlockDefinition blockDefinition,
     ref Vector3D translation,
     ref Quaternion rotation,
     ref Vector3 halfExtents,
     ref BoundingBoxD localAabb,
     MyEntity ignoredEntity = null)
 {
     MyCubeGrid touchingGrid;
     return TestBlockPlacementArea(targetGrid, ref settings, blockOrientation, blockDefinition, ref translation, ref rotation, ref halfExtents, ref localAabb, out touchingGrid, ignoredEntity: ignoredEntity);
 }
 /// <summary>
 /// Checkes whether blocks A and B have matching mount point on one of their sides. Each block is given by its
 /// definition, rotation and position in grid. Position has to be relative to same center. Also, normal relative to block A specifies
 /// wall which is used for checking.
 /// </summary>
 public static bool CheckMountPointsForSide(MyCubeBlockDefinition defA, MyCubeBlockDefinition.MountPoint[] mountPointsA, ref MyBlockOrientation orientationA, ref Vector3I positionA, ref Vector3I normalA,
                                            MyCubeBlockDefinition defB, MyCubeBlockDefinition.MountPoint[] mountPointsB, ref MyBlockOrientation orientationB, ref Vector3I positionB)
 {
     TransformMountPoints(m_cacheMountPointsA, defA, mountPointsA, ref orientationA);
     TransformMountPoints(m_cacheMountPointsB, defB, mountPointsB, ref orientationB);
     return CheckMountPointsForSide(m_cacheMountPointsA, ref orientationA, ref positionA, defA.Id, ref normalA, m_cacheMountPointsB, ref orientationB, ref positionB, defB.Id);
 }
        public static bool TestBlockPlacementArea(
            MyCubeGrid targetGrid,
            ref MyGridPlacementSettings settings,
            MyBlockOrientation blockOrientation,
            MyCubeBlockDefinition blockDefinition,
            ref Vector3D translation,
            ref Quaternion rotation,
            ref Vector3 halfExtents,
            ref BoundingBoxD localAabb,
            out MyCubeGrid touchingGrid,
            MyEntity ignoredEntity = null,
            bool ignoreFracturedPieces = false)
        {
            touchingGrid = null;

            ProfilerShort.Begin("UseModelIntersection");
            if (blockDefinition != null && blockDefinition.UseModelIntersection)
            {
                var model = VRage.Game.Models.MyModels.GetModelOnlyData(blockDefinition.Model);
                if (model != null)
                {
                    bool newErrorFound;
                    model.CheckLoadingErrors(blockDefinition.Context, out newErrorFound);
                    if (newErrorFound)
                        MyDefinitionErrors.Add(blockDefinition.Context,
                            "There was error during loading of model, please check log file.", TErrorSeverity.Error);
                }

                if (model != null && model.HavokCollisionShapes != null)
                {
                    int shapeCount = model.HavokCollisionShapes.Length;
                    HkShape[] shapes = new HkShape[shapeCount];
                    for (int q = 0; q < shapeCount; ++q)
                    {
                        shapes[q] = model.HavokCollisionShapes[q];
                    }

                    var shape = new HkListShape(shapes, shapeCount, HkReferencePolicy.None);

                    Quaternion q2 = Quaternion.CreateFromForwardUp(Base6Directions.GetVector(blockOrientation.Forward), Base6Directions.GetVector(blockOrientation.Up));
                    rotation = rotation * q2;
                    MyPhysics.GetPenetrationsShape(shape, ref translation, ref rotation, m_physicsBoxQueryList, MyPhysics.CollisionLayers.CharacterCollisionLayer);

                    shape.Base.RemoveReference();
                }
                else
                {
                    Debug.Assert(m_physicsBoxQueryList.Count == 0, "List not cleared");
                    MyPhysics.GetPenetrationsBox(ref halfExtents, ref translation, ref rotation, m_physicsBoxQueryList, MyPhysics.CollisionLayers.CharacterCollisionLayer);
                }
            }
            else
            {
                Debug.Assert(m_physicsBoxQueryList.Count == 0, "List not cleared");
                MyPhysics.GetPenetrationsBox(ref halfExtents, ref translation, ref rotation, m_physicsBoxQueryList, MyPhysics.CollisionLayers.CharacterCollisionLayer);
            }
            m_lastQueryBox.HalfExtents = halfExtents;
            m_lastQueryTransform = MatrixD.CreateFromQuaternion(rotation);
            m_lastQueryTransform.Translation = translation;

            var worldMatrix = targetGrid != null ? targetGrid.WorldMatrix : MatrixD.Identity;
            ProfilerShort.BeginNextBlock("TestPlacementAreaInternal");
            bool result = TestPlacementAreaInternal(targetGrid, ref settings, blockDefinition, blockOrientation, ref localAabb, ignoredEntity, ref worldMatrix, out touchingGrid, ignoreFracturedPieces: ignoreFracturedPieces);
            ProfilerShort.End();
            return result;
        }
Esempio n. 29
0
 public abstract void GetBlockPlacementMaterials(MyCubeBlockDefinition definition, Vector3I position, MyBlockOrientation orientation, MyCubeGrid grid);
 public static bool TestPlacementAreaCube(
     MyCubeGrid targetGrid,
     ref MyGridPlacementSettings settings,
     Vector3I min,
     Vector3I max,
     MyBlockOrientation blockOrientation,
     MyCubeBlockDefinition blockDefinition,
     MyEntity ignoredEntity = null,
     bool ignoreFracturedPieces = false)
 {
     MyCubeGrid touchingGrid = null;
     return TestPlacementAreaCube(targetGrid, ref settings, min, max, blockOrientation, blockDefinition, out touchingGrid, ignoredEntity: ignoredEntity, ignoreFracturedPieces: ignoreFracturedPieces);
 }
Esempio n. 31
0
        public void Init(MyObjectBuilder_CubeBlock objectBuilder, MyCubeGrid cubeGrid, MyCubeBlock fatBlock)
        {
            ProfilerShort.Begin("SlimBlock.Init(objectBuilder, ...)");
            Debug.Assert(cubeGrid != null);
            FatBlock = fatBlock;
            m_soundEmitter.Entity = FatBlock;

            if (objectBuilder is MyObjectBuilder_CompoundCubeBlock)
                BlockDefinition = MyCompoundCubeBlock.GetCompoundCubeBlockDefinition();
            else
                BlockDefinition = MyDefinitionManager.Static.GetCubeBlockDefinition(objectBuilder.GetId());
            m_componentStack = new MyComponentStack(BlockDefinition, objectBuilder.IntegrityPercent, objectBuilder.BuildPercent);

            if (MyCubeGridDefinitions.GetCubeRotationOptions(BlockDefinition) == MyRotationOptionsEnum.None)
            {
                objectBuilder.BlockOrientation = MyBlockOrientation.Identity;
            }

            DeformationRatio = BlockDefinition.DeformationRatio;
            Min = objectBuilder.Min;

            Orientation = objectBuilder.BlockOrientation;
            if (!Orientation.IsValid)
                Orientation = MyBlockOrientation.Identity;

            Debug.Assert(Orientation.IsValid, "Orientation of block is not valid.");

            CubeGrid = cubeGrid;
            ColorMaskHSV = objectBuilder.ColorMaskHSV;

            if (BlockDefinition.CubeDefinition != null)
            {
                //Ensure we have always only one distinct orientation use
                Orientation = MyCubeGridDefinitions.GetTopologyUniqueOrientation(BlockDefinition.CubeDefinition.CubeTopology, Orientation);
            }

            ComputeMax(BlockDefinition, Orientation, ref Min, out Max);

            Matrix localMatrix;
            Orientation.GetMatrix(out localMatrix);
            Position = ComputePositionInGrid(ref localMatrix);

            UpdateShowParts();

            if (FatBlock == null)
            {
                bool isRenderedAsModel = !String.IsNullOrEmpty(BlockDefinition.Model);
                bool showConstructionModel = BlockDefinition.BlockTopology == MyBlockTopology.Cube && !ShowParts;
                if (isRenderedAsModel || showConstructionModel)
                {
                    FatBlock = new MyCubeBlock();
                    m_soundEmitter.Entity = FatBlock;
                }
            }

            if (FatBlock != null)
            {
                ProfilerShort.Begin("FatBlock.Init(objectBuilder, ...)");
                FatBlock.SlimBlock = this;
                FatBlock.Init(objectBuilder, cubeGrid);
                ProfilerShort.End();
            }

            if (objectBuilder.ConstructionStockpile != null)
            {
                EnsureConstructionStockpileExists();
                m_stockpile.Init(objectBuilder.ConstructionStockpile);
            }
            else if (objectBuilder.ConstructionInventory != null) // Backwards compatibility
            {
                EnsureConstructionStockpileExists();
                m_stockpile.Init(objectBuilder.ConstructionInventory);
            }

            if (FatBlock == null || FatBlock.GetType() == typeof(MyCubeBlock))
                m_objectBuilder = new MyObjectBuilder_CubeBlock();

            if (MyFakes.SHOW_DAMAGE_EFFECTS && FatBlock != null && BlockDefinition.RationEnoughForDamageEffect(Integrity / MaxIntegrity))
            {//start effect
                if (CurrentDamage>0)//fix for weird simple blocks having FatBlock - old save?
                {
                    FatBlock.SetDamageEffect(true);
                }
                
            }

            ProfilerShort.End();
        }
        /// <summary>
        /// Test cube block placement area in grid.
        /// </summary>
        public static bool TestPlacementAreaCube(
            MyCubeGrid targetGrid,
            ref MyGridPlacementSettings settings,
            Vector3I min,
            Vector3I max,
            MyBlockOrientation blockOrientation,
            MyCubeBlockDefinition blockDefinition,
            out MyCubeGrid touchingGrid,
            MyEntity ignoredEntity = null,
            bool ignoreFracturedPieces = false)
        {
            touchingGrid = null;

            ProfilerShort.Begin("Math");
            var worldMatrix = targetGrid != null ? targetGrid.WorldMatrix : MatrixD.Identity;
            var gridSize = targetGrid != null ? targetGrid.GridSize : MyDefinitionManager.Static.GetCubeSize(MyCubeSize.Large);

            Vector3 halfExtents = ((max - min) * gridSize + gridSize) / 2;
            if (MyFakes.ENABLE_BLOCK_PLACING_IN_OCCUPIED_AREA)
                halfExtents -= new Vector3D(GRID_PLACING_AREA_FIX_VALUE);
            else
                halfExtents -= new Vector3(0.03f, 0.03f, 0.03f); //allows touching blocks like wheels
            var matrix = MatrixD.CreateTranslation((max + min) * 0.5f * gridSize) * worldMatrix;
            var localAabb = BoundingBoxD.CreateInvalid();
            localAabb.Include(min * gridSize - gridSize / 2);
            localAabb.Include(max * gridSize + gridSize / 2);

            Vector3D translation = matrix.Translation;
            Quaternion rotation = Quaternion.CreateFromRotationMatrix(matrix);

            ProfilerShort.BeginNextBlock("TestBlockPlacementArea");
            bool result = TestBlockPlacementArea(targetGrid, ref settings, blockOrientation, blockDefinition, ref translation, ref rotation, ref halfExtents, ref localAabb, out touchingGrid, ignoredEntity: ignoredEntity, 
                ignoreFracturedPieces: ignoreFracturedPieces);

            ProfilerShort.End();

            return result;
        }
Esempio n. 33
0
        /// <summary>
        /// An argument variant of the previous function
        /// </summary>
        public void InitOrientation(MyBlockOrientation orientation)
        {
            if (!orientation.IsValid)
                Orientation = MyBlockOrientation.Identity;

            InitOrientation(orientation.Forward, orientation.Up);
        }
Esempio n. 34
0
 void IMySlimBlock.InitOrientation(VRageMath.MyBlockOrientation orientation)
 {
     InitOrientation(orientation);
 }