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); }
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; }