Download

Throw Object with MotionController

Hey All,

I am trying to be able to pickup and throw objects with the Vive MotionController. Currently I can pickup and “drop” objects. The way it is currently working I turn off the phsyics & collision and parent it to the controller mesh. However when I reverse the process it just drops to the ground and doesn’t care about the momentum I am applying to it by waving the controller. How can I apply that force / throw it the direction I wanted when I release the object?

Here is a couple images of what I have so far:
Pickup:
a79d3824e7dccd911a11e23ca31897dadd3ea510.png

Drop:
5a11200aee80d4ca2c66bd4770f2c80670fef295.png

Anyone know how to do this?

Thanks in advance!
Chabala

You need the linear velocity and angular velocity of the controller upon release of object. Then apply those to your object.

Then send me your demo so I can play it! =D

Hey Paul,

I tried doing this.

Velocity:
f45d80720ddab9d16c1bb1c29cd6b50d739d4851.png

However it doesn’t seem to be doing anything. Is there a specific way I should be applying that? Should it be before or after the previous “drop” stuff?

Cheers,
Chabala

Okay, it looks like the error is something to do with how I am setting the Velocities. Apparently, if I use the MotionControllers themselves or the StaticMeshes attached to them it still comes back X0.0, Y0.0, Z0.0 in both.

Looks like it isn’t tracking the velocity of the Motion Controllers or I am not getting that information correctly. Does anyone know how to get that?

Do you know if your “PrimitiveComponent” has a rigidbody with physics? I believe that you’ll not get velocity without those bits.

My only problem with doing that is that I want the StaticMesh to stay where it is initially set up in relation to its parent object. When I check on the Simulate Physics option it just stays on the ground when I pickup the VIVE MotionController.

Are there settings that will allow me to still accomplish that?

Thanks for your information and patience. I am getting close to getting this working.

Cheers,
Chabala

In cases where I only want velocity and not the rest of the physical properties, I’ll fake it a bit by caching the position of the object at each frame as “Last Location”. On Tick, query location, compare with last location to get magnitude and vector direction, save location as “Last Location” so it can be calculated upon the next frame.

Obviously this doesn’t scale to a ton of objects, but when you’ve got important aspects of your game, this is a place that you might spend your calculation budget.

Thanks! That worked really well. I can see how it would be a bit intensive on calculations but since I only really need it for the left and right hand it should work just fine. I now can pickup and throw objects just fine. :slight_smile:

Awesome! Glad it helped out :smiley:

One other quick thing. This only gets me the linear velocity. Not sure how to get the angular velocity. I am trying to mess with the rotation amounts but not sure what the combination is. Can you help me with that as well?

You could do the same with quaternion math and some trig, though that’s where i’d have to start digging and rapidly testing my math myself…

Interesting okay. Testing it is. :slight_smile:

GetPhysicsLinearVelocity() and GetPhysicsAngularVelocity() for MotionController Components return ZeroVector, but i just found out this functions work for collision sphere (or any other actor component) attached to MotionController.

Wow, I had the same issue for ages! Collision sphere’s is a great workaround.

Thank you, Thank you, Thank you!

I also capture the motion controller positions and calculate a velocity vector from that.

Here’s something you’ll want to watch out for: If you’re only capturing the MC position at the current frame and comparing it against the position at the last frame, you’re going to get some pretty wild results if there is even a slight bit of jitter in the hand movement between Frame 0 and Frame T-1. You’ll want to apply some smoothing over time to account for this.

Here’s how I do it:

I create a queue with a fixed length of 10. Every frame, I enqueue the current position of the motion controller. If the queue is full, the last item is dequeued. So, here’s what my data structure looks like:



 0  1  2  3  4  5  6  7  8  9
[V][V][V][V][V][V][V][V][V][V]


When the player releases the grip on the motion controller, I then take the current vector values from the priority queue and then I multiply them by a weighting value, then calculate the deltas and sum them together. The most recent hand position should have the most weight and influence over the trajectory, and the oldest positions should have the least weight. The result is a weighted average vector which gives a smoothed value for velocity. So, if the players hand twitches a tad or they do some really rapid movement, we can still get a nice velocity vector and throw the held object in the hand velocity vector.

If the queue has only one position vector, then we can’t possibly create a delta to find velocity, so we just apply a zero velocity. This can happen if the player taps the grab and throw button extremely quickly. It’s rare, but if you don’t handle it, you’ll crash.

So, could somebody post the calculation for the angular velocity? I’ve never been able to figure out how to get angular velocity in the format UE4 wants for the Set Physics Angular Velocity function.

This seems to work.


FQuat Orientation = GetComponentQuat();
	FQuat DeltaQ = OldOrientation.Inverse() * Orientation;
	FVector Axis;
	float Angle;
	DeltaQ.ToAxisAndAngle(Axis, Angle);
	Angle = FMath::RadiansToDegrees(Angle);
	AngularVelocity = Orientation.RotateVector((Axis * Angle) / DeltaTime);
	OldOrientation = Orientation;

I was having this exact same problem. The solution was to NOT enable/disable collision. If I don’t touch the collision when grabbing/releasing the object, it keeps the momentum perfectly.

For some reason, disabling and enabling collision has this side-effect, but disabling and enabling response to specific collision channels does NOT have this side-effect.