Пример #1
0
        /// <summary>
        /// Create metadata from a quadnode
        /// </summary>
        /// <param name="node"></param>
        private void GenerateChunkdata(QuadNode <ChunkData> node, Zone2 region)
        {
            ChunkData data = new ChunkData();

            data.bounds     = null;
            data.breakpoint = maxResolutionAt * Mathf.Pow(2, maxDepth - node.depth);
            data.faceRegion = region;
            node.value      = data;
        }
Пример #2
0
        /// <summary>
        /// Scale region by a constant
        /// </summary>
        /// <param name="f"></param>
        /// <returns></returns>
        public Zone2 scale(float f)
        {
            Zone2 b = new Zone2();

            b.a = this.a * f;
            b.b = this.b * f;
            b.c = this.c * f;
            b.d = this.d * f;
            return(b);
        }
Пример #3
0
        /// <summary>
        /// Subdivide this range into 4 quadrants
        /// </summary>
        /// <param name="NE">North east zone</param>
        /// <param name="NW">North west zone</param>
        /// <param name="SE">South east zone</param>
        /// <param name="SW">South west zone</param>
        public void QuadSubdivide(out Zone2 NE, out Zone2 NW, out Zone2 SE, out Zone2 SW)
        {
            //Create 4 subdivided ranges
            Vector2 topl = this.a;
            Vector2 topr = this.b;
            Vector2 btnl = this.d;
            Vector2 btnr = this.c;

            Vector2 tc = Vector3.Lerp(topl, topr, 0.5f);
            Vector2 lm = Vector3.Lerp(topl, btnl, 0.5f);
            Vector2 rm = Vector3.Lerp(topr, btnr, 0.5f);
            Vector2 mc = Vector3.Lerp(lm, rm, 0.5f);
            Vector2 bc = Vector3.Lerp(btnl, btnr, 0.5f);

            NW = new Zone2(topl, tc, mc, lm);
            NE = new Zone2(tc, topr, rm, mc);
            SW = new Zone2(lm, mc, bc, btnl);
            SE = new Zone2(mc, rm, btnr, bc);
        }
        /// <summary>
        /// Make mesh
        /// </summary>
        /// <param name="topLeft"></param>
        /// <param name="topRight"></param>
        /// <param name="bottomLeft"></param>
        /// <param name="bottomRight"></param>
        /// <param name="radius"></param>
        /// <returns></returns>
        public override MeshData Make(Vector3 topLeft, Vector3 topRight, Vector3 bottomLeft, Vector3 bottomRight, Zone2 uvRange, float radius)
        {
            //Initial Calculations
            int width         = resolution + 2;
            int size          = width * width;
            int skirtVertices = useSkirts ? (width * 4) : 0;            //4 + resolution * 4;

            Vector3[] v = new Vector3[size + skirtVertices];
            Vector3[] n = new Vector3[size + skirtVertices];
            Vector2[] u = new Vector2[size + skirtVertices];
            int[]     t = new int[
                ((2 * (width - 1) * (width - 1)) * 3) +
                (useSkirts ? (6 * (skirtVertices - 1)) : 0)
                          ];

            //Initial Representivitive Normals and UVs
            Vector3 topNormal   = (topLeft - bottomLeft).normalized;
            Vector3 rightNormal = (topRight - topLeft).normalized;

            Vector2 uvTopLeft     = uvRange.a;
            Vector2 uvTopRight    = uvRange.b;
            Vector2 uvBottomLeft  = uvRange.d;
            Vector2 uvBottomRight = uvRange.c;

            float step = 1.0f / (resolution + 1);

            //Create Planar Faces
            int tidx = 0;

            for (int i = 0; i < width; i++)
            {
                for (int j = 0; j < width; j++)
                {
                    int idx = i + width * j;

                    //Create Vertice on Unit Cube
                    Vector3 rawPosition = Vector3.Lerp(
                        Vector3.Lerp(topLeft, topRight, i * step),
                        Vector3.Lerp(bottomLeft, bottomRight, i * step),
                        j * step
                        );

                    //Transform Vertice to Unit Sphere
                    Vector3 pos = IMeshService.Spherify(rawPosition);

                    //Sample Noise to Get Altitude
                    float alt = GetAltitude(rawPosition, radius);

                    v [idx] = pos * alt;

                    //Create UV for Texturing (optional)
                    Vector2 uv = Vector2.Lerp(
                        Vector2.Lerp(uvTopLeft, uvTopRight, i * step),
                        Vector2.Lerp(uvBottomLeft, uvBottomRight, i * step),
                        j * step
                        );
                    u[idx] = uv;

                    //Create Normals
                    //TODO take terrain shape into account
                    n[idx] = GetNormal(rawPosition, radius);

                    //Create Triangles
                    if (i > 0 && j > 0)
                    {
                        t[tidx++] = ((i - 1) + width * (j - 1));
                        t[tidx++] = ((i) + width * (j - 1));
                        t[tidx++] = (idx);

                        t[tidx++] = ((i - 1) + width * (j - 1));
                        t[tidx++] = (idx);
                        t[tidx++] = ((i - 1) + width * (j));
                    }
                }
            }

            //Create Skirts
            if (useSkirts)
            {
                for (int i = 0; i < width; i++)
                {
                    //Top
                    int     idx  = i;
                    Vector3 p    = v [idx];
                    Vector2 uv   = u [idx];
                    Vector3 norm = topNormal;
                    v [size + i] = p * skirtSize;
                    n [size + i] = norm;
                    u [size + i] = uv;
                    if (i != 0)
                    {
                        t [tidx++] = idx;
                        t [tidx++] = idx - 1;
                        t [tidx++] = size + (i - 1);

                        t [tidx++] = idx;
                        t [tidx++] = size + (i - 1);
                        t [tidx++] = size + i;
                    }

                    //Bottom
                    idx  = i + width * (width - 1);
                    p    = v [idx];
                    uv   = u [idx];
                    norm = -topNormal;
                    v [size + width + i] = p * skirtSize;
                    n [size + width + i] = norm;
                    u [size + width + i] = uv;
                    if (i != 0)
                    {
                        t [tidx++] = idx - 1;
                        t [tidx++] = idx;
                        t [tidx++] = size + (width + i);

                        t [tidx++] = idx - 1;
                        t [tidx++] = size + (width + i);
                        t [tidx++] = size + (width + i - 1);
                    }

                    //Left
                    idx  = 0 + width * (i);
                    p    = v [idx];
                    uv   = u [idx];
                    norm = -rightNormal;
                    v [size + 2 * width + i] = p * skirtSize;
                    n [size + 2 * width + i] = norm;
                    u [size + 2 * width + i] = uv;
                    if (i != 0)
                    {
                        t [tidx++] = width * (i - 1);
                        t [tidx++] = idx;
                        t [tidx++] = size + (2 * width + i);

                        t [tidx++] = width * (i - 1);
                        t [tidx++] = size + (2 * width + i);
                        t [tidx++] = size + (2 * width + i - 1);
                    }

                    //Right
                    idx  = (width - 1) + width * i;
                    p    = v [idx];
                    uv   = u [idx];
                    norm = rightNormal;
                    v [size + 3 * width + i] = p * skirtSize;
                    n [size + 3 * width + i] = norm;
                    u [size + 3 * width + i] = uv;
                    if (i != 0)
                    {
                        t [tidx++] = idx;
                        t [tidx++] = (width - 1) + width * (i - 1);
                        t [tidx++] = size + (3 * width + i - 1);

                        t [tidx++] = idx;
                        t [tidx++] = size + (3 * width + i - 1);
                        t [tidx++] = size + (3 * width + i);
                    }
                }
            }

            MeshData m = new MeshData();

            m.name = "Surface_r" + resolution;

            m.vertices  = v;
            m.uvs       = u;
            m.triangles = t;
            m.normals   = n;

            return(m);
        }
