private ProjectedGrid(ulong activator, IMyProjector p, List <MyObjectBuilder_CubeGrid> grids, GridBounds bounds, GridComponents comps, GridOrientation orientation, bool shiftBuildArea, int blockCount) { Activator = activator; BlockCount = blockCount; this.p = p; this.grids = grids; this.bounds = bounds; this.comps = comps; finalOrientation = orientation; this.shiftBuildArea = shiftBuildArea; }
private void Create(List <MyObjectBuilder_CubeGrid> grids) { Vector3D centerSum = new Vector3D(); MatrixD mRef = reference.WorldMatrix; MatrixD mRefNI = MatrixD.Normalize(MatrixD.Invert(mRef)); obbs = new List <MyOrientedBoundingBoxD>(grids.Count); orientation = new GridOrientation(reference); entityIds = new HashSet <long>(); foreach (MyObjectBuilder_CubeGrid grid in grids) { entityIds.Add(grid.EntityId); Vector3I min = Vector3I.MaxValue; Vector3I max = Vector3I.MinValue; foreach (MyObjectBuilder_CubeBlock cube in grid.CubeBlocks) { min = Vector3I.Min(min, cube.Min); max = Vector3I.Max(max, ComputeMax(cube)); } double cubeGridSize = grid.GridSizeEnum == MyCubeSize.Large ? 2.5 : 0.5; Vector3D pMin = min * cubeGridSize - (cubeGridSize * 0.5); Vector3D pMax = max * cubeGridSize + (cubeGridSize * 0.5); MyPositionAndOrientation pos = grid.PositionAndOrientation.Value; Vector3D center = Vector3D.Transform((pMin + pMax) * 0.5, pos.GetMatrix()); centerSum += center; MyOrientedBoundingBoxD box = new MyOrientedBoundingBoxD(center, (pMax - pMin) * 0.5, pos.Orientation); obbs.Add(box); orientation.Include(MatrixD.CreateWorld(center, pos.Forward, pos.Up)); } centerSum /= obbs.Count; relativeCenter = Vector3D.TransformNormal(centerSum - mRef.Translation, MatrixD.Transpose(mRef)); double radius2 = 0; foreach (MyOrientedBoundingBoxD obb in obbs) { double dist2 = Vector3D.DistanceSquared(centerSum, obb.Center) + obb.HalfExtent.LengthSquared(); if (dist2 > radius2) { radius2 = dist2; } } worldVolume = new BoundingSphereD(centerSum, Math.Sqrt(radius2)); }
public bool TryFindClearArea(GridOrientation orientation) { Vector3D?result = MyAPIGateway.Entities.FindFreePlace(worldVolume.Center, (float)worldVolume.Radius); if (!result.HasValue || Vector3D.DistanceSquared(worldVolume.Center, result.Value) > Constants.maxNewDist2) { return(false); } MatrixD mRef = reference.WorldMatrix; Vector3D newPosRel = Vector3D.TransformNormal(result.Value - mRef.Translation, MatrixD.Transpose(mRef)); orientation.Translate(newPosRel - relativeCenter); return(true); }
public static bool TryCreate(ulong activator, IMyProjector p, bool shiftBuildArea, out ProjectedGrid projectedGrid) { projectedGrid = null; // Ensure the projector is valid and has a projection if (p.CubeGrid?.Physics == null) { Utilities.Notify(Constants.msgError + "bad_physics", activator); return(false); } if (p.ProjectedGrid == null) { Utilities.Notify(Constants.msgNoGrid, activator); return(false); } MyObjectBuilder_Projector pBuilder = (MyObjectBuilder_Projector)p.GetObjectBuilderCubeBlock(true); if (pBuilder.ProjectedGrids == null || pBuilder.ProjectedGrids.Count == 0) { Utilities.Notify(Constants.msgNoGrid, activator); return(false); } // Prepare list of grids List <MyObjectBuilder_CubeGrid> grids = pBuilder.ProjectedGrids; int largestIndex = FindLargest(grids); MyObjectBuilder_CubeGrid largestGrid = grids[largestIndex]; if (Utilities.SupportsSubgrids(p)) { if (largestIndex != 0) { MyObjectBuilder_CubeGrid temp = grids[0]; grids[0] = largestGrid; grids[largestIndex] = temp; } } else { grids.Clear(); grids.Add(largestGrid); } MatrixD largestMatrixInvert = MatrixD.Invert(largestGrid.PositionAndOrientation.Value.GetMatrix()); MatrixD targetMatrix = p.ProjectedGrid.WorldMatrix; float scale = GetScale(p); GridOrientation orientation = new GridOrientation(p); GridComponents comps = null; if (!MyAPIGateway.Session.CreativeMode) { comps = new GridComponents(); } int totalBlocks = 0; MyIDModule owner = ((MyCubeBlock)p).IDModule; if (activator != 0) { long temp = MyAPIGateway.Players.TryGetIdentityId(activator); if (temp != 0) { if (owner.ShareMode == MyOwnershipShareModeEnum.All) { owner = new MyIDModule(temp, MyOwnershipShareModeEnum.Faction); } else { owner = new MyIDModule(temp, owner.ShareMode); } } } Random rand = new Random(); foreach (MyObjectBuilder_CubeGrid grid in grids) { totalBlocks += grid.CubeBlocks.Count; if (totalBlocks > IPSession.Instance.MapSettings.MaxBlocks) { Utilities.Notify(Constants.msgGridLarge, activator); return(false); } PrepBlocks(rand, owner, grid, comps); if (grid.CubeBlocks.Count == 0) { Utilities.Notify(Constants.msgGridSmall, activator); return(false); } grid.IsStatic = false; grid.CreatePhysics = true; grid.Immune = false; grid.DestructibleBlocks = true; MatrixD current = grid.PositionAndOrientation.Value.GetMatrix(); if (scale != 1) { current.Translation /= scale; } MatrixD newWorldMatrix = (current * largestMatrixInvert) * targetMatrix; grid.PositionAndOrientation = new MyPositionAndOrientation(ref newWorldMatrix); orientation.Include(newWorldMatrix); } if (totalBlocks < IPSession.Instance.MapSettings.MinBlocks) { Utilities.Notify(Constants.msgGridSmall, activator); return(false); } if (comps == null) { comps = new GridComponents(); } else { comps.ApplySettings(IPSession.Instance.MapSettings); int needed; MyDefinitionId neededId; if (!comps.HasComponents(Utilities.GetInventories(p), out needed, out neededId)) { Utilities.Notify(Utilities.GetCompsString(needed, neededId), activator); return(false); } } GridBounds bounds = new GridBounds(p, grids); IMyEntity e = bounds.GetOverlappingEntity(); if (e != null && (!shiftBuildArea || !bounds.HasClearArea())) { Utilities.Notify(Utilities.GetOverlapString(true, e), activator); return(false); } projectedGrid = new ProjectedGrid(activator, p, grids, bounds, comps, orientation, shiftBuildArea, totalBlocks); return(true); }