00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <stack>
00012
00013 #include "RayTracer.h"
00014 #include "../../core/src/geometrynode.h"
00015
00016 using namespace VRUT;
00017
00018
00019 void
00020 RayTracer::processEvent(wxCommandEvent & evt)
00021 {
00023 RenderModule::processEvent(evt);
00024
00025 switch (evt.GetEventType()) {
00027 case Event::EVT_PARAM_SET:
00028 UPDATE_PARAM_FROM_EVENT_INT(varParamID, var, evt);
00029 break;
00030 }
00031 }
00032
00033
00034 bool
00035 RayTracer::CastRay(const Ray & ray,
00036 RayIntersectionInfo &bestFound)
00037 {
00038 if (!bvh->GetRoot())
00039 return false;
00040
00041 bestFound.dist = 1e9f;
00042 bestFound.nodeID = NODE_ID_NONE;
00043
00044 std::stack<BVHNode *> stack;
00045 stack.push(bvh->GetRoot());
00046 while (!stack.empty()) {
00047 BVHNode * node = stack.top();
00048 stack.pop();
00049
00050 float dist = 1e9f;
00051 VECTOR3 intersection;
00052 bvh->UpdateBV(node);
00053 if (node->GetAABB()->Intersects(ray, 0, bestFound.dist, &dist)) {
00055 if (node->IsLeaf()) {
00056 const GeometryNode * sNode = (const GeometryNode *)scene->GetNode(node->GetSceneNodeID());
00057 const MATRIX * worldMat = sNode->GetWorldTransMatrix();
00058 MATRIX invWorldMat = worldMat->Inverse();
00059 VECTOR3 modelOrigin = invWorldMat.TransformCoord(ray.origin);
00060 VECTOR3 modelDir = invWorldMat.TransformNormal(ray.direction).Normalize();
00061 const Ray modelRay(modelOrigin, modelDir);
00062 RayIntersectionInfo gInfo;
00063 if (scene->GetGeometry(sNode->GetGeometryID())->CastRay(modelRay, gInfo)) {
00064 VECTOR3 intersection = modelRay.origin + modelRay.direction * gInfo.dist;
00065 intersection = worldMat->TransformCoord(intersection);
00066 dist = (ray.origin - intersection).Length();
00067 if (dist < bestFound.dist && dist > 0) {
00068 bestFound.nodeID = node->GetSceneNodeID();
00069 bestFound.dist = dist;
00070 bestFound.intersection = intersection;
00071 bestFound.normal = worldMat->TransformNormal(gInfo.normal);
00072 }
00073 }
00074 }
00075 else
00076 {
00077 if (node->GetLChild())
00078 stack.push(node->GetLChild());
00079 if (node->GetRChild())
00080 stack.push(node->GetRChild());
00081 }
00082 }
00083 }
00084
00085 return bestFound.nodeID != NODE_ID_NONE;
00086 }
00087
00088
00089
00090 RayTracer::RayTracer(const MODULE_ID & _id, const wxString & _name,
00091 EventHandler * msgSink)
00092 : RenderModule(_id, _name, 0, msgSink)
00093 {
00095 REGISTER_PARAM_GUI_SLIDER(varParamID, wxT("Test var"), wxT("100"), 0, 200, wxT("test var"));
00096 }
00097
00098 void
00099 RayTracer::Draw()
00100 {
00101 glClearColor(0.8, 0.1, 0.1, 0.0);
00102 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00103
00105 scene = GetSceneMgr()->GetScene(GetSceneID());
00106 if (!scene)
00107 return;
00108
00111 bvh = scene->GetBVH();
00112
00114 Camera * camera = (Camera *)scene->GetNode(cameraID);
00115 if (!camera || !bvh)
00116 return;
00117
00118 glMatrixMode(GL_PROJECTION);
00120 WriteLocker wrLock(*camera);
00122 scene->UpdateTransformation(camera->GetID());
00124 unsigned w, h;
00125 camera->GetWidthHeight(&w, &h);
00126 glViewport(0, 0, w, h);
00127 glLoadMatrixf(camera->GetProjectionMatrix()->_m);
00129 glMatrixMode(GL_MODELVIEW);
00130 glLoadMatrixf(camera->GetWorldTransMatrix()->Inverse()._m);
00131
00133 glDisable(GL_LIGHTING);
00134 glDisable(GL_TEXTURE_2D);
00135
00136
00137 VECTOR3 origin(0, 0, 0);
00138 origin = camera->GetWorldTransMatrix()->TransformCoord(origin);
00139
00140 glBegin(GL_POINTS);
00141 for (unsigned int y = 0; y < h; y+=2)
00142 for (unsigned int x = 0; x < w; x+=2) {
00143
00144 float px = ((( 2.0f * x) / w) - 1.0f) / camera->GetProjectionMatrix()->_m11;
00145 float py = (((-2.0f * y) / h) + 1.0f) / camera->GetProjectionMatrix()->_m22;
00146
00147 VECTOR3 direction(px, py, -1.0f);
00148
00149 direction = camera->GetWorldTransMatrix()->TransformNormal(direction).Normalize();
00150
00151 Ray ray(origin, direction);
00152 RayIntersectionInfo info;
00153
00154
00155 if (bvh->CastRay(ray, info)) {
00156 VECTOR3 p = info.intersection;
00157
00158
00159 const GeometryNode * sNode = (const GeometryNode *)scene->GetNode(info.nodeID);
00160 const Material * material = scene->GetMaterial(sNode->GetMaterialID());
00161 float a = abs(direction.Dot(info.normal));
00162
00163 if (material) {
00164 vector4 c = a*material->diffuse;
00165
00166 glColor4fv(c._v);
00167
00168
00169
00170
00171
00172
00173 } else
00174 glColor3f(a, a, a);
00175
00176
00177
00178 glVertex3f(p.x,
00179 p.y,
00180 p.z);
00181 }
00182 }
00183
00184 glEnd();
00185
00186 if (0) {
00187 std::stack<const BVHNode *> stack;
00188 VECTOR3 color(1,1,1);
00189
00190 stack.push(bvh->GetRoot());
00191
00192 while (!stack.empty()) {
00193 const BVHNode * node = stack.top();
00194 stack.pop();
00195
00196 if (node) {
00197 glColor3fv(color._v);
00198 VECTOR3 v0(node->GetAABB()->MinBound);
00199 VECTOR3 v7(node->GetAABB()->MaxBound);
00200 VECTOR3 v1(v7.x, v0.y, v0.z);
00201 VECTOR3 v2(v0.x, v7.y, v0.z);
00202 VECTOR3 v3(v7.x, v7.y, v0.z);
00203 VECTOR3 v4(v0.x, v0.y, v7.z);
00204 VECTOR3 v5(v7.x, v0.y, v7.z);
00205 VECTOR3 v6(v0.x, v7.y, v7.z);
00206 glBegin(GL_LINE_STRIP);
00207 glVertex3fv(v0._v);
00208 glVertex3fv(v1._v);
00209 glVertex3fv(v3._v);
00210 glVertex3fv(v2._v);
00211 glVertex3fv(v0._v);
00212 glVertex3fv(v4._v);
00213 glVertex3fv(v6._v);
00214 glVertex3fv(v7._v);
00215 glVertex3fv(v5._v);
00216 glVertex3fv(v4._v);
00217 glVertex3fv(v6._v);
00218 glVertex3fv(v2._v);
00219 glVertex3fv(v3._v);
00220 glVertex3fv(v7._v);
00221 glVertex3fv(v5._v);
00222 glVertex3fv(v1._v);
00223 glEnd();
00224
00225 stack.push(node->GetLChild());
00226 stack.push(node->GetRChild());
00227 }
00228
00229 }
00230 }
00231 }
00232
00233
00234