void OnSceneGUI() { MeshRoundCone mrc = target as MeshRoundCone; Transform trans = mrc.gameObject.transform; float defLeng = HandleUtility.GetHandleSize(Vector3.left); Vector3 pos = trans.position; Vector3 scale = trans.localScale; Quaternion rot = trans.rotation; float offset1, offset2; if (mrc.pivot == MeshRoundCone.Pivot.Center) { offset1 = -0.5f * mrc.length; offset2 = +0.5f * mrc.length; } else if (mrc.pivot == MeshRoundCone.Pivot.R1) { offset1 = 0; offset2 = mrc.length; } else { offset1 = -mrc.length; offset2 = 0; } EditorGUI.BeginChangeCheck(); float r1 = Handles.RadiusHandle(rot, pos + rot * new Vector3(offset1, 0, 0), mrc.r1); if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(target, "Change Radius 1"); mrc.r1 = r1; mrc.Reshape(); } EditorGUI.BeginChangeCheck(); float r2 = Handles.RadiusHandle(rot, pos + rot * new Vector3(offset2, 0, 0), mrc.r2); if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(target, "Change Radius 2"); mrc.r2 = r2; mrc.Reshape(); } EditorGUI.BeginChangeCheck(); float length = Handles.ScaleSlider(mrc.length, pos, rot * new Vector3(0, 1, 0), rot, 1, 0.5f); if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(target, "Change Length"); mrc.length = length; mrc.Reshape(); } }
// -- SpringheadのShapeオブジェクトを構築する public override CDShapeIf CreateShape(GameObject shapeObject) { MeshRoundCone mrc = shapeObject.GetComponent <MeshRoundCone>(); if (mrc == null) { throw new ObjectNotFoundException("CDRoundConeBehaviour requires MeshRoundCone", shapeObject); } desc.radius = new Vec2f(mrc.r1, mrc.r2); desc.length = mrc.length; return(phSdk.CreateShape(CDRoundConeIf.GetIfInfoStatic(), (CDRoundConeDesc)desc)); }
// -- SpringheadのShapeオブジェクトを構築する public override CDShapeIf CreateShape(GameObject shapeObject) { MeshRoundCone mrc = shapeObject.GetComponent <MeshRoundCone>(); if (mrc == null) { throw new ObjectNotFoundException("CDRoundConeBehaviour requires MeshRoundCone", shapeObject); } Vector3 scale = shapeObject.transform.lossyScale; desc.radius = new Vec2f(mrc.r1, mrc.r2) * (Mathf.Max(scale.x, scale.z)); desc.length = mrc.length * scale.y; return(phSdk.CreateShape(CDRoundConeIf.GetIfInfoStatic(), (CDRoundConeDesc)desc)); }
// ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- // CDShapeBehaviourの派生クラスで実装するメソッド // -- 形状固有のShapePoseの取得。剛体からの相対位置姿勢による分は除く public override Posed ShapePose(GameObject shapeObject) { MeshRoundCone mrc = shapeObject.GetComponent <MeshRoundCone>(); if (mrc == null) { throw new ObjectNotFoundException("CDRoundConeBehaviour requires MeshRoundCone", shapeObject); } // SpringheadとUnityでカプセルの向きが違うことに対する補正 Vec3f p = new Vec3f(); if (mrc.pivot == MeshRoundCone.Pivot.R1) { p = new Vec3f(+0.5f * mrc.length, 0, 0); } else if (mrc.pivot == MeshRoundCone.Pivot.R2) { p = new Vec3f(-0.5f * mrc.length, 0, 0); } return(new Posed(p, Quaterniond.Rot(90.0f * Mathf.Deg2Rad, new Vec3d(0, 1, 0)))); }
void OnSceneGUI() { MeshRoundCone mrc = target as MeshRoundCone; Transform trans = mrc.gameObject.transform; float scale = (trans.lossyScale.x + trans.lossyScale.y + trans.lossyScale.z) / 3.0f; mrc.UpdateR1R2HandlePosition(); float defLeng = HandleUtility.GetHandleSize(Vector3.left); EditorGUI.BeginChangeCheck(); float r1 = Handles.RadiusHandle(trans.rotation, mrc.positionR1, mrc.r1 * scale); if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(target, "Change Radius 1"); mrc.r1 = r1 / scale; mrc.Reshape(); } EditorGUI.BeginChangeCheck(); float r2 = Handles.RadiusHandle(trans.rotation, mrc.positionR2, mrc.r2 * scale); if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(target, "Change Radius 2"); mrc.r2 = r2 / scale; mrc.Reshape(); } EditorGUI.BeginChangeCheck(); float size = Mathf.Max(mrc.length * scale, Mathf.Max(mrc.r1 * scale, mrc.r2 * scale)); float length = Handles.ScaleSlider(mrc.length * scale, trans.position, trans.rotation * new Vector3(0, 1, 0), trans.rotation, size, 0.5f); if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(target, "Change Length"); mrc.length = length / scale; mrc.Reshape(); } if (mrc.pivot != MeshRoundCone.Pivot.R1) { EditorGUI.BeginChangeCheck(); Vector3 positionR1 = Handles.PositionHandle(mrc.positionR1, Quaternion.identity); if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(target, "Change R1 Position"); mrc.positionR1 = positionR1; mrc.Reposition(); mrc.Reshape(); } } if (mrc.pivot != MeshRoundCone.Pivot.R2) { EditorGUI.BeginChangeCheck(); Vector3 positionR2 = Handles.PositionHandle(mrc.positionR2, Quaternion.identity); if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(target, "Change R2 Position"); mrc.positionR2 = positionR2; mrc.Reposition(); mrc.Reshape(); } } }
static void OnMenu() { GameObject rc = new GameObject("RoundCone"); Mesh mesh = new Mesh(); MeshRenderer mr = rc.AddComponent <MeshRenderer>(); MeshFilter mf = rc.AddComponent <MeshFilter>(); MeshRoundCone mrc = rc.AddComponent <MeshRoundCone>(); int split = mrc.split, slice = mrc.slice; int sphereVtxs = split * (slice + 1); int sphereTris = 2 * split * slice; int coneVtxs = split * 2; int coneTris = split * 2; Vector3[] vertices = new Vector3[2 * sphereVtxs + coneVtxs]; int[] triangles = new int[(2 * sphereTris + coneTris) * 3]; // 頂点位置の設定は後でMeshRoundCone.Reshape()が行う // Make Triangles /// -- Sphere int cnt = 0; for (int n = 0; n < 2; n++) { for (int i = 0; i < split; i++) { for (int j = 0; j < slice; j++) { int i0 = i; int i1 = (i == split - 1) ? 0 : i + 1; triangles[cnt + 0] = split * (j + 0) + i1 + n * sphereVtxs; triangles[cnt + 1] = split * (j + 1) + i0 + n * sphereVtxs; triangles[cnt + 2] = split * (j + 0) + i0 + n * sphereVtxs; cnt += 3; triangles[cnt + 0] = split * (j + 0) + i1 + n * sphereVtxs; triangles[cnt + 1] = split * (j + 1) + i1 + n * sphereVtxs; triangles[cnt + 2] = split * (j + 1) + i0 + n * sphereVtxs; cnt += 3; } } } /// -- Cone for (int i = 0; i < split; i++) { int i0 = i; int i1 = (i == split - 1) ? 0 : i + 1; triangles[cnt + 0] = split * 0 + i0 + 2 * sphereVtxs; triangles[cnt + 1] = split * 1 + i0 + 2 * sphereVtxs; triangles[cnt + 2] = split * 0 + i1 + 2 * sphereVtxs; cnt += 3; triangles[cnt + 0] = split * 1 + i0 + 2 * sphereVtxs; triangles[cnt + 1] = split * 1 + i1 + 2 * sphereVtxs; triangles[cnt + 2] = split * 0 + i1 + 2 * sphereVtxs; cnt += 3; } mesh.vertices = vertices; mesh.triangles = triangles; mesh.RecalculateNormals(); mesh.RecalculateBounds(); mf.sharedMesh = mesh; if (default_material == null) { foreach (var i in Resources.FindObjectsOfTypeAll <Material>()) { if (i.name == "Default-Material") { default_material = i; break; } } } mr.sharedMaterial = default_material; // 頂点位置の設定 mrc.Reshape(); }