コード例 #1
0
        //Calculate the area of each triangle in the boat mesh and store them in an array
        private void CalculateOriginalTrianglesArea()
        {
            //Loop through all the triangles (3 vertices at a time = 1 triangle)
            int i = 0;
            int triangleCounter = 0;

            while (i < boatTriangles.Length)
            {
                Vector3 p1 = boatVertices[boatTriangles[i]];

                i++;

                Vector3 p2 = boatVertices[boatTriangles[i]];

                i++;

                Vector3 p3 = boatVertices[boatTriangles[i]];

                i++;

                //Calculate the area of the triangle
                float triangleArea = BoatPhysicsMath.GetTriangleArea(p1, p2, p3);

                //Store the area in a list
                slammingForceData[triangleCounter].originalArea = triangleArea;

                //The total area
                boatArea += triangleArea;

                triangleCounter += 1;
            }
        }
コード例 #2
0
ファイル: TriangleData.cs プロジェクト: sfq24/LegendSailer
        public TriangleData(Vector3 p1, Vector3 p2, Vector3 p3, Rigidbody boatRB, float timeSinceStart)
        {
            this.p1 = p1;
            this.p2 = p2;
            this.p3 = p3;

            //Center of the triangle
            this.center = (p1 + p2 + p3) / 3f;

            //Distance to the surface from the center of the triangle
            this.distanceToSurface = Mathf.Abs(WaterController.current.DistanceToWater(this.center, timeSinceStart));

            //Normal to the triangle
            this.normal = Vector3.Cross(p2 - p1, p3 - p1).normalized;

            //Area of the triangle
            this.area = BoatPhysicsMath.GetTriangleArea(p1, p2, p3);

            //Velocity vector of the triangle at the center
            this.velocity = BoatPhysicsMath.GetTriangleVelocity(boatRB, this.center);

            //Velocity direction
            this.velocityDir = this.velocity.normalized;

            //Angle between the normal and the velocity
            //Negative if pointing in the opposite direction
            //Positive if pointing in the same direction
            this.cosTheta = Vector3.Dot(this.velocityDir, this.normal);
        }
コード例 #3
0
ファイル: BoatPhysics.cs プロジェクト: sfq24/LegendSailer
        //Calculate the current velocity at the center of each triangle of the original boat mesh
        private void CalculateSlammingVelocities(List <SlammingForceData> slammingForceData)
        {
            for (int i = 0; i < slammingForceData.Count; i++)
            {
                //Set the new velocity to the old velocity
                slammingForceData[i].previousVelocity = slammingForceData[i].velocity;

                //Center of the triangle in world space
                Vector3 center = transform.TransformPoint(slammingForceData[i].triangleCenter);

                //Get the current velocity at the center of the triangle
                slammingForceData[i].velocity = BoatPhysicsMath.GetTriangleVelocity(boatRB, center);
            }
        }
コード例 #4
0
ファイル: BoatPhysics.cs プロジェクト: sfq24/LegendSailer
        //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, boatDrag);

                //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);
            }
        }
コード例 #5
0
ファイル: BoatPhysics.cs プロジェクト: sfq24/LegendSailer
        //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 = boatRB.mass; //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);
            }
        }
