Beispiel #1
0
        //Force 2 - Pressure Drag Force
        public static Vector3 PressureDragForce(TriangleData triangleData)
        {
            //Modify for different turning behavior and planing forces
            //f_p and f_S - falloff power, should be smaller than 1
            //C - coefficients to modify

            float velocity = triangleData.velocity.magnitude;

            //A reference speed used when modifying the parameters
            float velocityReference = velocity;

            velocity = velocity / velocityReference;

            Vector3 pressureDragForce = Vector3.zero;

            if (triangleData.cosTheta > 0f)
            {
                //float C_PD1 = 10f;
                //float C_PD2 = 10f;
                //float f_P = 0.5f;

                //To change the variables real-time - add the finished values later
                float C_PD1 = DebugPhysics.current.C_PD1;
                float C_PD2 = DebugPhysics.current.C_PD2;
                float f_P   = DebugPhysics.current.f_P;

                pressureDragForce = -(C_PD1 * velocity + C_PD2 * (velocity * velocity)) * triangleData.area * Mathf.Pow(triangleData.cosTheta, f_P) * triangleData.normal;
            }
            else
            {
                //float C_SD1 = 10f;
                //float C_SD2 = 10f;
                //float f_S = 0.5f;

                //To change the variables real-time - add the finished values later
                float C_SD1 = DebugPhysics.current.C_SD1;
                float C_SD2 = DebugPhysics.current.C_SD2;
                float f_S   = DebugPhysics.current.f_S;

                pressureDragForce = (C_SD1 * velocity + C_SD2 * (velocity * velocity)) * triangleData.area * Mathf.Pow(Mathf.Abs(triangleData.cosTheta), f_S) * triangleData.normal;
            }

            pressureDragForce = CheckForceIsValid(pressureDragForce, "Pressure drag");

            return(pressureDragForce);
        }
Beispiel #2
0
        //Add all forces that act on the squares above the water
        void AddAboveWaterForces()
        {
            //Get all triangles
            List <TriangleData> aboveWaterTriangleData = modifyBoatMesh.aboveWaterTriangleData;

            //Loop through all triangles
            for (int i = 0; i < aboveWaterTriangleData.Count; i++)
            {
                TriangleData triangleData = aboveWaterTriangleData[i];


                //Calculate the forces
                Vector3 forceToAdd = Vector3.zero;

                //Force 1 - Air resistance
                //Replace VisbyData.C_r with your boat's drag coefficient
                forceToAdd += BoatPhysicsMath.AirResistanceForce(rhoAir, triangleData, 1f);

                //Add the forces to the boat
                boatRB.AddForceAtPosition(forceToAdd, triangleData.center);


                //Debug

                //The normal
                //Debug.DrawRay(triangleCenter, triangleNormal * 3f, Color.white);

                //The velocity
                //Debug.DrawRay(triangleCenter, triangleVelocityDir * 3f, Color.black);

                if (triangleData.cosTheta > 0f)
                {
                    //Debug.DrawRay(triangleCenter, triangleVelocityDir * 3f, Color.black);
                }

                //Air resistance
                //-3 to show it in the opposite direction to see what's going on
                //Debug.DrawRay(triangleCenter, airResistanceForce.normalized * -3f, Color.blue);
            }
        }
Beispiel #3
0
        //
        // Buoyancy from http://www.gamasutra.com/view/news/237528/Water_interaction_model_for_boats_in_video_games.php
        //

        //The buoyancy force so the boat can float
        public static Vector3 BuoyancyForce(float rho, TriangleData triangleData)
        {
            //Buoyancy is a hydrostatic force - it's there even if the water isn't flowing or if the boat stays still

            // F_buoyancy = rho * g * V
            // rho - density of the mediaum you are in
            // g - gravity
            // V - volume of fluid directly above the curved surface

            // V = z * S * n
            // z - distance to surface
            // S - surface area
            // n - normal to the surface
            Vector3 buoyancyForce = rho * Physics.gravity.y * triangleData.distanceToSurface * triangleData.area * triangleData.normal;

            //The vertical component of the hydrostatic forces don't cancel out but the horizontal do
            buoyancyForce.x = 0f;
            buoyancyForce.z = 0f;

            //Check that the force is valid, such as not NaN to not break the physics model
            buoyancyForce = CheckForceIsValid(buoyancyForce, "Buoyancy");

            return(buoyancyForce);
        }
