/* ----------------------------------------------------------------------------- nEngine - GSFramework Copyright 2001-2012 Emmanuel Julien. All Rights Reserved. ------------------------------------------------------------------------------*/ #include "script_squirrel/cobject/quaternion_decl.h" #include "script_squirrel/cobject/matrix_decl.h" #include "script_squirrel/cobject/vector_decl.h" #include "math/matrix3.h" #include "math/quaternion.h" #include "math/vector.h" #include "nstring/nstring.h" #include "log/log.h" using namespace GS; _DECL_CLASS(Quaternion) _IMPL_NATIVE_CONSTRUCTION(Quaternion, Quaternion) //------------------------------------------------------------------------------ _MEMBER_FUNCTION_IMPL(Quaternion, constructor) Quaternion temp; int nparams = sa.GetParamCount(); switch (nparams) { case 1: temp.Set(); break; case 5: temp.Set(sa.GetFloat(2), sa.GetFloat(3), sa.GetFloat(4), sa.GetFloat(5)); break; default: return sa.ThrowError("Quaternion() wrong parameter count"); } return construct_Quaternion(v, new Quaternion(temp)); _END_IMPL //------------------------------------------------------------------------------ _MEMBER_FUNCTION_IMPL(Quaternion, _cloned) _GetTypedParam(quat, 2, Quaternion, Quaternion); return construct_Quaternion(v, new Quaternion(*quat)); _END_IMPL _MEMBER_FUNCTION_IMPL(Quaternion, _set) _GetSelf(Quaternion, Quaternion); const SQChar *s = sa.GetString(2); int index = s ? s[0] : sa.GetInt(2); switch (index) { case 0: case 'x': return sa.Return(self->x = sa.GetFloat(3)); case 1: case 'y': return sa.Return(self->y = sa.GetFloat(3)); case 2: case 'z': return sa.Return(self->z = sa.GetFloat(3)); case 3: case 'w': return sa.Return(self->w = sa.GetFloat(3)); } return SQ_ERROR; _END_IMPL _MEMBER_FUNCTION_IMPL(Quaternion, _get) _GetSelf(Quaternion, Quaternion); const SQChar *s = sa.GetString(2); if (s && (s[1] != 0)) return SQ_ERROR; int index = s && (s[1] == 0) ? s[0] : sa.GetInt(2); switch (index) { case 0: case 'x': return sa.Return(self->x); case 1: case 'y': return sa.Return(self->y); case 2: case 'z': return sa.Return(self->z); case 3: case 'w': return sa.Return(self->w); } return SQ_ERROR; _END_IMPL _MEMBER_FUNCTION_IMPL(Quaternion, _mul) _GetSelf(Quaternion, Quaternion); switch (sa.GetType(2)) { case OT_INSTANCE: { // Quaternion * Quaternion. _CHECK_INST_PARAM_RAW(quat, 2, Quaternion, Quaternion); if (quat) _SA_RETURN_OBJECT(new_Quaternion(v, *self * *quat)); } break; // Quaternion * Scalar case OT_INTEGER: _SA_RETURN_OBJECT(new_Quaternion(v, *self * (float)sa.GetInt(2))); case OT_FLOAT: _SA_RETURN_OBJECT(new_Quaternion(v, *self * sa.GetFloat(2))); } return sa.ThrowError("Quaternion * operator: Invalid argument type.\n"); _END_IMPL _MEMBER_FUNCTION_IMPL(Quaternion, _div) _GetSelf(Quaternion, Quaternion); switch (sa.GetType(2)) { // Quaternion / Scalar case OT_INTEGER: _SA_RETURN_OBJECT(new_Quaternion(v, *self / (float)sa.GetInt(2))); case OT_FLOAT: _SA_RETURN_OBJECT(new_Quaternion(v, *self / sa.GetFloat(2))); } return sa.ThrowError("Quaternion / operator: Invalid argument type.\n"); _END_IMPL _MEMBER_FUNCTION_IMPL(Quaternion, _add) _GetSelf(Quaternion, Quaternion); switch (sa.GetType(2)) { case OT_INSTANCE: { // Quaternion + Quaternion. _CHECK_INST_PARAM_RAW(quat, 2, Quaternion, Quaternion); if (quat) _SA_RETURN_OBJECT(new_Quaternion(v, *self + *quat)); } break; // Quaternion + Scalar case OT_INTEGER: _SA_RETURN_OBJECT(new_Quaternion(v, *self + (float)sa.GetInt(2))); case OT_FLOAT: _SA_RETURN_OBJECT(new_Quaternion(v, *self + sa.GetFloat(2))); } return sa.ThrowError("Quaternion + operator: Invalid argument type.\n"); _END_IMPL _MEMBER_FUNCTION_IMPL(Quaternion, _sub) _GetSelf(Quaternion, Quaternion); switch (sa.GetType(2)) { case OT_INSTANCE: { // Quaternion - Quaternion. _CHECK_INST_PARAM_RAW(quat, 2, Quaternion, Quaternion); if (quat) _SA_RETURN_OBJECT(new_Quaternion(v, *self - *quat)); } break; // Quaternion - Scalar case OT_INTEGER: _SA_RETURN_OBJECT(new_Quaternion(v, *self - (float)sa.GetInt(2))); case OT_FLOAT: _SA_RETURN_OBJECT(new_Quaternion(v, *self - sa.GetFloat(2))); } return sa.ThrowError("Quaternion - operator: Invalid argument type.\n"); _END_IMPL //------------------------------------------------------------------------------ _MEMBER_FUNCTION_IMPL(Quaternion, Set) _GetSelf(Quaternion, Quaternion); switch (sa.GetParamCount()) { case 1: self->Set(); break; case 2: self->Set(sa.GetFloat(2)); break; case 3: self->Set(sa.GetFloat(2), sa.GetFloat(3)); break; case 4: self->Set(sa.GetFloat(2), sa.GetFloat(3), sa.GetFloat(4)); break; case 5: self->Set(sa.GetFloat(2), sa.GetFloat(3), sa.GetFloat(4), sa.GetFloat(5)); break; default: return sa.ThrowError("Quaternion Set() wrong parameters"); } return 0; _END_IMPL _MEMBER_FUNCTION_IMPL(Quaternion, Slerp) _GetSelf(Quaternion, Quaternion); float k = sa.GetFloat(2); _GetTypedParam(quat, 3, Quaternion, Quaternion) _SA_RETURN_OBJECT(new_Quaternion(v, Quaternion::Slerp(k, *self, *quat))); _END_IMPL _MEMBER_FUNCTION_IMPL(Quaternion, Normalize) _GetSelf(Quaternion, Quaternion); _SA_RETURN_OBJECT(new_Quaternion(v, self->Normalize())); _END_IMPL _MEMBER_FUNCTION_IMPL(Quaternion, Inverse) _GetSelf(Quaternion, Quaternion); _SA_RETURN_OBJECT(new_Quaternion(v, self->Inverse())); _END_IMPL _MEMBER_FUNCTION_IMPL(Quaternion, Dot) _GetSelf(Quaternion, Quaternion); _GetTypedParam(quat, 2, Quaternion, Quaternion); return sa.Return(self->Dot(*quat)); _END_IMPL _MEMBER_FUNCTION_IMPL(Quaternion, AsMatrix3) _GetSelf(Quaternion, Quaternion); _SA_RETURN_OBJECT(new_Matrix3(v, self->AsMatrix3())); _END_IMPL _MEMBER_FUNCTION_IMPL(Quaternion, QuaternionFromAxisAngle) _GetSelf(Quaternion, Quaternion); _GetTypedParam(vec, 3, Vector4, Vector); _SA_RETURN_OBJECT(new_Quaternion(v, Quaternion::FromAxisAngle(sa.GetFloat(2), vec->x, vec->y, vec->z))); _END_IMPL _MEMBER_FUNCTION_IMPL(Quaternion, QuaternionFromMatrix3) _GetSelf(Quaternion, Quaternion); _GetTypedParam(mtx, 2, Matrix3, Matrix3); _SA_RETURN_OBJECT(new_Quaternion(v, Quaternion::FromMatrix3(*mtx))); _END_IMPL _MEMBER_FUNCTION_IMPL(Quaternion, QuaternionLookAt) _GetSelf(Quaternion, Quaternion); _GetTypedParam(vec, 2, Vector4, Vector); _SA_RETURN_OBJECT(new_Quaternion(v, Quaternion::LookAt(*vec))); _END_IMPL _MEMBER_FUNCTION_IMPL(Quaternion, Print) _GetSelf(Quaternion, Quaternion); const char *label = "Quaternion"; if (sa.GetParamCount() == 2) label = sa.GetString(2); __LOG__ << label << ": { x = " << self->x << ", y = " << self->y << ", z = " << self->z << ", w = " << self->w << "}\n"; return 0; _END_IMPL /*# Topic: Quaternion Type: Quaternion #*/ /*# Section: QuaternionGeneric Desc: Generic #*/ _BEGIN_CLASS(Quaternion) /*# Func: Quaternion Proto: Quaternion:float x = 0,float y = 0,float z = 0,float w = 1 Desc: Create a new quaternion. Example: local u = Quaternion() local v = Quaternion(0, 0, 0, 1) u.Set(-1, 0, 0) #*/ _MEMBER_FUNCTION(Quaternion, constructor, -1, _T(".n|xnnn")) _MEMBER_FUNCTION(Quaternion, _cloned, 2, _T(".x")) _MEMBER_FUNCTION(Quaternion, _set, 2, _T("xs|n")) _MEMBER_FUNCTION(Quaternion, _get, 2, _T("xs|n")) _MEMBER_FUNCTION(Quaternion, _add, 2, _T("xx|n")) _MEMBER_FUNCTION(Quaternion, _sub, 2, _T("xx|n")) _MEMBER_FUNCTION(Quaternion, _mul, 2, _T("xx|n")) _MEMBER_FUNCTION(Quaternion, _div, 2, _T("xn")) /*# Func: Set Proto: void:float x = 0,float y = 0,float z = 0,float w = 1 Desc: Set quaternion values. #*/ _MEMBER_FUNCTION(Quaternion, Set, -1, _T("xnnnn")) /*# Func: Slerp Proto: Quaternion:float,Quaternion Desc: Returns a spherical linear interpolation. #*/ _MEMBER_FUNCTION(Quaternion, Slerp, 3, _T("xnx")) /*# Func: Normalize Proto: Quaternion:void Desc: Returns the normalized quaternion. #*/ _MEMBER_FUNCTION(Quaternion, Normalize, 1, _T("x")) /*# Func: Inverse Proto: Quaternion:void Desc: Returns the inverse quaternion. #*/ _MEMBER_FUNCTION(Quaternion, Inverse, 1, _T("x")) /*# Func: Dot Proto: Quaternion:Quaternion Desc: Returns the Dot product. #*/ _MEMBER_FUNCTION(Quaternion, Dot, 2, _T("xx")) /*# Func: AsMatrix3 Proto: Matrix3:void Desc: Returns the Matrix3 from the quaternion. #*/ _MEMBER_FUNCTION(Quaternion, AsMatrix3, 1, _T("x")) /*# Func: QuaternionFromAxisAngle Proto: Quaternion:float angle,Vector axis Desc: Returns a quaternion based on angle and axis. #*/ _MEMBER_FUNCTION(Quaternion, QuaternionFromAxisAngle, 3, _T(".nx")) /*# Func: QuaternionFromMatrix3 Proto: Quaternion:Matrix3 Desc: Returns a quaternion based on a Matrix3. #*/ _MEMBER_FUNCTION(Quaternion, QuaternionFromMatrix3, 2, _T(".x")) /*# Func: QuaternionLookAt Proto: Quaternion:Vector direction Desc: Returns a quaternion looking at direction. #*/ _MEMBER_FUNCTION(Quaternion, QuaternionLookAt, 2, _T(".x")) /*# Func: Print Proto: void: Desc: Dump this quaternion components (x,y,z,w) to the engine log. #*/ _MEMBER_FUNCTION(Quaternion, Print, -1, _T("x")) _END_CLASS(Quaternion)