void TrackBallManipulator::rotate(int posX, int posY)
{
    Vec3 hitOld;
    int hit0 = hitSphere(mCurrentX,mCurrentY, hitOld);
    Vec3 hitNew;
    int hit1 = hitSphere(posX,posY,hitNew);
    if(hit0 != hit1) return;
//    if((hitNew - hitOld).length() / this->getRadius() > M_PI / 7) return;
    Vec3 center = getSceneGraph()->getCamera()->center();
    Vec3 axis = (hitOld - center) ^ (hitNew - center);
    if(axis.Normalize() < ZERO_TOLERANCE) return;
    Scalar angle = (hitNew - hitOld).length() / this->getRadius();
    Quat quat(axis,angle);
    getSceneGraph()->getCamera()->rotation_matrix() *= quat.convertToMatrix();
}
inline int Sphere::intersect( Ray &ray, float &t){
    return hitSphere(ray, t);
}
void hitObjects(Point3D_t rayO, Vector3D_t rayD,ShadeRec_t* sr)
{
	int i;
	FLOAT_T 		t;
	Normal_t 	normal;
	Point3D_t 	localHitPoint;
	FLOAT_T		tmin = kHugeValue;
	
	for(i = 0; i < nObjects; i++)
	{
		switch(objects[i]->type)
		{
			case SPHERE:
				if(hitSphere(rayO,rayD,&t,sr,objects[i]->center,objects[i]->radius) && (t < tmin))
				{
					sr->hitAnObject = 1;
					tmin = t;
					sr->material = objects[i]->material;
					//sr.local_hit_point = ray.o + t * ray.d;
					sr->hitPoint.x = rayO.x + (t*rayD.x);
					sr->hitPoint.y = rayO.y + (t*rayD.y);
					sr->hitPoint.z = rayO.z + (t*rayD.z); 
					normal.x = sr->normal.x;
					normal.y = sr->normal.y;
					normal.z = sr->normal.z;
					localHitPoint.x = sr->localHitPoint.x;
					localHitPoint.y = sr->localHitPoint.y;
					localHitPoint.z = sr->localHitPoint.z;
				}
				break;
			case PLANE:
				if(hitPlane(rayO,rayD,&t,sr,objects[i]->a,objects[i]->n) && (t < tmin))
				{
					sr->hitAnObject = 1;
					tmin = t;
					sr->material = objects[i]->material;
					//sr.local_hit_point = ray.o + t * ray.d;
					sr->hitPoint.x = rayO.x + (t*rayD.x);
					sr->hitPoint.y = rayO.y + (t*rayD.y);
					sr->hitPoint.z = rayO.z + (t*rayD.z); 
					normal.x = sr->normal.x;
					normal.y = sr->normal.y;
					normal.z = sr->normal.z;
					localHitPoint.x = sr->localHitPoint.x;
					localHitPoint.y = sr->localHitPoint.y;
					localHitPoint.z = sr->localHitPoint.z;
				}
				break;
		}
	}
	if(sr->hitAnObject)
	{
		sr->t = tmin;
		sr->normal.x = normal.x;
		sr->normal.y = normal.y;
		sr->normal.z = normal.z;
		sr->localHitPoint.x = localHitPoint.x ;
		sr->localHitPoint.y = localHitPoint.y ;
		sr->localHitPoint.z = localHitPoint.z ;	
	}
		
}
Exemple #4
0
float ray(int n, float x0, float y0, float z0, float dx, float dy, float dz)
{
	{
		const float xc = 0.0f, yc = 0.0f, zc = -6.0f, r = 1.0f;
		float x0c = x0 - xc;
		float y0c = y0 - yc;
		float z0c = z0 - zc;
		
		/*
		(x-xc)^2 + (y-yc)^2 + (z-zc)^2 = r^2;
		(x0c + dx * t)^2 + (y0c + dy * t)^2 + (z0c + dz * t)^2 = r^2;
		x0c^2 + 2*x0c*dx*t + dx^2*t^2 + y0c^2 + 2*y0c*dy*t + dy^2*t^2 + z0c^2 + 2 * z0c*dz*t + dz^2*t^2 = r^2
		
		(dx^2 + dy^2 + dz^2)*t^2 + (2*x0c*dx + 2*y0c&dy + 2*z0c*dz) * t + x0c^2+y0c^2+z0c^2-r^2
		*/
		float a = dx*dx + dy*dy + dz*dz;
		float b = 2*(x0c*dx + y0c*dy + z0c*dz);
		float c = x0c*x0c + y0c*y0c + z0c*z0c -r*r;
		
		float D = b*b - 4 * a * c;
		
		if(D >= 0)
		{
			float t = (-b -  sqrtf(D)) / (2*a);
			if(t > 0)
			{
				float x = x0 + dx * t;
				float y = y0 + dy * t;
				float z = z0 + dz * t;
				
				float dx2 = x - xc;
				float dy2 = y - yc;
				float dz2 = z - zc;
				
				
				float l = dx2 * dx + dy2 * dy + dz2 * dz;
				l *= 2;
				
				float reflected;
				if(n)
					reflected = ray(n-1, x,y,z, dx - l*dx2, dy - l*dy2, dz - l*dz2);
				else
					reflected = 0.0f;
				
				
				float lambert = dx2 * lxn + dy2 * lyn + dz2 * lzn;
				if(lambert < 0.0f)
					lambert = 0.0f;
				return 0.2f + 0.4f * lambert + 0.4f * reflected;
			}
		}
	}

	if(dy < 0)
	{
		float t = (-1.5f - y0) / dy;
		float x = x0 + dx * t;
		float z = z0 + dz * t;
		
		float color;
		if( ((int)( floorf(x) )
			+ (int)( floorf(z) )) % 2 )
			color = 0.8f;
		else
			color = 0.1f;
		
		float ts;
		if(hitSphere(x,-1.5f,z, lxn, lyn, lzn, &ts))
			color *= 0.2f;
		
		float v = color + 0.5f * ray(n-1, x,-1.5f,z,dx,-dy,dz);
		if(v > 1.0f)
			return 1.0f;
		else
			return v;
	}
	
	float v = dy * 0.3f;
	if(v < 0.0f)
		return 0.0f;
	else
		return v;
}