Files
2025-05-13 05:18:03 +03:00

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;
}
/**/
}