Mercurial > hg > Game > Games
diff Orchestland/Assets/LeapMotion/DemoResources/Scripts/StemMesh.cs @ 3:0030a1b971fb default tip
merge
author | Yuta ANSE <e135745@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 17 Jul 2015 23:23:43 +0900 |
parents | f7675884f2a1 |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Orchestland/Assets/LeapMotion/DemoResources/Scripts/StemMesh.cs Fri Jul 17 23:23:43 2015 +0900 @@ -0,0 +1,158 @@ +/******************************************************************************\ +* Copyright (C) Leap Motion, Inc. 2011-2014. * +* Leap Motion proprietary. Licensed under Apache 2.0 * +* Available at http://www.apache.org/licenses/LICENSE-2.0.html * +\******************************************************************************/ + +using UnityEngine; +using System.Collections; + +public class StemMesh : MonoBehaviour { + + const int TRIANGLE_INDICES_PER_QUAD = 6; + const int VERTICES_PER_QUAD = 4; + + public Collider[] segments; + public int sides = 4; + public AnimationCurve stemCurve; + public float growthProgress = 0.0f; + public float stumpDiminishTime = 2.0f; + + private Vector3[] vertices_; + private bool[] broken; + private float stump_width_ = 1.0f; + private bool is_diminishing_ = false; + + void Start () { + broken = new bool[segments.Length]; + for (int i = 0; i < broken.Length; ++i) + broken[i] = false; + + MeshFilter filter = GetComponent<MeshFilter>(); + filter.mesh = new Mesh(); + InitMesh(); + filter.mesh.RecalculateBounds(); + filter.mesh.RecalculateNormals(); + } + + void Update () { + UpdateMesh(); + MeshFilter filter = GetComponent<MeshFilter>(); + + filter.mesh.MarkDynamic(); + filter.mesh.vertices = vertices_; + filter.mesh.RecalculateBounds(); + filter.mesh.RecalculateNormals(); + } + + public bool IsBroken() { + if (broken == null) + return false; + + for (int i = 0; i < broken.Length; ++i) { + if (broken[i]) + return true; + } + return false; + } + + public bool IsStumpClear() { + return stump_width_ == 0.0f; + } + + public void RemoveStump() { + is_diminishing_ = true; + } + + private void InitMesh() { + Mesh mesh = GetComponent<MeshFilter>().mesh; + + int num_vertices = sides * segments.Length; + vertices_ = new Vector3[num_vertices]; + Vector2[] uv = new Vector2[num_vertices]; + + int[] triangles = new int[TRIANGLE_INDICES_PER_QUAD * (num_vertices - sides)]; + + for (int v = 0; v < num_vertices; ++v) { + vertices_[v] = new Vector3(0, 0, 0); + uv[v] = new Vector3(0, 0, 0); + } + + int vertex_index = 0; + for (int seg = 0; seg < segments.Length - 1; ++seg) { + if (segments[seg + 1].GetComponent<HingeJoint>() == null) { + for (int i = 0; i < sides * TRIANGLE_INDICES_PER_QUAD; ++i) + triangles[vertex_index++] = 0; + } + else { + for (int side = 0; side < sides; ++side) { + int next_side = (side + 1) % sides; + triangles[vertex_index++] = sides * seg + side; + triangles[vertex_index++] = sides * seg + next_side; + triangles[vertex_index++] = sides * (seg + 1) + next_side; + + triangles[vertex_index++] = sides * seg + side; + triangles[vertex_index++] = sides * (seg + 1) + next_side; + triangles[vertex_index++] = sides * (seg + 1) + side; + } + } + } + + mesh.vertices = vertices_; + mesh.uv = uv; + mesh.triangles = triangles; + } + + protected void Separate(int index) { + for (int i = 0; i < index; ++i) + segments[i] = null; + } + + private void Break(int index) { + for (int i = index; i < segments.Length; ++i) { + segments[i] = null; + } + } + + private void KillStump() { + for (int i = 0; i < broken.Length && !broken[i]; ++i) + segments[i].GetComponent<Collider>().enabled = false; + } + + private void UpdateMesh() { + if (is_diminishing_ && stump_width_ != 0.0f) { + stump_width_ -= Time.deltaTime / stumpDiminishTime; + stump_width_ = Mathf.Clamp(stump_width_, 0.0f, 1.0f); + if (stump_width_ == 0.0f) + KillStump(); + } + + for (int i = 0; i < segments.Length; ++i) { + if (!broken[i] && segments[i].GetComponent<HingeJoint>() == null) { + InitMesh(); + broken[i] = true; + } + } + + int vertex_index = 0; + float angle = 360.0f / sides; + + bool is_stump = true; + for (int i = 0; i < segments.Length; ++i) { + float phase = (1.0f * i) / (segments.Length - 1); + float width = Mathf.Clamp(segments.Length * growthProgress - i, 0.0f, 1.0f); + + is_stump = is_stump && !broken[i]; + if (is_stump) + width *= stump_width_; + + Vector3 offset = new Vector3(width * stemCurve.Evaluate(phase), 0, 0); + + for (int side = 0; side < sides; ++side) { + vertices_[vertex_index++] = + transform.InverseTransformPoint(segments[i].transform.TransformPoint(offset)); + offset = Quaternion.AngleAxis(angle, Vector3.up) * offset; + } + } + } +}