protected virtual void ApplyFloatData(WaterFloatInfo info)
    {
        if (floatBehaviour == FloatBehaviour.Realistic)
        {
            if (info.sizePercentageInWater < 0.15f)
            {
                Velocity.v += new Vector3(0, -9.81f * airTimer * airTimer * Time.deltaTime, 0);
                airTimer   += Time.deltaTime;
            }
            else
            {
                float heightDistance = info.height - transform.position.y;
                if (lastInfo != null && (lastInfo.sizePercentageInWater < 0.15f))
                {
                    if (Velocity.v.magnitude > 1)
                    {
                        float   splashScale  = 1;
                        float   splashFaktor = splashScale / Mathf.Max(splashScale, (maxLength * maxWidth));
                        Vector3 splashSize   = Velocity.v * mass * (1 - splashFaktor);
                        Velocity.v *= splashFaktor;
                        Debug.Log("Splash: " + splashSize.magnitude);
                    }
                }
                float yForce;

                yForce = (-9.81f + (9.81f * Mathf.Pow(info.densityDifferenceFactor, -1))) * Time.deltaTime * (heightDistance / 2);

                Velocity.v += new Vector3(0, yForce, 0);

                airTimer = 0;
            }
        }
        else if (floatBehaviour == FloatBehaviour.OnPoint)
        {
            transform.position = new Vector3(transform.position.x, info.height, transform.position.z);
        }

        if (rotateOnWave)
        {
            deltaEuler            = new Vector3(AngleDistance(info.newEulerAngle.x, transform.eulerAngles.x), 0, AngleDistance(info.newEulerAngle.x, transform.eulerAngles.x));
            transform.eulerAngles = info.newEulerAngle;
        }
    }
Exemple #2
0
    public WaterFloatInfo GetObjectFloatInfo(WaterRigidBody t)
    {
        WaterFloatInfo result = new WaterFloatInfo();

        try
        {
            Vector3 targetPosition = t.CurrentPosition;

            Vector3 localPosition = TransformToAnkorPosition(targetPosition);

            Vector3 objectForward = t.transform.forward;

            Vector3 objectRight = t.transform.right;

            float stackedHeight = 0;

            int xLength = (int)(t.maxLength * t.floatAccuracy + 1);

            ///move object in rotate direction
            Vector3 startPosition = localPosition + (objectForward * -1 * (t.maxLength / 2) + objectRight * -1 * (t.maxWidth / 2));

            float[][] heightGraph = new float[(int)(t.maxWidth * t.floatAccuracy + 1)][];

            Vector3 currentPosition = startPosition;

            Vector3 current2DPosition;

            int waveHeightCounter = 0;

            int   totalSize       = heightGraph.Length * XSize;
            float pointPercentage = 1f / totalSize;

            float objectStackedHeight = 0;
            float pointsInWater       = 0;
            float maxPointsInWater    = 0;

            for (int x = 0; x < heightGraph.Length; x++)
            {
                heightGraph[x]  = new float[xLength];
                currentPosition = startPosition + objectRight * x;
                for (int z = 0; z < heightGraph[x].Length; z++)
                {
                    current2DPosition = new Vector2(currentPosition.x, currentPosition.z);
                    Vector2 progress = LocalPosToProgress(current2DPosition);
                    if (progress.x > 0 || progress.x < 1 || progress.y > 0 || progress.y < 1)
                    {
                        float waveHeight;
                        switch (t.floatPrecision)
                        {
                        case (WaterRigidBody.FloatHeightPrecision.Approximately):
                        {
                            int index = GetNearestIndex(progress);
                            if (index >= 0)
                            {
                                waveHeight = vertices[index].y + transform.position.y;
                            }
                            else
                            {
                                waveHeight = 0;
                                //abseits von wasser
                            }
                            break;
                        }

                        case (WaterRigidBody.FloatHeightPrecision.Exact):
                        {
                            waveHeight = GetAccurateLocalHeightOnProgress(progress);
                            break;
                        }

                        default:
                        {
                            waveHeight = 0;
                            Debug.LogWarning("Unkown float precision: " + t.floatPrecision);
                            break;
                        }
                        }
                        if (waveHeight /* + transform.position.y*/ > currentPosition.y || t.floatBehaviour == WaterRigidBody.FloatBehaviour.OnPoint)
                        {
                            stackedHeight       += waveHeight;
                            objectStackedHeight += currentPosition.y;
                            heightGraph[x][z]    = waveHeight;
                            waveHeightCounter++;
                            pointsInWater++;
                        }
                        maxPointsInWater++;
                    }

                    currentPosition += objectForward;
                }
            }
            result.sizePercentageInWater = pointsInWater / maxPointsInWater;
            if (result.sizePercentageInWater > 0)
            {
                stackedHeight /= waveHeightCounter;

                objectStackedHeight /= waveHeightCounter;

                float densityDifference = (t.Mass / t.volume) / WATER_DENSITY;
                result.densityDifferenceFactor = densityDifference;

                float currentHeightPercentageInWater = Mathf.Clamp((stackedHeight - objectStackedHeight) / t.maxHeight, 0, 1);
                if (currentHeightPercentageInWater == 0)
                {
                    result.densityDifferenceFactor = 0;
                }
                else if (currentHeightPercentageInWater == 1)
                {
                    result.densityDifferenceFactor = densityDifference;
                }
                else
                {
                    float currentVolumeInWater = t.volumeDistribution.Integrate(0, currentHeightPercentageInWater, t.integrationPrecision);
                    result.densityDifferenceFactor = (t.Mass / (currentVolumeInWater * t.volume)) / WATER_DENSITY;
                }

                float heightPercentageInWater = t.volumeDistribution.IntegrateUntil(0, densityDifference);

                result.heightPercentageInWater = heightPercentageInWater;

                result.height = stackedHeight + (((t.maxHeight / 2) - t.maxHeight * heightPercentageInWater) + t.offset.y);

                float frequenzy = Frequenzy(ToZProgress(localPosition.z));

                float degreeRotation = Mathf.Cos(frequenzy) * waveAmplitude * (waveFrequenzy / (1 / 3f));

                float objectArea = t.maxWidth * t.maxLength;

                objectForward.y = 0;
                objectForward.Normalize();

                ///calculate the rotation for x and z axis. Use z direction axis as x rotation axis (both ways)
                result.newEulerAngle = new Vector3(-degreeRotation * objectForward.z, t.transform.eulerAngles.y, -degreeRotation * objectForward.x);
            }
        }
        catch
        {
        }
        return(result);
    }
 public void ApplyFloatInfo(WaterFloatInfo info)
 {
     ApplyFloatData(info);
     lastInfo = info;
 }