Beispiel #4
0
        //Force 3 - Air resistance on the part of the ship above the water (typically 4 to 8 percent of total resistance)
        public static Vector3 AirResistanceForce(float rho, TriangleData triangleData, float C_air)
        {
            // R_air = 0.5 * rho * v^2 * A_p * C_air
            // rho - air density
            // v - speed of ship
            // A_p - projected transverse profile area of ship
            // C_r - coefficient of air resistance (drag coefficient)

            //Only add air resistance if normal is pointing in the same direction as the velocity
            if (triangleData.cosTheta < 0f)
            {
                return(Vector3.zero);
            }

            //Find air resistance force
            Vector3 airResistanceForce = 0.5f * rho * triangleData.velocity.magnitude * triangleData.velocity * triangleData.area * C_air;

            //Acting in the opposite side of the velocity
            airResistanceForce *= -1f;

            airResistanceForce = CheckForceIsValid(airResistanceForce, "Air resistance");

            return(airResistanceForce);
        }
Beispiel #5
0
        //
        // Resistance forces from http://www.gamasutra.com/view/news/263237/Water_interaction_model_for_boats_in_video_games_Part_2.php
        //

        //Force 1 - Viscous Water Resistance (Frictional Drag)
        public static Vector3 ViscousWaterResistanceForce(float rho, TriangleData triangleData, float Cf)
        {
            //Viscous resistance occurs when water sticks to the boat's surface and the boat has to drag that water with it

            // F = 0.5 * rho * v^2 * S * Cf
            // rho - density of the medium you have
            // v - speed
            // S - surface area
            // Cf - Coefficient of frictional resistance

            //We need the tangential velocity
            //Projection of the velocity on the plane with the normal normalvec
            //http://www.euclideanspace.com/maths/geometry/elements/plane/lineOnPlane/
            Vector3 B = triangleData.normal;
            Vector3 A = triangleData.velocity;

            Vector3 velocityTangent = Vector3.Cross(B, (Vector3.Cross(A, B) / B.magnitude)) / B.magnitude;

            //The direction of the tangential velocity (-1 to get the flow which is in the opposite direction)
            Vector3 tangentialDirection = velocityTangent.normalized * -1f;

            //Debug.DrawRay(triangleCenter, tangentialDirection * 3f, Color.black);
            //Debug.DrawRay(triangleCenter, velocityVec.normalized * 3f, Color.blue);
            //Debug.DrawRay(triangleCenter, normal * 3f, Color.white);

            //The speed of the triangle as if it was in the tangent's direction
            //So we end up with the same speed as in the center of the triangle but in the direction of the flow
            Vector3 v_f_vec = triangleData.velocity.magnitude * tangentialDirection;

            //The final resistance force
            Vector3 viscousWaterResistanceForce = 0.5f * rho * v_f_vec.magnitude * v_f_vec * triangleData.area * Cf;

            viscousWaterResistanceForce = CheckForceIsValid(viscousWaterResistanceForce, "Viscous Water Resistance");

            return(viscousWaterResistanceForce);
        }
