示例#1
0
文件: ragdoll.cpp 项目: garinh/cs
  void RagdollAnimNode::BlendState (csSkeletalState2* state, float baseWeight)
  {
    if (!isActive)
      return;

    //printf ("RagdollAnimNode::BlendState\n");

    // TODO: use baseWeight
    for (csHash<Bone, BoneID>::GlobalIterator it = bones.GetIterator ();
	 it.HasNext(); )
    {
      Bone bone = it.Next ();
      csOrthoTransform bodyTransform = bone.rigidBody->GetTransform ();

      // TODO: test for deactivation of rigid body
      BoneID parentBoneID = skeleton->GetFactory ()->GetBoneParent (bone.boneID);

      // if this bone is the root of the skeleton
      // TODO: valid also for root of dynamic node?
      if (parentBoneID == InvalidBoneID)
      {
	csQuaternion boneRotation;
	csVector3 boneOffset;
	skeleton->GetFactory ()->GetTransformBoneSpace (bone.boneID, boneRotation,
							boneOffset);
	csOrthoTransform boneTransform (csMatrix3 (boneRotation), boneOffset);
	csOrthoTransform newTransform = boneTransform.GetInverse () * bodyTransform;

	iMovable* movable = sceneNode->GetMovable ();
	movable->SetTransform (newTransform);
	movable->UpdateMove ();

	continue;
      }
      
      // if this bone is inside the ragdoll chain
      if (bones.Contains (parentBoneID))
      {
	Bone nullBone;
	csOrthoTransform parentTransform = bones.Get (parentBoneID, nullBone)
	  .rigidBody->GetTransform ();
	csReversibleTransform relativeTransform =
	  bodyTransform * parentTransform.GetInverse ();

	state->SetBoneUsed (bone.boneID);
	state->GetVector (bone.boneID) = relativeTransform.GetOrigin ();
	csQuaternion quaternion;
	quaternion.SetMatrix (relativeTransform.GetT2O ());
	state->GetQuaternion (bone.boneID) = quaternion;

	continue;
      }

      // else this bone is the root of the ragdoll chain, but not of the skeleton
      else
      {
	// TODO: use kinematic object if not the root of the animesh
      }
    }
  }
