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()); }
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; }