Skip to content

Commit

Permalink
- add remaining quaternion function implementations
Browse files Browse the repository at this point in the history
  • Loading branch information
Gutawer authored and coelckers committed Nov 21, 2022
1 parent 540f778 commit 9f0c518
Show file tree
Hide file tree
Showing 5 changed files with 427 additions and 26 deletions.
1 change: 1 addition & 0 deletions src/common/scripting/backend/codegen.cpp
Expand Up @@ -8229,6 +8229,7 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx)
// because the resulting value type would cause problems in nearly every other place where identifiers are being used.
// [ZZ] substitute ccls for String internal type.
if (id == NAME_String) ccls = TypeStringStruct;
else if (id == NAME_Quat || id == NAME_FQuat) ccls = TypeQuaternionStruct;
else ccls = FindContainerType(id, ctx);
if (ccls != nullptr) static_cast<FxIdentifier *>(Self)->noglobal = true;
}
Expand Down
108 changes: 89 additions & 19 deletions src/common/scripting/interface/vmnatives.cpp
Expand Up @@ -1132,32 +1132,56 @@ DEFINE_FIELD(DHUDFont, mFont);

//
// Quaternion
DEFINE_ACTION_FUNCTION(_QuatStruct, FromEuler)
void QuatFromAngles(double yaw, double pitch, double roll, DQuaternion* pquat)
{
*pquat = DQuaternion::FromAngles(yaw, pitch, roll);
}

DEFINE_ACTION_FUNCTION_NATIVE(_QuatStruct, FromAngles, QuatFromAngles)
{
PARAM_PROLOGUE;
PARAM_FLOAT(yaw);
PARAM_FLOAT(pitch);
PARAM_FLOAT(roll);

I_Error("Quat.FromEuler not implemented");
ret->SetVector4({0, 1, 2, 3}); // X Y Z W
return 1;
DQuaternion quat;
QuatFromAngles(yaw, pitch, roll, &quat);
ACTION_RETURN_QUAT(quat);
}

DEFINE_ACTION_FUNCTION(_QuatStruct, AxisAngle)
void QuatAxisAngle(double x, double y, double z, double angleDeg, DQuaternion* pquat)
{
auto axis = DVector3(x, y, z);
auto angle = DAngle::fromDeg(angleDeg);
*pquat = DQuaternion::AxisAngle(axis, angle);
}

DEFINE_ACTION_FUNCTION_NATIVE(_QuatStruct, AxisAngle, QuatAxisAngle)
{
PARAM_PROLOGUE;
PARAM_FLOAT(x);
PARAM_FLOAT(y);
PARAM_FLOAT(z);
PARAM_FLOAT(angle);

I_Error("Quat.AxisAngle not implemented");
ret->SetVector4({ 0, 1, 2, 3 }); // X Y Z W
return 1;
DQuaternion quat;
QuatAxisAngle(x, y, z, angle, &quat);
ACTION_RETURN_QUAT(quat);
}

void QuatNLerp(
double ax, double ay, double az, double aw,
double bx, double by, double bz, double bw,
double t,
DQuaternion* pquat
)
{
auto from = DQuaternion { ax, ay, az, aw };
auto to = DQuaternion { bx, by, bz, bw };
*pquat = DQuaternion::NLerp(from, to, t);
}

DEFINE_ACTION_FUNCTION(_QuatStruct, Nlerp)
DEFINE_ACTION_FUNCTION_NATIVE(_QuatStruct, NLerp, QuatNLerp)
{
PARAM_PROLOGUE;
PARAM_FLOAT(ax);
Expand All @@ -1168,14 +1192,26 @@ DEFINE_ACTION_FUNCTION(_QuatStruct, Nlerp)
PARAM_FLOAT(by);
PARAM_FLOAT(bz);
PARAM_FLOAT(bw);
PARAM_FLOAT(f);
PARAM_FLOAT(t);

I_Error("Quat.NLerp not implemented");
ret->SetVector4({ 0, 1, 2, 3 }); // X Y Z W
return 1;
DQuaternion quat;
QuatNLerp(ax, ay, az, aw, bx, by, bz, bw, t, &quat);
ACTION_RETURN_QUAT(quat);
}

