コード例 #1
0
        public void DistanceAndFrustumCulling(CameraFrustum frustum)
        {
            var viewPoint = frustum.ViewPoint;
            var halfSize  = _clusterDimensions / 2;

            var minVisiblePosX = viewPoint.x - _cullingDistance;
            var minVisiblePosZ = viewPoint.z - _cullingDistance;
            var maxVisiblePosX = minVisiblePosX + _cullingDistance * 2;
            var maxVisiblePosZ = minVisiblePosZ + _cullingDistance * 2;

            int curVisibleStartX = Mathf.FloorToInt(minVisiblePosX / _clusterSize) + halfSize;
            int curVisibleStartZ = Mathf.FloorToInt(minVisiblePosZ / _clusterSize) + halfSize;
            int curVisibleEndX   = Mathf.CeilToInt(maxVisiblePosX / _clusterSize) + halfSize;
            int curVisibleEndZ   = Mathf.CeilToInt(maxVisiblePosZ / _clusterSize) + halfSize;

            bool enoughRoom = true;

            for (int i = _lastVisibleStartX; i < _lastVisibleEndX; ++i)
            {
                for (int j = _lastVisibleStartZ; j < _lastVisibleEndZ; ++j)
                {
                    if (i >= 0 && i < _clusterDimensions && j >= 0 && j < _clusterDimensions)
                    {
                        var cluster = _nodeClusters[i, j];
                        if (cluster == null)
                        {
                            continue;
                        }

                        var node = cluster.DistanceAndFrustumCulling(viewPoint, enoughRoom);
                        if (node != null && enoughRoom)
                        {
                            _curInstantiatingNode = node;
                            enoughRoom            = false;
                        }
                    }
                }
            }

            if (_lastVisibleStartX != curVisibleStartX || _lastVisibleEndX != curVisibleEndX ||
                _lastVisibleStartZ != curVisibleStartZ || _lastVisibleEndZ != curVisibleEndZ)
            {
                for (int i = curVisibleStartX; i < curVisibleEndX; ++i)
                {
                    for (int j = curVisibleStartZ; j < curVisibleEndZ; ++j)
                    {
                        if (i >= 0 && i < _clusterDimensions && j >= 0 && j < _clusterDimensions)
                        {
                            var cluster = _nodeClusters[i, j];
                            if (cluster == null)
                            {
                                continue;
                            }

                            var node = cluster.DistanceAndFrustumCulling(viewPoint, enoughRoom);
                            if (node != null && enoughRoom)
                            {
                                _curInstantiatingNode = node;
                                enoughRoom            = false;
                            }
                        }
                    }
                }

                _lastVisibleStartX = curVisibleStartX;
                _lastVisibleEndX   = curVisibleEndX;
                _lastVisibleStartZ = curVisibleStartZ;
                _lastVisibleEndZ   = curVisibleEndZ;
            }

            if (!enoughRoom)
            {
                _curInstantiatingNode.SetInstantiating();
                _curInstantiatingNode.Node.BuildBuffer(_curInstantiatingNode.HeightBuffer());
            }

            var count = _cachedNodes.Length;

            for (int i = 0; i < count; ++i)
            {
                var node = _cachedNodes[i];
                if (node != null && node.IsInstantiated)
                {
                    node.IsActive = frustum.IsDetailNodeVisible(node.Mins, node.Maxs);
                }
            }
        }