//--------------------------------------------------------------------------- CFabAtHomeView::CFabAtHomeView() //--------------------------------------------------------------------------- { hrc = 0; bRolling = FALSE; bPanning = FALSE; m_fov = 40; scale = 0.007; eye = CVec(0,0,5); view = CVec(0,0,-1000); up = CVec(0,1.0,0); bShowModel = true; bShowPrinter = true; bShaded = true; bShowPaths = true; bShowTrace = true; bFollowCurrentLayer = false; bShowCommanded =false; //try to show real-time positions firstlayer = -1; lastlayer = -1; m_bDrawing = false; m_dwTimerPeriod = VIEW_REFRESH_MULT*STATUS_UPDATE_PERIOD; bModelNormals = false; bPathNormals = false; }
//--------------------------------------------------------------------------- void CPrinterComponent::SetDefaults(void) //--------------------------------------------------------------------------- { geom.Clear(); color = CVec(100,100,100); alpha = 1; dir = CVec(1,0,0); mmps = 0.01; offset = CVec(0,0,0); refidx = -1; curstep = 0; cmdstep = 0; laststep = 0; cur_t = 0; last_t = 0; stepstomove = 0; rangemin = 0; rangemax = 240; vwindow = 5; v_calc_step = 0; velocity = 0; home = 0; posLimitSwitch = FALSE; negLimitSwitch = FALSE; axis = -1; axisDir = 1; jogIncrement = JOG_STEP_AXIS; m_dErrOffset = 0; component_geom = ""; component_appendgeom = ""; }
/////////////////// // Setup the camera for the car void Car_SetupCamera(carsim_t *psCar, CCamera *pcCam, float dt) { float length = 40; if(!pcCam) return; CVec pos = psCar->cPos; CVec up = psCar->Z; // Limit the UP vector to a certain degree up.SetZ( MAX(0.5f, up.GetZ()) ); psCar->cDestCamPos = pos - psCar->Y * length + up * 10; CVec v = pcCam->getPos() - psCar->cDestCamPos; float dist = VectorNormalize(&v); // Spring to the 'normal' position CVec campos = pcCam->getPos() - v * CVec(10,10,5) * (dist*dt); // Follow car camera pcCam->Setup( campos, pos+psCar->Y*8 ); // // DEVELOPER: side view // keyboard_t *kb = System_GetKeyboard(); if(psOptions->nDeveloper) { if(kb->keys[SDLK_q]) pcCam->Setup( pos - psCar->X*35 + psCar->Z*5, pos); if(kb->keys[SDLK_e]) pcCam->Setup( pos + psCar->X*35 + psCar->Z*5, pos); if(kb->keys[SDLK_w]) pcCam->Setup( pos + psCar->Y*35 + psCar->Z*5, pos); } // Stationary (DEBUG) camera campos = CVec(30,30,420); //pcCam->Setup( campos, pos ); // Hood camera if( psCar->nCameraType == CAM_INCAR ) { pos = psCar->X*psCar->cInCarCamera.GetX() + psCar->Y*psCar->cInCarCamera.GetY() + psCar->Z*psCar->cInCarCamera.GetZ() + psCar->cPos; pcCam->Setup( pos, pos+psCar->Y*5); // Find the roll angle of the car // TODO: Do this better float roll = -atanf( psCar->X.GetZ() ) * (180/PI); pcCam->setRoll( roll ); } else pcCam->setRoll( 0 ); }
//--------------------------------------------------------------------------- CCoordSys::CCoordSys(void) //--------------------------------------------------------------------------- { m_vecDirX = CVec(1,0,0); m_vecDirY = CVec(0,1,0); m_vecDirZ = CVec(0,0,1); m_vecOrg = CVec(0,0,0); m_enumUnits = SI; }
void CGameObject::gusInit( CWormInputHandler* owner, Vec pos_, Vec spd_ ) { nextS_=(0); nextD_=(0); prevD_=(0); cellIndex_=(-1); deleteMe=(false); m_owner=(owner); vPos = CVec(pos_); vVelocity = CVec(spd_); }
void CIDragon::render() { if (!m_bActive) { //draw just if nobody has it! m_pSpriteBody->SetPos(CVec(getRect())); m_pSpriteBody->Render(0); } else { m_pSpriteBody->SetPos(CVec(getRect())); m_pSpriteBody->Render(0.0f, getOwner()->getOrientation(), getOwner()->getWormID()); m_pSpriteWings->SetPos(CVec(getRect())); m_pSpriteWings->Render( (m_fAnimPhase < 0 ? -m_fAnimPhase : m_fAnimPhase) //MBE use real ABS-Func! , getOwner()->getOrientation(), getOwner()->getWormID()); } }
/////////////////// // Process the car void Car_ProcessCar(carsim_t *psCar, CModel *pcTrack, CCar *pcCar, CCamera *pcCam, double dt, bool bPaused) { double fixed = 0.025f; double t=0; double time = (double)SDL_GetTicks() * 0.001; // Fixed time-step physics simulation while(psCar->dTime < time) { dt = time - psCar->dTime; if(dt > fixed) dt = fixed; // Don't simulate cars when paused (only the camera) if(!bPaused) Car_SimulateCar(psCar, pcTrack, dt); Car_SetupCamera(psCar, pcCam, dt); psCar->dTime += dt; } psCar->dTime = time; if(!bPaused) Car_CheckCollisions(psCar, pcCar, pcTrack); // Do some sparks if( psCar->bCollision ) { for(int i=0;i<5;i++) SpawnEntity(ent_spark, 0, psCar->cColPoint, CVec(GetRandomNum()*15,GetRandomNum()*15,GetRandomNum()*15), 2); } }
virtual void SetUp() { f_vector_2d_t momentumVec(n_sections, f_vector_t(N_t + 1)); for (auto &v : momentumVec) mymath::linspace(v.data(), p_i, 1.01 * p_i, N_t + 1); f_vector_2d_t alphaVec(n_sections, f_vector_t(alpha_order, alpha)); f_vector_t CVec(n_sections, C); f_vector_2d_t hVec(n_sections, f_vector_t(N_t + 1, h)); f_vector_2d_t voltageVec(n_sections, f_vector_t(N_t + 1, V)); f_vector_2d_t dphiVec(n_sections, f_vector_t(N_t + 1, dphi)); Context::GP = new GeneralParameters(N_t, CVec, alphaVec, momentumVec, GeneralParameters::particle_t::proton); auto GP = Context::GP; auto Beam = Context::Beam = new Beams(GP, N_p, N_b); auto RfP = Context::RfP = new RfParameters(GP, n_sections, hVec, voltageVec, dphiVec); // RingAndRfSection *long_tracker = new RingAndRfSection(); // longitudinal_bigaussian(GP, RfP, Beam, tau_0 / 4, 0, -1, false); Context::Slice = new Slices(RfP, Beam, N_slices); }
virtual void SetUp() { f_vector_2d_t momentumVec(n_sections, f_vector_t(N_t + 1, p_i)); f_vector_2d_t alphaVec(n_sections, f_vector_t(alpha_order + 1, alpha)); f_vector_t CVec(n_sections, C); f_vector_2d_t hVec(n_sections , f_vector_t(N_t + 1, h)); f_vector_2d_t voltageVec(n_sections , f_vector_t(N_t + 1, V)); f_vector_2d_t dphiVec(n_sections , f_vector_t(N_t + 1, dphi)); Context::GP = new GeneralParameters(N_t, CVec, alphaVec, alpha_order, momentumVec, proton); Context::Beam = new Beams(N_p, N_b); Context::RfP = new RfParameters(n_sections, hVec, voltageVec, dphiVec); // long_tracker = new RingAndRfSection(); Context::Slice = new Slices(N_slices, 0, -constant::pi, constant::pi, cuts_unit_type::rad); }
// -------------------------------------------------------------------------- void CFabAtHomeDoc::OnModelTranslate() // -------------------------------------------------------------------------- { CString action; action.Format("Translate Model"); CAxesDlg dlg(NULL, action); dlg.m_xax = "0.0"; dlg.m_yax = "0.0"; dlg.m_zax = "0.0"; if (dlg.DoModal() == IDOK) { for (int i=0; i<model.chunk.GetSize(); i++) { if (model.chunk[i].IsSelected()) { model.chunk[i].geometry.Translate(CVec(atof(dlg.m_xax),atof(dlg.m_yax),atof(dlg.m_zax))); } } model.Flush(); SetModifiedFlag(); UpdateAllViews(0); } }
/////////////////// // Roll in a new opponent void Dnr_RollinOpponent(void) { // Choose a random opponent int num = GetRandomInt( cMainGuy->getNumOpponents()-1 ); psDiner->pcCurOpp = cMainGuy->getOpponentList()+num; psDiner->nOppState = opp_rollingin; psDiner->cOppPosition = CVec(-10,-60,3.5); psDiner->bGoodOffer = false; // Rotate the opponent CMatrix m; m.Rotate(CVec(0,0,1),90); psDiner->pcCurOpp->zeroRotation(); psDiner->pcCurOpp->rotate(m); }
virtual void SetUp() { f_vector_2d_t momentumVec(n_sections, f_vector_t(N_t + 1)); for (auto &v : momentumVec) mymath::linspace(v.data(), p_i, p_f, N_t + 1); f_vector_2d_t alphaVec(n_sections , f_vector_t(alpha_order+1, alpha)); f_vector_t CVec(n_sections, C); f_vector_2d_t hVec(n_sections , f_vector_t(N_t + 1, h)); f_vector_2d_t voltageVec(n_sections , f_vector_t(N_t + 1, V)); f_vector_2d_t dphiVec(n_sections , f_vector_t(N_t + 1, dphi)); Context::GP = new GeneralParameters(N_t, CVec, alphaVec, alpha_order, momentumVec, proton); Context::Beam = new Beams(N_p, N_b); Context::RfP = new RfParameters(n_sections, hVec, voltageVec, dphiVec); longitudinal_bigaussian(tau_0 / 4, 0, -1, false); Context::Slice = new Slices(N_slices); }
CPhysicalObject() { m_bCanMove = false; m_bIsSolid = false; m_bCanJump = false; m_bHasGravity = true; m_dir = CVec(0.0f, 0.0f); m_lastCollisionY.bIsCollision = false; m_lastCollisionX.bIsCollision = false; };
var FlattenSequence(Var vector, bool evaluate) { size_t n = Size(vector); var r = Vec(); Reserve(r,n); for(size_t i = 0; i < n; ++i) { var c = evaluate ? Eval(At(vector, i)) : At(vector, i); if(ExQ(c,TAG(Sequence))) CVec(r).insert( CVec(r).end(), CVec(Body(c)).begin(), CVec(Body(c)).end()); else Push(r,c); } return r; }
//--------------------------------------------------------------------------- void CFabAtHomeView::ResetView(void) //--------------------------------------------------------------------------- { //reset the view back to its starting condition m_fov = 40; scale = 0.007; eye = CVec(0,0,5); view = CVec(0,0,-1000); up = CVec(0,1.0,0); // reinitialize rolling matrix with unity glPushMatrix(); glLoadIdentity(); glRotated(-90,0,0,1); glRotated(-60,0,1,0); glScaled(scale, scale, scale); glGetDoublev(GL_MODELVIEW_MATRIX, rotmat); glPopMatrix(); Invalidate(); }
/////////////////// // Change an engine part void Gar_ChangeEnginePart(CPart *pcPart, bool bRemoval, gitem_t *g) { CCar *car = cMainGuy->getCurCar(); // Safety check if(car == NULL) return; // Check if this part can be unbolted if(!car->checkPartRemoval(pcPart->getType())) { Gar_InitSpeechBubble("You cannot take that part off"); return; } // Move the camera if( pcPart->getType() == PRT_BLOCK ) { // Block cGarLocation->startCameraMove(pcPart->getPos(), pcPart->getPos() + CVec(3,3,2)); } else { // Normal part Gar_MoveCamera(pcPart->getPos(), 5); } cGarSection.setEnabled(false); cSidebar.setEnabled(false); cGarLocation->setAngleLimit(false); cGarLocation->setItemCheck(false); System_GetMouse()->Up = 0; // Add an engine pic to the taskbar cGarTaskb.Remove("parts"); cGarTaskb.Remove("tuning"); tGarage->iState = GAR_ENGINEPART; // Setup the part change tPartChange.iNutsGoingon = false; tPartChange.iChange = true; tPartChange.cCar = car; tPartChange.cPart = pcPart; tPartChange.tItem = g; tPartChange.iNutsGoingon = !bRemoval; // Initialize the part change Gar_SetupPartChange(); pcPart->setDrawNuts(true); }
void CAA_DragonFire::update() { if (getLastCollisionX().bIsCollision) { CBlockKoord blockKoord; CVec vec = CVec( getRect().x+(m_bOrientation == OLEFT ? -3.0f : getRect().w+3.0f), //x getRect().y + 50.0f); //y blockKoord = vec.toBlockKoord(); CBlock * pOldBlock = m_pGame->getBlock(blockKoord); if ((pOldBlock != NULL) && (pOldBlock->getBlockType() != CBlock::AIR)) { m_pGame->BuildBlock(blockKoord, CBlock::AIR, m_WormID, m_TeamID); } //TODO: save map in xml... } }
/////////////////// // Process & Draw the speech bubble void Dnr_SpeechProcess(void) { glColor4f(1,1,1,1); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); DrawPic( psDnrSpeech, 144, 500 ); int size = 16; Font_SetSize(size); int length = strlen( szDnrSpeech ) * size; Font_Draw( 400 - length/2, 445, CVec(0,0,0), szDnrSpeech ); if( (System_GetMouse()->Up & SDL_BUTTON(1)) || System_GetKeyboard()->KeyUp[SDLK_ESCAPE] ) { psDiner->bSpeechBubble = false; // If we have an offer, lets go! if(psDiner->bGoodOffer) { Dnr_LetsGo(); return; } } }
/////////////////// // Get the force from the tyre CVec Car_GetWheelForce(carsim_t *psCar, int i) { CVec force; wheel_t *w = &psCar->sWheels[i]; float k = w->fSpring; float Dampening = w->fDampening; if(!w->bCollision) return CVec(0,0,0); float f = k * (w->fRestLength - w->fSuspLength); f -= w->fPistonVelocity * Dampening; //f += 200; // Ground force (-gravity) f = MAX(0,f); // No negative forces force = (w->cNormal * f) / 4; return force; }
/////////////////// // Simulate the entities void SimulateEntities(float dt) { entity_t *ent = psEntities; for(int i=0; i<MAX_ENTITIES; i++, ent++) { if( !ent->bUsed ) continue; ent->fLife += dt; ent->cOldPos = ent->cPos; switch( ent->nType ) { // Spark case ent_spark: ent->cVel += CVec(0,0,-50)*dt; ent->cPos += ent->cVel*dt; if( ent->fLife > ent->fAge ) ent->bUsed = false; break; } } }
virtual void SetUp() { omp_set_num_threads(1); f_vector_2d_t momentumVec(n_sections, f_vector_t(N_t + 1, p_i)); f_vector_2d_t alphaVec(n_sections, f_vector_t(alpha_order, alpha)); f_vector_t CVec(n_sections, C); f_vector_2d_t hVec(n_sections, f_vector_t(N_t + 1, h)); f_vector_2d_t voltageVec(n_sections, f_vector_t(N_t + 1, V)); f_vector_2d_t dphiVec(n_sections, f_vector_t(N_t + 1, dphi)); Context::GP = new GeneralParameters(N_t, CVec, alphaVec, momentumVec, GeneralParameters::particle_t::proton); // Context::Beam = new Beams(N_p, N_b); auto GP = Context::GP; auto Beam = Context::Beam = new Beams(GP, N_p, N_b); Context::RfP = new RfParameters(GP, n_sections, hVec, voltageVec, dphiVec); RfP1 = new RfParameters(GP, n_sections, hVec, voltageVec, dphiVec); RfP2 = new RfParameters(GP, n_sections, hVec, voltageVec, dphiVec); long_tracker1 = new RingAndRfSection(RfP1); long_tracker2 = new RingAndRfSection(RfP2); // long_tracker = new RingAndRfSection(RfP); // Context::Slice = new Slices(RfP, Beam, N_slices, 0, -constant::pi, constant::pi, // cuts_unit_type::rad); }
//--------------------------------------------------------------------------- bool CTriangle::Intersect(double z, CVec &p1, CVec &p2) //--------------------------------------------------------------------------- { // intersect triangle with plane parallel to x-y and at z. // Return p1 and p2 in an order such that material side is on // left when going from p1 to p2. if (v[0].z >= z && v[1].z >= z && v[2].z >= z) return false; if (v[0].z <= z && v[1].z <= z && v[2].z <= z) return false; CVec p; int cnt=0; for (int i0=0; i0<3; i0++) { int i1 = (i0+1)%3; if ((v[i0].z <= z && v[i1].z > z) || (v[i1].z <= z && v[i0].z > z)) { p = v[i0]+(v[i1]-v[i0])*(z-v[i0].z)/(v[i1].z-v[i0].z); if (cnt == 0) { p1 = p; cnt++; } else { p2 = p; // set right order if ((n.Cross(p2-p1)).Dot(CVec(0,0,1)) < 0) { // swap p = p1; p1 = p2; p2 = p; } return true; } } } return false; // less than 2 points found }
/////////////////// // Setup a car void Car_SetupCar(carsim_t *psCar, CCar *pcCar) { int i; gobject_t *g; char *sTyres[] = {"$frwheel","$brwheel","$blwheel","$flwheel"}; // Identity orientation psCar->X = CVec(1,0,0); psCar->Y = CVec(0,1,0); psCar->Z = CVec(0,0,1); psCar->cPos = CVec(0,0,2); psCar->cVelocity = CVec(0,0,0); // Camera psCar->nCameraType = CAM_INCAR; psCar->cInCarCamera = pcCar->getInCarCamera(); // Engine psCar->fAcceleration = 0; psCar->nGear = 0; // Neutral psCar->nRPM = 1000; psCar->dTime = (double)SDL_GetTicks() * 0.001; // Collision psCar->bCollision = false; psCar->bFlipping = false; psCar->fSteerAngle = 0; // Stats psCar->fMaxSpeed = 0; psCar->fRaceTime = 0; // Wheels float c = 0; for(i=0; i<4; i++) { psCar->sWheels[i].bCollision = false; psCar->sWheels[i].fSpin = 0; psCar->sWheels[i].fSpeed = 0; psCar->sWheels[i].fPistonVelocity = 0; psCar->sWheels[i].fWheelZ = 0; psCar->sWheels[i].fTorque = 0; psCar->sWheels[i].fEngineLoad = 0; psCar->sWheels[i].bSlip = false; // Defaults psCar->sWheels[i].fSpring = 400; psCar->sWheels[i].fDampening = 15; psCar->sWheels[i].fCornering = 1; if( pcCar->getShock(i) ) { psCar->sWheels[i].fSpring = pcCar->getShock(i)->getSpring(); psCar->sWheels[i].fDampening = pcCar->getShock(i)->getDampening(); psCar->sWheels[i].fRestLength = pcCar->getShock(i)->getRestLength(); } if( pcCar->getTire(i) ) { psCar->sWheels[i].fCornering = pcCar->getTire(i)->getCornering(); psCar->sWheels[i].fRadius = pcCar->getTire(i)->getDimensions().GetZ()/2; } c += psCar->sWheels[i].fCornering; } // Calculate the average cornering value for the 4 wheels psCar->fCornering = c / 4; // Setup the wheels from the parts /*CModel *pcModel = pcCar->getModel(); g = pcModel->findGameObject(sTyres[0]); CVec FR = g->vPosition + CVec(0,0,2); // Only use 1 tyre, and base the other positions from that // This maintains that the tyre positions are equal distance from the center of gravity psCar->sWheels[0].cRelPos = FR; // Front Right psCar->sWheels[1].cRelPos = CVec(FR.GetX(), -FR.GetY(), FR.GetZ()); // Back Right psCar->sWheels[2].cRelPos = CVec(-FR.GetX(), -FR.GetY(), FR.GetZ()); // Back Left psCar->sWheels[3].cRelPos = CVec(-FR.GetX(), FR.GetY(), FR.GetZ()); // Front Left*/ for(i=0; i<4; i++) { g = pcCar->getModel()->findGameObject(sTyres[i]); psCar->sWheels[i].cRelPos = g->vPosition + CVec(0,0,2); } }
CVec operator * (const float &rhs) { return CVec(x*rhs, y*rhs); }
CVec operator / (const float &rhs) { return CVec(x/rhs, y/rhs); }
CVec operator - (const CVec &rhs) { return CVec(x-rhs.x, y-rhs.y); }
CVec operator + (const CVec &rhs) {//rhs=right hand side return CVec(x+rhs.x, y+rhs.y); }
/////////////////// // Update the wheel position void Car_UpdateWheel(carsim_t *psCar, CModel *pcTrack, int id) { wheel_t *w = &psCar->sWheels[id]; CVec relpos = w->cRelPos; float p[3], t1[9], t2[9]; plane_t plane; // Calculate the wheel 'top' pos CVec wheelPos = psCar->X*relpos.GetX() + psCar->Y*relpos.GetY() + psCar->Z*relpos.GetZ() + psCar->cPos; // Convert the wheel in car coords relpos -= CVec(0,0,w->fRestLength); w->cPos = psCar->X*relpos.GetX() + psCar->Y*relpos.GetY() + psCar->Z*relpos.GetZ() + psCar->cPos; // This is for the rendering w->fWheelZ = -w->fRestLength; // Defaults w->fSuspLength = w->fRestLength; w->fPistonVelocity = 0; // Check for collisions p[0] = w->cPos.GetX(); p[1] = w->cPos.GetY(); p[2] = w->cPos.GetZ(); w->bCollision = false; float pDist = 0; if( pcTrack->getCDModel()->sphereCollision( p, w->fRadius ) ) { float top=999999; for(int n=0; n<pcTrack->getCDModel()->getNumCollisions(); n++) { pcTrack->getCDModel()->getCollidingTriangles(n, t1,t2,false); plane = CalculatePlane(CVec(t1[0],t1[1],t1[2]), CVec(t1[3],t1[4],t1[5]), CVec(t1[6],t1[7],t1[8])); // If the normal is too great for the tyre, ignore the collision if(DotProduct(plane.vNormal,psCar->Z) < 0.5f) continue; // Find the plane that is raised towards the wheel center the most if( DotProduct(wheelPos, plane.vNormal) + plane.fDistance < top) { // TODO: Check if the tyre is not too high (ie, over the suspension joint) top = DotProduct(wheelPos, plane.vNormal) + plane.fDistance; w->cNormal = plane.vNormal; pDist = plane.fDistance; } w->bCollision = true; } } w->fSpeed = 0; // If not colliding, just leave if(!w->bCollision) return; // Make the tyre sit on top of the road float d = DotProduct(w->cPos, w->cNormal) + pDist; w->fSuspLength = d; relpos = w->cRelPos - CVec(0,0,w->fSuspLength); w->fWheelZ = -w->fSuspLength; w->cPos = psCar->X*relpos.GetX() + psCar->Y*relpos.GetY() + psCar->Z*relpos.GetZ() + psCar->cPos; // Get the piston velocity for the suspension CVec vel = CrossProduct(psCar->cPos-w->cPos, psCar->cAngVelocity) + psCar->cVelocity; w->fPistonVelocity = (psCar->Z * DotProduct(psCar->Z,vel)).GetZ(); // Calculate the rotation speed of the tyre CVec s = psCar->Y * DotProduct(psCar->cVelocity, psCar->Y); w->fSpeed = VectorLength(s); if(DotProduct(psCar->cVelocity, psCar->Y) > 0) w->fSpin += w->fSpeed / w->fRadius; else w->fSpin -= w->fSpeed / w->fRadius; // Rotation is based on the Torque from the engine //w->fSpin += w->fTorque / w->fRadius; // If the torque is greater then the slip torque for the surface, the wheel is slipping and the engine force // is less // Note: The slip torque is constant for now if(id == 1) { //tMainSR3.f1 = w->fTorque; } if(w->fTorque > 100) { // Slipping w->fEngineLoad = w->fTorque/50; w->bSlip = true; } else { w->bSlip = false; w->fEngineLoad = 0; } w->fSpin = LimitAngle(w->fSpin); }
/////////////////// // Check collisions between the car & track void Car_CheckCollisions(carsim_t *psCar, CCar *pcCar, CModel *pcTrack) { int i; float m[16], t1[9], t2[9]; float p[3]; // Clear it for(i=0;i<16;i++) m[i] = 0; for(i=0;i<3;i++) m[i] = psCar->X.GetIndex(i); for(i=4;i<7;i++) m[i] = psCar->Y.GetIndex(i-4); for(i=8;i<11;i++) m[i] = psCar->Z.GetIndex(i-8); for(i=12;i<15;i++) m[i] = psCar->cPos.GetIndex(i-12); m[15] = 1; // Raise the car up a bit m[14] += 2; psCar->bCollision = false; CollisionModel3D *col = pcCar->getColMod();//pcCar->getModel()->GetCDModel(); col->setTransform(m); if(col->collision( pcTrack->getCDModel(),-1,500 )) { // Get collision point //carcol->getCollisionPoint(v1); //for(i=0;i<3;i++) cont->Pos.SetIndex(i,v1[i]); //cont->Pos = cont->Pos + offset; CVec oldVel = psCar->cVelocity; CVec oldAng = psCar->cAngVelocity; for(int n=0; n<col->getNumCollisions(); n++) { // Get collision normal col->getCollidingTriangles(n,t1,t2,false); col->getCollisionPoint(n,p,false); plane_t plane = CalculatePlane(CVec(t2[0],t2[1],t2[2]), CVec(t2[3],t2[4],t2[5]), CVec(t2[6],t2[7],t2[8])); // Resolve the collision // Check to make sure the plane we're rebounding off is facing opposite the velocity if(DotProduct(psCar->cVelocity, plane.vNormal) > 0) continue; // Check to make sure the car position is the good side of the plane if(DotProduct(psCar->cPos,plane.vNormal) + plane.fDistance < 0) continue; float Mass = 2000; float coef = 0.2f; // If the velocity against the mesh is too low, make sure we fully bounce back so we don't slowly // go into the mesh if( DotProduct(psCar->cVelocity, plane.vNormal) > -1) coef = 1.0f; psCar->bCollision = true; psCar->cColNormal = plane.vNormal; psCar->cColPoint = CVec(p[0], p[1], p[2]); // Linear velocity rebound float j = DotProduct(psCar->cVelocity * -(1+coef),plane.vNormal) / DotProduct(plane.vNormal,plane.vNormal * (1/Mass)); psCar->cVelocity += plane.vNormal * (j*(1/Mass)); // Angular velocity rebound float pnt[3]; col->getCollisionPoint(n, pnt); //CVec p = CVec(pnt[0],pnt[1],pnt[2]); CVec p = psCar->X*pnt[0] + psCar->Y*pnt[1] + psCar->Z*pnt[2]; CVec v = CrossProduct(oldAng, p) + oldVel; if(DotProduct(plane.vNormal,v) > EPSILON) continue; if(DotProduct(p+psCar->cPos,plane.vNormal) + plane.fDistance > EPSILON) continue; v = CrossProduct(p, plane.vNormal*-DotProduct(v,plane.vNormal) * 0.01f); //psCar->cAngVelocity += v; } //rbody.ResolveCollisions(); //return true; } }
/////////////////// // Check Resolve a collision between 2 cars void Car_CheckCarCollisions(CCar *pcCar1, CCar *pcCar2) { float m1[16], m2[16]; carsim_t *psCar1 = pcCar1->getCarSim(); carsim_t *psCar2 = pcCar2->getCarSim(); // First, do a quick check to make sure the cars are within a small // distance of each other using a seperating axis check if( fabs(psCar1->cPos.GetX() - psCar2->cPos.GetX()) > 50 ) return; if( fabs(psCar1->cPos.GetY() - psCar2->cPos.GetY()) > 50 ) return; if( fabs(psCar1->cPos.GetZ() - psCar2->cPos.GetZ()) > 50 ) return; // Clear it for(int i=0;i<16;i++) { m1[i] = 0; m2[i] = 0; } for(i=0;i<3;i++) { m1[i] = psCar1->X.GetIndex(i); m2[i] = psCar2->X.GetIndex(i); } for(i=4;i<7;i++) { m1[i] = psCar1->Y.GetIndex(i-4); m2[i] = psCar2->Y.GetIndex(i-4); } for(i=8;i<11;i++) { m1[i] = psCar1->Z.GetIndex(i-8); m2[i] = psCar2->Z.GetIndex(i-8); } for(i=12;i<15;i++) { m1[i] = psCar1->cPos.GetIndex(i-12); m2[i] = psCar2->cPos.GetIndex(i-12); } m1[15] = 1; m2[15] = 1; // Rase it a bit m1[14] += 2; m2[14] += 2; CollisionModel3D *col = pcCar1->getColMod(); CollisionModel3D *col2 = pcCar2->getColMod(); col->setTransform( m1 ); //col->setTransform( m2 ); CVec relVel = psCar1->cVelocity - psCar2->cVelocity; CVec posNorm = psCar1->cPos - psCar2->cPos; VectorNormalize(&posNorm); // Check for collision if(col->collision( col2, -1, 0, m2 )) { float t1[9], t2[9]; plane_t plane1, plane2; for(int n=0; n<col->getNumCollisions(); n++) { // Get collision normal col->getCollidingTriangles(n,t1,t2,false); plane2 = CalculatePlane(CVec(t1[0],t1[1],t1[2]), CVec(t1[3],t1[4],t1[5]), CVec(t1[6],t1[7],t1[8])); plane1 = CalculatePlane(CVec(t2[0],t2[1],t2[2]), CVec(t2[3],t2[4],t2[5]), CVec(t2[6],t2[7],t2[8])); //plane1.vNormal.SetZ( 0 );//MIN(plane1.vNormal.GetZ(), 0) ); //plane2.vNormal.SetZ( 0 );//MIN(plane2.vNormal.GetZ(), 0) ); // Make sure we are going into the plane //if(DotProduct(psCar1->cVelocity, plane1.vNormal) > 0) //continue; // Check to make sure the car position is the good side of the plane //if(DotProduct(psCar1->cPos,plane1.vNormal) + plane1.fDistance < 0) //continue; //float nRV = DotProduct(relVel, posNorm); //if(nRV > 0) //continue; break; } // Car 1 CVec norm = plane1.vNormal; float dot = DotProduct(plane1.vNormal, psCar1->cVelocity); norm = norm * dot; CVec vt = psCar1->cVelocity - norm; float coef = 0.01f; // Ball-on-ball collision CVec norm2 = norm * coef; psCar1->cVelocity = vt + norm2; norm2 = norm * (1.0f - coef); psCar2->cVelocity += norm2; // Car 2 /*norm = plane2.vNormal; dot = DotProduct(plane2.vNormal, psCar2->cVelocity); norm = norm * dot; vt = psCar2->cVelocity - norm; coef = 0.01f; // Ball-on-ball collision norm2 = norm * coef; psCar2->cVelocity = vt + norm2; norm2 = norm * (1.0f - coef); psCar1->cVelocity += norm2;*/ } }