コード例 #6
0
        //Build the new triangles where two of the old vertices are above the water
        private void AddTrianglesTwoAboveWater(List <VertexData> vertexData, int triangleCounter)
        {
            //H and M are above the water
            //H is after the vertice that's below water, which is L
            //So we know which one is L because it is last in the sorted list
            Vector3 L = vertexData[2].globalVertexPos;

            //Find the index of H
            int H_index = vertexData[2].index + 1;

            if (H_index > 2)
            {
                H_index = 0;
            }


            //We also need the heights to water
            float h_L = vertexData[2].distance;
            float h_H = 0f;
            float h_M = 0f;

            Vector3 H = Vector3.zero;
            Vector3 M = Vector3.zero;

            //This means that H is at position 1 in the list
            if (vertexData[1].index == H_index)
            {
                H = vertexData[1].globalVertexPos;
                M = vertexData[0].globalVertexPos;

                h_H = vertexData[1].distance;
                h_M = vertexData[0].distance;
            }
            else
            {
                H = vertexData[0].globalVertexPos;
                M = vertexData[1].globalVertexPos;

                h_H = vertexData[0].distance;
                h_M = vertexData[1].distance;
            }


            //Now we can find where to cut the triangle

            //Point J_M
            Vector3 LM = M - L;

            float t_M = -h_L / (h_M - h_L);

            Vector3 LJ_M = t_M * LM;

            Vector3 J_M = LJ_M + L;


            //Point J_H
            Vector3 LH = H - L;

            float t_H = -h_L / (h_H - h_L);

            Vector3 LJ_H = t_H * LH;

            Vector3 J_H = LJ_H + L;


            //Save the data, such as normal, area, etc
            //1 triangle above the water
            underWaterTriangleData.Add(new TriangleData(L, J_H, J_M, boatRB, timeSinceStart));
            //2 triangles below the water
            aboveWaterTriangleData.Add(new TriangleData(J_H, H, J_M, boatRB, timeSinceStart));
            aboveWaterTriangleData.Add(new TriangleData(J_M, H, M, boatRB, timeSinceStart));

            //Calculate the submerged area
            slammingForceData[triangleCounter].submergedArea = BoatPhysicsMath.GetTriangleArea(L, J_H, J_M);

            indexOfOriginalTriangle.Add(triangleCounter);
        }
コード例 #7
0
        //Build the new triangles where one of the old vertices is above the water
        private void AddTrianglesOneAboveWater(List <VertexData> vertexData, int triangleCounter)
        {
            //H is always at position 0
            Vector3 H = vertexData[0].globalVertexPos;

            //Left of H is M
            //Right of H is L

            //Find the index of M
            int M_index = vertexData[0].index - 1;

            if (M_index < 0)
            {
                M_index = 2;
            }

            //We also need the heights to water
            float h_H = vertexData[0].distance;
            float h_M = 0f;
            float h_L = 0f;

            Vector3 M = Vector3.zero;
            Vector3 L = Vector3.zero;

            //This means M is at position 1 in the List
            if (vertexData[1].index == M_index)
            {
                M = vertexData[1].globalVertexPos;
                L = vertexData[2].globalVertexPos;

                h_M = vertexData[1].distance;
                h_L = vertexData[2].distance;
            }
            else
            {
                M = vertexData[2].globalVertexPos;
                L = vertexData[1].globalVertexPos;

                h_M = vertexData[2].distance;
                h_L = vertexData[1].distance;
            }


            //Now we can calculate where we should cut the triangle to form 2 new triangles
            //because the resulting area will always form a square

            //Point I_M
            Vector3 MH = H - M;

            float t_M = -h_M / (h_H - h_M);

            Vector3 MI_M = t_M * MH;

            Vector3 I_M = MI_M + M;


            //Point I_L
            Vector3 LH = H - L;

            float t_L = -h_L / (h_H - h_L);

            Vector3 LI_L = t_L * LH;

            Vector3 I_L = LI_L + L;


            //Save the data, such as normal, area, etc
            //2 triangles below the water
            underWaterTriangleData.Add(new TriangleData(M, I_M, I_L, boatRB, timeSinceStart));
            underWaterTriangleData.Add(new TriangleData(M, I_L, L, boatRB, timeSinceStart));
            //1 triangle above the water
            aboveWaterTriangleData.Add(new TriangleData(I_M, H, I_L, boatRB, timeSinceStart));

            //Calculate the total submerged area
            float totalArea = BoatPhysicsMath.GetTriangleArea(M, I_M, I_L) + BoatPhysicsMath.GetTriangleArea(M, I_L, L);

            slammingForceData[triangleCounter].submergedArea = totalArea;

            indexOfOriginalTriangle.Add(triangleCounter);
            //Add 2 times because 2 submerged triangles need to connect to the same original triangle
            indexOfOriginalTriangle.Add(triangleCounter);
        }