public static Vector3 BuoyancyForce(float densityOfWater, TriangleInfo triangle)
        {
            Vector3 buoyancyForce = densityOfWater * Physics.gravity.y * -1 * triangle.height * triangle.area * triangle.normal;

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

            return(buoyancyForce);
        }
        public static Vector3 PressureDragForce(TriangleInfo triangle, float referenceVelocity, float pdCoefficient1, float pdCoefficient2, float pdFallOffPower, float sdCoefficient1, float sdCoefficient2, float sdFallOffPower)
        {
            float speed  = triangle.velocity.magnitude / referenceVelocity;
            float cosine = triangle.cosine;

            if (cosine > 0)
            {
                return(-1 * (pdCoefficient1 * speed + pdCoefficient2 * speed * speed) * triangle.area * Mathf.Pow(cosine, pdFallOffPower) * triangle.normal);
            }
            else
            {
                return((sdCoefficient1 * speed + sdCoefficient2 * speed * speed) * triangle.area * Mathf.Pow(-cosine, sdFallOffPower) * triangle.normal);
            }
        }
Example #3
0
        private float CuttingAlgorithmHorizontal(VertexInfo top, VertexInfo mid, VertexInfo bottom, int triangleIndex)
        {
            if (top.height - mid.height < epsilon)
            {
                int triangleType = (mid.height - bottom.height < epsilon) ? 2 : 1;

                TriangleInfo triangle;
                if ((top.clockwiseOrder + 1) % 3 == mid.clockwiseOrder)
                {
                    triangle = new TriangleInfo(top, mid, bottom, triangleType, Rigidbody3d, timeStamp);
                }
                else
                {
                    triangle = new TriangleInfo(mid, top, bottom, triangleType, Rigidbody3d, timeStamp);
                }

                TriangleBufferIndices.Add(triangleIndex);
                SubmergedTriangles.Add(triangle);
                return(triangle.area);
            }
            else if (mid.height - bottom.height < epsilon)
            {
                TriangleInfo triangle;
                if ((top.clockwiseOrder + 1) % 3 == mid.clockwiseOrder)
                {
                    triangle = new TriangleInfo(top, mid, bottom, 0, Rigidbody3d, timeStamp);
                }
                else
                {
                    triangle = new TriangleInfo(top, bottom, mid, 0, Rigidbody3d, timeStamp);
                }

                TriangleBufferIndices.Add(triangleIndex);
                SubmergedTriangles.Add(triangle);
                return(triangle.area);
            }

            float      tPointCutTB = (mid.height - bottom.height) / (top.height - bottom.height);
            Vector3    pointCutTB  = bottom.globalVertex + (top.globalVertex - bottom.globalVertex) * tPointCutTB;
            VertexInfo cutTB       = new VertexInfo
            {
                clockwiseOrder = -1, // no more use
                globalVertex   = pointCutTB,
                height         = WaterPatch.instance.DistanceToWater(pointCutTB, timeStamp),
            };

            TriangleInfo upside, downside;

            if ((top.clockwiseOrder + 1) % 3 == mid.clockwiseOrder)
            {
                // downLeft: bottom, downRight: mid
                upside   = new TriangleInfo(top, mid, cutTB, 0, Rigidbody3d, timeStamp);
                downside = new TriangleInfo(cutTB, mid, bottom, 1, Rigidbody3d, timeStamp);
            }
            else
            {
                // downLeft: mid, downRight: bottom
                upside   = new TriangleInfo(top, cutTB, mid, 0, Rigidbody3d, timeStamp);
                downside = new TriangleInfo(mid, cutTB, bottom, 1, Rigidbody3d, timeStamp);
            }

            TriangleBufferIndices.Add(triangleIndex);
            TriangleBufferIndices.Add(triangleIndex);
            SubmergedTriangles.Add(upside);
            SubmergedTriangles.Add(downside);

            return(upside.area + downside.area);
        }
        public static Vector3 ViscousWaterResistance(float densityOfWater, float viscosityCoefficient, TriangleInfo triangle)
        {
            Vector3 velocity           = triangle.velocity;
            Vector3 normal             = triangle.normal;
            Vector3 tangentialVelocity = velocity - Vector3.Dot(velocity, normal) * normal;

            tangentialVelocity *= -1;
            tangentialVelocity.Normalize();

            return(0.5f * densityOfWater * viscosityCoefficient * triangle.area * velocity.magnitude * velocity.magnitude * tangentialVelocity);
        }
        public static Vector3 SlammingForce(TriangleBuffer previousBuffer, TriangleBuffer currentBuffer, TriangleInfo triangle, float maxAcceleration, float rampUpPower, float totalMass, float totalArea)
        {
            if (triangle.cosine < 0f)
            {
                return(Vector3.zero);
            }

            Vector3 currentDeltaVolume  = currentBuffer.submergedArea * currentBuffer.velocity;
            Vector3 previousDeltaVolume = previousBuffer.submergedArea * previousBuffer.velocity;
            Vector3 acceleration        = (currentDeltaVolume - previousDeltaVolume) / (currentBuffer.originalArea * Time.fixedDeltaTime);

            Vector3 stoppingForce    = totalMass * triangle.velocity * (2f * triangle.area / totalArea);
            float   realAcceleration = Mathf.Clamp01(acceleration.magnitude / maxAcceleration);

            return(-1 * Mathf.Pow(realAcceleration, rampUpPower) * triangle.cosine * stoppingForce);
        }