Beispiel #6
0
        //Add all forces that act on the squares below the water
        void AddUnderWaterForces()
        {
            //The resistance coefficient - same for all triangles
            float Cf = BoatPhysicsMath.ResistanceCoefficient(
                rhoWater,
                boatRB.velocity.magnitude,
                modifyBoatMesh.CalculateUnderWaterLength());

            //To calculate the slamming force we need the velocity at each of the original triangles
            List <SlammingForceData> slammingForceData = modifyBoatMesh.slammingForceData;

            CalculateSlammingVelocities(slammingForceData);

            //Need this data for slamming forces
            float boatArea = modifyBoatMesh.boatArea;
            float boatMass = 1f;             //Replace this line with your boat's total mass

            //To connect the submerged triangles with the original triangles
            List <int> indexOfOriginalTriangle = modifyBoatMesh.indexOfOriginalTriangle;

            //Get all triangles
            List <TriangleData> underWaterTriangleData = modifyBoatMesh.underWaterTriangleData;

            for (int i = 0; i < underWaterTriangleData.Count; i++)
            {
                TriangleData triangleData = underWaterTriangleData[i];


                //Calculate the forces
                Vector3 forceToAdd = Vector3.zero;

                //Force 1 - The hydrostatic force (buoyancy)
                forceToAdd += BoatPhysicsMath.BuoyancyForce(rhoWater, triangleData);

                //Force 2 - Viscous Water Resistance
                forceToAdd += BoatPhysicsMath.ViscousWaterResistanceForce(rhoWater, triangleData, Cf);

                //Force 3 - Pressure drag
                forceToAdd += BoatPhysicsMath.PressureDragForce(triangleData);

                //Force 4 - Slamming force
                //Which of the original triangles is this triangle a part of
                int originalTriangleIndex = indexOfOriginalTriangle[i];

                SlammingForceData slammingData = slammingForceData[originalTriangleIndex];

                forceToAdd += BoatPhysicsMath.SlammingForce(slammingData, triangleData, boatArea, boatMass);


                //Add the forces to the boat
                boatRB.AddForceAtPosition(forceToAdd, triangleData.center);


                //Debug

                //Normal
                //Debug.DrawRay(triangleData.center, triangleData.normal * 3f, Color.white);

                //Buoyancy
                //Debug.DrawRay(triangleData.center, BoatPhysicsMath.BuoyancyForce(rhoWater, triangleData).normalized * -3f, Color.blue);

                //Velocity
                //Debug.DrawRay(triangleCenter, triangleVelocityDir * 3f, Color.black);

                //Viscous Water Resistance
                //Debug.DrawRay(triangleCenter, viscousWaterResistanceForce.normalized * 3f, Color.black);
            }
        }
Beispiel #7
0
        //Force 3 - Slamming Force (Water Entry Force)
        public static Vector3 SlammingForce(SlammingForceData slammingData, TriangleData triangleData, float boatArea, float boatMass)
        {
            //To capture the response of the fluid to sudden accelerations or penetrations

            //Add slamming if the normal is in the same direction as the velocity (the triangle is not receding from the water)
            //Also make sure thea area is not 0, which it sometimes is for some reason
            if (triangleData.cosTheta < 0f || slammingData.originalArea <= 0f)
            {
                return(Vector3.zero);
            }


            //Step 1 - Calculate acceleration
            //Volume of water swept per second
            Vector3 dV          = slammingData.submergedArea * slammingData.velocity;
            Vector3 dV_previous = slammingData.previousSubmergedArea * slammingData.previousVelocity;

            //Calculate the acceleration of the center point of the original triangle (not the current underwater triangle)
            //But the triangle the underwater triangle is a part of
            Vector3 accVec = (dV - dV_previous) / (slammingData.originalArea * Time.fixedDeltaTime);

            //The magnitude of the acceleration
            float acc = accVec.magnitude;

            //Debug.Log(slammingForceData.originalArea);

            //Step 2 - Calculate slamming force
            // F = clamp(acc / acc_max, 0, 1)^p * cos(theta) * F_stop
            // p - power to ramp up slamming force - should be 2 or more

            // F_stop = m * v * (2A / S)
            // m - mass of the entire boat
            // v - velocity
            // A - this triangle's area
            // S - total surface area of the entire boat

            Vector3 F_stop = boatMass * triangleData.velocity * ((2f * triangleData.area) / boatArea);

            //float p = DebugPhysics.current.p;

            //float acc_max = DebugPhysics.current.acc_max;

            float p = 2f;

            float acc_max = acc;

            float slammingCheat = DebugPhysics.current.slammingCheat;

            Vector3 slammingForce = Mathf.Pow(Mathf.Clamp01(acc / acc_max), p) * triangleData.cosTheta * F_stop * slammingCheat;

            //Vector3 slammingForce = Vector3.zero;

            //Debug.Log(slammingForce);

            //The force acts in the opposite direction
            slammingForce *= -1f;

            slammingForce = CheckForceIsValid(slammingForce, "Slamming");

            return(slammingForce);
        }