Пример #1
0
 private void OnTriggerExit(Collider otherCollider) {
     // Making sure the object we have left is DynamicWater
     if (_water != null && otherCollider.CompareTag(FluidVolume.DynamicWaterTagName) &&
         otherCollider == _water.Collider) {
         _water = null;
     }
 }
 private void OnTriggerEnter(Collider otherCollider)
 {
     // Making sure the object we have entered is DynamicWater
     if (otherCollider.CompareTag(FluidVolume.DynamicWaterTagName))
     {
         _water = otherCollider.gameObject.GetComponent <DynamicWater>();
     }
 }
 private void OnTriggerExit(Collider otherCollider)
 {
     // Making sure the object we have left is DynamicWater
     if (_water != null && otherCollider.CompareTag(FluidVolume.DynamicWaterTagName) &&
         otherCollider == _water.Collider)
     {
         _water = null;
     }
 }
Пример #4
0
    /// <summary>
    /// Called when BuoyantObject enters the water.
    /// </summary>
    /// <param name="eventWater">
    /// The FluidVolume which the object has entered.
    /// </param>
    public void OnFluidVolumeEnter(IDynamicWaterFluidVolume eventWater) {
        _water = eventWater as IDynamicWaterSettings;
        if (_water == null) {
            return;
        }

        if (_water.PlaneCollider != null) {
            SpawnSplash(SplashPrefab, _water.PlaneCollider.ClosestPointOnBounds(transform.position));
        }
    }
Пример #5
0
    /// <summary>
    /// Checking if we have left the fluid volume.
    /// </summary>
    private void OnTriggerExit(Collider otherCollider)
    {
        if (!_isReady)
        {
            return;
        }

        if (_water != null && otherCollider.CompareTag(FluidVolume.DynamicWaterTagName) && otherCollider == _water.Collider)
        {
            _water = null;
        }
    }
Пример #6
0
    /// <summary>
    /// Called when BuoyantObject enters the water.
    /// </summary>
    /// <param name="eventWater">
    /// The FluidVolume which the object has entered.
    /// </param>
    public void OnFluidVolumeEnter(IDynamicWaterFluidVolume eventWater)
    {
        _water = eventWater as IDynamicWaterSettings;
        if (_water == null)
        {
            return;
        }

        if (_water.PlaneCollider != null)
        {
            SpawnSplash(SplashPrefab, _water.PlaneCollider.ClosestPointOnBounds(transform.position));
        }
    }
Пример #7
0
    /// <summary>
    /// Checking if we are staying in the fluid volume.
    /// </summary>
    private void OnTriggerStay(Collider otherCollider)
    {
        if (!_isReady)
        {
            return;
        }

        if (_water == null || (otherCollider.CompareTag(FluidVolume.DynamicWaterTagName) && otherCollider != _water.Collider))
        {
            IDynamicWaterFluidVolume water = otherCollider.gameObject.GetComponent <FluidVolume>() ??
                                             otherCollider.gameObject.GetComponent <DynamicWater>();
            if (water != null)
            {
                _water = water;

                RecalculateCache();
            }
        }
    }
Пример #8
0
 private void OnTriggerEnter(Collider otherCollider) {
     // Making sure the object we have entered is DynamicWater
     if (otherCollider.CompareTag(FluidVolume.DynamicWaterTagName)) {
         _water = otherCollider.gameObject.GetComponent<DynamicWater>();
     }
 }
