## Internal quaternion class for ZScript

Remember, just because you request it, that doesn't mean you'll get it.

Moderator: GZDoom Developers

### Internal quaternion class for ZScript

I wasn't sure if anyone suggested this before but couldn't find anything on this.

I think it'd be nice if there's an internal quaternion and/or matrix class on the C++ side that could be exposed with functions.

Right now I've been using libraries like Gutawer/Marisa Kirisame/PhantomBeta/Dodopod's quaternions but many times I've found that some are missing some features from the other, or they cause some slowdowns when used en masse.

So I think it would be a good idea to have an internal Quaternion class at the very least to use so we can optimize and present all means of use for modders.

-----

I'm making monsters from Minecraft, and each limb is controlled by ZScript since there's no model animations that would do it justice. This allows me to control the rotation distance of each limb and give it sway where needed, along with offsetting held weapons. The problem is, this happens on all limbs that aren't the torso: the head, arms and legs. Don't even get me started on spider legs...

So constantly using these quaternion classes quickly adds up because there's a lot of operations being performed, and I've had to put some features on hold as a result.

Major Cooke
QZDoom Maintenance Team

Joined: 28 Jan 2007

### Re: Internal quaternion class for ZScript

IMO rotation matrices would be a more suitable solution here.
Because rotation matrices uses matrices (just set of numbers, simple thing) and cos/sin functions (something about triangle angles, simple thing), while quaternions uses 4-dimensional complex numbers (which is a relatively complex thing). So it would be easy for someone to figure out what is rotation matrices and not so easy what is quadro....quatro....quanto...4-dimensional complex number.
Plus, to transform euler angles to quaternion form you still need to find sine/cosine of angles.

Apeirogon
I have a strange sense of humour

Joined: 12 Jun 2017

### Re: Internal quaternion class for ZScript

There are operations that simply aren't comfortable using matrices, such as 6DOF movement. Quaternions are better suited for that.

Marisa Kirisame
ZScript Crimester

Joined: 08 Feb 2008
Location: Vigo, Galicia
Discord: 霧雨魔理沙#1666
Github ID: OrdinaryMagician
Operating System: Other Linux 64-bit
OS Test Version: No (Using Stable Public Version)
Graphics Processor: nVidia with Vulkan support

### Re: Internal quaternion class for ZScript

Not to mention matrices are more expensive, or so I've heard.

Major Cooke
QZDoom Maintenance Team

Joined: 28 Jan 2007

### Re: Internal quaternion class for ZScript

Point was not in the "it would be better" but in "it would be more clear". Quaternion is quite complicated mathematical object by itself.

Apeirogon
I have a strange sense of humour

Joined: 12 Jun 2017

### Re: Internal quaternion class for ZScript

Apeirogon wrote:Point was not in the "it would be better" but in "it would be more clear". Quaternion is quite complicated mathematical object by itself.

Please don't talk about something you don't know, and even if what you said were true, "we shouldn't add it because it's would probably be complex to the layman" is truly a terrible argument, I'll have to remember that one. Quaternions have started to appear again because it turns out the make many things much simpler.