Пример #5
0
 public abstract MeshData Make(
     Vector3 topLeft, Vector3 topRight, Vector3 bottomLeft, Vector3 bottomRight,
     Zone2 uvRange,
     float radius
     );
Пример #6
0
        public override MeshData Make(Vector3 topLeft, Vector3 topRight, Vector3 bottomLeft, Vector3 bottomRight, Zone2 uvRange, float radius)
        {
            //Replace resolution with one matching out shader's threads
            //Resolution is number of vertices across any axis
            int resolution = (resolutionMultipler > 1 ? resolutionMultipler : 1) * numthreads.xy;             //Ensure multiple of xy

            //Initialize values
            int width = resolution;
            int size  = width * width;

            int num_vertices  = size;
            int num_normals   = size;
            int num_uvs       = size;
            int num_triangles = ((width - 1) * (width - 1)) * 6;

            //Create Buffers
            Vector3[] v = new Vector3[num_vertices];
            Vector3[] n = new Vector3[num_normals];
            Vector2[] u = new Vector2[num_uvs];
            int[]     t = new int[num_triangles];

            ComputeBuffer vb = new ComputeBuffer(v.Length, 3 * sizeof(float));              //3 floats * 4 bytes / float
            ComputeBuffer nb = new ComputeBuffer(n.Length, 3 * sizeof(float));
            ComputeBuffer ub = new ComputeBuffer(u.Length, 2 * sizeof(float));
            ComputeBuffer tb = new ComputeBuffer(t.Length, sizeof(int));

            //Transfer data to GPU
            shader.SetInt(arrayWidthParameter, width);
            shader.SetFloat(radiusParameter, radius);
            shader.SetVector(topLeftParameter, topLeft);
            shader.SetVector(topRightParameter, topRight);
            shader.SetVector(bottomLeftParameter, bottomLeft);
            shader.SetVector(bottomRightParameter, bottomRight);

            if (useSkirts)
            {
            }

            shader.SetBuffer(handle, vertexArray, vb);
            shader.SetBuffer(handle, normalArray, nb);
            shader.SetBuffer(handle, uvArray, ub);
            shader.SetBuffer(handle, triangleArray, tb);

            //Dispatch the shader
            shader.Dispatch(handle, width / numthreads.x, width / numthreads.y, 1);

            if (useSkirts)
            {
                //shader.Dispatch(skirtHandle, width / numthreads.x, 1, 1);
            }

            //Retrieve data from GPU
            vb.GetData(v);
            nb.GetData(n);
            ub.GetData(u);
            tb.GetData(t);

            //Dispose buffers to be cleaned up by GC
            vb.Dispose();
            nb.Dispose();
            ub.Dispose();
            tb.Dispose();

            //Create mesh
            MeshData m = new MeshData();

            m.name = "Surface_r" + resolution;

            m.vertices  = v;
            m.uvs       = u;
            m.triangles = t;
            m.normals   = n;

            return(m);
        }