Пример #9
0
        /// <summary>
        /// Buoyancy calculation step.
        /// </summary>
        private void FixedUpdate() {
            // Happens on assembly reload
            if (_recompileMarker == null) {
                RecalculateVoxels();
                _water = null;
                _recompileMarker = new RecompiledMarker();
            }

            // Failsafe
            if (_water == null || _density < 0.01f || !_isReady) {
                _rigidbody.drag = _dragNonFluid;
                _rigidbody.angularDrag = _angularDragNonFluid;
                return;
            }

            float invDoubleVoxelSize = 1f / (2f * _voxelSize);
            DynamicWater dynamicWater = _water as DynamicWater;
            bool solverCanInteract = dynamicWater != null && dynamicWater.Solver.CanInteract;

            for (int i = 0; i < _voxelsLength; i++) {
                Vector3 wp = _transform.TransformPoint(_buoyancyVoxels[i].Position);
                float waterLevel = _water.GetWaterLevel(wp.x, wp.y, wp.z);

                // No force is applied to the points outside the fluid
                if (waterLevel != float.NegativeInfinity && (wp.y - _voxelSize / 1f < waterLevel)) {
                    Vector3 velocity = _rigidbody.GetPointVelocity(wp);

                    // k == 1 when the voxel is fully submerged
                    // k == 0 when the voxel is fully outside
                    float k = (waterLevel - wp.y) * invDoubleVoxelSize + 0.5f;

                    // Create the splash when the point has passed the water surface.
                    if (_buoyancyVoxels[i].IsOnColliderEdge) {
                        if (!_buoyancyVoxels[i].HadPassedWater && (k < 1f && k > 0f)) {
                            // Scaling and limiting the splash force
                            if (solverCanInteract) {
                                float force = FastFunctions.FastVector3Magnitude(velocity) * _splashForceFactorNormalized;
                                if (force > _maxSplashForceNormalized) {
                                    force = _maxSplashForceNormalized;
                                }

                                if (force > 0.0075f) {
                                    _water.CreateSplash(wp, _voxelSize, force);
                                }
                            }

                            _buoyancyVoxels[i].HadPassedWater = true;
                        } else {
                            _buoyancyVoxels[i].HadPassedWater = false;
                        }
                    }

                    k = (k > 1f) ? 1f : (k < 0f) ? 0f : k;
                    _subMergedVolume += k;

                    // Calculating the actual force for this point depending oh how much
                    // the point is submerged into the fluid
                    Vector3 archimedesForce;
                    archimedesForce.x = k * _voxelArchimedesForce.x;
                    archimedesForce.y = k * _voxelArchimedesForce.y;
                    archimedesForce.z = k * _voxelArchimedesForce.z;

                    // Applying the local force
                    _rigidbody.AddForceAtPosition(archimedesForce, wp, ForceMode.Impulse);
                }
            }

            // Normalizing the submerged volume
            // 0 - object is fully outside the water
            // 1 - object is fully submerged
            _subMergedVolume /= _voxelsLength;

            const float threshold = 0.01f;

            // Sending the message to other components
            if (_subMergedVolumePrev < threshold && _subMergedVolume >= threshold) {
                SendMessage("OnFluidVolumeEnter", _water, SendMessageOptions.DontRequireReceiver);
            } else if (_subMergedVolumePrev >= threshold && _subMergedVolume < threshold) {
                SendMessage("OnFluidVolumeExit", _water, SendMessageOptions.DontRequireReceiver);
            }

            _subMergedVolumePrev = _subMergedVolume;

            // Calculating the drag
            _rigidbody.drag = Mathf.Lerp(_rigidbody.drag, _subMergedVolume > 0.0001f ? _dragNonFluid + _dragInFluid : _dragNonFluid, 8f * Time.deltaTime);
            _rigidbody.angularDrag = Mathf.Lerp(_rigidbody.angularDrag, _subMergedVolume > 0.0001f ? _angularDragNonFluid + _angularDragInFluid : _angularDragNonFluid, 8f * Time.deltaTime);
        }
Пример #10
0
        /// <summary>
        /// Checking if we have left the fluid volume.
        /// </summary>
        private void OnTriggerExit(Collider otherCollider) {
            if (!_isReady) {
                return;
            }

            if (_water != null && otherCollider.CompareTag(FluidVolume.DynamicWaterTagName) && otherCollider == _water.Collider) {
                _water = null;
            }
        }
Пример #11
0
        /// <summary>
        /// Checking if we are staying in the fluid volume.
        /// </summary>
        private void OnTriggerStay(Collider otherCollider) {
            if (!_isReady) {
                return;
            }

            if (_water == null || (otherCollider.CompareTag(FluidVolume.DynamicWaterTagName) && otherCollider != _water.Collider)) {
                IDynamicWaterFluidVolume water = otherCollider.gameObject.GetComponent<FluidVolume>() ??
                                                 otherCollider.gameObject.GetComponent<DynamicWater>();
                if (water != null) {
                    _water = water;

                    RecalculateCache();
                }
            }
        }
