AABB <float> BEZIER::GetAABB() const { float maxv[3]; float minv[3]; bool havevals[6]; for (int n = 0; n < 6; n++) havevals[n] = false; for (int x = 0; x < 4; x++) { for (int y = 0; y < 4; y++) { MATHVECTOR<float,3> temp(points[x][y]); //cache for bbox stuff for ( int n = 0; n < 3; n++ ) { if (!havevals[n]) { maxv[n] = temp[n]; havevals[n] = true; } else if (temp[n] > maxv[n]) maxv[n] = temp[n]; if (!havevals[n+3]) { minv[n] = temp[n]; havevals[n+3] = true; } else if (temp[n] < minv[n]) minv[n] = temp[n]; } } } MATHVECTOR<float,3> bboxmin(minv[0], minv[1], minv[2]); MATHVECTOR<float,3> bboxmax(maxv[0], maxv[1], maxv[2]); AABB <float> box; box.SetFromCorners(bboxmin, bboxmax); return box; }
//---------------------------------------------------------------------------------------------------------------------------------- /// Init dynamics //---------------------------------------------------------------------------------------------------------------------------------- void CARDYNAMICS::Init( class SETTINGS* pSet1, class Scene* pScene1, class FluidsXml* pFluids1, COLLISION_WORLD & world, const MODEL & chassisModel, const MODEL & wheelModelFront, const MODEL & wheelModelRear, const MATHVECTOR<Dbl,3> & position, const QUATERNION<Dbl> & orientation) { pSet = pSet1; pScene = pScene1; pFluids = pFluids1; this->world = &world; MATHVECTOR<Dbl,3> zero(0, 0, 0); body.SetPosition(position); body.SetOrientation(orientation); body.SetInitialForce(zero); body.SetInitialTorque(zero); // init engine engine.SetInitialConditions(); // init chassis btTransform tr; tr.setIdentity(); AABB <float> box = chassisModel.GetAABB(); for (int i = 0; i < 4; i++) { MATHVECTOR<float,3> wheelpos = GetLocalWheelPosition(WHEEL_POSITION(i), 0); const MODEL * wheelmodel = &wheelModelFront; if (i > 1) wheelmodel = &wheelModelRear; AABB <float> wheelaabb; float sidefactor = 1.0; if (i == 1 || i == 3) sidefactor = -1.0; wheelaabb.SetFromCorners( wheelpos - wheelmodel->GetAABB().GetSize() * 0.5 * sidefactor, wheelpos + wheelmodel->GetAABB().GetSize() * 0.5 * sidefactor); box.CombineWith(wheelaabb); } /// chassis shape --------------------------------------------------------- const MATHVECTOR<Dbl,3> verticalMargin(0, 0, 0.3); btVector3 origin = ToBulletVector(box.GetCenter() + verticalMargin - center_of_mass); btVector3 size = ToBulletVector(box.GetSize() - verticalMargin); //btCompoundShape * chassisShape = new btCompoundShape(false); #if 0 //btBoxShape * hull = new btBoxShape( btVector3(1.8,0.8,0.5) ); btBoxShape * hull = new btBoxShape( btVector3(1.7,0.7,0.3) ); tr.setOrigin(origin + btVector3(0,0,0.2)); chassisShape->addChildShape(tr, hull); #else /// todo: all params in .car // y| length x- width z^ height btScalar w = size.getX()*0.2, r = size.getZ()*0.3, h = 0.45; /// spheres btScalar l0 = 0.f, w0 = 0.f, h0 = 0.f; if (coll_R > 0.f) r = coll_R; l0 = coll_Lofs; if (coll_W > 0.f) w = coll_W; w0 = coll_Wofs; if (coll_H > 0.f) h = coll_H; h0 = coll_Hofs; origin = btVector3(l0, w0, h0); btScalar r2 = r*0.6; btScalar l1 = coll_posLfront, l2 = coll_posLback, l1m = l1*0.5, l2m = l2*0.5; //LogO("Car shape dims: r="+toStr(r)+" w="+toStr(w)+" h="+toStr(h)+" h0="+toStr(h0)); //LogO("Car offset: x="+toStr(origin.x())+" y="+toStr(origin.y())+" z="+toStr(origin.z())); const int numSph = 14; int i = 0; btScalar rad[numSph]; btVector3 pos[numSph]; pos[i] = btVector3( l1 , -w, -h); rad[i] = r2; ++i; // front pos[i] = btVector3( l1 , w, -h); rad[i] = r2; ++i; pos[i] = btVector3( l1m, -w, -h); rad[i] = r; ++i; // front near pos[i] = btVector3( l1m, w, -h); rad[i] = r; ++i; pos[i] = btVector3( l2m, -w, -h); rad[i] = r; ++i; // rear near pos[i] = btVector3( l2m, w, -h); rad[i] = r; ++i; pos[i] = btVector3( l2 , -w, -h); rad[i] = r2; ++i; // rear pos[i] = btVector3( l2 , w, -h); rad[i] = r2; ++i; pos[i] = btVector3( 0.4, -w*0.8, h*0.2); rad[i] = r2; ++i; // top pos[i] = btVector3( 0.4, w*0.8, h*0.2); rad[i] = r2; ++i; pos[i] = btVector3(-0.3, -w*0.8, h*0.4); rad[i] = r2; ++i; pos[i] = btVector3(-0.3, w*0.8, h*0.4); rad[i] = r2; ++i; pos[i] = btVector3(-1.1, -w*0.8, h*0.2); rad[i] = r2; ++i; // top rear pos[i] = btVector3(-1.1, w*0.8, h*0.2); rad[i] = r2; ++i; for (i=0; i < numSph; ++i) pos[i] += origin; btMultiSphereShape* chassisShape = new btMultiSphereShape(pos, rad, numSph); //chassisShape->setMargin(0.2f); #endif Dbl chassisMass = body.GetMass();// * 0.4; // Magic multiplier makes collisions better - problem: mud is very different MATRIX3 <Dbl> inertia = body.GetInertia(); btVector3 chassisInertia(inertia[0], inertia[4], inertia[8]); btTransform transform; transform.setOrigin(ToBulletVector(position)); transform.setRotation(ToBulletQuaternion(orientation)); btDefaultMotionState * chassisState = new btDefaultMotionState(); chassisState->setWorldTransform(transform); btRigidBody::btRigidBodyConstructionInfo info(chassisMass, chassisState, chassisShape, chassisInertia); info.m_angularDamping = ang_damp; info.m_restitution = 0.0; //... info.m_friction = coll_friction; /// 0.4~ 0.7 /// chasis^ chassis = world.AddRigidBody(info, true, pSet->game.collis_cars); chassis->setActivationState(DISABLE_DEACTIVATION); chassis->setUserPointer(new ShapeData(ST_Car, this, 0)); ///~~ world.AddAction(this); /// join chassis and wheel triggers //________________________________________________________ { for (int w=0; w < 4; ++w) { WHEEL_POSITION wp = WHEEL_POSITION(w); Dbl whR = GetWheel(wp).GetRadius() * 1.2; //bigger par.. MATHVECTOR<float,3> wheelpos = GetWheelPosition(wp, 0); //par wheelpos[0] += coll_Lofs; wheelpos[2] += coll_flTrig_H; btSphereShape* whSph = new btSphereShape(whR); //btCylinderShapeX* whSph = new btCylinderShapeX(btVector3(whR,whR,whR));//todo.. whTrigs = new btRigidBody(0.001f, 0, whSph); whTrigs->setUserPointer(new ShapeData(ST_Wheel, this, 0, w)); ///~~ whTrigs->setActivationState(DISABLE_DEACTIVATION); whTrigs->setCollisionFlags(whTrigs->getCollisionFlags() | btCollisionObject::CF_NO_CONTACT_RESPONSE); world.world->addRigidBody(whTrigs); world.shapes.push_back(whSph); //todo: collision mask only to fluid triggers //todo: optimize- 1 constr only or none? //todo: cylinders? fixed constr\_ /*btTransform f1,f2; f1.setIdentity(); f2.setIdentity(); f1.setOrigin(ToBulletVector(wheelpos)); btGeneric6DofConstraint* constr = new btGeneric6DofConstraint(*chassis, *whTrigs, f1, f2, true); constr->setLimit(0,0,0); constr->setLimit(1,0,1); constr->setLimit(2,0,0); //constr->setLimit(3,0,0); //constr->setLimit(4,0,0); constr->setLimit(5,0,0);/*??*/ btTypedConstraint* constr = new btPoint2PointConstraint(*chassis, *whTrigs, ToBulletVector(wheelpos), btVector3(0,0,0)); world.world->addConstraint(constr, true); world.constraints.push_back(constr); } /// init poly for buoyancy computations //________________________________________________________ if (poly == NULL) { poly = new Polyhedron(); poly->numVerts = 8; poly->numFaces = 12; poly->verts = new Vec3[8]; poly->faces = new Face[12]; float hx = 1.2f, hy = 0.7f, hz = 0.4f; // box dim poly->verts[0] = Vec3(-hx,-hy,-hz); poly->verts[1] = Vec3(-hx,-hy, hz); poly->verts[2] = Vec3(-hx, hy,-hz); poly->verts[3] = Vec3(-hx, hy, hz); poly->verts[4] = Vec3( hx,-hy,-hz); poly->verts[5] = Vec3( hx,-hy, hz); poly->verts[6] = Vec3( hx, hy,-hz); poly->verts[7] = Vec3( hx, hy, hz); poly->faces[0] = Face(0,1,3); poly->faces[1] = Face(0,3,2); poly->faces[2] = Face(6,3,7); poly->faces[3] = Face(6,2,3); poly->faces[4] = Face(4,6,5); poly->faces[5] = Face(6,7,5); poly->faces[6] = Face(4,5,0); poly->faces[7] = Face(0,5,1); poly->faces[8] = Face(5,7,1); poly->faces[9] = Face(7,3,1); poly->faces[10]= Face(0,6,4); poly->faces[11]= Face(0,2,6); poly->length = 1.0f; // approx. length-? poly->volume = ComputeVolume(*poly); body_mass = 1900.0f * 2.688; //poly->volume; // car density body_inertia = (4.0f * body_mass / 12.0f) * btVector3(hy*hz, hx*hz, hx*hy); } } //------------------------------------------------------------- // init wheels, suspension for (int i = 0; i < WHEEL_POSITION_SIZE; i++) { wheel[WHEEL_POSITION(i)].SetInitialConditions(); wheel_velocity[i].Set(0.0); wheel_position[i] = GetWheelPositionAtDisplacement(WHEEL_POSITION(i), 0); wheel_orientation[i] = orientation * GetWheelSteeringAndSuspensionOrientation(WHEEL_POSITION(i)); } AlignWithGround();//-- }