Esempio n. 1
0
        private readonly Vector3 _upDirection = Vector3.up; // Force direction is towards the XZ plane up

        private void Start() {
            _isReady = false;

            _recompileMarker = new RecompiledMarker();

            _transform = GetComponent<Transform>();
            _rigidbody = GetComponent<Rigidbody>();

            RecalculateVoxels();
            RecalculateCache();
        }
Esempio n. 2
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);
        }
Esempio n. 3
0
        private void FixedUpdate() {
            if (!Application.isPlaying) {
                return;
            }

            if (_recompiledMarker == null) {
                Initialize();
                _recompiledMarker = new RecompiledMarker();
            }

            if (Application.isEditor) {
                UpdateComponents();
            }

#if !ARBITRARY_ROTATIONS
        _cachedPosition = _transform.position;
        _cachedLossyScale = _transform.lossyScale;
        #endif

            StepSimulation();
        }
Esempio n. 4
0
 private void Start() {
     _recompiledMarker = new RecompiledMarker();
     Initialize();
 }
    /// <summary>
    /// Sets up the manager.
    /// </summary>
    private void Initialize() {
        _instance = this;
#if UNITY_EDITOR
        _recompileMarker = new RecompiledMarker();
#endif
        _isDestroyed = false;
        UpdateCameraEvents(Camera.allCameras);
    }
    private void OnEnable() {
#if UNITY_EDITOR
        if (_recompileMarker == null) {
            Initialize();
            _recompileMarker = new RecompiledMarker();
        }
#endif
    }
    private void LateUpdate() {
        if (_recompileMarker == null) {
            Initialize();
            _recompileMarker = new RecompiledMarker();
        }

        UpdateCameraEvents(SceneView.GetAllSceneCameras());
    }