With that being said, I'd argue that added matrix support might be a better idea, but more because matrices are more general, and the performance isn't much worse afaik, if at all in general. Quaternions are a bit more specialized in their application (albeit an important application). Quaternions can also be represent as 4-by-4 real matrices, so adding matrix support can implicitly add quaternion support as well (I'm not sure how the performance of using quaternions that way will be though).

3saster

Joined: 11 May 2018

### Re: Internal quaternion class for ZScript

That was my IMO, not "you should do it as I said to do it, or else........................................................................"
And yes, I see at least one problem with quaternions in this context. Gzdoom are not use any quaternions internally, only matrices. So unless someone implement quaternions on C++ side (just to export them to Zscript then and/or will replace all "angled" code to use quaternions) matrices export/native Zscript implementation are the only solution here.

Apeirogon
I have a strange sense of humour

Joined: 12 Jun 2017

### Re: Internal quaternion class for ZScript

Personally in favor of quaternions. I'm more familiar with them than matrices because I also do work in Unity, and as such I think quats would be more immediately accessible to other devs coming here from other engines.

Although, why not support both? Quats for rotations, matrices for more general use - oooh even colors!

Nero
Royal Boredom....Why can't I do this in Windows?

Joined: 06 Sep 2006
Location: Middle of Nowheresville Il.

### Re: Internal quaternion class for ZScript

Because so many people out there have quaternion packages out there, this would allow to remove the need for having one in a library too, which would be nice to reduce.

Major Cooke
QZDoom Maintenance Team

Joined: 28 Jan 2007

### Re: Internal quaternion class for ZScript

This obviously needs someone who is familiar with quaternion math. That person's not me.

Graf Zahl

Joined: 19 Jul 2003
Location: Germany

### Re: Internal quaternion class for ZScript

I'm familiar with quaternions, but not exactly how they would be implemented in GZDoom. IMO, these should be a base unit akin to ints or strings; or rather more specifically, the operators +,-,*,/ should be written that way, not through some secondary function. The basic jist of quaternions (complex numbers) is that they are just 4-D (2-D) vectors with a specific multiplication operator defined on them. Everything else about them is derived from this operation (addition and subtraction are the same as regular vectors, i.e. element-wise). Perhaps we could come up with a "specification", and someone else does the "guts"?

3saster

Joined: 11 May 2018

### Re: Internal quaternion class for ZScript

Hmm, excuse me .......

which is the easy internal
PitchOffset
AngleOffset
RollOffset
Offset xoffset yoffset zoffset
Scale float float float
(VSMatrix / objectToWorldMatrix)

g4-2-4/src/r_data/models/models.cpp wrote:
Code: Select all
`   VSMatrix objectToWorldMatrix;   objectToWorldMatrix.loadIdentity();   // Model space => World space   objectToWorldMatrix.translate(x, z, y);   // [Nash] take SpriteRotation into account   angle += actor->SpriteRotation.Degrees;   // Applying model transformations:   // 1) Applying actor angle, pitch and roll to the model   if (smf->flags & MDL_USEROTATIONCENTER)   {      objectToWorldMatrix.translate(smf->rotationCenterX, smf->rotationCenterZ, smf->rotationCenterY);   }   objectToWorldMatrix.rotate(-angle, 0, 1, 0);   objectToWorldMatrix.rotate(pitch, 0, 0, 1);   objectToWorldMatrix.rotate(-roll, 1, 0, 0);   if (smf->flags & MDL_USEROTATIONCENTER)   {      objectToWorldMatrix.translate(-smf->rotationCenterX, -smf->rotationCenterZ, -smf->rotationCenterY);   }   // 2) Applying Doomsday like rotation of the weapon pickup models   // The rotation angle is based on the elapsed time.   if (smf->flags & MDL_ROTATING)   {      objectToWorldMatrix.translate(smf->rotationCenterX, smf->rotationCenterY, smf->rotationCenterZ);      objectToWorldMatrix.rotate(rotateOffset, smf->xrotate, smf->yrotate, smf->zrotate);      objectToWorldMatrix.translate(-smf->rotationCenterX, -smf->rotationCenterY, -smf->rotationCenterZ);   }   // 3) Scaling model.   objectToWorldMatrix.scale(scaleFactorX, scaleFactorZ, scaleFactorY);   // 4) Aplying model offsets (model offsets do not depend on model scalings).   objectToWorldMatrix.translate(smf->xoffset / smf->xscale, smf->zoffset / smf->zscale, smf->yoffset / smf->yscale);   // 5) Applying model rotations.   objectToWorldMatrix.rotate(-smf->angleoffset, 0, 1, 0);   objectToWorldMatrix.rotate(smf->pitchoffset, 0, 0, 1);   objectToWorldMatrix.rotate(-smf->rolloffset, 1, 0, 0);`

It would be possible to expose this as:
A_objectToWorldMatrixRotate(pitch, angle ,roll)

that's what i did with all the dodopod code. I simply reduced it to:
void ROTATE_6DOF (double P, double A, double R)
void THRUST_6DOF (X, Y, Z)

Deybar_TECH
Siempre vuelo mas alla de los <∟imites>

Joined: 26 Dec 2018
Location: La Paz - BOLIVIA