private bool AllSiblingsWereLoaded(ref MyCellCoord thisLodCell) { MyCellCoord sibling; sibling.Lod = thisLodCell.Lod; var start = new Vector3I( // get rid of lowest bit to make this min child of parent thisLodCell.CoordInLod.X & (-2), thisLodCell.CoordInLod.Y & (-2), thisLodCell.CoordInLod.Z & (-2)); var end = start + 1; Vector3I.Min(ref end, ref m_lodSizeMinusOne, out end); for (sibling.CoordInLod.Z = start.Z; sibling.CoordInLod.Z <= end.Z; ++sibling.CoordInLod.Z) { for (sibling.CoordInLod.Y = start.Y; sibling.CoordInLod.Y <= end.Y; ++sibling.CoordInLod.Y) { for (sibling.CoordInLod.X = start.X; sibling.CoordInLod.X <= end.X; ++sibling.CoordInLod.X) { var key = sibling.PackId64(); MyClipmap_CellData data; if (!m_storedCellData.TryGetValue(key, out data)) { return(false); } if (!data.WasLoaded) { return(false); } } } } return(true); }
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); } } }
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); } } } }
/// <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(); MyClipmap_CellData data; if (!childLod.m_storedCellData.TryGetValue(key, out data) || !data.WasLoaded) { return(false); } } return(true); }
private static MyObjectBuilder_CubeBlock ConvertDynamicGridBlockToStatic(ref MatrixD worldMatrix, MyObjectBuilder_CubeBlock origBlock) { MyDefinitionId defId = new MyDefinitionId(origBlock.TypeId, origBlock.SubtypeName); MyCubeBlockDefinition blockDefinition; MyDefinitionManager.Static.TryGetCubeBlockDefinition(defId, out blockDefinition); if (blockDefinition == null) { return(null); } var blockBuilder = Sandbox.Common.ObjectBuilders.Serializer.MyObjectBuilderSerializer.CreateNewObject(defId) as MyObjectBuilder_CubeBlock; blockBuilder.EntityId = origBlock.EntityId; // Orientation quaternion is not setup in origblock MyBlockOrientation orientation = origBlock.BlockOrientation; Quaternion rotationQuat; orientation.GetQuaternion(out rotationQuat); Matrix origRotationMatrix = Matrix.CreateFromQuaternion(rotationQuat); Matrix rotationMatrix = origRotationMatrix * worldMatrix; blockBuilder.Orientation = Quaternion.CreateFromRotationMatrix(rotationMatrix); Vector3I origSizeRotated = Vector3I.Abs(Vector3I.Round(Vector3.TransformNormal((Vector3)blockDefinition.Size, origRotationMatrix))); Vector3I origMin = origBlock.Min; Vector3I origMax = origBlock.Min + origSizeRotated - Vector3I.One; Vector3I minXForm = Vector3I.Round(Vector3.TransformNormal((Vector3)origMin, worldMatrix)); Vector3I maxXForm = Vector3I.Round(Vector3.TransformNormal((Vector3)origMax, worldMatrix)); blockBuilder.Min = Vector3I.Min(minXForm, maxXForm); return(blockBuilder); }
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); }
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); } } } } }
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); } } } } }
/// <summary> /// Converts the given block with the given matrix for static grid. /// </summary> private static void ConvertRotatedGridBlockToStatic(ref MatrixI transform, MyObjectBuilder_CubeBlock origBlock) { MyDefinitionId defId = new MyDefinitionId(origBlock.TypeId, origBlock.SubtypeName); MyCubeBlockDefinition blockDefinition; MyDefinitionManager.Static.TryGetCubeBlockDefinition(defId, out blockDefinition); if (blockDefinition == null) { return; } // Orientation quaternion is not setup in origblock MyBlockOrientation origOrientation = origBlock.BlockOrientation; Vector3I origMin = origBlock.Min; Vector3I origMax; MySlimBlock.ComputeMax(blockDefinition, origOrientation, ref origMin, out origMax); Vector3I tMin; Vector3I tMax; Vector3I.Transform(ref origMin, ref transform, out tMin); Vector3I.Transform(ref origMax, ref transform, out tMax); Base6Directions.Direction forward = transform.GetDirection(origOrientation.Forward); Base6Directions.Direction up = transform.GetDirection(origOrientation.Up); // Write data MyBlockOrientation newBlockOrientation = new MyBlockOrientation(forward, up); Quaternion rotationQuat; newBlockOrientation.GetQuaternion(out rotationQuat); origBlock.Orientation = rotationQuat; origBlock.Min = Vector3I.Min(tMin, tMax); }
/// <summary> /// Transforms given compound block with matrix for static grid. Rotation of block is not changed. /// </summary> private static void ConvertRotatedGridCompoundBlockToStatic(ref MatrixI transform, MyObjectBuilder_CompoundCubeBlock origBlock) { MyDefinitionId defId = new MyDefinitionId(origBlock.TypeId, origBlock.SubtypeName); MyCubeBlockDefinition blockDefinition; MyDefinitionManager.Static.TryGetCubeBlockDefinition(defId, out blockDefinition); if (blockDefinition == null) { return; } // Orientation quaternion is not setup in origblock MyBlockOrientation origOrientation = origBlock.BlockOrientation; Vector3I origMin = origBlock.Min; Vector3I origMax; MySlimBlock.ComputeMax(blockDefinition, origOrientation, ref origMin, out origMax); Vector3I tMin; Vector3I tMax; Vector3I.Transform(ref origMin, ref transform, out tMin); Vector3I.Transform(ref origMax, ref transform, out tMax); // Write data origBlock.Min = Vector3I.Min(tMin, tMax); }
/// <summary> /// Checks only immediate children (any deeper would take too long). /// </summary> private static bool ChildrenWereLoaded(LodLevel childLod, ref MyCellCoord thisLodCell) { if (childLod == null || !childLod.Visible) return false; Debug.Assert(thisLodCell.Lod == childLod.m_lodIndex + 1); var childLodCell = new MyCellCoord(); childLodCell.Lod = childLod.m_lodIndex; var start = thisLodCell.CoordInLod << 1; var end = start + 1; Vector3I.Min(ref end, ref childLod.m_lodSizeMinusOne, out end); for (childLodCell.CoordInLod.Z = start.Z; childLodCell.CoordInLod.Z <= end.Z; ++childLodCell.CoordInLod.Z) for (childLodCell.CoordInLod.Y = start.Y; childLodCell.CoordInLod.Y <= end.Y; ++childLodCell.CoordInLod.Y) for (childLodCell.CoordInLod.X = start.X; childLodCell.CoordInLod.X <= end.X; ++childLodCell.CoordInLod.X) { var key = childLodCell.PackId64(); CellData data; if (!childLod.m_storedCellData.TryGetValue(key, out data)) { return false; } if (!data.WasLoaded) { return false; } } return true; }
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 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); } } } } }
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 unsafe void AddSegmentedParts(float gridSize, MyVoxelSegmentation segmenter, MyVoxelSegmentationType segmentationType) { int num = (int)Math.Floor((double)(40f / gridSize)); Vector3 vector = new Vector3(gridSize * 0.5f); if (segmenter != null) { int mergeIterations = (segmentationType == MyVoxelSegmentationType.Optimized) ? 1 : 0; segmenter.ClearInput(); foreach (Vector3I vectori3 in this.m_tmpCubes) { segmenter.AddInput(vectori3); } foreach (MyVoxelSegmentation.Segment segment in segmenter.FindSegments(segmentationType, mergeIterations)) { Vector3I vectori; vectori.X = segment.Min.X; while (vectori.X <= segment.Max.X) { vectori.Y = segment.Min.Y; while (true) { if (vectori.Y > segment.Max.Y) { int *numPtr3 = (int *)ref vectori.X; numPtr3[0] += num; break; } vectori.Z = segment.Min.Z; while (true) { if (vectori.Z > segment.Max.Z) { int *numPtr2 = (int *)ref vectori.Y; numPtr2[0] += num; break; } Vector3I maxPos = Vector3I.Min((Vector3I)((vectori + num) - 1), segment.Max); Vector3 min = ((Vector3)(vectori * gridSize)) - vector; Vector3 max = (maxPos * gridSize) + vector; this.AddBox(vectori, maxPos, ref min, ref max); int *numPtr1 = (int *)ref vectori.Z; numPtr1[0] += num; } } } } } else { foreach (Vector3I vectori4 in this.m_tmpCubes) { Vector3 min = ((Vector3)(vectori4 * gridSize)) - vector; Vector3 max = (vectori4 * gridSize) + vector; this.AddBox(vectori4, vectori4, ref min, ref max); } } }
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 ReadRange(MyStorageData target, MyStorageDataTypeFlags dataToRead, int lodIndex, ref Vector3I lodVoxelRangeMin, ref Vector3I lodVoxelRangeMax, ref MyVoxelRequestFlags requestFlags) { ProfilerShort.Begin(GetType().Name + ".ReadRange"); try { const int SUBRANGE_SIZE_SHIFT = 3; const int SUBRANGE_SIZE = 1 << SUBRANGE_SIZE_SHIFT; var threshold = new Vector3I(SUBRANGE_SIZE); var rangeSize = lodVoxelRangeMax - lodVoxelRangeMin + 1; if ((dataToRead & MyStorageDataTypeFlags.Content) != 0) { target.ClearContent(0); } if ((rangeSize.X <= threshold.X && rangeSize.Y <= threshold.Y && rangeSize.Z <= threshold.Z) || !MyFakes.ENABLE_SPLIT_VOXEL_READ_QUERIES) { using (m_lock.AcquireSharedUsing()) { ReadRangeInternal(target, ref Vector3I.Zero, dataToRead, lodIndex, ref lodVoxelRangeMin, ref lodVoxelRangeMax, ref requestFlags); } } else { // These optimizations don't work when splitting the range. requestFlags &= ~(MyVoxelRequestFlags.OneMaterial | MyVoxelRequestFlags.ContentChecked); MyVoxelRequestFlags flags = requestFlags; // splitting to smaller ranges to make sure the lock is not held for too long, preventing write on update thread // subranges could be aligned to multiple of their size for possibly better performance var steps = (rangeSize - 1) >> SUBRANGE_SIZE_SHIFT; for (var it = new Vector3I.RangeIterator(ref Vector3I.Zero, ref steps); it.IsValid(); it.MoveNext()) { flags = requestFlags; var offset = it.Current << SUBRANGE_SIZE_SHIFT; var min = lodVoxelRangeMin + offset; var max = min + SUBRANGE_SIZE - 1; Vector3I.Min(ref max, ref lodVoxelRangeMax, out max); Debug.Assert(min.IsInsideInclusive(ref lodVoxelRangeMin, ref lodVoxelRangeMax)); Debug.Assert(max.IsInsideInclusive(ref lodVoxelRangeMin, ref lodVoxelRangeMax)); using (m_lock.AcquireSharedUsing()) { ReadRangeInternal(target, ref offset, dataToRead, lodIndex, ref min, ref max, ref flags); } } // If the storage is consistent this should be fine. requestFlags = flags; } } finally { ProfilerShort.End(); } }
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); } }
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); } }
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++; } } }
public void ReadRange(MyStorageDataCache target, MyStorageDataTypeFlags dataToRead, int lodIndex, ref Vector3I lodVoxelRangeMin, ref Vector3I lodVoxelRangeMax) { ProfilerShort.Begin(GetType().Name + ".ReadRange"); try { const int SUBRANGE_SIZE_SHIFT = 3; const int SUBRANGE_SIZE = 1 << SUBRANGE_SIZE_SHIFT; var threshold = new Vector3I(SUBRANGE_SIZE); var rangeSize = lodVoxelRangeMax - lodVoxelRangeMin + 1; if ((dataToRead & MyStorageDataTypeFlags.Content) != 0) { target.ClearContent(0); } if ((dataToRead & MyStorageDataTypeFlags.Material) != 0) { target.ClearMaterials(m_defaultMaterial); } if (rangeSize.X <= threshold.X && rangeSize.Y <= threshold.Y && rangeSize.Z <= threshold.Z) { using (m_lock.AcquireSharedUsing()) { ReadRangeInternal(target, ref Vector3I.Zero, dataToRead, lodIndex, ref lodVoxelRangeMin, ref lodVoxelRangeMax); } } else { // splitting to smaller ranges to make sure the lock is not held for too long, preventing write on update thread // subranges could be aligned to multiple of their size for possibly better performance var steps = (rangeSize - 1) >> SUBRANGE_SIZE_SHIFT; for (var it = new Vector3I.RangeIterator(ref Vector3I.Zero, ref steps); it.IsValid(); it.MoveNext()) { var offset = it.Current << SUBRANGE_SIZE_SHIFT; var min = lodVoxelRangeMin + offset; var max = min + SUBRANGE_SIZE - 1; Vector3I.Min(ref max, ref lodVoxelRangeMax, out max); Debug.Assert(min.IsInsideInclusive(ref lodVoxelRangeMin, ref lodVoxelRangeMax)); Debug.Assert(max.IsInsideInclusive(ref lodVoxelRangeMin, ref lodVoxelRangeMax)); using (m_lock.AcquireSharedUsing()) { ReadRangeInternal(target, ref offset, dataToRead, lodIndex, ref min, ref max); } } } } finally { ProfilerShort.End(); } }
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); }
public static void ApplyTransformation(MyObjectBuilder_CubeBlock output, MatrixI transform) { var cMin = (Vector3I)output.Min; Vector3I cMax; ComputeBlockMax(output, out cMax); output.BlockOrientation.Forward = transform.GetDirection(output.BlockOrientation.Forward); output.BlockOrientation.Up = transform.GetDirection(output.BlockOrientation.Up); Vector3I.Transform(ref cMin, ref transform, out cMin); Vector3I.Transform(ref cMax, ref transform, out cMax); output.Min = Vector3I.Min(cMin, cMax); }
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); }
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)); }