void reMeshRenderable::updateShader( reShader* shader )
{
	if (mesh()->hasSkin)
	{
		if (!bonesMatched) matchBones();
		reMat4 bones[32];
		for ( size_t i=0; i<boneLinks.size(); i++)
		{
			if (boneLinks[i].bone)
			{
				reMat4 boneTransform(boneLinks[i].bone->worldTransform().matrix);
				reMat4 linkTransform(boneLinks[i].linkMatrix);
				bones[i] = boneTransform * linkTransform;
			}
		}
		shader->setUniformMatrix(reShader::boneMatrices, 32, glm::value_ptr(bones[0]));
	}
}
示例#3
0
文件: ragdoll.cpp 项目: garinh/cs
  bool RagdollAnimNode::CreateRigidBodyNode (iBodyChainNode* node,
					     iRigidBody* parentBody)
  {
    iBodyBone* bodyBone = node->GetBodyBone ();

    // check availability of collider
    if (!bodyBone->GetBoneColliderCount ())
    {
      factory->manager->Report (CS_REPORTER_SEVERITY_ERROR,
			"No colliders for bone %i while creating ragdoll chain.\n",
			bodyBone->GetAnimeshBone ());
      return false;
    }

    // check availability of joint
    if (parentBody && !bodyBone->GetBoneJoint ())
    {
      factory->manager->Report (CS_REPORTER_SEVERITY_ERROR,
			"No joint for bone %i while creating ragdoll chain.\n",
			bodyBone->GetAnimeshBone ());
      return false;
    }

    // create bone reference
    Bone bone;
    bone.boneID = bodyBone->GetAnimeshBone ();

    // create rigid body
    csRef<iRigidBody> rigidBody = factory->dynSys->CreateBody ();
    bone.rigidBody = rigidBody;

    // set body position
    csQuaternion rotation;
    csVector3 offset;
    skeleton->GetTransformAbsSpace (bone.boneID, rotation, offset);
    // TODO: we shouldn't have to use the conjugate of the quaternion, isn't it?
    csOrthoTransform boneTransform (csMatrix3 (rotation.GetConjugate ()), offset);
    csOrthoTransform animeshTransform = sceneNode->GetMovable ()->GetTransform ();
    csOrthoTransform bodyTransform = boneTransform * animeshTransform;
    rigidBody->SetTransform (bodyTransform);

    // set body properties if they are defined
    // (with the Bullet plugin, it is more efficient to define it before the colliders)
    iBodyBoneProperties* properties = bodyBone->GetBoneProperties ();
    if (properties)
      rigidBody->SetProperties (properties->GetMass (),
				properties->GetCenter (),
				properties->GetInertia ());

    // attach bone colliders
    for (uint index = 0; index < bodyBone->GetBoneColliderCount (); index++)
    {
      iBodyBoneCollider* collider = bodyBone->GetBoneCollider (index);

      switch (collider->GetGeometryType ())
	{
	case BOX_COLLIDER_GEOMETRY:
	  {
	    csVector3 boxSize;
	    collider->GetBoxGeometry (boxSize);
	    rigidBody->AttachColliderBox
	      (boxSize, collider->GetTransform (), collider->GetFriction (),
	       collider->GetDensity (), collider->GetElasticity (),
	       collider->GetSoftness ());
	    break;
	  }

	case CYLINDER_COLLIDER_GEOMETRY:
	  {
	    float length, radius;
	    collider->GetCylinderGeometry (length, radius);
	    rigidBody->AttachColliderCylinder
	      (length, radius, collider->GetTransform (), collider->GetFriction (),
	       collider->GetDensity (), collider->GetElasticity (),
	       collider->GetSoftness ());
	    break;
	  }

	case CAPSULE_COLLIDER_GEOMETRY:
	  {
	    float length, radius;
	    collider->GetCapsuleGeometry (length, radius);
	    rigidBody->AttachColliderCapsule
	      (length, radius, collider->GetTransform (), collider->GetFriction (),
	       collider->GetDensity (), collider->GetElasticity (),
	       collider->GetSoftness ());
	    break;
	  }

	case CONVEXMESH_COLLIDER_GEOMETRY:
	  {
	    iMeshWrapper* mesh;
	    collider->GetConvexMeshGeometry (mesh);
	    rigidBody->AttachColliderConvexMesh
	      (mesh, collider->GetTransform (), collider->GetFriction (),
	       collider->GetDensity (), collider->GetElasticity (),
	       collider->GetSoftness ());
	    break;
	  }

	case TRIMESH_COLLIDER_GEOMETRY:
	  {
	    iMeshWrapper* mesh;
	    collider->GetMeshGeometry (mesh);
	    rigidBody->AttachColliderMesh
	      (mesh, collider->GetTransform (), collider->GetFriction (),
	       collider->GetDensity (), collider->GetElasticity (),
	       collider->GetSoftness ());
	    break;
	  }

	case PLANE_COLLIDER_GEOMETRY:
	  {
	    csPlane3 plane;
	    collider->GetPlaneGeometry (plane);
	    // TODO: add transform
	    rigidBody->AttachColliderPlane
	      (plane, collider->GetFriction (),
	       collider->GetDensity (), collider->GetElasticity (),
	       collider->GetSoftness ());
	    break;
	  }

	case SPHERE_COLLIDER_GEOMETRY:
	  {
	    csSphere sphere;
	    collider->GetSphereGeometry (sphere);
	    rigidBody->AttachColliderSphere
	      (sphere.GetRadius (),
	       sphere.GetCenter () + collider->GetTransform ().GetOrigin (),
	       collider->GetFriction (), collider->GetDensity (),
	       collider->GetElasticity (), collider->GetSoftness ());
	    break;
	  }

	default:
	  factory->manager->Report (CS_REPORTER_SEVERITY_ERROR,
	    "No geometry for collider in bone %i while creating ragdoll chain.\n",
				    bodyBone->GetAnimeshBone ());
	  return false;
	}
    }

    // TODO: remove bodies if problem

    // create dynamic joint
    if (parentBody)
      bone.joint = CreateDynamicJoint (bodyBone->GetBoneJoint (),
				       parentBody, rigidBody);

    // store bone
    bones.Put (bone.boneID, bone);

    // create child nodes
    for (uint i = 0; i < node->GetChildCount (); i++)
      if (!CreateRigidBodyNode (node->GetChild (i), rigidBody))
      {
	factory->manager->Report (CS_REPORTER_SEVERITY_ERROR,
				  "Problem creating ragdoll body for bone %i\n",
				  bodyBone->GetAnimeshBone ());
	return false;
      }

    return true;
  }
示例#4
0
  void IKPhysicalNode::AddConstraint (CS::Animation::EffectorID effectorID,
					  ConstraintData& constraint)
  {
    // Find the effector data
    EffectorData* effector = factory->effectors[effectorID];

    // Check if this chain has already some constraints
    ChainData chainData;
    if (!chains.Contains (effector->chain))
    {
      // Create a new entry for the chain
      chainData.previousState = ragdollNode->GetBodyChainState (effector->chain);
      chainData.constraintCount = 1;
      chains.Put (effector->chain, chainData);

      // Set the chain as dynamic
      ragdollNode->SetBodyChainState (effector->chain, CS::Animation::STATE_DYNAMIC);
    }

    else
    {
      chainData = chains.Get (effector->chain, chainData);
      chainData.constraintCount++;
    }

    // Compute the world transform of the effector
    csQuaternion boneRotation;
    csVector3 boneOffset;
    skeleton->GetTransformAbsSpace (effector->bone, boneRotation, boneOffset);
    csOrthoTransform boneTransform (csMatrix3 (boneRotation.GetConjugate ()), boneOffset);
    csOrthoTransform effectorTransform =
      effector->transform * boneTransform * sceneNode->GetMovable ()->GetFullTransform ();

    // Compute the world transform of the constraint target
    csOrthoTransform targetTransform;
    switch (constraint.type)
    {
    case CONSTRAINT_FIXED:
      targetTransform = constraint.offset;
      break;

    case CONSTRAINT_MOVABLE:
      targetTransform = constraint.offset * constraint.movable->GetFullTransform ();
      break;

    case CONSTRAINT_CAMERA:
      targetTransform = constraint.offset * constraint.camera->GetTransform ();
      break;

    default:
      break;
    }

    // Create a pivot joint
    constraint.dragJoint = bulletDynamicSystem->CreatePivotJoint ();
    constraint.dragJoint->Attach (ragdollNode->GetBoneRigidBody (effector->bone),
				  effectorTransform.GetOrigin ());
    constraint.dragJoint->SetPosition (targetTransform.GetOrigin ());

    constraints.PutUnique (effectorID, constraint);
  }