private void SimulateBuoyancy(FluidVolume fluidVolume) { Bounds bounds = buoyancyCollider.bounds; bounds.Expand(boundsExtentBias); float tangentOffset = bounds.size.x / (float)samples; float bitangentOffset = bounds.size.z / (float)samples; float impulse = -Physics.gravity.y * Time.fixedDeltaTime; if (useWeighting) { impulse *= (weightFactor + weightFactorBias) * rigidbody.mass * inverseVolume; } else { impulse *= fluidVolume.density; } Vector3 min = new Vector3(bounds.min.x, fluidVolume.collider.bounds.min.y, bounds.min.z); for (int x = 0; x < samples; x++) { for (int z = 0; z < samples; z++) { Vector3 offset = new Vector3(tangentOffset * ((float)x + 0.5f), 0.0f, bitangentOffset * ((float)z + 0.5f)); Vector3 start = min + offset; ApplySampleImpulse(start, tangentOffset, bitangentOffset, fluidVolume.RelativeHeightAtPoint(start), impulse); } } }
public Quadrant(QuadrantId quadrantId) { myResources = new QuadrantResource[(int)RelativeQuadrantLocation.NUM_RELATIVE_QUADRANT_LOCATIONS]; myQuadrantId = quadrantId; // Initialise the Quadrant Resources that are also Receptacles for (RelativeQuadrantLocation location = RelativeQuadrantLocation.START_LOCATION; location < RelativeQuadrantLocation.NUM_RELATIVE_QUADRANT_LOCATIONS; ++location) { // Assume the QuadrantReceptacleCapacityTable is not in any particular order. // In other words, search the table for the relevant QuadrantLocation details. for (int entryIndex = 0; entryIndex < theQuadrantReceptacleCapacityTable.GetLength(0); ++entryIndex) { if (location == theQuadrantReceptacleCapacityTable[entryIndex].aLocation) { double amount = theQuadrantReceptacleCapacityTable[entryIndex].aCapacity; FluidVolumeUnit unit = theQuadrantReceptacleCapacityTable[entryIndex].aVolumeUnit; FluidVolume capacity = new FluidVolume(amount, unit); myResources[(int)location] = new Receptacle(capacity); break; // Proceed with the next 'location' } } } // Initialise the Quadrant Resources that are not Receptacles myResources[(int)RelativeQuadrantLocation.TipsBox] = new QuadrantResource(); //Set the initial state of the quadrant Clear(false); }
public void AtReportInstrumentConfiguration(FluidVolume bccmDeadVolume) { if (ReportInstrumentConfiguration != null) { ReportInstrumentConfiguration(bccmDeadVolume); } }
/// <summary> /// Creates a New Instance of the Base Ship Class /// </summary> /// <param name="AssetPath"></param> public vxWaterEntity(vxEngine Engine, Vector3 StartPosition, Vector3 WaterScale) : base(Engine, Engine.Assets.Models.WaterPlane, StartPosition) { Engine.Current3DSceneBase.waterItems.Add(this); waterBumpMap = vxEngine.Assets.Textures.Texture_WaterWaves; waterDistortionMap = vxEngine.Assets.Textures.Texture_WaterDistort; //Render even in debug mode RenderEvenInDebug = true; this.WaterScale = WaterScale; WrknPlane = new Plane(0, 1, 0, StartPosition.Y); Position = StartPosition; World = Matrix.CreateScale(WaterScale); World *= Matrix.CreateTranslation(Position); //Set up Scale Cubes scPosition = new vxScaleCube(vxEngine, StartPosition); scPosition.Moved += ScPosition_Moved; scLeft = new vxScaleCube(vxEngine, StartPosition + Vector3.Backward * WaterScale.Z); scLeft.Moved += Sc_Moved; scRight = new vxScaleCube(vxEngine, StartPosition - Vector3.Backward * WaterScale.Z); scRight.Moved += Sc_Moved; scForward = new vxScaleCube(vxEngine, StartPosition + Vector3.Right * WaterScale.X); scForward.Moved += Sc_Moved; scBack = new vxScaleCube(vxEngine, StartPosition - Vector3.Right * WaterScale.X); scBack.Moved += Sc_Moved; // //Physics Body // var tris = new List <Vector3[]>(); //Remember, the triangles composing the surface need to be coplanar with the surface. In this case, this means they have the same height. tris.Add(new[] { new Vector3(Position.X - WaterScale.X, Position.Y, Position.Z - WaterScale.Z), new Vector3(Position.X + WaterScale.X, Position.Y, Position.Z - WaterScale.Z), new Vector3(Position.X - WaterScale.X, Position.Y, Position.Z + WaterScale.Z), }); tris.Add(new[] { new Vector3(Position.X - WaterScale.X, Position.Y, Position.Z + WaterScale.Z), new Vector3(Position.X + WaterScale.X, Position.Y, Position.Z - WaterScale.Z), new Vector3(Position.X + WaterScale.X, Position.Y, Position.Z + WaterScale.Z), }); fluidVolume = new FluidVolume(Vector3.Up, -9.81f, tris, WaterScale.Y, density, 0.9f, .4f); Current3DScene.BEPUPhyicsSpace.Add(fluidVolume); }
/// <summary> /// Constructs a new static physics actor. /// </summary> /// <param name="desc">Descriptor for the actor.</param> public WaterVolumeBEPUActor(ActorDesc desc) : base(desc) { if (desc.Shapes.Count != 1) { throw new Exception("Water volume actors can only consist of one shape"); } ShapeDesc shapeDesc = desc.Shapes[0]; if (shapeDesc is BoxShapeDesc) { var boxDesc = shapeDesc as BoxShapeDesc; this.volumeExtents = boxDesc.Extents; var tris = new List <Vector3[]>(); float basinWidth = boxDesc.Extents.X; float basinLength = boxDesc.Extents.Z; float waterHeight = desc.Position.Y; this.position = desc.Position; //Remember, the triangles composing the surface need to be coplanar with the surface. In this case, this means they have the same height. tris.Add(new[] { desc.Position, new Vector3(basinWidth, 0, 0) + desc.Position, new Vector3(0, 0, basinLength) + desc.Position }); tris.Add(new[] { new Vector3(0, 0, basinLength) + desc.Position, new Vector3(basinWidth, 0, 0) + desc.Position, new Vector3(basinWidth, 0, basinLength) + desc.Position }); var msgGetScene = ObjectPool.Aquire <MsgGetPhysicsScene>(); this.game.SendInterfaceMessage(msgGetScene, Interfaces.InterfaceType.Physics); this.fluidVolume = new FluidVolume(Vector3.Up, msgGetScene.PhysicsScene.Gravity.Y, tris, waterHeight, 1.0f, 0.8f, 0.7f, msgGetScene.PhysicsScene.PhysicsSpace.BroadPhase.QueryAccelerator, msgGetScene.PhysicsScene.PhysicsSpace.ThreadManager); } else { throw new Exception("Shape description for a Terrain actor must be HeightFieldShapeDesc."); } // Tag the physics with data needed by the engine var tag = new EntityTag(this.ownerEntityID); this.fluidVolume.Tag = tag; this.spaceObject = this.fluidVolume; }
void ResetScaleCubes() { if (scLeft.SelectionState != vxEnumSelectionState.Selected) { scLeft.Position = this.Position + Vector3.Backward * WaterScale.Z; } if (scRight.SelectionState != vxEnumSelectionState.Selected) { scRight.Position = this.Position - Vector3.Backward * WaterScale.Z; } if (scForward.SelectionState != vxEnumSelectionState.Selected) { scForward.Position = this.Position + Vector3.Right * WaterScale.X; } if (scBack.SelectionState != vxEnumSelectionState.Selected) { scBack.Position = this.Position - Vector3.Right * WaterScale.X; } // //Reset the Physics Body // Current3DScene.BEPUPhyicsSpace.Remove(fluidVolume); var tris = new List <Vector3[]>(); //Remember, the triangles composing the surface need to be coplanar with the surface. In this case, this means they have the same height. tris.Add(new[] { new Vector3(Position.X - WaterScale.X, Position.Y, Position.Z - WaterScale.Z), new Vector3(Position.X + WaterScale.X, Position.Y, Position.Z - WaterScale.Z), new Vector3(Position.X - WaterScale.X, Position.Y, Position.Z + WaterScale.Z), }); tris.Add(new[] { new Vector3(Position.X - WaterScale.X, Position.Y, Position.Z + WaterScale.Z), new Vector3(Position.X + WaterScale.X, Position.Y, Position.Z - WaterScale.Z), new Vector3(Position.X + WaterScale.X, Position.Y, Position.Z + WaterScale.Z), }); fluidVolume = new FluidVolume(Vector3.Up, -9.81f, tris, WaterScale.Y, density, 0.9f, .4f); Current3DScene.BEPUPhyicsSpace.Add(fluidVolume); }
/// <summary> /// Constructs a new demo. /// </summary> /// <param name="game">Game owning this demo.</param> public BuoyancyDemo(DemosGame game) : base(game) { var tris = new List <Vector3[]>(); Fix64 basinWidth = 100; Fix64 basinLength = 100; Fix64 basinHeight = 16; Fix64 waterHeight = 15; //Remember, the triangles composing the surface need to be coplanar with the surface. In this case, this means they have the same height. tris.Add(new[] { new Vector3(-basinWidth / 2, waterHeight, -basinLength / 2), new Vector3(basinWidth / 2, waterHeight, -basinLength / 2), new Vector3(-basinWidth / 2, waterHeight, basinLength / 2) }); tris.Add(new[] { new Vector3(-basinWidth / 2, waterHeight, basinLength / 2), new Vector3(basinWidth / 2, waterHeight, -basinLength / 2), new Vector3(basinWidth / 2, waterHeight, basinLength / 2) }); var fluid = new FluidVolume(Vector3.Up, -9.81m, tris, waterHeight, .8m, .8m, .7m); Space.ForceUpdater.Gravity = new Vector3(0, -9.81m, 0); //fluid.FlowDirection = Vector3.Right; //fluid.FlowForce = 80; //fluid.MaxFlowSpeed = 50; Space.Add(fluid); game.ModelDrawer.Add(fluid); //Create the container. Space.Add(new Box(new Vector3(0, 0, 0), basinWidth, 1, basinLength)); Space.Add(new Box(new Vector3(-basinWidth / 2 - .5m, basinHeight / 2 - .5m, 0), 1, basinHeight, basinLength)); Space.Add(new Box(new Vector3(basinWidth / 2 + .5m, basinHeight / 2 - .5m, 0), 1, basinHeight, basinLength)); Space.Add(new Box(new Vector3(0, basinHeight / 2 - .5m, -basinLength / 2 - .5m), basinWidth + 2, basinHeight, 1)); Space.Add(new Box(new Vector3(0, basinHeight / 2 - .5m, basinLength / 2 + .5m), basinWidth + 2, basinHeight, 1)); //Create a tiled floor. Entity toAdd; Fix64 boxWidth = 10; int numBoxesWide = 8; for (int i = 0; i < numBoxesWide; i++) { for (int k = 0; k < numBoxesWide; k++) { toAdd = new Box(new Vector3( -boxWidth * numBoxesWide / 2 + (boxWidth + .1m) * i, 15, -boxWidth * numBoxesWide / 2 + (boxWidth + .1m) * k), boxWidth, 5, boxWidth, 300); Space.Add(toAdd); } } //Create a bunch o' spheres and dump them into the water. //Random random = new Random(); //for (int k = 0; k < 80; k++) //{ // var toAddSphere = new Sphere(new Vector3(-48 + k * 1f, 12 + 4 * k, random.Next(-15, 15)), 2, 27); // Space.Add(toAddSphere); //} game.Camera.Position = new Vector3(0, waterHeight + 5, 35); }
private void SimulateBuoyancy(FluidVolume fluidVolume) { Bounds bounds = buoyancyCollider.bounds; bounds.Expand(boundsExtentBias); Vector3 min = new Vector3(bounds.min.x, fluidVolume.collider.bounds.min.y, bounds.min.z); float tangentOffset = bounds.size.x / (float)samples; float bitangentOffset = bounds.size.z / (float)samples; float impulse = -Physics.gravity.y * Time.fixedDeltaTime; if (useWeighting) { impulse *= (weightFactor + weightFactorBias) * rigidbody.mass * inverseVolume; } else { impulse *= fluidVolume.density; } bool submerged = false; bool completelySubmerged = true; for (int x = 0; x < samples; x++) { for (int z = 0; z < samples; z++) { Vector3 offset = new Vector3(tangentOffset * ((float)x + 0.5f), 0.0f, bitangentOffset * ((float)z + 0.5f)); Vector3 start = min + offset; float height = fluidVolume.RelativeHeightAtPoint(start); RaycastHit lowerHit; if (buoyancyCollider.Raycast(new Ray(start, Vector3.up), out lowerHit, height)) { submerged = true; float fluidBoxHeight = lowerHit.distance; RaycastHit upperHit; if (buoyancyCollider.Raycast(new Ray(start + Vector3.up * height, Vector3.down), out upperHit, height)) { fluidBoxHeight += upperHit.distance; } else { completelySubmerged = false; } float sampleBoxHeight = height - fluidBoxHeight; float sampleVolume = sampleBoxHeight * tangentOffset * bitangentOffset; rigidbody.AddForceAtPosition(Vector3.up * (sampleVolume * impulse), lowerHit.point, ForceMode.Impulse); } } } if (!submerged) { completelySubmerged = false; } if (submerged) { totalDrag += dragScalar * fluidVolume.rigidbodyDrag; totalAngularDrag += angularDragScalar * fluidVolume.rigidbodyAngularDrag; totalSubmerged = true; if (completelySubmerged) { totalCompletelySubmerged = true; } } }
public FluidVolumeMessage(FluidVolume fluidVolume, Collider collider) { this.fluidVolume = fluidVolume; this.collider = collider; }
public Receptacle(FluidVolume capacity) { myFluidCapacity = capacity; }
public void TestFluidVolume() { FluidVolume fluidVolume = new FluidVolume(2000.0, FluidVolumeUnit.MicroLitres); }
/// <summary> /// Constructs a new demo. /// </summary> /// <param name="game">Game owning this demo.</param> public BuoyancyDemo(DemosGame game) : base(game) { var tris = new List <Vector3[]>(); float basinWidth = 100; float basinLength = 100; float basinHeight = 16; float waterHeight = 15; //Remember, the triangles composing the surface need to be coplanar with the surface. In this case, this means they have the same height. tris.Add(new[] { new Vector3(-basinWidth / 2, waterHeight, -basinLength / 2), new Vector3(basinWidth / 2, waterHeight, -basinLength / 2), new Vector3(-basinWidth / 2, waterHeight, basinLength / 2) }); tris.Add(new[] { new Vector3(-basinWidth / 2, waterHeight, basinLength / 2), new Vector3(basinWidth / 2, waterHeight, -basinLength / 2), new Vector3(basinWidth / 2, waterHeight, basinLength / 2) }); var fluid = new FluidVolume(Vector3.Up, -9.81f, tris, waterHeight, .8f, .8f, .7f, Space.BroadPhase.QueryAccelerator, Space.ThreadManager); //fluid.flowDirection = Vector3.Right; //fluid.flowForce = 80; //fluid.maxFlowSpeed = 50; Space.Add(fluid); game.ModelDrawer.Add(fluid); //Create the container. Space.Add(new Box(new Vector3(0, 0, 0), basinWidth, 1, basinLength)); Space.Add(new Box(new Vector3(-basinWidth / 2 - .5f, basinHeight / 2 - .5f, 0), 1, basinHeight, basinLength)); Space.Add(new Box(new Vector3(basinWidth / 2 + .5f, basinHeight / 2 - .5f, 0), 1, basinHeight, basinLength)); Space.Add(new Box(new Vector3(0, basinHeight / 2 - .5f, -basinLength / 2 - .5f), basinWidth + 2, basinHeight, 1)); Space.Add(new Box(new Vector3(0, basinHeight / 2 - .5f, basinLength / 2 + .5f), basinWidth + 2, basinHeight, 1)); var random = new Random(); //Create a bunch of random blocks. /*for (int k = 0; k < 1; k++) * { * toAddBox = new Box(new Vector3(random.Next((int)basinWidth) - basinWidth / 2f, 30 + (.1f) * k, random.Next((int)basinLength) - basinLength / 2f), 2, 4, 2, 12); * toAddBox.CollisionMargin = .2f; * toAddBox.AllowedPenetration = .1f; * toAddBox.Orientation = Quaternion.Normalize(new Quaternion((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble())); * space.Add(toAddBox); * }*/ //Create a tiled floor. Entity toAdd; float boxWidth = 10; int numBoxesWide = 8; for (int i = 0; i < numBoxesWide; i++) { for (int k = 0; k < numBoxesWide; k++) { toAdd = new Box(new Vector3( -boxWidth * numBoxesWide / 2f + (boxWidth + .1f) * i, 15, -boxWidth * numBoxesWide / 2f + (boxWidth + .1f) * k), boxWidth, 5, boxWidth, 300); Space.Add(toAdd); } } //Create a bunch o' spheres and dump them into the water. /*for (int k = 0; k < 80; k++) * { * toAddSphere = new Sphere(new Vector3(-48 + k * 1f, 12 + 4 * k, (float)random.Next(-15, 15)), 2, 27); * space.Add(toAddSphere); * }*/ game.Camera.Position = new Microsoft.Xna.Framework.Vector3(0, waterHeight + 5, 35); }