Пример #1
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);
            }
        }
Пример #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);
        }