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

        //Celocity 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);
    }
Пример #2
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;
        }
    }
Пример #3
0
    void AddUnderWaterForces()
    {
        float Cf = BoatPhysicsMath.ResistanceCoefficient(
            water,
            boat.velocity.magnitude,
            modifyBoatMesh.CalculateUnderWaterLength());
        List <SlammingForceData> slammingForceData = modifyBoatMesh.slammingForceData;

        CalculateSlammingVelocities(slammingForceData);

        float      boatArea = modifyBoatMesh.boatArea;
        float      boatMass = VisbyData.mass;
        List <int> indexOfOriginalTriangle = modifyBoatMesh.indexOfOriginalTriangle;

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

            vector3 forceToAdd = Vector3.zero;
            forceToAdd += BoatPhysicsMath.BuoyancyForce(water, triangleData);
            forceToAdd += BoatPhysicsMath.ViscousWaterResistanceForce(water, triangleData, Cf);
            forceToAdd += BoatPhysicsMath.PressureDragForce(triangleData);
            int originalTriangleIndex = indexOfOriginalTriangle[i];

            slammingForceData slammingData = slammingForceData[originalTriangleIndex];

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

            boatRB.addForceAtPosition(forceToAdd, triangleData.center);
        }
    }
Пример #4
0
 private void CalculateSlammingVelocities(List <SlammingForceData> slammingForceData)
 {
     for (int i = 0; i < slammingForceData.Count; i++)
     {
         slammingForceData[i].previousVelocity = slammingForceData[i].velocity;
         Vector3 center = transform.TransformPoint(slammingForceData[i].triangleCenter);
         slammingForceData[i].velocity = BoatPhysicsMath.GetTriangleVelocity(boatRB, center);
     }
 }
Пример #5
0
 public TriangleData(Vector3 p1, Vector3 p2, Vector3 p3, Rigidbody boatRB, float timeSinceStart)
 {
     this.p1                = p1;
     this.p2                = p2;
     this.p3                = p3;
     this.center            = (p1 + p2 + p3) / 3f;
     this.distanceToSurface = Mathf.Abs(WaterController.current.DistanceToWater(this.center, timeSinceStart));
     this.normal            = Vector3.Cross(p2 - p1, p3 - p1).normalized;
     this.area              = BoatPhysicsMath.GetTriangleArea(p1, p2, p3);
     this.velocity          = BoatPhysicsMath.GetTriangleVelocity(boatRB, this.center);
     this.velocityDir       = this.velocity.normalized;
     this.cosTheta          = Vector3.Dot(this.velocityDir, this.normal);
 }
Пример #6
0
    void AddAboveWaterForces()
    {
        List <TriangleData> aboveWaterTriangleData = modifyBoatMesh.aboveWaterTriangleData;

        for (int i = 0; i < aboveWaterTriangleData.Count; i++)
        {
            TriangleData triangleData = aboveWaterTriangleData[i];
            Vector3      forceToAdd   = Vector3.zero;

            forceToAdd += BoatPhysicsMath.AirResistanceForce(rhoAir, triangleData, boatRB.drag);
            boatRB.AddForceAtPosition(forceToAdd, triangleData.center);
        }
    }
Пример #7
0
    //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);
        }
    }
Пример #8
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, gameObject.GetComponent <Rigidbody>().drag);

            //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);
        }
    }
Пример #9
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 = gameObject.GetComponent <Rigidbody>().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);
            //Debug.Log(BoatPhysicsMath.SlammingForce(slammingData, triangleData, boatArea, boatMass));

            //Add the forces to the boat
            //Debug.Log("Adding force: " + forceToAdd + " to triangle " + i);
            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, 2f, true);

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

            //Viscous Water Resistance
            //Debug.DrawRay(triangleCenter, viscousWaterResistanceForce.normalized * 3f, Color.black);
        }
    }
Пример #10
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);
    }
Пример #11
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);
    }
Пример #12
0
 //Add wind direction to calculate projected sail size
 void CalculateSailSize()
 {
     Vector3 windDirection = Vector3.left;
     float   test          = BoatPhysicsMath.GetSailSize(sailMesh, windDirection);
 }