Mercurial > hg > Game > Games
view Orchestland/Assets/LeapMotion/Scripts/Hands/PolyFinger.cs @ 1:f7675884f2a1
Add Orchestland project
author | Daiki OYAKAWA <e135764@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 17 Jul 2015 23:09:20 +0900 |
parents | |
children |
line wrap: on
line source
/******************************************************************************\ * 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; using System; using Leap; /** Draws the bones of the finger as a polygonal tube. **/ public class PolyFinger : FingerModel { const int MAX_SIDES = 30; const int TRIANGLE_INDICES_PER_QUAD = 6; const int VERTICES_PER_QUAD = 4; /** The number of sides for finger tube. */ public int sides = 4; /** Whether to smooth the mesh normals, providing a smoother appearance.*/ public bool smoothNormals = false; public float startingAngle = 0.0f; /** An array containing the width of the finger at each joint. */ public float[] widths = new float[NUM_JOINTS]; protected Vector3[] vertices_; protected Vector3[] normals_; protected Vector3[] joint_vertices_; protected Mesh mesh_; protected Mesh cap_mesh_; protected Vector3[] cap_vertices_; /** Creates the finger mesh. */ public override void InitFinger() { InitJointVertices(); InitCapsMesh(); InitMesh(); GetComponent<MeshFilter>().mesh = new Mesh(); UpdateFinger(); } /** Updates the mesh.*/ public override void UpdateFinger() { UpdateMesh(); UpdateCapMesh(); } void OnDestroy() { Destroy(mesh_); Destroy(cap_mesh_); Destroy(GetComponent<MeshFilter>().mesh); } void Update() { if (vertices_ == null) return; mesh_.vertices = vertices_; if (smoothNormals) mesh_.normals = normals_; else mesh_.RecalculateNormals(); cap_mesh_.vertices = cap_vertices_; cap_mesh_.RecalculateNormals(); CombineInstance[] combine = new CombineInstance[2]; combine[0].mesh = mesh_; combine[1].mesh = cap_mesh_; GetComponent<MeshFilter>().mesh.CombineMeshes(combine, true, false); GetComponent<MeshFilter>().mesh.RecalculateBounds(); } protected Quaternion GetJointRotation(int joint) { if (joint <= 0) return GetBoneRotation(joint); if (joint >= NUM_BONES) return GetBoneRotation(joint - 1); return Quaternion.Slerp(GetBoneRotation(joint - 1), GetBoneRotation(joint), 0.5f); } protected void InitJointVertices() { joint_vertices_ = new Vector3[sides]; for (int s = 0; s < sides; ++s) { float angle = startingAngle + s * 360.0f / sides; joint_vertices_[s] = Quaternion.AngleAxis(angle, -Vector3.forward) * Vector3.up; } } protected void UpdateMesh() { int vertex_index = 0; for (int i = 0; i < NUM_BONES; ++i) { Vector3 joint_position = transform.InverseTransformPoint(GetJointPosition(i)); Vector3 next_joint_position = transform.InverseTransformPoint(GetJointPosition(i + 1)); Quaternion joint_rotation = Quaternion.Inverse(transform.rotation) * (GetJointRotation(i)); Quaternion next_joint_rotation = Quaternion.Inverse(transform.rotation) * GetJointRotation(i + 1); for (int s = 0; s < sides; ++s) { int next_side = (s + 1) % sides; if (smoothNormals) { Vector3 normal = joint_rotation * joint_vertices_[s]; Vector3 next_normal = joint_rotation * joint_vertices_[next_side]; normals_[vertex_index] = normals_[vertex_index + 2] = normal; normals_[vertex_index + 1] = normals_[vertex_index + 3] = next_normal; } Vector3 offset = joint_rotation * (widths[i] * joint_vertices_[s]); vertices_[vertex_index++] = joint_position + offset; offset = joint_rotation * (widths[i] * joint_vertices_[next_side]); vertices_[vertex_index++] = joint_position + offset; offset = next_joint_rotation * (widths[i + 1] * joint_vertices_[s]); vertices_[vertex_index++] = next_joint_position + offset; offset = next_joint_rotation * (widths[i + 1] * joint_vertices_[next_side]); vertices_[vertex_index++] = next_joint_position + offset; } } } protected void UpdateCapMesh() { Vector3 base_position = transform.InverseTransformPoint(GetJointPosition(0)); Vector3 tip_position = transform.InverseTransformPoint(GetJointPosition(NUM_JOINTS - 1)); Quaternion base_rotation = Quaternion.Inverse(transform.rotation) * GetJointRotation(0); Quaternion tip_rotation = Quaternion.Inverse(transform.rotation) * GetJointRotation(NUM_JOINTS - 1); for (int s = 0; s < sides; ++s) { cap_vertices_[s] = base_position + base_rotation * (widths[0] * joint_vertices_[s]); cap_vertices_[sides + s] = tip_position + tip_rotation * (widths[NUM_JOINTS - 1] * joint_vertices_[s]); } } protected void InitMesh() { mesh_ = new Mesh(); mesh_.MarkDynamic(); int vertex_index = 0; int num_vertices = VERTICES_PER_QUAD * sides * NUM_BONES; vertices_ = new Vector3[num_vertices]; normals_ = new Vector3[num_vertices]; Vector2[] uv = new Vector2[num_vertices]; int triangle_index = 0; int num_triangles = TRIANGLE_INDICES_PER_QUAD * sides * NUM_BONES; int[] triangles = new int[num_triangles]; for (int i = 0; i < NUM_BONES; ++i) { for (int s = 0; s < sides; ++s) { triangles[triangle_index++] = vertex_index; triangles[triangle_index++] = vertex_index + 2; triangles[triangle_index++] = vertex_index + 1; triangles[triangle_index++] = vertex_index + 2; triangles[triangle_index++] = vertex_index + 3; triangles[triangle_index++] = vertex_index + 1; uv[vertex_index] = new Vector3((1.0f * s) / sides, (1.0f * i) / NUM_BONES); uv[vertex_index + 1] = new Vector3((1.0f + s) / sides, (1.0f * i) / NUM_BONES); uv[vertex_index + 2] = new Vector3((1.0f * s) / sides, (1.0f + i) / NUM_BONES); uv[vertex_index + 3] = new Vector3((1.0f + s) / sides, (1.0f + i) / NUM_BONES); vertices_[vertex_index++] = new Vector3(0, 0, 0); vertices_[vertex_index++] = new Vector3(0, 0, 0); vertices_[vertex_index++] = new Vector3(0, 0, 0); vertices_[vertex_index++] = new Vector3(0, 0, 0); } } mesh_.vertices = vertices_; mesh_.normals = normals_; mesh_.uv = uv; mesh_.triangles = triangles; } protected void InitCapsMesh() { cap_mesh_ = new Mesh(); cap_mesh_.MarkDynamic(); cap_vertices_ = cap_mesh_.vertices; int num_vertices = 2 * sides; if (num_vertices != cap_vertices_.Length) Array.Resize(ref cap_vertices_, num_vertices); Vector2[] uv = cap_mesh_.uv; if (uv.Length != num_vertices) Array.Resize(ref uv, num_vertices); int triangle_index = 0; int[] triangles = cap_mesh_.triangles; int num_triangles = 2 * 3 * (sides - 2); if (num_triangles != triangles.Length) Array.Resize(ref triangles, num_triangles); for (int i = 0; i < sides; ++i) { cap_vertices_[i] = new Vector3(0, 0, 0); cap_vertices_[i + sides] = new Vector3(0, 0, 0); uv[i] = 0.5f * joint_vertices_[i]; uv[i] += new Vector2(0.5f, 0.5f); uv[i + sides] = 0.5f * joint_vertices_[i]; uv[i + sides] += new Vector2(0.5f, 0.5f); } for (int i = 0; i < sides - 2; ++i) { triangles[triangle_index++] = 0; triangles[triangle_index++] = i + 1; triangles[triangle_index++] = i + 2; triangles[triangle_index++] = sides; triangles[triangle_index++] = sides + i + 2; triangles[triangle_index++] = sides + i + 1; } cap_mesh_.vertices = cap_vertices_; cap_mesh_.uv = uv; cap_mesh_.triangles = triangles; } }