Beispiel #1
0
    private void GenerateTerrain()
    {
        GameObject = new GameObject
        {
            name  = "Patch_LOD_ " + SplitLevel + " : [" + Up + "]",
            layer = Sphere.gameObject.layer
        };

        Mesh = new Mesh();
        Data = new PatchData(PatchSettings.Vertices);

        var origin  = Volume.Vertices[0];
        var spacing = Size / (PatchSettings.VerticesPerSide - 1);

        for (ushort y = 0; y < PatchSettings.VerticesPerSide; y++)
        {
            var offset = origin;

            for (ushort x = 0; x < PatchSettings.VerticesPerSide; x++)
            {
                var vertex = offset;

                Data.Vertices.Add(vertex.NormalizeToRadius(Sphere.Radius));
                Data.Normals.Add(vertex.normalized);
                Data.Volume.Add(offset);

                Data.UV1.Add(VectorHelper.CartesianToPolarUV(vertex));
                Data.UV2.Add(new Vector2(0, 0));

                offset += Right * spacing;
            }

            origin -= Front * spacing;
        }

        //update projected center
        MiddleProjected = MiddleProjected.NormalizeToRadius(Sphere.Radius);

        //save original parent transformations
        var parentPosition = Sphere.gameObject.transform.position;
        var parentRotation = Sphere.gameObject.transform.rotation;

        //reset parent transformations before assigning data (so our vertices will be centered on the parent transform)
        Sphere.gameObject.transform.position = Vector3.zero;
        Sphere.gameObject.transform.rotation = Quaternion.identity;

        //put this node as a child of parent
        GameObject.transform.parent = Sphere.gameObject.transform;

        var indices = Sphere.PatchManager.Patches[Edges];

        //assign data to this node's mesh
        Mesh.SetVertices(Data.Vertices);
        Mesh.SetNormals(Data.Normals);
        Mesh.SetTriangles(indices, 0);
        Mesh.SetUVs(0, Data.UV1);
        Mesh.SetUVs(1, Data.UV2);

        Mesh.hideFlags = HideFlags.HideAndDontSave;

        Mesh.SolveTangents(ref indices, ref Data.Vertices, ref Data.Normals, ref Data.UV1);
        Mesh.RecalculateBounds();

        //restore parent transformations
        Sphere.gameObject.transform.position = parentPosition;
        Sphere.gameObject.transform.rotation = parentRotation;

        NeedsTerrain = false;

        //discard parent's resources
        if (Parent != null)
        {
            Parent.DestroyNode();
        }

        var patch      = GameObject.AddComponent <Patch>();
        var meshFilter = GameObject.AddComponent <MeshFilter>();

        GameObject.AddComponent <MeshRenderer>();
        GameObject.GetComponent <MeshRenderer>().sharedMaterial = MaterialHelper.CreateTemp(Sphere.Shader, "Patch");

        meshFilter.mesh = Mesh;
        patch.PatchTree = this;
    }
Beispiel #2
0
    private void GenerateTerrain()
    {
        GameObject = new GameObject
        {
            name  = "Patch_LOD_ " + SplitLevel + " : [" + Up + "]",
            layer = Sphere.gameObject.layer
        };

        Mesh = new Mesh();
        Data = new PatchData(PatchSettings.Vertices);

        var origin = Volume.Vertices[0];

        var vertStep  = Size / (PatchSettings.VerticesPerSide - 1); //vertex spacing
        var startHMap = 1.0f;
        var endHMap   = 1.0f - startHMap;

        var uCoord = startHMap;
        var vCoord = startHMap;                                                   //uv coordinates for the heightmap

        var uvStep = (endHMap - startHMap) / (PatchSettings.VerticesPerSide - 1); //hmap uv step size inside the loop

        var uVolCoord = Volume.UVs[0].x;
        var vVolCoord = Volume.UVs[0].y;                                                              //flat uv coordinates for the cube face

        var volCoordStep = (Volume.UVs[1].x - Volume.UVs[0].x) / (PatchSettings.VerticesPerSide - 1); //step size of flat uv inside the loop
        var idx          = 0;

        for (ushort y = 0; y < PatchSettings.VerticesPerSide; y++)
        {
            var offset = origin;

            uCoord    = startHMap;
            uVolCoord = Volume.UVs[0].x;

            for (ushort x = 0; x < PatchSettings.VerticesPerSide; x++)
            {
                //heightmap texture coordinates
                Data.UV1[idx] = new Vector2(uCoord, vCoord);
                uCoord       += uvStep;

                //volume texture coordinates
                //x,y = flat volume uv coordinates
                //z = vertex slope
                Data.UV2[idx] = new Vector2(uVolCoord, vVolCoord);
                uVolCoord    += volCoordStep;

                //calculate vertex position
                var vtx = offset;

                //use normalized vertex position as vertex normal
                vtx.Normalize();
                Data.Normals[idx] = vtx;

                //scale to sphere
                vtx = vtx * Sphere.Radius;

                //store
                Data.Vertices[idx] = vtx;
                Data.Volume[idx]   = offset;

                idx++;
                offset += Right * vertStep;
            }

            origin    -= Front * vertStep;
            vCoord    += uvStep;
            vVolCoord += volCoordStep;
        }

        //update projected center
        MiddleProjected = MiddleProjected.NormalizeToRadius(Sphere.Radius);

        //save original parent transformations
        var parentPosition = Sphere.gameObject.transform.position;
        var parentRotation = Sphere.gameObject.transform.rotation;

        //reset parent transformations before assigning data (so our vertices will be centered on the parent transform)
        Sphere.gameObject.transform.position = Vector3.zero;
        Sphere.gameObject.transform.rotation = Quaternion.identity;

        //put this node as a child of parent
        GameObject.transform.parent = Sphere.gameObject.transform;

        //assign data to this node's mesh
        Mesh.SetVertices(Data.Vertices.ToList());
        Mesh.SetUVs(0, Data.UV1.ToList());
        Mesh.SetUVs(1, Data.UV2.ToList());
        Mesh.SetNormals(Data.Normals.ToList());
        Mesh.SetTriangles(Sphere.PatchManager.Patches[Edges], 0);
        Mesh.hideFlags = HideFlags.DontSave;

        MeshFactory.SolveTangents(Mesh);

        Mesh.RecalculateBounds();

        //restore parent transformations
        Sphere.gameObject.transform.position = parentPosition;
        Sphere.gameObject.transform.rotation = parentRotation;

        NeedsTerrain = false;

        //discard parent's resources
        if (Parent != null)
        {
            Parent.DestroyNode();
        }

        var patch      = GameObject.AddComponent <Patch>();
        var meshFilter = GameObject.AddComponent <MeshFilter>();

        GameObject.AddComponent <MeshRenderer>();
        GameObject.GetComponent <MeshRenderer>().sharedMaterial = MaterialHelper.CreateTemp(Sphere.Shader, "Patch");

        meshFilter.mesh = Mesh;
        patch.PatchTree = this;
    }