Exemple #1
0
 /// <summary>
 /// Creates the four subquads of this quad.
 /// </summary>
 private void Subdivide()
 {
     Children[0] = new TerrainQuad(Owner, this, 2 * Tx, 2 * Ty, Ox, Oy, LengthHalf, ZMin, ZMax);
     Children[1] = new TerrainQuad(Owner, this, 2 * Tx + 1, 2 * Ty, Ox + LengthHalf, Oy, LengthHalf, ZMin, ZMax);
     Children[2] = new TerrainQuad(Owner, this, 2 * Tx, 2 * Ty + 1, Ox, Oy + LengthHalf, LengthHalf, ZMin, ZMax);
     Children[3] = new TerrainQuad(Owner, this, 2 * Tx + 1, 2 * Ty + 1, Ox + LengthHalf, Oy + LengthHalf, LengthHalf, ZMin, ZMax);
 }
Exemple #2
0
        public void DrawQuads(TerrainQuad quad, Mesh mesh, MaterialPropertyBlock mpb, int layer)
        {
            if (!quad.IsVisible)
            {
                return;
            }
            if (!quad.Drawable)
            {
                return;
            }

            if (quad.IsLeaf)
            {
                for (var i = 0; i < SamplersSuitable.Count; ++i)
                {
                    // Set the unifroms needed to draw the texture for this sampler
                    SamplersSuitable[i].SetUniforms(mpb, quad);
                }

                DrawMesh(quad, mesh, mpb, layer);
            }
            else
            {
                quad.CalculateOrder(quad.Owner.LocalCameraPosition.x, quad.Owner.LocalCameraPosition.y, quad.Ox + quad.LengthHalf, quad.Oy + quad.LengthHalf);

                // Draw quads in a order based on distance to camera
                var done = 0;

                for (var i = 0; i < 4; ++i)
                {
                    var targetQuad = quad.GetChild(quad.Order[i]);

                    if (targetQuad.Visibility == Frustum3d.VISIBILITY.INVISIBLE)
                    {
                        done |= 1 << quad.Order[i];
                    }
                    else if (targetQuad.Drawable)
                    {
                        DrawQuads(targetQuad, mesh, mpb, layer);

                        done |= 1 << quad.Order[i];
                    }
                }

                if (done < 15)
                {
                    // If the a leaf quad needs to be drawn but its tiles are not ready, then this will draw the next parent tile instead that is ready.
                    // Because of the current set up all tiles always have there tasks run on the frame they are generated, so this section of code is never reached.
                    Debug.LogWarning(string.Format("Looks like rendering false start! {0}:{1}:{2}", quad.Level, quad.Tx, quad.Ty));

                    for (var i = 0; i < SamplersSuitable.Count; ++i)
                    {
                        // Set the unifroms needed to draw the texture for this sampler
                        SamplersSuitable[i].SetUniforms(mpb, quad);
                    }

                    DrawMesh(quad, mesh, mpb, layer);
                }
            }
        }
Exemple #3
0
        private void DrawMesh(TerrainQuad quad, Mesh mesh, MaterialPropertyBlock mpb)
        {
            // Set the uniforms unique to each quad
            SetPerQuadUniforms(quad, mpb);

            Graphics.DrawMesh(mesh, Matrix4x4.identity, TerrainMaterial, 0, CameraHelper.Main(), 0, mpb);
        }
Exemple #4
0
        private void DrawMesh(TerrainQuad quad, Mesh mesh, MaterialPropertyBlock mpb, int layer)
        {
            // Set the uniforms unique to each quad
            SetPerQuadUniforms(quad, mpb);

            Graphics.DrawMesh(mesh, Matrix4x4.identity, TerrainMaterial, layer, CameraHelper.Main(), 0, mpb, ShadowCastingMode.On, true);
        }
