Пример #1
0
        public PlanetFace(PlanetFaceDirection direction, IMeshService ms, IDetailer ds, float baseRadius, int minDistance, int treeDepth, Zone3 range, ITextureService textureService)
        {
            //Apply params
            this.direction       = direction;
            this.maxResolutionAt = minDistance;
            this.maxDepth        = treeDepth;
            this.textureService  = textureService;
            this.meshService     = ms;
            this.detailService   = ds;
            this.radius          = baseRadius;

            //Create Gameobjects
            go = new GameObject("PlanetFace");

            //Create quadtree
            root = new QuadNode <ChunkData>(range);
            Vector2 topLeft     = new Vector2(0, 1);
            Vector2 topRight    = new Vector2(1, 1);
            Vector2 bottomRight = new Vector2(1, 0);
            Vector2 bottomLeft  = new Vector2(0, 0);

            GenerateChunkdata(
                root,
                //Default zone for root quadnode - covers whole 0:1 range
                new Zone2(
                    topLeft,
                    topRight,
                    bottomRight,
                    bottomLeft
                    )
                );
        }
            private void FillTexture(Texture2D t, Face face, NoiseOptions opts, float discrete = -1000)
            {
                float  w    = t.width - 1;
                float  h    = t.height - 1;
                Perlin perl = new Perlin();

                for (int i = 0; i <= w; i++)
                {
                    for (int j = 0; j <= h; j++)
                    {
                        float xp = 0, yp = 0, zp = 0;

                        switch (face)
                        {
                        case Face.Top:
                            yp = 1;
                            xp = (i / w) * 2 - 1;
                            zp = 1 - (j / h) * 2;
                            break;

                        case Face.Bottom:
                            yp = -1;
                            xp = (i / w) * 2 - 1;
                            zp = (j / h) * 2 - 1;
                            break;

                        case Face.Left:
                            xp = -1;
                            zp = 1 - (i / w) * 2;
                            yp = 1 - (j / h) * 2;
                            break;

                        case Face.Back:
                            zp = -1;
                            xp = (i / w) * 2 - 1;
                            yp = 1 - (j / h) * 2;
                            break;

                        case Face.Right:
                            xp = 1;
                            zp = (i / w) * 2 - 1;
                            yp = 1 - (j / h) * 2;
                            break;

                        case Face.Front:
                            zp = 1;
                            xp = 1 - (i / w) * 2;
                            yp = 1 - (j / h) * 2;
                            break;
                        }

                        Vector3 pos = IMeshService.Spherify(new Vector3(xp, yp, zp));

                        float n = perl.Sum(pos, opts);
                        t.SetPixel(i, j, (discrete <= 1 && discrete >= -1) ? (n < discrete ? a : b) : Color.Lerp(a, b, (n + 1) * 0.5f));
                    }
                }
            }
Пример #3
0
 public PlanetConfig(PlanetConfig other)
 {
     this.name     = other.name;
     this.radius   = other.radius;
     this.lodDepth = other.lodDepth;
     this.highestQualityAtDistance = other.highestQualityAtDistance;
     this.generationService        = other.generationService;
     this.textureService           = other.textureService;
     this.detailService            = other.detailService;
 }
Пример #4
0
        public PlanetFace(IMeshService ms, IDetailer ds, float baseRadius, int minDistance, int treeDepth, Range3d range, Material material)
        {
            //Apply params
            this.maxResolutionAt = minDistance;
            this.maxDepth        = treeDepth;
            this.material        = material;
            this.meshService     = ms;
            this.detailService   = ds;
            this.radius          = baseRadius;

            //Create Gameobjects
            go = new GameObject("PlanetFace");

            //Create quadtree
            root = new QuadNode <ChunkData>(range);
            GenerateChunkdata(root);
        }
        /// <summary>
        /// Get the normal of the planet at a certain point
        /// </summary>
        /// <param name="pos"></param>
        /// <param name="baseRadius"></param>
        /// <returns></returns>
        public Vector3 GetNormal(Vector3 pos, float baseRadius)
        {
            float   e  = 0.001f; //Some small value
            Vector3 p  = IMeshService.Spherify(pos);
            Vector3 p1 = new Vector3(pos.x + e, pos.y, pos.z);
            Vector3 p2 = new Vector3(pos.x, pos.y + e, pos.z);
            Vector3 p3 = new Vector3(pos.x, pos.y, pos.z + e);

            Vector3 a = p * SampleHeightmap(pos);
            Vector3 b = IMeshService.Spherify(p1) * SampleHeightmap(p1);
            Vector3 c = IMeshService.Spherify(p2) * SampleHeightmap(p2);
            Vector3 d = IMeshService.Spherify(p3) * SampleHeightmap(p3);

            Vector3 delta  = (b - a) + (c - a) + (d - a);
            Vector3 normal = delta - p * Vector3.Dot(delta, p) + p;

            return(normal.normalized);
        }
        /// <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);
        }
        public override MeshData Make(Vector3 topLeft, Vector3 topRight, Vector3 bottomLeft, Vector3 bottomRight, 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     = new Vector2(0, 0);
            Vector2 uvTopRight    = new Vector2(0, 1);
            Vector2 uvBottomLeft  = new Vector2(1, 0);
            Vector2 uvBottomRight = new Vector2(1, 1);

            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);
        }