예제 #1
0
        public IEnumerable<PatchDescriptor> GetPatches(TerrainTile tile, Frustum f, Vector3 eyeWorld)
        {
            // create root node
            var root = new QuadTreeNode(tile);

            return root.GetPatches(eyeWorld,f);
        }
        private void DebugRenderFrustum(Frustum f)
        {
            lineBuffer.SetColour(new Vector4(1f, 1f, 1f, 1f));
            lineBuffer.MoveTo(f.NearTopLeftCorner.Xyz.TopDown());
            lineBuffer.LineTo(f.NearTopRightCorner.Xyz.TopDown());
            lineBuffer.LineTo(f.FarTopRightCorner.Xyz.TopDown());
            lineBuffer.LineTo(f.FarTopLeftCorner.Xyz.TopDown());
            lineBuffer.LineTo(f.NearTopLeftCorner.Xyz.TopDown());

            lineBuffer.SetColour(new Vector4(1f, 1f, 1f, .5f));
            lineBuffer.MoveTo(f.NearBottomLeftCorner.Xyz.TopDown());
            lineBuffer.LineTo(f.NearBottomRightCorner.Xyz.TopDown());
            lineBuffer.LineTo(f.FarBottomRightCorner.Xyz.TopDown());
            lineBuffer.LineTo(f.FarBottomLeftCorner.Xyz.TopDown());
            lineBuffer.LineTo(f.NearBottomLeftCorner.Xyz.TopDown());

            lineBuffer.SetColour(new Vector4(1f, 0f, 0f, 1f));
            lineBuffer.MoveTo(f.NearTopLeftCorner.Xyz.TopDown());
            lineBuffer.LineTo(f.FarTopLeftCorner.Xyz.TopDown());
            lineBuffer.LineTo(f.FarBottomLeftCorner.Xyz.TopDown());
            lineBuffer.LineTo(f.NearBottomLeftCorner.Xyz.TopDown());
            lineBuffer.LineTo(f.NearTopLeftCorner.Xyz.TopDown());

            lineBuffer.SetColour(new Vector4(0f, 1f, 0f, 1f));
            lineBuffer.MoveTo(f.NearTopRightCorner.Xyz.TopDown());
            lineBuffer.LineTo(f.FarTopRightCorner.Xyz.TopDown());
            lineBuffer.LineTo(f.FarBottomRightCorner.Xyz.TopDown());
            lineBuffer.LineTo(f.NearBottomRightCorner.Xyz.TopDown());
            lineBuffer.LineTo(f.NearTopRightCorner.Xyz.TopDown());
        }
