private static bool ResetVoxelInArea(Vector3D Center, float Radius) { try { BoundingSphereD Sphere = new BoundingSphereD(Center, Radius); List <MyVoxelBase> Maps = MyEntities.GetEntitiesInSphere(ref Sphere).OfType <MyVoxelBase>().ToList(); if (Maps.Count == 0) { return(true); } foreach (var voxelMap in Maps) { using (voxelMap.Pin()) { if (voxelMap.MarkedForClose) { continue; } MyShapeSphere shape = new MyShapeSphere(); shape.Center = Center; shape.Radius = Radius; Vector3I minCorner; Vector3I maxCorner; Vector3I numCells; BoundingBoxD shapeAabb = shape.GetWorldBoundaries(); Vector3I StorageSize = voxelMap.Storage.Size; MyVoxelCoordSystems.WorldPositionToVoxelCoord(voxelMap.PositionLeftBottomCorner, ref shapeAabb.Min, out minCorner); MyVoxelCoordSystems.WorldPositionToVoxelCoord(voxelMap.PositionLeftBottomCorner, ref shapeAabb.Max, out maxCorner); minCorner += voxelMap.StorageMin; maxCorner += voxelMap.StorageMin; maxCorner += 1; StorageSize -= 1; Vector3I.Clamp(ref minCorner, ref Vector3I.Zero, ref StorageSize, out minCorner); Vector3I.Clamp(ref maxCorner, ref Vector3I.Zero, ref StorageSize, out maxCorner); numCells = new Vector3I((maxCorner.X - minCorner.X) / 16, (maxCorner.Y - minCorner.Y) / 16, (maxCorner.Z - minCorner.Z) / 16); minCorner = Vector3I.Max(Vector3I.One, minCorner); maxCorner = Vector3I.Max(minCorner, maxCorner - Vector3I.One); voxelMap.Storage.DeleteRange(MyStorageDataTypeFlags.ContentAndMaterial, minCorner, maxCorner, false); BoundingBoxD cutOutBox = shape.GetWorldBoundaries(); MySandboxGame.Static.Invoke(delegate { if (voxelMap.Storage != null) { voxelMap.Storage.NotifyChanged(minCorner, maxCorner, MyStorageDataTypeFlags.ContentAndMaterial); MyVoxelGenerator.NotifyVoxelChanged(MyVoxelBase.OperationType.Revert, voxelMap, ref cutOutBox); } }, "RevertShape notify"); } } return(true); } catch (Exception ex) { _log.Error(ex, "Voxel reset failed!"); return(false); } }
protected override void Init(MyObjectBuilder_DefinitionBase builder) { base.Init(builder); var ob = builder as MyObjectBuilder_MultiBlockDefinition; MyDebug.AssertDebug(ob != null); if (ob.BlockDefinitions != null && ob.BlockDefinitions.Length > 0) { MinPosition = Vector3I.MaxValue; MaxPosition = Vector3I.MinValue; BlockDefinitions = new MyMultiBlockPartDefinition[ob.BlockDefinitions.Length]; for (int i = 0; i < ob.BlockDefinitions.Length; ++i) { BlockDefinitions[i] = new MyMultiBlockPartDefinition(); var obBlockDef = ob.BlockDefinitions[i]; BlockDefinitions[i].Id = obBlockDef.Id; BlockDefinitions[i].Position = obBlockDef.Position; BlockDefinitions[i].Forward = obBlockDef.Orientation.Forward; BlockDefinitions[i].Up = obBlockDef.Orientation.Up; MinPosition = Vector3I.Min(MinPosition, obBlockDef.Position); MaxPosition = Vector3I.Max(MaxPosition, obBlockDef.Position); } } }
private Vector3I FindTriangleCube(int triIndex, ref Vector3I edgePositionA, ref Vector3I edgePositionB) { Vector3I min, max; Vector3I.Min(ref edgePositionA, ref edgePositionB, out min); Vector3I.Max(ref edgePositionA, ref edgePositionB, out max); min = Vector3I.Round(new Vector3(min) / 256.0f - Vector3.Half); max = Vector3I.Round(new Vector3(max) / 256.0f + Vector3.Half); for (var it = new Vector3I.RangeIterator(ref min, ref max); it.IsValid(); it.GetNext(out min)) { List <int> list; m_smallTriangleRegistry.TryGetValue(min, out list); if (list == null) { continue; } if (list.Contains(triIndex)) { return(min); } } Debug.Assert(false, "Could not find navmesh triangle cube. Shouldn't get here!"); return(Vector3I.Zero); }
/// <summary> /// Non-allocating version of Sandbox.Game.Entities.MyCubeGrid.GetBlocksInsideSphere() /// </summary> public void GetBlocksInsideSphere(IMyCubeGrid grid, List <IMySlimBlock> blockList, ref BoundingSphereD sphere) { if (grid.PositionComp != null) { MatrixD matrix = grid.PositionComp.WorldMatrixNormalizedInv; Vector3D result; Vector3D.Transform(ref sphere.Center, ref matrix, out result); BoundingSphere localSphere = new BoundingSphere(result, (float)sphere.Radius); BoundingBox boundingBox = BoundingBox.CreateFromSphere(localSphere); double gridSizeR = 1d / grid.GridSize; Vector3I searchMin = new Vector3I ( (int)Math.Round(boundingBox.Min.X * gridSizeR), (int)Math.Round(boundingBox.Min.Y * gridSizeR), (int)Math.Round(boundingBox.Min.Z * gridSizeR) ); Vector3I searchMax = new Vector3I ( (int)Math.Round(boundingBox.Max.X * gridSizeR), (int)Math.Round(boundingBox.Max.Y * gridSizeR), (int)Math.Round(boundingBox.Max.Z * gridSizeR) ); Vector3I start = Vector3I.Max(Vector3I.Min(searchMin, searchMax), grid.Min); Vector3I end = Vector3I.Min(Vector3I.Max(searchMin, searchMax), grid.Max); var gridIterator = new Vector3I_RangeIterator(ref start, ref end); Vector3I next = gridIterator.Current; blockHashBuffer.Clear(); while (gridIterator.IsValid()) { IMySlimBlock cube = grid.GetCubeBlock(next); float gridSizeHalf = grid.GridSize / 2f; if (cube != null) { var cubeBounds = new BoundingBox((cube.Min * grid.GridSize) - gridSizeHalf, (cube.Max * grid.GridSize) + gridSizeHalf); if (cubeBounds.Intersects(localSphere)) { blockHashBuffer.Add(cube); } } gridIterator.GetNext(out next); } blockList.Clear(); blockList.EnsureCapacity(blockHashBuffer.Count); foreach (IMySlimBlock block in blockHashBuffer) { blockList.Add(block); } } }
public void GetFilledStorageBounds(out Vector3I min, out Vector3I max) { min = Vector3I.MaxValue; max = Vector3I.MinValue; Vector3I sz = Size; Vector3I SMax = Size - 1; MyStorageData data = new MyStorageData(); data.Resize(Size); Storage.ReadRange(data, MyStorageDataTypeFlags.Content, 0, Vector3I.Zero, SMax); for (int z = 0; z < sz.Z; ++z) { for (int y = 0; y < sz.Y; ++y) { for (int x = 0; x < sz.X; ++x) { if (data.Content(x, y, z) > MyVoxelConstants.VOXEL_ISO_LEVEL) { Vector3I l = Vector3I.Max(new Vector3I(x - 1, y - 1, z - 1), Vector3I.Zero); min = Vector3I.Min(l, min); Vector3I h = Vector3I.Min(new Vector3I(x + 1, y + 1, z + 1), SMax); max = Vector3I.Max(h, max); } } } } }
void DoCuboid() { Vector3I min = Vector3I.Min(mark1, mark2); Vector3I max = Vector3I.Max(mark1, mark2); if (!game.World.IsValidPos(min) || !game.World.IsValidPos(max)) { return; } BlockID toPlace = (BlockID)block; if (block == -1) { toPlace = game.Inventory.Selected; } for (int y = min.Y; y <= max.Y; y++) { for (int z = min.Z; z <= max.Z; z++) { for (int x = min.X; x <= max.X; x++) { game.UpdateBlock(x, y, z, toPlace); } } } }
protected override void Init(MyObjectBuilder_DefinitionBase ob) { base.Init(ob); var objectBuilder = ob as MyObjectBuilder_BlockNavigationDefinition; Debug.Assert(ob != null); if (ob == null) { return; } if (objectBuilder.NoEntry || objectBuilder.Triangles == null) { NoEntry = true; } else { NoEntry = false; var newMesh = new MyGridNavigationMesh(null, null, objectBuilder.Triangles.Length); Vector3I maxPos = objectBuilder.Size - Vector3I.One - objectBuilder.Center; Vector3I minPos = -(Vector3I)(objectBuilder.Center); foreach (var triOb in objectBuilder.Triangles) { Vector3 pa = (Vector3)triOb.Points[0]; Vector3 pb = (Vector3)triOb.Points[1]; Vector3 pc = (Vector3)triOb.Points[2]; var tri = newMesh.AddTriangle(ref pa, ref pb, ref pc); var center = (pa + pb + pc) / 3.0f; // We want to move the triangle vertices more towards the triangle center to ensure correct calculation of containing cube Vector3 cvA = (center - pa) * 0.0001f; Vector3 cvB = (center - pb) * 0.0001f; Vector3 cvC = (center - pc) * 0.0001f; Vector3I gridPosA = Vector3I.Round(pa + cvA); Vector3I gridPosB = Vector3I.Round(pb + cvB); Vector3I gridPosC = Vector3I.Round(pc + cvC); Vector3I.Clamp(ref gridPosA, ref minPos, ref maxPos, out gridPosA); Vector3I.Clamp(ref gridPosB, ref minPos, ref maxPos, out gridPosB); Vector3I.Clamp(ref gridPosC, ref minPos, ref maxPos, out gridPosC); Vector3I min, max; Vector3I.Min(ref gridPosA, ref gridPosB, out min); Vector3I.Min(ref min, ref gridPosC, out min); Vector3I.Max(ref gridPosA, ref gridPosB, out max); Vector3I.Max(ref max, ref gridPosC, out max); Vector3I pos = min; for (var it = new Vector3I.RangeIterator(ref min, ref max); it.IsValid(); it.GetNext(out pos)) { newMesh.RegisterTriangle(tri, ref pos); } } m_mesh = newMesh; } }
// Get normal from lookup table or calc it void GetVoxelNormal(MyTemporaryVoxel temporaryVoxel, ref Vector3I coord, ref Vector3I voxelCoord, MyTemporaryVoxel centerVoxel) { if (temporaryVoxel.Normal_CalcCounter != m_temporaryVoxelsCounter) { Vector3I sampleMin = coord - 1; Vector3I sampleMax = coord + 1; var cache = m_cache; var clampMax = cache.Size3D - 1; Vector3I.Max(ref sampleMin, ref Vector3I.Zero, out sampleMin); Vector3I.Min(ref sampleMax, ref clampMax, out sampleMax); Vector3 normal = new Vector3( (cache.Content(sampleMin.X, coord.Y, coord.Z) - cache.Content(sampleMax.X, coord.Y, coord.Z)) / MyVoxelConstants.VOXEL_CONTENT_FULL_FLOAT, (cache.Content(coord.X, sampleMin.Y, coord.Z) - cache.Content(coord.X, sampleMax.Y, coord.Z)) / MyVoxelConstants.VOXEL_CONTENT_FULL_FLOAT, (cache.Content(coord.X, coord.Y, sampleMin.Z) - cache.Content(coord.X, coord.Y, sampleMax.Z)) / MyVoxelConstants.VOXEL_CONTENT_FULL_FLOAT); if (normal.LengthSquared() <= 0.000001f) { // If voxels surounding voxel for which we want to get normal vector are of the same value, their subtracting leads to zero vector and that can't be used. So following line is hack. temporaryVoxel.Normal = centerVoxel.Normal; } else { MyUtils.Normalize(ref normal, out temporaryVoxel.Normal); } temporaryVoxel.Normal_CalcCounter = m_temporaryVoxelsCounter; } }
/// <summary> /// Checks only immediate children (any deeper would take too long). /// </summary> private static bool ChildrenWereLoaded(LodLevel childLod, ref MyCellCoord thisLodCell) { if (childLod == null) { return(false); } Debug.Assert(thisLodCell.Lod == childLod.m_lodIndex + 1); var childLodCell = new MyCellCoord(); childLodCell.Lod = childLod.m_lodIndex; var shiftToChild = MyVoxelCoordSystems.RenderCellSizeShiftToMoreDetailed(thisLodCell.Lod); var start = thisLodCell.CoordInLod << shiftToChild; var end = start + ((1 << shiftToChild) >> 1); Vector3I.Max(ref childLod.m_lodSizeMinusOne, ref Vector3I.Zero, out childLod.m_lodSizeMinusOne); Vector3I.Min(ref end, ref childLod.m_lodSizeMinusOne, out end); childLodCell.CoordInLod = start; for (var it = new Vector3I.RangeIterator(ref start, ref end); it.IsValid(); it.GetNext(out childLodCell.CoordInLod)) { var key = childLodCell.PackId64(); CellData data; if (!childLod.m_storedCellData.TryGetValue(key, out data) || !data.WasLoaded) { return(false); } } return(true); }
void DoCuboid() { Vector3I min = Vector3I.Min(mark1, mark2); Vector3I max = Vector3I.Max(mark1, mark2); if (!game.World.IsValidPos(min) || !game.World.IsValidPos(max)) { return; } byte id = block; if (id == 0xFF) { id = (byte)game.Inventory.HeldBlock; } for (int y = min.Y; y <= max.Y; y++) { for (int z = min.Z; z <= max.Z; z++) { for (int x = min.X; x <= max.X; x++) { game.UpdateBlock(x, y, z, id); } } } }
public static void GetExistingCubes(MyCubeGrid grid, Vector3I min, Vector3I max, BoundingSphere localSphere, bool checkDestroyed, List <IMySlimBlock> resultSet) { resultSet.Clear(); Vector3I result1 = Vector3I.Floor((min - Vector3I.One) / 2f); Vector3I result2 = Vector3I.Ceiling((max - Vector3I.One) / 2f); var gridMin = grid.Min; var gridMax = grid.Max; Vector3I.Max(ref result1, ref gridMin, out result1); Vector3I.Min(ref result2, ref gridMax, out result2); Vector3I key; for (key.X = result1.X; key.X <= result2.X; ++key.X) { for (key.Y = result1.Y; key.Y <= result2.Y; ++key.Y) { for (key.Z = result1.Z; key.Z <= result2.Z; ++key.Z) { MyCube myCube; if (grid.TryGetCube(key, out myCube)) { var block = (IMySlimBlock)myCube.CubeBlock; if (checkDestroyed && block.IsDestroyed || !new BoundingBox(block.Min * grid.GridSize - grid.GridSizeHalf, block.Max * grid.GridSize + grid.GridSizeHalf).Intersects(localSphere)) { continue; } resultSet.Add(block); } } } } }
public static void GetExistingCubes(MyCubeGrid grid, Vector3I min, Vector3I max, List <IMySlimBlock> resultSet) { resultSet.Clear(); Vector3I result1 = Vector3I.Floor((min - Vector3I.One) / 2f); Vector3I result2 = Vector3I.Ceiling((max - Vector3I.One) / 2f); var gridMin = grid.Min; var gridMax = grid.Max; Vector3I.Max(ref result1, ref gridMin, out result1); Vector3I.Min(ref result2, ref gridMax, out result2); Vector3I key; for (key.X = result1.X; key.X <= result2.X; ++key.X) { for (key.Y = result1.Y; key.Y <= result2.Y; ++key.Y) { for (key.Z = result1.Z; key.Z <= result2.Z; ++key.Z) { MyCube myCube; if (grid.TryGetCube(key, out myCube)) { resultSet.Add(myCube.CubeBlock); } } } } }
private bool IsInInflatedBounds(IMyCubeGrid grid, Vector3I pos) { var min = grid.Min - Vector3I.One; var max = grid.Max + Vector3I.One; return(!(min != Vector3I.Min(pos, min)) && !(max != Vector3I.Max(pos, max))); }
public static BoundingBoxI TransformBoundingBox(BoundingBoxI box, ref MatrixI matrix) { Vector3I a, b; Vector3I.Transform(ref box.Min, ref matrix, out a); Vector3I.Transform(ref box.Max, ref matrix, out b); return(new BoundingBoxI(Vector3I.Min(a, b), Vector3I.Max(a, b))); }
private static bool IntersectsVoxelSurface(OrientedBoundingBoxD box) { var data = VoxelData; using (PoolManager.Get(out List <MyEntity> entities)) { MyGamePruningStructure.GetTopmostEntitiesInBox(box.GetAABB(), entities, MyEntityQueryType.Static); foreach (var ent in entities) { if (ent is MyVoxelBase voxel && !(ent is MyVoxelPhysics)) { var invWorld = voxel.PositionComp.WorldMatrixInvScaled; var storageBounds = BoundingBoxD.CreateInvalid(); var voxelOffset = (voxel.Size >> 1) + voxel.StorageMin; var storageObb = box; storageObb.Transform(invWorld); storageObb.HalfExtent /= voxel.VoxelSize; storageObb.Center = storageObb.Center / voxel.VoxelSize + voxelOffset; storageBounds.Include(storageObb.GetAABB()); var storageMin = Vector3I.Max(Vector3I.Floor(storageBounds.Min), voxel.StorageMin); var storageMax = Vector3I.Min(Vector3I.Ceiling(storageBounds.Max), voxel.StorageMax); var localBox = new BoundingBoxI(storageMin, storageMax); localBox.Inflate(1); var floatBox = new BoundingBox(localBox); if (voxel.IntersectStorage(ref floatBox) == ContainmentType.Disjoint) { continue; } data.Resize(storageMin, storageMax); voxel.Storage.ReadRange(data, MyStorageDataTypeFlags.Content, 0, storageMin, storageMax); foreach (var pt in new BoundingBoxI(Vector3I.Zero, storageMax - storageMin).EnumeratePoints()) { var voxelBox = new BoundingBoxD(storageMin + pt, storageMin + pt + 1); var containment = storageObb.Contains(ref voxelBox); if (containment == ContainmentType.Disjoint) { continue; } var tmpPt = pt; var index = data.ComputeLinear(ref tmpPt); var content = data.Content(index); if (containment == ContainmentType.Intersects && content >= 127) { return(true); } if (containment == ContainmentType.Contains && content > 0) { return(true); } } } } } return(false); }
public void Replace(IEnumerable <Vector3I> voxels) { this.Min = Vector3I.MaxValue; this.Max = Vector3I.MinValue; foreach (Vector3I vectori in voxels) { this.Min = Vector3I.Min(this.Min, vectori); this.Max = Vector3I.Max(this.Max, vectori); } }
public void Replace(IEnumerable <Vector3I> voxels) { Min = Vector3I.MaxValue; Max = Vector3I.MinValue; foreach (var v in voxels) { Min = Vector3I.Min(Min, v); Max = Vector3I.Max(Max, v); } }
private static bool HasBlocksInside(MyCubeGrid grid, ref MyOrientedBoundingBoxD obb) { Vector3I center = grid.WorldToGridInteger(obb.Center); double radius = obb.HalfExtent.Length(); radius *= grid.GridSizeR; Vector3I gridMin = grid.Min; Vector3I gridMax = grid.Max; double radiusSq = radius * radius; int radiusCeil = (int)Math.Ceiling(radius); BoundingSphereD cubeSphere = new BoundingSphereD(new Vector3D(), grid.GridSizeHalf * Math.Sqrt(3)); Vector3I max = Vector3I.Min(Vector3I.One * radiusCeil, gridMax - center); Vector3I min = Vector3I.Max(Vector3I.One * -radiusCeil, gridMin - center); int x, y, z; for (x = min.X; x <= max.X; ++x) { for (y = min.Y; y <= max.Y; ++y) { for (z = min.Z; z <= max.Z; ++z) { if (x * x + y * y + z * z >= radiusSq) { continue; } Vector3I offset = new Vector3I(x, y, z); Vector3I cubePos = center + offset; MyCube cube; if (!grid.TryGetCube(cubePos, out cube)) { continue; } IMySlimBlock slim = cube.CubeBlock; if (slim.IsDestroyed) { continue; } cubeSphere.Center = grid.GridIntegerToWorld(cubePos); if (obb.Contains(ref cubeSphere) != ContainmentType.Disjoint) { return(true); } } } } return(false); }
private unsafe void MergeSegments() { int num = 0; while (true) { int num2; while (true) { if (num >= this.m_segments.Count) { return; } num2 = num + 1; break; } while (true) { if (num2 >= this.m_segments.Count) { num++; break; } Segment segment = this.m_segments[num]; Segment segment2 = this.m_segments[num2]; int num3 = 0; if ((segment.Min.X == segment2.Min.X) && (segment.Max.X == segment2.Max.X)) { num3++; } if ((segment.Min.Y == segment2.Min.Y) && (segment.Max.Y == segment2.Max.Y)) { num3++; } if ((segment.Min.Z == segment2.Min.Z) && (segment.Max.Z == segment2.Max.Z)) { num3++; } if ((num3 == 2) && (((segment.Min.X == (segment2.Max.X + 1)) || (((segment.Max.X + 1) == segment2.Min.X) || ((segment.Min.Y == (segment2.Max.Y + 1)) || (((segment.Max.Y + 1) == segment2.Min.Y) || (segment.Min.Z == (segment2.Max.Z + 1)))))) || ((segment.Max.Z + 1) == segment2.Min.Z))) { Segment *segmentPtr1 = (Segment *)ref segment; segmentPtr1->Min = Vector3I.Min(segment.Min, segment2.Min); Segment *segmentPtr2 = (Segment *)ref segment; segmentPtr2->Max = Vector3I.Max(segment.Max, segment2.Max); this.m_segments[num] = segment; this.m_segments.RemoveAt(num2); continue; } num2++; } } }
internal static void Export(Entity entity, string schematic) { EntityCheck(entity); var target = PositionClone()[entity]; var cube = new VectorCubeI(target.Pos1.From3Dto3I(), target.Pos2.From3Dto3I()); var cube0 = Vector3I.Min(new Vector3I(cube.Start.X, cube.Start.Y, cube.Start.Z), new Vector3I(cube.End.X, cube.End.Y, cube.End.Z)); var cube1 = Vector3I.Max(new Vector3I(cube.Start.X, cube.Start.Y, cube.Start.Z), new Vector3I(cube.End.X, cube.End.Y, cube.End.Z)) - cube0 + Vector3I.One; FoxCore.SaveDirectory.FetchDirectory("Exports").ExportCube(cube1, cube0, schematic); }
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)); }
private bool IsInBounds(Vector3I pos) { if (GridMin() != Vector3I.Min(pos, GridMin())) { return(false); } if (GridMax() != Vector3I.Max(pos, GridMax())) { return(false); } return(true); }
private static DeformationTable CreateTable(Vector3I normal) { DeformationTable table = new DeformationTable { Normal = normal }; Vector3I vectori = new Vector3I(1, 1, 1); Vector3I vectori2 = Vector3I.Abs(normal); Vector3I vectori3 = (new Vector3I(1, 1, 1) - vectori2) * 2; int x = -vectori3.X; while (x <= vectori3.X) { int y = -vectori3.Y; while (true) { if (y > vectori3.Y) { x++; break; } int z = -vectori3.Z; while (true) { if (z > vectori3.Z) { y++; break; } Vector3I vectori4 = new Vector3I(x, y, z); float num4 = 1f; if (Math.Max(Math.Abs(z), Math.Max(Math.Abs(x), Math.Abs(y))) > 1f) { num4 = 0.3f; } float num5 = num4 * 0.25f; Vector3I key = (Vector3I)((vectori + new Vector3I(x, y, z)) + normal); table.OffsetTable.Add(key, Matrix.CreateFromDir((Vector3)(-normal * num5))); Vector3I item = key >> 1; Vector3I vectori7 = (key - Vector3I.One) >> 1; table.CubeOffsets.Add(item); table.CubeOffsets.Add(vectori7); table.MinOffset = Vector3I.Min(table.MinOffset, vectori4); table.MaxOffset = Vector3I.Max(table.MaxOffset, vectori4); z++; } } } return(table); }
public static VoxelModel GenerateTreeModel(int seed, TreeBluePrint blueprint, TreeLSystem treeSystem = null) { if (treeSystem == null) { treeSystem = new TreeLSystem(); } var blocks = treeSystem.Generate(seed, new Vector3I(), blueprint); var max = new Vector3I(int.MinValue); var min = new Vector3I(int.MaxValue); foreach (var blockWithPosition in blocks) { max = Vector3I.Max(max, blockWithPosition.WorldPosition); min = Vector3I.Min(min, blockWithPosition.WorldPosition); } var size = max - min + Vector3I.One; var model = new VoxelModel(); model.Name = "Tree Example"; model.ColorMapping = new ColorMapping(); model.ColorMapping.BlockColors = new Color4[64]; model.ColorMapping.BlockColors[0] = Color.Brown.ToColor4(); model.ColorMapping.BlockColors[1] = Color.Green.ToColor4(); var frame = new VoxelFrame(size); foreach (var blockWithPosition in blocks) { frame.BlockData.SetBlock(blockWithPosition.WorldPosition - min, blockWithPosition.BlockId == blueprint.TrunkBlock ? (byte)1 : (byte)2); } model.Frames.Add(frame); var part = new VoxelModelPart(); part.Name = "Main"; model.Parts.Add(part); var state = new VoxelModelState(model); state.Name = "Default"; state.PartsStates[0].Translation = new Vector3(min.X, 0, min.Z); model.States.Add(state); return(model); }
static MySlimBlock GetContactBlock(MyCubeGrid grid, Vector3D worldPosition, float graceDistance) { graceDistance = Math.Max(Math.Abs(graceDistance), grid.GridSize * 0.2f); graceDistance += 1f; MatrixD invWorld = grid.PositionComp.GetWorldMatrixNormalizedInv(); Vector3D localVelocity = Vector3D.TransformNormal(grid.Physics.LinearVelocity * Sandbox.Common.MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS, invWorld); Vector3D localPos; Vector3D.Transform(ref worldPosition, ref invWorld, out localPos); // MW:TODO optimize var min1 = Vector3I.Round((localPos - graceDistance - localVelocity) / grid.GridSize); var max1 = Vector3I.Round((localPos + graceDistance + localVelocity) / grid.GridSize); var min2 = Vector3I.Round((localPos + graceDistance - localVelocity) / grid.GridSize); var max2 = Vector3I.Round((localPos - graceDistance + localVelocity) / grid.GridSize); Vector3I min = Vector3I.Min(Vector3I.Min(Vector3I.Min(min1, max1), min2), max2); Vector3I max = Vector3I.Max(Vector3I.Max(Vector3I.Max(min1, max1), min2), max2); MySlimBlock resultBlock = null; float distSq = float.MaxValue; // TODO: optimize this, it should be possible using normal from contact Vector3I pos; for (pos.X = min.X; pos.X <= max.X; pos.X++) { for (pos.Y = min.Y; pos.Y <= max.Y; pos.Y++) { for (pos.Z = min.Z; pos.Z <= max.Z; pos.Z++) { var block = grid.GetCubeBlock(pos); if (block != null) { var testDistSq = (float)(pos * grid.GridSize - localPos).LengthSquared(); if (testDistSq < distSq) { distSq = testDistSq; resultBlock = block; } } } } } return(resultBlock); }
public bool GetBoundingBox(out Vector3I min, out Vector3I max) { MatrixI xi; min = new Vector3I(); max = new Vector3I(); if (!this.GetTransform(out xi)) { return(false); } Vector3I vectori = Vector3I.Transform(this.MultiBlockDefinition.Min, xi); Vector3I vectori2 = Vector3I.Transform(this.MultiBlockDefinition.Max, xi); min = Vector3I.Min(vectori, vectori2); max = Vector3I.Max(vectori, vectori2); return(true); }
public static bool AnyBlocksInAABB(this MyGridDataComponent g, BoundingBoxD box) { var e = g.Entity; if (e.PositionComp == null) { return(false); } if (box.Contains(e.PositionComp.WorldAABB) == ContainmentType.Contains) { return(g.BlockCount > 0); } var orientedBoundingBoxD = OrientedBoundingBoxD.Create(box, e.PositionComp.WorldMatrixNormalizedInv); var sizeR = 1f / g.Size; orientedBoundingBoxD.Center *= sizeR; orientedBoundingBoxD.HalfExtent *= sizeR; box = box.TransformFast(e.PositionComp.WorldMatrixNormalizedInv); var min = box.Min; var max = box.Max; var obbPt1 = new Vector3I((int)Math.Round(min.X * sizeR), (int)Math.Round(min.Y * sizeR), (int)Math.Round(min.Z * sizeR)); var obbPt2 = new Vector3I((int)Math.Round(max.X * sizeR), (int)Math.Round(max.Y * sizeR), (int)Math.Round(max.Z * sizeR)); var obbMin = Vector3I.Min(obbPt1, obbPt2); var obbMax = Vector3I.Max(obbPt1, obbPt2); var start = Vector3I.Max(obbMin, g.Min); var end = Vector3I.Min(obbMax, g.Max); if (start.X > end.X || start.Y > end.Y || start.Z > end.Z) { return(false); } var vector3IRangeIterator = new Vector3I_RangeIterator(ref start, ref end); var next = vector3IRangeIterator.Current; while (vector3IRangeIterator.IsValid()) { if (g.GetAnyBlock(next) != null) { return(true); } vector3IRangeIterator.GetNext(out next); } return(false); }
protected static bool TestBlockPlacementOnGrid(MySlimBlock block, ref MatrixI transform, ref MyGridPlacementSettings settings, MyCubeGrid hitGrid) { Vector3I positionMin; Vector3I.Transform(ref block.Min, ref transform, out positionMin); Vector3I positionMax; Vector3I.Transform(ref block.Max, ref transform, out positionMax); Vector3I min = Vector3I.Min(positionMin, positionMax); Vector3I max = Vector3I.Max(positionMin, positionMax); var forward = transform.GetDirection(block.Orientation.Forward); var up = transform.GetDirection(block.Orientation.Up); MyBlockOrientation blockOrientation = new MyBlockOrientation(forward, up); return(hitGrid.CanPlaceBlock(min, max, blockOrientation, block.BlockDefinition, ref settings)); }
private void ReadRangeAdviseCache(MyStorageData target, MyStorageDataTypeFlags dataToRead, ref Vector3I lodVoxelRangeMin, ref Vector3I lodVoxelRangeMax) { // Skip if too many cached cells if (m_pendingChunksToWrite.Count > WriteCacheCap) { ReadRange(target, dataToRead, 0, ref lodVoxelRangeMin, ref lodVoxelRangeMax); return; } if (CachedWrites) { var lodDiff = VoxelChunk.SizeBits; var chunkMin = lodVoxelRangeMin >> lodDiff; var chunkMax = lodVoxelRangeMax >> lodDiff; var pos = Vector3I.Zero; for (pos.Z = chunkMin.Z; pos.Z <= chunkMax.Z; ++pos.Z) { for (pos.Y = chunkMin.Y; pos.Y <= chunkMax.Y; ++pos.Y) { for (pos.X = chunkMin.X; pos.X <= chunkMax.X; ++pos.X) { var celPos = pos << lodDiff; var lodCkStart = pos << lodDiff; lodCkStart = Vector3I.Max(lodCkStart, lodVoxelRangeMin); var targetOffset = lodCkStart - lodVoxelRangeMin; var lodCkEnd = ((pos + 1) << lodDiff) - 1; lodCkEnd = Vector3I.Min(lodCkEnd, lodVoxelRangeMax); VoxelChunk chunk; GetChunk(ref pos, out chunk, dataToRead); lodCkStart -= celPos; lodCkEnd -= celPos; using (chunk.Lock.AcquireSharedUsing()) chunk.ReadLod(target, dataToRead, ref targetOffset, 0, ref lodCkStart, ref lodCkEnd); } } } } }
public static void GetBlocksInsideSphereFast(MyCubeGrid grid, ref BoundingSphereD sphere, bool checkDestroyed, ConcurrentCachingList <CubeAccel> blocks) { var radius = sphere.Radius; radius *= grid.GridSizeR; var center = grid.WorldToGridInteger(sphere.Center); var gridMin = grid.Min; var gridMax = grid.Max; double radiusSq = radius * radius; int radiusCeil = (int)Math.Ceiling(radius); int i, j, k; Vector3I max2 = Vector3I.Min(Vector3I.One * radiusCeil, gridMax - center); Vector3I min2 = Vector3I.Max(Vector3I.One * -radiusCeil, gridMin - center); for (i = min2.X; i <= max2.X; ++i) { for (j = min2.Y; j <= max2.Y; ++j) { for (k = min2.Z; k <= max2.Z; ++k) { if (i * i + j * j + k * k < radiusSq) { MyCube cube; var vector3I = center + new Vector3I(i, j, k); if (grid.TryGetCube(vector3I, out cube)) { var slim = (IMySlimBlock)cube.CubeBlock; if (slim.Position == vector3I) { if (checkDestroyed && slim.IsDestroyed) { continue; } blocks.Add(new CubeAccel { Block = slim, CubeExists = slim.FatBlock != null, Grid = (MyCubeGrid)slim.CubeGrid }); } } } } } } blocks.ApplyAdditions(); }