Beispiel #1
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, 0);

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


                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 #2
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);
    }
Beispiel #3
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 = 475; //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);
            }
        }
Beispiel #4
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 #5
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 #6
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 #7
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);
    }