예제 #3
0
        public IEnumerable<PatchDescriptor> GetPatches(Vector3 eye, Frustum f)
        {
            bool childFrustumCheck = true;

            // frustum cull
            if (checkFrustum)
            {
                var clipresult = f.TestBox(this.vertex);
                if (clipresult == Frustum.ObjectClipResult.TotallyOutside)
                {
                    yield break;
                }
                if (clipresult == Frustum.ObjectClipResult.TotallyInside)
                {
                    childFrustumCheck = false;
                }
            }

            // get eye y-difference (0 within min/max height)

            //float eyeY = U.Max(U.Max(eye.Y - MaxHeight, 0f), U.Max(MinHeight - eye.Y, 0f));
            float eyeYdiff = 0f;
            if (eye.Y > MaxHeight)
            {
                eyeYdiff = eye.Y - MaxHeight;
            }
            else if (eye.Y < MinHeight)
            {
                eyeYdiff = MinHeight - eye.Y;
            }

            eyeYdiff *= eyeYdiff;

            int i = 0;
            distance[i++] = (float)Math.Sqrt((eye.X - vertex[i].X).Sqr() + eyeYdiff + (eye.Z - vertex[i].Z).Sqr());
            distance[i++] = (float)Math.Sqrt((eye.X - vertex[i].X).Sqr() + eyeYdiff + (eye.Z - vertex[i].Z).Sqr());
            distance[i++] = (float)Math.Sqrt((eye.X - vertex[i].X).Sqr() + eyeYdiff + (eye.Z - vertex[i].Z).Sqr());
            distance[i++] = (float)Math.Sqrt((eye.X - vertex[i].X).Sqr() + eyeYdiff + (eye.Z - vertex[i].Z).Sqr());
            distance[i++] = U.DistanceToSquare(
                                vertex[(int)Corner.BottomNearLeft].X, vertex[(int)Corner.BottomNearLeft].Z,
                                vertex[(int)Corner.BottomFarRight].X, vertex[(int)Corner.BottomFarRight].Z,
                                eye.X, eye.Z,
                                eyeYdiff);

            for (i = 0; i < 5; i++)
            {
                lod[i] = GetLOD(distance[i], depth);
            }

            int patchLOD = lod.Max();
            int LODDiff = patchLOD - lod.Min();
            float patchDistance = distance.Min();

            // recusion limit, or not enough lod difference
            if (depth > MaxDepth || LODDiff <= MaxLODDiff)
            {
                yield return new PatchDescriptor
                {
                    Tile = this.tile,
                    TileModelMatrix = this.tile.ModelMatrix,
                    TileSize = tileSize,
                    MeshSize = GetMeshSize(tileSize, patchLOD),
                    //Offset = (vertex[(int)Corner.BottomNearLeft].Xz - TileOffset.Xz) / (float)this.tile.Width,

                    Scale = (float)tileSize / (float)tile.Width,
                    Offset = this.Offset,

                    Distance = patchDistance,
                    LOD = patchLOD
                };
            }
            else
            {
                // recurse

                var BottomNearCentre = vertex[(int)Corner.BottomNearLeft];
                BottomNearCentre.X = BottomCentre.X;
                var BottomCentreLeft = vertex[(int)Corner.BottomNearLeft];
                BottomCentreLeft.Z = BottomCentre.Z;
                var BottomFarCentre = vertex[(int)Corner.BottomFarLeft];
                BottomFarCentre.X = BottomCentre.X;
                var BottomCentreRight = vertex[(int)Corner.BottomNearRight];
                BottomCentreRight.Z = BottomCentre.Z;

                var TopNearCentre = vertex[(int)Corner.TopNearLeft];
                TopNearCentre.X = TopCentre.X;
                var TopCentreLeft = vertex[(int)Corner.TopNearLeft];
                TopCentreLeft.Z = TopCentre.Z;
                var TopFarCentre = vertex[(int)Corner.TopFarLeft];
                TopFarCentre.X = TopCentre.X;
                var TopCentreRight = vertex[(int)Corner.TopNearRight];
                TopCentreRight.Z = TopCentre.Z;

                float offsetfactor = 1.0f/(1 << (depth+1));

                // near left quadrant
                foreach (var pd in new QuadTreeNode(this, tile, tileSize >> 1, depth + 1, childFrustumCheck, Offset,
                    vertex[(int)Corner.BottomNearLeft],
                    BottomNearCentre,
                    BottomCentreLeft,
                    BottomCentre,
                    vertex[(int)Corner.TopNearLeft],
                    TopNearCentre,
                    TopCentreLeft,
                    TopCentre
                    ).GetPatches(eye, f))
                {
                    yield return pd;
                }

                // near right quadrant
                foreach (var pd in new QuadTreeNode(this, tile, tileSize >> 1, depth + 1, childFrustumCheck, Offset + new Vector2(offsetfactor, 0f),
                    BottomNearCentre,
                    vertex[(int)Corner.BottomNearRight],
                    BottomCentre,
                    BottomCentreRight,
                    TopNearCentre,
                    vertex[(int)Corner.TopNearRight],
                    TopCentre,
                    TopCentreRight
                    ).GetPatches(eye, f))
                {
                    yield return pd;
                }

                // far left quadrant
                foreach (var pd in new QuadTreeNode(this, tile, tileSize >> 1, depth + 1, childFrustumCheck, Offset + new Vector2(0f, offsetfactor),
                    BottomCentreLeft,
                    BottomCentre,
                    vertex[(int)Corner.BottomFarLeft],
                    BottomFarCentre,
                    TopCentreLeft,
                    TopCentre,
                    vertex[(int)Corner.TopFarLeft],
                    TopFarCentre
                    ).GetPatches(eye, f))
                {
                    yield return pd;
                }

                // far right quadrant
                foreach (var pd in new QuadTreeNode(this, tile, tileSize >> 1, depth + 1, childFrustumCheck, Offset + new Vector2(offsetfactor, offsetfactor),
                    BottomCentre,
                    BottomCentreRight,
                    BottomFarCentre,
                    vertex[(int)Corner.BottomFarRight],
                    TopCentre,
                    TopCentreRight,
                    TopFarCentre,
                    vertex[(int)Corner.TopFarRight]
                    ).GetPatches(eye, f))
                {
                    yield return pd;
                }
            }
        }