Created
January 21, 2017 15:49
-
-
Save andrewzimmer906/3411d7f0903769fe0b1ab6706aca78c1 to your computer and use it in GitHub Desktop.
3D Model Generation for a Cloud Object
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using System.Collections; | |
using System.Collections.Generic; | |
enum Direction {Up, Down, West, East, North, South}; | |
public class Cloud : MonoBehaviour { | |
public int cloudSizeX = 2; | |
public int cloudSizeY = 2; | |
public int cloudSizeZ = 2; | |
private float centerX; | |
private float centerY; | |
private float centerZ; | |
private Mesh mesh; | |
private List<Vector3> verticies = new List<Vector3>(); | |
private List<int> triangles = new List<int>(); | |
private int squareCount; | |
public int maxTurbulence = 20; | |
public float turbulenceHeight = 1.2f; | |
public float turbulenceScale = 1f; | |
public float turbulenceSpeed = 0.05f; | |
public float startSeed = 0f; | |
private int[,,] turbulenceData; | |
public bool update = false; | |
void Start() { | |
mesh = GetComponent<MeshFilter> ().mesh; | |
CreateNoise (); | |
GenerateCloud (); | |
} | |
void CreateNoise() { | |
// we use plus 1 to account for the extra vertex | |
turbulenceData = new int[cloudSizeX + 1,cloudSizeY + 1, cloudSizeZ + 1]; | |
for (int x = 0; x <= cloudSizeX; x++) { | |
for (int y = 0; y <= cloudSizeY; y++) { | |
for (int z = 0; z <= cloudSizeZ; z++) { | |
turbulenceData [x, y, z] = PerlinNoise (x, y, z, turbulenceScale, maxTurbulence, 0); | |
} | |
} | |
} | |
} | |
void GenerateCloud() { | |
centerX = (float)cloudSizeX / 2f; | |
centerY = (float)cloudSizeY / 2f; | |
centerZ = (float)cloudSizeZ / 2f; | |
for (int x = 0; x < cloudSizeX; x++) { | |
for (int y = 0; y < cloudSizeY; y++) { | |
for (int z = 0; z < cloudSizeZ; z++) { | |
if (x == 0) { | |
AddSquare (x, y, z, Direction.West); | |
} else if (x == cloudSizeX - 1) { | |
AddSquare (x, y, z, Direction.East); | |
} | |
if (y == 0) { | |
AddSquare (x, y, z, Direction.Down); | |
} else if (y == cloudSizeY - 1) { | |
AddSquare (x, y, z, Direction.Up); | |
} | |
if (z == 0) { | |
AddSquare (x, y, z, Direction.South); | |
} else if (z == cloudSizeZ - 1) { | |
AddSquare (x, y, z, Direction.North); | |
} | |
} | |
} | |
} | |
UpdateMesh (); | |
} | |
/* -- Geometry -- */ | |
void AddSquare (int x, int y, int z, Direction direction) { | |
if (direction == Direction.Up || | |
direction == Direction.Down) { | |
AddFaceForTopBottom (x, y, z, direction); | |
} else if (direction == Direction.North || | |
direction == Direction.South) { | |
AddFaceForNorthSouth (x, y, z, direction); | |
} else if (direction == Direction.West || | |
direction == Direction.East) { | |
AddFaceForWestEast (x, y, z, direction); | |
} | |
squareCount++; // Add this line | |
} | |
void AddFaceForTopBottom(int x, int y, int z, Direction direction) { | |
if (direction == Direction.Up) { | |
y += 1; | |
} | |
verticies.Add (VertexForIndex (x, y , z + 1)); | |
verticies.Add (VertexForIndex (x + 1, y , z + 1)); | |
verticies.Add (VertexForIndex (x + 1, y, z)); | |
verticies.Add (VertexForIndex (x, y, z)); | |
if (direction == Direction.Up) { | |
AddLatestTriangles (true); | |
} else { | |
AddLatestTriangles (false); | |
} | |
} | |
void AddFaceForWestEast(int x, int y, int z, Direction direction) { | |
if (direction == Direction.East) { | |
x += 1; | |
} | |
verticies.Add (VertexForIndex (x, y + 1, z)); | |
verticies.Add (VertexForIndex (x, y + 1, z + 1)); | |
verticies.Add (VertexForIndex (x, y, z + 1)); | |
verticies.Add (VertexForIndex (x, y, z)); | |
if (direction == Direction.East) { | |
AddLatestTriangles (true); | |
} else { | |
AddLatestTriangles (false); | |
} | |
} | |
void AddFaceForNorthSouth(int x, int y, int z, Direction direction) { | |
if (direction == Direction.North) { | |
z += 1; | |
} | |
verticies.Add (VertexForIndex (x, y + 1, z)); | |
verticies.Add (VertexForIndex (x + 1, y + 1, z)); | |
verticies.Add (VertexForIndex (x + 1, y, z)); | |
verticies.Add (VertexForIndex (x, y, z)); | |
if (direction == Direction.South) { | |
AddLatestTriangles (true); | |
} else { | |
AddLatestTriangles (false); | |
} | |
} | |
Vector3 VertexForIndex(int x, int y, int z) { | |
return new Vector3 ( | |
x - centerX + turbulenceAtVertex(x, y, z), | |
y - centerY + turbulenceAtVertex(x, y, z), | |
z - centerZ + turbulenceAtVertex(x, y, z)); | |
} | |
void AddLatestTriangles(bool clockwise) { | |
if (clockwise) { | |
triangles.Add(squareCount * 4 ); // 1 | |
triangles.Add(squareCount * 4 + 1 ); // 2 | |
triangles.Add(squareCount * 4 + 2 ); // 3 | |
triangles.Add(squareCount * 4 ); // 1 | |
triangles.Add(squareCount * 4 + 2 ); // 3 | |
triangles.Add(squareCount * 4 + 3 ); // 4 | |
} else { | |
triangles.Add(squareCount * 4 + 2 ); // 3 | |
triangles.Add(squareCount * 4 + 1 ); // 2 | |
triangles.Add(squareCount * 4 ); // 1 | |
triangles.Add(squareCount * 4 + 3 ); // 4 | |
triangles.Add(squareCount * 4 + 2 ); // 3 | |
triangles.Add(squareCount * 4 ); // 1 | |
} | |
} | |
float turbulenceAtVertex(int x, int y, int z) { | |
int turbulenceDataAtVertex = turbulenceData [x, y, z]; | |
float tav = ((float)turbulenceDataAtVertex / (float)maxTurbulence) * turbulenceHeight; | |
return tav; | |
} | |
/* -- Updates -- */ | |
void UpdateMesh () { | |
mesh.Clear (); | |
mesh.vertices = verticies.ToArray(); | |
mesh.triangles = triangles.ToArray(); | |
mesh.Optimize (); | |
mesh.RecalculateNormals (); | |
// Reset back to factory | |
verticies.Clear(); | |
triangles.Clear(); | |
squareCount = 0; | |
} | |
void FixedUpdate() { | |
CreateNoise (); | |
GenerateCloud (); | |
transform.position = new Vector3 (transform.position.x + 0.005f, transform.position.y, transform.position.z + .005f); | |
} | |
/* -- Noise Creation -- */ | |
int PerlinNoise(int x, int y, int z, float scale, float height, float power){ | |
float rValue; | |
rValue = Noise.Noise.GetNoise (((double)x) / scale + (Time.timeSinceLevelLoad * turbulenceSpeed) + startSeed, | |
((double)y)/ scale + (Time.timeSinceLevelLoad * turbulenceSpeed) + startSeed, | |
((double)z)/ scale + (Time.timeSinceLevelLoad * turbulenceSpeed) + startSeed) - 0.5f; | |
rValue *= height; | |
if(power != 0){ | |
rValue=Mathf.Pow( rValue, power); | |
} | |
return (int) rValue; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment