[SOLVED] Quaternion Rigidbody Torque rotation

Hi everyone, after a lot of time away I finally found time to continue my game project :slight_smile:
However Iā€™m directly stuck again at the issue I had last.

Iā€™m trying to rotate a rigidbody to a target quaternion using torque, but I do not manage to wrap my head around the math required :frowning:

I kinda know the idea behind hit, but do not manage to get it into code.
As far as I understand,
a) I calculate the deltaQuaternion between current and targetrotation
b) I convert this via toAngles into Euler angles
c) I clamp the angles based on my maximum rotationAcceleation
d) I convert this into a torque vector
e) predict how long untill target rotation, and determine if acceleration on axis is wanted?

I kinda hope that someone already solved this or a similar problem, as I kinda hit a brickwall here

	Quaternion currentRotation = rigidBody.getPhysicsRotation();
	Quaternion deltaOrientation = targetRotation.mult(currentRotation.inverse());
	Quaternion rotatedDeltaOrient = currentRotation.inverse().mult(deltaOrientation);
	float[] deltaEulerRaw  = new float[3];
	rotatedDeltaOrient.toAngles(deltaEulerRaw);
	//do I risk a gimbal lock here?
	Vector3f deltaEuler = new Vector3f(deltaEulerRaw[0],deltaEulerRaw[1],deltaEulerRaw[2]);

	
	//Clamping for now simulated by scaling it to a probably low speed? use maxis.getTurnSpeedLimit() instead later 
	System.out.println(deltaEuler);
	Vector3f deltaEulerMin = deltaEuler.mult(0.01f);
	
	//instead of just the mass probably use the inertia also for correction of this?
	//somehow incorporate the current angularVelocity and break before reaching target, can this be calculated for each axis if in local space of rigidbody?
	rigidBody.applyTorque(deltaEulerMin.mult(rigidBody.getMass()));
3 Likes

i kinda have gone in something like that , but i think far more simpler , which is RocksPlotterSystem , it was using rocks & gravity only to draw 2d maths functions in jme world :

 public static abstract class Simulate2dQuadratic extends AbstractControl{
        
        private final float zDirection;
        private final float[] xPoints;
        private final float equationConstant;
        private final float timeToGenerate;
        private float generatorTime;
        
        private int xPosition=0;
       
        private final Vector3f coffecientVector;
        /**
         * Simulate Square/Quadratic equation using Formula : f(x)=y=[((x*coffecientX)^2)+C*signC] * coffecientY based upon f(x)=y=(+/-)x^2 (+/-) C
         * 
         * use Right Hand Rule (RHR) to provide yourself with adequate coordinate system orientation in JME world :
         * 
         * where : - thumb is the +ve y-axis going up
         *         - Index is the +ve z-axis going into the screen
         *         - The other fingers represent the direction of +ve x-axis 
         * 
         * so , ++++CoffecientZ -> ++++++in the domain of the function :-))
         * 
         *    , +++++CoffecientY -> +++++++in function Height or peak 
         * 
         *    , +++++CoffecientX -> +++++++in function wide & height/peak
         * 
         * warning : timeToGenerate should be >= 0.5f because this algorithum simulates the 2d Exponential function using Gravitional Acceleration
         *
         * @param coffecientVector the starting point of applying gravity produces coffecientX & coffecientY & coffecientZ
         * @param zDirection the direction on z-axis takes in : SAME_TAIL , REVERSED_TAIL , ORIGIN_TAIL
         * @param xPoints the points on x-axis to find thier f(x)=y 
         * @param equationConstant the equation constant C or the function peak 
         * @param timeToGenerate time required by fps to regenerate rocks
         */
        public Simulate2dQuadratic(Vector3f coffecientVector,float zDirection,float[] xPoints,float equationConstant,float timeToGenerate){
            this.coffecientVector=coffecientVector;
            this.zDirection=zDirection;
            this.xPoints=xPoints;
            this.equationConstant=equationConstant;
            this.timeToGenerate=timeToGenerate;
        }
        /**
         * Simulate Exponential equation using Formula : f(x)=y=[sign*((x*startingPointX)^2)+C*signC] * startingPointY based upon f(x)=y=(+/-)x^2 (+/-) C
         * @param xPosition the current X to be substituted to find the f(x) respectively
         */
        private void simulateQuadraticly(int xPosition){
            rigidRocks.setGravity(new Vector3f(
                    coffecientVector.getX()*xPoints[xPosition],
                    coffecientVector.getY()*((FastMath.pow(xPoints[xPosition], 2)*coffecientVector.getX())+equationConstant),
                    coffecientVector.getZ()*zDirection));
        }
        
        @Override
        protected void controlUpdate(float tpf) {
            generatorTime+=tpf;
            if(generatorTime > timeToGenerate){
                if(xPosition<xPoints.length-1){
                    simulateQuadraticly(xPosition++);
                }else{
                    xPosition=0;
                    afterRockDecays();
                }
                generatorTime=0f;
            }
        }
        /**
         * controls what to do after x ends substitution  
         */
        public abstract void afterRockDecays();

        
        @Override
        protected void controlRender(RenderManager arg0, ViewPort arg1) {

        }
        
    }

I have made QuadraticPlotter , CubicPlotter ,AbsolutePlotter, ModuluoPlotter,LinearPlotter,Reciprocal&Radical``` ,

i was trying to handle & wrap the Circle equation in gravity to create a circular motion by some (x,z) co-ordinates , but i am still trying , you can try using Gravity because applyTorque sometimes gives bad behavour .

EDIT: so circle equation is basically nothing but Pythagras theory :smile: , if you can do (x,z) points based on the object that you try to rotate around , you will get the answer using gravity only.

https://www.mathsisfun.com/algebra/circle-equations.html

Maybe this answer can help you: https://gamedev.stackexchange.com/a/81387/108825 :slight_smile:

Ok that helped, the simple case seems to work for now

  Quaternion currentRotation = rigidBody.getPhysicsRotation();
  Quaternion deltaOrientation = targetRotation.inverse().mult(currentRotation);
  float[] deltaEulerRaw  = new float[3];
  //do I risk a gimbal lock here?
  deltaOrientation.toAngles(deltaEulerRaw);

  Vector3f deltaEuler = new Vector3f(-deltaEulerRaw[0],-deltaEulerRaw[1],-deltaEulerRaw[2]);
  System.out.println(deltaEuler);
  
  Vector3f local = new Vector3f(deltaEuler);
  local = currentRotation.mult(local);
  rigidBody.applyTorqueMassless(local);
  

  //instead of just the mass probably use the inertia also for correction of this?
  //somehow incorporate the current angularVelocity and break before reaching target, can this be calculated for each axis if in local space of rigidbody?
  //simple stabilizing for now
  rigidBody.setAngularDamping(0.9f);

The important information was, that bullet seems to do torque in world space

Now I need to think about incorporating the current angular velocity in a way so I can reduce the angular dampening by a lot (as that causes a lot of strange effects when colliding)

2 Likes