#include "SceneQuery.h" #include "glInterface.h" #include "Vector3.h" #include "Camera.h" #include "SceneQuery.h" #include "RenderTraverser.h" #include #include void startil() { ilInit(); assert(ilGetError() == IL_NO_ERROR); } void stopil() { ilShutDown(); assert(ilGetError() == IL_NO_ERROR); } namespace CHCDemoEngine { using namespace std; //const static int viewport[4] = {0, 0, 512, 512}; const static int viewport[4] = {0, 0, 1024, 768}; //const static int viewport[4] = {0, 0, 2048, 2048}; SceneQuery::SceneQuery(const AxisAlignedBox3 &sceneBox, RenderTraverser *renderer): mSceneBox(sceneBox), mDepth(NULL) { Prepare(renderer); } bool SceneQuery::CalcIntersection(Vector3 &pt) { int px = (pt.x - mSceneBox.Min(0)) * (viewport[2] - 1) / mSceneBox.Size(0); int py = (pt.y - mSceneBox.Min(1)) * (viewport[3] - 1) / mSceneBox.Size(1); unsigned char d = mDepth[px + py * viewport[2]]; const float offs = mSceneBox.Size(2) * 1e-1f; static float depth = (float)d; if (d > 0) { const float x = 0.1f; depth = depth * x + d * (1.0f - x); pt.z = mSceneBox.Max().z - mSceneBox.Size().z * depth / 255.0f + offs; //cout << "new depth " << pt.z << " (" << d << ")" << endl; return true; } //cout << "invalid depth: " << d << endl; return false; } void SceneQuery::Prepare(RenderTraverser *renderer) { cout << "Preparing scene queries" << endl; const float xlen = mSceneBox.Size().x * 0.5f; const float ylen = mSceneBox.Size().y * 0.5f; Camera *orthoCam = new Camera(xlen, ylen); orthoCam->SetOrtho(true); orthoCam->SetNear(0.0f); orthoCam->Yaw(M_PI * 0.5f); Vector3 pos = Vector3(mSceneBox.Center().x, mSceneBox.Center().y, mSceneBox.Max().z); orthoCam->SetPosition(pos); //glPixelStorei(GL_PACK_ROW_LENGTH, viewport[2]); glPixelStorei(GL_PACK_ALIGNMENT, 1); glReadBuffer(GL_BACK); // hack: should create offscreen buffer for this glViewport(0, 0, viewport[2], viewport[3]); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-xlen, xlen, -ylen, ylen, 0.0f, mSceneBox.Size().z); glMatrixMode(GL_MODELVIEW); orthoCam->SetupCameraView(); glClear(GL_DEPTH_BUFFER_BIT); mDepth = new unsigned char[viewport[2] * viewport[3]]; //mDepth = new float[viewport[2] * viewport[3]]; //renderer->SetCamera(orthoCam); renderer->RenderScene(); glReadPixels(0, 0, viewport[2], viewport[3], GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, mDepth); //glReadPixels(0, 0, viewport[2], viewport[3], GL_DEPTH_COMPONENT, GL_FLOAT, mDepth); /* startil(); if (!ilTexImage(viewport[2], viewport[3], 1, 1, IL_LUMINANCE, IL_UNSIGNED_BYTE, mDepth)) { cerr << "IL error " << ilGetError() << endl; stopil(); return; } ILstring writename = ILstring("out.tga"); ilSetInteger(IL_TGA_RLE, 1); if (!ilSaveImage(writename)) { cerr << "TGA write error " << ilGetError() << endl; } stopil(); */ DEL_PTR(orthoCam); } }