Exemple #5
0
        protected override void InitNode()
        {
            Body = GetComponentInParent <CelestialBody>();
            Body.TerrainNodes.Add(this);

            TerrainMaterial = MaterialHelper.CreateTemp(Body.ColorShader, "TerrainNode");

            //Manager.GetSkyNode().InitUniforms(TerrainMaterial);

            var faces = new Vector3d[] { new Vector3d(0, 0, 0), new Vector3d(90, 0, 0), new Vector3d(90, 90, 0), new Vector3d(90, 180, 0), new Vector3d(90, 270, 0), new Vector3d(0, 180, 180) };

            FaceToLocal = Matrix4x4d.Identity();

            // If this terrain is deformed into a sphere the face matrix is the rotation of the
            // terrain needed to make up the spherical planet. In this case there should be 6 terrains, each with a unique face number
            if (Face - 1 >= 0 && Face - 1 < 6)
            {
                FaceToLocal = Matrix4x4d.Rotate(faces[Face - 1]);
            }

            //LocalToWorld = Matrix4x4d.ToMatrix4x4d(transform.localToWorldMatrix) * FaceToLocal;
            LocalToWorld = FaceToLocal;

            Deformation = new DeformationSpherical(Body.Radius);

            TerrainQuadRoot = new TerrainQuad(this, null, 0, 0, -Body.Radius, -Body.Radius, 2.0 * Body.Radius, ZMin, ZMax);
        }
Exemple #6
0
        /// <summary>
        /// Creates the four subquads of this quad.
        /// </summary>
        private void Subdivide()
        {
            var hl = (float)Length / 2.0f;

            Children[0] = new TerrainQuad(Owner, this, 2 * Tx, 2 * Ty, Ox, Oy, hl, ZMin, ZMax);
            Children[1] = new TerrainQuad(Owner, this, 2 * Tx + 1, 2 * Ty, Ox + hl, Oy, hl, ZMin, ZMax);
            Children[2] = new TerrainQuad(Owner, this, 2 * Tx, 2 * Ty + 1, Ox, Oy + hl, hl, ZMin, ZMax);
            Children[3] = new TerrainQuad(Owner, this, 2 * Tx + 1, 2 * Ty + 1, Ox + hl, Oy + hl, hl, ZMin, ZMax);
        }
Exemple #7
0
        private void CreateTerrainQuadRoot(float size)
        {
            if (TerrainQuadRoot != null)
            {
                Debug.Log("TerrainNode: Hey! You're gonna create quad root, but it's already exist!"); return;
            }

            TerrainQuadRoot = new TerrainQuad(this, null, 0, 0, -size, -size, 2.0 * size, ZMin, ZMax);
        }
Exemple #8
0
        public void DrawQuad(TerrainQuad quad, List <TileSampler> samplers, Mesh mesh, MaterialPropertyBlock mpb)
        {
            if (!quad.IsVisible)
            {
                return;
            }
            if (!quad.Drawable)
            {
                return;
            }

            if (quad.IsLeaf)
            {
                for (byte i = 0; i < samplers.Count; ++i)
                {
                    // Set the unifroms needed to draw the texture for this sampler
                    samplers[i].SetTile(mpb, quad.Level, quad.Tx, quad.Ty);
                }

                DrawMesh(quad, mesh, mpb);
            }
            else
            {
                // Draw quads in a order based on distance to camera
                var done = 0;

                var order = quad.CalculateOrder(LocalCameraPosition.x, LocalCameraPosition.y, quad.Ox + quad.LengthHalf, quad.Oy + quad.LengthHalf);

                for (byte i = 0; i < 4; ++i)
                {
                    if (quad.GetChild(order[i]).Visibility == Frustum.VISIBILITY.INVISIBLE)
                    {
                        done |= (1 << order[i]);
                    }
                    else if (quad.GetChild(order[i]).Drawable)
                    {
                        DrawQuad(quad.GetChild(order[i]), samplers, mesh, mpb);

                        done |= (1 << order[i]);
                    }
                }

                if (done < 15)
                {
                    // If the a leaf quad needs to be drawn but its tiles are not ready then this will draw the next parent tile instead that is ready.
                    // Because of the current set up all tiles always have there tasks run on the frame they are generated so this section of code is never reached.

                    for (byte i = 0; i < samplers.Count; ++i)
                    {
                        // Set the unifroms needed to draw the texture for this sampler
                        samplers[i].SetTile(mpb, quad.Level, quad.Tx, quad.Ty);
                    }

                    DrawMesh(quad, mesh, mpb);
                }
            }
        }
