public void DoWork(WorkData workData = null) { try { // LOD above is 5 we decrease it by 2 so our LOD now is 3 Min <<= 2; Max <<= 2; MyStorageData cache = Cache; cache.Resize(new Vector3I(8)); for (int x = Min.X; x <= Max.X; x++) { for (int y = Min.Y; y <= Max.Y; y++) { for (int z = Min.Z; z <= Max.Z; z++) { ProcessCell(cache, VoxelMap.Storage, new Vector3I(x, y, z), 0); } } } Callback(); } catch (Exception e) { Logging.Instance.WriteLine($"{e}"); Callback(); } }
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); } } } } }
private bool FindMaterial(IMyStorage storage, byte[] findMaterial) { if (findMaterial.Length == 0) { return(false); } var oldCache = new MyStorageData(); oldCache.Resize(storage.Size); storage.ReadRange(oldCache, MyStorageDataTypeFlags.ContentAndMaterial, 2, Vector3I.Zero, storage.Size - 1); //MyAPIGateway.Utilities.ShowMessage("check", string.Format("SizeLinear {0} {1}.", oldCache.SizeLinear, oldCache.StepLinear)); Vector3I p; for (p.Z = 0; p.Z < storage.Size.Z; ++p.Z) { for (p.Y = 0; p.Y < storage.Size.Y; ++p.Y) { for (p.X = 0; p.X < storage.Size.X; ++p.X) { var content = oldCache.Content(ref p); var material = oldCache.Material(ref p); if (content > 0 && findMaterial.Contains(material)) { return(true); } } } } return(false); }
public static MyStorageData GetVoxelCacheInSphere(this IMyVoxelBase Voxel, BoundingSphereD Sphere, out Vector3I refCorner, out Vector3I refMaxCorner) { if (Voxel == null) { throw new ArgumentNullException(nameof(Voxel)); } if (Voxel.Storage == null) { throw new ArgumentException("Voxel.Storage is null"); } BoundingBoxD SphereBound = VoxelHelpers.GetWorldBoundariesForSphere(Sphere); Vector3I minCorner, maxCorner; Voxel.MyVoxelGenerator_ComputeShapeBounds(ref SphereBound, out minCorner, out maxCorner); Vector3I minCorner1 = minCorner - 1; Vector3I maxCorner1 = maxCorner + 1; Voxel.Storage_ClampVoxelCoord(ref minCorner1, 1); Voxel.Storage_ClampVoxelCoord(ref maxCorner1, 1); MyStorageData cache = new MyStorageData(MyStorageDataTypeFlags.ContentAndMaterial); cache.Resize(minCorner1, maxCorner1); MyVoxelRequestFlags myVoxelRequestFlags = MyVoxelRequestFlags.AdviseCache | MyVoxelRequestFlags.ConsiderContent; Voxel.Storage.ReadRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, 0, minCorner1, maxCorner1, ref myVoxelRequestFlags); refCorner = minCorner1; refMaxCorner = maxCorner1; return(cache); }
public static MyVoxelMaterialDefinition GetMaterialAt(this VRage.Game.Voxels.IMyStorage self, ref Vector3D localCoords) { Vector3I lodVoxelRangeMin = Vector3D.Floor(localCoords / 1.0); MyStorageData target = new MyStorageData(MyStorageDataTypeFlags.All); target.Resize(Vector3I.One); self.ReadRange(target, MyStorageDataTypeFlags.Material, 0, lodVoxelRangeMin, lodVoxelRangeMin); return(MyDefinitionManager.Static.GetVoxelMaterialDefinition(target.Material(0))); }
public static MyVoxelMaterialDefinition GetMaterialAt(this VRage.Game.Voxels.IMyStorage self, ref Vector3I voxelCoords) { MyStorageData target = new MyStorageData(MyStorageDataTypeFlags.All); target.Resize(Vector3I.One); self.ReadRange(target, MyStorageDataTypeFlags.All, 0, voxelCoords, voxelCoords); byte materialIndex = target.Material(0); return((materialIndex != 0xff) ? MyDefinitionManager.Static.GetVoxelMaterialDefinition(materialIndex) : null); }
void ShrinkVMap() { Vector3I min, max; m_selectedVoxel.GetFilledStorageBounds(out min, out max); MyVoxelMapStorageDefinition def = null; if (m_selectedVoxel.AsteroidName != null) { MyDefinitionManager.Static.TryGetVoxelMapStorageDefinition(m_selectedVoxel.AsteroidName, out def); } var origSize = m_selectedVoxel.Size; var tightSize = max - min + 1; var storage = new MyOctreeStorage(null, tightSize); var offset = (storage.Size - tightSize) / 2 + 1; MyStorageData data = new MyStorageData(); data.Resize(tightSize); m_selectedVoxel.Storage.ReadRange(data, MyStorageDataTypeFlags.ContentAndMaterial, 0, min, max); min = offset; max = offset + tightSize - 1; storage.WriteRange(data, MyStorageDataTypeFlags.ContentAndMaterial, ref min, ref max); var newMap = MyWorldGenerator.AddVoxelMap(m_selectedVoxel.StorageName, storage, m_selectedVoxel.WorldMatrix); m_selectedVoxel.Close(); newMap.Save = true; if (def == null) { ShowAlert("Voxel map {0} does not have a definition, the shrunk voxel map will be saved with the world instead.", m_selectedVoxel.StorageName); } else { byte[] cVmapData; newMap.Storage.Save(out cVmapData); using (var ostream = MyFileSystem.OpenWrite(Path.Combine(MyFileSystem.ContentPath, def.StorageFile), FileMode.Open)) { ostream.Write(cVmapData, 0, cVmapData.Length); } var notification = new MyHudNotification(MyStringId.GetOrCompute("Voxel prefab {0} updated succesfuly (size changed from {1} to {2})."), 4000); notification.SetTextFormatArguments(def.Id.SubtypeName, origSize, storage.Size); MyHud.Notifications.Add(notification); } }
public float GetVoxelContentInBoundingBox_Obsolete(BoundingBoxD worldAabb, out float cellCount) { MyPrecalcComponent.AssertUpdateThread(); cellCount = 0; float result = 0; Vector3I minCorner, maxCorner; MyVoxelCoordSystems.WorldPositionToVoxelCoord(PositionLeftBottomCorner, ref worldAabb.Min, out minCorner); MyVoxelCoordSystems.WorldPositionToVoxelCoord(PositionLeftBottomCorner, ref worldAabb.Max, out maxCorner); minCorner += StorageMin; maxCorner += StorageMin; Storage.ClampVoxelCoord(ref minCorner); Storage.ClampVoxelCoord(ref maxCorner); m_tempStorage.Resize(minCorner, maxCorner); Storage.ReadRange(m_tempStorage, MyStorageDataTypeFlags.Content, 0, ref minCorner, ref maxCorner); BoundingBoxD voxelBox; Vector3I coord, cache; for (coord.Z = minCorner.Z, cache.Z = 0; coord.Z <= maxCorner.Z; coord.Z++, cache.Z++) { for (coord.Y = minCorner.Y, cache.Y = 0; coord.Y <= maxCorner.Y; coord.Y++, cache.Y++) { for (coord.X = minCorner.X, cache.X = 0; coord.X <= maxCorner.X; coord.X++, cache.X++) { MyVoxelCoordSystems.VoxelCoordToWorldAABB(PositionLeftBottomCorner - StorageMin * MyVoxelConstants.VOXEL_SIZE_IN_METRES, ref coord, out voxelBox); if (worldAabb.Intersects(voxelBox)) { float content = m_tempStorage.Content(ref cache) / MyVoxelConstants.VOXEL_CONTENT_FULL_FLOAT; float containPercent = (float)(worldAabb.Intersect(voxelBox).Volume / MyVoxelConstants.VOXEL_VOLUME_IN_METERS); result += content * containPercent; cellCount += containPercent; } } } } return(result); }
unsafe void IWork.DoWork(WorkData workData) { try { if (this.m_result == null) { this.m_result = new List <MyEntityOreDeposit>(); this.m_emptyCells = new List <Vector3I>(); } MyStorageData cache = Cache; cache.Resize(new Vector3I(8)); IMyStorage storage = this.VoxelMap.Storage; if (storage != null) { using (StoragePin pin = storage.Pin()) { if (pin.Valid) { Vector3I vectori; vectori.Z = this.Min.Z; while (vectori.Z <= this.Max.Z) { vectori.Y = this.Min.Y; while (true) { if (vectori.Y > this.Max.Y) { int *numPtr3 = (int *)ref vectori.Z; numPtr3[0]++; break; } vectori.X = this.Min.X; while (true) { if (vectori.X > this.Max.X) { int *numPtr2 = (int *)ref vectori.Y; numPtr2[0]++; break; } this.ProcessCell(cache, storage, vectori, this.DetectorId); int *numPtr1 = (int *)ref vectori.X; numPtr1[0]++; } } } } } } } finally { } }
private static bool HasContentAt(this MyVoxelBase voxel, ref Vector3D localPosition) { Vector3I voxelCoord; MyVoxelCoordSystems.LocalPositionToVoxelCoord(ref localPosition, out voxelCoord); MyStorageData cache = new MyStorageData(); cache.Resize(Vector3I.One); voxel.Storage.ReadRange(cache, MyStorageDataTypeFlags.Content, 0, ref voxelCoord, ref voxelCoord); return(cache.Content(0) > MyVoxelConstants.VOXEL_ISO_LEVEL); }
public static void GetMaterialContent(this VRage.Game.Voxels.IMyStorage self, ref Vector3I voxelCoords, out byte material, out byte content) { MyStorageData myStorageData = new MyStorageData(MyStorageDataTypeFlags.ContentAndMaterial); myStorageData.Resize(Vector3I.One); myStorageData.ClearMaterials(0); self.ReadRange(myStorageData, MyStorageDataTypeFlags.ContentAndMaterial, 0, voxelCoords, voxelCoords); material = myStorageData.Material(0); content = myStorageData.Content(0); }
private static void VoxelReading() { var camera = MySector.MainCamera; if (camera == null) { return; } var offset = 0; // MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF; var targetPosition = camera.Position + (Vector3D)camera.ForwardVector * 4.5f - offset; MyVoxelBase targetVoxelMap = null; foreach (var voxelMap in MySession.Static.VoxelMaps.Instances) { if (voxelMap.PositionComp.WorldAABB.Contains(targetPosition) == ContainmentType.Contains) { targetVoxelMap = voxelMap; break; } } if (targetVoxelMap == null) { return; } var targetMin = targetPosition - Vector3.One * MyVoxelConstants.VOXEL_SIZE_IN_METRES; var targetMax = targetPosition + Vector3.One * MyVoxelConstants.VOXEL_SIZE_IN_METRES; Vector3I minVoxel, maxVoxel; MyVoxelCoordSystems.WorldPositionToVoxelCoord(targetVoxelMap.PositionLeftBottomCorner, ref targetMin, out minVoxel); MyVoxelCoordSystems.WorldPositionToVoxelCoord(targetVoxelMap.PositionLeftBottomCorner, ref targetMax, out maxVoxel); MyVoxelCoordSystems.VoxelCoordToWorldPosition(targetVoxelMap.PositionLeftBottomCorner, ref minVoxel, out targetMin); MyVoxelCoordSystems.VoxelCoordToWorldPosition(targetVoxelMap.PositionLeftBottomCorner, ref maxVoxel, out targetMax); { BoundingBoxD bbox = BoundingBoxD.CreateInvalid(); bbox.Include(targetMin); bbox.Include(targetMax); VRageRender.MyRenderProxy.DebugDrawAABB(bbox, Vector3.One, 1f, 1f, true); } if (MyInput.Static.IsNewLeftMousePressed()) { var cache = new MyStorageData(); cache.Resize(minVoxel, maxVoxel); targetVoxelMap.Storage.ReadRange(cache, MyStorageDataTypeFlags.Content, 0, ref minVoxel, ref maxVoxel); targetVoxelMap.Storage.WriteRange(cache, MyStorageDataTypeFlags.Content, ref minVoxel, ref maxVoxel); Debug.Assert(true); } }
/// <summary> /// called multiple times for ships, to be kept up to date. /// </summary> public override void UpdateAfterSimulation10() { if (CommandAsteroidEditClear.ActiveVoxelDeleter) { var worldMatrix = MyAPIGateway.Session.Player.Controller.ControlledEntity.Entity.WorldMatrix; var position = worldMatrix.Translation + worldMatrix.Forward * 1.6f + worldMatrix.Up * 1.35f + worldMatrix.Right * 0.1f; var currentAsteroidList = new List <IMyVoxelBase>(); var bb = new BoundingBoxD(position - 0.2f, position + 0.2f); MyAPIGateway.Session.VoxelMaps.GetInstances(currentAsteroidList, v => v.IsBoxIntersectingBoundingBoxOfThisVoxelMap(ref bb)); if (currentAsteroidList.Count > 0) { _isInRange = true; var storage = currentAsteroidList[0].Storage; var point = new Vector3I(position - currentAsteroidList[0].PositionLeftBottomCorner); var cache = new MyStorageData(); var min = (point / 64) * 64; var max = min + 63; var size = max - min; cache.Resize(size); storage.ReadRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, (int)VRageRender.MyLodTypeEnum.LOD0, min, max); Vector3I p = point - min; var content = cache.Content(ref p); if (content > 0) { content = 0x00; cache.Content(ref p, content); storage.WriteRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, min, max); } //storage = null; } else { _isInRange = false; } } if (CommandAsteroidEditSet.ActiveVoxelSetter) { var worldMatrix = MyAPIGateway.Session.Player.Controller.ControlledEntity.Entity.WorldMatrix; CommandAsteroidEditSet.ActiveVoxelSetterPosition = worldMatrix.Translation + worldMatrix.Forward * 1.6f + worldMatrix.Up * 1.35f + worldMatrix.Right * 0.1f; } else { CommandAsteroidEditSet.ActiveVoxelSetterPosition = null; } }
/// <summary> /// called multiple times for ships, to be kept up to date. /// </summary> public override void UpdateAfterSimulation10() { if (CommandAsteroidEditClear.ActiveVoxelDeleter) { var worldMatrix = MyAPIGateway.Session.Player.Controller.ControlledEntity.Entity.WorldMatrix; var position = worldMatrix.Translation + worldMatrix.Forward * 1.6f + worldMatrix.Up * 1.35f + worldMatrix.Right * 0.1f; var currentAsteroidList = new List<IMyVoxelBase>(); var bb = new BoundingBoxD(position - 0.2f, position + 0.2f); MyAPIGateway.Session.VoxelMaps.GetInstances(currentAsteroidList, v => v.IsBoxIntersectingBoundingBoxOfThisVoxelMap(ref bb)); if (currentAsteroidList.Count > 0) { _isInRange = true; var storage = currentAsteroidList[0].Storage; var point = new Vector3I(position - currentAsteroidList[0].PositionLeftBottomCorner); var cache = new MyStorageData(); var min = (point / 64) * 64; var max = min + 63; var size = max - min; cache.Resize(size); storage.ReadRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, (int)VRageRender.MyLodTypeEnum.LOD0, min, max); Vector3I p = point - min; var content = cache.Content(ref p); if (content > 0) { content = 0x00; cache.Content(ref p, content); storage.WriteRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, min, max); } //storage = null; } else { _isInRange = false; } } if (CommandAsteroidEditSet.ActiveVoxelSetter) { var worldMatrix = MyAPIGateway.Session.Player.Controller.ControlledEntity.Entity.WorldMatrix; CommandAsteroidEditSet.ActiveVoxelSetterPosition = worldMatrix.Translation + worldMatrix.Forward * 1.6f + worldMatrix.Up * 1.35f + worldMatrix.Right * 0.1f; } else { CommandAsteroidEditSet.ActiveVoxelSetterPosition = null; } }
public static MyVoxelMaterialDefinition GetMaterialAt_R(this IMyStorage self, ref Vector3I voxelCoords) { MyVoxelMaterialDefinition def; var cache = new MyStorageData(); cache.Resize(Vector3I.One); cache.ClearMaterials(0); self.ReadRange(cache, MyStorageDataTypeFlags.Material, 0, voxelCoords, voxelCoords); def = MyDefinitionManager.Static.GetVoxelMaterialDefinition(cache.Material(0)); return(def); }
private bool ReplaceAsteroidMaterial(ulong steamId, IMyVoxelBase originalAsteroid, string searchMaterialName1, string searchMaterialName2) { MyVoxelMaterialDefinition material1; string suggestedMaterials = ""; if (!Support.FindMaterial(searchMaterialName1, out material1, ref suggestedMaterials)) { MyAPIGateway.Utilities.SendMessage(steamId, "Invalid Material1 specified.", "Cannot find the material '{0}'.\r\nTry the following: {1}", searchMaterialName1, suggestedMaterials); return(true); } MyVoxelMaterialDefinition material2; if (!Support.FindMaterial(searchMaterialName2, out material2, ref suggestedMaterials)) { MyAPIGateway.Utilities.SendMessage(steamId, "Invalid Material2 specified.", "Cannot find the material '{0}'.\r\nTry the following: {1}", searchMaterialName2, suggestedMaterials); return(true); } var oldStorage = originalAsteroid.Storage; var oldCache = new MyStorageData(); oldCache.Resize(oldStorage.Size); oldStorage.ReadRange(oldCache, MyStorageDataTypeFlags.ContentAndMaterial, 0, Vector3I.Zero, oldStorage.Size - 1); Vector3I p; for (p.Z = 0; p.Z < oldStorage.Size.Z; ++p.Z) { for (p.Y = 0; p.Y < oldStorage.Size.Y; ++p.Y) { for (p.X = 0; p.X < oldStorage.Size.X; ++p.X) { var material = oldCache.Material(ref p); if (material == material1.Index) { oldCache.Material(ref p, material2.Index); } } } } oldStorage.WriteRange(oldCache, MyStorageDataTypeFlags.ContentAndMaterial, Vector3I.Zero, oldStorage.Size - 1); MyAPIGateway.Utilities.SendMessage(steamId, "Asteroid", "'{0}' material '{1}' replaced with '{2}'.", originalAsteroid.StorageName, material1.Id.SubtypeName, material2.Id.SubtypeName); return(true); }
internal static int PointsInsideVoxel(MyVoxelBase voxel, MyStorageData tmpStorage, List <Vector3D> points) { var voxelMatrix = voxel.PositionComp.WorldMatrixInvScaled; var vecMax = new Vector3I(int.MaxValue); var vecMin = new Vector3I(int.MinValue); var results = 0; for (int index = 0; index < points.Count; ++index) { var point = points[index]; 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); vecMax = v2; vecMin = 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; if (num13 + (num14 - num13) * r.Z >= sbyte.MaxValue) { ++results; } } return(results); }
internal static bool CheckPointsOnLine(MyVoxelBase voxel, LineD testLine, MyStorageData tmpStorage, int distBetweenPoints) { var voxelMatrix = voxel.PositionComp.WorldMatrixInvScaled; var vecMax = new Vector3I(int.MaxValue); var vecMin = new Vector3I(int.MinValue); var checkPoints = (int)(testLine.Length / distBetweenPoints); for (int i = 0; i < checkPoints; i++) { var point = testLine.From + (testLine.Direction * (distBetweenPoints * i)); 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); vecMax = v2; vecMin = 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; if (num13 + (num14 - num13) * r.Z >= sbyte.MaxValue) { return(true); } } return(false); }
public static MyVoxelMaterialDefinition GetMaterialAt(this IMyStorage self, ref Vector3D localCoords) { MyVoxelMaterialDefinition def; Vector3I voxelCoords = Vector3D.Floor(localCoords / MyVoxelConstants.VOXEL_SIZE_IN_METRES); MyStorageData cache = new MyStorageData(); cache.Resize(Vector3I.One); cache.ClearMaterials(0); self.ReadRange(cache, MyStorageDataTypeFlags.Material, 0, ref voxelCoords, ref voxelCoords); def = MyDefinitionManager.Static.GetVoxelMaterialDefinition(cache.Material(0)); return(def); }
public static bool CheckVoxelContent(long voxelId, Vector3D position) { IMyEntity entity; if (!MyAPIGateway.Entities.TryGetEntityById(voxelId, out entity)) { return(false); } var voxel = entity as IMyVoxelBase; var targetMin = position; var targetMax = position; Vector3I minVoxel, maxVoxel; MyVoxelCoordSystems.WorldPositionToVoxelCoord(voxel.PositionLeftBottomCorner, ref targetMin, out minVoxel); MyVoxelCoordSystems.WorldPositionToVoxelCoord(voxel.PositionLeftBottomCorner, ref targetMax, out maxVoxel); MyVoxelBase voxelBase = voxel as MyVoxelBase; minVoxel += voxelBase.StorageMin; maxVoxel += voxelBase.StorageMin; voxel.Storage.ClampVoxel(ref minVoxel); voxel.Storage.ClampVoxel(ref maxVoxel); MyStorageData cache = new MyStorageData(); cache.Resize(minVoxel, maxVoxel); voxel.Storage.ReadRange(cache, MyStorageDataTypeFlags.Content, 0, minVoxel, maxVoxel); // Grab content and material var original = cache.Content(0); //var material = cache.Material(0); if (original == MyVoxelConstants.VOXEL_CONTENT_EMPTY) { //Logging.Instance.WriteLine(string.Format("Content is empty")); return(false); } return(true); }
public bool ChangeMaterials(byte[] materialChangeFrom, byte[] materialChangeTo) { int rewrites = 0; if (materialChangeFrom != null && materialChangeTo != null) { int maxIndex = Math.Min(materialChangeFrom.Length, materialChangeTo.Length); if (maxIndex > 0) { Vector3I minCorner = Vector3I.Zero; Vector3I maxCorner = this.Size - 1; MyStorageData cache = new MyStorageData(); cache.Resize(this.Size); cache.ClearMaterials(0); this.ReadRange(cache, MyStorageDataTypeFlags.Material, 0, ref minCorner, ref maxCorner); byte[] data = cache[MyStorageDataTypeEnum.Material]; int i, j; for (i = 0; i < data.Length; i++) { if (data[i] > 0) { for (j = 0; j < maxIndex; j++) { if (data[i] == materialChangeFrom[j]) { data[i] = materialChangeTo[j]; rewrites++; break; } } } } if (rewrites > 0) { this.WriteRange(cache, MyStorageDataTypeFlags.Material, ref minCorner, ref maxCorner); } } } return(rewrites > 0); }
public unsafe bool ChangeMaterials(Dictionary <byte, byte> map) { int rewrites = 0; if ((Size + 1).Size > 4 * 1024 * 1024) { MyLog.Default.Error("Cannot overwrite materials for a storage 4 MB or larger."); return(false); } Vector3I minCorner = Vector3I.Zero; Vector3I maxCorner = Size - 1; // I don't like this but write range will also allocate so f.. it. MyStorageData cache = new MyStorageData(); cache.Resize(Size); ReadRange(cache, MyStorageDataTypeFlags.Material, 0, ref minCorner, ref maxCorner); var len = cache.SizeLinear; fixed(byte *data = cache[MyStorageDataTypeEnum.Material]) for (int i = 0; i < len; i++) { byte to; if (map.TryGetValue(data[i], out to)) { data[i] = to; rewrites++; } } if (rewrites > 0) { this.WriteRange(cache, MyStorageDataTypeFlags.Material, ref minCorner, ref maxCorner); } return(rewrites > 0); }
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)); }
protected void RefreshCache( ) { IMyVoxelMap voxelMap = (IMyVoxelMap)BackingObject; m_cache = new MyStorageData( ); Vector3I size = voxelMap.Storage.Size; m_cache.Resize(size); // SandboxGameAssemblyWrapper.Instance.GameAction(() => // { voxelMap.Storage.ReadRange(m_cache, MyStorageDataTypeFlags.Material, 0, Vector3I.Zero, size - 1); //voxelMap.Storage.ReadRange(m_cache, MyStorageDataTypeFlags.Material, Vector3I.Zero, size - 1); // }); foreach (byte materialIndex in m_cache.Data) { try { MyVoxelMaterialDefinition material = MyDefinitionManager.Static.GetVoxelMaterialDefinition(materialIndex); if (material == null) { continue; } if (!m_materialTotals.ContainsKey(material)) { m_materialTotals.Add(material, 1); } else { m_materialTotals[material]++; } } catch (Exception ex) { ApplicationLog.BaseLog.Error(ex); } } }
private bool excludeVoxelBase(Vector3D center, ref HashSet <IMyVoxelBase> asteroids) { MyStorageData cache = new MyStorageData(); cache.Resize(Vector3I.One); Vector3I voxelCoord; foreach (IMyVoxelBase asteroid in asteroids) { if (asteroid.WorldAABB.Contains(center) != ContainmentType.Contains) { continue; } MyVoxelCoordSystems.WorldPositionToVoxelCoord(asteroid.PositionLeftBottomCorner, ref center, out voxelCoord); asteroid.Storage.ReadRange(cache, MyStorageDataTypeFlags.Content, 0, voxelCoord, voxelCoord); if (cache.Content(ref Vector3I.Zero) != (byte)0) { return(true); } } return(false); }
void IMyOctreeLeafNode.WriteRange(MyStorageData source, ref Vector3I readOffset, ref Vector3I min, ref Vector3I max) { m_octree.WriteRange(source, m_dataType, ref readOffset, ref min, ref max); if (DEBUG_WRITES) { var tmp = new MyStorageData(); tmp.Resize(min, max); m_octree.ReadRange(tmp, m_dataType, ref Vector3I.Zero, 0, ref min, ref max); Vector3I p = Vector3I.Zero; var cacheEnd = max - min; int errorCounter = 0; for (var it = new Vector3I.RangeIterator(ref Vector3I.Zero, ref cacheEnd); it.IsValid(); it.GetNext(out p)) { var read = readOffset + p; if (source.Get(m_dataType, ref read) != tmp.Get(m_dataType, ref p)) { ++errorCounter; } } Debug.Assert(errorCounter == 0, string.Format("{0} errors writing to leaf octree.", errorCounter)); } }
public bool ChangeMaterials(byte[] materialChangeFrom, byte[] materialChangeTo) { int rewrites = 0; if (materialChangeFrom != null && materialChangeTo != null) { int maxIndex = Math.Min(materialChangeFrom.Length, materialChangeTo.Length); if (maxIndex > 0) { Vector3I minCorner = Vector3I.Zero; Vector3I maxCorner = this.Size-1; MyStorageData cache = new MyStorageData(); cache.Resize(this.Size); cache.ClearMaterials(0); this.ReadRange(cache, MyStorageDataTypeFlags.Material, 0, ref minCorner, ref maxCorner); byte[] data = cache[MyStorageDataTypeEnum.Material]; int i, j; for (i = 0; i < data.Length; i++) { if (data[i] > 0) { for (j = 0; j < maxIndex; j++) { if (data[i] == materialChangeFrom[j]) { data[i] = materialChangeTo[j]; rewrites++; break; } } } } if (rewrites > 0) this.WriteRange(cache, MyStorageDataTypeFlags.Material, ref minCorner, ref maxCorner); } } return (rewrites > 0); }
/// <summary> /// /// </summary> /// <param name="voxelMap"></param> /// <param name="resolution">0 to 8. 0 for fine/slow detail.</param> /// <param name="distance"></param> /// <returns></returns> private int FindMaterial(IMyVoxelBase voxelMap, Vector3D center, int resolution, double distance) { int hits = 0; var materials = MyDefinitionManager.Static.GetVoxelMaterialDefinitions().Where(v => v.IsRare).ToArray(); var findMaterial = materials.Select(f => f.Index).ToArray(); var storage = voxelMap.Storage; var scale = (int)Math.Pow(2, resolution); //MyAPIGateway.Utilities.ShowMessage("center", center.ToString()); var point = new Vector3I(center - voxelMap.PositionLeftBottomCorner); //MyAPIGateway.Utilities.ShowMessage("point", point.ToString()); var min = ((point - (int)distance) / 64) * 64; min = Vector3I.Max(min, Vector3I.Zero); //MyAPIGateway.Utilities.ShowMessage("min", min.ToString()); var max = ((point + (int)distance) / 64) * 64; max = Vector3I.Max(max, min + 64); //MyAPIGateway.Utilities.ShowMessage("max", max.ToString()); //MyAPIGateway.Utilities.ShowMessage("size", voxelMap.StorageName + " " + storage.Size.ToString()); if (min.X >= storage.Size.X || min.Y >= storage.Size.Y || min.Z >= storage.Size.Z) { //MyAPIGateway.Utilities.ShowMessage("size", "out of range"); return 0; } var oldCache = new MyStorageData(); //var smin = new Vector3I(0, 0, 0); //var smax = new Vector3I(31, 31, 31); ////var size = storage.Size; //var size = smax - smin + 1; //size = new Vector3I(16, 16, 16); //oldCache.Resize(size); //storage.ReadRange(oldCache, MyStorageDataTypeFlags.ContentAndMaterial, resolution, Vector3I.Zero, size - 1); var smax = (max / scale) - 1; var smin = (min / scale); var size = smax - smin + 1; oldCache.Resize(size); storage.ReadRange(oldCache, MyStorageDataTypeFlags.ContentAndMaterial, resolution, smin, smax); //MyAPIGateway.Utilities.ShowMessage("smax", smax.ToString()); //MyAPIGateway.Utilities.ShowMessage("size", size .ToString()); //MyAPIGateway.Utilities.ShowMessage("size - 1", (size - 1).ToString()); Vector3I p; for (p.Z = 0; p.Z < size.Z; ++p.Z) for (p.Y = 0; p.Y < size.Y; ++p.Y) for (p.X = 0; p.X < size.X; ++p.X) { // place GPS in the center of the Voxel var position = voxelMap.PositionLeftBottomCorner + (p * scale) + (scale / 2) + min; if (Math.Sqrt((position - center).LengthSquared()) < distance) { var content = oldCache.Content(ref p); var material = oldCache.Material(ref p); if (content > 0 && findMaterial.Contains(material)) { var index = Array.IndexOf(findMaterial, material); var name = materials[index].MinedOre; var gps = MyAPIGateway.Session.GPS.Create("Ore " + name, "scanore", position, true, false); MyAPIGateway.Session.GPS.AddGps(MyAPIGateway.Session.Player.IdentityId, gps); hits++; } } } return hits; }
void IMyOctreeLeafNode.WriteRange(MyStorageData source, ref Vector3I readOffset, ref Vector3I min, ref Vector3I max) { m_octree.WriteRange(source, m_dataType, ref readOffset, ref min, ref max); if (DEBUG_WRITES) { var tmp = new MyStorageData(); tmp.Resize(min, max); m_octree.ReadRange(tmp, m_dataType, ref Vector3I.Zero, 0, ref min, ref max); Vector3I p = Vector3I.Zero; var cacheEnd = max - min; int errorCounter = 0; for (var it = new Vector3I.RangeIterator(ref Vector3I.Zero, ref cacheEnd); it.IsValid(); it.GetNext(out p)) { var read = readOffset + p; if (source.Get(m_dataType, ref read) != tmp.Get(m_dataType, ref p)) ++errorCounter; } Debug.Assert(errorCounter == 0, string.Format("{0} errors writing to leaf octree.", errorCounter)); } }
private static MyStorageBase Compatibility_LoadCellStorage(int fileVersion, Stream stream) { // Size of this voxel map (in voxels) Vector3I tmpSize; tmpSize.X = stream.ReadInt32(); tmpSize.Y = stream.ReadInt32(); tmpSize.Z = stream.ReadInt32(); var storage = new MyOctreeStorage(null, tmpSize); // Size of data cell in voxels. Has to be the same as current size specified by our constants. Vector3I cellSize; cellSize.X = stream.ReadInt32(); cellSize.Y = stream.ReadInt32(); cellSize.Z = stream.ReadInt32(); Trace.Assert(cellSize.X == MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS && cellSize.Y == MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS && cellSize.Z == MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS); Vector3I cellsCount = tmpSize / cellSize; Dictionary<byte, MyVoxelMaterialDefinition> mappingTable = null; if (fileVersion == STORAGE_TYPE_VERSION_CELL) { // loading material names->index mappings mappingTable = Compatibility_LoadMaterialIndexMapping(stream); } else if (fileVersion == 1) { // material name->index mappings were not saved in this version } var startCoord = Vector3I.Zero; var endCoord = new Vector3I(MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS - 1); var cache = new MyStorageData(); cache.Resize(Vector3I.Zero, endCoord); Vector3I cellCoord; for (cellCoord.X = 0; cellCoord.X < cellsCount.X; cellCoord.X++) { for (cellCoord.Y = 0; cellCoord.Y < cellsCount.Y; cellCoord.Y++) { for (cellCoord.Z = 0; cellCoord.Z < cellsCount.Z; cellCoord.Z++) { MyVoxelRangeType cellType = (MyVoxelRangeType)stream.ReadByteNoAlloc(); // Cell's are FULL by default, therefore we don't need to change them switch (cellType) { case MyVoxelRangeType.EMPTY: cache.ClearContent(MyVoxelConstants.VOXEL_CONTENT_EMPTY); break; case MyVoxelRangeType.FULL: cache.ClearContent(MyVoxelConstants.VOXEL_CONTENT_FULL); break; case MyVoxelRangeType.MIXED: Vector3I v; for (v.X = 0; v.X < MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; v.X++) { for (v.Y = 0; v.Y < MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; v.Y++) { for (v.Z = 0; v.Z < MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; v.Z++) { cache.Content(ref v, stream.ReadByteNoAlloc()); } } } break; } startCoord = cellCoord * MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; endCoord = startCoord + (MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS - 1); storage.WriteRange(cache, MyStorageDataTypeFlags.Content, ref startCoord, ref endCoord); } } } try { // In case materials are not saved, catch any exceptions caused by this. // Read materials and indestructible for (cellCoord.X = 0; cellCoord.X < cellsCount.X; cellCoord.X++) { for (cellCoord.Y = 0; cellCoord.Y < cellsCount.Y; cellCoord.Y++) { for (cellCoord.Z = 0; cellCoord.Z < cellsCount.Z; cellCoord.Z++) { bool isSingleMaterial = stream.ReadByteNoAlloc() == 1; MyVoxelMaterialDefinition material = null; if (isSingleMaterial) { material = Compatibility_LoadCellVoxelMaterial(stream, mappingTable); cache.ClearMaterials(material.Index); } else { byte indestructibleContent; Vector3I voxelCoordInCell; for (voxelCoordInCell.X = 0; voxelCoordInCell.X < MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; voxelCoordInCell.X++) { for (voxelCoordInCell.Y = 0; voxelCoordInCell.Y < MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; voxelCoordInCell.Y++) { for (voxelCoordInCell.Z = 0; voxelCoordInCell.Z < MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; voxelCoordInCell.Z++) { material = Compatibility_LoadCellVoxelMaterial(stream, mappingTable); indestructibleContent = stream.ReadByteNoAlloc(); cache.Material(ref voxelCoordInCell, material.Index); } } } } startCoord = cellCoord * MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; endCoord = startCoord + (MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS - 1); storage.WriteRange(cache, MyStorageDataTypeFlags.Material, ref startCoord, ref endCoord); } } } } catch (EndOfStreamException ex) { MySandboxGame.Log.WriteLine(ex); } return storage; }
public override bool Invoke(string messageText) { if (messageText.StartsWith("/rotateroid ", StringComparison.InvariantCultureIgnoreCase)) { var match = Regex.Match(messageText, @"/rotateroid\s{1,}(?<Key>.+){1,}\s{1,}(?<X>[+-]?((\d+(\.\d*)?)|(\.\d+)))\s{1,}(?<Y>[+-]?((\d+(\.\d*)?)|(\.\d+)))\s{1,}(?<Z>[+-]?((\d+(\.\d*)?)|(\.\d+)))", RegexOptions.IgnoreCase); if (match.Success) { var rotateVector = new Vector3( double.Parse(match.Groups["X"].Value, CultureInfo.InvariantCulture), double.Parse(match.Groups["Y"].Value, CultureInfo.InvariantCulture), double.Parse(match.Groups["Z"].Value, CultureInfo.InvariantCulture)); var searchName = match.Groups["Key"].Value; var currentAsteroidList = new List<IMyVoxelBase>(); IMyVoxelBase originalAsteroid = null; MyAPIGateway.Session.VoxelMaps.GetInstances(currentAsteroidList, v => v.StorageName.Equals(searchName, StringComparison.InvariantCultureIgnoreCase)); if (currentAsteroidList.Count == 1) { originalAsteroid = currentAsteroidList[0]; } else { MyAPIGateway.Session.VoxelMaps.GetInstances(currentAsteroidList, v => v.StorageName.IndexOf(searchName, StringComparison.InvariantCultureIgnoreCase) >= 0); if (currentAsteroidList.Count == 1) { originalAsteroid = currentAsteroidList[0]; } } int index; if (searchName.Substring(0, 1) == "#" && Int32.TryParse(searchName.Substring(1), out index) && index > 0 && index <= CommandAsteroidsList.AsteroidCache.Count) { originalAsteroid = CommandAsteroidsList.AsteroidCache[index - 1]; } if (originalAsteroid == null) { MyAPIGateway.Utilities.ShowMessage("Cannot find asteroid", string.Format("'{0}'", searchName)); return true; } var quaternion = Quaternion.CreateFromYawPitchRoll(rotateVector.X / (180 / MathHelper.Pi), rotateVector.Y / (180 / MathHelper.Pi), rotateVector.Z / (180 / MathHelper.Pi)); var oldStorage = originalAsteroid.Storage; var oldCache = new MyStorageData(); oldCache.Resize(oldStorage.Size); oldStorage.ReadRange(oldCache, MyStorageDataTypeFlags.ContentAndMaterial, 0, Vector3I.Zero, oldStorage.Size - 1); var transSize = Vector3I.Transform(oldStorage.Size, quaternion); var newSize = Vector3I.Abs(transSize); var newName = Support.CreateUniqueStorageName(originalAsteroid.StorageName); var newVoxelMap = Support.CreateNewAsteroid(newName, newSize, originalAsteroid.PositionLeftBottomCorner); var cache = new MyStorageData(); var min = Vector3I.Zero; var max = newSize - 1; cache.Resize(min, max); Vector3I p; for (p.Z = 0; p.Z < oldStorage.Size.Z; ++p.Z) for (p.Y = 0; p.Y < oldStorage.Size.Y; ++p.Y) for (p.X = 0; p.X < oldStorage.Size.X; ++p.X) { var content = oldCache.Content(ref p); var material = oldCache.Material(ref p); var newP = Vector3I.Transform(p, quaternion); // readjust the points, as rotation occurs arround 0,0,0. newP.X = newP.X < 0 ? newP.X - transSize.X - 1 : newP.X; newP.Y = newP.Y < 0 ? newP.Y - transSize.Y - 1 : newP.Y; newP.Z = newP.Z < 0 ? newP.Z - transSize.Z - 1 : newP.Z; cache.Content(ref newP, content); cache.Material(ref newP, material); } newVoxelMap.Storage.WriteRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, min, max); MyAPIGateway.Entities.RemoveEntity((IMyEntity)originalAsteroid); // Invalidate the cache, to force user to select again to prevent possible corruption by using an old cache. CommandAsteroidsList.AsteroidCache.Clear(); return true; } } return false; }
public static MyVoxelMaterialDefinition GetMaterialAt(this IMyStorage self, ref Vector3I voxelCoords) { MyVoxelMaterialDefinition def; MyStorageData cache = new MyStorageData(); cache.Resize(Vector3I.One); cache.ClearMaterials(0); self.ReadRange(cache, MyStorageDataTypeFlags.Material, 0, ref voxelCoords, ref voxelCoords); def = MyDefinitionManager.Static.GetVoxelMaterialDefinition(cache.Material(0)); return def; }
public static MyVoxelMaterialDefinition GetMaterialAt(this IMyStorage self, ref Vector3D localCoords) { MyVoxelMaterialDefinition def; Vector3I voxelCoords = Vector3D.Floor(localCoords / MyVoxelConstants.VOXEL_SIZE_IN_METRES); MyStorageData cache = new MyStorageData(); cache.Resize(Vector3I.One); cache.ClearMaterials(0); self.ReadRange(cache, MyStorageDataTypeFlags.Material, 0, ref voxelCoords, ref voxelCoords); def = MyDefinitionManager.Static.GetVoxelMaterialDefinition(cache.Material(0)); return def; }
void ShrinkVMap() { Vector3I min, max; m_selectedVoxel.GetFilledStorageBounds(out min, out max); MyVoxelMapStorageDefinition def = null; if (m_selectedVoxel.AsteroidName != null) MyDefinitionManager.Static.TryGetVoxelMapStorageDefinition(m_selectedVoxel.AsteroidName, out def); var origSize = m_selectedVoxel.Size; var tightSize = max - min + 1; var storage = new MyOctreeStorage(null, tightSize); var offset = (storage.Size - tightSize)/2 + 1; MyStorageData data = new MyStorageData(); data.Resize(tightSize); m_selectedVoxel.Storage.ReadRange(data, MyStorageDataTypeFlags.ContentAndMaterial, 0, min, max); min = offset; max = offset + tightSize - 1; storage.WriteRange(data, MyStorageDataTypeFlags.ContentAndMaterial, ref min, ref max); var newMap = MyWorldGenerator.AddVoxelMap(m_selectedVoxel.StorageName, storage, m_selectedVoxel.WorldMatrix); m_selectedVoxel.Close(); newMap.Save = true; if (def == null) { ShowAlert("Voxel map {0} does not have a definition, the shrunk voxel map will be saved with the world instead.", m_selectedVoxel.StorageName); } else { byte[] cVmapData; newMap.Storage.Save(out cVmapData); using (var ostream = MyFileSystem.OpenWrite(Path.Combine(MyFileSystem.ContentPath, def.StorageFile), FileMode.Open)) { ostream.Write(cVmapData, 0, cVmapData.Length); } var notification = new MyHudNotification(MyStringId.GetOrCompute("Voxel prefab {0} updated succesfuly (size changed from {1} to {2})."), 4000); notification.SetTextFormatArguments(def.Id.SubtypeName, origSize, storage.Size); MyHud.Notifications.Add(notification); } }
private void ProcessAsteroid(string displayType, string displayName, IMyVoxelMap voxelMap, double distance, BoundingBoxD aabb) { Vector3I min = Vector3I.MaxValue; Vector3I max = Vector3I.MinValue; Vector3I block; Dictionary <byte, long> assetCount = new Dictionary <byte, long>(); // read the asteroid in chunks of 64 to avoid the Arithmetic overflow issue. for (block.Z = 0; block.Z < voxelMap.Storage.Size.Z; block.Z += 64) { for (block.Y = 0; block.Y < voxelMap.Storage.Size.Y; block.Y += 64) { for (block.X = 0; block.X < voxelMap.Storage.Size.X; block.X += 64) { var cacheSize = new Vector3I(64); var oldCache = new MyStorageData(); oldCache.Resize(cacheSize); // LOD1 is not detailed enough for content information on asteroids. voxelMap.Storage.ReadRange(oldCache, MyStorageDataTypeFlags.ContentAndMaterial, 0, block, block + cacheSize - 1); Vector3I p; for (p.Z = 0; p.Z < cacheSize.Z; ++p.Z) { for (p.Y = 0; p.Y < cacheSize.Y; ++p.Y) { for (p.X = 0; p.X < cacheSize.X; ++p.X) { var content = oldCache.Content(ref p); if (content > 0) { min = Vector3I.Min(min, p + block); max = Vector3I.Max(max, p + block + 1); var material = oldCache.Material(ref p); if (assetCount.ContainsKey(material)) { assetCount[material] += content; } else { assetCount.Add(material, content); } } } } } } } } var assetNameCount = new Dictionary <string, long>(); foreach (var kvp in assetCount) { var name = MyDefinitionManager.Static.GetVoxelMaterialDefinition(kvp.Key).Id.SubtypeName; if (assetNameCount.ContainsKey(name)) { assetNameCount[name] += kvp.Value; } else { assetNameCount.Add(name, kvp.Value); } } assetNameCount = assetNameCount.OrderByDescending(e => e.Value).ToDictionary(kvp => kvp.Key, kvp => kvp.Value); var sum = assetNameCount.Values.Sum(); var ores = new StringBuilder(); foreach (var kvp in assetNameCount) { ores.AppendFormat("{0} {1:N} {2:P}\r\n", kvp.Key, (double)kvp.Value / 255, (double)kvp.Value / (double)sum); } var contentBox = new BoundingBoxD(voxelMap.PositionLeftBottomCorner + min, voxelMap.PositionLeftBottomCorner + max); var description = string.Format("Distance: {0:N}\r\nSize: {1}\r\nBoundingBox Center: [X:{2:N} Y:{3:N} Z:{4:N}]\r\n\r\nContent Size:{5}\r\nLOD0 Content Center: [X:{6:N} Y:{7:N} Z:{8:N}]\r\n\r\nMaterial Mass Percent\r\n{9}", distance, voxelMap.Storage.Size, aabb.Center.X, aabb.Center.Y, aabb.Center.Z, max - min, contentBox.Center.X, contentBox.Center.Y, contentBox.Center.Z, ores); MyAPIGateway.Utilities.ShowMissionScreen(string.Format("ID {0}:", displayType), string.Format("'{0}'", displayName), " ", description, null, "OK"); }
private void ProcessAsteroid(string displayType, string displayName, IMyVoxelMap voxelMap, double distance, BoundingBoxD aabb) { Vector3I min = Vector3I.MaxValue; Vector3I max = Vector3I.MinValue; Vector3I block; Dictionary<byte, long> assetCount = new Dictionary<byte, long>(); // read the asteroid in chunks of 64 to avoid the Arithmetic overflow issue. for (block.Z = 0; block.Z < voxelMap.Storage.Size.Z; block.Z += 64) for (block.Y = 0; block.Y < voxelMap.Storage.Size.Y; block.Y += 64) for (block.X = 0; block.X < voxelMap.Storage.Size.X; block.X += 64) { var cacheSize = new Vector3I(64); var oldCache = new MyStorageData(); oldCache.Resize(cacheSize); // LOD1 is not detailed enough for content information on asteroids. voxelMap.Storage.ReadRange(oldCache, MyStorageDataTypeFlags.ContentAndMaterial, 0, block, block + cacheSize - 1); Vector3I p; for (p.Z = 0; p.Z < cacheSize.Z; ++p.Z) for (p.Y = 0; p.Y < cacheSize.Y; ++p.Y) for (p.X = 0; p.X < cacheSize.X; ++p.X) { var content = oldCache.Content(ref p); if (content > 0) { min = Vector3I.Min(min, p + block); max = Vector3I.Max(max, p + block + 1); var material = oldCache.Material(ref p); if (assetCount.ContainsKey(material)) assetCount[material] += content; else assetCount.Add(material, content); } } } var assetNameCount = new Dictionary<string, long>(); foreach (var kvp in assetCount) { var name = MyDefinitionManager.Static.GetVoxelMaterialDefinition(kvp.Key).Id.SubtypeName; if (assetNameCount.ContainsKey(name)) assetNameCount[name] += kvp.Value; else assetNameCount.Add(name, kvp.Value); } assetNameCount = assetNameCount.OrderByDescending(e => e.Value).ToDictionary(kvp => kvp.Key, kvp => kvp.Value); var sum = assetNameCount.Values.Sum(); var ores = new StringBuilder(); foreach (var kvp in assetNameCount) ores.AppendFormat("{0} {1:N} {2:P}\r\n", kvp.Key, (double)kvp.Value / 255, (double)kvp.Value / (double)sum); var contentBox = new BoundingBoxD(voxelMap.PositionLeftBottomCorner + min, voxelMap.PositionLeftBottomCorner + max); var description = string.Format("Distance: {0:N}\r\nSize: {1}\r\nBoundingBox Center: [X:{2:N} Y:{3:N} Z:{4:N}]\r\n\r\nContent Size:{5}\r\nLOD0 Content Center: [X:{6:N} Y:{7:N} Z:{8:N}]\r\n\r\nMaterial Mass Percent\r\n{9}", distance, voxelMap.Storage.Size, aabb.Center.X, aabb.Center.Y, aabb.Center.Z, max - min, contentBox.Center.X, contentBox.Center.Y, contentBox.Center.Z, ores); MyAPIGateway.Utilities.ShowMissionScreen(string.Format("ID {0}:", displayType), string.Format("'{0}'", displayName), " ", description, null, "OK"); }
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); } } }
private bool ReplaceAsteroidMaterial(IMyVoxelBase originalAsteroid, string searchMaterialName1, string searchMaterialName2) { MyVoxelMaterialDefinition material1; string suggestedMaterials = ""; if (!Support.FindMaterial(searchMaterialName1, out material1, ref suggestedMaterials)) { MyAPIGateway.Utilities.ShowMessage("Invalid Material1 specified.", "Cannot find the material '{0}'.\r\nTry the following: {1}", searchMaterialName1, suggestedMaterials); return true; } MyVoxelMaterialDefinition material2; if (!Support.FindMaterial(searchMaterialName2, out material2, ref suggestedMaterials)) { MyAPIGateway.Utilities.ShowMessage("Invalid Material2 specified.", "Cannot find the material '{0}'.\r\nTry the following: {1}", searchMaterialName2, suggestedMaterials); return true; } var oldStorage = originalAsteroid.Storage; var oldCache = new MyStorageData(); oldCache.Resize(oldStorage.Size); oldStorage.ReadRange(oldCache, MyStorageDataTypeFlags.ContentAndMaterial, 0, Vector3I.Zero, oldStorage.Size - 1); Vector3I p; for (p.Z = 0; p.Z < oldStorage.Size.Z; ++p.Z) for (p.Y = 0; p.Y < oldStorage.Size.Y; ++p.Y) for (p.X = 0; p.X < oldStorage.Size.X; ++p.X) { var material = oldCache.Material(ref p); if (material == material1.Index) oldCache.Material(ref p, material2.Index); } oldStorage.WriteRange(oldCache, MyStorageDataTypeFlags.ContentAndMaterial, Vector3I.Zero, oldStorage.Size - 1); MyAPIGateway.Utilities.ShowMessage("Asteroid", "'{0}' material '{1}' replaced with '{2}'.", originalAsteroid.StorageName, material1.Id.SubtypeName, material2.Id.SubtypeName); return true; }
/// <summary> /// For debugging/testing only! This can be very slow for large storage. /// </summary> public void Voxelize(MyStorageDataTypeFlags data) { MyVoxelRequestFlags flags = 0; var cache = new MyStorageData(); cache.Resize(new Vector3I(LeafSizeInVoxels)); var leafCount = (Size / LeafSizeInVoxels); Vector3I leaf = Vector3I.Zero; var end = leafCount - 1; for (var it = new Vector3I.RangeIterator(ref Vector3I.Zero, ref end); it.IsValid(); it.GetNext(out leaf)) { Debug.WriteLine("Processing {0} / {1}", leaf, end); var min = leaf * LeafSizeInVoxels; var max = min + (LeafSizeInVoxels - 1); ReadRangeInternal(cache, ref Vector3I.Zero, data, 0, ref min, ref max, ref flags); WriteRangeInternal(cache, data, ref min, ref max); } OnRangeChanged(Vector3I.Zero, Size - 1, data); }
private bool FindMaterial(IMyStorage storage, byte[] findMaterial) { if (findMaterial.Length == 0) return false; var oldCache = new MyStorageData(); oldCache.Resize(storage.Size); storage.ReadRange(oldCache, MyStorageDataTypeFlags.ContentAndMaterial, 2, Vector3I.Zero, storage.Size - 1); //MyAPIGateway.Utilities.ShowMessage("check", string.Format("SizeLinear {0} {1}.", oldCache.SizeLinear, oldCache.StepLinear)); Vector3I p; for (p.Z = 0; p.Z < storage.Size.Z; ++p.Z) for (p.Y = 0; p.Y < storage.Size.Y; ++p.Y) for (p.X = 0; p.X < storage.Size.X; ++p.X) { var content = oldCache.Content(ref p); var material = oldCache.Material(ref p); if (content > 0 && findMaterial.Contains(material)) { return true; } } return false; }
private static void VoxelReading() { var camera = MySector.MainCamera; if (camera == null) return; var offset = 0; // MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF; var targetPosition = camera.Position + (Vector3D)camera.ForwardVector * 4.5f - offset; MyVoxelBase targetVoxelMap = null; foreach (var voxelMap in MySession.Static.VoxelMaps.Instances) { if (voxelMap.PositionComp.WorldAABB.Contains(targetPosition) == ContainmentType.Contains) { targetVoxelMap = voxelMap; break; } } if (targetVoxelMap == null) return; var targetMin = targetPosition - Vector3.One * MyVoxelConstants.VOXEL_SIZE_IN_METRES; var targetMax = targetPosition + Vector3.One * MyVoxelConstants.VOXEL_SIZE_IN_METRES; Vector3I minVoxel, maxVoxel; MyVoxelCoordSystems.WorldPositionToVoxelCoord(targetVoxelMap.PositionLeftBottomCorner, ref targetMin, out minVoxel); MyVoxelCoordSystems.WorldPositionToVoxelCoord(targetVoxelMap.PositionLeftBottomCorner, ref targetMax, out maxVoxel); MyVoxelCoordSystems.VoxelCoordToWorldPosition(targetVoxelMap.PositionLeftBottomCorner, ref minVoxel, out targetMin); MyVoxelCoordSystems.VoxelCoordToWorldPosition(targetVoxelMap.PositionLeftBottomCorner, ref maxVoxel, out targetMax); { BoundingBoxD bbox = BoundingBoxD.CreateInvalid(); bbox.Include(targetMin); bbox.Include(targetMax); VRageRender.MyRenderProxy.DebugDrawAABB(bbox, Vector3.One, 1f, 1f, true); } if (MyInput.Static.IsNewLeftMousePressed()) { var cache = new MyStorageData(); cache.Resize(minVoxel, maxVoxel); targetVoxelMap.Storage.ReadRange(cache, MyStorageDataTypeFlags.Content, 0, ref minVoxel, ref maxVoxel); targetVoxelMap.Storage.WriteRange(cache, MyStorageDataTypeFlags.Content, ref minVoxel, ref maxVoxel); Debug.Assert(true); } }
private static MyStorageBase Compatibility_LoadCellStorage(int fileVersion, Stream stream) { // Size of this voxel map (in voxels) Vector3I tmpSize; tmpSize.X = stream.ReadInt32(); tmpSize.Y = stream.ReadInt32(); tmpSize.Z = stream.ReadInt32(); var storage = new MyOctreeStorage(null, tmpSize); // Size of data cell in voxels. Has to be the same as current size specified by our constants. Vector3I cellSize; cellSize.X = stream.ReadInt32(); cellSize.Y = stream.ReadInt32(); cellSize.Z = stream.ReadInt32(); #if !XB1 Trace.Assert(cellSize.X == MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS && cellSize.Y == MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS && cellSize.Z == MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS); #else // XB1 System.Diagnostics.Debug.Assert(cellSize.X == MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS && cellSize.Y == MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS && cellSize.Z == MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS); #endif // XB1 Vector3I cellsCount = tmpSize / cellSize; Dictionary <byte, MyVoxelMaterialDefinition> mappingTable = null; if (fileVersion == STORAGE_TYPE_VERSION_CELL) { // loading material names->index mappings mappingTable = Compatibility_LoadMaterialIndexMapping(stream); } else if (fileVersion == 1) { // material name->index mappings were not saved in this version } var startCoord = Vector3I.Zero; var endCoord = new Vector3I(MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS - 1); var cache = new MyStorageData(); cache.Resize(Vector3I.Zero, endCoord); Vector3I cellCoord; for (cellCoord.X = 0; cellCoord.X < cellsCount.X; cellCoord.X++) { for (cellCoord.Y = 0; cellCoord.Y < cellsCount.Y; cellCoord.Y++) { for (cellCoord.Z = 0; cellCoord.Z < cellsCount.Z; cellCoord.Z++) { MyVoxelRangeType cellType = (MyVoxelRangeType)stream.ReadByteNoAlloc(); // Cell's are FULL by default, therefore we don't need to change them switch (cellType) { case MyVoxelRangeType.EMPTY: cache.ClearContent(MyVoxelConstants.VOXEL_CONTENT_EMPTY); break; case MyVoxelRangeType.FULL: cache.ClearContent(MyVoxelConstants.VOXEL_CONTENT_FULL); break; case MyVoxelRangeType.MIXED: Vector3I v; for (v.X = 0; v.X < MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; v.X++) { for (v.Y = 0; v.Y < MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; v.Y++) { for (v.Z = 0; v.Z < MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; v.Z++) { cache.Content(ref v, stream.ReadByteNoAlloc()); } } } break; } startCoord = cellCoord * MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; endCoord = startCoord + (MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS - 1); storage.WriteRange(cache, MyStorageDataTypeFlags.Content, ref startCoord, ref endCoord); } } } try { // In case materials are not saved, catch any exceptions caused by this. // Read materials and indestructible for (cellCoord.X = 0; cellCoord.X < cellsCount.X; cellCoord.X++) { for (cellCoord.Y = 0; cellCoord.Y < cellsCount.Y; cellCoord.Y++) { for (cellCoord.Z = 0; cellCoord.Z < cellsCount.Z; cellCoord.Z++) { bool isSingleMaterial = stream.ReadByteNoAlloc() == 1; MyVoxelMaterialDefinition material = null; if (isSingleMaterial) { material = Compatibility_LoadCellVoxelMaterial(stream, mappingTable); cache.ClearMaterials(material.Index); } else { byte indestructibleContent; Vector3I voxelCoordInCell; for (voxelCoordInCell.X = 0; voxelCoordInCell.X < MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; voxelCoordInCell.X++) { for (voxelCoordInCell.Y = 0; voxelCoordInCell.Y < MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; voxelCoordInCell.Y++) { for (voxelCoordInCell.Z = 0; voxelCoordInCell.Z < MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; voxelCoordInCell.Z++) { material = Compatibility_LoadCellVoxelMaterial(stream, mappingTable); indestructibleContent = stream.ReadByteNoAlloc(); cache.Material(ref voxelCoordInCell, material.Index); } } } } startCoord = cellCoord * MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; endCoord = startCoord + (MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS - 1); storage.WriteRange(cache, MyStorageDataTypeFlags.Material, ref startCoord, ref endCoord); } } } } catch (EndOfStreamException ex) { MySandboxGame.Log.WriteLine(ex); } return(storage); }
public override bool Invoke(ulong steamId, long playerId, string messageText) { // voxelset [0/off] [1/on] [A] [B] [C/Clear] if (messageText.StartsWith("/voxelset ", StringComparison.InvariantCultureIgnoreCase)) { var strings = messageText.Split(' '); if (strings.Length > 1) { if (strings[1].Equals("off", StringComparison.InvariantCultureIgnoreCase) || strings[1].Equals("0", StringComparison.InvariantCultureIgnoreCase)) { ActiveVoxelSetterPosition = null; _activeVoxelSetterPositionA = null; _activeVoxelSetterPositionB = null; _activeVoxelSetterNameA = null; _activeVoxelSetterNameB = null; ActiveVoxelSetter = false; MyAPIGateway.Utilities.ShowNotification("Voxel setter off", 1000, MyFontEnum.Green); return true; } if (strings[1].Equals("on", StringComparison.InvariantCultureIgnoreCase) || strings[1].Equals("1", StringComparison.InvariantCultureIgnoreCase)) { ActiveVoxelSetterPosition = null; _activeVoxelSetterPositionA = null; _activeVoxelSetterPositionB = null; _activeVoxelSetterNameA = null; _activeVoxelSetterNameB = null; ActiveVoxelSetter = true; MyAPIGateway.Utilities.ShowNotification("Voxel setter activated", 1000, MyFontEnum.Green); return true; } if (!ActiveVoxelSetter) { MyAPIGateway.Utilities.ShowNotification("Voxel setter hasn't been actived.", 2000, MyFontEnum.Red); return true; } if (strings[1].Equals("A", StringComparison.InvariantCultureIgnoreCase)) { var tmp = ActiveVoxelSetterPosition; if (tmp.HasValue) { var currentAsteroidList = new List<IMyVoxelBase>(); var bb = new BoundingBoxD(tmp.Value - 0.2f, tmp.Value + 0.2f); MyAPIGateway.Session.VoxelMaps.GetInstances(currentAsteroidList, v => v.IsBoxIntersectingBoundingBoxOfThisVoxelMap(ref bb)); if (currentAsteroidList.Count > 0) { _activeVoxelSetterNameA = currentAsteroidList[0].StorageName; _activeVoxelSetterPositionA = tmp; } } if (_activeVoxelSetterPositionA.HasValue) MyAPIGateway.Utilities.ShowMessage(_activeVoxelSetterNameA, "Voxel setter point A: active"); //MyAPIGateway.Utilities.ShowNotification("Voxel setter A: active.", 1000, MyFontEnum.Green); else MyAPIGateway.Utilities.ShowNotification("Voxel setter A: invalid.", 1000, MyFontEnum.Red); return true; } if (strings[1].Equals("B", StringComparison.InvariantCultureIgnoreCase)) { var tmp = ActiveVoxelSetterPosition; if (tmp.HasValue) { var currentAsteroidList = new List<IMyVoxelBase>(); var bb = new BoundingBoxD(tmp.Value - 0.2f, tmp.Value + 0.2f); MyAPIGateway.Session.VoxelMaps.GetInstances(currentAsteroidList, v => v.IsBoxIntersectingBoundingBoxOfThisVoxelMap(ref bb)); if (currentAsteroidList.Count > 0) { _activeVoxelSetterNameB = currentAsteroidList[0].StorageName; _activeVoxelSetterPositionB = tmp; } } if (_activeVoxelSetterPositionB.HasValue) MyAPIGateway.Utilities.ShowMessage(_activeVoxelSetterNameB, "Voxel setter point B: active"); //MyAPIGateway.Utilities.ShowNotification("Voxel setter B: active.", 1000, MyFontEnum.Green); else MyAPIGateway.Utilities.ShowNotification("Voxel setter B: invalid.", 1000, MyFontEnum.Red); return true; } if (strings[1].Equals("C", StringComparison.InvariantCultureIgnoreCase) || strings[1].Equals("Clear", StringComparison.InvariantCultureIgnoreCase)) { if (_activeVoxelSetterPositionA.HasValue && _activeVoxelSetterPositionB.HasValue && _activeVoxelSetterNameA == _activeVoxelSetterNameB) { var currentAsteroidList = new List<IMyVoxelBase>(); MyAPIGateway.Session.VoxelMaps.GetInstances(currentAsteroidList, v => v.StorageName.Equals(_activeVoxelSetterNameA, StringComparison.InvariantCultureIgnoreCase)); if (currentAsteroidList.Count > 0) { var storage = currentAsteroidList[0].Storage; var point1 = new Vector3I(_activeVoxelSetterPositionA.Value - currentAsteroidList[0].PositionLeftBottomCorner); var point2 = new Vector3I(_activeVoxelSetterPositionB.Value - currentAsteroidList[0].PositionLeftBottomCorner); var cache = new MyStorageData(); var size = storage.Size; cache.Resize(size); storage.ReadRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, (int)VRageRender.MyLodTypeEnum.LOD0, Vector3I.Zero, size - 1); var min = Vector3I.Min(point1, point2); var max = Vector3I.Max(point1, point2); MyAPIGateway.Utilities.ShowMessage("Cutting", min.ToString() + " " + max.ToString()); //MyAPIGateway.Utilities.ShowNotification("cutting:" + min.ToString() + " " + max.ToString(), 5000, MyFontEnum.Blue); Vector3I p; for (p.Z = min.Z; p.Z <= max.Z; ++p.Z) for (p.Y = min.Y; p.Y <= max.Y; ++p.Y) for (p.X = min.X; p.X <= max.X; ++p.X) cache.Content(ref p, 0); storage.WriteRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, Vector3I.Zero, size - 1); } } else if (_activeVoxelSetterNameA != _activeVoxelSetterNameB) { MyAPIGateway.Utilities.ShowNotification("Voxel setter Cut: different asteroids.", 2000, MyFontEnum.Red); } else { MyAPIGateway.Utilities.ShowNotification("Voxel setter Cut: invalid points.", 2000, MyFontEnum.Red); } return true; } if (strings[1].Equals("F", StringComparison.InvariantCultureIgnoreCase) || strings[1].Equals("Fill", StringComparison.InvariantCultureIgnoreCase)) { if (_activeVoxelSetterPositionA.HasValue && _activeVoxelSetterPositionB.HasValue && _activeVoxelSetterNameA == _activeVoxelSetterNameB) { var currentAsteroidList = new List<IMyVoxelBase>(); MyAPIGateway.Session.VoxelMaps.GetInstances(currentAsteroidList, v => v.StorageName.Equals(_activeVoxelSetterNameA, StringComparison.InvariantCultureIgnoreCase)); if (currentAsteroidList.Count > 0) { var storage = currentAsteroidList[0].Storage; var point1 = new Vector3I(_activeVoxelSetterPositionA.Value - currentAsteroidList[0].PositionLeftBottomCorner); var point2 = new Vector3I(_activeVoxelSetterPositionB.Value - currentAsteroidList[0].PositionLeftBottomCorner); var cache = new MyStorageData(); var size = storage.Size; cache.Resize(size); storage.ReadRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, (int)VRageRender.MyLodTypeEnum.LOD0, Vector3I.Zero, size - 1); var min = Vector3I.Min(point1, point2); var max = Vector3I.Max(point1, point2); MyAPIGateway.Utilities.ShowMessage("Filling", min.ToString() + " " + max.ToString()); //MyAPIGateway.Utilities.ShowNotification("filling:" + min.ToString() + " " + max.ToString(), 5000, MyFontEnum.Blue); Vector3I p; for (p.Z = min.Z; p.Z <= max.Z; ++p.Z) for (p.Y = min.Y; p.Y <= max.Y; ++p.Y) for (p.X = min.X; p.X <= max.X; ++p.X) cache.Content(ref p, 0xff); storage.WriteRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, Vector3I.Zero, size - 1); } } else if (_activeVoxelSetterNameA != _activeVoxelSetterNameB) { MyAPIGateway.Utilities.ShowNotification("Voxel setter Cut: different asteroids.", 2000, MyFontEnum.Red); } else { MyAPIGateway.Utilities.ShowNotification("Voxel setter Cut: invalid points.", 2000, MyFontEnum.Red); } return true; } } } return false; }
/// <summary> /// /// </summary> /// <param name="voxelMap"></param> /// <param name="center"></param> /// <param name="resolution">0 to 8. 0 for fine/slow detail.</param> /// <param name="distance"></param> /// <param name="scanHits"></param> /// <returns></returns> private void FindMaterial(IMyVoxelBase voxelMap, Vector3D center, int resolution, double distance, List <ScanHit> scanHits) { const double checkDistance = 50 * 50; // 50 meter seperation. var materials = MyDefinitionManager.Static.GetVoxelMaterialDefinitions().Where(v => v.IsRare).ToArray(); var findMaterial = materials.Select(f => f.Index).ToArray(); var storage = voxelMap.Storage; var scale = (int)Math.Pow(2, resolution); //MyAPIGateway.Utilities.ShowMessage("center", center.ToString()); var point = new Vector3I(center - voxelMap.PositionLeftBottomCorner); //MyAPIGateway.Utilities.ShowMessage("point", point.ToString()); var min = ((point - (int)distance) / 64) * 64; min = Vector3I.Max(min, Vector3I.Zero); //MyAPIGateway.Utilities.ShowMessage("min", min.ToString()); var max = ((point + (int)distance) / 64) * 64; max = Vector3I.Max(max, min + 64); //MyAPIGateway.Utilities.ShowMessage("max", max.ToString()); //MyAPIGateway.Utilities.ShowMessage("size", voxelMap.StorageName + " " + storage.Size.ToString()); if (min.X >= storage.Size.X || min.Y >= storage.Size.Y || min.Z >= storage.Size.Z) { //MyAPIGateway.Utilities.ShowMessage("size", "out of range"); return; } var oldCache = new MyStorageData(); //var smin = new Vector3I(0, 0, 0); //var smax = new Vector3I(31, 31, 31); ////var size = storage.Size; //var size = smax - smin + 1; //size = new Vector3I(16, 16, 16); //oldCache.Resize(size); //storage.ReadRange(oldCache, MyStorageDataTypeFlags.ContentAndMaterial, resolution, Vector3I.Zero, size - 1); var smax = (max / scale) - 1; var smin = (min / scale); var size = smax - smin + 1; oldCache.Resize(size); storage.ReadRange(oldCache, MyStorageDataTypeFlags.ContentAndMaterial, resolution, smin, smax); //MyAPIGateway.Utilities.ShowMessage("smax", smax.ToString()); //MyAPIGateway.Utilities.ShowMessage("size", size .ToString()); //MyAPIGateway.Utilities.ShowMessage("size - 1", (size - 1).ToString()); Vector3I p; for (p.Z = 0; p.Z < size.Z; ++p.Z) { for (p.Y = 0; p.Y < size.Y; ++p.Y) { for (p.X = 0; p.X < size.X; ++p.X) { // place GPS in the center of the Voxel Vector3D position = voxelMap.PositionLeftBottomCorner + (p * scale) + (scale / 2f) + min; if (Math.Sqrt((position - center).LengthSquared()) < distance) { byte content = oldCache.Content(ref p); byte material = oldCache.Material(ref p); if (content > 0 && findMaterial.Any(m => m == material)) { bool addHit = true; foreach (ScanHit scanHit in scanHits) { if (scanHit.Material == material && Vector3D.DistanceSquared(position, scanHit.Position) < checkDistance) { addHit = false; break; } } if (addHit) { scanHits.Add(new ScanHit(position, material)); } } } } } } }
public unsafe bool ChangeMaterials(Dictionary<byte, byte> map) { int rewrites = 0; if ((Size + 1).Size > 4 * 1024 * 1024) { MyLog.Default.Error("Cannot overwrite materials for a storage 4 MB or larger."); return false; } Vector3I minCorner = Vector3I.Zero; Vector3I maxCorner = Size - 1; // I don't like this but write range will also allocate so f.. it. MyStorageData cache = new MyStorageData(); cache.Resize(Size); ReadRange(cache, MyStorageDataTypeFlags.Material, 0, ref minCorner, ref maxCorner); var len = cache.SizeLinear; fixed (byte* data = cache[MyStorageDataTypeEnum.Material]) for (int i = 0; i < len; i++) { byte to; if (map.TryGetValue(data[i], out to)) data[i] = to; } if (rewrites > 0) this.WriteRange(cache, MyStorageDataTypeFlags.Material, ref minCorner, ref maxCorner); return rewrites > 0; }
public override bool Invoke(ulong steamId, long playerId, string messageText) { // voxelset [0/off] [1/on] [A] [B] [C/Clear] if (messageText.StartsWith("/voxelset ", StringComparison.InvariantCultureIgnoreCase)) { var strings = messageText.Split(' '); if (strings.Length > 1) { if (strings[1].Equals("off", StringComparison.InvariantCultureIgnoreCase) || strings[1].Equals("0", StringComparison.InvariantCultureIgnoreCase)) { ActiveVoxelSetterPosition = null; _activeVoxelSetterPositionA = null; _activeVoxelSetterPositionB = null; _activeVoxelSetterNameA = null; _activeVoxelSetterNameB = null; ActiveVoxelSetter = false; MyAPIGateway.Utilities.ShowNotification("Voxel setter off", 1000, MyFontEnum.Green); return(true); } if (strings[1].Equals("on", StringComparison.InvariantCultureIgnoreCase) || strings[1].Equals("1", StringComparison.InvariantCultureIgnoreCase)) { ActiveVoxelSetterPosition = null; _activeVoxelSetterPositionA = null; _activeVoxelSetterPositionB = null; _activeVoxelSetterNameA = null; _activeVoxelSetterNameB = null; ActiveVoxelSetter = true; MyAPIGateway.Utilities.ShowNotification("Voxel setter activated", 1000, MyFontEnum.Green); return(true); } if (!ActiveVoxelSetter) { MyAPIGateway.Utilities.ShowNotification("Voxel setter hasn't been actived.", 2000, MyFontEnum.Red); return(true); } if (strings[1].Equals("A", StringComparison.InvariantCultureIgnoreCase)) { var tmp = ActiveVoxelSetterPosition; if (tmp.HasValue) { var currentAsteroidList = new List <IMyVoxelBase>(); var bb = new BoundingBoxD(tmp.Value - 0.2f, tmp.Value + 0.2f); MyAPIGateway.Session.VoxelMaps.GetInstances(currentAsteroidList, v => v.IsBoxIntersectingBoundingBoxOfThisVoxelMap(ref bb)); if (currentAsteroidList.Count > 0) { _activeVoxelSetterNameA = currentAsteroidList[0].StorageName; _activeVoxelSetterPositionA = tmp; } } if (_activeVoxelSetterPositionA.HasValue) { MyAPIGateway.Utilities.ShowMessage(_activeVoxelSetterNameA, "Voxel setter point A: active"); } //MyAPIGateway.Utilities.ShowNotification("Voxel setter A: active.", 1000, MyFontEnum.Green); else { MyAPIGateway.Utilities.ShowNotification("Voxel setter A: invalid.", 1000, MyFontEnum.Red); } return(true); } if (strings[1].Equals("B", StringComparison.InvariantCultureIgnoreCase)) { var tmp = ActiveVoxelSetterPosition; if (tmp.HasValue) { var currentAsteroidList = new List <IMyVoxelBase>(); var bb = new BoundingBoxD(tmp.Value - 0.2f, tmp.Value + 0.2f); MyAPIGateway.Session.VoxelMaps.GetInstances(currentAsteroidList, v => v.IsBoxIntersectingBoundingBoxOfThisVoxelMap(ref bb)); if (currentAsteroidList.Count > 0) { _activeVoxelSetterNameB = currentAsteroidList[0].StorageName; _activeVoxelSetterPositionB = tmp; } } if (_activeVoxelSetterPositionB.HasValue) { MyAPIGateway.Utilities.ShowMessage(_activeVoxelSetterNameB, "Voxel setter point B: active"); } //MyAPIGateway.Utilities.ShowNotification("Voxel setter B: active.", 1000, MyFontEnum.Green); else { MyAPIGateway.Utilities.ShowNotification("Voxel setter B: invalid.", 1000, MyFontEnum.Red); } return(true); } if (strings[1].Equals("C", StringComparison.InvariantCultureIgnoreCase) || strings[1].Equals("Clear", StringComparison.InvariantCultureIgnoreCase)) { if (_activeVoxelSetterPositionA.HasValue && _activeVoxelSetterPositionB.HasValue && _activeVoxelSetterNameA == _activeVoxelSetterNameB) { var currentAsteroidList = new List <IMyVoxelBase>(); MyAPIGateway.Session.VoxelMaps.GetInstances(currentAsteroidList, v => v.StorageName.Equals(_activeVoxelSetterNameA, StringComparison.InvariantCultureIgnoreCase)); if (currentAsteroidList.Count > 0) { var storage = currentAsteroidList[0].Storage; var point1 = new Vector3I(_activeVoxelSetterPositionA.Value - currentAsteroidList[0].PositionLeftBottomCorner); var point2 = new Vector3I(_activeVoxelSetterPositionB.Value - currentAsteroidList[0].PositionLeftBottomCorner); var cache = new MyStorageData(); var size = storage.Size; cache.Resize(size); storage.ReadRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, (int)VRageRender.MyLodTypeEnum.LOD0, Vector3I.Zero, size - 1); var min = Vector3I.Min(point1, point2); var max = Vector3I.Max(point1, point2); MyAPIGateway.Utilities.ShowMessage("Cutting", min.ToString() + " " + max.ToString()); //MyAPIGateway.Utilities.ShowNotification("cutting:" + min.ToString() + " " + max.ToString(), 5000, MyFontEnum.Blue); Vector3I p; for (p.Z = min.Z; p.Z <= max.Z; ++p.Z) { for (p.Y = min.Y; p.Y <= max.Y; ++p.Y) { for (p.X = min.X; p.X <= max.X; ++p.X) { cache.Content(ref p, 0); } } } storage.WriteRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, Vector3I.Zero, size - 1); } } else if (_activeVoxelSetterNameA != _activeVoxelSetterNameB) { MyAPIGateway.Utilities.ShowNotification("Voxel setter Cut: different asteroids.", 2000, MyFontEnum.Red); } else { MyAPIGateway.Utilities.ShowNotification("Voxel setter Cut: invalid points.", 2000, MyFontEnum.Red); } return(true); } if (strings[1].Equals("F", StringComparison.InvariantCultureIgnoreCase) || strings[1].Equals("Fill", StringComparison.InvariantCultureIgnoreCase)) { if (_activeVoxelSetterPositionA.HasValue && _activeVoxelSetterPositionB.HasValue && _activeVoxelSetterNameA == _activeVoxelSetterNameB) { var currentAsteroidList = new List <IMyVoxelBase>(); MyAPIGateway.Session.VoxelMaps.GetInstances(currentAsteroidList, v => v.StorageName.Equals(_activeVoxelSetterNameA, StringComparison.InvariantCultureIgnoreCase)); if (currentAsteroidList.Count > 0) { var storage = currentAsteroidList[0].Storage; var point1 = new Vector3I(_activeVoxelSetterPositionA.Value - currentAsteroidList[0].PositionLeftBottomCorner); var point2 = new Vector3I(_activeVoxelSetterPositionB.Value - currentAsteroidList[0].PositionLeftBottomCorner); var cache = new MyStorageData(); var size = storage.Size; cache.Resize(size); storage.ReadRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, (int)VRageRender.MyLodTypeEnum.LOD0, Vector3I.Zero, size - 1); var min = Vector3I.Min(point1, point2); var max = Vector3I.Max(point1, point2); MyAPIGateway.Utilities.ShowMessage("Filling", min.ToString() + " " + max.ToString()); //MyAPIGateway.Utilities.ShowNotification("filling:" + min.ToString() + " " + max.ToString(), 5000, MyFontEnum.Blue); Vector3I p; for (p.Z = min.Z; p.Z <= max.Z; ++p.Z) { for (p.Y = min.Y; p.Y <= max.Y; ++p.Y) { for (p.X = min.X; p.X <= max.X; ++p.X) { cache.Content(ref p, 0xff); } } } storage.WriteRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, Vector3I.Zero, size - 1); } } else if (_activeVoxelSetterNameA != _activeVoxelSetterNameB) { MyAPIGateway.Utilities.ShowNotification("Voxel setter Cut: different asteroids.", 2000, MyFontEnum.Red); } else { MyAPIGateway.Utilities.ShowNotification("Voxel setter Cut: invalid points.", 2000, MyFontEnum.Red); } return(true); } } } return(false); }
private void UpdateLoad() { ConstructAreas(); if (m_checkQueue.Count == 0) { bool finishedLoading = true; m_ground = MySession.Static.VoxelMaps.TryGetVoxelMapByNameStart("Ground"); if (m_ground != null) { m_worldArea = m_ground.SizeInMetres.X * m_ground.SizeInMetres.Z; m_voxelCache = new MyStorageData(); m_voxelCache.Resize(Vector3I.One * 3); InvalidateAreaValues(); if (m_highLevelBoxes.Count == 0) { // MW: we need to find some candidates for forest starting points finishedLoading = false; m_findValidForestPhase = true; } } if (finishedLoading) { m_loadPhase = false; if (LoadFinished != null) LoadFinished(); } } }
public static void MakeCrater(MyVoxelBase voxelMap, BoundingSphereD sphere, Vector3 normal, MyVoxelMaterialDefinition material) { ProfilerShort.Begin("MakeCrater"); Vector3I minCorner, maxCorner; { Vector3D sphereMin = sphere.Center - (sphere.Radius - MyVoxelConstants.VOXEL_SIZE_IN_METRES); Vector3D sphereMax = sphere.Center + (sphere.Radius + MyVoxelConstants.VOXEL_SIZE_IN_METRES); MyVoxelCoordSystems.WorldPositionToVoxelCoord(voxelMap.PositionLeftBottomCorner, ref sphereMin, out minCorner); MyVoxelCoordSystems.WorldPositionToVoxelCoord(voxelMap.PositionLeftBottomCorner, ref sphereMax, out maxCorner); } voxelMap.Storage.ClampVoxelCoord(ref minCorner); voxelMap.Storage.ClampVoxelCoord(ref maxCorner); // We are tracking which voxels were changed, so we can invalidate only needed cells in the cache bool changed = false; ProfilerShort.Begin("Reading cache"); m_cache.Resize(minCorner, maxCorner); voxelMap.Storage.ReadRange(m_cache, MyStorageDataTypeFlags.ContentAndMaterial, 0, ref minCorner, ref maxCorner); ProfilerShort.End(); ProfilerShort.Begin("Changing cache"); int removedVoxelContent = 0; Vector3I tempVoxelCoord; Vector3I cachePos; for (tempVoxelCoord.Z = minCorner.Z, cachePos.Z = 0; tempVoxelCoord.Z <= maxCorner.Z; tempVoxelCoord.Z++, ++cachePos.Z) { for (tempVoxelCoord.Y = minCorner.Y, cachePos.Y = 0; tempVoxelCoord.Y <= maxCorner.Y; tempVoxelCoord.Y++, ++cachePos.Y) { for (tempVoxelCoord.X = minCorner.X, cachePos.X = 0; tempVoxelCoord.X <= maxCorner.X; tempVoxelCoord.X++, ++cachePos.X) { Vector3D voxelPosition; MyVoxelCoordSystems.VoxelCoordToWorldPosition(voxelMap.PositionLeftBottomCorner, ref tempVoxelCoord, out voxelPosition); float addDist = (float)(voxelPosition - sphere.Center).Length(); float addDiff = (float)(addDist - sphere.Radius); byte newContent; if (addDiff > MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF) { newContent = MyVoxelConstants.VOXEL_CONTENT_EMPTY; } else if (addDiff < -MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF) { newContent = MyVoxelConstants.VOXEL_CONTENT_FULL; } else { // This formula will work even if diff is positive or negative newContent = (byte)(MyVoxelConstants.VOXEL_ISO_LEVEL - addDiff / MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * MyVoxelConstants.VOXEL_ISO_LEVEL); } byte originalContent = m_cache.Content(ref cachePos); if (newContent > originalContent && originalContent > 0) { if (material != null) { m_cache.Material(ref cachePos, material.Index); } changed = true; m_cache.Content(ref cachePos, newContent); } float delDist = (float)(voxelPosition - (sphere.Center + (float)sphere.Radius * 0.7f * normal)).Length(); float delDiff = (float)(delDist - sphere.Radius); byte contentToRemove; if (delDiff > MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF) { contentToRemove = MyVoxelConstants.VOXEL_CONTENT_EMPTY; } else if (delDiff < -MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF) { contentToRemove = MyVoxelConstants.VOXEL_CONTENT_FULL; } else { // This formula will work even if diff is positive or negative contentToRemove = (byte)(MyVoxelConstants.VOXEL_ISO_LEVEL - delDiff / MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * MyVoxelConstants.VOXEL_ISO_LEVEL); } originalContent = m_cache.Content(ref cachePos); if (originalContent > MyVoxelConstants.VOXEL_CONTENT_EMPTY && contentToRemove > MyVoxelConstants.VOXEL_CONTENT_EMPTY) { changed = true; int newVal = originalContent - contentToRemove; if (newVal < MyVoxelConstants.VOXEL_CONTENT_EMPTY) { newVal = MyVoxelConstants.VOXEL_CONTENT_EMPTY; } m_cache.Content(ref cachePos, (byte)newVal); removedVoxelContent += originalContent - newVal; } float setDist = (float)(voxelPosition - (sphere.Center - (float)sphere.Radius * 0.5f * normal)).Length(); float setDiff = (float)(setDist - sphere.Radius / 4f); if (setDiff <= MyVoxelConstants.VOXEL_SIZE_IN_METRES * 1.5f) // could be VOXEL_SIZE_IN_METRES_HALF, but we want to set material in empty cells correctly { byte indestructibleContentToSet = MyVoxelConstants.VOXEL_CONTENT_FULL; if (setDiff >= MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF) // outside { indestructibleContentToSet = MyVoxelConstants.VOXEL_CONTENT_EMPTY; } else if (setDiff >= -MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF) // boundary { indestructibleContentToSet = (byte)(MyVoxelConstants.VOXEL_ISO_LEVEL - setDiff / MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * MyVoxelConstants.VOXEL_ISO_LEVEL); } MyVoxelMaterialDefinition originalMaterial = MyDefinitionManager.Static.GetVoxelMaterialDefinition(m_cache.Material(ref cachePos)); // Change the material: // - always on boundaries between material and nothing // - smoothly on inner boundaries MyVoxelMaterialDefinition newMaterial = material; if (setDiff > 0) { byte content = m_cache.Content(ref cachePos); if (content == MyVoxelConstants.VOXEL_CONTENT_FULL) { newMaterial = originalMaterial; } if (setDiff >= MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF && content != MyVoxelConstants.VOXEL_CONTENT_EMPTY) // set material behind boundary only for empty voxels { newMaterial = originalMaterial; } } if (originalMaterial == newMaterial) { continue; } m_cache.Material(ref cachePos, newMaterial.Index); changed = true; } float dist = (float)(voxelPosition - sphere.Center).Length(); float diff = (float)(dist - sphere.Radius); if (diff <= 0f) { originalContent = m_cache.Content(ref cachePos); if (originalContent > MyVoxelConstants.VOXEL_CONTENT_EMPTY) { bool wrinkled = m_cache.WrinkleVoxelContent(ref cachePos, MyVoxelConstants.DEFAULT_WRINKLE_WEIGHT_ADD, MyVoxelConstants.DEFAULT_WRINKLE_WEIGHT_REMOVE); if (wrinkled) { changed = true; } } } } } } ProfilerShort.End(); if (changed) { ProfilerShort.Begin("RemoveSmallVoxelsUsingChachedVoxels"); RemoveSmallVoxelsUsingChachedVoxels(); ProfilerShort.BeginNextBlock("Writing cache"); voxelMap.Storage.WriteRange(m_cache, MyStorageDataTypeFlags.ContentAndMaterial, ref minCorner, ref maxCorner); ProfilerShort.End(); } ProfilerShort.End(); }
protected void RefreshCache( ) { IMyVoxelMap voxelMap = (IMyVoxelMap)BackingObject; m_cache = new MyStorageData( ); Vector3I size = voxelMap.Storage.Size; m_cache.Resize( size ); // SandboxGameAssemblyWrapper.Instance.GameAction(() => // { voxelMap.Storage.ReadRange( m_cache, MyStorageDataTypeFlags.Material, 0, Vector3I.Zero, size - 1 ); //voxelMap.Storage.ReadRange(m_cache, MyStorageDataTypeFlags.Material, Vector3I.Zero, size - 1); // }); foreach ( byte materialIndex in m_cache.Data ) { try { MyVoxelMaterialDefinition material = MyDefinitionManager.Static.GetVoxelMaterialDefinition( materialIndex ); if ( material == null ) continue; if ( !m_materialTotals.ContainsKey( material ) ) m_materialTotals.Add( material, 1 ); else m_materialTotals[ material ]++; } catch ( Exception ex ) { ApplicationLog.BaseLog.Error( ex ); } } }