Example #6
0
        private void CalculateForce()
        {
            float zMin = float.MaxValue;
            float zMax = float.MinValue;

            for (int i = 0; i < triangleBuilder.SubmergedTriangles.Count; ++i)
            {
                TriangleInfo triangle = triangleBuilder.SubmergedTriangles[i];
                if (triangle.center.z < zMin)
                {
                    zMin = triangle.center.z;
                }
                if (triangle.center.z > zMax)
                {
                    zMax = triangle.center.z;
                }
            }

            float logRigidbodyVelocity    = Mathf.Log10(Rigidbody3d.velocity.magnitude);
            float travelLengthScaleFactor = Mathf.Log10(zMax - zMin) * 2;

            for (int i = 0; i < triangleBuilder.SubmergedTriangles.Count; ++i)
            {
                TriangleInfo triangle = triangleBuilder.SubmergedTriangles[i];
                if (triangle.height > 0f)
                {
                    continue;
                }

                float lookUpKey            = (triangle.center.z - zMin) / (zMax - zMin);
                float logFluidTravelLength = curveLookUpTable.LookUp(lookUpKey) * travelLengthScaleFactor;
                float viscosityCoefficient = WaterInteractionUtils.CalculateViscosityCoefficient(logRigidbodyVelocity, logFluidTravelLength, logViscosity);

                int TriangleBufferIndex = triangleBuilder.TriangleBufferIndices[i];

                Vector3 buoyancyForce          = WaterInteractionUtils.BuoyancyForce(densityOfWater, triangle);
                Vector3 viscousWaterResistance = WaterInteractionUtils.ViscousWaterResistance(densityOfWater, viscosityCoefficient, triangle);
                Vector3 pressureDragForce      = WaterInteractionUtils.PressureDragForce(triangle, referenceSpeed, pdCoefficient1, pdCoefficient2, pdFallOffPower, sdCoefficient1, sdCoefficient2, sdFallOffPower);
                Vector3 slammingForce          = WaterInteractionUtils.SlammingForce(triangleBuilder.PreviousBuffers[TriangleBufferIndex], triangleBuilder.CurrentBuffers[TriangleBufferIndex], triangle, maxAcceleration, smRampUpPower, Rigidbody3d.mass, TotalArea);

                Vector3 netForce = Vector3.zero;
                if (debugBuoyancyForce)
                {
                    netForce += buoyancyForce;
                }
                if (debugViscousWaterResistance)
                {
                    netForce += viscousWaterResistance;
                }
                if (debugPressureDrag)
                {
                    netForce += pressureDragForce;
                }
                if (debugSlammingForce)
                {
                    netForce += slammingForce;
                }

                Rigidbody3d.AddForceAtPosition(netForce, triangle.center);

                // Debug.DrawRay(triangle.center, slammingForce, Color.white);
                // Debug.DrawRay(triangle.center, triangle.normal, Color.white);
                // Debug.DrawRay(triangle.center, buoyancyForce, Color.blue);
                // Debug.DrawRay(triangle.center, viscousWaterResistance, Color.green);
            }
        }