Exemple #9
0
 /// <summary>
 /// Creates a new <see cref="TerrainQuad"/>
 /// </summary>
 /// <param name="owner">The <see cref="TerrainNode"/> to which the terrain quadtree belongs.</param>
 /// <param name="parent">The <see cref="TerrainQuad"/> parent of this quad.</param>
 /// <param name="tx">The logical x coordinate of this quad.</param>
 /// <param name="ty">The logical y coordinate of this quad.</param>
 /// <param name="ox">The physical x coordinate of the lower left corner of this quad.</param>
 /// <param name="oy">The physical y coordinate of the lower left corner of this quad.</param>
 /// <param name="length">The physical size of this quad.</param>
 /// <param name="zmin">The minimum terrain elevation inside this quad.</param>
 /// <param name="zmax">The maximum terrain elevation inside this quad.</param>
 public TerrainQuad(TerrainNode owner, TerrainQuad parent, int tx, int ty, double ox, double oy, double length, float zmin, float zmax)
 {
     Owner    = owner;
     Parent   = parent;
     Level    = (Parent == null) ? 0 : Parent.Level + 1;
     Tx       = tx;
     Ty       = ty;
     Ox       = ox;
     Oy       = oy;
     ZMax     = zmax;
     ZMin     = zmin;
     Length   = length;
     LocalBox = new Box3d(Ox, Ox + Length, Oy, Oy + Length, ZMin, ZMax);
 }
Exemple #10
0
        private bool FindDrawableSamplers(TerrainQuad quad, List <TileSampler> samplers)
        {
            for (short i = 0; i < samplers.Count; ++i)
            {
                var producer = samplers[i].Producer;

                if (producer.HasTile(quad.Level, quad.Tx, quad.Ty) && producer.FindTile(quad.Level, quad.Tx, quad.Ty, false, true) == null)
                {
                    return(true);
                }
            }

            return(false);
        }
Exemple #11
0
        public Queue <TerrainQuad> Traverse(TerrainQuad root)
        {
            if (!root.IsVisible)
            {
                return(null);
            }
            if (!root.Drawable)
            {
                return(null);
            }

            var traverse   = new Queue <TerrainQuad>();
            var quadsQueue = new Queue <TerrainQuad>();
            var quadsSet   = new HashSet <TerrainQuad>();

            quadsQueue.Enqueue(root);
            quadsSet.Add(root);

            while (quadsQueue.Count > 0)
            {
                var currentQuad = quadsQueue.Dequeue();

                traverse.Enqueue(currentQuad);

                if (currentQuad.IsLeaf)
                {
                    quadsSet.Add(currentQuad);
                }
                else
                {
                    for (var i = 0; i < 4; ++i)
                    {
                        var currentQuadChild = currentQuad.GetChild(currentQuad.Order[i]);

                        if (!quadsSet.Contains(currentQuadChild) && (currentQuadChild.IsVisible && currentQuadChild.Drawable))
                        {
                            quadsQueue.Enqueue(currentQuadChild);
                            quadsSet.Add(currentQuadChild);
                        }
                    }
                }
            }

            return(traverse);
        }
Exemple #12
0
        public void FindDrawableQuads(TerrainQuad quad)
        {
            quad.Drawable = false;

            if (!quad.IsVisible)
            {
                quad.Drawable = true;

                return;
            }

            if (quad.IsLeaf)
            {
                if (FindDrawableSamplers(quad))
                {
                    return;
                }
            }
            else
            {
                byte drawableCount = 0;

                for (var i = 0; i < 4; ++i)
                {
                    var targetQuad = quad.GetChild(i);

                    FindDrawableQuads(targetQuad);

                    if (targetQuad.Drawable)
                    {
                        ++drawableCount;
                    }
                }

                if (drawableCount < 4)
                {
                    if (FindDrawableSamplers(quad))
                    {
                        return;
                    }
                }
            }

            quad.Drawable = true;
        }
