Example #1
0
    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);
            }
        }
    }
Example #2
0
        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);
        }
Example #5
0
        /// <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);
        }
Example #7
0
        /// <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);
        }
Example #8
0
    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;
            }
        }
    }
Example #9
0
 public FluidVolumeMessage(FluidVolume fluidVolume, Collider collider)
 {
     this.fluidVolume = fluidVolume;
     this.collider = collider;
 }
Example #10
0
    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);
            }
        }
    }
Example #11
0
 public FluidVolumeMessage(FluidVolume fluidVolume, Collider collider)
 {
     this.fluidVolume = fluidVolume;
     this.collider    = collider;
 }
 public Receptacle(FluidVolume capacity)
 {
     myFluidCapacity = capacity;
 }
Example #13
0
 public void TestFluidVolume()
 {
     FluidVolume fluidVolume = new FluidVolume(2000.0, FluidVolumeUnit.MicroLitres);
 }
Example #14
0
        /// <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);
        }