How to Flip Quaternion With X,Y,Z,W

Hey Guys… Yo @Deltakosh … How can FLIP the Y -Axis of a Quaternion using the setting of the X,Y,Z,W values ???

I know i can convert the quaternion to euler then invert the Y -axis then convert back to quaternion… but that seems like a alot of work in the an update loop.

I cam trying to sync a physics world transform with the babylon mesh transform:

var tm = this.physicsBody.getWorldTransform(i);
var p = tm.getOrigin();
var q = tm.getRotation();
this.babylonMesh.position.set(p.x(), p.y(), p.z());
this.babylonMesh.rotationQuaternion.set(q.x(), q.y(), q.z(), q.w());

This actually updates my babylon mesh EXCEPT the quaternion is INVERTED on the y and my wheels are flipped around the wrong way… I need to FLIP that quaternion around… I thought i could just multiply the Z and W by -1.0 but that did not work…

What should i do ???

You should be able to multiply the current quaternion by another made which defines a rotation of Math.PI on Y axis

1 Like

And it works! :slight_smile: https://playground.babylonjs.com/#A1210C#44 Line 21 (click screen to test).

1 Like

Shit :frowning:
I tried that:

                tm = this.vehicleController.getWheelTransform(i);
                p = tm.getOrigin();
                q = tm.getRotation();
                this.wheelTransforms[i].position.set(p.x(), p.y(), p.z());
                this.wheelTransforms[i].rotationQuaternion.set(q.x(), q.y(), q.z(), q.w());
                this.wheelTransforms[i].rotationQuaternion.multiplyInPlace(BABYLON.Quaternion.RotationYawPitchRoll(0, Math.PI, 0));

My Wheels are still flipped the wrong way…

Should look like this:

But the wheel positions that are getting set from a btTransform i Physics World… flips it to this:

I tried the code which should just flip the transform around… but it does not :frowning:

Code is pretty simple… Each Frame…

Iterate wheel info… update the in internal wheel info… get the updated world transform and apply that position and rotation to the actual wheel meshes (TansformNode)… so the wheels can turn and bounces up and down with the suspension handling


    protected after(): void {
        if (this.wheelTransforms != null && this.wheelTransforms.length >= 4) {
            let tm:any, p:any, q:any, i:number;
            const n = this.vehicleController.getNumWheels();
            for (i = 0; i < n; i++) {
                this.vehicleController.updateWheelTransform(i, true);
                tm = this.vehicleController.getWheelTransform(i);
                p = tm.getOrigin();
                q = tm.getRotation();
                this.wheelTransforms[i].position.set(p.x(), p.y(), p.z());
                this.wheelTransforms[i].rotationQuaternion.set(q.x(), q.y(), q.z(), q.w());
                this.wheelTransforms[i].rotationQuaternion.multiplyInPlace(BABYLON.Quaternion.RotationYawPitchRoll(0, Math.PI, 0));
            }
        }
    }

maybe transform them the direction you need initially before adding the physics at origin, and then bake them to make sure their origin axis is in the correct alignment?

Or do a secondary calculation that rotates them depending on their position offset from the parent that switches the Pitch value that you are doing?

Id go with the first one if its the physics engine giving you trouble.

Yo @Pryme8 … Thanks for the response…

I dont think i have (or dont know how) a change to Transform the direction of a WHEEL that gets added with the btRaycastVehicle::addWheel

this.m_wheelDirectionCS0 = new Ammo.btVector3(0, -1, 0);    // Y-UP-AXIS
this.m_wheelAxleCS = new Ammo.btVector3(-1, 0, 0);          // Y-UP-AXIS

And then

this.m_vehicle.addWheel(new Ammo.btVector3(wheelHalfTrack, ((wheelAxisHeight + (suspensionDistance * 0.5)) + wheelOffset), wheelAxisPosition), this.m_wheelDirectionCS0, this.m_wheelAxleCS, suspensionRestLength, wheelRadius, this.m_vehicleTuning, isfrontwheel);

Unless you see from the line of code above… i can somehow FLIP or transform the wheel direction before it is added the btRaycastVehicle using addWheel

Note: using the Bullet VehicleDemo.cpp as a guide.

whats the m_wheelAxleCS?

Is from Bullet Physics API… Used in the addWheel method of the btRaycastVehicle class from Bullet Vehicle SDK