Exemple #13
0
        /// <summary>
        /// Creates a new <see cref="TerrainQuad"/>
        /// </summary>
        /// <param name="owner">The <see cref="TerrainNode"/> to which the terrain quadtree belongs.</param>
        /// <param name="parent">The <see cref="TerrainQuad"/> parent of this quad.</param>
        /// <param name="tx">The logical x coordinate of this quad.</param>
        /// <param name="ty">The logical y coordinate of this quad.</param>
        /// <param name="ox">The physical x coordinate of the lower left corner of this quad.</param>
        /// <param name="oy">The physical y coordinate of the lower left corner of this quad.</param>
        /// <param name="length">The physical size of this quad.</param>
        /// <param name="zmin">The minimum terrain elevation inside this quad.</param>
        /// <param name="zmax">The maximum terrain elevation inside this quad.</param>
        public TerrainQuad(TerrainNode owner, TerrainQuad parent, int tx, int ty, double ox, double oy, double length, float zmin, float zmax)
        {
            Owner      = owner;
            Parent     = parent;
            Level      = (Parent == null) ? 0 : Parent.Level + 1;
            Tx         = tx;
            Ty         = ty;
            Ox         = ox;
            Oy         = oy;
            ZMax       = zmax;
            ZMin       = zmin;
            Length     = length;
            LengthHalf = length / 2.0;
            LocalBox   = new Box3d(Ox, Ox + Length, Oy, Oy + Length, ZMin, ZMax);

            // TODO : Hm. Maybe too heavy for a ctor? Threading? Hueading?
            CalculateMatrices(ox, oy, length, owner.ParentBody.Size);
        }
Exemple #14
0
        public void FindDrawableQuads(TerrainQuad quad, List <TileSampler> samplers)
        {
            quad.Drawable = false;

            if (!quad.IsVisible)
            {
                quad.Drawable = true;

                return;
            }

            if (quad.IsLeaf)
            {
                if (FindDrawableSamplers(quad, samplers))
                {
                    return;
                }
            }
            else
            {
                byte drawableCount = 0;

                for (byte i = 0; i < 4; ++i)
                {
                    FindDrawableQuads(quad.GetChild(i), samplers);

                    if (quad.GetChild(i).Drawable)
                    {
                        ++drawableCount;
                    }
                }

                if (drawableCount < 4)
                {
                    if (FindDrawableSamplers(quad, samplers))
                    {
                        return;
                    }
                }
            }

            quad.Drawable = true;
        }
Exemple #15
0
        public void SetPerQuadUniforms(TerrainQuad quad, MaterialPropertyBlock target)
        {
            // TODO : BOTTLENECK!
            Deformation.SetUniforms(this, quad, target);

            // TODO : Planet texturing...

            /*
             * var rootQuadSize = TerrainQuadRoot.Length;
             * var offset = new Vector4d(((double)quad.Tx / (1 << quad.Level) - 0.5) * rootQuadSize,
             *                        ((double)quad.Ty / (1 << quad.Level) - 0.5) * rootQuadSize,
             *                        rootQuadSize / (1 << quad.Level),
             *                        ParentBody.Size);
             *
             * target.SetVector("_Offset", offset.ToVector4());
             *
             * if (ParentBody.TCCPS != null) ParentBody.TCCPS.SetUniforms(target);
             */

            /*
             * if (ParentBody.TCCPS != null) ParentBody.TCCPS.SetUniforms(target);
             */
        }
Exemple #16
0
 public void SetPerQuadUniforms(TerrainQuad quad, MaterialPropertyBlock matPropertyBlock)
 {
     // TODO : BOTTLENECK!
     Deformation.SetUniforms(this, quad, matPropertyBlock);
 }