Problems with driveToPose

Problems with driveToPose

drvn的头像
My english isn't perfect, but I hope you can at least understand me.

What I try to achieve is simpel. I want to sync a ragdoll across the internet. And I know all about "You shouldn'tdo that! Calculate the ragdoll-effect on the client-side like all the other games!", but yet I want/need to do it. My old approach to solve this feels both smooth and looks correct. The big drawback is that it is very recource-demanding as I use hkpRigidBody::setTransform() to interpolate all bodies towards the server-position.

The advantage is the way I can directly set the the ragdolls velocities (linear and angular) to the same as the ragdoll on the server side. This results in a ragdoll movingtowards the server-position and receive the server-velocities at the same time.

But the way Havok works you have to do this without using thesetTransform (if your goal isn't to kill the CPU ofc.).

So I found the functionhkaRagdollRigidBodyController::driveToPose (which will solve this in a velocity way). This approach introducetwo new problems.

This picture might illustrate the first one: http://www.drvn.se/ragdoll_sync.png

The left half is how I want it to be (the ragdoll are moving to the server position, but the velocities are neverthelessthe same as the servers) The right half is whats happening (the ragdolls new velocities are totally wrong). My "fix" so far is to simply wait untill next frame/step where to correct them. The second problem is that this seem to jitter the ragdoll evenwhen the server-ragdoll are absolutely still. It feels like something is wrong with the way I calldriveToPose. So here are some code:

// This information is sent to the clients 
hkpRigidBody::getPosition()
hkpRigidBody::getLinearVelocity()
hkpRigidBody::getAngularVelocity()
hkpRigidBody::getRotation()


// Just so you know what the private members are:
// my_bone_weights = float* (they are all set to 0.15f)
// my_ragdoll_rigid_body_controller = hkaRagdollRigidBodyController*
// my_low_skeleton = hkaSkeleton*
// my_ragdoll_instance = hkaRagdollInstance*


void Ragdoll::DriveToWorldPose(float dt, const D3DXVECTOR3 positions[], const D3DXQUATERNION rotations[])
{
	hkaPose low_pose(my_low_skeleton);

	// Update hkaRagdollRigidBodyController to it's current state
	my_ragdoll_rigid_body_controller->reinitialize();


	hkArray ragdoll_world_transforms(my_ragdoll_instance->getNumBones());

	// Set 'ragdoll_world_transforms' to be identical to the server
	for (int i = 0; i < ragdoll_transform.getSize(); ++i)
	{
		ragdoll_world_transforms[i].set(ConvertToVector3(positions[i]), ConvertToQuaternion(rotations[i]), hkVector4(1.0f, 1.0f, 1.0f));
	}

	low_pose.setPoseModelSpace(ragdoll_world_transforms);

	hkLocalBuffer ragdoll_local_transforms(my_ragdoll_instance->getNumBones());

	// This might cause the jitter as my transforms are in world space and not model space
	// But I don't know how to get them to model space :/
	hkaSkeletonUtils::transformModelPoseToLocalPose(
		my_ragdoll_instance->getNumBones(),
		&my_low_skeleton->m_parentIndices[0],
		low_pose.getSyncedPoseModelSpace().begin(),
		ragdoll_local_transforms.begin());


	g_physics->MarkForWrite();
	my_ragdoll_rigid_body_controller->setBoneWeights(my_bone_weights);

	// I pass hkQsTransform::getIdentity() here to make up for setting the transforms in world space and not in model space above.
	// But this might be the wrong as my ragdoll jitters.
	my_ragdoll_rigid_body_controller->driveToPose(dt, &ragdoll_local_transforms[0], hkQsTransform::getIdentity(), HK_NULL);
	g_physics->UnmarkForWrite();
}
Finally I want to thank you for making the best engine ever.
2 帖子 / 0 new
最新文章
如需更全面地了解编译器优化,请参阅优化注意事项
havokcormac的头像

Hi,

From looking at your code, it seems that what you're telling the ragdollRigidBodyController to do is exactly the right-hand side of your diagram.
That is, "drive these rigid bodies toward this world location".

If I understand you correctly you want to drive the client ragdoll to the same pose (in model space) as the server ragdoll, and also to correct the error in overall ragdoll position and orientation in world space.

The distinction between world space and model space is important here.
Model space just means 'relative to a coordinate system you've chosen as the root of your character'.

In this case, you could choose bone 0 of the (client) ragdoll.
Then using hkaSkeletonUtils::transformWorldPoseToLocalPose and passing in the transform of bone 0 as worldFromModel will get you the ragdoll's local pose.

That should eliminate the large error so the client ragdoll should have the same overall velocity as before but its limbs will be taking up the same posture as the server ragdoll.

Now, to get the client ragdoll to move to the same world location as the server ragdoll you'd have to add some (I suppose small) error-correcting velocity calculated from the difference in world positions between the client and server ragdolls (and an angular velocity calculated from their orientations).

This error-correcting velocity would have to be added to each of the client ragdoll's rigid bodies.

Hope that makes sense (crude diagram)

Cormac

登陆并发表评论。