212 lines
5.6 KiB
C#
212 lines
5.6 KiB
C#
using UnityEngine;
|
|||
|
|
using System.Collections;
|
||
|
|
using System.Collections.Generic;
|
||
|
|
using System;
|
||
|
|
|
||
|
|
public static class AdvancedUtils {
|
||
|
|
|
||
|
|
public static GameObject CreateMeshObject(string name){
|
||
|
|
GameObject result = new GameObject(name);
|
||
|
|
MeshFilter meshFilter = (MeshFilter)result.AddComponent(typeof(MeshFilter));
|
||
|
|
result.AddComponent(typeof(MeshRenderer));
|
||
|
|
|
||
|
|
Mesh m = new Mesh();
|
||
|
|
m.name = result.name;
|
||
|
|
meshFilter.sharedMesh = m;
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
public static GameObject CreateMeshObject(){
|
||
|
|
return CreateMeshObject ("Unnamed object");
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void GenerateCylinder(float radius, float length, int sides, int heightSegments,float uTile, float vTile, out Vector3[] vertices, out int[] indices, out Vector2[] uvs, out Vector3[] normals){
|
||
|
|
float yBottom = 0.0f;
|
||
|
|
Vector3 up = Vector3.up;
|
||
|
|
int ringVertexCount = (sides + 1);
|
||
|
|
int ringCount = heightSegments + 1;
|
||
|
|
int vertexCount = ringCount * ringVertexCount;
|
||
|
|
vertices = new Vector3[vertexCount];
|
||
|
|
uvs = new Vector2[vertices.Length];
|
||
|
|
normals = new Vector3[vertices.Length];
|
||
|
|
|
||
|
|
//generate vertices
|
||
|
|
for (int i = 0; i < ringVertexCount; ++i) {
|
||
|
|
float angle = ((Mathf.PI * 2.0f) / (float)sides) * (float)(i);
|
||
|
|
normals[i] = new Vector3(Mathf.Cos(angle), 0.0f, Mathf.Sin(angle));
|
||
|
|
vertices[i] = new Vector3(normals[i].x * radius, yBottom, normals[i].z * radius);
|
||
|
|
uvs[i] = new Vector2(((1.0f / (float)sides) * (float)i) * uTile, vTile);
|
||
|
|
}
|
||
|
|
|
||
|
|
for (int i = 1; i < ringCount; ++i) {
|
||
|
|
float ringY = (length / (float)heightSegments) * (float)i;
|
||
|
|
int ringVertexOffset = ringVertexCount * i;
|
||
|
|
for (int j = 0; j < ringVertexCount; ++j) {
|
||
|
|
vertices[ringVertexOffset + j] = vertices[j];
|
||
|
|
vertices[ringVertexOffset + j].y = ringY;
|
||
|
|
uvs[ringVertexOffset + j] = new Vector2(uvs[j].x, (1.0f - ((1.0f / (float)heightSegments) * (float)i)) * vTile);
|
||
|
|
normals[ringVertexOffset + j] = normals[j];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
//generate indices
|
||
|
|
int triangleCount = (2 * sides) * heightSegments;
|
||
|
|
indices = new int[triangleCount * 3];
|
||
|
|
int idOffset = 0;
|
||
|
|
for (int i = 0; i < heightSegments; ++i) {
|
||
|
|
int segmentVertexOffset = i * ringVertexCount;
|
||
|
|
int nextSegmentVertexOffset = (i + 1) * ringVertexCount;
|
||
|
|
|
||
|
|
for (int j = 0; j < sides; ++j) {
|
||
|
|
int sideOffset = segmentVertexOffset + j;
|
||
|
|
|
||
|
|
indices[idOffset + 0] = segmentVertexOffset + j;
|
||
|
|
indices[idOffset + 2] = nextSegmentVertexOffset + j + 1;
|
||
|
|
indices[idOffset + 1] = nextSegmentVertexOffset + j;
|
||
|
|
|
||
|
|
indices[idOffset + 3] = segmentVertexOffset + j;
|
||
|
|
indices[idOffset + 5] = segmentVertexOffset + j + 1;
|
||
|
|
indices[idOffset + 4] = nextSegmentVertexOffset + j + 1;
|
||
|
|
|
||
|
|
idOffset+=6;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public static int[] cubeIndices = new int[]{
|
||
|
|
3,2,7,
|
||
|
|
7,2,6,
|
||
|
|
1,0,5,
|
||
|
|
0,4,5,
|
||
|
|
0,1,2,
|
||
|
|
0,2,3,
|
||
|
|
4,6,5,
|
||
|
|
4,7,6,
|
||
|
|
0,3,4,
|
||
|
|
3,7,4,
|
||
|
|
2,1,6,
|
||
|
|
1,5,6
|
||
|
|
};
|
||
|
|
|
||
|
|
public static Vector3[] cubeVertices = new[]{
|
||
|
|
new Vector3(-0.5f, 0.5f, -0.5f),
|
||
|
|
new Vector3(-0.5f, 0.5f, 0.5f),
|
||
|
|
new Vector3(0.5f, 0.5f, 0.5f),
|
||
|
|
new Vector3(0.5f, 0.5f, -0.5f),
|
||
|
|
new Vector3(-0.5f, -0.5f, -0.5f),
|
||
|
|
new Vector3(-0.5f, -0.5f, 0.5f),
|
||
|
|
new Vector3(0.5f, -0.5f, 0.5f),
|
||
|
|
new Vector3(0.5f, -0.5f, -0.5f),
|
||
|
|
};
|
||
|
|
|
||
|
|
public static void CreateMeshCube(Matrix4x4 matrix, out Vector3[] vertices, out int[] indices){
|
||
|
|
indices = new int[cubeIndices.Length];
|
||
|
|
Array.Copy (cubeIndices, indices, cubeIndices.Length);
|
||
|
|
|
||
|
|
int vertexCount = cubeVertices.Length;
|
||
|
|
vertices = new Vector3[vertexCount];
|
||
|
|
for (int i = 0; i < vertexCount; ++i) {
|
||
|
|
vertices[i] = matrix.MultiplyPoint3x4(cubeVertices[i]);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
public static GameObject FindChild(GameObject parent, string childName){
|
||
|
|
if (parent == null) {
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
var tf = parent.transform.FindChild (childName);
|
||
|
|
return tf == null ? null : tf.gameObject;
|
||
|
|
}
|
||
|
|
|
||
|
|
public static List<Vector3> CutMesh(Vector3[] vertices, int[] indices, Plane p){
|
||
|
|
List<Vector3> cuttedTriangles = new List<Vector3> ();
|
||
|
|
|
||
|
|
int cut = 0;
|
||
|
|
int notCut = 0;
|
||
|
|
|
||
|
|
bool[] sideFlags = new bool[3];
|
||
|
|
|
||
|
|
for (int i = 0; i < indices.Length; i+=3) {
|
||
|
|
int outside = 0;
|
||
|
|
int lastOutsideId = 0;
|
||
|
|
int lastInsideId = 0;
|
||
|
|
for(int j = 0; j < 3; ++j){
|
||
|
|
sideFlags[j] = p.GetSide(vertices[indices[i + j]]);
|
||
|
|
if(sideFlags[j]){
|
||
|
|
outside++;
|
||
|
|
lastOutsideId = j;
|
||
|
|
}else{
|
||
|
|
lastInsideId = j;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if( outside ==3){
|
||
|
|
notCut++;
|
||
|
|
}else{
|
||
|
|
cut++;
|
||
|
|
}
|
||
|
|
|
||
|
|
switch(outside)
|
||
|
|
{
|
||
|
|
case 0:
|
||
|
|
for(int j = 0; j < 3; ++j){
|
||
|
|
cuttedTriangles.Add(vertices[indices[i + j]]);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
case 1:
|
||
|
|
{
|
||
|
|
Vector3 v0 = vertices[indices[i + lastOutsideId]];
|
||
|
|
Vector3 v1 = vertices[indices[i + (lastOutsideId + 1) % 3]];
|
||
|
|
Vector3 v2 = vertices[indices[i + (lastOutsideId + 2) % 3]];
|
||
|
|
|
||
|
|
float d0 = p.GetDistanceToPoint(v0);
|
||
|
|
float d1 = p.GetDistanceToPoint(v1);
|
||
|
|
float d2 = p.GetDistanceToPoint(v2);
|
||
|
|
|
||
|
|
float a = d0 / (d0 - d1);
|
||
|
|
float b = d0 / (d0 - d2);
|
||
|
|
|
||
|
|
Vector3 v3 = v0 + (v1 - v0) * a;
|
||
|
|
Vector3 v4 = v0 + (v2 - v0) * b;
|
||
|
|
|
||
|
|
|
||
|
|
cuttedTriangles.Add(v2);
|
||
|
|
cuttedTriangles.Add(v4);
|
||
|
|
cuttedTriangles.Add(v3);
|
||
|
|
|
||
|
|
cuttedTriangles.Add(v2);
|
||
|
|
cuttedTriangles.Add(v3);
|
||
|
|
cuttedTriangles.Add(v1);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
case 2:
|
||
|
|
{
|
||
|
|
Vector3 v0 = vertices[indices[i + lastInsideId]];
|
||
|
|
Vector3 v1 = vertices[indices[i + (lastInsideId + 1) % 3]];
|
||
|
|
Vector3 v2 = vertices[indices[i + (lastInsideId + 2) % 3]];
|
||
|
|
|
||
|
|
float d0 = p.GetDistanceToPoint(v0);
|
||
|
|
float d1 = p.GetDistanceToPoint(v1);
|
||
|
|
float d2 = p.GetDistanceToPoint(v2);
|
||
|
|
|
||
|
|
float a = d0 / (d0 - d1);
|
||
|
|
float b = d0 / (d0 - d2);
|
||
|
|
|
||
|
|
Vector3 v3 = v0 + (v1 - v0) * a;
|
||
|
|
Vector3 v4 = v0 + (v2 - v0) * b;
|
||
|
|
|
||
|
|
cuttedTriangles.Add(v0);
|
||
|
|
cuttedTriangles.Add(v3);
|
||
|
|
cuttedTriangles.Add(v4);
|
||
|
|
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return cuttedTriangles;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**/
|
||
|
|
}
|