void SwapSimulatedDatas() { var temp = m_finishedData; m_finishedData = m_simulatedData; m_simulatedData = temp; }
private void AddNeighbours(GridSimulationData simData) { using (Stats.Timing.Measure("SI - AddNeighbours", VRage.Stats.MyStatTypeEnum.Sum | VRage.Stats.MyStatTypeEnum.DontDisappearFlag)) { foreach (var node in simData.All) { foreach (var offset in Offsets) { Node neighbour; if (simData.All.TryGetValue(node.Value.Pos + offset, out neighbour)) { node.Value.Neighbours.Add(neighbour); } } } } }
private void FindAndCaculateFromAdvancedStatic(GridSimulationData simData) { // Instead of using uniform distribution of support between all fixed nodes, calculate non-uniform distribution based on vectors for few closest nodes // Use this distribution when setting support weight and transferring mass // SupportingWeights: x * support // ? TransferMass: x * numStaticBlocksForCurrentDynamicBlock * TransferMass int keepLookingDistance = (int)ClosestDistanceThreshold; // How far keep looking when closest static block is found simData.Queue.Clear(); // Set initial distance to max for all dynamic foreach (var dyn in simData.DynamicBlocks) { dyn.Distance = int.MaxValue; } // Wide search from all static blocks foreach (var stat in simData.StaticBlocks) { stat.Distance = 0; var path = new PathInfo() { EndNode = stat, StartNode = stat, Distance = 0, DirectionRatio = 1 }; #if ENHANCED_DEBUG path.PathNodes.Add(stat); #endif simData.Queue.Enqueue(path); } while (simData.Queue.Count > 0) { var path = simData.Queue.Dequeue(); foreach (var neighbour in path.EndNode.Neighbours) { if (neighbour.IsStatic) { continue; } PathInfo neighbourPath; if (!neighbour.Paths.TryGetValue(path.StartNode, out neighbourPath)) { if ((path.Distance - keepLookingDistance) <= neighbour.Distance) { neighbour.Distance = Math.Min(neighbour.Distance, path.Distance); neighbourPath = new PathInfo(); neighbourPath.Distance = path.Distance + 1; neighbourPath.StartNode = path.StartNode; neighbourPath.EndNode = neighbour; #if ENHANCED_DEBUG neighbourPath.PathNodes = path.PathNodes.ToList(); neighbourPath.PathNodes.Add(neighbour); #endif neighbourPath.Parents.Add(path); float t = neighbour.PhysicalMaterial.HorisontalTransmissionMultiplier * path.EndNode.PhysicalMaterial.HorisontalTransmissionMultiplier; float massRatio = MathHelper.Clamp(path.EndNode.Mass / (neighbour.Mass + path.EndNode.Mass), 0, 1); t *= neighbour.Mass * massRatio; //Horisontal transmission is very low on weak objects (floor, roof). Should be correctly get from mount point area float[] horisontalTransmission = new float[] { t, 1, t }; int component = ((Vector3D)(neighbour.Pos - path.EndNode.Pos)).AbsMaxComponent(); neighbourPath.DirectionRatio = path.DirectionRatio * DirectionRatios[component] * horisontalTransmission[component]; neighbour.Paths.Add(path.StartNode, neighbourPath); simData.Queue.Enqueue(neighbourPath); path.StartNode.OwnedPaths.Push(neighbourPath); } } else if (neighbourPath.Distance == path.Distance + 1) // Another path with same length { neighbourPath.Parents.Add(path); } } } // Iterate all dynamic blocks and calculate support ratio for each static foreach (var dyn in simData.DynamicBlocks) { dyn.PathCount = 1; if (dyn.Pos == new Vector3I(-6, 6, 0)) { } // Uniform distribution //foreach (var s in dyn.Paths) //{ // s.Value.Ratio = 1.0f / dyn.Paths.Count; //} //continue; // Non-uniform distribution // Calculate angle between one vector and all other // Split weight support based on sum angle ratio float totalAngles = 0; if (dyn.Paths.Count > 1) { foreach (var s in dyn.Paths) { Vector3 localVector1 = (dyn.Pos - s.Value.StartNode.Pos) * m_grid.GridSize; Vector3 worldVector1 = Vector3.TransformNormal(localVector1, m_grid.WorldMatrix); // float sumAngle = 0; float sumAngleReduced = 0; foreach (var s2 in dyn.Paths) { if (s.Key == s2.Key) { continue; } Vector3 localVector2 = (dyn.Pos - s2.Value.StartNode.Pos) * m_grid.GridSize; Vector3 worldVector2 = Vector3.TransformNormal(localVector2, m_grid.WorldMatrix); float angle = MyUtils.GetAngleBetweenVectorsAndNormalise(worldVector1, worldVector2); float dot1 = Math.Abs(Vector3.Normalize(worldVector1).Dot(Vector3.Up)); float dot2 = Math.Abs(Vector3.Normalize(worldVector2).Dot(Vector3.Up)); float lowerBound = 0.1f; dot1 = MathHelper.Lerp(lowerBound, 1, dot1); dot2 = MathHelper.Lerp(lowerBound, 1, dot2); float reducedAngle = angle; if (!MyPetaInputComponent.OLD_SI) { //Reduce dependent on gravity reducedAngle = angle * dot1 * s.Value.DirectionRatio; } //sumAngle += angle; sumAngleReduced += reducedAngle; } s.Value.Ratio = sumAngleReduced; totalAngles += sumAngleReduced; } foreach (var s in dyn.Paths) { if (totalAngles > 0) { s.Value.Ratio /= totalAngles; if (s.Value.Ratio < 0.000001f) { s.Value.Ratio = 0; } } else { s.Value.Ratio = 1; } } } else { foreach (var s in dyn.Paths) { s.Value.Ratio = 1.0f; } } } // Iterate all static blocks and calculate support mass and mass transfer foreach (var staticBlock in simData.StaticBlocks) { // Initial mass and ratio foreach (var path in staticBlock.OwnedPaths) { path.EndNode.TransferMass = 0; } // For each block in path (ordered by distance, furthest first) while (staticBlock.OwnedPaths.Count > 0) { var pathInfo = staticBlock.OwnedPaths.Pop(); var node = pathInfo.EndNode; Debug.Assert(pathInfo.StartNode == staticBlock, "Wrong path"); Debug.Assert(!node.IsStatic, "Static node unexpected"); float outgoing = node.TransferMass + node.Mass * pathInfo.Ratio; //float outgoindTotal = 0; //foreach (var p in pathInfo.Parents) // outgoindTotal += p.DirectionRatio; if (node.Pos == new Vector3I(-1, 1, 0)) { } float outgoingPerParent = outgoing / pathInfo.Parents.Count; foreach (var parent in pathInfo.Parents) { var delta = parent.EndNode.Pos - node.Pos; // Node to parent int index, parentIndex; if (delta.X + delta.Y + delta.Z > 0) { index = delta.Y + delta.Z * 2; // UnitX = 0, UnitY = 1, UnitZ = 2 parentIndex = index + 3; } else { index = -delta.X * 3 - delta.Y * 4 - delta.Z * 5; // // -UnitX = 3, -UnitY = 4, -UnitZ = 5 parentIndex = index - 3; } //outgoingPerParent = outgoing * parent.DirectionRatio / outgoindTotal; #if ENHANCED_DEBUG node.OutgoingNodeswWithWeights[index].Add(new Tuple <Node, float>(parent.EndNode, outgoingPerParent)); #endif if (index == 0 || index == 2 || index == 3 || index == 5) { node.SupportingWeights[index] -= node.PhysicalMaterial.HorisontalFragility * outgoingPerParent; } else { node.SupportingWeights[index] -= outgoingPerParent; } if (parentIndex == 0 || parentIndex == 2 || parentIndex == 3 || parentIndex == 5) { parent.EndNode.SupportingWeights[parentIndex] += parent.EndNode.PhysicalMaterial.HorisontalFragility * outgoingPerParent; } else { parent.EndNode.SupportingWeights[parentIndex] += outgoingPerParent; } #if ENHANCED_DEBUG parent.EndNode.SupportingNodeswWithWeights[parentIndex].Add(new Tuple <Node, float>(node, outgoingPerParent)); #endif parent.EndNode.TransferMass += outgoingPerParent; } node.TransferMass -= outgoing; } } using (Stats.Timing.Measure("SI - Sum", VRage.Stats.MyStatTypeEnum.Sum | VRage.Stats.MyStatTypeEnum.DontDisappearFlag)) { foreach (var node in simData.All) { //node.Value.TotalSupportingWeight = 0; } foreach (var node in simData.All) { if (node.Key == new Vector3I(-1, 1, 0)) { } float sum = 0; for (int i = 0; i < 6; i++) { float sideWeight = node.Value.SupportingWeights[i]; sum += Math.Abs(sideWeight); //sum = Math.Max(sum, Math.Abs(node.Value.SupportingWeights[i])); } if (!(sum == 0 && node.Value.PathCount == 0)) { // sum = sum * 2 - 1; node.Value.TotalSupportingWeight += node.Value.IsStatic ? 0 : (sum * 0.5f / node.Value.PathCount); } } // Idea behind blur: // When block is supporting too much weight, it deforms still supports something, but allows neighbour block to support more weight, thus sharing support List <Node> supportingNeighbours = new List <Node>(); foreach (var node in simData.All) { supportingNeighbours.Clear(); float totalSharedSupport = node.Value.TotalSupportingWeight; float totalMass = node.Value.Mass; foreach (var neighbour in node.Value.Neighbours) { bool isHorisontalNeighbour = neighbour.Pos.Y == node.Key.Y; bool isVerticallySupported = neighbour.Paths.Any(x => (x.Key.Pos.X == node.Key.X && x.Key.Pos.Z == node.Key.Z)); if (isHorisontalNeighbour && isVerticallySupported) { totalSharedSupport += neighbour.TotalSupportingWeight; totalMass += neighbour.Mass; supportingNeighbours.Add(neighbour); } } if (supportingNeighbours.Count > 0) { float supportPerNode = totalSharedSupport / totalMass; foreach (var neighbour in supportingNeighbours) { neighbour.TotalSupportingWeight = supportPerNode * neighbour.Mass; } node.Value.TotalSupportingWeight = supportPerNode * node.Value.Mass; } } foreach (var node in simData.All) { simData.TotalMax = Math.Max(simData.TotalMax, node.Value.TotalSupportingWeight); } // var timeMs = (Stopwatch.GetTimestamp() - ts) / (float)Stopwatch.Frequency * 1000.0f; //Console.WriteLine(String.Format("Generated structural integrity, time: {0}ms, object name: {1}", timeMs, m_grid.ToString())); } }
private void LoadBlocks(GridSimulationData simData) { simData.BlockCount = m_grid.GetBlocks().Count; simData.All.Clear(); simData.DynamicBlocks.Clear(); simData.StaticBlocks.Clear(); using (Stats.Timing.Measure("SI - Collect", VRage.Stats.MyStatTypeEnum.Sum | VRage.Stats.MyStatTypeEnum.DontDisappearFlag)) { // Store blocks foreach (var block in m_grid.GetBlocks()) { if (simData.All.ContainsKey(block.Position)) { Debug.Fail("Same blocks in grid!"); continue; } bool isStatic = m_grid.Physics.Shape.BlocksConnectedToWorld.Contains(block.Position); if (isStatic) { var n = new Node(block.Position, true); n.PhysicalMaterial = block.BlockDefinition.PhysicalMaterial; simData.StaticBlocks.Add(n); simData.All.Add(block.Position, n); } else { float mass = m_grid.Physics.Shape.GetBlockMass(block.Position); var cubeMass = MassToSI(mass); var physicalMaterial = block.BlockDefinition.PhysicalMaterial; if (block.FatBlock is MyCompoundCubeBlock) { var compBlock = block.FatBlock as MyCompoundCubeBlock; physicalMaterial = compBlock.GetBlocks().First().BlockDefinition.PhysicalMaterial; bool isGenerated = true; foreach (var b in compBlock.GetBlocks()) { if (!b.BlockDefinition.IsGeneratedBlock) { isGenerated = false; } else if (b.BlockDefinition.IsGeneratedBlock && b.BlockDefinition.PhysicalMaterial.Id.SubtypeName == "Stone") { isGenerated = false; } } //we dont want to simulate these pieces.. if (isGenerated) { continue; } } var node = new Node(block.Position, false); node.Mass = cubeMass; node.PhysicalMaterial = physicalMaterial; simData.DynamicBlocks.Add(node); simData.All.Add(block.Position, node); } } foreach (var block in simData.DynamicWeights) { if (simData.All.ContainsKey(block.Key)) { simData.All[block.Key].Mass += block.Value; } else { var node = new Node(block.Key, false); node.Mass = simData.DynamicWeights[block.Key]; node.IsDynamicWeight = true; simData.DynamicBlocks.Add(node); simData.All.Add(block.Key, node); } } } m_grid.Physics.ContactPointCallback -= Physics_ContactPointCallback; m_grid.Physics.ContactPointCallback += Physics_ContactPointCallback; AddNeighbours(simData); }
private void FindAndCaculateFromAdvancedStatic(GridSimulationData simData) { // Instead of using uniform distribution of support between all fixed nodes, calculate non-uniform distribution based on vectors for few closest nodes // Use this distribution when setting support weight and transferring mass // SupportingWeights: x * support // ? TransferMass: x * numStaticBlocksForCurrentDynamicBlock * TransferMass int keepLookingDistance = (int)ClosestDistanceThreshold; // How far keep looking when closest static block is found simData.Queue.Clear(); // Set initial distance to max for all dynamic foreach (var dyn in simData.DynamicBlocks) { dyn.Distance = int.MaxValue; } // Wide search from all static blocks foreach (var stat in simData.StaticBlocks) { stat.Distance = 0; var path = new PathInfo() { EndNode = stat, StartNode = stat, Distance = 0, DirectionRatio = 1 }; #if ENHANCED_DEBUG path.PathNodes.Add(stat); #endif simData.Queue.Enqueue(path); } while (simData.Queue.Count > 0) { var path = simData.Queue.Dequeue(); foreach (var neighbour in path.EndNode.Neighbours) { if (neighbour.IsStatic) continue; PathInfo neighbourPath; if (!neighbour.Paths.TryGetValue(path.StartNode, out neighbourPath)) { if ((path.Distance - keepLookingDistance) <= neighbour.Distance) { neighbour.Distance = Math.Min(neighbour.Distance, path.Distance); neighbourPath = new PathInfo(); neighbourPath.Distance = path.Distance + 1; neighbourPath.StartNode = path.StartNode; neighbourPath.EndNode = neighbour; #if ENHANCED_DEBUG neighbourPath.PathNodes = path.PathNodes.ToList(); neighbourPath.PathNodes.Add(neighbour); #endif neighbourPath.Parents.Add(path); float t = neighbour.PhysicalMaterial.HorisontalTransmissionMultiplier * path.EndNode.PhysicalMaterial.HorisontalTransmissionMultiplier; float massRatio = MathHelper.Clamp(path.EndNode.Mass / (neighbour.Mass + path.EndNode.Mass), 0, 1); t *= neighbour.Mass * massRatio; //Horisontal transmission is very low on weak objects (floor, roof). Should be correctly get from mount point area float[] horisontalTransmission = new float[] { t, 1, t }; int component = ((Vector3D)(neighbour.Pos - path.EndNode.Pos)).AbsMaxComponent(); neighbourPath.DirectionRatio = path.DirectionRatio * DirectionRatios[component] * horisontalTransmission[component]; neighbour.Paths.Add(path.StartNode, neighbourPath); simData.Queue.Enqueue(neighbourPath); path.StartNode.OwnedPaths.Push(neighbourPath); } } else if (neighbourPath.Distance == path.Distance + 1) // Another path with same length { neighbourPath.Parents.Add(path); } } } // Iterate all dynamic blocks and calculate support ratio for each static foreach (var dyn in simData.DynamicBlocks) { dyn.PathCount = 1; if (dyn.Pos == new Vector3I(-6, 6, 0)) { } // Uniform distribution //foreach (var s in dyn.Paths) //{ // s.Value.Ratio = 1.0f / dyn.Paths.Count; //} //continue; // Non-uniform distribution // Calculate angle between one vector and all other // Split weight support based on sum angle ratio float totalAngles = 0; if (dyn.Paths.Count > 1) { foreach (var s in dyn.Paths) { Vector3 localVector1 = (dyn.Pos - s.Value.StartNode.Pos) * m_grid.GridSize; Vector3 worldVector1 = Vector3.TransformNormal(localVector1, m_grid.WorldMatrix); // float sumAngle = 0; float sumAngleReduced = 0; foreach (var s2 in dyn.Paths) { if (s.Key == s2.Key) { continue; } Vector3 localVector2 = (dyn.Pos - s2.Value.StartNode.Pos) * m_grid.GridSize; Vector3 worldVector2 = Vector3.TransformNormal(localVector2, m_grid.WorldMatrix); float angle = MyUtils.GetAngleBetweenVectorsAndNormalise(worldVector1, worldVector2); float dot1 = Math.Abs(Vector3.Normalize(worldVector1).Dot(Vector3.Up)); float dot2 = Math.Abs(Vector3.Normalize(worldVector2).Dot(Vector3.Up)); float lowerBound = 0.1f; dot1 = MathHelper.Lerp(lowerBound, 1, dot1); dot2 = MathHelper.Lerp(lowerBound, 1, dot2); float reducedAngle = angle; if (!MyPetaInputComponent.OLD_SI) { //Reduce dependent on gravity reducedAngle = angle * dot1 * s.Value.DirectionRatio; } //sumAngle += angle; sumAngleReduced += reducedAngle; } s.Value.Ratio = sumAngleReduced; totalAngles += sumAngleReduced; } foreach (var s in dyn.Paths) { if (totalAngles > 0) { s.Value.Ratio /= totalAngles; if (s.Value.Ratio < 0.000001f) s.Value.Ratio = 0; } else s.Value.Ratio = 1; } } else { foreach (var s in dyn.Paths) { s.Value.Ratio = 1.0f; } } } // Iterate all static blocks and calculate support mass and mass transfer foreach (var staticBlock in simData.StaticBlocks) { // Initial mass and ratio foreach (var path in staticBlock.OwnedPaths) { path.EndNode.TransferMass = 0; } // For each block in path (ordered by distance, furthest first) while (staticBlock.OwnedPaths.Count > 0) { var pathInfo = staticBlock.OwnedPaths.Pop(); var node = pathInfo.EndNode; Debug.Assert(pathInfo.StartNode == staticBlock, "Wrong path"); Debug.Assert(!node.IsStatic, "Static node unexpected"); float outgoing = node.TransferMass + node.Mass * pathInfo.Ratio; //float outgoindTotal = 0; //foreach (var p in pathInfo.Parents) // outgoindTotal += p.DirectionRatio; if (node.Pos == new Vector3I(-1, 1, 0)) { } float outgoingPerParent = outgoing / pathInfo.Parents.Count; foreach (var parent in pathInfo.Parents) { var delta = parent.EndNode.Pos - node.Pos; // Node to parent int index, parentIndex; if (delta.X + delta.Y + delta.Z > 0) { index = delta.Y + delta.Z * 2; // UnitX = 0, UnitY = 1, UnitZ = 2 parentIndex = index + 3; } else { index = -delta.X * 3 - delta.Y * 4 - delta.Z * 5; // // -UnitX = 3, -UnitY = 4, -UnitZ = 5 parentIndex = index - 3; } //outgoingPerParent = outgoing * parent.DirectionRatio / outgoindTotal; #if ENHANCED_DEBUG node.OutgoingNodeswWithWeights[index].Add(new Tuple<Node, float>(parent.EndNode, outgoingPerParent)); #endif if (index == 0 || index == 2 || index == 3 || index == 5) { node.SupportingWeights[index] -= node.PhysicalMaterial.HorisontalFragility * outgoingPerParent; } else node.SupportingWeights[index] -= outgoingPerParent; if (parentIndex == 0 || parentIndex == 2 || parentIndex == 3 || parentIndex == 5) { parent.EndNode.SupportingWeights[parentIndex] += parent.EndNode.PhysicalMaterial.HorisontalFragility * outgoingPerParent; } else parent.EndNode.SupportingWeights[parentIndex] += outgoingPerParent; #if ENHANCED_DEBUG parent.EndNode.SupportingNodeswWithWeights[parentIndex].Add(new Tuple<Node, float>(node, outgoingPerParent)); #endif parent.EndNode.TransferMass += outgoingPerParent; } node.TransferMass -= outgoing; } } using (Stats.Timing.Measure("SI - Sum", VRage.Stats.MyStatTypeEnum.Sum | VRage.Stats.MyStatTypeEnum.DontDisappearFlag)) { foreach (var node in simData.All) { //node.Value.TotalSupportingWeight = 0; } foreach (var node in simData.All) { if (node.Key == new Vector3I(-1, 1, 0)) { } float sum = 0; for (int i = 0; i < 6; i++) { float sideWeight = node.Value.SupportingWeights[i]; sum += Math.Abs(sideWeight); //sum = Math.Max(sum, Math.Abs(node.Value.SupportingWeights[i])); } if (!(sum == 0 && node.Value.PathCount == 0)) { // sum = sum * 2 - 1; node.Value.TotalSupportingWeight += node.Value.IsStatic ? 0 : (sum * 0.5f / node.Value.PathCount); } } // Idea behind blur: // When block is supporting too much weight, it deforms still supports something, but allows neighbour block to support more weight, thus sharing support List<Node> supportingNeighbours = new List<Node>(); foreach (var node in simData.All) { supportingNeighbours.Clear(); float totalSharedSupport = node.Value.TotalSupportingWeight; float totalMass = node.Value.Mass; foreach (var neighbour in node.Value.Neighbours) { bool isHorisontalNeighbour = neighbour.Pos.Y == node.Key.Y; bool isVerticallySupported = neighbour.Paths.Any(x => (x.Key.Pos.X == node.Key.X && x.Key.Pos.Z == node.Key.Z)); if (isHorisontalNeighbour && isVerticallySupported) { totalSharedSupport += neighbour.TotalSupportingWeight; totalMass += neighbour.Mass; supportingNeighbours.Add(neighbour); } } if (supportingNeighbours.Count > 0) { float supportPerNode = totalSharedSupport / totalMass; foreach (var neighbour in supportingNeighbours) { neighbour.TotalSupportingWeight = supportPerNode * neighbour.Mass; } node.Value.TotalSupportingWeight = supportPerNode * node.Value.Mass; } } foreach (var node in simData.All) { simData.TotalMax = Math.Max(simData.TotalMax, node.Value.TotalSupportingWeight); } // var timeMs = (Stopwatch.GetTimestamp() - ts) / (float)Stopwatch.Frequency * 1000.0f; //Console.WriteLine(String.Format("Generated structural integrity, time: {0}ms, object name: {1}", timeMs, m_grid.ToString())); } }
private void AddNeighbours(GridSimulationData simData) { using (Stats.Timing.Measure("SI - AddNeighbours", VRage.Stats.MyStatTypeEnum.Sum | VRage.Stats.MyStatTypeEnum.DontDisappearFlag)) { foreach (var node in simData.All) { foreach (var offset in Offsets) { Node neighbour; if (simData.All.TryGetValue(node.Value.Pos + offset, out neighbour)) { node.Value.Neighbours.Add(neighbour); } } } } }
private void LoadBlocks(GridSimulationData simData) { simData.BlockCount = m_grid.GetBlocks().Count; simData.All.Clear(); simData.DynamicBlocks.Clear(); simData.StaticBlocks.Clear(); using (Stats.Timing.Measure("SI - Collect", VRage.Stats.MyStatTypeEnum.Sum | VRage.Stats.MyStatTypeEnum.DontDisappearFlag)) { // Store blocks foreach (var block in m_grid.GetBlocks()) { if (simData.All.ContainsKey(block.Position)) { Debug.Fail("Same blocks in grid!"); continue; } bool isStatic = m_grid.Physics.Shape.BlocksConnectedToWorld.Contains(block.Position); if (isStatic) { var n = new Node(block.Position, true); n.PhysicalMaterial = block.BlockDefinition.PhysicalMaterial; simData.StaticBlocks.Add(n); simData.All.Add(block.Position, n); } else { float mass = m_grid.Physics.Shape.GetBlockMass(block.Position); var cubeMass = MassToSI(mass); var physicalMaterial = block.BlockDefinition.PhysicalMaterial; if (block.FatBlock is MyCompoundCubeBlock) { var compBlock = block.FatBlock as MyCompoundCubeBlock; physicalMaterial = compBlock.GetBlocks().First().BlockDefinition.PhysicalMaterial; bool isGenerated = true; foreach (var b in compBlock.GetBlocks()) { if (!b.BlockDefinition.IsGeneratedBlock) isGenerated = false; else if (b.BlockDefinition.IsGeneratedBlock && b.BlockDefinition.PhysicalMaterial.Id.SubtypeName == "Stone") isGenerated = false; else if (b.BlockDefinition.IsGeneratedBlock && b.BlockDefinition.PhysicalMaterial.Id.SubtypeName == "RoofTile" && compBlock.GetBlocks().Count == 1) { isGenerated = false; cubeMass *= 6f; } } //we dont want to simulate these pieces.. if (isGenerated) continue; } var node = new Node(block.Position, false); node.Mass = cubeMass; node.PhysicalMaterial = physicalMaterial; simData.DynamicBlocks.Add(node); simData.All.Add(block.Position, node); } } foreach (var block in simData.DynamicWeights) { if (simData.All.ContainsKey(block.Key)) { simData.All[block.Key].Mass += block.Value; } else { var node = new Node(block.Key, false); node.Mass = simData.DynamicWeights[block.Key]; node.IsDynamicWeight = true; simData.DynamicBlocks.Add(node); simData.All.Add(block.Key, node); } } } m_grid.Physics.ContactPointCallback -= Physics_ContactPointCallback; m_grid.Physics.ContactPointCallback += Physics_ContactPointCallback; AddNeighbours(simData); }
void SwapSimulatedDatas() { var temp = m_finishedData; m_finishedData = m_simulatedData; m_simulatedData = temp; }
private void LoadBlocks(GridSimulationData simData) { simData.BlockCount = m_grid.GetBlocks().Count; simData.All.Clear(); simData.DynamicBlocks.Clear(); simData.StaticBlocks.Clear(); using (Stats.Timing.Measure("SI - Collect", VRage.Stats.MyStatTypeEnum.Sum | VRage.Stats.MyStatTypeEnum.DontDisappearFlag)) { // Store blocks foreach (var block in m_grid.GetBlocks()) { if (simData.All.ContainsKey(block.Position)) { Debug.Fail("Same blocks in grid!"); continue; } bool isStatic = m_grid.Physics.Shape.BlocksConnectedToWorld.Contains(block.Position); if (isStatic) { var n = new Node(block.Position, true); n.PhysicalMaterial = block.BlockDefinition.PhysicalMaterial; simData.StaticBlocks.Add(n); simData.All.Add(block.Position, n); } else { float mass = m_grid.Physics.Shape.GetBlockMass(block.Position); var cubeMass = MassToSI(mass); var physicalMaterial = block.BlockDefinition.PhysicalMaterial; if (block.FatBlock is MyCompoundCubeBlock) { var compBlock = block.FatBlock as MyCompoundCubeBlock; physicalMaterial = compBlock.GetBlocks().First().BlockDefinition.PhysicalMaterial; //Simulate blocks where or pieces are generated bool allAreGenerated = true; foreach (var b in compBlock.GetBlocks()) { if (!b.BlockDefinition.IsGeneratedBlock) { allAreGenerated = false; break; } } bool isGenerated = true; foreach (var b in compBlock.GetBlocks()) { if (!b.BlockDefinition.IsGeneratedBlock) { isGenerated = false; break; } else if (b.BlockDefinition.IsGeneratedBlock && b.BlockDefinition.PhysicalMaterial.Id.SubtypeName == "Stone") { isGenerated = false; break; } else if (b.BlockDefinition.IsGeneratedBlock && b.BlockDefinition.PhysicalMaterial.Id.SubtypeName == "RoofTile" && allAreGenerated) { isGenerated = false; cubeMass *= 6f; break; } else if (b.BlockDefinition.IsGeneratedBlock && b.BlockDefinition.PhysicalMaterial.Id.SubtypeName == "RoofWood" && allAreGenerated) { isGenerated = false; cubeMass *= 3f; break; } else if (b.BlockDefinition.IsGeneratedBlock && b.BlockDefinition.PhysicalMaterial.Id.SubtypeName == "RoofHay" && allAreGenerated) { isGenerated = false; cubeMass *= 1.2f; break; } else { } } //we dont want to simulate these pieces.. if (isGenerated) { continue; } } Vector3I pos = block.Min; float volumeRecip = 1.0f / block.BlockDefinition.Size.Size; for (var it = new Vector3I_RangeIterator(ref block.Min, ref block.Max); it.IsValid(); it.GetNext(out pos)) { var node = new Node(pos, false); node.Mass = cubeMass * volumeRecip; node.PhysicalMaterial = physicalMaterial; simData.DynamicBlocks.Add(node); simData.All.Add(pos, node); } } } foreach (var block in simData.DynamicWeights) { if (simData.All.ContainsKey(block.Key)) { simData.All[block.Key].Mass += block.Value; } else { var node = new Node(block.Key, false); node.Mass = simData.DynamicWeights[block.Key]; node.IsDynamicWeight = true; simData.DynamicBlocks.Add(node); simData.All.Add(block.Key, node); } } } m_grid.Physics.ContactPointCallback -= Physics_ContactPointCallback; m_grid.Physics.ContactPointCallback += Physics_ContactPointCallback; AddNeighbours(simData); }
private void LoadBlocks(GridSimulationData simData) { simData.BlockCount = m_grid.GetBlocks().Count; simData.All.Clear(); simData.DynamicBlocks.Clear(); simData.StaticBlocks.Clear(); using (Stats.Timing.Measure("SI - Collect", VRage.Stats.MyStatTypeEnum.Sum | VRage.Stats.MyStatTypeEnum.DontDisappearFlag)) { // Store blocks foreach (var block in m_grid.GetBlocks()) { if (simData.All.ContainsKey(block.Position)) { Debug.Fail("Same blocks in grid!"); continue; } bool isStatic = m_grid.Physics.Shape.BlocksConnectedToWorld.Contains(block.Position); if (isStatic) { var n = new Node(block.Position, true); n.PhysicalMaterial = block.BlockDefinition.PhysicalMaterial; simData.StaticBlocks.Add(n); simData.All.Add(block.Position, n); } else { float mass = m_grid.Physics.Shape.GetBlockMass(block.Position); var cubeMass = MassToSI(mass); var physicalMaterial = block.BlockDefinition.PhysicalMaterial; if (block.FatBlock is MyCompoundCubeBlock) { var compBlock = block.FatBlock as MyCompoundCubeBlock; physicalMaterial = compBlock.GetBlocks().First().BlockDefinition.PhysicalMaterial; //Simulate blocks where or pieces are generated bool allAreGenerated = true; foreach (var b in compBlock.GetBlocks()) { if (!b.BlockDefinition.IsGeneratedBlock) { allAreGenerated = false; break; } } bool isGenerated = true; foreach (var b in compBlock.GetBlocks()) { if (!b.BlockDefinition.IsGeneratedBlock) { isGenerated = false; break; } else if (b.BlockDefinition.IsGeneratedBlock && b.BlockDefinition.PhysicalMaterial.Id.SubtypeName == "Stone") { isGenerated = false; break; } else if (b.BlockDefinition.IsGeneratedBlock && b.BlockDefinition.PhysicalMaterial.Id.SubtypeName == "RoofTile" && allAreGenerated) { isGenerated = false; cubeMass *= 6f; break; } else if (b.BlockDefinition.IsGeneratedBlock && b.BlockDefinition.PhysicalMaterial.Id.SubtypeName == "RoofWood" && allAreGenerated) { isGenerated = false; cubeMass *= 3f; break; } else if (b.BlockDefinition.IsGeneratedBlock && b.BlockDefinition.PhysicalMaterial.Id.SubtypeName == "RoofHay" && allAreGenerated) { isGenerated = false; cubeMass *= 1.2f; break; } else { } } //we dont want to simulate these pieces.. if (isGenerated) continue; } Vector3I pos = block.Min; float volumeRecip = 1.0f / block.BlockDefinition.Size.Size; for (var it = new Vector3I_RangeIterator(ref block.Min, ref block.Max); it.IsValid(); it.GetNext(out pos)) { var node = new Node(pos, false); node.Mass = cubeMass * volumeRecip; node.PhysicalMaterial = physicalMaterial; simData.DynamicBlocks.Add(node); simData.All.Add(pos, node); } } } foreach (var block in simData.DynamicWeights) { if (simData.All.ContainsKey(block.Key)) { simData.All[block.Key].Mass += block.Value; } else { var node = new Node(block.Key, false); node.Mass = simData.DynamicWeights[block.Key]; node.IsDynamicWeight = true; simData.DynamicBlocks.Add(node); simData.All.Add(block.Key, node); } } } m_grid.Physics.ContactPointCallback -= Physics_ContactPointCallback; m_grid.Physics.ContactPointCallback += Physics_ContactPointCallback; AddNeighbours(simData); }