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