void vpRagdoll::Create(vpWorld *pWorld)
{
	int i;

	scalar rope_elasticity = 100.0;
	scalar neck_elasticity = 100;
	scalar waist_elasticity = 100;
	scalar shoulder_elasticity = 100;
	scalar elbow_elasticity = 100;
	scalar hip_elasticity = 100;
	scalar knee_elasticity = 100;

	scalar rope_damping = 50.0;
	scalar neck_damping = 30.0;
	scalar waist_damping = 30.0;
	scalar shoulder_damping = 30.0;
	scalar elbow_damping = 30.0;
	scalar hip_damping = 30.0;
	scalar knee_damping = 30.0;

	vpMaterial::GetDefaultMaterial()->SetRestitution(0.3);
	vpMaterial::GetDefaultMaterial()->SetDynamicFriction(0.1);

	// rope
	G.m_szName = string("ground");
	pWorld->AddBody(&G);
	G.SetGround();
	G.SetJoint(&J_rope[0], Vec3(0, 0, 2 * NUM_ROPE + 15));
	for ( i = 0; i < NUM_ROPE; i++ )
	{
		stringstream strstr;
		strstr << "rope" << i;
		strstr >> B_rope[i].m_szName;
		strstr.clear();
		strstr << "rope" << i+1;
		strstr >> B_rope[i+1].m_szName;
		B_rope[i].SetJoint(&J_rope[i], Vec3(0, 0, 1));
		B_rope[i].SetJoint(&J_rope[i+1], Vec3(0, 0, -1));
		J_rope[i].SetElasticity(0, rope_elasticity);
		J_rope[i].SetDamping(0, rope_damping);
		J_rope[i].SetElasticity(1, rope_elasticity);
		J_rope[i].SetDamping(1, rope_damping);
		B_rope[i].AddGeometry(new vpCapsule(0.2, 2.4));
		pWorld->IgnoreCollision(&B_rope[i], &B_rope[i+1]);
	}

	B_trunk.m_szName = string("trunk");
	B_trunk.SetJoint(&J_rope[NUM_ROPE], Vec3(0, -1.5, -1.5));
	J_rope[NUM_ROPE].SetElasticity(0, rope_elasticity);
	J_rope[NUM_ROPE].SetDamping(0, rope_damping);
	J_rope[NUM_ROPE].SetElasticity(1, rope_elasticity);
	J_rope[NUM_ROPE].SetDamping(1, rope_damping);
	
	// puppet
	B_trunk.AddGeometry(new vpBox(Vec3(2.4, 1.8, 3)));
	B_trunk.SetJoint(&J_neck, Vec3(0, 0, 2));
	J_neck.SetElasticity(0, neck_elasticity);
	J_neck.SetDamping(0, neck_damping);
	J_neck.SetElasticity(1, neck_elasticity);
	J_neck.SetDamping(1, neck_damping);
	
	B_head.m_szName = string("head");
	B_head.SetJoint(&J_neck, Vec3(0, 0, -1));
	B_head.AddGeometry(new vpSphere(1.0));
	
	B_trunk.SetJoint(&J_waist, Vec3(0, 0, -2));
	B_pelvis.SetJoint(&J_waist, Vec3(0, 0, 0.8));
	J_waist.SetElasticity(SpatialSpring(waist_elasticity));
	J_waist.SetDamping(SpatialDamper(waist_damping));
	B_pelvis.AddGeometry(new vpBox(Vec3(2.4, 1.8, 1.8)));
	B_pelvis.m_szName = string("pelvis");

	// left side
	B_trunk.SetJoint(&J_shoulder[0], Vec3(1.8, 0, 1.5));
	B_upper_arm[0].SetJoint(&J_shoulder[0], Vec3(0, 0, 1.2));
	J_shoulder[0].SetElasticity(SpatialSpring(shoulder_elasticity));
	J_shoulder[0].SetDamping(SpatialDamper(shoulder_damping));
	J_shoulder[0].SetOrientation(EulerZYX(Vec3(0, -0.5, 0)));
	B_upper_arm[0].AddGeometry(new vpCapsule(0.6, 2.5));
	
	B_upper_arm[0].SetJoint(&J_elbow[0], Vec3(0, 0, -1.5));
	B_lower_arm[0].SetJoint(&J_elbow[0], Vec3(0, 0, 1.2));
	J_elbow[0].SetAxis(Vec3(1, 0, 0));
	J_elbow[0].SetElasticity(elbow_elasticity);
	J_elbow[0].SetDamping(elbow_damping);
	B_lower_arm[0].AddGeometry(new vpCapsule(0.6, 2.5));
	B_lower_arm[0].AddGeometry(new vpSphere(0.7), Vec3(0, 0, -1.5));

	pWorld->IgnoreCollision(&B_pelvis, &B_thigh[0]);
	B_pelvis.SetJoint(&J_hip[0], Vec3(1.5, 0, -1));
	B_thigh[0].SetJoint(&J_hip[0], Vec3(0, 0, 1.7));
	J_hip[0].SetAngle(1, -0.2);
	J_hip[0].SetElasticity(0, hip_elasticity);
	J_hip[0].SetDamping(0, hip_damping);
	J_hip[0].SetElasticity(1, hip_elasticity);
	J_hip[0].SetDamping(1, hip_damping);
	J_hip[0].SetUpperLimit(0, 1.5);
	J_hip[0].SetLowerLimit(0, -1.5);
	J_hip[0].SetUpperLimit(1, 1.0);
	J_hip[0].SetLowerLimit(1, -1.0);
	J_hip[0].SetRestitution(0, 0.5);
	J_hip[0].SetRestitution(1, 0.5);
	B_thigh[0].AddGeometry(new vpCapsule(0.7, 3.0));

	B_thigh[0].SetJoint(&J_knee[0], Vec3(0, 0, -1.7));
	B_calf[0].SetJoint(&J_knee[0], Vec3(0, 0, 2));
	J_knee[0].SetAxis(Vec3(1, 0, 0));
	J_knee[0].SetElasticity(knee_elasticity);
	J_knee[0].SetDamping(knee_damping);
	J_knee[0].SetUpperLimit(0.1);
	J_knee[0].SetLowerLimit(-1.0);
	B_calf[0].AddGeometry(new vpCapsule(0.7, 3.3));
	B_calf[0].AddGeometry(new vpBox(Vec3(1.5, 2.4, 0.5)), Vec3(0, 0.6, -2));

	// right side
	B_trunk.SetJoint(&J_shoulder[1], Vec3(-1.8, 0, 1.5));
	B_upper_arm[1].SetJoint(&J_shoulder[1], Vec3(0, 0, 1.2));
	J_shoulder[1].SetElasticity(SpatialSpring(shoulder_elasticity));
	J_shoulder[1].SetDamping(SpatialDamper(shoulder_damping));
	J_shoulder[1].SetOrientation(EulerZYX(Vec3(0, 0.5, 0)));
	B_upper_arm[1].AddGeometry(new vpCapsule(0.6, 2.5));
	
	B_upper_arm[1].SetJoint(&J_elbow[1], Vec3(0, 0, -1.5));
	B_lower_arm[1].SetJoint(&J_elbow[1], Vec3(0, 0, 1.2));
	J_elbow[1].SetAxis(Vec3(1, 0, 0));
	J_elbow[1].SetElasticity(elbow_elasticity);
	J_elbow[1].SetDamping(elbow_damping);
	B_lower_arm[1].AddGeometry(new vpCapsule(0.6, 2.5));
	B_lower_arm[1].AddGeometry(new vpSphere(0.7), Vec3(0, 0, -1.5));

	pWorld->IgnoreCollision(&B_pelvis, &B_thigh[1]);
	B_pelvis.SetJoint(&J_hip[1], Vec3(-1.5, 0, -1));
	B_thigh[1].SetJoint(&J_hip[1], Vec3(0, 0, 1.7));
	J_hip[1].SetAngle(1, 0.2);
	J_hip[1].SetElasticity(0, hip_elasticity);
	J_hip[1].SetDamping(0, hip_damping);
	J_hip[1].SetElasticity(1, hip_elasticity);
	J_hip[1].SetDamping(1, hip_damping);
	J_hip[1].SetUpperLimit(0, 1.5);
	J_hip[1].SetLowerLimit(0, -1.5);
	J_hip[1].SetUpperLimit(1, 1.0);
	J_hip[1].SetLowerLimit(1, -1.0);
	J_hip[1].SetRestitution(0, 0.5);
	J_hip[1].SetRestitution(1, 0.5);
	B_thigh[1].AddGeometry(new vpCapsule(0.7, 3.0));

	B_thigh[1].SetJoint(&J_knee[1], Vec3(0, 0, -1.7));
	B_calf[1].SetJoint(&J_knee[1], Vec3(0, 0, 2));
	J_knee[1].SetAxis(Vec3(1, 0, 0));
	J_knee[1].SetElasticity(knee_elasticity);
	J_knee[1].SetDamping(knee_damping);
	J_knee[1].SetUpperLimit(0.1);
	J_knee[1].SetLowerLimit(-1.0);
	B_calf[1].AddGeometry(new vpCapsule(0.7, 3.3));
	B_calf[1].AddGeometry(new vpBox(Vec3(1.5, 2.4, 0.5)), Vec3(0.0, 0.6, -2.0));
}
//This method makes a rotation matrix that rotates around the z axis,
//the y axis, and the x axis in that order.
Matrix3 Matrix3::EulerZYX(const Vector3 &vector3)
{
    return EulerZYX(vector3.x, vector3.y, vector3.z);
}