public Transform(Transform parent)
 {
     this.parent = parent;
     position = Vector3.Zero;
     rotation = Quaternion.Zero;
     scale = Vector3.One;
 }
 public Transform()
 {
     position = Vector3.Zero;
     rotation = Quaternion.Zero;
     scale = Vector3.One;
 }
 public void Rotate(Vector3 axic, float angle)
 {
     rotation = (new Quaternion(axic, angle) * rotation).Normalized;
 }
 public void Update()
 {
     if(_position != null) {
         _position = new Vector3(position);
         _rotation = new Quaternion(rotation);
         _scale = new Vector3(scale);
     } else {
         _position = new Vector3(position) + 1;
         _rotation = new Quaternion(rotation) * 0.5;
         _scale = new Vector3(scale) + 1;
     }
 }
 public Vector3 Rotate(Quaternion rotation)
 {
     var w = (rotation * this) * rotation.Conjugate;
     return new Vector3(w.X, w.Y, w.Z);
 }
 public void LookAt(Vector3 point, Vector3 up)
 {
     rotation = GetLookAtRotation(point, up);
 }
 public Quaternion SLerp(Quaternion dest, float lerp_factor, bool shortest)
 {
     var cos = Dot(dest);
     var corrected_dest = dest;
     if(shortest && cos < 0) {
         cos *= -1;
         corrected_dest = new Quaternion(-1 * dest.x, -1 * dest.y, -1 * dest.z, -1 * dest.w);
     }
     if(System.Math.Abs(cos) >= 1 - EPSILON) {
         return NLerp(corrected_dest, lerp_factor, false);
     } else {
         var sin = System.Math.Sqrt(1 - cos * cos);
         var angle = System.Math.Atan2(sin, cos);
         var src_factor = System.Math.Sin((1 - lerp_factor) * angle) * (1 / sin);
         var dest_factor = System.Math.Sin((lerp_factor) * angle) * (1 / sin);
         return (this * src_factor) + (corrected_dest * dest_factor);
     }
 }
 public Quaternion Set(Quaternion v)
 {
     Set(v.x, v.y, v.z, v.w);
     return this;
 }
 public Quaternion NLerp(Quaternion dest, float lerp_factor, bool shortest)
 {
     var corrected_dest = dest;
     if(shortest && Dot(dest) < 0) {
         corrected_dest = new Quaternion(-1 * dest.x, -1 * dest.y, -1 * dest.z, -1 * dest.w);
     }
     return (((corrected_dest - this) * lerp_factor) + this).Normalize();
 }
 public float Dot(Quaternion v)
 {
     return x * v.x + y * v.y + z * v.z + w * v.z;
 }
 public Quaternion(Quaternion v)
 {
     Set(v);
 }