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.


