public void SelectVertices() { if (SelectedMesh != null && SelectedVertex != null) { CalcSkindeform(); Vector3 center = SelectedVertex.deformed_position; MqoMesh mqo_mesh = MqoMesh.FromTSOMesh(SelectedMesh); float squared_radius = radius * radius; foreach (MqoVert v in mqo_mesh.vertices) { //頂点間距離が半径未満なら選択する。 Vector3 p1 = v.deformed_position; float squared_length = Vector3.LengthSq(p1 - center); v.selected = squared_length - squared_radius < float.Epsilon; if (v.selected) { if (squared_radius < float.Epsilon) { v.factor = 1.0f; } else { //半径 1.0f とみなしたときの平方距離を得る double len = 1.0 - squared_length / squared_radius; //ウェイト乗数 //半径境界で 0.0f になる v.factor = (float)Math.Pow(len, power); } } } } }
public void SelectVerticesFromPath() { if (SelectedMesh != null && source != null && target != null) { MqoMesh mqo_mesh = MqoMesh.FromTSOMesh(SelectedMesh); mqo_mesh.CreatePathDijkstra(source.Index, target.Index); float squared_radius = mqo_mesh.djk.GetCostToTarget(); foreach (MqoVert v in mqo_mesh.vertices) { v.selected = mqo_mesh.djk.Selected(v.Index); if (v.selected) { float squared_length = mqo_mesh.djk.GetCostToNode(v.Index); if (squared_radius < float.Epsilon) { v.factor = 1.0f; } else { //半径 1.0f とみなしたときの平方距離を得る double len = 1.0 - squared_length / squared_radius; //ウェイト乗数 //半径境界で 0.0f になる v.factor = (float)Math.Pow(len, power); } } } } }
/// <summary> /// シーンをレンダリングします。 /// </summary> public void RenderDerived() { if (MotionEnabled) { return; } Figure fig; if (TryGetFigure(out fig)) { if (node_selection_mode == NodeSelectionMode.AllBones) { //nodeを描画する。 DrawNodeTree(fig); DrawSelectedNode(fig); } if (SelectedMesh != null) { //頂点を描画する。 MqoMesh mqo_mesh = MqoMesh.FromTSOMesh(SelectedMesh); DrawVertices(mqo_mesh); DrawSelectedVertex(); } } }
/// 選択ボーンに対応するウェイトを加算する。 /// returns: ウェイトを変更したか public bool Execute() { bool updated = false; MqoMesh mqo_mesh = MqoMesh.FromTSOMesh(mesh); SmoothMqoMeshCommand mqo_mesh_command = new SmoothMqoMeshCommand(tso, mqo_mesh, selected_node); if (mqo_mesh_command.Execute()) { mqo_mesh.WriteBuffer(); this.mqo_mesh_commands.Add(mqo_mesh_command); updated = true; } return(updated); }
void CalcSkindeform() { if (!NeedSkindeform) { return; } Figure fig; if (TryGetFigure(out fig)) { if (SelectedMesh != null) { Matrix[] clipped_boneMatrices = fig.ClipBoneMatrices(SelectedTSOFile); MqoMesh mqo_mesh = MqoMesh.FromTSOMesh(SelectedMesh); mqo_mesh.CalcSkindeform(clipped_boneMatrices); } } NeedSkindeform = false; }
/// 頂点を選択します。 /// returns: 頂点を見つけたかどうか public bool SelectVertex() { bool found = false; if (SelectedMesh != null) { //スクリーン座標から頂点を見つけます。 //衝突する頂点の中で最も近い位置にある頂点を返します。 float x = lastScreenPoint.X; float y = lastScreenPoint.Y; int width = 3;//頂点ハンドルの幅 float min_z = 1e12f; MqoVert found_vertex = null; MqoMesh mqo_mesh = MqoMesh.FromTSOMesh(SelectedMesh); CalcSkindeform(); switch (vertex_selection_mode) { case VertexSelectionMode.AllVertices: { for (int i = 0; i < mqo_mesh.vertices.Length; i++) { MqoVert v = mqo_mesh.vertices[i]; Vector3 p2 = GetVertPositionOnScreen(v); if (p2.X - width <= x && x <= p2.X + width && p2.Y - width <= y && y <= p2.Y + width) { if (p2.Z < min_z) { min_z = p2.Z; found = true; found_vertex = v; } } } } break; case VertexSelectionMode.CcwVertices: { bool[] ccws = CreateCcws(mqo_mesh); for (int i = 0; i < mqo_mesh.vertices.Length; i++) { if (!ccws[i]) { continue; } MqoVert v = mqo_mesh.vertices[i]; Vector3 p2 = GetVertPositionOnScreen(v); if (p2.X - width <= x && x <= p2.X + width && p2.Y - width <= y && y <= p2.Y + width) { if (p2.Z < min_z) { min_z = p2.Z; found = true; found_vertex = v; } } } } break; case VertexSelectionMode.None: break; } // if (found) { selected_vertex = found_vertex; SelectVertices(); if (SelectedVertexChanged != null) { SelectedVertexChanged(this, EventArgs.Empty); } } } return(found); }