private void UpdateCellHeightData(StandardCell reference, StandardCell neighbour, NeighbourPosition neighbourPos, float maxHeightDiff, float ledgeThreshold, bool testForPermanentBlock)
        {
            var heightSampler = GetHeightSampler();

            var dir = reference.GetDirectionTo(neighbour);
            var offsets = GetPerpendicularOffsets(dir.x, dir.z);
            var granularity = _matrix.granularity;
            var steps = _matrix.cellSize / granularity;

            var maxClimb = 0f;
            var maxDrop = 0f;

            for (int o = 0; o < 3; o++)
            {
                var samplePos = reference.position + offsets[o];
                var fromHeight = heightSampler.SampleHeight(samplePos, _matrix);

                var climbAccumulator = 0.0f;
                var dropAccumulator = 0.0f;

                for (int i = 0; i < steps; i++)
                {
                    samplePos.x += (dir.x * granularity);
                    samplePos.z += (dir.z * granularity);

                    var toHeight = heightSampler.SampleHeight(samplePos, _matrix);

                    var heightDiff = toHeight - fromHeight;
                    var absDiff = Mathf.Abs(heightDiff);

                    bool ledgeEncountered = absDiff < ledgeThreshold;

                    if (absDiff <= maxHeightDiff || ledgeEncountered)
                    {
                        if (climbAccumulator > maxClimb)
                        {
                            maxClimb = climbAccumulator;
                        }
                        else if (dropAccumulator > maxDrop)
                        {
                            maxDrop = dropAccumulator;
                        }

                        climbAccumulator = 0f;
                        dropAccumulator = 0f;
                    }
                    else if (heightDiff > 0f)
                    {
                        climbAccumulator += heightDiff;
                        if (dropAccumulator > maxDrop)
                        {
                            maxDrop = dropAccumulator;
                        }

                        dropAccumulator = 0f;
                    }
                    else if (heightDiff < 0f)
                    {
                        dropAccumulator += absDiff;
                        if (climbAccumulator > maxClimb)
                        {
                            maxClimb = climbAccumulator;
                        }

                        climbAccumulator = 0f;
                    }

                    fromHeight = toHeight;
                } /* end steps */

                maxClimb = Mathf.Max(climbAccumulator, maxClimb);
                maxDrop = Mathf.Max(dropAccumulator, maxDrop);
            }

            var refPos = reference.GetRelativePositionTo(neighbour);
            if (maxClimb > _maxClimbHeight || maxDrop > _maxDropHeight)
            {
                neighbour.heightBlockedFrom |= refPos;
            }

            if (maxClimb > _maxDropHeight || maxDrop > _maxClimbHeight)
            {
                reference.heightBlockedFrom |= neighbourPos;
            }

            reference.heightIntializedFrom |= neighbourPos;
            neighbour.heightIntializedFrom |= refPos;
        } /* end method */
Ejemplo n.º 2
0
        private void UpdateCellHeightData(StandardCell reference, StandardCell neighbour, NeighbourPosition neighbourPos, float maxHeightDiff, float ledgeThreshold, bool testForPermanentBlock)
        {
            var heightSampler = GetHeightSampler();

            var dir         = reference.GetDirectionTo(neighbour);
            var offsets     = GetPerpendicularOffsets(dir.x, dir.z);
            var granularity = _matrix.granularity;
            var steps       = _matrix.cellSize / granularity;

            var maxClimb = 0f;
            var maxDrop  = 0f;

            for (int o = 0; o < 3; o++)
            {
                var samplePos  = reference.position + offsets[o];
                var fromHeight = heightSampler.SampleHeight(samplePos, _matrix);

                var climbAccumulator = 0.0f;
                var dropAccumulator  = 0.0f;

                for (int i = 0; i < steps; i++)
                {
                    samplePos.x += (dir.x * granularity);
                    samplePos.z += (dir.z * granularity);

                    var toHeight = heightSampler.SampleHeight(samplePos, _matrix);

                    var heightDiff = toHeight - fromHeight;
                    var absDiff    = Mathf.Abs(heightDiff);

                    bool ledgeEncountered = absDiff < ledgeThreshold;

                    if (absDiff <= maxHeightDiff || ledgeEncountered)
                    {
                        if (climbAccumulator > maxClimb)
                        {
                            maxClimb = climbAccumulator;
                        }
                        else if (dropAccumulator > maxDrop)
                        {
                            maxDrop = dropAccumulator;
                        }

                        climbAccumulator = 0f;
                        dropAccumulator  = 0f;
                    }
                    else if (heightDiff > 0f)
                    {
                        climbAccumulator += heightDiff;
                        if (dropAccumulator > maxDrop)
                        {
                            maxDrop = dropAccumulator;
                        }

                        dropAccumulator = 0f;
                    }
                    else if (heightDiff < 0f)
                    {
                        dropAccumulator += absDiff;
                        if (climbAccumulator > maxClimb)
                        {
                            maxClimb = climbAccumulator;
                        }

                        climbAccumulator = 0f;
                    }

                    fromHeight = toHeight;
                } /* end steps */

                maxClimb = Mathf.Max(climbAccumulator, maxClimb);
                maxDrop  = Mathf.Max(dropAccumulator, maxDrop);
            }

            var refPos = reference.GetRelativePositionTo(neighbour);

            if (maxClimb > _maxClimbHeight || maxDrop > _maxDropHeight)
            {
                neighbour.heightBlockedFrom |= refPos;
            }

            if (maxClimb > _maxDropHeight || maxDrop > _maxClimbHeight)
            {
                reference.heightBlockedFrom |= neighbourPos;
            }

            reference.heightIntializedFrom |= neighbourPos;
            neighbour.heightIntializedFrom |= refPos;
        } /* end method */