DEFINE_ACTION_FUNCTION(_QuatStruct, Slerp)
void QuatSLerp(
double ax, double ay, double az, double aw,
double bx, double by, double bz, double bw,
double t,
DQuaternion* pquat
)
{
auto from = DQuaternion { ax, ay, az, aw };
auto to = DQuaternion { bx, by, bz, bw };
*pquat = DQuaternion::SLerp(from, to, t);
}

DEFINE_ACTION_FUNCTION_NATIVE(_QuatStruct, SLerp, QuatSLerp)
{
PARAM_PROLOGUE;
PARAM_FLOAT(ax);
Expand All @@ -1186,9 +1222,43 @@ DEFINE_ACTION_FUNCTION(_QuatStruct, Slerp)
PARAM_FLOAT(by);
PARAM_FLOAT(bz);
PARAM_FLOAT(bw);
PARAM_FLOAT(f);
PARAM_FLOAT(t);

DQuaternion quat;
QuatSLerp(ax, ay, az, aw, bx, by, bz, bw, t, &quat);
ACTION_RETURN_QUAT(quat);
}

I_Error("Quat.SLerp not implemented");
ret->SetVector4({ 0, 1, 2, 3 }); // X Y Z W
return 1;
}
void QuatConjugate(
double x, double y, double z, double w,
DQuaternion* pquat
)
{
*pquat = DQuaternion(x, y, z, w).Conjugate();
}

DEFINE_ACTION_FUNCTION_NATIVE(_QuatStruct, Conjugate, QuatConjugate)
{
PARAM_SELF_STRUCT_PROLOGUE(DQuaternion);

DQuaternion quat;
QuatConjugate(self->X, self->Y, self->Z, self->W, &quat);
ACTION_RETURN_QUAT(quat);
}

void QuatInverse(
double x, double y, double z, double w,
DQuaternion* pquat
)
{
*pquat = DQuaternion(x, y, z, w).Inverse();
}

DEFINE_ACTION_FUNCTION_NATIVE(_QuatStruct, Inverse, QuatInverse)
{
PARAM_SELF_STRUCT_PROLOGUE(DQuaternion);

DQuaternion quat;
QuatInverse(self->X, self->Y, self->Z, self->W, &quat);
ACTION_RETURN_QUAT(quat);
}
10 changes: 10 additions & 0 deletions src/common/scripting/vm/vm.h
Expand Up @@ -147,6 +147,14 @@ struct VMReturn
((double *)Location)[2] = val[2];
((double *)Location)[3] = val[3];
}
void SetQuaternion(const DQuaternion &val)
{
assert(RegType == (REGT_FLOAT | REGT_MULTIREG4));
((double *)Location)[0] = val[0];
((double *)Location)[1] = val[1];
((double *)Location)[2] = val[2];
((double *)Location)[3] = val[3];
}
void SetVector(const double val[3])
{
assert(RegType == (REGT_FLOAT|REGT_MULTIREG3));
Expand Down Expand Up @@ -748,6 +756,8 @@ class AActor;
#define ACTION_RETURN_FLOAT(v) do { double u = v; if (numret > 0) { assert(ret != nullptr); ret->SetFloat(u); return 1; } return 0; } while(0)
#define ACTION_RETURN_VEC2(v) do { DVector2 u = v; if (numret > 0) { assert(ret != nullptr); ret[0].SetVector2(u); return 1; } return 0; } while(0)
#define ACTION_RETURN_VEC3(v) do { DVector3 u = v; if (numret > 0) { assert(ret != nullptr); ret[0].SetVector(u); return 1; } return 0; } while(0)
#define ACTION_RETURN_VEC4(v) do { DVector4 u = v; if (numret > 0) { assert(ret != nullptr); ret[0].SetVector4(u); return 1; } return 0; } while(0)
#define ACTION_RETURN_QUAT(v) do { DQuaternion u = v; if (numret > 0) { assert(ret != nullptr); ret[0].SetQuaternion(u); return 1; } return 0; } while(0)
#define ACTION_RETURN_INT(v) do { int u = v; if (numret > 0) { assert(ret != NULL); ret->SetInt(u); return 1; } return 0; } while(0)
#define ACTION_RETURN_BOOL(v) ACTION_RETURN_INT(v)
#define ACTION_RETURN_STRING(v) do { FString u = v; if (numret > 0) { assert(ret != NULL); ret->SetString(u); return 1; } return 0; } while(0)
Expand Down

0 comments on commit 9f0c518

Please sign in to comment.