public void RemoveGerstnerComponent(ShapeGerstnerBatched gerstner) { if (OceanRenderer.Instance == null) { // Ocean has unloaded, clear out _gerstnerComponents.Clear(); return; } _gerstnerComponents.Remove(gerstner); }
public void ApplyForceToRB(ShapeGerstnerBatched _waves, Rigidbody _rb) { Vector3 undispPos = _waves.GetPositionDisplacedToPosition(ref _position, 0f); Vector3 displacement = _waves.SampleDisplacement(ref undispPos, 0f); float height = OceanRenderer.Instance.SeaLevel + displacement.y; Vector3 onSeaLevel = _position; onSeaLevel.y = OceanRenderer.Instance.SeaLevel; // h is the height of the water relative to the center of the sphere float h = height - _position.y + _r; h = Mathf.Min(h, 2f * _r); float submergedness = Mathf.Clamp01(h / (2f * _r)); if (submergedness < 0.001f) { // not in water return; } // volume of spherical cap, from https://en.wikipedia.org/wiki/Spherical_cap float Vdisp = Mathf.PI * h * h * (3f * _r - h) / 3f; // scale up to full volume //float Vfull = 4f * Mathf.PI * _r * _r * _r / 3f; float V = Vdisp;// _volume * Vdisp / Vfull; float rotAmt = .1f; float F = V * _waterDensity * Physics.gravity.magnitude; _rb.AddForceAtPosition(-F * Physics.gravity.normalized, Vector3.Lerp(_rb.position, _position, rotAmt)); Debug.DrawLine(_position, _position - F * Physics.gravity.normalized, Color.red * 0.5f); // apply drag relative to water var vel = _waves.GetSurfaceVelocity(ref undispPos, 0f); var deltaV = _rb.velocity - vel; // approximation - interpolate drag based on how submerged the sphere is _rb.AddForceAtPosition(-submergedness * _dragInWater * deltaV, Vector3.Lerp(_rb.position, _position, rotAmt)); Debug.DrawLine(_position, _position - submergedness * _dragInWater * deltaV, Color.white); }
public GerstnerBatch(ShapeGerstnerBatched gerstner, int batchIndex, MeshRenderer rend, bool directTowardsPoint) { _gerstner = gerstner; _batchIndex = batchIndex; _materials = new PropertyWrapperMaterial[] { new PropertyWrapperMaterial(new Material(rend.sharedMaterial ?? rend.material)), new PropertyWrapperMaterial(new Material(rend.sharedMaterial ?? rend.material)) }; if (directTowardsPoint) { _materials[0].material.EnableKeyword(DIRECT_TOWARDS_POINT_KEYWORD); _materials[1].material.EnableKeyword(DIRECT_TOWARDS_POINT_KEYWORD); } _rend = rend; Enabled = true; }
public GerstnerBatch(ShapeGerstnerBatched gerstner, int batchIndex, MeshRenderer rend, bool directTowardsPoint) { _gerstner = gerstner; _batchIndex = batchIndex; _materials = new PropertyWrapperMaterial[] { new PropertyWrapperMaterial(new Material(rend.sharedMaterial ?? rend.material)), new PropertyWrapperMaterial(new Material(rend.sharedMaterial ?? rend.material)) }; if (directTowardsPoint) { _materials[0].material.EnableKeyword(DIRECT_TOWARDS_POINT_KEYWORD); _materials[1].material.EnableKeyword(DIRECT_TOWARDS_POINT_KEYWORD); } _rend = rend; // Enabled stays true, because we don't sort the waves into buckets until Draw time, so we don't know if something should // be drawn in advance. Enabled = true; }
void Start() { _rb = GetComponent <Rigidbody>(); _waves = FindObjectOfType <ShapeGerstnerBatched>(); }