Example #1
0
    private void RefineNode(TerrainPatch patch, Transform playerTransform, ref List <TerrainPatch> active)
    {
        int x = GetQuadX(patch);
        int z = GetQuadZ(patch);

        // 视景体剔除
        if (!GeometryUtility.TestPlanesAABB(frustum, patch.bound))
        {
            quadMatrix[z * quadSize + x] = 0;
            DisableRenderer(patch);
            return;
        }

        Vector3 cameraPos = playerTransform.position;
        Vector3 facePos   = patch.center;
        //calculate the distance from the current point (L1 NORM, which, essentially, is a faster version of the
        //normal distance equation you may be used to... yet again, thanks to Chris Cookson)
        int   v1           = GetQuadMatrixData(x + 1, z);
        float viewDistance = (float)(Mathf.Abs(cameraPos.x - (facePos.x)) +
                                     Mathf.Abs(cameraPos.y - v1) +
                                     Mathf.Abs(cameraPos.z - (facePos.z)));


        //compute the 'f' value (as stated in Roettger's whitepaper of this algorithm)
        int   v2 = GetQuadMatrixData(x - 1, z);
        float f  = viewDistance / (patch.scale * minResolution *
                                   Mathf.Max(detailLevel * v2 / 4.0f, 1.0f));

        int blend;

        if (f >= 1)
        {
            blend = 0;
        }
        else
        {
            blend = 255;
        }
        quadMatrix[z * quadSize + x] = blend;

        // 不需要拆分
        if (blend == 0)
        {
            active.Add(patch);

            if (patch.tree != null)
            {
                // 合并前恢复原始值
                for (int i = 0; i < patch.tree.Length; i++)
                {
                    int childX = GetQuadX(patch.tree[i]);
                    int childZ = GetQuadZ(patch.tree[i]);
                    quadMatrix[childZ * quadSize + childX] = quadMatrix[childZ * quadSize + childX - 1];
                }
                quadMatrix[z * quadSize + x] = quadMatrix[z * quadSize + x - 1];
                patch.Merge();
            }
        }
        // 需要拆分
        else if (patch.scale >= 4)
        {
            if (patch.tree == null)
            {
                patch.SubDivide();
            }
        }

        // 计算子节点递归
        if (patch.tree != null)
        {
            for (int i = 0; i < patch.tree.Length; i++)
            {
                RefineNode(patch.tree[i], playerTransform, ref active);
            }
        }
    }