Пример #1
0
void Camera::renderRayBoxIntersection(unsigned int width, unsigned int height, float m_bgcolor[], float m_boxcolor[], std::string& outputFile){

	BMP file;
	file.SetSize(width,height);
	file.SetBitDepth(24);

	Vector myVectorEyetoMiddle(m_direction.normalize());

	double tanfovx = tan(m_fovRad)*double(width)/height ;  
    Vector myEyeVectorX = myVectorEyetoMiddle.crossProduct(m_up) ;     //A
	Vector myEyeVectorY = myEyeVectorX.crossProduct(myVectorEyetoMiddle) ;     //B

	Vector myMiddlePoint = myVectorEyetoMiddle + m_position;

	Vector myImageVectorX = myEyeVectorX *  ( myVectorEyetoMiddle.normalize().length() * tanfovx / myEyeVectorX.length() ); //H
	Vector myImageVectorY = myEyeVectorY *  ( myVectorEyetoMiddle.normalize().length() * tan(m_fovRad) / myEyeVectorY.length() ); //V

	
	RGBApixel BGColor; 
	BGColor.Red = (ebmpBYTE) m_bgcolor[0]*255;
	BGColor.Green = (ebmpBYTE) m_bgcolor[1]*255;
	BGColor.Blue = (ebmpBYTE) m_bgcolor[2]*255;
	BGColor.Alpha = 0;
			
	RGBApixel BoxColor; 
	BoxColor.Red = (ebmpBYTE) m_boxcolor[0]*255;
	BoxColor.Green = (ebmpBYTE) m_boxcolor[1]*255;
	BoxColor.Blue = (ebmpBYTE) m_boxcolor[2]*255;
	BoxColor.Alpha = 0;

	double UnitCube[2][3] = { {0, 0, -1},  {1, 1, 0} };  //cube

	double a1 = UnitCube[0][0] - m_position[0];
	double a2 = UnitCube[1][0] - m_position[0];
	double b1 = UnitCube[0][1] - m_position[1];
	double b2 = UnitCube[1][1] - m_position[1];
	double c1 = UnitCube[0][2] - m_position[2];
	double c2 = UnitCube[1][2] - m_position[2];

	for(unsigned int i=0;i<width;i++){
		for(unsigned int j=0;j<height;j++){


			
			double t1x, t2x, t1y, t2y, t1z, t2z;
		    double sx,sy;
			sx = double(i)/width;
			sy = double(j)/height;

			Vector P =  myImageVectorX*(2*sx-1) + myImageVectorY*(2*sy-1) + myMiddlePoint ;
			Vector myRayCasting = (P - m_position)*(1.0 / (P - m_position).normalize().length()); //RayDirection = (P - E)/normalize(P - E);
		
			t1x =  a1 / myRayCasting[0];
			t2x =  a2 / myRayCasting[0];
			t1y =  b1 / myRayCasting[1];
			t2y =  b2 / myRayCasting[1];
			t1z =  c1 / myRayCasting[2];
			t2z =  c2 / myRayCasting[2];
			
			bool hit = RayBoxIntersection( t1x, t2x, t1y, t2y, t1z, t2z );

			if (!hit)
				file.SetPixel(i, height-j-1, BGColor);
			else
				file.SetPixel(i, height-j-1, BoxColor);
		}
	}

	file.WriteToFile(outputFile.c_str());
}
Пример #2
0
bool PhysicsWorld::Intersects(const StaticPhysicsEntity &s, const DynamicPhysicsEntity &d, Vec &outNormal, Vec &outDir)
{
	float dmin = 0, radiusSquared;

	Vec min, max, center, scale;

	min = vec(-1, -1, -1, 0);
	max = vec(1, 1, 1, 0);
	scale = vec(1, 1, 1, 0);

	Mat m, sc;

	center = entGetTransform(d.ent)->GetPosition();
	entGetTransform(s.ent)->GetMatrix(&m);
	entGetTransform(d.ent)->GetMatrix(&sc);

	// scale the unit vector and take the largest component
	// as the radius for the sphere; as long as we don't do
	// silly rotations we should be ok
	matMulVec(&scale, sc, scale);
	radiusSquared = vecMax(scale);
	radiusSquared *= radiusSquared;

	// we don't have an inv matrix of anything so instead
	// we transform everything to worldspace and do the 
	// calculations there

	// rot + scale
	matMulVec(&min, m, min);
	matMulVec(&max, m, max);

	// pos
	Vec p = entGetTransform(s.ent)->GetPosition();
	min = vecAdd(min, p);
	max = vecAdd(max, p);

	// the actual intersection test (don't test w)
	for(int i = 0; i < 3; i++)
	{
		float C = vecGetElem(center, i);

		float Bmin = vecGetElem(min, i);
		float Bmax = vecGetElem(max, i);

		if(C < Bmin)		dmin += square(C - Bmin);
		else if(C > Bmax)	dmin += square(C - Bmax);
	}

	if(dmin <= radiusSquared)
	{
		Ray r;
		r.o = center;
		r.d = vecSub(p, center);
		r.d = vecNormalize(r.d);

		float dist;
		bool hit = RayBoxIntersection(r, min, max, dist, outNormal);
		outDir = vecMul(r.d, vec(dist));

		return hit;
	}

	return false;
}