/////////////////// // Initialize the sky bool CSky::Initialize(void) { // Allocate the stars m_psStars = new star_t[MAX_STARS]; if(m_psStars == NULL) return false; // Set the star details float radius = 90; CVec f; for(int i=0; i<MAX_STARS; i++) { GetAngles(-fabs(GetRandomNum()*45), 0, fabs(GetRandomNum()*360), &f, NULL, NULL); m_psStars[i].pos = f*radius; m_psStars[i].size = fabs(GetRandomNum()); m_psStars[i].flicker = fabs(GetRandomNum()); // Calculate the rotation CVec p = m_psStars[i].pos; VectorNormalize( &p ); m_psStars[i].yaw = (float)(-atan2(p.GetX(),p.GetY()) * (180/PI)); float dist = (float)sqrt((float)(p.GetX() * p.GetX() + p.GetY() * p.GetY())); m_psStars[i].pitch = (float)(-atan2(dist,p.GetZ()) * (180/PI)+270); } // Load the moon texture m_psMoonTexture = Cache_LoadTexture("data/textures/sky/moonlg.png"); if(m_psMoonTexture == NULL) return false; Tex_Upload(m_psMoonTexture); // Load the star texture m_psStarTexture = Cache_LoadTexture("data/textures/sky/star.png"); if(m_psStarTexture == NULL) return false; Tex_Upload(m_psStarTexture); return true; }
/////////////////// // 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); }
/////////////////// // Render the sky void CSky::Render(CCamera *psCamera) { int i; float fSize; State_Enable(GL_TEXTURE_2D); State_Disable(GL_FOG); State_Disable(GL_LIGHTING); State_Enable(GL_BLEND); glBlendFunc(GL_ONE,GL_ONE_MINUS_SRC_COLOR); glDepthMask(0); // Make the sky be around the camera glPushMatrix(); if(psCamera) { CVec p = psCamera->getPos(); glTranslatef(p.GetX(), p.GetY(), p.GetZ()); } // Draw the stars Tex_Bind(m_psStarTexture); star_t *s = m_psStars; for(i=0; i<MAX_STARS; i++, s++) { glPushMatrix(); glTranslatef(s->pos.GetX(), s->pos.GetY(), s->pos.GetZ()); glRotatef(s->yaw-180, 0,0,1); glRotatef(s->pitch, 0,0,1); float f = 1-(fabs(GetRandomNum()*0.6f) * s->flicker); glColor4f(f,f,f,1.0f); fSize = s->size; glBegin(GL_QUADS); glTexCoord2i(0,0); glVertex3f(-fSize, 0, -fSize); glTexCoord2i(1,0); glVertex3f(fSize, 0, -fSize); glTexCoord2i(1,1); glVertex3f(fSize, 0, fSize); glTexCoord2i(0,1); glVertex3f(-fSize, 0, fSize); glEnd(); glPopMatrix(); } // Draw the moon glColor4f(1,1,1,1); Tex_Bind(m_psMoonTexture); glPushMatrix(); fSize = 5.5f; glTranslatef(-60,100,40); glRotatef(10,0,0,1); glBegin(GL_QUADS); glTexCoord2i(0,0); glVertex3f(-fSize, 0, -fSize); glTexCoord2i(1,0); glVertex3f(fSize, 0, -fSize); glTexCoord2i(1,1); glVertex3f(fSize, 0, fSize); glTexCoord2i(0,1); glVertex3f(-fSize, 0, fSize); glEnd(); glPopMatrix(); glDepthMask(1); glPopMatrix(); }