| using FalcoEngine;
using System;
using System.Collections;
using System.Collections.Generic;
public class MeshGenerator : MonoBehaviour
{
public Material material1;
public Material material2;
public Slider segmentsSlider;
public Text segmentsText;
GameObject sphere = null;
GameObject cube = null;
MeshRenderer sphereMeshRenderer = null;
Mesh sphereMesh = null;
MeshRenderer cubeMeshRenderer = null;
Mesh cubeMesh = null;
void Start()
{
//Sphere
sphere = new GameObject();
sphere.transform.position = transform.position + new Vector3(3, 0, 0);
sphere.transform.scale = new Vector3(1.8f, 1.8f, 1.8f);
sphereMeshRenderer = sphere.AddComponent<MeshRenderer>();
sphereMesh = new Mesh();
RebuildSphere(sphereMesh, 24);
//Cube
cube = new GameObject();
cube.transform.position = transform.position + new Vector3(-3, 0, 0);
cube.transform.scale = new Vector3(1.5f, 1.5f, 1.5f);
cubeMeshRenderer = cube.AddComponent<MeshRenderer>();
cubeMesh = new Mesh();
RebuildCube(cubeMesh);
//UI
segmentsSlider.SetProgress(24 / 100.0f);
segmentsSlider.OnChange += SegmentsSlider_OnChange;
}
private void SegmentsSlider_OnChange(float value)
{
int count = (int)(value * 100.0f);
segmentsText.text = count.ToString();
RebuildSphere(sphereMesh, count);
}
void Update()
{
float speed = 20.0f * Time.deltaTime;
sphere.transform.rotation *= Quaternion.Euler(speed, 0.0f, speed);
cube.transform.rotation *= Quaternion.Euler(speed, 0.0f, speed);
}
void CalculateTangentSpace(List<int> indices, List<Vector3> vertices, List<Vector3> normals, List<Vector3> tangents, List<Vector3> bitangents, List<Vector2> texCoords)
{
//Calculate normals + tangents + bitangents
for (int i = 0; i < indices.Count; i += 3)
{
//Normals
int id0 = indices[i + 0];
int id1 = indices[i + 1];
int id2 = indices[i + 2];
Vector3 v1 = vertices[id0];
Vector3 v2 = vertices[id1];
Vector3 v3 = vertices[id2];
Vector3 normalA = Vector3.Normalize(Vector3.Cross(v2 - v1, v3 - v1));
normals[id0] = normalA;
normals[id1] = normalA;
normals[id2] = normalA;
//Tangent space
Vector3 deltaPos = Vector3.zero;
if (v1 == v2)
deltaPos = v3 - v1;
else
deltaPos = v2 - v1;
Vector2 uv0 = texCoords[id0];
Vector2 uv1 = texCoords[id1];
Vector2 deltaUV1 = uv1 - uv0;
Vector3 tan = Vector3.zero; // tangent
Vector3 bin = Vector3.zero; // binormal
// avoid divion with 0
if (deltaUV1.x != 0)
tan = deltaPos / deltaUV1.x;
else
tan = deltaPos / 1.0f;
tan = Vector3.Normalize(tan - Vector3.Dot(normalA, tan) * normalA);
bin = Vector3.Normalize(Vector3.Cross(tan, normalA));
tangents[id0] = tan;
bitangents[id0] = bin;
tangents[id1] = tan;
bitangents[id1] = bin;
tangents[id2] = tan;
bitangents[id2] = bin;
}
}
void RebuildSphere(Mesh mesh, int size)
{
while (mesh.subMeshCount > 0)
{
mesh.GetSubMesh(0).Dispose();
mesh.RemoveSubMesh(0);
}
SubMesh subMesh = new SubMesh();
List<Vector3> vertices = new List<Vector3>();
List<Vector3> normals = new List<Vector3>();
List<Vector3> tangents = new List<Vector3>();
List<Vector3> bitangents = new List<Vector3>();
List<Vector2> texCoords = new List<Vector2>();
List<int> indices = new List<int>();
float radius = 1.0f;
int sectorCount = size;
int stackCount = size / 2;
float x, y, z, xy; // position
float s, t; // texCoord
float sectorStep = 2 * Mathf.PI / sectorCount;
float stackStep = Mathf.PI / stackCount;
float sectorAngle, stackAngle;
for (int i = 0; i <= stackCount; ++i)
{
stackAngle = Mathf.PI / 2 - i * stackStep;
xy = radius * Mathf.Cos(stackAngle);
z = radius * Mathf.Sin(stackAngle);
for (int j = 0; j <= sectorCount; ++j)
{
sectorAngle = j * sectorStep; // starting from 0 to 2pi
// vertex position (x, y, z)
x = xy * Mathf.Cos(sectorAngle);
y = xy * Mathf.Sin(sectorAngle);
vertices.Add(new Vector3(x, y, z));
// vertex tex coord (s, t) range between [0, 1]
s = (float)j / (float)sectorCount;
t = (float)i / (float)stackCount;
texCoords.Add(new Vector2(s, t));
}
}
int k1, k2;
for (int i = 0; i < stackCount; ++i)
{
k1 = i * (sectorCount + 1);
k2 = k1 + sectorCount + 1;
for (int j = 0; j < sectorCount; ++j, ++k1, ++k2)
{
if (i != 0)
{
indices.Add(k1);
indices.Add(k2);
indices.Add(k1 + 1);
}
// k1+1 => k2 => k2+1
if (i != (stackCount - 1))
{
indices.Add(k1 + 1);
indices.Add(k2);
indices.Add(k2 + 1);
}
}
}
normals.AddRange(new Vector3[vertices.Count]);
tangents.AddRange(new Vector3[vertices.Count]);
bitangents.AddRange(new Vector3[vertices.Count]);
CalculateTangentSpace(indices, vertices, normals, tangents, bitangents, texCoords);
subMesh.vertices = vertices.ToArray();
subMesh.normals = normals.ToArray();
subMesh.tangents = tangents.ToArray();
subMesh.bitangents = bitangents.ToArray();
subMesh.texcoords0 = texCoords.ToArray();
subMesh.indices = indices.ToArray();
vertices.Clear();
normals.Clear();
tangents.Clear();
bitangents.Clear();
texCoords.Clear();
indices.Clear();
mesh.AddSubMesh(subMesh);
mesh.Commit();
sphereMeshRenderer.mesh = mesh;
sphereMeshRenderer.SetSharedMaterial(0, material1);
}
void RebuildCube(Mesh mesh)
{
while (mesh.subMeshCount > 0)
{
mesh.GetSubMesh(0).Dispose();
mesh.RemoveSubMesh(0);
}
SubMesh subMesh = new SubMesh();
List<Vector3> vertices = new List<Vector3>(new Vector3[24]
{
new Vector3(-1.0f, 1.0f, 1.0f),
new Vector3( 1.0f, 1.0f, 1.0f),
new Vector3( -1.0f, -1.0f, 1.0f),
new Vector3( 1.0f, -1.0f, 1.0f),
new Vector3(-1.0f, 1.0f, -1.0f),
new Vector3(1.0f, 1.0f, -1.0f),
new Vector3(-1.0f, -1.0f, -1.0f),
new Vector3(1.0f, -1.0f, -1.0f),
new Vector3(-1.0f, 1.0f, 1.0f),
new Vector3(1.0f, 1.0f, 1.0f),
new Vector3(-1.0f, 1.0f, -1.0f),
new Vector3(1.0f, 1.0f, -1.0f),
new Vector3(-1.0f, -1.0f, 1.0f),
new Vector3(1.0f, -1.0f, 1.0f),
new Vector3(-1.0f, -1.0f, -1.0f),
new Vector3(1.0f, -1.0f, -1.0f),
new Vector3(1.0f, -1.0f, 1.0f),
new Vector3(1.0f, 1.0f, 1.0f),
new Vector3(1.0f, -1.0f, -1.0f),
new Vector3(1.0f, 1.0f, -1.0f),
new Vector3(-1.0f, -1.0f, 1.0f),
new Vector3(-1.0f, 1.0f, 1.0f),
new Vector3(-1.0f, -1.0f, -1.0f),
new Vector3(-1.0f, 1.0f, -1.0f),
});
List<Vector3> normals = new List<Vector3>();
List<Vector3> tangents = new List<Vector3>();
List<Vector3> bitangents = new List<Vector3>();
List<Vector2> texCoords = new List<Vector2>(new Vector2[24]
{
new Vector2(0, 0),
new Vector2(1, 0),
new Vector2(0, 1),
new Vector2(1, 1),
new Vector2(0, 0),
new Vector2(1, 0),
new Vector2(0, 1),
new Vector2(1, 1),
new Vector2(0, 0),
new Vector2(1, 0),
new Vector2(0, 1),
new Vector2(1, 1),
new Vector2(0, 0),
new Vector2(1, 0),
new Vector2(0, 1),
new Vector2(1, 1),
new Vector2(0, 0),
new Vector2(1, 0),
new Vector2(0, 1),
new Vector2(1, 1),
new Vector2(0, 0),
new Vector2(1, 0),
new Vector2(0, 1),
new Vector2(1, 1),
});
List<int> indices = new List<int>(new int[36]
{
0, 2, 1,
1, 2, 3,
4, 5, 6,
5, 7, 6,
14, 15, 13,
14, 13, 12,
11, 10, 9,
9, 10, 8,
16, 18, 17,
17, 18, 19,
20, 21, 22,
21, 23, 22,
});
normals.AddRange(new Vector3[vertices.Count]);
tangents.AddRange(new Vector3[vertices.Count]);
bitangents.AddRange(new Vector3[vertices.Count]);
CalculateTangentSpace(indices, vertices, normals, tangents, bitangents, texCoords);
subMesh.vertices = vertices.ToArray();
subMesh.normals = normals.ToArray();
subMesh.tangents = tangents.ToArray();
subMesh.bitangents = bitangents.ToArray();
subMesh.texcoords0 = texCoords.ToArray();
subMesh.indices = indices.ToArray();
vertices.Clear();
normals.Clear();
tangents.Clear();
bitangents.Clear();
texCoords.Clear();
indices.Clear();
mesh.AddSubMesh(subMesh);
mesh.Commit();
cubeMeshRenderer.mesh = mesh;
cubeMeshRenderer.SetSharedMaterial(0, material2);
}
}
|