using System.Drawing; using System.Collections.Generic; using System.Windows.Forms; using OpenTK; using OpenTK.Graphics.OpenGL; namespace Toolbox.Library { public class STBone : TreeNodeCustom { private bool visbile = true; public bool Visible { get { return visbile; } set { visbile = value; } } public bool UseSegmentScaleCompensate; public STSkeleton skeletonParent; public BoneRotationType RotationType; public short BillboardIndex; public short RigidMatrixIndex; public short SmoothMatrixIndex; private Matrix4 transform; private Quaternion rotation = Quaternion.Identity; private Vector3 eulerRotation; /// /// Gets or sets the transformation of the bone. /// Setting this will adjust the /// , /// , and /// properties. /// public Matrix4 Transform { set { // Scale = value.ExtractScale(); // Rotation = value.ExtractRotation(); // Position = value.ExtractTranslation(); transform = value; } get { return transform; } } /// /// Gets or sets the position of the bone in world space. /// public Vector3 Position { get; set; } /// /// Gets or sets the scale of the bone in world space. /// public Vector3 Scale { get; set; } = Vector3.One; /// /// Gets or sets the rotation of the bone in world space. /// public Quaternion Rotation { get { return rotation; } set { if (RotationType == BoneRotationType.Euler) { eulerRotation = new Vector3(value.X, value.Y, value.Z); rotation = STMath.FromEulerAngles(eulerRotation); } else { eulerRotation = STMath.ToEulerAngles(Rotation); rotation = value; } } } /// /// Gets or sets the using euler method. /// public Vector3 EulerRotation { get { return eulerRotation; } set { eulerRotation = value; rotation = STMath.FromEulerAngles(value); if (rotation.W == 0) rotation.W = 1; } } public Vector3 pos = Vector3.Zero, sca = new Vector3(1f, 1f, 1f); public Quaternion rot = Quaternion.Identity; public Matrix4 invert; public Matrix4 GetTransform() { return Matrix4.CreateScale(Scale) * Matrix4.CreateFromQuaternion(Rotation) * Matrix4.CreateTranslation(Position); } public void FromTransform(Matrix4 transform) { Scale = transform.ExtractScale(); Position = transform.ExtractTranslation(); rotation = transform.ExtractRotation(); eulerRotation = STMath.ToEulerAngles(rotation); } //Used for shifting models with the bones in the shader public Matrix4 ModelMatrix = Matrix4.Identity; public Vector3 GetPosition() { return pos; } public Quaternion GetRotation() { return rot; } public Vector3 GetScale() { return sca; } public int GetIndex() { if (skeletonParent != null) return skeletonParent.bones.IndexOf(this); else return -1; } public override void OnClick(TreeView treeView) { } public enum BoneRotationType { Euler, Quaternion, } public int parentIndex { set { if (Parent != null) Parent.Nodes.Remove(this); if (value > -1 && value < skeletonParent.bones.Count) { skeletonParent.bones[value].Nodes.Add(this); } } get { if (Parent == null || !(Parent is STBone)) return -1; return skeletonParent.bones.IndexOf((STBone)Parent); } } public List GetChildren() { List l = new List(); foreach (STBone b in skeletonParent.bones) if (b.Parent == this) l.Add(b); return l; } public STBone(STSkeleton skl) { skeletonParent = skl; ImageKey = "bone"; SelectedImageKey = "bone"; Checked = true; } public STBone() { ImageKey = "bone"; SelectedImageKey = "bone"; Checked = true; } public void RenderLegacy() { if (!Runtime.OpenTKInitialized || !Runtime.renderBones) return; Vector3 pos_c = Vector3.TransformPosition(Vector3.Zero, Transform); if (IsSelected) { GL.Color3(Color.Red); } else GL.Color3(Color.GreenYellow); RenderTools.DrawCube(pos_c, 0.1f); // now draw line between parent GL.Color3(Color.LightBlue); GL.LineWidth(2f); GL.Begin(PrimitiveType.Lines); if (Parent != null && Parent is STBone) { Vector3 pos_p = Vector3.TransformPosition(Vector3.Zero, ((STBone)Parent).Transform); GL.Vertex3(pos_c); GL.Color3(Color.Blue); GL.Vertex3(pos_p); } GL.End(); } } }