Vector rayColour(Scene *s, Ray *r) { Vector ret; if ((*r).recursionDepth++ < RECURSELIMIT) { //printf("\nrecurse %d",(*r).recursionDepth); Intersection intersections[(*s).objectsSize]; Intersection first; int i; Vector pntTime, nat; for (i=0; i<(*s).objectsSize; i++){ ObjectRel objectrel = (*s).objects[i]; (intersections[i]) = initIntersection(objectrel.sphere, intersectionTime((*s).objects[i].sphere,(*r)), (*s).objects[i].surface); } first = firstIntersection(intersections, (*s).objectsSize); if (first.t == 9999999) { ret.x = 0; ret.y = 0; ret.z = 0; } else { pntTime = pointAtTime((*r), first.t); nat = normalAt(first.o, pntTime); //printf("lambert: %f\n", first.s.lambertCoefficient); ret = colorAt(&first.s, s, (*r), &pntTime, nat ); } } else { ret.x = 0; ret.y = 0; ret.z = 0; } return ret; }
QueryResult Query::raycast_faces(Ray ray, QueryType queryType) { if (!boundary_faces){ rebuild_boundary_cache(); } FaceKey firstIntersection((unsigned int) -1); double dist = std::numeric_limits<double>::max(); for (auto faceIter : *boundary_faces){ Face & face = mesh->get(faceIter); auto nodePos = mesh->get_pos(face.node_keys()); double newDist; if (ray.intersect_triangle(nodePos[0], nodePos[1], nodePos[2], newDist)){ bool isFirstFoundTriangle = dist == std::numeric_limits<double>::max(); if (isFirstFoundTriangle){ firstIntersection = faceIter; dist = newDist; } else { if (newDist < dist){ firstIntersection = faceIter; dist = newDist; } break; } } } if ((unsigned int)firstIntersection == (unsigned int)-1){ return QueryResult(); } return QueryResult(firstIntersection, dist, ray, queryType, mesh); }
//-------------------------------------------------------------------------------------------------- /// Find the intersection between the cell and the ray. The point closest to the ray origin is returned /// if no intersection is found, the intersection point is untouched. //-------------------------------------------------------------------------------------------------- bool RigCell::firstIntersectionPoint(const cvf::Ray& ray, cvf::Vec3d* intersectionPoint) const { CVF_ASSERT(intersectionPoint != NULL); cvf::ubyte faceVertexIndices[4]; int face; const std::vector<cvf::Vec3d>& nodes = m_hostGrid->mainGrid()->nodes(); cvf::Vec3d firstIntersection(cvf::Vec3d::ZERO); double minLsq = HUGE_VAL; for (face = 0; face < 6 ; ++face) { cvf::StructGridInterface::cellFaceVertexIndices(static_cast<cvf::StructGridInterface::FaceType>(face), faceVertexIndices); cvf::Vec3d intersection; cvf::Vec3d faceCenter = this->faceCenter(static_cast<cvf::StructGridInterface::FaceType>(face)); ray.triangleIntersect(nodes[m_cornerIndices[faceVertexIndices[0]]], nodes[m_cornerIndices[faceVertexIndices[1]]], faceCenter, &intersection); for (size_t i = 0; i < 4; ++i) { size_t next = i < 3 ? i+1 : 0; if ( ray.triangleIntersect( nodes[m_cornerIndices[faceVertexIndices[i]]], nodes[m_cornerIndices[faceVertexIndices[next]]], faceCenter, &intersection)) { double lsq = (intersection - ray.origin() ).lengthSquared(); if (lsq < minLsq) { firstIntersection = intersection; minLsq = lsq; } } } } if (minLsq != HUGE_VAL) { *intersectionPoint = firstIntersection; return true; } return false; }
void iluminatePixel(VECTOR *anchor, VECTOR *rayFromEyeDirection, RGB *color, INTERSECTION *intersection) { int sumDiffuse = 0, sumEspecular = 0; LIST_NODE_PTR lights = lightsList; LIST_NODE_PTR obstacle = NULL; long double i = 0.0; //Light Intensity for diffuse illumination long double e = 0.0; //Intensity of specular reflexion long double productPointResult; long double productPointN_L; long double lightIntensityThrowObject = 1.0; //Controls the intensity of the light when it pass throw an object, if no object is on the way of the light the intensity is 1 long double distanceToLight; VECTOR vectorToLight_l, vectorToEye_v, vectorReflexionOfL_r; //Test that the normal is the correct one if (dotProduct(rayFromEyeDirection, &intersection->object.normal) > EPSILON) { VECTOR newN; newN.x = -1 * intersection->object.normal.x; newN.y = -1 * intersection->object.normal.y; newN.z = -1 * intersection->object.normal.z; intersection->object.dependedNormal = newN; } while (lights != NULL) { LIGHT_POINT currentLight = lights->data.light; vectorToLight_l = calculateVectorToLight_L(intersection->intersection, currentLight.position, &distanceToLight); //Calculate Vector V, which is a vector to points back to the light, it is the same vector D but with the inverse direction vectorToEye_v.x = rayFromEyeDirection->x * -1; //With this is inverse the direction vectorToEye_v.y = rayFromEyeDirection->y * -1; vectorToEye_v.z = rayFromEyeDirection->z * -1; //Calculate Vector R, which is a vector ho is a Reflexion of the vector L taken the VEctor N as reference productPointN_L = dotProduct(&intersection->object.dependedNormal, &vectorToLight_l); vectorReflexionOfL_r.x = (2 * intersection->object.dependedNormal.x * productPointN_L) - vectorToLight_l.x; vectorReflexionOfL_r.y = (2 * intersection->object.dependedNormal.y * productPointN_L) - vectorToLight_l.y; vectorReflexionOfL_r.z = (2 * intersection->object.dependedNormal.z * productPointN_L) - vectorToLight_l.z; long double fAtt = attenuationFactor(intersection->intersection, currentLight); productPointResult = dotProduct(&vectorToLight_l, &intersection->object.dependedNormal); if (productPointResult > EPSILON) { if (APPLY_SHADOWS) { firstIntersection(&intersection->intersection, &vectorToLight_l, &obstacle); if (obstacle == NULL) { sumDiffuse = 1; if (APPLY_SPECULAR_REFLEXION) { sumEspecular = 1; } } else { lightIntensityThrowObject = obstacle->data.intersection.object.translucencyCoefficient_kt; sumDiffuse = 1; if (APPLY_SPECULAR_REFLEXION) { sumEspecular = 1; } } //I have to clean the obstacle intersections list, because it depends on the light cleanList(&obstacle); obstacle = NULL; } else { sumDiffuse = 1; if (APPLY_SPECULAR_REFLEXION) { sumEspecular = 1; } } } if (sumDiffuse == 1) { i += productPointResult * intersection->object.diffusionCoefficient_Kd * fAtt * (currentLight.intensity_Ip * lightIntensityThrowObject); } if (sumEspecular == 1) { long double dotProductResultRV = dotProduct(&vectorReflexionOfL_r, &vectorToEye_v); if (productPointN_L > EPSILON && dotProductResultRV > EPSILON) { e += pow(dotProductResultRV, intersection->object.specularReflexionRefinement_Kn) * intersection->object.specularReflexionCoeffient_Ks * (currentLight.intensity_Ip * lightIntensityThrowObject) * fAtt; } } sumDiffuse = 0; sumEspecular = 0; lights = lights->nextPtr; lightIntensityThrowObject = 1.0; } i += (intersection->object.ambientLightingCoefficient_Ka * ambientLighting_IA); if (i > 1.0) { i = 1.0; } color->r = intersection->object.color.r * i; color->g = intersection->object.color.g * i; color->b = intersection->object.color.b * i; if (APPLY_SPECULAR_REFLEXION) { color->r = color->r + e * (1.0 - color->r); color->g = color->g + e * (1.0 - color->g); color->b = color->b + e * (1.0 - color->b); } }
RGB whichColor(VECTOR *anchor, VECTOR *rayFromEyeDirection, int reflexionLevel, int *setBackground) { *setBackground = 0; RGB color, reflexionColor, transparencyColor; LIST_NODE_PTR intersection = NULL; VECTOR vectorToEye_v, vectorReflexionOfV_R; long double productPointN_V; firstIntersection(anchor, rayFromEyeDirection, &intersection); if (intersection == NULL) { //If intersection is equals to NULL *setBackground = 1; color = backgroundColor; } else { //Calculate Vector V, which is a vector to points back to the light, it is the same vector D but with the inverse direction vectorToEye_v.x = rayFromEyeDirection->x * -1; //With this is inverse the direction vectorToEye_v.y = rayFromEyeDirection->y * -1; vectorToEye_v.z = rayFromEyeDirection->z * -1; iluminatePixel(anchor, rayFromEyeDirection, &color, &intersection->data.intersection); if (APPLY_MIRRORS) { if (intersection->data.intersection.object.O2 > 0.0 && reflexionLevel > 0) { int isReflexionBackground = 0; productPointN_V = dotProduct(&intersection->data.intersection.object.dependedNormal, &vectorToEye_v); vectorReflexionOfV_R.x = 2 * productPointN_V * intersection->data.intersection.object.dependedNormal.x - vectorToEye_v.x; vectorReflexionOfV_R.y = 2 * productPointN_V * intersection->data.intersection.object.dependedNormal.y - vectorToEye_v.y; vectorReflexionOfV_R.z = 2 * productPointN_V * intersection->data.intersection.object.dependedNormal.z - vectorToEye_v.z; reflexionColor = whichColor(&intersection->data.intersection.intersection, &vectorReflexionOfV_R, reflexionLevel - 1, &isReflexionBackground); if (isReflexionBackground == 0) { color.r = intersection->data.intersection.object.O1 * color.r + intersection->data.intersection.object.O2 * reflexionColor.r; color.g = intersection->data.intersection.object.O1 * color.g + intersection->data.intersection.object.O2 * reflexionColor.g; color.b = intersection->data.intersection.object.O1 * color.b + intersection->data.intersection.object.O2 * reflexionColor.b; } /* color.r = intersection->data.intersection.object.O1 * color.r + intersection->data.intersection.object.O2 * reflexionColor.r; color.g = intersection->data.intersection.object.O1 * color.g + intersection->data.intersection.object.O2 * reflexionColor.g; color.b = intersection->data.intersection.object.O1 * color.b + intersection->data.intersection.object.O2 * reflexionColor.b; */ } } if (APPLY_TRANSPARENCY) { if (intersection->data.intersection.object.O3 > 0.0 && intersection->nextPtr != NULL) { iluminatePixel(anchor, rayFromEyeDirection, &transparencyColor, &intersection->nextPtr->data.intersection); color.r += intersection->data.intersection.object.O3 * transparencyColor.r; color.g += intersection->data.intersection.object.O3 * transparencyColor.g; color.b += intersection->data.intersection.object.O3 * transparencyColor.b; } } } cleanList(&intersection); return color; }