private Vector3 PressureDragForce(WaterTriangle triangle) { var velocity = triangle.Velocity.magnitude; velocity = velocity / _optionsController.PressureOptions.ReferenceSpeed; var pressureDragForce = new Vector3(); if (triangle.CosTheta > 0f) { var pressureCoefficient1 = _optionsController.PressureOptions.PressureCoefficient1; var pressureCoefficient2 = _optionsController.PressureOptions.PressureCoefficient2; var pressureFalloff = _optionsController.PressureOptions.PressureFalloff; pressureDragForce = -(pressureCoefficient1 * velocity + pressureCoefficient2 * (velocity * velocity)) * triangle.Area * Mathf.Pow(triangle.CosTheta, pressureFalloff) * _transform.TransformVector(triangle.Normal); } else { var suctionCoefficient1 = _optionsController.PressureOptions.SuctionCoefficient1; var suctionCoefficient2 = _optionsController.PressureOptions.SuctionCoefficient2; var suctionFalloff = _optionsController.PressureOptions.SuctionFalloff; pressureDragForce = (suctionCoefficient1 * velocity + suctionCoefficient2 * (velocity * velocity)) * triangle.Area * Mathf.Pow(Mathf.Abs(triangle.CosTheta), suctionFalloff) * _transform.TransformVector(triangle.Normal); } if (_optionsController.PressureDebugEnabled) { Debug.DrawRay(_transform.TransformPoint(triangle.Center), pressureDragForce * _optionsController.DebugUIScale, Color.magenta); } return(pressureDragForce); }
private Vector3 BouancyForce(WaterTriangle triangle) { var forceVector = RhoWater * Physics.gravity.y * -triangle.DepthAtCenter * triangle.Area * _transform.TransformVector(triangle.Normal); forceVector.x = forceVector.z = 0f; if (_optionsController.BounancyDebugEnabled) { var color = forceVector.y > 0 ? Color.green : Color.red; Debug.DrawRay(_transform.TransformPoint(triangle.Center), forceVector * _optionsController.DebugUIScale, color); } return(forceVector); }
private Vector3 ViscousWaterResistanceForce(WaterTriangle triangle, float resistanceCoefficient) { var normal = _transform.TransformVector(triangle.Normal); var velocity = triangle.Velocity; var velocityTangent = Vector3.Cross(normal, Vector3.Cross(velocity, normal) / normal.magnitude) / normal.magnitude; var tangentialDirection = velocityTangent.normalized * -1f; var tangentialVelocity = triangle.Velocity.magnitude * tangentialDirection; var viscousWaterResistanceForce = 0.5f * RhoWater * tangentialVelocity.magnitude * tangentialVelocity * triangle.Area * resistanceCoefficient; if (_optionsController.ViscosityDebugEnabled) { Debug.DrawRay(_transform.TransformPoint(triangle.Center), velocity * _optionsController.DebugUIScale, Color.blue); Debug.DrawRay(_transform.TransformPoint(triangle.Center), normal * _optionsController.DebugUIScale, Color.white); Debug.DrawRay(_transform.TransformPoint(triangle.Center), tangentialDirection * _optionsController.DebugUIScale, Color.black); Debug.DrawRay(_transform.TransformPoint(triangle.Center), tangentialVelocity * _optionsController.DebugUIScale, Color.gray); Debug.DrawRay(_transform.TransformPoint(triangle.Center), viscousWaterResistanceForce * _optionsController.DebugUIScale, Color.red); } return(viscousWaterResistanceForce); }
private void AnalyzeTriangle(int originalMeshIndex, Vector3 pointA, Vector3 pointB, Vector3 pointC) { var center = (pointA + pointB + pointC) / 3f; //Area of the triangle var a = Vector3.Distance(pointA, pointB); var c = Vector3.Distance(pointC, pointA); var area = a * c * Mathf.Sin(Vector3.Angle(pointB - pointA, pointC - pointA) * Mathf.Deg2Rad) / 2f; var triangle = new WaterTriangle { Vertices = new[] { pointA, pointB, pointC }, Center = center, DepthAtCenter = _boatTrans.TransformPoint(center).y, Normal = Vector3.Cross(pointB - pointA, pointC - pointA).normalized, Area = area, OriginalMeshIndex = originalMeshIndex }; UnderwaterTriangles.Add(triangle); _slammingForces[originalMeshIndex].SubmergedArea += triangle.Area; }
private void CalculateTriangleVelocity(WaterTriangle triangle) { triangle.Velocity = _rigidbody.GetRelativePointVelocity(_transform.TransformVector(triangle.Center)); triangle.CosTheta = Vector3.Dot(triangle.Velocity.normalized, _transform.TransformVector(triangle.Normal)); }
private Vector3 SlammingForce(SlammingForce slammingData, WaterTriangle triangle, 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 (triangle.CosTheta < 0f || slammingData.OriginalArea <= 0f) { return(Vector3.zero); } var deltaTime = Time.fixedDeltaTime; //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 * deltaTime); //The magnitude of the acceleration float acc = accVec.magnitude; //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 * triangle.Velocity * (2f * triangle.Area / boatArea); //float p = DebugPhysics.current.p; //float acc_max = DebugPhysics.current.acc_max; float p = _optionsController.SlammingOptions.RampingPower; float acc_max = (dV / (slammingData.OriginalArea * deltaTime)).magnitude; float slammingCheat = _optionsController.SlammingOptions.SlammingCheat; Vector3 slammingForce = Mathf.Pow(Mathf.Clamp01(acc / acc_max), p) * triangle.CosTheta * F_stop * slammingCheat; //Vector3 slammingForce = F_stop; //The force acts in the opposite direction slammingForce *= -1f; //slammingForce = CheckForceIsValid(slammingForce, "Slamming"); if (_optionsController.SlammingDebugEnabled) { Debug.DrawRay(_transform.TransformPoint(triangle.Center), slammingForce * _optionsController.DebugUIScale, Color.yellow); } return(slammingForce); }