void PhysicsHelper::CreateTetrahedron(PhysicsWorld& world)
{
	Particle* p0 = new Particle(Random::GetF(-kParticleSpawnVariance, kParticleSpawnVariance), Random::GetF(kParticleHeight, kParticleSpawnVariance + kParticleHeight), Random::GetF(-kParticleSpawnVariance, kParticleSpawnVariance), kRadius, kInverseMass);
	Particle* p1 = new Particle(Random::GetF(-kParticleSpawnVariance, kParticleSpawnVariance), Random::GetF(kParticleHeight, kParticleSpawnVariance + kParticleHeight), Random::GetF(-kParticleSpawnVariance, kParticleSpawnVariance), kRadius, kInverseMass);
	Particle* p2 = new Particle(Random::GetF(-kParticleSpawnVariance, kParticleSpawnVariance), Random::GetF(kParticleHeight, kParticleSpawnVariance + kParticleHeight), Random::GetF(-kParticleSpawnVariance, kParticleSpawnVariance), kRadius, kInverseMass);
	Particle* p3 = new Particle(Random::GetF(-kParticleSpawnVariance, kParticleSpawnVariance), Random::GetF(kParticleHeight, kParticleSpawnVariance + kParticleHeight), Random::GetF(-kParticleSpawnVariance, kParticleSpawnVariance), kRadius, kInverseMass);

	p0->SetVelocity(Random::GetF(-kParticleVelocityRange, kParticleVelocityRange)*kTimeStep, Random::GetF(0.0f, kParticleVelocityRange)*kTimeStep, Random::GetF(-kParticleVelocityRange, kParticleVelocityRange)*kTimeStep);
	p1->SetVelocity(Random::GetF(-kParticleVelocityRange, kParticleVelocityRange)*kTimeStep, Random::GetF(0.0f, kParticleVelocityRange)*kTimeStep, Random::GetF(-kParticleVelocityRange, kParticleVelocityRange)*kTimeStep);
	p2->SetVelocity(Random::GetF(-kParticleVelocityRange, kParticleVelocityRange)*kTimeStep, Random::GetF(0.0f, kParticleVelocityRange)*kTimeStep, Random::GetF(-kParticleVelocityRange, kParticleVelocityRange)*kTimeStep);
	p3->SetVelocity(Random::GetF(-kParticleVelocityRange, kParticleVelocityRange)*kTimeStep, Random::GetF(0.0f, kParticleVelocityRange)*kTimeStep, Random::GetF(-kParticleVelocityRange, kParticleVelocityRange)*kTimeStep);

	world.AddParticle(p0);
	world.AddParticle(p1);
	world.AddParticle(p2);
	world.AddParticle(p3);

	Spring* s0 = new Spring(p0, p1, 1.0f);
	Spring* s1 = new Spring(p1, p2, 1.0f);
	Spring* s2 = new Spring(p2, p3, 1.0f);
	Spring* s3 = new Spring(p3, p0, 1.0f);
	Spring* s4 = new Spring(p0, p2, 1.0f);
	Spring* s5 = new Spring(p1, p3, 1.0f);

	world.AddConstraint(s0);
	world.AddConstraint(s1);
	world.AddConstraint(s2);
	world.AddConstraint(s3);
	world.AddConstraint(s4);
	world.AddConstraint(s5);
}
void PhysicsHelper::CreateCube(PhysicsWorld& world)
{
	Particle* p0 = new Particle(Random::GetF(-kParticleSpawnVariance, kParticleSpawnVariance), Random::GetF(kParticleHeight, kParticleSpawnVariance + kParticleHeight), Random::GetF(-kParticleSpawnVariance, kParticleSpawnVariance), kRadius, kInverseMass);
	Particle* p1 = new Particle(Random::GetF(-kParticleSpawnVariance, kParticleSpawnVariance), Random::GetF(kParticleHeight, kParticleSpawnVariance + kParticleHeight), Random::GetF(-kParticleSpawnVariance, kParticleSpawnVariance), kRadius, kInverseMass);
	Particle* p2 = new Particle(Random::GetF(-kParticleSpawnVariance, kParticleSpawnVariance), Random::GetF(kParticleHeight, kParticleSpawnVariance + kParticleHeight), Random::GetF(-kParticleSpawnVariance, kParticleSpawnVariance), kRadius, kInverseMass);
	Particle* p3 = new Particle(Random::GetF(-kParticleSpawnVariance, kParticleSpawnVariance), Random::GetF(kParticleHeight, kParticleSpawnVariance + kParticleHeight), Random::GetF(-kParticleSpawnVariance, kParticleSpawnVariance), kRadius, kInverseMass);
	Particle* p4 = new Particle(Random::GetF(-kParticleSpawnVariance, kParticleSpawnVariance), Random::GetF(kParticleHeight, kParticleSpawnVariance + kParticleHeight), Random::GetF(-kParticleSpawnVariance, kParticleSpawnVariance), kRadius, kInverseMass);
	Particle* p5 = new Particle(Random::GetF(-kParticleSpawnVariance, kParticleSpawnVariance), Random::GetF(kParticleHeight, kParticleSpawnVariance + kParticleHeight), Random::GetF(-kParticleSpawnVariance, kParticleSpawnVariance), kRadius, kInverseMass);
	Particle* p6 = new Particle(Random::GetF(-kParticleSpawnVariance, kParticleSpawnVariance), Random::GetF(kParticleHeight, kParticleSpawnVariance + kParticleHeight), Random::GetF(-kParticleSpawnVariance, kParticleSpawnVariance), kRadius, kInverseMass);
	Particle* p7 = new Particle(Random::GetF(-kParticleSpawnVariance, kParticleSpawnVariance), Random::GetF(kParticleHeight, kParticleSpawnVariance + kParticleHeight), Random::GetF(-kParticleSpawnVariance, kParticleSpawnVariance), kRadius, kInverseMass);

	p0->SetVelocity(Random::GetF(-kParticleVelocityRange, kParticleVelocityRange)*kTimeStep, Random::GetF(0.0f, kParticleVelocityRange)*kTimeStep, Random::GetF(-kParticleVelocityRange, kParticleVelocityRange)*kTimeStep);
	p1->SetVelocity(Random::GetF(-kParticleVelocityRange, kParticleVelocityRange)*kTimeStep, Random::GetF(0.0f, kParticleVelocityRange)*kTimeStep, Random::GetF(-kParticleVelocityRange, kParticleVelocityRange)*kTimeStep);
	p2->SetVelocity(Random::GetF(-kParticleVelocityRange, kParticleVelocityRange)*kTimeStep, Random::GetF(0.0f, kParticleVelocityRange)*kTimeStep, Random::GetF(-kParticleVelocityRange, kParticleVelocityRange)*kTimeStep);
	p3->SetVelocity(Random::GetF(-kParticleVelocityRange, kParticleVelocityRange)*kTimeStep, Random::GetF(0.0f, kParticleVelocityRange)*kTimeStep, Random::GetF(-kParticleVelocityRange, kParticleVelocityRange)*kTimeStep);
	p4->SetVelocity(Random::GetF(-kParticleVelocityRange, kParticleVelocityRange)*kTimeStep, Random::GetF(0.0f, kParticleVelocityRange)*kTimeStep, Random::GetF(-kParticleVelocityRange, kParticleVelocityRange)*kTimeStep);
	p5->SetVelocity(Random::GetF(-kParticleVelocityRange, kParticleVelocityRange)*kTimeStep, Random::GetF(0.0f, kParticleVelocityRange)*kTimeStep, Random::GetF(-kParticleVelocityRange, kParticleVelocityRange)*kTimeStep);
	p6->SetVelocity(Random::GetF(-kParticleVelocityRange, kParticleVelocityRange)*kTimeStep, Random::GetF(0.0f, kParticleVelocityRange)*kTimeStep, Random::GetF(-kParticleVelocityRange, kParticleVelocityRange)*kTimeStep);
	p7->SetVelocity(Random::GetF(-kParticleVelocityRange, kParticleVelocityRange)*kTimeStep, Random::GetF(0.0f, kParticleVelocityRange)*kTimeStep, Random::GetF(-kParticleVelocityRange, kParticleVelocityRange)*kTimeStep);

	world.AddParticle(p0);
	world.AddParticle(p1);
	world.AddParticle(p2);
	world.AddParticle(p3);
	world.AddParticle(p4);
	world.AddParticle(p5);
	world.AddParticle(p6);
	world.AddParticle(p7);


	Spring* s0 = new Spring(p0, p1, 1.0f);
	Spring* s1 = new Spring(p1, p2, 1.0f);
	Spring* s2 = new Spring(p2, p3, 1.0f);
	Spring* s3 = new Spring(p3, p0, 1.0f);

	Spring* s4 = new Spring(p0, p4, 1.0f);
	Spring* s5 = new Spring(p1, p5, 1.0f);
	Spring* s6 = new Spring(p2, p6, 1.0f);
	Spring* s7 = new Spring(p3, p7, 1.0f);

	Spring* s8 = new Spring(p4, p5, 1.0f);
	Spring* s9 = new Spring(p5, p6, 1.0f);
	Spring* s10 = new Spring(p6, p7, 1.0f);
	Spring* s11 = new Spring(p7, p4, 1.0f);

	f32 const kRootTwo = Math::Sqrt(2.0f);

	Spring* s12 = new Spring(p0, p2, kRootTwo);
	Spring* s13 = new Spring(p1, p3, kRootTwo);
	Spring* s14 = new Spring(p1, p6, kRootTwo);
	Spring* s15 = new Spring(p5, p2, kRootTwo);
	Spring* s16 = new Spring(p4, p6, kRootTwo);
	Spring* s17 = new Spring(p5, p7, kRootTwo);
	Spring* s18 = new Spring(p4, p3, kRootTwo);
	Spring* s19 = new Spring(p0, p7, kRootTwo);
	Spring* s20 = new Spring(p0, p5, kRootTwo);
	Spring* s21 = new Spring(p1, p4, kRootTwo);
	Spring* s22 = new Spring(p3, p6, kRootTwo);
	Spring* s23 = new Spring(p2, p7, kRootTwo);

	world.AddConstraint(s0);
	world.AddConstraint(s1);
	world.AddConstraint(s2);
	world.AddConstraint(s3);
	world.AddConstraint(s4);
	world.AddConstraint(s5);
	world.AddConstraint(s6);
	world.AddConstraint(s7);
	world.AddConstraint(s8);
	world.AddConstraint(s9);
	world.AddConstraint(s10);
	world.AddConstraint(s11);
	world.AddConstraint(s12);
	world.AddConstraint(s13);
	world.AddConstraint(s14);
	world.AddConstraint(s15);
	world.AddConstraint(s16);
	world.AddConstraint(s17);
	world.AddConstraint(s18);
	world.AddConstraint(s19);
	world.AddConstraint(s20);
	world.AddConstraint(s21);
	world.AddConstraint(s22);
	world.AddConstraint(s23);
}
Beispiel #3
0
		void Spawned()
		{
			physics = corpse->game_state->physics_world;

			// get bone pos/ori info
			vector<Mat4> mats = vector<Mat4>();
			unsigned int count = character->skeleton->bones.size();
			for(unsigned int i = 0; i < count; ++i)
			{
				Bone* bone = character->skeleton->bones[i];

				bone_offsets.push_back(bone->rest_pos);
				mats.push_back(whole_xform * bone->GetTransformationMatrix());
			}

			UberModel::BonePhysics** bone_physes = new UberModel::BonePhysics* [count];

			// create rigid bodies
			for(unsigned int i = 0; i < count; ++i)
			{
				Bone* bone = character->skeleton->bones[i];

				Mat4 mat = mats[i];
				float ori_values[] = {mat[0], mat[1], mat[2], mat[4], mat[5], mat[6], mat[8], mat[9], mat[10]};
				bone->ori = Quaternion::FromRotationMatrix(Mat3(ori_values));

				Vec3 bone_pos = mat.TransformVec3(bone_offsets[i], 1);

				UberModel::BonePhysics* phys = NULL;
				for(unsigned int j = 0; j < model->bone_physics.size(); ++j)
					if(Bone::string_table[model->bone_physics[j].bone_name] == bone->name)
						phys = &model->bone_physics[j];

				bone_physes[i] = phys;

				if(phys != NULL)
				{
					btCollisionShape* shape = phys->shape;
					if(shape != NULL)
					{
						RigidBodyInfo* rigid_body = new RigidBodyInfo(shape, MassInfo::FromCollisionShape(shape, phys->mass), bone_pos, bone->ori);

						rigid_body->SetLinearVelocity(initial_vel);

						// these constants taken from the ragdoll demo
						rigid_body->SetDamping(0.05f, 0.85f);
						rigid_body->SetDeactivationTime(0.8f);
						rigid_body->SetSleepingThresholds(1.6f, 2.5f);

						rigid_body->SetFriction(1.0f);
						rigid_body->SetRestitution(0.01f);

						physics->AddRigidBody(rigid_body);
						rigid_bodies.push_back(rigid_body);

						CorpseBoneShootable* shootable = new CorpseBoneShootable(corpse->game_state, corpse, rigid_body, blood_material);
						shootables.push_back(shootable);
						rigid_body->SetCustomCollisionEnabled(shootable);

						bone_indices.push_back(i);
					}
				}
			}

			// create constraints between bones
			for(unsigned int i = 0; i < rigid_bodies.size(); ++i)
			{
				unsigned int bone_index = bone_indices[i];
				UberModel::BonePhysics* phys = bone_physes[bone_index];

				if(phys != NULL)
				{
					Bone* bone = character->skeleton->bones[bone_index];
					Bone* parent = bone->parent;

					if(parent != NULL)
					{
						// find index of parent (bone's index is the same as rigid body info's index)
						for(unsigned int j = 0; j < rigid_bodies.size(); ++j)
						{
							unsigned int j_index = bone_indices[j];

							if(character->skeleton->bones[j_index] == parent)
							{
								if(bone_physes[j_index] != NULL)
								{
									RigidBodyInfo* my_body = rigid_bodies[i];
									RigidBodyInfo* parent_body = rigid_bodies[j];

									ConeTwistConstraint* c = new ConeTwistConstraint(my_body, parent_body, Quaternion::Identity(), Vec3(), phys->ori, phys->pos);
									c->SetLimit(phys->span);
									c->SetDamping(0.1f);							// default is 0.01

									constraints.push_back(c);
									physics->AddConstraint(c, true);				// true = prevent them from colliding normally

									break;
								}
							}
						}
					}
				}
			}

			// emancipate bones
			for(unsigned int i = 0; i < count; ++i)
			{
				Bone* bone = character->skeleton->bones[i];
				bone->parent = NULL;									// orientation and position are no longer relative to a parent!
			}

			if(rigid_bodies.size() == 0)
				corpse->is_valid = false;

			delete[] bone_physes;
		}