Пример #12
0
    /// <summary>
    /// Buoyancy calculation step.
    /// </summary>
    private void FixedUpdate()
    {
        // Happens on assembly reload
        if (_recompileMarker == null)
        {
            RecalculateVoxels();
            _water           = null;
            _recompileMarker = new RecompiledMarker();
        }

        // Failsafe
        if (_water == null || _density < 0.01f || !_isReady)
        {
            _rigidbody.drag        = _dragNonFluid;
            _rigidbody.angularDrag = _angularDragNonFluid;
            return;
        }

        float        invDoubleVoxelSize = 1f / (2f * _voxelSize);
        DynamicWater dynamicWater       = _water as DynamicWater;
        bool         solverCanInteract  = dynamicWater != null && dynamicWater.Solver.CanInteract;

        for (int i = 0; i < _voxelsLength; i++)
        {
            Vector3 wp         = _transform.TransformPoint(_buoyancyVoxels[i].Position);
            float   waterLevel = _water.GetWaterLevel(wp.x, wp.y, wp.z);

            // No force is applied to the points outside the fluid
            if (waterLevel != float.NegativeInfinity && (wp.y - _voxelSize / 1f < waterLevel))
            {
                Vector3 velocity = _rigidbody.GetPointVelocity(wp);

                // k == 1 when the voxel is fully submerged
                // k == 0 when the voxel is fully outside
                float k = (waterLevel - wp.y) * invDoubleVoxelSize + 0.5f;

                // Create the splash when the point has passed the water surface.
                if (_buoyancyVoxels[i].IsOnColliderEdge)
                {
                    if (!_buoyancyVoxels[i].HadPassedWater && (k <1f && k> 0f))
                    {
                        // Scaling and limiting the splash force
                        if (solverCanInteract)
                        {
                            float force = FastFunctions.FastVector3Magnitude(velocity) * _splashForceFactorNormalized;
                            if (force > _maxSplashForceNormalized)
                            {
                                force = _maxSplashForceNormalized;
                            }

                            if (force > 0.0075f)
                            {
                                _water.CreateSplash(wp, _voxelSize, force);
                            }
                        }

                        _buoyancyVoxels[i].HadPassedWater = true;
                    }
                    else
                    {
                        _buoyancyVoxels[i].HadPassedWater = false;
                    }
                }

                k = (k > 1f) ? 1f : (k < 0f) ? 0f : k;
                _subMergedVolume += k;

                // Calculating the actual force for this point depending oh how much
                // the point is submerged into the fluid
                Vector3 archimedesForce;
                archimedesForce.x = k * _voxelArchimedesForce.x;
                archimedesForce.y = k * _voxelArchimedesForce.y;
                archimedesForce.z = k * _voxelArchimedesForce.z;

                // Applying the local force
                _rigidbody.AddForceAtPosition(archimedesForce, wp, ForceMode.Impulse);
            }
        }

        // Normalizing the submerged volume
        // 0 - object is fully outside the water
        // 1 - object is fully submerged
        _subMergedVolume /= _voxelsLength;

        const float threshold = 0.01f;

        // Sending the message to other components
        if (_subMergedVolumePrev < threshold && _subMergedVolume >= threshold)
        {
            SendMessage("OnFluidVolumeEnter", _water, SendMessageOptions.DontRequireReceiver);
        }
        else if (_subMergedVolumePrev >= threshold && _subMergedVolume < threshold)
        {
            SendMessage("OnFluidVolumeExit", _water, SendMessageOptions.DontRequireReceiver);
        }

        _subMergedVolumePrev = _subMergedVolume;

        // Calculating the drag
        _rigidbody.drag        = Mathf.Lerp(_rigidbody.drag, _subMergedVolume > 0.0001f ? _dragNonFluid + _dragInFluid : _dragNonFluid, 8f * Time.deltaTime);
        _rigidbody.angularDrag = Mathf.Lerp(_rigidbody.angularDrag, _subMergedVolume > 0.0001f ? _angularDragNonFluid + _angularDragInFluid : _angularDragNonFluid, 8f * Time.deltaTime);
    }