private void CreatePlanetMenu() { m_currentVoxel = null; MyGuiControlList list = new MyGuiControlList(size: new Vector2(SCREEN_SIZE.X, 1.0f)); Vector2 controlPadding = new Vector2(0.02f, 0.02f); // X: Left & Right, Y: Bottom & Top float textScale = 0.8f; float usableWidth = SCREEN_SIZE.X - HIDDEN_PART_RIGHT - controlPadding.X * 2; m_currentPosition = Vector2.Zero;/* -m_size.Value / 2.0f; * m_currentPosition += controlPadding;*/ m_scale = textScale; var label = AddLabel(MyTexts.GetString(MySpaceTexts.ScreenDebugSpawnMenu_SelectAsteroidType), Vector4.One, m_scale); Controls.Remove(label); list.Controls.Add(label); var combo = AddCombo(); combo.AddItem(1, MySpaceTexts.ScreenDebugSpawnMenu_PredefinedAsteroids); combo.AddItem(2, MySpaceTexts.ScreenDebugSpawnMenu_ProceduralAsteroids); combo.AddItem(3, MySpaceTexts.ScreenDebugSpawnMenu_Planets); combo.SelectItemByKey(m_asteroid_showPlanet ? 3 : m_asteroid_showPredefinedOrProcedural ? 1 : 2); combo.ItemSelected += () => { m_asteroid_showPredefinedOrProcedural = combo.GetSelectedKey() == 1; m_asteroid_showPlanet = combo.GetSelectedKey() == 3; RecreateControls(false); }; Controls.Remove(combo); list.Controls.Add(combo); CreatePlanetControls(list, usableWidth); AddSeparator(list); var button = CreateDebugButton(usableWidth, MySpaceTexts.ScreenDebugSpawnMenu_SpawnAsteroid, OnSpawnProceduralAsteroid); Controls.Remove(button); list.Controls.Add(button); Controls.Add(list); }
public static bool RayCastVoxels(ref Vector3D start, ref Vector3D end, out MyVoxelBase hitVoxel, out Vector3D hitPosition, bool checkPlanet = DefaultCheckPlanet) { #if PROFILE Profiler.StartProfileBlock(); try { #endif CapsuleD capsule; capsule.P0 = start; capsule.P1 = end; capsule.Radius = 0f; return(CapsuleDExtensions.IntersectsVoxel(ref capsule, out hitVoxel, out hitPosition, checkPlanet)); #if PROFILE } finally { Profiler.EndProfileBlock(); } #endif }
/// <summary> /// Ray cast all the voxels in the world to check for intersection. /// </summary> /// <param name="line">The line to check</param> ///// <param name="shortTest">Shortens the line by 5 m, needed to interact with an entity that may be on the surface of the voxel.</param> /// <returns>True iff any voxel intersects the line</returns> public static bool RayCastVoxels(LineD line, out MyVoxelBase hitVoxel, out Vector3D hitPosition, bool checkPlanet = DefaultCheckPlanet) { //const double ShortenBy = 5d; #if PROFILE Profiler.StartProfileBlock(); try { #endif CapsuleD capsule; capsule.P0 = line.From; capsule.P1 = line.To; capsule.Radius = 0f; return(CapsuleDExtensions.IntersectsVoxel(ref capsule, out hitVoxel, out hitPosition, checkPlanet)); #if PROFILE } finally { Profiler.EndProfileBlock(); } #endif }
/// <summary> /// Resets aabbb outside area of the given voxel map to default. Area inside aabb (inclusive) stays the same. /// mk:TODO Remove MyVoxelBase and bounding box reference and just pass in integer range. Move computation of range to entities. /// </summary> public override void ResetOutsideBorders(MyVoxelBase voxelMap, BoundingBoxD worldAabb) { m_tmpResetLeaves.Clear(); m_tmpResetLeavesBoundingBox = worldAabb; Vector3I minVoxel, maxVoxel; MyVoxelCoordSystems.WorldPositionToVoxelCoord(voxelMap.PositionLeftBottomCorner, ref worldAabb.Min, out minVoxel); MyVoxelCoordSystems.WorldPositionToVoxelCoord(voxelMap.PositionLeftBottomCorner, ref worldAabb.Max, out maxVoxel); bool unused; bool changedContent = ResetOutsideBorders(m_dataProvider, MyStorageDataTypeEnum.Content, m_treeHeight, m_contentNodes, m_contentLeaves, Vector3I.Zero, minVoxel, maxVoxel, out unused, outResetLeaves: m_tmpResetLeaves); bool changedMaterial = ResetOutsideBorders(m_dataProvider, MyStorageDataTypeEnum.Material, m_treeHeight, m_materialNodes, m_materialLeaves, Vector3I.Zero, minVoxel, maxVoxel, out unused); if (changedContent || changedMaterial) { OnRangeChanged(Vector3I.Zero, Size - 1, MyStorageDataTypeFlags.ContentAndMaterial); } }
public static Vector3D VoxelHitCheck(MyVoxelBase voxel, MyPlanet closestPlanet, Vector3D lineStartPoint, Vector3D lineEndPoint, LineD lineCheck) { Vector3D?voxelHit = Vector3D.Zero; if (voxel != null) { if (voxel.RootVoxel != voxel) { return(Vector3D.Zero); } if (voxel == closestPlanet) { var closestPos = closestPlanet.GetClosestSurfacePointGlobal(ref lineStartPoint); return(closestPos); } } return(Vector3D.Zero); }
/// <summary> /// Find a sphere free from voxel. /// </summary> /// <param name="voxel">The voxel to avoid.</param> /// <param name="startPosition">The position to start the search.</param> /// <param name="minRadius">The minimum radius around freePosition.</param> /// <param name="freePosition">A position that is minRadius from voxel</param> public static void FindFreeSpace(this MyVoxelBase voxel, Vector3D startPosition, double minRadius, out Vector3D freePosition) { MyPlanet planet = voxel as MyPlanet; if (planet != null) { Vector3D centre = planet.GetCentre(); Vector3D direction; Vector3D.Subtract(ref startPosition, ref centre, out direction); direction.Normalize(); FindFreeSpace(voxel, startPosition, direction, minRadius, out freePosition); return; } BoundingSphereD testSphere; testSphere.Radius = minRadius; for (double testDist = minRadius; ; testDist += minRadius) { foreach (Vector3I neighbour in Globals.Neighbours) { Vector3D disp = Vector3D.Multiply(neighbour, testDist); Vector3D.Add(ref startPosition, ref disp, out testSphere.Center); if (!ContainsOrIntersects(voxel, ref testSphere, true)) { CapsuleD capsule; capsule.P0 = testSphere.Center; Vector3D disp1 = Vector3D.Multiply(neighbour, testDist * 0.5d); Vector3D.Add(ref startPosition, ref disp1, out capsule.P1); capsule.Radius = (float)minRadius; if (!CapsuleDExtensions.Intersects(ref capsule, voxel, out freePosition)) { freePosition = capsule.P1; } return; } } } }
internal static bool CheckPointsOnLine(MyVoxelBase voxel, LineD testLine, int distBetweenPoints) { var planet = voxel as MyPlanet; var map = voxel as MyVoxelMap; var hit = new VoxelHit(); var checkPoints = (int)(testLine.Length / distBetweenPoints); for (int i = 0; i < checkPoints; i++) { var testPos = testLine.From + (testLine.Direction * (distBetweenPoints * i)); //Log.Line($"i: {i} - lookAhead:{(distBetweenPoints * i)}"); if (planet != null) { var from = testPos; var localPosition = (Vector3)(from - planet.PositionLeftBottomCorner); var v = localPosition / 1f; Vector3I voxelCoord; Vector3I.Floor(ref v, out voxelCoord); planet.Storage.ExecuteOperationFast(ref hit, MyStorageDataTypeFlags.Content, ref voxelCoord, ref voxelCoord, notifyRangeChanged: false); if (hit.HasHit) { return(true); } } else if (map != null) { var from = testPos; var localPosition = (Vector3)(from - map.PositionLeftBottomCorner); var v = localPosition / 1f; Vector3I voxelCoord; Vector3I.Floor(ref v, out voxelCoord); map.Storage.ExecuteOperationFast(ref hit, MyStorageDataTypeFlags.Content, ref voxelCoord, ref voxelCoord, notifyRangeChanged: false); if (hit.HasHit) { return(true); } } } return(false); }
private unsafe void DisableOtherItemsInVMap(MyVoxelBase voxelMap) { MyOrientedBoundingBoxD obb = MyOrientedBoundingBoxD.Create((BoundingBoxD)voxelMap.PositionComp.LocalAABB, voxelMap.PositionComp.WorldMatrix); var center = obb.Center; var box = voxelMap.PositionComp.WorldAABB; m_entities.Clear(); MyGamePruningStructure.GetAllEntitiesInBox(ref box, m_entities, MyEntityQueryType.Static); for (int eIndex = 0; eIndex < m_entities.Count; ++eIndex) { var sector = m_entities[eIndex] as MyEnvironmentSector; if (sector == null || sector.DataView == null) { continue; } obb.Center = center - sector.SectorCenter; for (int sectorInd = 0; sectorInd < sector.DataView.LogicalSectors.Count; sectorInd++) { var logicalSector = sector.DataView.LogicalSectors[sectorInd]; var logicalItems = logicalSector.Items; var cnt = logicalItems.Count; fixed(ItemInfo *items = logicalItems.GetInternalArray()) for (int i = 0; i < cnt; ++i) { var point = items[i].Position + sector.SectorCenter; if (items[i].DefinitionIndex >= 0 && obb.Contains(ref items[i].Position) && voxelMap.CountPointsInside(&point, 1) > 0 && !IsVoxelItem(sector, items[i].DefinitionIndex)) { logicalSector.EnableItem(i, false); } } } } }
public static bool IntersectsVoxel(ref CapsuleD capsule, out MyVoxelBase hitVoxel, out Vector3D hitPosition, bool checkPlanet, double capsuleLength = -1d) { Profiler.StartProfileBlock(); if (capsuleLength < 0) { Vector3D.Distance(ref capsule.P0, ref capsule.P1, out capsuleLength); } double halfLength = capsuleLength * 0.5d; Vector3D temp; Vector3D.Add(ref capsule.P0, ref capsule.P1, out temp); Vector3D middle; Vector3D.Multiply(ref temp, 0.5d, out middle); double radius = halfLength + capsule.Radius; BoundingSphereD worldSphere = new BoundingSphereD() { Center = middle, Radius = radius }; List <MyVoxelBase> voxels = ResourcePool <List <MyVoxelBase> > .Get(); MyGamePruningStructure.GetAllVoxelMapsInSphere(ref worldSphere, voxels); foreach (MyVoxelBase voxel in voxels) { if ((voxel is MyVoxelMap || voxel is MyPlanet && checkPlanet) && Intersects(ref capsule, voxel, out hitPosition, capsuleLength)) { hitVoxel = voxel; voxels.Clear(); ResourcePool.Return(voxels); Profiler.EndProfileBlock(); return(true); } } voxels.Clear(); ResourcePool.Return(voxels); hitVoxel = null; hitPosition = Vector3.Invalid; Profiler.EndProfileBlock(); return(false); }
protected virtual bool TryDrillVoxels(MyVoxelBase voxels, Vector3D hitPosition, bool collectOre, bool onlyCheck, bool applyDamagedMaterial) { const float DISCARDING_MULTIPLIER = 3.0f; if (voxels.GetOrePriority() == MyVoxelConstants.PRIORITY_IGNORE_EXTRACTION) { return(false); } bool somethingDrilled = false; var bsphere = new MyShapeSphere() { Center = m_cutOut.Sphere.Center, Radius = (float)m_cutOut.Sphere.Radius }; if (!collectOre) { bsphere.Radius *= DISCARDING_MULTIPLIER; } float voxelsCountInPercent; MyVoxelMaterialDefinition material; MyVoxelGenerator.CutOutShapeWithProperties(voxels, bsphere, out voxelsCountInPercent, out material, m_drilledMaterialBuffer, Sync.IsServer, onlyCheck, applyDamagedMaterial); foreach (var entry in m_drilledMaterialBuffer) { somethingDrilled = (!collectOre || TryHarvestOreMaterial(entry.Key, hitPosition, entry.Value, onlyCheck)) || somethingDrilled; if (somethingDrilled && !onlyCheck) { MyDebris.Static.CreateDirectedDebris(hitPosition, MyUtils.GetRandomVector3Normalized(), 0.1f, 1, 0, MathHelper.Pi, 5, 1, 0.15f, entry.Key); } } m_drilledMaterialBuffer.Clear(); return(somethingDrilled); }
public static void DisableFarmingItemsIn(this MyVoxelBase voxel, BoundingBoxD worldAabb) { if (voxel.Hierarchy == null) { return; } using (PoolManager.Get(out List <MyEntity> working)) { voxel.Hierarchy.QueryBounds(in worldAabb, working); foreach (var entity in working) { var sector = entity as MyEnvironmentSector; if (sector == null) { continue; } var tmp = worldAabb; sector.DisableItemsInAabb(ref tmp); } } }
private MyVoxelMaterialDefinition GetVoxelMaterial(MyVoxelBase voxelBase, Vector3D hitPos) { if (voxelBase.Storage == null || voxelBase.PositionComp == null) { return(null); } Vector3D localPosition; var wm = voxelBase.PositionComp.WorldMatrixInvScaled; Vector3D.TransformNoProjection(ref hitPos, ref wm, out localPosition); var voxelPosition = voxelBase.StorageMin + new Vector3I(localPosition) + (voxelBase.Size >> 1); StorageData.Resize(Vector3I.One); voxelBase.Storage.ReadRange(StorageData, MyStorageDataTypeFlags.Material, 0, voxelPosition, voxelPosition); byte materialIndex = StorageData.Material(0); return(MyVoxelMaterialDefinition.Get(materialIndex)); }
public static void DisableFarmingItemsIn(this MyVoxelBase voxel, BoundingBoxD box) { if (voxel.Hierarchy == null) { return; } _working.Clear(); voxel.Hierarchy.QueryBounds(in box, _working); foreach (var entity in _working) { var sector = entity as MyEnvironmentSector; if (sector == null) { continue; } var tmp = box; sector.DisableItemsInAabb(ref tmp); } _working.Clear(); }
private void MoveToTarget() { if (m_navSet.DistanceLessThan(1f)) { Log.DebugLog("Reached position: " + m_target, Logger.severity.WARNING); if (m_stage == Stage.Backout) { m_target.SetWorld(m_target.WorldPosition() + m_navBlock.WorldMatrix.Backward * 100d); } else { Vector3D targetWorld = m_target.WorldPosition(); MyVoxelBase voxel = TargetVoxel; m_target.SetWorld(targetWorld + Vector3D.Normalize(targetWorld - voxel.GetCentre()) * voxel.PositionComp.LocalVolume.Radius); } } else if (IsStuck) { if (m_stage == Stage.Backout) { Log.DebugLog("Stuck", Logger.severity.DEBUG); m_stage = Stage.FromCentre; } else { Log.DebugLog("Stuck", Logger.severity.DEBUG); m_navSet.OnTaskComplete_NavWay(); } } else if (!IsNearVoxel(2d)) { Log.DebugLog("Outside of voxel", Logger.severity.INFO); m_mover.MoveAndRotateStop(); m_navSet.OnTaskComplete_NavMove(); } else { m_pathfinder.MoveTo(destinations: m_target); } }
/// <summary> /// Tests for path intersection with voxel. /// </summary> /// <returns>True iff path is clear; voxel does not intersect path.</returns> private bool TestVoxel(MyVoxelBase voxel, Capsule path, out Vector3?pointOfObstruction) { if (m_ignoreAsteroid) { m_logger.debugLog("Ignoring asteroid: " + voxel.getBestName()); pointOfObstruction = null; return(true); } Vector3[] intersection = new Vector3[2]; if (!path.IntersectsAABB(voxel, out intersection[0])) { m_logger.debugLog("path does not intersect AABB. " + voxel.getBestName(), Logger.severity.TRACE); pointOfObstruction = null; return(true); } if (!path.get_Reverse().IntersectsAABB(voxel, out intersection[1])) { m_logger.debugLog("Reversed path does not intersect AABB, perhaps it moved? " + voxel.getBestName(), Logger.severity.WARNING); pointOfObstruction = null; return(true); } Capsule testSection = new Capsule(intersection[0], intersection[1], path.Radius); IMyVoxelMap asteroid = voxel as IMyVoxelMap; if (asteroid != null) { if (testSection.Intersects(asteroid, out pointOfObstruction)) { return(false); } } // planet test is done by PlanetChecker m_logger.debugLog("Does not intersect path: " + voxel.getBestName(), Logger.severity.TRACE); pointOfObstruction = null; return(true); }
public static bool ContainsOrIntersects(this MyVoxelBase voxel, ref BoundingSphereD worldSphere, bool checkContains = false) { if (!voxel.PositionComp.WorldAABB.Intersects(ref worldSphere)) { return(false); } Vector3D leftBottom = voxel.PositionLeftBottomCorner; BoundingSphereD localSphere; Vector3D.Subtract(ref worldSphere.Center, ref leftBottom, out localSphere.Center); localSphere.Radius = worldSphere.Radius; BoundingBox localBox = BoundingBox.CreateFromSphere(localSphere); if (voxel.Storage.Intersect(ref localBox) == ContainmentType.Disjoint) { return(false); } return(voxel.Storage.Geometry.Intersects(ref localSphere) || checkContains && HasContentAt(voxel, ref localSphere.Center)); }
internal MyVoxelPhysicsBody(MyVoxelBase voxelMap, float phantomExtend, float predictionSize = 3.0f, bool lazyPhysics = false) : base(voxelMap, RigidBodyFlag.RBF_STATIC) { ProfilerShort.Begin("MyVoxelPhysicsBody("); m_predictionSize = predictionSize; m_phantomExtend = phantomExtend; m_voxelMap = voxelMap; Vector3I storageSize = m_voxelMap.Size; Vector3I numCels = storageSize >> MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_VOXELS_BITS; m_cellsOffset = m_voxelMap.StorageMin >> MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_VOXELS_BITS; if (!MyFakes.ENABLE_LAZY_VOXEL_PHYSICS || !lazyPhysics || !ENABLE_AABB_PHANTOM) { CreateRigidBodies(); } ProfilerShort.End(); MaterialType = MyMaterialType.ROCK; }
internal static bool PointInsideVoxel(MyVoxelBase voxel, MyStorageData tmpStorage, Vector3D pos) { var voxelMatrix = voxel.PositionComp.WorldMatrixInvScaled; var vecMax = new Vector3I(int.MaxValue); var vecMin = new Vector3I(int.MinValue); var point = pos; Vector3D result; Vector3D.Transform(ref point, ref voxelMatrix, out result); var r = result + (Vector3D)(voxel.Size / 2); var v1 = Vector3D.Floor(r); Vector3D.Fract(ref r, out r); var v2 = v1 + voxel.StorageMin; var v3 = v2 + 1; if (v2 != vecMax && v3 != vecMin) { tmpStorage.Resize(v2, v3); voxel.Storage.ReadRange(tmpStorage, MyStorageDataTypeFlags.Content, 0, v2, v3); } var num1 = tmpStorage.Content(0, 0, 0); var num2 = tmpStorage.Content(1, 0, 0); var num3 = tmpStorage.Content(0, 1, 0); var num4 = tmpStorage.Content(1, 1, 0); var num5 = tmpStorage.Content(0, 0, 1); var num6 = tmpStorage.Content(1, 0, 1); var num7 = tmpStorage.Content(0, 1, 1); var num8 = tmpStorage.Content(1, 1, 1); var num9 = num1 + (num2 - num1) * r.X; var num10 = num3 + (num4 - num3) * r.X; var num11 = num5 + (num6 - num5) * r.X; var num12 = num7 + (num8 - num7) * r.X; var num13 = num9 + (num10 - num9) * r.Y; var num14 = num11 + (num12 - num11) * r.Y; return(num13 + (num14 - num13) * r.Z >= sbyte.MaxValue); }
public MyVoxelNavigationMesh(MyVoxelBase voxelMap, MyNavmeshCoordinator coordinator, Func <long> timestampFunction) : base(coordinator.Links, 0x10, timestampFunction) { this.LimitAddingWeight = GetWeight(25f); this.m_voxelMap = voxelMap; m_staticVoxelMap = this.m_voxelMap; this.m_processedCells = new MyVector3ISet(); this.m_cellsOnWayCoords = new HashSet <ulong>(); this.m_cellsOnWay = new List <Vector3I>(); this.m_primitivesOnPath = new List <MyHighLevelPrimitive>(0x80); this.m_toAdd = new MyBinaryHeap <float, CellToAddHeapItem>(0x80); this.m_heapItemList = new List <CellToAddHeapItem>(); this.m_markedForAddition = new MyVector3ISet(); this.m_cellsToChange = new LinkedList <Vector3I>(); this.m_cellsToChangeSet = new MyVector3ISet(); this.m_connectionHelper = new MyVoxelConnectionHelper(); this.m_navmeshCoordinator = coordinator; this.m_higherLevel = new MyHighLevelGroup(this, coordinator.HighLevelLinks, timestampFunction); this.m_higherLevelHelper = new MyVoxelHighLevelHelper(this); this.m_debugCellEdges = new Dictionary <ulong, List <DebugDrawEdge> >(); voxelMap.Storage.RangeChanged += new Action <Vector3I, Vector3I, MyStorageDataTypeFlags>(this.OnStorageChanged); this.m_maxCellCoord = ((Vector3I)(this.m_voxelMap.Size / 8)) - Vector3I.One; }
public override void ContactPointCallback(ref MyGridContactInfo value) { //return; var prop = value.Event.ContactProperties; prop.Friction = Friction; prop.Restitution = 0.5f; value.EnableParticles = false; value.RubberDeformation = true; if (value.CollidingEntity is MyVoxelBase) { MyVoxelBase voxel = value.CollidingEntity as MyVoxelBase; Vector3D contactPosition = value.ContactPosition; MyParticleEffectsIDEnum particleEffect = voxel.GetMaterialAt(ref contactPosition).ParticleEffect; if (Render != null && particleEffect != MyParticleEffectsIDEnum.None) { Render.TrySpawnParticle(value.ContactPosition, particleEffect); } } }
internal MyVoxelPhysicsBody(MyVoxelBase voxelMap, float phantomExtend, float predictionSize = 3.0f) : base(voxelMap, RigidBodyFlag.RBF_STATIC) { m_predictionSize = predictionSize; m_phantomExtend = phantomExtend; m_voxelMap = voxelMap; Vector3I storageSize = m_voxelMap.Size; Vector3I numCels = storageSize >> MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_VOXELS_BITS; m_cellsOffset = m_voxelMap.StorageMin >> MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_VOXELS_BITS; HkUniformGridShape shape = new HkUniformGridShape( new HkUniformGridShapeArgs() { CellsCount = numCels, CellSize = MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_METRES, CellOffset = MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF, CellExpand = MyVoxelConstants.VOXEL_SIZE_IN_METRES, }); shape.SetShapeRequestHandler(RequestShapeBlocking); CreateFromCollisionObject(shape, -m_voxelMap.SizeInMetresHalf, m_voxelMap.WorldMatrix, collisionFilter: MyPhysics.VoxelCollisionLayer); shape.Base.RemoveReference(); if (ENABLE_AABB_PHANTOM) { m_aabbPhantom = new Havok.HkpAabbPhantom(new BoundingBox(Vector3.Zero, m_voxelMap.SizeInMetres), 0); m_aabbPhantom.CollidableAdded = AabbPhantom_CollidableAdded; m_aabbPhantom.CollidableRemoved = AabbPhantom_CollidableRemoved; } if (MyFakes.ENABLE_PHYSICS_HIGH_FRICTION) { Friction = 0.65f; } MaterialType = Sandbox.Common.MyMaterialType.ROCK; }
public void UpdatePlacement() { this.m_lastUpdate = MySession.Static.GameplayFrameCounter; this.m_hitInfo = null; this.m_closestGrid = null; this.m_closestVoxelMap = null; LineD ed = new LineD(this.RayStart, this.RayStart + (this.RayDirection * this.IntersectionDistance)); MyPhysics.CastRay(ed.From, ed.To, this.m_tmpHitList, 0x18); if (MySession.Static.ControlledEntity != null) { this.m_tmpHitList.RemoveAll(hitInfo => ReferenceEquals(hitInfo.HkHitInfo.GetHitEntity(), MySession.Static.ControlledEntity.Entity)); } if (this.m_tmpHitList.Count != 0) { Sandbox.Engine.Physics.MyPhysics.HitInfo info = this.m_tmpHitList[0]; if (info.HkHitInfo.GetHitEntity() != null) { this.m_closestGrid = info.HkHitInfo.GetHitEntity().GetTopMostParent(null) as MyCubeGrid; } if (this.m_closestGrid != null) { this.m_hitInfo = new Sandbox.Engine.Physics.MyPhysics.HitInfo?(info); if (!this.ClosestGrid.Editable) { this.m_closestGrid = null; } } else { this.m_closestVoxelMap = info.HkHitInfo.GetHitEntity() as MyVoxelBase; if (this.m_closestVoxelMap != null) { this.m_hitInfo = new Sandbox.Engine.Physics.MyPhysics.HitInfo?(info); } } } }
protected void SetOutsideTarget(Vector3D direction) { PseudoBlock navBlock = m_navBlock; MyVoxelBase voxel = (MyVoxelBase)m_target.Entity; CapsuleD capsule; Vector3D offset; Vector3D.Multiply(ref direction, voxel.PositionComp.LocalVolume.Radius * 2d, out offset); capsule.P1 = navBlock.WorldPosition; Vector3D.Add(ref capsule.P1, ref offset, out capsule.P0); capsule.Radius = m_grid.LocalVolume.Radius * 4f; Vector3D hitPos; if (!CapsuleDExtensions.Intersects(ref capsule, voxel, out hitPos)) { Log.DebugLog("capsule: " + capsule.String() + ", does not intersect voxel", Logger.severity.DEBUG); hitPos = capsule.P0; } //Log.DebugLog((tunnel ? "Tunnel target: " : "Backout target: ") + hitPos, Logger.severity.DEBUG); m_target.SetWorld(ref hitPos); }
internal MyVoxelPhysicsBody(MyVoxelBase voxelMap, float phantomExtend, float predictionSize = 3f, bool lazyPhysics = false) : base(voxelMap, RigidBodyFlag.RBF_STATIC) { this.RunningBatchTask = new MyPrecalcJobPhysicsBatch[2]; this.m_nearbyEntities = new HashSet <IMyEntity>(); this.m_nearbyEntitiesLock = new FastResourceLock(); this.m_workTracker = new MyWorkTracker <MyCellCoord, MyPrecalcJobPhysicsPrefetch>(MyCellCoord.Comparer); this.m_cellsOffset = new Vector3I(0, 0, 0); this.m_staticForCluster = true; this.m_predictionSize = 3f; this.m_queuedRange = new BoundingBoxI(-1, -1); this.InvalidCells = new HashSet <Vector3I>[] { new HashSet <Vector3I>(), new HashSet <Vector3I>() }; this.m_predictionSize = predictionSize; this.m_phantomExtend = phantomExtend; this.m_voxelMap = voxelMap; Vector3I vectori1 = this.m_voxelMap.Size >> 3; this.m_cellsOffset = this.m_voxelMap.StorageMin >> 3; if (!MyFakes.ENABLE_LAZY_VOXEL_PHYSICS || !lazyPhysics) { this.CreateRigidBodies(); } base.MaterialType = VRage.Game.MyMaterialType.ROCK; }
public static unsafe bool CutOutSphereFast(MyVoxelBase voxelMap, ref Vector3D center, float radius, out Vector3I cacheMin, out Vector3I cacheMax, bool notifyChanged) { Vector3I vectori; Vector3I vectori2; MatrixD worldMatrixInvScaled = voxelMap.PositionComp.WorldMatrixInvScaled; MatrixD *xdPtr1 = (MatrixD *)ref worldMatrixInvScaled; xdPtr1.Translation += voxelMap.SizeInMetresHalf; BoundingBoxD shapeAabb = BoundingBoxD.CreateFromSphere(new BoundingSphereD(center, (double)radius)).TransformFast(worldMatrixInvScaled); ComputeShapeBounds(voxelMap, ref shapeAabb, Vector3.Zero, voxelMap.Storage.Size, out vectori, out vectori2); cacheMin = vectori - 1; cacheMax = (Vector3I)(vectori2 + 1); voxelMap.Storage.ClampVoxelCoord(ref cacheMin, 1); voxelMap.Storage.ClampVoxelCoord(ref cacheMax, 1); CutOutSphere voxelOperator = new CutOutSphere { RadSq = radius * radius, Center = Vector3D.Transform(center, worldMatrixInvScaled) - (cacheMin - voxelMap.StorageMin) }; voxelMap.Storage.ExecuteOperationFast <CutOutSphere>(ref voxelOperator, MyStorageDataTypeFlags.Content, ref cacheMin, ref cacheMax, notifyChanged); return(voxelOperator.Changed); }
public static void MyVoxelGenerator_ComputeShapeBounds(this IMyVoxelBase VoxelMap, ref BoundingBoxD shapeAabb, out Vector3I voxelMin, out Vector3I voxelMax) { if (VoxelMap == null) { throw new ArgumentNullException(nameof(VoxelMap)); } if (VoxelMap.Storage == null) { throw new ArgumentException("Voxel.Storage is null"); } MyVoxelBase voxelMap = VoxelMap as MyVoxelBase; Vector3I storageSize = voxelMap.Storage.Size; MyVoxelCoordSystems.WorldPositionToVoxelCoord(voxelMap.PositionLeftBottomCorner, ref shapeAabb.Min, out voxelMin); MyVoxelCoordSystems.WorldPositionToVoxelCoord(voxelMap.PositionLeftBottomCorner, ref shapeAabb.Max, out voxelMax); voxelMin += voxelMap.StorageMin; voxelMax += voxelMap.StorageMin; voxelMax += 1; storageSize -= 1; Vector3I.Clamp(ref voxelMin, ref Vector3I.Zero, ref storageSize, out voxelMin); Vector3I.Clamp(ref voxelMax, ref Vector3I.Zero, ref storageSize, out voxelMax); }
public static bool HasVoxelAt(this IMyVoxelBase Voxel, Vector3D Point) { if (Voxel == null) { throw new ArgumentNullException(nameof(Voxel)); } if (Voxel.Storage == null) { throw new ArgumentException("Voxel.Storage is null"); } MyVoxelBase _Voxel = Voxel as MyVoxelBase; VoxelHit hit = new VoxelHit(); //The following magic is taken from Sandbox.Game.Entities.VoxelBaseExtensions Vector3 value; MyVoxelCoordSystems.WorldPositionToLocalPosition(Point, _Voxel.PositionComp.WorldMatrix, _Voxel.PositionComp.WorldMatrixInvScaled, _Voxel.SizeInMetresHalf, out value); Vector3I voxelCoord = new Vector3I(value / 1f) + _Voxel.StorageMin; _Voxel.Storage.ExecuteOperationFast(ref hit, MyStorageDataTypeFlags.Content, ref voxelCoord, ref voxelCoord, false); return(hit.HasHit); }
public override void ContactPointCallback(ref MyGridContactInfo value) { //return; var prop = value.Event.ContactProperties; prop.Friction = Friction; prop.Restitution = 0.5f; value.EnableParticles = false; value.RubberDeformation = true; if (value.CollidingEntity is MyVoxelBase && MyFakes.ENABLE_DRIVING_PARTICLES) { MyVoxelBase voxel = value.CollidingEntity as MyVoxelBase; Vector3D contactPosition = value.ContactPosition; MyStringHash material = MyStringHash.GetOrCompute(voxel.GetMaterialAt(ref contactPosition).MaterialTypeName); MyTuple <int, ContactPropertyParticleProperties> particle = MyMaterialPropertiesHelper.Static.GetCollisionEffectAndProperties(MyMaterialPropertiesHelper.CollisionType.Start, m_wheelStringHash, material); if (Render != null && particle.Item1 > 0) { Render.TrySpawnParticle(value.ContactPosition, particle); } } }
public static void RevertShape(MyVoxelBase voxelMap, MyShape shape) { using (voxelMap.Pin()) { if (!voxelMap.MarkedForClose) { Vector3I vectori; Vector3I maxCorner; Vector3I minCorner; GetVoxelShapeDimensions(voxelMap, shape, out minCorner, out maxCorner, out vectori); minCorner = Vector3I.Max(Vector3I.One, minCorner); maxCorner = Vector3I.Max(minCorner, maxCorner - Vector3I.One); voxelMap.Storage.DeleteRange(MyStorageDataTypeFlags.All, minCorner, maxCorner, false); BoundingBoxD cutOutBox = shape.GetWorldBoundaries(); MySandboxGame.Static.Invoke(delegate { if (voxelMap.Storage != null) { voxelMap.Storage.NotifyChanged(minCorner, maxCorner, MyStorageDataTypeFlags.All); NotifyVoxelChanged(MyVoxelBase.OperationType.Revert, voxelMap, ref cutOutBox); } }, "RevertShape notify"); } } }
public override void ContactPointCallback(ref MyGridContactInfo value) { //return; var prop = value.Event.ContactProperties; prop.Friction = Friction; prop.Restitution = 0.5f; value.EnableParticles = false; value.RubberDeformation = true; string particle = null; if (value.CollidingEntity is MyVoxelBase && MyFakes.ENABLE_DRIVING_PARTICLES) { MyVoxelBase voxel = value.CollidingEntity as MyVoxelBase; Vector3D contactPosition = value.ContactPosition; var vmat = voxel.GetMaterialAt(ref contactPosition); if (vmat == null) { return; } MyStringHash material = MyStringHash.GetOrCompute(vmat.MaterialTypeName); particle = MyMaterialPropertiesHelper.Static.GetCollisionEffect(MyMaterialPropertiesHelper.CollisionType.Start, m_wheelStringHash, material); } else if (value.CollidingEntity is MyCubeGrid && MyFakes.ENABLE_DRIVING_PARTICLES) { MyCubeGrid grid = value.CollidingEntity as MyCubeGrid; MyStringHash material = grid.Physics.GetMaterialAt(value.ContactPosition); particle = MyMaterialPropertiesHelper.Static.GetCollisionEffect(MyMaterialPropertiesHelper.CollisionType.Start, m_wheelStringHash, material); } if (Render != null && particle != null) { Render.TrySpawnParticle((Vector3)value.ContactPosition, value.Event.ContactPoint.Normal, particle); } }
public void UpdatePlacement() { m_lastUpdate = MySession.Static.GameplayFrameCounter; m_hitInfo = null; m_closestGrid = null; m_closestVoxelMap = null; LineD line = new LineD(RayStart, RayStart + RayDirection * IntersectionDistance); MyPhysics.CastRay(line.From, line.To, m_tmpHitList, MyPhysics.CollisionLayers.ObjectDetectionCollisionLayer); // Remove character hits. m_tmpHitList.RemoveAll(delegate(MyPhysics.HitInfo hitInfo) { return (hitInfo.HkHitInfo.GetHitEntity() == MySession.Static.ControlledEntity.Entity); }); if (m_tmpHitList.Count == 0) return; var hit = m_tmpHitList[0]; m_closestGrid = hit.HkHitInfo.GetHitEntity() as MyCubeGrid; if (m_closestGrid != null) { //always assign otherwise the block will be completely inside/behind the grid m_hitInfo = hit; if (!ClosestGrid.Editable) m_closestGrid = null; return; } //if (MyFakes.ENABLE_BLOCK_PLACEMENT_ON_VOXEL) // TODO: check this MyFake to remove or what? //{ m_closestVoxelMap = hit.HkHitInfo.GetHitEntity() as MyVoxelBase; if (m_closestVoxelMap != null) m_hitInfo = hit; //} }
public void CreateExplosionDebris(ref BoundingSphereD explosionSphere, float voxelsCountInPercent, MyVoxelMaterialDefinition voxelMaterial, MyVoxelBase voxelMap) { MyDebug.AssertDebug((voxelsCountInPercent >= 0.0f) && (voxelsCountInPercent <= 1.0f)); MyDebug.AssertDebug(explosionSphere.Radius > 0); ProfilerShort.Begin("CreateExplosionDebris"); ProfilerShort.Begin("Matrices"); // This matrix will rotate all newly created debrises, so they won't apper as alligned with coordinate system MatrixD randomRotationMatrix = MatrixD.CreateRotationX(MyUtils.GetRandomRadian()) * MatrixD.CreateRotationY(MyUtils.GetRandomRadian()); float highScale = MathHelper.Clamp((float)explosionSphere.Radius * m_debrisScaleUpper, 0, m_debrisScaleClamp); float lowScale = highScale * (m_debrisScaleLower / m_debrisScaleUpper); int objectsToGenerate = (int)(m_voxelDebrisOffsets.Count * voxelsCountInPercent); ProfilerShort.End(); ProfilerShort.Begin("m_positionOffsets"); const float SPHERE_FIT_CUBE_SCALE = 1 / 1.73f; // Resize sphere to fit inside cube int debrisCount = m_voxelDebrisOffsets.Count; //float debrisScale = Math.Max(explosionSphere.Radius / debrisCount, 0.2f); float debrisScale = Math.Max((float)explosionSphere.Radius, 0.2f); for (int i = 0; i < debrisCount; i++) { MyDebrisVoxel newObj = CreateVoxelDebris(); if (newObj == null) { break; // no point in continuing } Vector3D position = m_voxelDebrisOffsets[i] * (float)explosionSphere.Radius * SPHERE_FIT_CUBE_SCALE; Vector3D.Transform(ref position, ref randomRotationMatrix, out position); position += explosionSphere.Center; var initialVelocity = MyUtils.GetRandomVector3Normalized(); if (initialVelocity == Vector3.Zero) continue; initialVelocity *= MyUtils.GetRandomFloat(MyDebrisConstants.EXPLOSION_DEBRIS_INITIAL_SPEED_MIN, MyDebrisConstants.EXPLOSION_DEBRIS_INITIAL_SPEED_MAX); (newObj.Debris as MyDebrisVoxel.MyDebrisVoxelLogic).Start(position, initialVelocity, debrisScale, voxelMaterial); } ProfilerShort.End(); ProfilerShort.End(); }