*
This commit is contained in:
@@ -0,0 +1,201 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
|
||||
|
||||
[ExecuteInEditMode]
|
||||
public class Diaphragm : MonoBehaviour {
|
||||
public float OutsideDiameter = 1.0f;
|
||||
public float MaxAperture = 0.75f;
|
||||
public float MinAperture = 0.05f;
|
||||
public int LeafCount = 15;
|
||||
public float LeafDegreeLength = 140.0f;
|
||||
public int LeafLengthTesselation = 10;
|
||||
public float LeafThickness = 0.005f;
|
||||
public Material material;
|
||||
public bool DrawDebugLines = true;
|
||||
public bool updateInEditor = false;
|
||||
|
||||
|
||||
public float MaxLeafAngle = 50.0f;
|
||||
[Range(0.0f,1.0f)]
|
||||
public float State = 0.0f;
|
||||
// Use this for initialization
|
||||
void Start () {
|
||||
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update () {
|
||||
UpdateLeafs ();
|
||||
}
|
||||
|
||||
///Vector2//Vec
|
||||
|
||||
void UpdateLeafs(){
|
||||
if (transform.childCount > LeafCount) {
|
||||
int cntRemove = transform.childCount - LeafCount;
|
||||
GameObject[] removeArray = new GameObject[cntRemove];
|
||||
for (int i = 0; i < cntRemove; ++i) {
|
||||
removeArray [i] = transform.GetChild (i).gameObject;
|
||||
}
|
||||
foreach (GameObject go in removeArray) {
|
||||
go.transform.parent = null;
|
||||
DestroyImmediate (go);
|
||||
}
|
||||
} else {
|
||||
int cntAdd = LeafCount - transform.childCount;
|
||||
for (int i = 0; i < cntAdd; ++i) {
|
||||
GameObject obj = AdvancedUtils.CreateMeshObject();
|
||||
obj.renderer.sharedMaterial = material;
|
||||
obj.transform.parent = transform;
|
||||
}
|
||||
}
|
||||
|
||||
float jointsRadius = (OutsideDiameter * 0.5f + MaxAperture * 0.5f) * 0.5f;
|
||||
for (int i = 0; i < LeafCount; ++i) {
|
||||
float leafAngle = (360.0f / (float)LeafCount) * (float)i;
|
||||
|
||||
GameObject go = transform.GetChild (i).gameObject;
|
||||
go.transform.localPosition = GetLeafPosition(i);
|
||||
go.transform.localRotation = Quaternion.identity;
|
||||
go.transform.localScale = new Vector3(1,1,1);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int leafsCount = transform.childCount;
|
||||
|
||||
float rotation = MaxLeafAngle * State;
|
||||
|
||||
for (int i = 0; i < leafsCount; ++i) {
|
||||
GameObject obj = transform.GetChild(i).gameObject;
|
||||
|
||||
if (DrawDebugLines) {
|
||||
AdvancedGizmo.DrawCircle(obj.transform.position, Vector3.up, 0.02f, Color.blue, 12, false, 2);
|
||||
|
||||
}
|
||||
|
||||
var mf = obj.GetComponent<MeshFilter>();
|
||||
Mesh m = mf.sharedMesh;
|
||||
|
||||
float leafWidth = (OutsideDiameter - MaxAperture) * 0.5f;
|
||||
float leafAngularOffset = (360.0f / (float)LeafCount) * (float)i;
|
||||
|
||||
int planeVertCnt = (LeafLengthTesselation + 1) * 2;
|
||||
int totalVertCnt = planeVertCnt * 4;
|
||||
|
||||
float innerRadius = MaxAperture * 0.5f;
|
||||
float outerRadius = OutsideDiameter * 0.5f;
|
||||
Vector3 leafPosition = GetLeafPosition(i);
|
||||
|
||||
float angleBetweenPivots = 360.0f / leafsCount;
|
||||
|
||||
float angularElevation = LeafThickness / angleBetweenPivots;
|
||||
|
||||
float sectionAngularLength = LeafDegreeLength / (float)LeafLengthTesselation;
|
||||
|
||||
//generate vertices& uvs
|
||||
Vector3[] vertices = new Vector3[totalVertCnt];
|
||||
Vector2[] uvs = new Vector2[vertices.Length];
|
||||
|
||||
for(int j = 0; j <= LeafLengthTesselation; ++j){
|
||||
float elevation = angularElevation * sectionAngularLength * (float)j;
|
||||
Vector3 elevationVector = Vector3.up * - elevation;
|
||||
|
||||
Vector3 sliceDirection = Quaternion.AngleAxis(leafAngularOffset + sectionAngularLength * (float)j, Vector3.up) * Vector3.forward;
|
||||
int sliceVertexOffset = j * 8;
|
||||
|
||||
vertices[sliceVertexOffset + 0] = sliceDirection * outerRadius - leafPosition + elevationVector;
|
||||
vertices[sliceVertexOffset + 1] = sliceDirection * innerRadius - leafPosition + elevationVector;
|
||||
vertices[sliceVertexOffset + 2] = vertices[sliceVertexOffset + 1];
|
||||
vertices[sliceVertexOffset + 3] = vertices[sliceVertexOffset + 1] + Vector3.up * (-LeafThickness);
|
||||
|
||||
vertices[sliceVertexOffset + 4] = vertices[sliceVertexOffset + 3];
|
||||
vertices[sliceVertexOffset + 5] = vertices[sliceVertexOffset + 0] + Vector3.up * (-LeafThickness);
|
||||
vertices[sliceVertexOffset + 6] = vertices[sliceVertexOffset + 5];
|
||||
vertices[sliceVertexOffset + 7] = vertices[sliceVertexOffset + 0];
|
||||
|
||||
float u = (1.0f / (float)LeafLengthTesselation) * (float)j;
|
||||
for(int k = 0; k < 8; ++k){
|
||||
uvs[sliceVertexOffset + k] = new Vector2(u,k%2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//triangulate
|
||||
const int trianglePerSection = 8;
|
||||
int totalTriangles = trianglePerSection * LeafLengthTesselation;
|
||||
const int indicesPerSection = trianglePerSection * 3;
|
||||
int totalIndices = indicesPerSection * LeafLengthTesselation;
|
||||
int[] indices = new int[totalIndices];
|
||||
|
||||
int[] sectionIndices = new int[indicesPerSection]{
|
||||
0,8,9, 0,9,1, 2,10,11, 2,11,3,
|
||||
4,12,13, 4,13,5, 15,7,6, 15,6,14};
|
||||
|
||||
int indexOffset = 0;
|
||||
//triangulate per section
|
||||
for(int j = 0; j < LeafLengthTesselation; ++j){
|
||||
int sectionVertexOffset = j * 8;
|
||||
|
||||
for(int k = 0; k < indicesPerSection; ++k){
|
||||
indices[indexOffset++] = sectionVertexOffset + sectionIndices[k];
|
||||
}
|
||||
}
|
||||
|
||||
//generate normals
|
||||
Vector3[] normals = new Vector3[vertices.Length];
|
||||
for(int j = 0; j < indices.Length; j+=3){
|
||||
Vector3 normal = AdvancedMath.TriangleNormal(
|
||||
vertices[indices[j + 0]],
|
||||
vertices[indices[j + 1]],
|
||||
vertices[indices[j + 2]]);
|
||||
|
||||
normals[indices[j + 0]] = normal;
|
||||
normals[indices[j + 1]] = normal;
|
||||
normals[indices[j + 2]] = normal;
|
||||
|
||||
}
|
||||
|
||||
m.vertices = vertices;
|
||||
m.SetIndices(indices, MeshTopology.Triangles, 0);
|
||||
m.uv = uvs;
|
||||
m.normals = normals;
|
||||
|
||||
|
||||
MeshCollider collider = obj.GetComponent<MeshCollider>();
|
||||
if(collider == null){
|
||||
collider = obj.AddComponent<MeshCollider>();
|
||||
collider.sharedMesh = m;
|
||||
}
|
||||
obj.transform.localRotation = Quaternion.AngleAxis(rotation, Vector3.up);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Vector3 GetLeafPosition(int id){
|
||||
float jointsRadius = (OutsideDiameter * 0.5f + MaxAperture * 0.5f) * 0.5f;
|
||||
float leafAngle = (360.0f / (float)LeafCount) * (float)id;
|
||||
return Quaternion.AngleAxis(leafAngle, Vector3.up) * Vector3.forward * jointsRadius;
|
||||
}
|
||||
|
||||
void OnDrawGizmos(){
|
||||
if (updateInEditor) {
|
||||
UpdateLeafs ();
|
||||
}
|
||||
|
||||
|
||||
if (DrawDebugLines) {
|
||||
AdvancedGizmo.DrawCircle (transform.position, Vector3.up, OutsideDiameter * 0.5f, Color.red, 36);
|
||||
AdvancedGizmo.DrawCircle (transform.position, Vector3.up, MaxAperture * 0.5f, Color.green, 36, false, 2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dc5258ee36511cc48b9f1338e2232fac
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
Binary file not shown.
@@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d1a0c5933f01a8f418e465aa71834e82
|
||||
DefaultImporter:
|
||||
userData:
|
||||
Reference in New Issue
Block a user