Internal quaternion class for ZScript

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

Moderator: GZDoom Developers

User avatar
Major Cooke
Posts: 8197
Joined: Sun Jan 28, 2007 3:55 pm
Preferred Pronouns: He/Him
Location: QZDoom Maintenance Team

Internal quaternion class for ZScript

Post by Major Cooke »

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.
User avatar
Apeirogon
Posts: 1606
Joined: Mon Jun 12, 2017 12:57 am

Re: Internal quaternion class for ZScript

Post by Apeirogon »

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.
User avatar
Marisa the Magician
Posts: 3886
Joined: Fri Feb 08, 2008 9:15 am
Preferred Pronouns: She/Her
Operating System Version (Optional): (btw I use) Arch
Graphics Processor: nVidia with Vulkan support
Location: Vigo, Galicia

Re: Internal quaternion class for ZScript

Post by Marisa the Magician »

There are operations that simply aren't comfortable using matrices, such as 6DOF movement. Quaternions are better suited for that.
User avatar
Major Cooke
Posts: 8197
Joined: Sun Jan 28, 2007 3:55 pm
Preferred Pronouns: He/Him
Location: QZDoom Maintenance Team

Re: Internal quaternion class for ZScript

Post by Major Cooke »

Not to mention matrices are more expensive, or so I've heard.
User avatar
Apeirogon
Posts: 1606
Joined: Mon Jun 12, 2017 12:57 am

Re: Internal quaternion class for ZScript

Post by Apeirogon »

Point was not in the "it would be better" but in "it would be more clear". Quaternion is quite complicated mathematical object by itself.
User avatar
3saster
Posts: 199
Joined: Fri May 11, 2018 2:39 pm
Location: Canada

Re: Internal quaternion class for ZScript

Post by 3saster »

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).
User avatar
Apeirogon
Posts: 1606
Joined: Mon Jun 12, 2017 12:57 am

Re: Internal quaternion class for ZScript

Post by Apeirogon »

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.
User avatar
Sarah
Posts: 551
Joined: Wed Sep 06, 2006 12:36 pm
Preferred Pronouns: She/Her
Operating System Version (Optional): Debian 11 (bullseye), Windows 10
Location: Middle of Nowheresville Il.

Re: Internal quaternion class for ZScript

Post by Sarah »

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!
User avatar
Major Cooke
Posts: 8197
Joined: Sun Jan 28, 2007 3:55 pm
Preferred Pronouns: He/Him
Location: QZDoom Maintenance Team

Re: Internal quaternion class for ZScript

Post by Major Cooke »

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.
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49194
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: Internal quaternion class for ZScript

Post by Graf Zahl »

This obviously needs someone who is familiar with quaternion math. That person's not me.
User avatar
3saster
Posts: 199
Joined: Fri May 11, 2018 2:39 pm
Location: Canada

Re: Internal quaternion class for ZScript

Post by 3saster »

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"?
User avatar
Deybar_TECH
Posts: 159
Joined: Wed Dec 26, 2018 3:36 pm
Preferred Pronouns: He/Him
Operating System Version (Optional): Windows 7
Graphics Processor: Not Listed
Location: El Alto - La Paz - BOLIVIA

Re: Internal quaternion class for ZScript

Post by Deybar_TECH »

Hmm, excuse me .......

which is the easy internal
pre-adjustment of MODELDEF:
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)

Return to “Feature Suggestions [GZDoom]”