private void UpdateCellHeightData(RichCell reference, RichCell neighbour, float ledgeThreshold, int dx, int dz)
            {
                GetPerpendicularOffsets(dx, dz);
                var granularity = _matrix.granularity;
                var steps       = _matrix.cellSize / granularity;

                var data = new RichCell.HeightData();

                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 += (dx * granularity);
                        samplePos.z += (dz * granularity);

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

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

                        //Initially we just record the slope as the height diff
                        if (data.slope < absDiff)
                        {
                            data.slope = absDiff;
                        }

                        if (absDiff < ledgeThreshold)
                        {
                            if (data.dropHeight < dropAccumulator)
                            {
                                data.dropHeight = dropAccumulator;
                            }
                            else if (data.climbHeight < climbAccumulator)
                            {
                                data.climbHeight = climbAccumulator;
                            }

                            dropAccumulator  = 0f;
                            climbAccumulator = 0f;
                        }

                        if (heightDiff > 0f)
                        {
                            climbAccumulator += heightDiff;

                            if (data.dropHeight < dropAccumulator)
                            {
                                data.dropHeight = dropAccumulator;
                            }

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

                            if (data.climbHeight < climbAccumulator)
                            {
                                data.climbHeight = climbAccumulator;
                            }

                            climbAccumulator = 0f;
                        }

                        fromHeight = toHeight;
                    }

                    //Make sure we get the last accumulation recorded
                    if (data.dropHeight < dropAccumulator)
                    {
                        data.dropHeight = dropAccumulator;
                    }
                    else if (data.climbHeight < climbAccumulator)
                    {
                        data.climbHeight = climbAccumulator;
                    }
                } /* end for each offset */

                //Set the slope to an angular value
                var mod = (dx != 0 && dz != 0) ? Consts.SquareRootTwo : 1f;

                data.slope = Mathf.Atan(data.slope / (granularity * mod)) * Mathf.Rad2Deg;

                //Set the data
                reference.SetHeightData(dx, dz, data);
                reference.CalculateWorst();

                //Create the neighbour data as the reverse of this, i.e. drop = climb and vice versa
                var neighbourData = new RichCell.HeightData(data.slope, data.dropHeight, data.climbHeight);

                neighbour.SetHeightData(-dx, -dz, neighbourData);
                neighbour.CalculateWorst();
            }
Esempio n. 2
0
            private void UpdateCellHeightData(StandardCell reference, StandardCell neighbour, NeighbourPosition neighbourPos, float maxHeightDiff, float ledgeThreshold, bool testForPermanentBlock)
            {
                var dir = reference.GetDirectionTo(neighbour);

                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 */