color_t getAntialiasedPixel(float x, float y, intersect_t *intersect, float antialiasLevel) { float antialiasLevelSquared = antialiasLevel * antialiasLevel; float precalculatedOffsetPart = 1.0 / (2.0 * antialiasLevel); point_t pos; vec_t rayDirection; ray_t ray; color_t color; float avgR = 0, avgG = 0, avgB = 0; for (int j = 0; j < antialiasLevel; j++) { for (int i = 0; i < antialiasLevel; i++) { float xOff = i / antialiasLevel + precalculatedOffsetPart; float yOff = j / antialiasLevel + precalculatedOffsetPart; float xPos = (x + xOff) * 2 / width - 1; float yPos = -((y + yOff) * 2 / height - 1); pos = point_new(xPos, yPos, -2); rayDirection = vec_normalize(point_direction(cameraPos, pos)); ray = ray_new(cameraPos, rayDirection); color = shootRay(ray, intersect, 0); avgR += (float)color.r / (float)antialiasLevelSquared; avgG += (float)color.g / (float)antialiasLevelSquared; avgB += (float)color.b / (float)antialiasLevelSquared; } } return rgb((char)avgR, (char)avgG, (char)avgB); }
color_t getPixel(float x, float y, intersect_t *intersect) { intersect->t = -1; x = (x + 0.5) * 2 / width - 1; y = -((y + 0.5) * 2 / height - 1); point_t pixelPos = point_new(x, y, -2); vec_t rayDirection = vec_normalize(point_direction(cameraPos, pixelPos)); ray_t ray = ray_new(cameraPos, rayDirection); return shootRay(ray, intersect, 0); }
void invRTSGame::terrainPoint() { double objx, objy, objz; shootRay(objx, objy, objz, sinput->mousex, sinput->mousey); terrainX = (float)objx; terrainZ = (float)objz; // printf("terrainX : %g terrainZ : %g\n", terrainX, terrainZ); if(sinput->mousebutton == SDL_BUTTON_LEFT && sinput->mousestate == 2) { // notice lua lua_pushnumber(mainL, nb_selectedl); lua_setglobal(mainL, "nb_selected"); if(nb_selectedl) { lua_getglobal(mainL, "selected_units"); lua_pushnumber(mainL, 1); lua_pushnumber(mainL, selectedl[0]->id); lua_rawset(mainL, -3); lua_pop(mainL, 1); } } }
color_t shootRay(ray_t ray, intersect_t *intersect, int recursionCount) { rayIntersectionTest(ray, intersect); if (intersect->t > 0) { // We hit something color_t color; GeomType geomType = intersect->geomType; void *geomObject = intersect->object; bool reflective = false; // Check the material if (geomType == GeomTypeTriangle) { triangle_t *temp = (triangle_t *)geomObject; color = temp->material.color; reflective = temp->material.reflective; } else if (geomType == GeomTypeSphere) { sphere_t *temp = (sphere_t *)geomObject; color = temp->material.color; reflective = temp->material.reflective; } else if (geomType == GeomTypeLight) { return rgb(255, 255, 255); } // Get a normal where we intersected vec_t normal; if (geomType == GeomTypeTriangle) { triangle_t *temp = (triangle_t *)geomObject; normal = temp->normal; } else if (geomType == GeomTypeSphere) { sphere_t *temp = (sphere_t *)geomObject; normal = sphere_normal_at_point(*temp, intersect->point); } if (reflective && recursionCount < 10) { // First find the reflected ray vec_t r = vec_sub(ray.direction, vec_mult(normal, 2 * vec_dot(normal, ray.direction))); point_t start = point_offset(intersect->point, vec_mult(r, 0.0001)); ray_t reflectedRay = ray_new(start, r); // Shoot out a new ray and take its color color = shootRay(reflectedRay, intersect, recursionCount + 1); } else if (!reflective) { point_t sPos = intersect->point; ray_t sRay; float totalDiffuse = 0; for (int m = 0; m < numLights; m++) { if (lights[m].size == 0) { sRay = ray_to_light(lights[m], sPos); sRay.point = point_offset(sRay.point, vec_mult(sRay.direction, 0.0001)); rayIntersectionNonLightTest(sRay, intersect); if (intersect->t <= 0) { // We did't hit anything, diffuse like normal totalDiffuse += fabsf(vec_dot(sRay.direction, normal)); } // Otherwise, we're in shadow } else { float lightRays = 100 * lights[m].size; float lightDiffuse = 0; for (int l = 0; l < lightRays; l++) { sRay = ray_to_light(lights[m], sPos); sRay.point = point_offset(sRay.point, vec_mult(sRay.direction, 0.0001)); rayIntersectionNonLightTest(sRay, intersect); if (intersect->t <= 0) { // We didn't hit anything, diffuse like normal lightDiffuse += fabsf(vec_dot(sRay.direction, normal)); } // Otherwise, we're in shadow } totalDiffuse += lightDiffuse / lightRays; } } totalDiffuse /= numLights; // We want the total intensity of lights to be the // same no matter how many we have if (totalDiffuse < 0.2) totalDiffuse = 0.2; if (totalDiffuse > 1) totalDiffuse = 1; color.r *= totalDiffuse; color.g *= totalDiffuse; color.b *= totalDiffuse; } return color; } // No intersection, color black return rgb(0, 0, 0); }
void CreateCadTesselation::scan(bool create_grid, int interlaces) { m_Dx = (m_X2[0] - m_X1[0])/(m_Ni-1); m_Dy = (m_X2[1] - m_X1[1])/(m_Nj-1); m_Dz = (m_X2[2] - m_X1[2])/(m_Nk-1); EG_VTKSP(vtkImageData, gdata); gdata->SetDimensions(m_Ni, m_Nj, m_Nk); EG_VTKSP(vtkFloatArray, g); g->SetName("g"); g->SetNumberOfValues(m_Ni*m_Nj*m_Nk); gdata->GetPointData()->AddArray(g); for (int i = 0; i < m_Ni; ++i) { for (int j = 0; j < m_Nj; ++j) { for (int k = 0; k < m_Nk; ++k) { if (preserveFluid()) { g->SetValue(getIdx(i,j,k), 1); } else { g->SetValue(getIdx(i,j,k), 0); } } } } m_XScan1 = m_X2; m_XScan2 = m_X1; vec3_t x_in, x_out, n_in, n_out; int progress = 0; m_GeometryFound = false; double dxi = m_Dx/(interlaces + 1); double dyi = m_Dy/(interlaces + 1); double dzi = m_Dz/(interlaces + 1); double shift = 1e-6; // scan ij plane -> k direction // xy plane -> z direction for (int i = 0; i < m_Ni; ++i) { for (int j = 0; j < m_Nj; ++j) { vec3_t x0 = getX(i,j,0); for (int i_il = 0; i_il <= interlaces; ++i_il) { for (int j_il = 0; j_il <= interlaces; ++j_il) { vec3_t x = x0; x[0] += i_il*dxi; x[1] += j_il*dyi; int k_last = 0; while (shootRay(x, vec3_t(0,0,1), x_in, x_out, n_in, n_out)) { m_GeometryFound = true; m_XScan1[2] = min(m_XScan1[2], x_in[2]); m_XScan2[2] = max(m_XScan2[2], x_out[2]); int k1 = int((x_in[2] - m_X1[2])/m_Dz) + 1; int k2 = int((x_out[2] - m_X1[2])/m_Dz); if (preserveFluid()) { for (int k = k_last; k < min(m_Nk-1,k1); ++k) { g->SetValue(getIdx(i,j,k), 0); } } else { for (int k = max(0,k1); k <= min(m_Nk-1,k2); ++k) { g->SetValue(getIdx(i,j,k), 1); } } x = x_out; x[2] += shift*m_Dz; k_last = min(m_Nk-1,k2+1); } if (preserveFluid()) { for (int k = k_last; k <= m_Nk-1; ++k) { g->SetValue(getIdx(i,j,k), 0); } } } } } progress += m_Nj; GuiMainWindow::pointer()->setProgress(progress); } // scan ik plane -> j direction // xz plane -> y direction for (int i = 0; i < m_Ni; ++i) { for (int k = 0; k < m_Nk; ++k) { vec3_t x0 = getX(i,0,k); for (int i_il = 0; i_il <= interlaces; ++i_il) { for (int k_il = 0; k_il <= interlaces; ++k_il) { vec3_t x = x0; x[0] += i_il*dxi; x[2] += k_il*dzi; int j_last = 0; /* if (fabs(x0[0]) < 1.5 && fabs(x0[2]) < 1.5 && create_grid) { cout << x0 << endl; } */ while (shootRay(x, vec3_t(0,1,0), x_in, x_out, n_in, n_out)) { m_GeometryFound = true; m_XScan1[1] = min(m_XScan1[1], x_in[1]); m_XScan2[1] = max(m_XScan2[1], x_out[1]); int j1 = int((x_in[1]-m_X1[1])/m_Dy) + 1; int j2 = int((x_out[1]-m_X1[1])/m_Dy); if (preserveFluid()) { for (int j = j_last; j < min(m_Nj-1,j1); ++j) { g->SetValue(getIdx(i,j,k), 0); } } else { for (int j = max(0,j1); j <= min(m_Nj-1,j2); ++j) { g->SetValue(getIdx(i,j,k), 1); } } x = x_out; x[1] += shift*m_Dy; j_last = min(m_Nj-1,j2+1); } if (preserveFluid()) { for (int j = j_last; j <= m_Nj-1; ++j) { g->SetValue(getIdx(i,j,k), 0); } } } } } progress += m_Nk; GuiMainWindow::pointer()->setProgress(progress); } // scan jk plane -> i direction // yz plane -> x direction for (int j = 0; j < m_Nj; ++j) { for (int k = 0; k < m_Nk; ++k) { vec3_t x0 = getX(0,j,k); for (int j_il = 0; j_il <= interlaces; ++j_il) { for (int k_il = 0; k_il <= interlaces; ++k_il) { vec3_t x = x0; x[1] += j_il*dyi; x[2] += k_il*dzi; int i_last = 0; while (shootRay(x, vec3_t(1,0,0), x_in, x_out, n_in, n_out)) { m_GeometryFound = true; m_XScan1[0] = min(m_XScan1[0], x_in[0]); m_XScan2[0] = max(m_XScan2[0], x_out[0]); int i1 = int((x_in[0]-m_X1[0])/m_Dx) + 1; int i2 = int((x_out[0]-m_X1[0])/m_Dx); if (preserveFluid()) { for (int i = i_last; i < min(m_Ni-1,i1); ++i) { g->SetValue(getIdx(i,j,k), 0); } } else { for (int i = max(0,i1); i <= min(m_Ni-1,i2); ++i) { g->SetValue(getIdx(i,j,k), 1); } } x = x_out; x[0] += shift*m_Dx; i_last = min(m_Ni-1,i2+1); } if (preserveFluid()) { for (int i = i_last; i <= m_Ni-1; ++i) { g->SetValue(getIdx(i,j,k), 0); } } } } } progress += m_Nk; GuiMainWindow::pointer()->setProgress(progress); } if (create_grid) { GuiMainWindow::pointer()->resetProgress("smoothing", m_Ni*m_Nj*m_Nk*m_NumIterations); // smooth image data int progress = 0; for (int iter = 1; iter <= m_NumIterations; ++iter) { for (int i = 1; i < m_Ni-1; ++i) { for (int j = 1; j < m_Nj-1; ++j) { for (int k = 1; k < m_Nk-1; ++k) { int idx = getIdx(i,j,k); bool preserve = false; if (m_PreservationType == 1 && g->GetValue(idx) > 0.999) { preserve = true; } if (m_PreservationType == 2 && g->GetValue(idx) < 0.001) { preserve = true; } if (!preserve) { double g_new = 0; g_new += g->GetValue(getIdx(i+1,j,k)); g_new += g->GetValue(getIdx(i-1,j,k)); g_new += g->GetValue(getIdx(i,j+1,k)); g_new += g->GetValue(getIdx(i,j-1,k)); g_new += g->GetValue(getIdx(i,j,k+1)); g_new += g->GetValue(getIdx(i,j,k-1)); g_new *= 1.0/6.0; g->SetValue(idx, g_new); } } } progress += m_Nj*m_Nk; GuiMainWindow::pointer()->setProgress(progress); } } // write image data for testing and reporting purposes EG_VTKSP(vtkXMLImageDataWriter, vti); QString file_name = GuiMainWindow::pointer()->getCwd() + "/g.vti"; vti->SetFileName(qPrintable(file_name)); vti->SetDataModeToBinary(); vti->SetInputData(gdata); vti->Write(); gdata->GetPointData()->SetActiveScalars("g"); EG_VTKSP(vtkContourFilter, contour); contour->SetInputData(gdata); contour->SetNumberOfContours(1); double g_level = 0.5; if (m_PreservationType == 1) { g_level = 0.5; } if (m_PreservationType == 2) { g_level = 0.5; } contour->SetValue(0, g_level); EG_VTKSP(vtkTriangleFilter, tri); tri->SetInputConnection(contour->GetOutputPort()); EG_VTKSP(vtkDecimatePro, decimate); decimate->PreserveTopologyOn(); decimate->SetTargetReduction(m_TargetReduction); decimate->SetFeatureAngle(GeometryTools::deg2rad(45)); decimate->SetInputConnection(tri->GetOutputPort()); decimate->Update(); allocateGrid(m_Grid, decimate->GetOutput()->GetNumberOfPolys(), decimate->GetOutput()->GetNumberOfPoints()); for (vtkIdType id_node = 0; id_node < m_Grid->GetNumberOfPoints(); ++id_node) { vec3_t x; decimate->GetOutput()->GetPoint(id_node, x.data()); x[0] = m_X1[0] + x[0]*m_Dx; x[1] = m_X1[1] + x[1]*m_Dx; x[2] = m_X1[2] + x[2]*m_Dx; m_Grid->GetPoints()->SetPoint(id_node, x.data()); } EG_VTKDCC(vtkIntArray, cell_code, m_Grid, "cell_code"); for (vtkIdType id_cell = 0; id_cell < decimate->GetOutput()->GetNumberOfPolys(); ++id_cell) { EG_GET_CELL(id_cell, decimate->GetOutput()); vtkIdType id_new_cell = m_Grid->InsertNextCell(type_cell, num_pts, pts); cell_code->SetValue(id_new_cell, 1); } } }
void PointLight::emitPhoton(Ray &ray, RGBColor &_color){ ray = shootRay(); _color = color; }