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;
+      }
+    }
+  }
+}