3 hours Code/Asset
Ok where to start, I have been busy following a tutorial and have come up with this, this code creates a cube then when you click on different vertices it makes the selected vertices go up or down in real time. I have been working on my commenting. It still needs more work.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class DeformableMesh : MonoBehaviour
{
public float pointDeformation = 0.01f;
Mesh mesh;
Material mat;
List<Vector3> Points;
List<Vector3> Verts;
List<int> Tris;
List<Vector2> UVs;
float size = 0.5f;
// Use to set up refernces between scripts Awake is called before Start.
// Is called after all objects are initialzed but before scripts are run.
void Awake ()
{
}
// Use this for initialization
void Start ()
{
Points = new List<Vector3>();
//Setting the poistions of the verts
Points.Add(new Vector3(-size, size,-size));
Points.Add(new Vector3( size, size,-size));
Points.Add(new Vector3( size,-size,-size));
Points.Add(new Vector3(-size,-size,-size));
Points.Add(new Vector3( size, size, size));
Points.Add(new Vector3(-size, size, size));
Points.Add(new Vector3(-size,-size, size));
Points.Add(new Vector3( size,-size, size));
Verts = new List<Vector3>();
Tris = new List<int>();
UVs = new List<Vector2>();
CreateMesh();
}
// Render update is called once per frame
void Update ()
{
// Controls to raise and lower points
// If its not working check the mesh collider mesh slot
if (Input.GetMouseButton(0))
{
RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit ))
{
RaisePoint(FindNearestPoint(hit.point));
Debug.Log(hit.point);
}
}
if (Input.GetMouseButton(1))
{
RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit))
{
LowerPoint(FindNearestPoint(hit.point));
}
}
}
// Pysics update is called once per 1/60 seconds
void FixedUpdate ()
{
}
private Vector3 FindNearestPoint(Vector3 point)
{
Vector3 NearestPoint = new Vector3();
float lastDistance = 99999999f;
for (int i = 0; i < Points.Count; i++)
{
float distance = GetDistance(point, Points[i]);
if (distance < lastDistance)
{
lastDistance = distance;
NearestPoint = Points[i];
}
}
return NearestPoint;
}
// Using math finding the distance between 2 points;
private float GetDistance(Vector3 start, Vector3 end)
{
return Mathf.Sqrt(Mathf.Pow((start.x - end.x), 2) + Mathf.Pow((start.y - end.y), 2) + Mathf.Pow((start.z - end.z), 2));
}
private void RaisePoint(Vector3 point)
{
int index = -1;
for (int i = 0; i < Points.Count; i++)
{
if (Points[i] == point)
{
index = i;
break;
}
}
if (index == -1)
{
Debug.LogError("Could not match points");
}
else
{
Vector3 newPoint = Points[index];
newPoint.y += pointDeformation;
Points[index] = newPoint;
UpdateMesh();
}
}
private void LowerPoint(Vector3 point)
{
int index = -1;
for (int i = 0; i < Points.Count; i++)
{
if (Points[i] == point)
{
index = i;
break;
}
}
if (index == -1)
{
Debug.LogError("Could not match points");
}
else
{
Vector3 newPoint = Points[index];
newPoint.y -= pointDeformation;
Points[index] = newPoint;
UpdateMesh();
}
}
private void CreateMesh()
{
// Adding the requite components to show a mesh
gameObject.AddComponent<MeshFilter>();
gameObject.AddComponent<MeshRenderer>();
gameObject.AddComponent<MeshCollider>();
mat = Resources.Load("Materials/Defualt") as Material;
if (mat == null)
{
Debug.LogError("Material not found");
return;
}
MeshFilter meshFilter = GetComponent<MeshFilter>();
if (meshFilter == null)
{
Debug.LogError("meshFilter not found");
return;
}
mesh = meshFilter.sharedMesh;
if (mesh == null)
{
meshFilter.mesh = new Mesh();
mesh = meshFilter.sharedMesh;
}
MeshCollider meshCollier = GetComponent<MeshCollider>();
if (meshCollier == null)
{
Debug.LogError("MeshCollider not found");
return;
}
mesh.Clear();
UpdateMesh();
}
private void UpdateMesh()
{
// Front Plane
Verts.Add(Points[0]); Verts.Add(Points[1]); Verts.Add(Points[2]); Verts.Add(Points[3]);
// Back Plane
Verts.Add(Points[4]); Verts.Add(Points[5]); Verts.Add(Points[6]); Verts.Add(Points[7]);
// Left Plane
Verts.Add(Points[5]); Verts.Add(Points[0]); Verts.Add(Points[3]); Verts.Add(Points[6]);
// Right Plane
Verts.Add(Points[1]); Verts.Add(Points[4]); Verts.Add(Points[7]); Verts.Add(Points[2]);
// Top Plane
Verts.Add(Points[5]); Verts.Add(Points[4]); Verts.Add(Points[1]); Verts.Add(Points[0]);
// Bottum Plane
Verts.Add(Points[3]); Verts.Add(Points[2]); Verts.Add(Points[7]); Verts.Add(Points[6]);
//Front Plane
Tris.Add(0); Tris.Add(1); Tris.Add(2);
Tris.Add(2); Tris.Add(3); Tris.Add(0);
//Back Plane
Tris.Add(4); Tris.Add(5); Tris.Add(6);
Tris.Add(6); Tris.Add(7); Tris.Add(4);
//Left Plane
Tris.Add(8); Tris.Add(9); Tris.Add(10);
Tris.Add(10); Tris.Add(11); Tris.Add(8);
//Right Plane
Tris.Add(12); Tris.Add(13); Tris.Add(14);
Tris.Add(14); Tris.Add(15); Tris.Add(12);
//Top Plane
Tris.Add(16); Tris.Add(17); Tris.Add(18);
Tris.Add(18); Tris.Add(19); Tris.Add(16);
//Bottum Plane
Tris.Add(20); Tris.Add(21); Tris.Add(22);
Tris.Add(22); Tris.Add(23); Tris.Add(20);
// Front Plane
UVs.Add(new Vector2(0, 1));
UVs.Add(new Vector2(1, 1));
UVs.Add(new Vector2(1, 0));
UVs.Add(new Vector2(0, 0));
// Back Plane
UVs.Add(new Vector2(0, 1));
UVs.Add(new Vector2(1, 1));
UVs.Add(new Vector2(1, 0));
UVs.Add(new Vector2(0, 0));
// Left Plane
UVs.Add(new Vector2(0, 1));
UVs.Add(new Vector2(1, 1));
UVs.Add(new Vector2(1, 0));
UVs.Add(new Vector2(0, 0));
// Right Plane
UVs.Add(new Vector2(0, 1));
UVs.Add(new Vector2(1, 1));
UVs.Add(new Vector2(1, 0));
UVs.Add(new Vector2(0, 0));
// Top Plane
UVs.Add(new Vector2(0, 1));
UVs.Add(new Vector2(1, 1));
UVs.Add(new Vector2(1, 0));
UVs.Add(new Vector2(0, 0));
// Bottum Plane
UVs.Add(new Vector2(0, 1));
UVs.Add(new Vector2(1, 1));
UVs.Add(new Vector2(1, 0));
UVs.Add(new Vector2(0, 0));
//Setting everything to arrays;
mesh.vertices = Verts.ToArray();
mesh.triangles = Tris.ToArray();
mesh.uv = UVs.ToArray();
//Clearing all the lists, so new ones can be created;
Verts.Clear();
Tris.Clear();
UVs.Clear();
//Telling unity to create the mesh with the above information
MeshCollider meshCollider = GetComponent<MeshCollider>();
mesh.RecalculateNormals();
mesh.RecalculateBounds();
RecalculateTangents(mesh);
meshCollider.sharedMesh = null; // need to set shared mesh to null before setting the mesh.
meshCollider.sharedMesh = mesh;
gameObject.GetComponent<Renderer>().material = mat; // To access the renderer you need to get the component
mesh.Optimize();
}
//Storing the data
private static void RecalculateTangents(Mesh mesh)
{
int[] triangles = mesh.triangles;
Vector3[] vertices = mesh.vertices;
Vector2[] uv = mesh.uv;
Vector3[] normals = mesh.normals;
int triangleCount = triangles.Length;
int vertexCount = vertices.Length;
Vector3[] tan1 = new Vector3[vertexCount];
Vector3[] tan2 = new Vector3[vertexCount];
Vector4[] tangents = new Vector4[vertexCount];
for (long a = 0; a < triangleCount; a += 3)
{
//Triangle Storage
long tris1 = triangles[a + 0];
long tris2 = triangles[a + 1];
long tris3 = triangles[a + 2];
//Vertices Storage
Vector3 verts1 = vertices[tris1];
Vector3 verts2 = vertices[tris2];
Vector3 verts3 = vertices[tris3];
//UV Storage
Vector2 w1 = uv[tris1];
Vector2 w2 = uv[tris2];
Vector2 w3 = uv[tris3];
//Verticies
float x1 = verts2.x - verts1.x;
float x2 = verts3.x - verts1.x;
float y1 = verts2.y - verts1.y;
float y2 = verts3.y - verts1.y;
float z1 = verts2.z - verts1.z;
float z2 = verts3.z - verts1.z;
//UVS
float s1 = w2.x - w1.x;
float s2 = w3.x - w1.x;
float t1 = w2.y - w1.y;
float t2 = w3.y - w1.y;
float div = s1 * t2 - s2 * t1;
float r = div == 0.0f ? 0.0f : 1.0f / div;
Vector3 sdir = new Vector3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r);
Vector3 tdir = new Vector3((s2 * x2 - s1 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r);
tan1[tris1] += sdir;
tan1[tris2] += sdir;
tan1[tris3] += sdir;
tan2[tris1] += tdir;
tan2[tris2] += tdir;
tan2[tris3] += tdir;
}
for (long a = 0; a < vertexCount; ++a)
{
Vector3 n = normals[a];
Vector3 t = tan1[a];
Vector3.OrthoNormalize(ref n, ref t);
tangents[a].x = t.x;
tangents[a].x = t.y;
tangents[a].x = t.z;
tangents[a].w = (Vector3.Dot(Vector3.Cross(n, t), tan2[a]) < 0.0f) ? -1.0f : 1.0f;
}
mesh.tangents = tangents;
}
}
No comments:
Post a Comment