public void Render(SwapChain swapChain, ref Viewport viewport, hkaBone selected_bone, string anim_filename) { Size2 size = new Size2(viewport.Width, viewport.Height); CreateDeviceResources(swapChain); renderTarget.BeginDraw(); DrawCenterAxis(); DrawBoneTree(); DrawSelectedBone(selected_bone); DrawText(anim_filename, ref size); try { renderTarget.EndDraw(); } catch (SharpDXException ex) when((uint)ex.HResult == 0x8899000C) // D2DERR_RECREATE_TARGET { // device has been lost! DiscardDeviceResources(); } }
/// 選択boneを描画する。 void DrawSelectedBone(hkaBone selected_bone) { if (selected_bone == null) { return; } Vector3 p1 = GetBonePositionOnScreen(selected_bone); p1.Z = 0.0f; if (selected_bone.children.Count != 0) { hkaBone bone = selected_bone.children[0]; Vector3 p0 = GetBonePositionOnScreen(bone); p0.Z = 0.0f; Vector3 pd = p0 - p1; float len = pd.Length(); float scale = 4.0f / len; Vector2 p3 = new Vector2(p1.X + pd.Y * scale, p1.Y - pd.X * scale); Vector2 p4 = new Vector2(p1.X - pd.Y * scale, p1.Y + pd.X * scale); RawVector2[] vertices = new RawVector2[3]; vertices[0] = new RawVector2(p3.X, p3.Y); vertices[1] = new RawVector2(p0.X, p0.Y); vertices[2] = new RawVector2(p4.X, p4.Y); DrawBoneLine(ref vertices, true); } DrawBoneAxis(selected_bone); DrawBoneEllipse(ref p1, true); }
/// 選択boneを指定軸中心に回転します。 public void RotateAxis(int dx, int dy, Vector3 axis) { hkaBone bone = selected_bone; if (bone == null) { return; } float angle = dx * 0.005f; bone.patch.rotation *= Quaternion.RotationAxis(axis, angle); }
/// 選択boneを指定軸方向に移動します。 public void TranslateAxis(int dx, int dy, Vector3 axis) { hkaBone bone = selected_bone; if (bone == null) { return; } axis = Vector3.Transform(axis, bone.local.rotation * bone.patch.rotation); float len = dx * 0.0125f; bone.patch.translation += axis * len; }
internal Transform GetWorldCoordinate() { Transform t = new Transform(); hkaBone bone = this; //int i = 0; while (bone != null) { //Console.WriteLine(" local loop idx {0} Ref {1}", i, node.self_ref); t = bone.local * bone.patch * t; bone = bone.parent; //i++; } return(t); }
/// boneを選択します。 /// returns: boneを見つけたかどうか public bool SelectBone() { bool found = false; //スクリーン座標からboneを見つけます。 //衝突する頂点の中で最も近い位置にあるboneを返します。 float x = lastScreenPoint.X; float y = lastScreenPoint.Y; int width = 5;//頂点ハンドルの幅 float min_z = 1e12f; hkaBone found_bone = null; foreach (hkaBone bone in skeleton.bones) { if (bone.hide) { continue; } Vector3 p2 = GetBonePositionOnScreen(bone); 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_bone = bone; } } } if (found) { selected_bone = found_bone; Console.WriteLine("Select Bone: {0}", selected_bone.name); camera.Center = selected_bone.GetWorldCoordinate().translation; camera.UpdateTranslation(); } return(found); }
Vector3 GetBonePositionOnScreen(hkaBone bone) { Transform t = bone.GetWorldCoordinate(); return(WorldToScreen(t.translation)); }
void DrawBoneAxis(hkaBone bone) { Transform t = bone.GetWorldCoordinate(); DrawBoneAxis(t); }
public void Read(BinaryReader reader) { /// A user name to aid in identifying the skeleton this.name = reader.ReadCString(); /// Parent relationship int nparentIndices = reader.ReadInt32(); this.parentIndices = new short[nparentIndices]; for (int i = 0; i < nparentIndices; i++) { this.parentIndices[i] = reader.ReadInt16(); } /// Bones for this skeleton int nbones = reader.ReadInt32(); this.bones = new hkaBone[nbones]; for (int i = 0; i < nbones; i++) { hkaBone bone = new hkaBone(); bone.Read(reader); this.bones[i] = bone; } for (short i = 0; i < nbones; i++) { hkaBone bone = this.bones[i]; bone.idx = i; short parent_idx = this.parentIndices[i]; if (parent_idx != -1) { hkaBone parent = this.bones[parent_idx]; bone.parent = parent; parent.children.Add(bone); } } // hide NPC Root this.bones[0].hide = true; #if false // hide since Camera3rd if (nbones != 1) { bool hide = false; for (int i = 1; i < nbones; i++) { hkaBone bone = this.bones[i]; if (bone.parent == null) { hide = true; } bone.hide = hide; } } #endif /// The reference pose for the bones of this skeleton. This pose is stored in local space. int nreferencePose = reader.ReadInt32(); this.referencePose = new Transform[nreferencePose]; for (int i = 0; i < nreferencePose; i++) { Transform t = new Transform(); t.Read(reader); this.referencePose[i] = t; } for (int i = 0; i < nbones; i++) { hkaBone bone = this.bones[i]; bone.local = this.referencePose[i]; bone.patch = new Transform(); } /// The reference values for the float slots of this skeleton. This pose is stored in local space. int nreferenceFloats = reader.ReadInt32(); this.referenceFloats = new float[nreferenceFloats]; for (int i = 0; i < nreferenceFloats; i++) { this.referenceFloats[i] = reader.ReadSingle(); } /// Floating point track slots. Often used for auxiliary float data or morph target parameters etc. /// This defines the target when binding animations to a particular rig. int nfloatSlots = reader.ReadInt32(); this.floatSlots = new string[nfloatSlots]; for (int i = 0; i < nfloatSlots; i++) { this.floatSlots[i] = reader.ReadCString(); } }
/// bone操作を生成します。 public BoneCommand(hkaBone bone) { this.bone = bone; this.old_attr.rotation = bone.patch.rotation; this.old_attr.translation = bone.patch.translation; }