// *** RecalcMousePos3d
void UserInput::RecalcMousePos3d()
{
	// Get click ray
    Vector3 rayStart;
    Vector3 rayDir;
    g_app->m_camera->GetClickRay( g_target->X(), g_target->Y(), &rayStart, &rayDir );
	ASSERT_VECTOR3_IS_SANE(rayStart);
	ASSERT_VECTOR3_IS_SANE(rayDir);
	rayStart += rayDir * 0.0f;


    bool landscapeHit = false;
	if (g_app->m_location)
	{
		landscapeHit = g_app->m_location->m_landscape.RayHit( rayStart, rayDir, &m_mousePos3d );
	}
    else
    {
        // We are in the global world
        // So hit against the outer sphere

		Vector3 sphereCentre(0,0,0);
		float sphereRadius = 36000.0f;

		rayStart += rayDir * (sphereRadius * 4.0f);
		rayDir = -rayDir;
		landscapeHit = RaySphereIntersection(rayStart, rayDir,
			    							 sphereCentre, sphereRadius, 1e10,
				    						 &m_mousePos3d);
        return;
    }


	if (!landscapeHit)
	{
		// OK, we didn't hit against the landscape mesh, so hit against a sphere that
		// encloses the whole world
		Vector3 sphereCentre;
		sphereCentre.x = g_app->m_globalWorld->GetSize() * 0.5f;
		sphereCentre.y = 0.0f;
		sphereCentre.z = g_app->m_globalWorld->GetSize() * 0.5f;

		float sphereRadius = g_app->m_globalWorld->GetSize() * 40.0f;

        float dist = (rayStart - sphereCentre).Mag();
        //DarwiniaDebugAssert(dist < sphereRadius);

		rayStart += rayDir * (sphereRadius * 4.0f);
		rayDir = -rayDir;
		landscapeHit = RaySphereIntersection(rayStart, rayDir,
											 sphereCentre, sphereRadius, 1e10,
											 &m_mousePos3d);
		//DarwiniaDebugAssert(landscapeHit);
	}
}
Exemplo n.º 2
0
void Renderer::Render(SDL_Surface* surface)
{
	Ray tracingRay;

	// Shoot ray from every pixel and compute its intersetion
	for(int i = 0; i < m_scene.GetImageWidth(); ++i)
	{
		for(int j = 0; j < m_scene.GetImageHeight(); ++j)
		{
			// Cast Ray
			tracingRay = RayThruPixel(i, j);

			Sphere sphere(0, 0, 0, 1);

			if(RaySphereIntersection(tracingRay, sphere))
			{
				unsigned randColor = SDL_MapRGB(surface->format, 255, 0, 0);
				PutPixelColor(surface, i, j, randColor);
			}

			//unsigned randColor = SDL_MapRGB(surface->format, 255, rand() % 255, rand() % 255);
			//PutPixelColor(surface, i, j, randColor);
		}
	}
}
bool Entity::RayHit(Vector3 const &_rayStart, Vector3 const &_rayDir)
{
	if (m_shape)
	{
		RayPackage package(_rayStart, _rayDir);
		Matrix34 mat(m_front, g_upVector, m_pos);
		return m_shape->RayHit(&package, mat);
	}
	else
	{
		return RaySphereIntersection(_rayStart, _rayDir, m_pos, 5.0);
	}
}
bool Building::DoesRayHit(Vector3 const &_rayStart, Vector3 const &_rayDir,
                          float _rayLen, Vector3 *_pos, Vector3 *norm )
{
	if (m_shape)
	{
		RayPackage ray(_rayStart, _rayDir, _rayLen);
		Matrix34 transform(m_front, m_up, m_pos);
		return m_shape->RayHit(&ray, transform, true);
	}
	else
	{
		return RaySphereIntersection(_rayStart, _rayDir, m_pos, m_radius, _rayLen);
	}
}
Exemplo n.º 5
0
void GlobePicker::Eval()
{
    FPoint3 pos, dir;

    vtGetScene()->CameraRay(m_pos, pos, dir);

    // test whether we hit the globe
    FSphere sphere(FPoint3(0.0f, 0.0f, 0.0f), (float)m_fRadius);
    FPoint3 akPoint[2];
    int riQuantity;

    m_bOnTerrain = RaySphereIntersection(pos, dir, sphere, riQuantity, akPoint);
    if (m_bOnTerrain)
    {
        // save result
        m_GroundPoint = akPoint[0];

        // apply global position to target (which is not a child of the globe)
        vtTransform *pTarget = (vtTransform *) GetTarget();
        if (pTarget)
        {
            pTarget->Identity();
            pTarget->SetTrans(m_GroundPoint);
            pTarget->PointTowards(m_GroundPoint * 2.0f);
            pTarget->Scale(m_fTargetScale);
        }

        if (m_pGlobe)
        {
            // rotate to find position relative to globe's rotation
            vtTransform *xform = m_pGlobe->GetTop();
            FMatrix4 rot;
            xform->GetTransform1(rot);
            FMatrix4 inverse;
            inverse.Invert(rot);
            FPoint3 newpoint;

            // work around SML bug: matrices flagged as identity but
            // will still transform by their components
            if (! inverse.IsIdentity())
            {
                inverse.Transform(m_GroundPoint, newpoint);
                m_GroundPoint = newpoint;
            }
        }

        // Find corresponding geographic coordinates
        xyz_to_geo(m_fRadius, m_GroundPoint, m_EarthPos);
    }
}
Exemplo n.º 6
0
// se c'e' intersezione con almeno un elemento ritorna TRUE e restituisce il numero, il tipo e il punto di intersezione
// con la prima navicella che c'e' nella direzione della telecamera, altrimenti ritorna FALSE 
GLboolean firstShip(SpaceShip *spSh, int *nShip,char *typeShip,Point3 *intersection){
	Point3		me=g_camera.getPos(),
			tmp;
	GLfloat 	dist,
			minDist=MAX_DIST+1000;
	GLboolean	anyIntersection=false;

	for(int i=0;i<NUM_ENEMY;i++){
		if ( enemy[i].life>0 && (spSh->type!='e' || spSh->index!=i) &&		// per non far il controllo con la navetta stessa
			RaySphereIntersection(spSh->pos,me,enemy[i].pos,enemy[i].rad+spSh->rad+0.1, &tmp))
		{
			dist=distance(spSh->pos,tmp);
			if(dist<minDist){
				anyIntersection=true;
				minDist=dist;
				*nShip=i;
				*typeShip='e';
				*intersection=tmp;
			}
		}
	}
	for(int i=0;i<NUM_POLICE;i++){
		if ( police[i].life>0 && (spSh->type!='p' || spSh->index!=i) &&		// per non far il controllo con la navetta stessa
			RaySphereIntersection(spSh->pos,me,police[i].pos,police[i].rad+spSh->rad+0.1, &tmp))
		{
			dist=distance(spSh->pos,tmp);
			if(dist<minDist){
				anyIntersection=true;
				minDist=dist;
				*nShip=i;
				*typeShip='p';
				*intersection=tmp;
			}
		}
	}
	return anyIntersection;
}
int LocationEditor::DoesRayHitCameraMount(Vector3 const &rayStart, Vector3 const &rayDir)
{
	Shape *camShape = g_app->m_resource->GetShape("camera.shp");
	Vector3 centre = camShape->CalculateCentre(g_identityMatrix34);
	float radius = camShape->CalculateRadius(g_identityMatrix34, centre);

	for (int i = 0; i < g_app->m_location->m_levelFile->m_cameraMounts.Size(); ++i)
	{
		CameraMount *mount = g_app->m_location->m_levelFile->m_cameraMounts[i];
		if (RaySphereIntersection(rayStart, rayDir, mount->m_pos, radius))
		{
			return i;
		}
	}

	return -1;
}
int LocationEditor::DoesRayHitInstantUnit(Vector3 const &rayStart, Vector3 const &rayDir)
{
	Location *location = g_app->m_location;

	for (int i = 0; i < location->m_levelFile->m_instantUnits.Size(); i++)
	{
		if (!location->m_levelFile->m_instantUnits.ValidIndex(i))	continue;

		InstantUnit *iu = location->m_levelFile->m_instantUnits.GetData(i);
		Vector3 pos(iu->m_posX, 0, iu->m_posZ);
		pos.y = location->m_landscape.m_heightMap->GetValue(pos.x, pos.z);
		bool result = RaySphereIntersection(rayStart, rayDir, pos, 
											iv_sqrt(iu->m_number) * INSTANT_UNIT_SIZE_FACTOR);
		if (result)
		{
			return i;
		}
	}

	return -1;
}
Exemplo n.º 9
0
/*
*	FUNZIONE CHE DATO IL PUNTATORE ALLA POSIZIONE E ALLA DIREZIONE ATTUALI
*	SETTA LA NUOVA POSIZIONE E LA NUOVA DIREZIONE 
*/
GLvoid setPosDir(SpaceShip *spSh){
	me=g_camera.getPos();
	dist=distance(spSh->pos,me);
	GLfloat rad=spSh->rad;
	
	if(dist>35){
	//if(dist>10){
		spSh->move=true;	
		int i=checkDistPlanet(spSh->pos);
		int j=checkDistSatellite(spSh->pos);
		Point3 *tmp=(Point3 *) malloc(sizeof(Point3));
		
		/* ALGORITMO CHE PERMETTE ALLE NAVETTE SPAZIALI DI EVITARE PIANETI, SATELLITI E ALTRE NAVETTE */
			
			if( (i!=-1) && (j==-1) && RaySphereIntersection(spSh->pos,me,posPlanet[i],radius[i]+rad+rad*0.1,tmp) )
			{	// se stiamo andando addosso ad un pianeta ma non c'e' un satellite nelle vicinanze		
			
				// troviamo il nuovo punto verso cui dirigerci per evitare il pianeta
				*tmp=addPos(*tmp, radius[i]+rad);			
				spSh->dir=directionRel(spSh->pos,*tmp);
				spSh->dirCorr=false;		// perche' non ci stiamo muovendo verso la telecamera
			}
			// se stiamo andando addosso ad un satellite ma non siamo ancora nelle vicinanze di un pianeta
			else if( (i==-1) && (j!=-1) && RaySphereIntersection(spSh->pos,me,satellite[j].pos,satellite[j].rad+rad+rad*0.1,tmp) )
			{
				*tmp=addPos(*tmp, satellite[j].rad);
				spSh->dir=directionRel(spSh->pos,*tmp);
				spSh->dirCorr=false;		// perche' non ci stiamo muovendo verso la telecamera
			}
			// se siamo nelle vicinanze sia di un satellite che di un pianeta e vi e' intesersezione con almeno uno dei due
			else if( (i!=-1) && (j!=-1) && 
				( 	RaySphereIntersection(spSh->pos,me,satellite[j].pos,satellite[j].rad+rad+rad*0.1,tmp) ||  
					RaySphereIntersection(spSh->pos,me,posPlanet[i],radius[i]+rad+rad*0.1,tmp))	)
				{
				
				Point3 *tmpSat=(Point3 *) malloc(sizeof(Point3));
				Point3 *tmpPl=(Point3 *) malloc(sizeof(Point3));
				bool intersectionSat=RaySphereIntersection(spSh->pos,me,satellite[j].pos,satellite[j].rad+rad+rad*0.1,tmpSat);
				bool intersectionPl=RaySphereIntersection(spSh->pos,me,posPlanet[i],radius[i]+rad+rad*0.1,tmpPl);
				float distPl=distance(spSh->pos,*tmpPl);
				float distSat=distance(spSh->pos,*tmpSat);
				// se interseca solo il pianeta, o se gli interseca entrambi, ma prima il pianeta
				if( (intersectionPl && !intersectionSat) || ((intersectionPl && intersectionSat) && distPl<distSat) )
				{
					*tmpPl=addPos(*tmpPl, radius[i]+rad);
					spSh->dir=directionRel(spSh->pos,*tmpPl);
					spSh->dirCorr=false;		// perche' non ci stiamo muovendo verso la telecamera
				} 
				// se interseca solo il satellite, o se gli interseca entrambi, ma prima il satellite
				else if(!intersectionPl && intersectionSat || ((intersectionPl && intersectionSat) && distSat<=distPl) )
				{
					*tmpSat=addPos(*tmpSat, satellite[j].rad);
					//*tmpSat=addPos(*tmpSat, satellite[j].rad+rad);
					spSh->dir=directionRel(spSh->pos,*tmpSat);
					spSh->dirCorr=false;		// perche' non ci stiamo muovendo verso la telecamera
				}
				free(tmpPl);
				free(tmpSat);
			}
			else	// se non c'e' rischio collisione ne con un satellite ne con un pianeta
			{	
				// le variabili di tipo clock servono per non far "impazzire" il cambio di direzione delle navicelle 
				//quando abbengono rapidi cambiamenti di posizione della telecamera
				int num;
				char type;
				Point3 intShip;
				GLboolean collision=firstShip(spSh,&num,&type,&intShip);
				// restituisce se esiste il numero e il tipo della prima navicella che c'e' nella direzione verso la telecamera
				if(collision && abs(clock()-pastClock)>=CLOCKS_PER_SEC*0.3)
				{ 	// si controlla se c'e' un altra navetta sulla traiettoria
					pastClock=clock();					
					
					GLboolean mv;
					switch(type){	case 'p': mv=police[num].move; break;
							case 'e': mv=enemy[num].move; break;	}
					
					// si settano queste variabili in modo che si mantenga la stessa direzione 
					// finche' continua ad esserci insersezione con la stessa navetta		
					if(!mv && type!=oldType && num!=oldNum)
					{	// si trova la nuova direzione per evitarla						
						oldType=type;
						oldNum=num;	
						switch(type){
							case 'p': *tmp=addPos(intShip, (spSh->rad+police[num].rad)); break;
							case 'e': *tmp=addPos(intShip, (spSh->rad+enemy[num].rad)); break;
						}
						spSh->dir= directionRel(spSh->pos,*tmp);
						spSh->dirCorr=false;	
					}
					//else if(mv && abs(clock()-pastClock)>=CLOCKS_PER_SEC*0.3)
					else if(mv) 
					{
						oldType=' ';
						oldNum=-1;
						switch(type){
							case 'p': *tmp=addPos(intShip, (spSh->rad+police[num].rad)); break;
							case 'e': *tmp=addPos(intShip, (spSh->rad+enemy[num].rad)); break;
						}
						spSh->dir= directionRel(spSh->pos,*tmp);
						spSh->dirCorr=false;
					}
				}
				// se non ci sono ostacoli
				else if(!collision && abs(clock()-pastClock)>=CLOCKS_PER_SEC*0.3)
				//else
				{
					pastClock=clock();
					oldType=' ';
					oldNum=-1;
					spSh->dir=directionRel(spSh->pos,me); 	// si aggiorna nella direzione tra oggetto e me
					spSh->dirCorr=true;			// perche' ci stiamo muovendo verso la telecamera
				}
			}
		
			// ora che abbiamo trovato la direzione di movimento, muoviamo la navicella
			if (!freezeShip){			
				spSh->pos.x += spSh->dir.x*sp;
				spSh->pos.y += spSh->dir.y*sp;
				spSh->pos.z += spSh->dir.z*sp;
				glutPostRedisplay();
			}
		free(tmp);
	}
	// se non ci si deve muovere, la direzione deve essere sempre rivolta verso la telecamera
	else if (!freezeShip){
		spSh->move=false;
		spSh->dir=directionRel(spSh->pos,me); 		// si aggiorna nella direzione tra oggetto e me
		spSh->dirCorr=true; 				// perche' ci stiamo muovendo verso la telecamera
	}
}
bool ResearchItem::DoesRayHit(Vector3 const &_rayStart, Vector3 const &_rayDir, 
                              double _rayLen, Vector3 *_pos, Vector3 *norm )
{
    return RaySphereIntersection(_rayStart, _rayDir, m_pos, m_radius, _rayLen);
}