Download

Rationalizing objects' rotations via angular velocity, in C++

First off, I’m coming from Unity development, and I’m trying to translate a system I wrote for that engine to something analogous for UE4.

What I’m trying to write is a system for interacting with objects using the HTC Vive (or Oculus touch, but I don’t have one of those). The system I wrote for Unity works by manipulating objects’ velocity and angular velocity. This is advantageous for a couple of reasons, related mostly to user experience.

So, I’ve gotten it to work in as far as the position of the object goes, by manipulating the object’s velocity. What I’m having trouble with is getting an object to obtain the correct orientation via it’s angular velocity.

In Unity, the c# for the operation I’m attempting to perform looked something like this (Note that I got the guts of what’s going on here from somebody else’s system and applied it to my own):



            rotDelta = this.transform.rotation * Quaternion.Inverse(interactionPoint.rotation);
            rotDelta.ToAngleAxis(out angle, out axis);

            if (angle > 180)
            {
                angle -= 360;
            }

            //make sure the object isn't already in the appropriate rotation
            if (angle != 0 && axis != Vector3.zero)
            {
                //set the object's angular velocity so that the object is rotating towards where it should be as a grabbed object
                grabbedObj.rigidBody.angularVelocity = (Time.fixedDeltaTime * angle * axis) * grabbedObj.rotationFactor;
            }


The first problem I ran into is that rotations in quaternion form aren’t really accessable to blueprint. So, I fired up and figured out the cpp api commands I thought would be the steps in getting this to work. Basically, I was trying to build a blue print node that would spit out the proper vector3 that I could plug into the Set Physics Angular Velocity node.

Here’s what I wrote for UE4 (the blueprint has inputs for the transform of the grabbing controller, the transform of the grabbed object, a float for delta seconds, and a float variable that is meant to speed up or slow down the rotation speed):



FVector UGetAngularVelocity::GetAngVel(FTransform controller, FTransform object, float deltaTime, float angVelFactor)
{
	FVector outputVector;
	FQuat cQuat = controller.GetRotation();
	FQuat oQuat = object.GetRotation();
	FQuat rotDelta = cQuat * oQuat.Inverse();
	FVector axis;
	float angle;
	rotDelta.ToAxisAndAngle(axis, angle);

	if (angle > 180) {
		angle -= 360;
	}

	if (angle != 0) {
		outputVector = angle * axis * deltaTime * angVelFactor;
	}

	return outputVector;
}


This doesn’t really work. When I rotate the grabbing controller, the object sort of rotates in the correct direction, but it’s all messed up. Way slower, and not nearly as interactive.

As I see it, I’m experiencing two main problems here. 1) I don’t have a very good handle on the underlying 3d math taking place here to begin with, and 2) I’m not at all familiar with the UE4 cpp api (yet, I’m getting there).

If anybody who is more familiar with these two subjects than I am feels like giving a helping hand here, I would be much appreciative. :slight_smile:

Thanks!

Hey did you ever end up figuring out a solution? I’ve run into the same problem. :S

I faced the same problem, I solved it this way.



FQuat target_quaternion = target_rotator.Quaternion();
FQuat current_quaternion = current_rotator.Quaternion();
FQuat quaternion_difference = target_quaternion * current_quaternion.Inverse();
FVector angle_speed = quaternion_difference.Euler() * angular_velocity_factor;
angle_speed.X *= -1.0f;
angle_speed.Y *= -1.0f;

component->SetPhysicsAngularVelocityInDegrees(angle_speed);


I reversed the sign of X and Y. I don’t know why, but it worked.