From the cpp examples the main difference for dealing with Z-UP vs Y-UP:

// By default, Bullet Vehicle uses Y as up axis.
// You can override the up axis, for example Z-axis up. Enable this define to see how to:
//#define FORCE_ZAXIS_UP 1
//

#ifdef FORCE_ZAXIS_UP
		int rightIndex = 0; 
		int upIndex = 2; 
		int forwardIndex = 1;
		btVector3 wheelDirectionCS0(0,0,-1);
		btVector3 wheelAxleCS(1,0,0);
#else
		int rightIndex = 0;
		int upIndex = 1;
		int forwardIndex = 2;
		btVector3 wheelDirectionCS0(0,-1,0);
		btVector3 wheelAxleCS(-1,0,0);
#endif

Used by the addWheel function:


btWheelInfo & btRaycastVehicle::addWheel	(	const btVector3 & 	connectionPointCS0,
const btVector3 & 	wheelDirectionCS0,
const btVector3 & 	wheelAxleCS,
btScalar 	suspensionRestLength,
btScalar 	wheelRadius,
const btVehicleTuning & 	tuning,
bool 	isFrontWheel 
)		

https://pybullet.org/Bullet/BulletFull/classbtRaycastVehicle.html#ab553ee172346b9cea796abd56ba12a40

NEVER MIND… I lied… that makes everything go backwards :frowning:

What about:

this.wheelTransforms[i].addRotation(0, Math.PI, 0); 

?

1 Like

Thanks @Raggar … That did it… Doesn’t like Multiply that PI rotation… But Adding it works and flips my wheels the right way :slight_smile:

1 Like

Yo @Raggar or @Pryme8 and not to forget @Wingnut

I got another one… How can i easily transform WORLD space position to local space position…

Using the same wheel config above… I have to set the wheelTransform.parent = null becuase the the positions coming from physics world WheelInfo is in WORLD space… How can i leave the wheel as a child of its parent and covert that world position to local position relative to the wheelTransform.parent…

Can i do that ???

Maybe an overall transformNode

Yo @Deltakosh or @sebavan

I found a way to offset the world / local space…

                        var m = new BABYLON.Matrix(); 
                        transform.parent.getWorldMatrix().invertToRef(m); 
                        var v = BABYLON.Vector3.TransformCoordinates(v, m);
                        transform.position.set(v.x, v.y, v.z);

But it messes up the quaternion rotation of the wheel if i transform the position coordinates…

Is there some kind of transform quaternion that i need to do on the rotation as well ???

What are you trying to do precisely?

Yo @Deltakosh … I am trying to turn the wheels of a car using my Physics Vehicle SDK (Babylon Toolkit Wrapper Around Ammo.btRaycastVehicle)

There is a function for each wheel: getWheelTransformWS this return the TRANSFORM in world space for the wheel. I then take the transform.getOrigin (the position) and transform.getRotation (the rotation)
and apply that to the wheels so they turn and bounce while driving.

This all works fine if the wheel has no parent . But if it has a parent, i have to set to null otherwise the wheel is in wrong position. I assume this is because the position and rotation are given in WORLD SPACE and since the wheel has a parent i would need to convert that world space to local space… I tried the inverse transform direction that didnt work…

How should i offset that world space… Subtract the parent position from the word space position or something like that… Can you show me calculation to do such a thing … Please :slight_smile:

Pinging @trevordev

I got this to work and keep the wheel in the correct position relative to its parent:

 var v = new BABYLON.Vector3(this.m_tempPosition.x(), this.m_tempPosition.y(), this.m_tempPosition.z());
                        var m = new BABYLON.Matrix(); 
                        transform.parent.getWorldMatrix().invertToRef(m); 
                        var v = BABYLON.Vector3.TransformCoordinates(v, m);
                        transform.position.set(v.x, v.y, v.z);

But as soon as i add the rotation (Which comes from the WORLD SPACE transform)

transform.rotationQuaternion.set(this.m_tempRotation.x(), this.m_tempRotation.y(), this.m_tempRotation.z(), this.m_tempRotation.w());

They rotate funny… so

Is there some equivalent Inverse Transform Coordinates that is to be used for rotations

@MackeyK24 Does the Quaternion.Inverse function do what you want?

What an exciting thread coming from a position of I always wanted to build 3d from the ground up but was repulsed by maths.