Пример #7
0
        public override MeshData Make(Vector3 topLeft, Vector3 topRight, Vector3 bottomLeft, Vector3 bottomRight, Zone2 uvRange, float radius)
        {
            int width = subdivisions + 2;
            int size  = width * width;

            Vector3[]  v = new Vector3[size];
            Vector3[]  n = new Vector3[size];
            Vector2[]  u = new Vector2[size];
            List <int> t = new List <int>();

            Vector2 uvTopLeft     = uvRange.a;
            Vector2 uvTopRight    = uvRange.b;
            Vector2 uvBottomLeft  = uvRange.d;
            Vector2 uvBottomRight = uvRange.c;

            float step = 1.0f / (subdivisions + 1);

            for (int i = 0; i < width; i++)
            {
                for (int j = 0; j < width; j++)
                {
                    int idx = i + width * j;

                    //Create Vertice
                    Vector3 rawPosition = Vector3.Lerp(
                        Vector3.Lerp(topLeft, topRight, i * step),
                        Vector3.Lerp(bottomLeft, bottomRight, i * step),
                        j * step
                        );
                    Vector3 pos = IMeshService.Spherify(rawPosition);
                    v[idx] = pos * GetAltitude(pos, radius);;

                    //Create uv
                    Vector2 uv = Vector2.Lerp(
                        Vector2.Lerp(uvTopLeft, uvTopRight, i * step),
                        Vector2.Lerp(uvBottomLeft, uvBottomRight, i * step),
                        j * step
                        );
                    u[idx] = uv;

                    //Create normals
                    n[idx] = GetNormal(pos, radius);

                    //Create triangles
                    if (i > 0 && j > 0)
                    {
                        t.Add((i - 1) + width * (j - 1));
                        t.Add((i) + width * (j - 1));
                        t.Add(idx);

                        t.Add((i - 1) + width * (j - 1));
                        t.Add(idx);
                        t.Add((i - 1) + width * (j));
                    }
                }
            }

            MeshData m = new MeshData();

            m.name = "Surface_r" + subdivisions;

            m.vertices  = v;
            m.uvs       = u;
            m.triangles = t.ToArray();
            m.normals   = n;

            return(m);
        }