예제 #1
0
//---------------------------------------------------------------------------
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;
}
예제 #2
0
//---------------------------------------------------------------------------
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 );
}
예제 #4
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;
}
예제 #5
0
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_);
}
예제 #6
0
파일: IDragon.cpp 프로젝트: xy124/Spill
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);
    }

}
예제 #8
0
    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);
    }
예제 #9
0
   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);

   }
예제 #10
0
// --------------------------------------------------------------------------
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);
    }

}
예제 #11
0
파일: Diner.cpp 프로젝트: tecan/StreetRod3
///////////////////
// 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);
}
예제 #12
0
   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);

   }
예제 #13
0
		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;
		};
예제 #14
0
파일: eval.cpp 프로젝트: hyln9/nV
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;
}
예제 #15
0
//---------------------------------------------------------------------------
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();
}
예제 #16
0
///////////////////
// 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);
}
예제 #17
0
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...


	}

}
예제 #18
0
파일: Diner.cpp 프로젝트: tecan/StreetRod3
///////////////////
// 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;
}
예제 #20
0
파일: Entity.cpp 프로젝트: tecan/StreetRod3
///////////////////
// 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;
        }
    }
}
예제 #21
0
    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);
    }
예제 #22
0
//---------------------------------------------------------------------------
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);
    }
}
예제 #24
0
파일: Vec.hpp 프로젝트: xy124/Spill
		CVec operator * (const float &rhs) {
			return CVec(x*rhs, y*rhs);
		}
예제 #25
0
파일: Vec.hpp 프로젝트: xy124/Spill
		CVec operator / (const float &rhs) {
			return CVec(x/rhs, y/rhs);
		}
예제 #26
0
파일: Vec.hpp 프로젝트: xy124/Spill
		CVec operator - (const CVec &rhs) {
			return CVec(x-rhs.x, y-rhs.y);
		}
예제 #27
0
파일: Vec.hpp 프로젝트: xy124/Spill
		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;*/
    }
}