private void SimulateBuoyancy(FluidVolume fluidVolume) { Bounds bounds = buoyancyCollider.bounds; bounds.Expand(boundsExtentBias); float tangentOffset = bounds.size.x / (float)samples; float bitangentOffset = bounds.size.z / (float)samples; float impulse = -Physics.gravity.y * Time.fixedDeltaTime; if (useWeighting) { impulse *= (weightFactor + weightFactorBias) * rigidbody.mass * inverseVolume; } else { impulse *= fluidVolume.density; } Vector3 min = new Vector3(bounds.min.x, fluidVolume.collider.bounds.min.y, bounds.min.z); for (int x = 0; x < samples; x++) { for (int z = 0; z < samples; z++) { Vector3 offset = new Vector3(tangentOffset * ((float)x + 0.5f), 0.0f, bitangentOffset * ((float)z + 0.5f)); Vector3 start = min + offset; ApplySampleImpulse(start, tangentOffset, bitangentOffset, fluidVolume.RelativeHeightAtPoint(start), impulse); } } }
private void SimulateBuoyancy(FluidVolume fluidVolume) { Bounds bounds = buoyancyCollider.bounds; bounds.Expand(boundsExtentBias); Vector3 min = new Vector3(bounds.min.x, fluidVolume.collider.bounds.min.y, bounds.min.z); float tangentOffset = bounds.size.x / (float)samples; float bitangentOffset = bounds.size.z / (float)samples; float impulse = -Physics.gravity.y * Time.fixedDeltaTime; if (useWeighting) { impulse *= (weightFactor + weightFactorBias) * rigidbody.mass * inverseVolume; } else { impulse *= fluidVolume.density; } bool submerged = false; bool completelySubmerged = true; for (int x = 0; x < samples; x++) { for (int z = 0; z < samples; z++) { Vector3 offset = new Vector3(tangentOffset * ((float)x + 0.5f), 0.0f, bitangentOffset * ((float)z + 0.5f)); Vector3 start = min + offset; float height = fluidVolume.RelativeHeightAtPoint(start); RaycastHit lowerHit; if (buoyancyCollider.Raycast(new Ray(start, Vector3.up), out lowerHit, height)) { submerged = true; float fluidBoxHeight = lowerHit.distance; RaycastHit upperHit; if (buoyancyCollider.Raycast(new Ray(start + Vector3.up * height, Vector3.down), out upperHit, height)) { fluidBoxHeight += upperHit.distance; } else { completelySubmerged = false; } float sampleBoxHeight = height - fluidBoxHeight; float sampleVolume = sampleBoxHeight * tangentOffset * bitangentOffset; rigidbody.AddForceAtPosition(Vector3.up * (sampleVolume * impulse), lowerHit.point, ForceMode.Impulse); } } } if (!submerged) { completelySubmerged = false; } if (submerged) { totalDrag += dragScalar * fluidVolume.rigidbodyDrag; totalAngularDrag += angularDragScalar * fluidVolume.rigidbodyAngularDrag; totalSubmerged = true; if (completelySubmerged) { totalCompletelySubmerged = true; } } }