inline int postIntersect(const RTCRay& ray, DifferentialGeometry& dg) { int materialID = 0; unsigned int instID = ray.instID; { unsigned int geomID = ray.geomID; { ISPCGeometry* geometry = nullptr; if (g_instancing_mode == ISPC_INSTANCING_SCENE_GEOMETRY || g_instancing_mode == ISPC_INSTANCING_SCENE_GROUP) { ISPCInstance* instance = g_ispc_scene->geomID_to_inst[instID]; geometry = g_ispc_scene->geometries[instance->geom.geomID]; } else { geometry = g_ispc_scene->geometries[geomID]; } postIntersectGeometry(ray,dg,geometry,materialID); } } if (g_instancing_mode != ISPC_INSTANCING_NONE) { unsigned int instID = ray.instID; { /* get instance and geometry pointers */ ISPCInstance* instance = g_ispc_scene->geomID_to_inst[instID]; /* convert normals */ //AffineSpace3fa space = (1.0f-ray.time)*AffineSpace3fa(instance->space0) + ray.time*AffineSpace3fa(instance->space1); AffineSpace3fa space = calculate_interpolated_space(instance,ray.time); dg.Ng = xfmVector(space,dg.Ng); dg.Ns = xfmVector(space,dg.Ns); } } return materialID; }
__forceinline Color HDRILight::Le(const Vec3f& wo) const { Vec3f wi = xfmVector(world2local, -wo); float theta = acosf(clamp(wi.y,-1.0f,1.0f)); float phi = atan2f(-wi.z,-wi.x); if (phi < 0) phi += 2.0f * float(pi); float u = 1.0f - (phi * float(one_over_two_pi)); float v = theta * float(one_over_pi); ssize_t x = clamp(ssize_t(u*width), ssize_t(0), ssize_t(width-1)); ssize_t xNext = x + 1; if (size_t(xNext) == width) xNext = 0; float alpha = u*width - x; ssize_t y = clamp(ssize_t(v*height), ssize_t(0), ssize_t(height-1)); ssize_t yNext = y+1; if (size_t(yNext) == height) yNext = height-1; float beta = v*height - y; Color c0 = pixels->get(x, y ); Color c1 = pixels->get(xNext, y ); Color c2 = pixels->get(xNext, yNext); Color c3 = pixels->get(x, yNext); Color temp0 = beta*c3 + (1-beta)*c0; Color temp1 = beta*c2 + (1-beta)*c1; return L * (alpha*temp1 + (1-alpha)*temp0); }
int convertSubdivMesh(Ref<SceneGraph::SubdivMeshNode> mesh, const AffineSpace3fa& space0, const AffineSpace3fa& space1) { int materialID = convert(mesh->material); TutorialScene::SubdivMesh* subdivmesh = new TutorialScene::SubdivMesh(); const LinearSpace3fa nspace0 = rcp(space0.l).transposed(); subdivmesh->positions.resize(mesh->positions.size()); for (size_t i=0; i<mesh->positions.size(); i++) subdivmesh->positions[i] = xfmPoint(space0,mesh->positions[i]); subdivmesh->normals.resize(mesh->normals.size()); for (size_t i=0; i<mesh->normals.size(); i++) subdivmesh->normals[i] = xfmVector(nspace0,mesh->normals[i]); subdivmesh->texcoords = mesh->texcoords; subdivmesh->position_indices = mesh->position_indices; subdivmesh->normal_indices = mesh->normal_indices; subdivmesh->texcoord_indices = mesh->texcoord_indices; subdivmesh->verticesPerFace = mesh->verticesPerFace; subdivmesh->holes = mesh->holes; subdivmesh->edge_creases = mesh->edge_creases; subdivmesh->edge_crease_weights = mesh->edge_crease_weights; subdivmesh->vertex_creases = mesh->vertex_creases; subdivmesh->vertex_crease_weights = mesh->vertex_crease_weights; subdivmesh->materialID = materialID; scene->geometries.push_back(subdivmesh); return scene->geometries.size()-1; }
void FastInstanceIntersectorK<K>::intersect(vint<K>* valid, const Instance* instance, RayK<K>& ray, size_t item) { typedef Vec3<vfloat<K>> Vec3vfK; typedef AffineSpaceT<LinearSpace3<Vec3vfK>> AffineSpace3vfK; AffineSpace3vfK world2local; if (likely(instance->numTimeSteps == 1)) { world2local = instance->world2local[0]; } else { vfloat<K> t1 = ray.time, t0 = vfloat<K>(1.0f)-t1; world2local = rcp(t0*AffineSpace3vfK(instance->local2world[0]) + t1*AffineSpace3vfK(instance->local2world[1])); } const Vec3vfK ray_org = ray.org; const Vec3vfK ray_dir = ray.dir; const vint<K> ray_geomID = ray.geomID; const vint<K> ray_instID = ray.instID; ray.org = xfmPoint (world2local,ray_org); ray.dir = xfmVector(world2local,ray_dir); ray.geomID = RTC_INVALID_GEOMETRY_ID; ray.instID = instance->id; intersectObject(valid,instance->object,ray); ray.org = ray_org; ray.dir = ray_dir; vbool<K> nohit = ray.geomID == vint<K>(RTC_INVALID_GEOMETRY_ID); ray.geomID = select(nohit,ray_geomID,ray.geomID); ray.instID = select(nohit,ray_instID,ray.instID); }
float HDRILight::pdf(const DifferentialGeometry& dg, const Vec3f& _wi) const { Vec3f wi = xfmVector(world2local, _wi); float theta = acosf(wi.y); float phi = atan2f(-wi.z,-wi.x); if (phi < 0) phi += 2.0f * float(pi); float u = 1.0f - float(one_over_two_pi) * phi; float v = float(one_over_pi) * theta; return distribution->pdf(Vec2f(u,v))*rcp(float(two_pi) * float(pi) * sinf(theta)); }
/* task that renders a single screen tile */ Vec3fa renderPixelStandard(float x, float y, const ISPCCamera& camera, RayStats& stats) { /* initialize ray */ RTCRay ray; ray.org = Vec3fa(camera.xfm.p); ray.dir = Vec3fa(normalize(x*camera.xfm.l.vx + y*camera.xfm.l.vy + camera.xfm.l.vz)); ray.tnear = 0.0f; ray.tfar = (float)(inf); ray.geomID = RTC_INVALID_GEOMETRY_ID; ray.primID = RTC_INVALID_GEOMETRY_ID; ray.instID = -1; ray.mask = -1; ray.time = 0; /* intersect ray with scene */ rtcIntersect(g_scene,ray); RayStats_addRay(stats); /* shade pixels */ Vec3fa color = Vec3fa(0.0f); if (ray.geomID != RTC_INVALID_GEOMETRY_ID) { /* calculate shading normal in world space */ Vec3fa Ns = ray.Ng; if (ray.instID != RTC_INVALID_GEOMETRY_ID) Ns = xfmVector(normal_xfm[ray.instID],Ns); Ns = normalize(Ns); /* calculate diffuse color of geometries */ Vec3fa diffuse = Vec3fa(1,1,1); if (ray.instID != RTC_INVALID_GEOMETRY_ID) diffuse = colors[ray.instID][ray.geomID]; color = color + diffuse*0.5; /* initialize shadow ray */ Vec3fa lightDir = normalize(Vec3fa(-1,-1,-1)); RTCRay shadow; shadow.org = ray.org + ray.tfar*ray.dir; shadow.dir = neg(lightDir); shadow.tnear = 0.001f; shadow.tfar = (float)(inf); shadow.geomID = 1; shadow.primID = 0; shadow.mask = -1; shadow.time = 0; /* trace shadow ray */ rtcOccluded(g_scene,shadow); RayStats_addShadowRay(stats); /* add light contribution */ if (shadow.geomID) color = color + diffuse*clamp(-dot(lightDir,Ns),0.0f,1.0f); } return color; }
void FastInstanceIntersector1::occluded (const UserGeometryScene::Instance* instance, Ray& ray, size_t item) { const Vec3fa ray_org = ray.org; const Vec3fa ray_dir = ray.dir; ray.org = xfmPoint (instance->world2local,ray_org); ray.dir = xfmVector(instance->world2local,ray_dir); instance->object->occluded((RTCRay&)ray); ray.org = ray_org; ray.dir = ray_dir; }
void instanceOccludedFunc(const Instance* instance, RTCRay& ray, size_t item) { const Vec3f ray_org = ray.org; const Vec3f ray_dir = ray.dir; ray.org = xfmPoint (instance->world2local,ray_org); ray.dir = xfmVector(instance->world2local,ray_dir); rtcOccluded(instance->object,ray); ray.org = ray_org; ray.dir = ray_dir; }
Color HDRILight::sample(const DifferentialGeometry& dg, Sample3f& wi, float& tMax, const Vec2f& sample) const { Sample2f pixelF = distribution->sample(sample); float theta = float(pi) * pixelF.value.y*rcp(float(height)); float phi = float(two_pi) * (1.0f - pixelF.value.x*rcp(float(width))); Vec3f _wi = Vec3f(-sinf(theta)*cosf(phi),cosf(theta),-sinf(theta)*sinf(phi)); wi = Sample3f(xfmVector(local2world, _wi),pixelF.pdf*rcp(float(two_pi) * float(pi) * sinf(theta))); tMax = inf; return L*pixels->get(clamp(ssize_t(pixelF.value.x), ssize_t(0), ssize_t(width-1)), clamp(ssize_t(pixelF.value.y), ssize_t(0), ssize_t(height-1))); }
void FastInstanceIntersector8::occluded (avxb* valid, const UserGeometryScene::Instance* instance, Ray8& ray, size_t item) { const avx3f ray_org = ray.org; const avx3f ray_dir = ray.dir; const avxi ray_geomID = ray.geomID; const AffineSpace3fAVX world2local(instance->world2local); ray.org = xfmPoint (world2local,ray_org); ray.dir = xfmVector(world2local,ray_dir); instance->object->occluded8(valid,(RTCRay8&)ray); ray.org = ray_org; ray.dir = ray_dir; }
void FastInstanceIntersector4::occluded (bool4* valid, const Instance* instance, Ray4& ray, size_t item) { const Vec3f4 ray_org = ray.org; const Vec3f4 ray_dir = ray.dir; const int4 ray_geomID = ray.geomID; const AffineSpace3faSSE world2local(instance->world2local); ray.org = xfmPoint (world2local,ray_org); ray.dir = xfmVector(world2local,ray_dir); ray.instID = instance->id; instance->object->occluded4(valid,(RTCRay4&)ray); ray.org = ray_org; ray.dir = ray_dir; }
void FastInstanceIntersector16::occluded (mic_i* valid, const UserGeometryScene::Instance* instance, Ray16& ray, size_t item) { const mic3f ray_org = ray.org; const mic3f ray_dir = ray.dir; const mic_i ray_geomID = ray.geomID; const AffineSpace3faMIC world2local(instance->world2local); ray.org = xfmPoint (world2local,ray_org); ray.dir = xfmVector(world2local,ray_dir); ray.instID = instance->id; instance->object->occluded16(valid,(RTCRay16&)ray); ray.org = ray_org; ray.dir = ray_dir; }
Ref<Shape> TriangleMeshFull::transform(const AffineSpace3f& xfm) const { /*! do nothing for identity matrix */ if (xfm == AffineSpace3f(one)) return (Shape*)this; /*! create transformed */ TriangleMeshFull* mesh = new TriangleMeshFull(ty); mesh->position.resize(position.size()); for (size_t i=0; i<position.size(); i++) mesh->position[i] = xfmPoint(xfm,position[i]); mesh->motion.resize(motion.size()); for (size_t i=0; i<motion.size(); i++) mesh->motion[i] = xfmVector(xfm,motion[i]); mesh->normal.resize(normal.size() ); for (size_t i=0; i<normal.size(); i++) mesh->normal[i] = xfmNormal(xfm,normal[i]); mesh->tangent_x.resize(tangent_x.size() ); for (size_t i=0; i<tangent_x.size(); i++) mesh->tangent_x[i] = xfmVector(xfm,tangent_x[i]); mesh->tangent_y.resize(tangent_y.size() ); for (size_t i=0; i<tangent_y.size(); i++) mesh->tangent_y[i] = xfmVector(xfm,tangent_y[i]); mesh->texcoord = texcoord; mesh->triangles = triangles; return mesh; }
void FastInstanceIntersector4::occluded (sseb* valid, const UserGeometryScene::Instance* instance, Ray4& ray, size_t item) { const sse3f ray_org = ray.org; const sse3f ray_dir = ray.dir; const ssei ray_geomID = ray.geomID; const AffineSpace3faSSE world2local(instance->world2local); ray.org = xfmPoint (world2local,ray_org); ray.dir = xfmVector(world2local,ray_dir); ray.instID = instance->id; instance->object->occluded4(valid,(RTCRay4&)ray); ray.org = ray_org; ray.dir = ray_dir; }
void instanceIntersectFunc(const Instance* instance, RTCRay& ray, size_t item) { const Vec3f ray_org = ray.org; const Vec3f ray_dir = ray.dir; const int geomID = ray.geomID; ray.org = xfmPoint (instance->world2local,ray_org); ray.dir = xfmVector(instance->world2local,ray_dir); ray.geomID = RTC_INVALID_GEOMETRY_ID; rtcIntersect(instance->object,ray); ray.org = ray_org; ray.dir = ray_dir; if (ray.geomID == RTC_INVALID_GEOMETRY_ID) ray.geomID = geomID; else ray.instID = instance->userID; }
__forceinline void FastInstanceIntersectorN::occluded1(const Instance* instance, const RTCIntersectContext* user_context, Ray& ray, size_t item) { const AffineSpace3fa world2local = likely(instance->numTimeSteps == 1) ? instance->getWorld2Local() : instance->getWorld2Local(ray.time); const Vec3fa ray_org = ray.org; const Vec3fa ray_dir = ray.dir; ray.org = xfmPoint (world2local,ray_org); ray.dir = xfmVector(world2local,ray_dir); ray.instID = instance->geomID; IntersectContext context(instance->object,user_context); instance->object->intersectors.occluded((RTCRay&)ray,&context); ray.org = ray_org; ray.dir = ray_dir; }
void FastInstanceIntersector8::intersect(avxb* valid, const UserGeometryScene::Instance* instance, Ray8& ray, size_t item) { const avx3f ray_org = ray.org; const avx3f ray_dir = ray.dir; const avxi ray_geomID = ray.geomID; const AffineSpace3fAVX world2local(instance->world2local); ray.org = xfmPoint (world2local,ray_org); ray.dir = xfmVector(world2local,ray_dir); ray.geomID = -1; instance->object->intersect8(valid,(RTCRay8&)ray); ray.org = ray_org; ray.dir = ray_dir; avxb nohit = ray.geomID == avxi(-1); ray.geomID = select(nohit,ray_geomID,ray.geomID); ray.instID = select(nohit,ray.instID,instance->id); }
void FastInstanceIntersectorK<K>::occluded(vint<K>* valid, const Instance* instance, RayK<K>& ray, size_t item) { typedef Vec3<vfloat<K>> Vec3vfK; typedef AffineSpaceT<LinearSpace3<Vec3vfK>> AffineSpace3vfK; const Vec3vfK ray_org = ray.org; const Vec3vfK ray_dir = ray.dir; const vint<K> ray_geomID = ray.geomID; const AffineSpace3vfK world2local(instance->world2local); ray.org = xfmPoint (world2local,ray_org); ray.dir = xfmVector(world2local,ray_dir); ray.instID = instance->id; occludedObject(valid,instance->object,ray); ray.org = ray_org; ray.dir = ray_dir; }
__noinline void FastInstanceIntersectorN::occludedN(vint<N>* validi, const Instance* instance, const RTCIntersectContext* user_context, RayK<N>& ray, size_t item) { AffineSpace3vf<N> world2local; const vbool<N> valid = *validi == vint<N>(-1); if (likely(instance->numTimeSteps == 1)) world2local = instance->getWorld2Local(); else world2local = instance->getWorld2Local<N>(valid,ray.time); const Vec3vf<N> ray_org = ray.org; const Vec3vf<N> ray_dir = ray.dir; ray.org = xfmPoint (world2local,ray_org); ray.dir = xfmVector(world2local,ray_dir); ray.instID = instance->geomID; IntersectContext context(instance->object,user_context); occludedObject((vint<N>*)validi,instance->object,&context,ray); ray.org = ray_org; ray.dir = ray_dir; }
void FastInstanceIntersector4::intersect(sseb* valid, const UserGeometryScene::Instance* instance, Ray4& ray, size_t item) { const sse3f ray_org = ray.org; const sse3f ray_dir = ray.dir; const ssei ray_geomID = ray.geomID; const ssei ray_instID = ray.instID; const AffineSpace3faSSE world2local(instance->world2local); ray.org = xfmPoint (world2local,ray_org); ray.dir = xfmVector(world2local,ray_dir); ray.geomID = -1; ray.instID = instance->id; instance->object->intersect4(valid,(RTCRay4&)ray); ray.org = ray_org; ray.dir = ray_dir; sseb nohit = ray.geomID == ssei(-1); ray.geomID = select(nohit,ray_geomID,ray.geomID); ray.instID = select(nohit,ray_instID,ray.instID); }
void FastInstanceIntersector4::intersect(bool4* valid, const Instance* instance, Ray4& ray, size_t item) { const Vec3f4 ray_org = ray.org; const Vec3f4 ray_dir = ray.dir; const int4 ray_geomID = ray.geomID; const int4 ray_instID = ray.instID; const AffineSpace3faSSE world2local(instance->world2local); ray.org = xfmPoint (world2local,ray_org); ray.dir = xfmVector(world2local,ray_dir); ray.geomID = -1; ray.instID = instance->id; instance->object->intersect4(valid,(RTCRay4&)ray); ray.org = ray_org; ray.dir = ray_dir; bool4 nohit = ray.geomID == int4(-1); ray.geomID = select(nohit,ray_geomID,ray.geomID); ray.instID = select(nohit,ray_instID,ray.instID); }
void FastInstanceIntersector16::intersect(mic_i* valid, const UserGeometryScene::Instance* instance, Ray16& ray, size_t item) { const mic3f ray_org = ray.org; const mic3f ray_dir = ray.dir; const mic_i ray_geomID = ray.geomID; const mic_i ray_instID = ray.instID; const AffineSpace3faMIC world2local(instance->world2local); ray.org = xfmPoint (world2local,ray_org); ray.dir = xfmVector(world2local,ray_dir); ray.geomID = -1; ray.instID = instance->id; instance->object->intersect16(valid,(RTCRay16&)ray); ray.org = ray_org; ray.dir = ray_dir; mic_m nohit = ray.geomID == mic_i(-1); ray.geomID = select(nohit,ray_geomID,ray.geomID); ray.instID = select(nohit,ray_instID,ray.instID); }
void FastInstanceIntersector1::intersect(const UserGeometryScene::Instance* instance, Ray& ray, size_t item) { const Vec3fa ray_org = ray.org; const Vec3fa ray_dir = ray.dir; const int ray_geomID = ray.geomID; const int ray_instID = ray.instID; ray.org = xfmPoint (instance->world2local,ray_org); ray.dir = xfmVector(instance->world2local,ray_dir); ray.geomID = -1; ray.instID = instance->id; instance->object->intersect((RTCRay&)ray); ray.org = ray_org; ray.dir = ray_dir; if (ray.geomID == -1) { ray.geomID = ray_geomID; ray.instID = ray_instID; } }
void FastInstanceIntersectorK<K>::intersect(vint<K>* valid, const Instance* instance, RayK<K>& ray, size_t item) { typedef Vec3<vfloat<K>> Vec3vfK; typedef AffineSpaceT<LinearSpace3<Vec3vfK>> AffineSpace3vfK; const Vec3vfK ray_org = ray.org; const Vec3vfK ray_dir = ray.dir; const vint<K> ray_geomID = ray.geomID; const vint<K> ray_instID = ray.instID; const AffineSpace3vfK world2local(instance->world2local); ray.org = xfmPoint (world2local,ray_org); ray.dir = xfmVector(world2local,ray_dir); ray.geomID = -1; ray.instID = instance->id; intersectObject(valid,instance->object,ray); ray.org = ray_org; ray.dir = ray_dir; vbool<K> nohit = ray.geomID == vint<K>(-1); ray.geomID = select(nohit,ray_geomID,ray.geomID); ray.instID = select(nohit,ray_instID,ray.instID); }
__forceinline void FastInstanceIntersectorN::intersect1(const Instance* instance, const RTCIntersectContext* user_context, Ray& ray, size_t item) { const AffineSpace3fa world2local = likely(instance->numTimeSteps == 1) ? instance->getWorld2Local() : instance->getWorld2Local(ray.time); const Vec3fa ray_org = ray.org; const Vec3fa ray_dir = ray.dir; const int ray_geomID = ray.geomID; const int ray_instID = ray.instID; ray.org = xfmPoint (world2local,ray_org); ray.dir = xfmVector(world2local,ray_dir); ray.geomID = RTC_INVALID_GEOMETRY_ID; ray.instID = instance->geomID; IntersectContext context(instance->object,user_context); instance->object->intersectors.intersect((RTCRay&)ray,&context); ray.org = ray_org; ray.dir = ray_dir; if (ray.geomID == RTC_INVALID_GEOMETRY_ID) { ray.geomID = ray_geomID; ray.instID = ray_instID; } }
void FastInstanceIntersectorK<K>::occluded(vint<K>* valid, const Instance* instance, RayK<K>& ray, size_t item) { typedef Vec3<vfloat<K>> Vec3vfK; typedef AffineSpaceT<LinearSpace3<Vec3vfK>> AffineSpace3vfK; AffineSpace3vfK world2local; if (likely(instance->numTimeSteps == 1)) { world2local = instance->world2local[0]; } else { vfloat<K> t1 = ray.time, t0 = vfloat<K>(1.0f)-t1; world2local = rcp(t0*AffineSpace3vfK(instance->local2world[0]) + t1*AffineSpace3vfK(instance->local2world[1])); } const Vec3vfK ray_org = ray.org; const Vec3vfK ray_dir = ray.dir; ray.org = xfmPoint (world2local,ray_org); ray.dir = xfmVector(world2local,ray_dir); ray.instID = instance->id; occludedObject(valid,instance->object,ray); ray.org = ray_org; ray.dir = ray_dir; }
__noinline void FastInstanceIntersectorN::intersectN(vint<N>* validi, const Instance* instance, const RTCIntersectContext* user_context, RayK<N>& ray, size_t item) { AffineSpace3vf<N> world2local; const vbool<N> valid = *validi == vint<N>(-1); if (likely(instance->numTimeSteps == 1)) world2local = instance->getWorld2Local(); else world2local = instance->getWorld2Local<N>(valid,ray.time); const Vec3vf<N> ray_org = ray.org; const Vec3vf<N> ray_dir = ray.dir; const vint<N> ray_geomID = ray.geomID; const vint<N> ray_instID = ray.instID; ray.org = xfmPoint (world2local,ray_org); ray.dir = xfmVector(world2local,ray_dir); ray.geomID = RTC_INVALID_GEOMETRY_ID; ray.instID = instance->geomID; IntersectContext context(instance->object,user_context); intersectObject((vint<N>*)validi,instance->object,&context,ray); ray.org = ray_org; ray.dir = ray_dir; vbool<N> nohit = ray.geomID == vint<N>(RTC_INVALID_GEOMETRY_ID); ray.geomID = select(nohit,ray_geomID,ray.geomID); ray.instID = select(nohit,ray_instID,ray.instID); }
/* renders a single screen tile */ void renderTileStandardStream(int taskIndex, int* pixels, const int width, const int height, const float time, const ISPCCamera& camera, const int numTilesX, const int numTilesY) { const int tileY = taskIndex / numTilesX; const int tileX = taskIndex - tileY * numTilesX; const int x0 = tileX * TILE_SIZE_X; const int x1 = min(x0+TILE_SIZE_X,width); const int y0 = tileY * TILE_SIZE_Y; const int y1 = min(y0+TILE_SIZE_Y,height); RTCRay primary_stream[TILE_SIZE_X*TILE_SIZE_Y]; RTCRay shadow_stream[TILE_SIZE_X*TILE_SIZE_Y]; Vec3fa color_stream[TILE_SIZE_X*TILE_SIZE_Y]; float weight_stream[TILE_SIZE_X*TILE_SIZE_Y]; bool valid_stream[TILE_SIZE_X*TILE_SIZE_Y]; /* select stream mode */ RTCIntersectFlags iflags = g_mode == MODE_STREAM_COHERENT ? RTC_INTERSECT_COHERENT : RTC_INTERSECT_INCOHERENT; /* generate stream of primary rays */ int N = 0; int numActive = 0; for (int y=y0; y<y1; y++) for (int x=x0; x<x1; x++) { /* ISPC workaround for mask == 0 */ if (all(1 == 0)) continue; /* initialize variables */ color_stream[N] = Vec3fa(0.0f); weight_stream[N] = 1.0f; bool mask = 1; { valid_stream[N] = mask; } /* initialize ray */ RTCRay& primary = primary_stream[N]; primary.org = Vec3fa(camera.xfm.p); primary.dir = Vec3fa(normalize(x*camera.xfm.l.vx + y*camera.xfm.l.vy + camera.xfm.l.vz)); mask = 1; { // invalidates inactive rays primary.tnear = mask ? 0.0f : (float)(pos_inf); primary.tfar = mask ? (float)(inf) : (float)(neg_inf); } primary.instID = -1; primary.geomID = RTC_INVALID_GEOMETRY_ID; primary.primID = RTC_INVALID_GEOMETRY_ID; primary.mask = -1; primary.time = 0.0f; N++; } Vec3fa lightDir = normalize(Vec3fa(-1,-1,-1)); /* trace rays */ RTCIntersectContext primary_context; primary_context.flags = iflags; primary_context.userRayExt = &primary_stream; rtcIntersect1M(g_scene,&primary_context,(RTCRay*)&primary_stream,N,sizeof(RTCRay)); /* terminate rays and update color */ N = -1; for (int y=y0; y<y1; y++) for (int x=x0; x<x1; x++) { N++; /* ISPC workaround for mask == 0 */ if (all(1 == 0)) continue; /* invalidate shadow rays by default */ RTCRay& shadow = shadow_stream[N]; { shadow.tnear = (float)(pos_inf); shadow.tfar = (float)(neg_inf); } /* ignore invalid rays */ if (valid_stream[N] == false) continue; /* terminate rays that hit nothing */ if (primary_stream[N].geomID == RTC_INVALID_GEOMETRY_ID) { valid_stream[N] = false; continue; } /* calculate shading normal in world space */ RTCRay& primary = primary_stream[N]; Vec3fa Ns = primary.Ng; if (primary.instID != -1) Ns = xfmVector(normal_xfm[primary.instID],Ns); Ns = normalize(Ns); /* calculate diffuse color of geometries */ Vec3fa diffuse = Vec3fa(1,1,1); if (primary.instID != -1) diffuse = colors[primary.instID][primary.geomID]; color_stream[N] = color_stream[N] + diffuse*0.5; /* initialize shadow ray */ shadow.org = primary.org + primary.tfar*primary.dir; shadow.dir = neg(lightDir); bool mask = 1; { shadow.tnear = mask ? 0.001f : (float)(pos_inf); shadow.tfar = mask ? (float)(inf) : (float)(neg_inf); } shadow.geomID = RTC_INVALID_GEOMETRY_ID; shadow.primID = RTC_INVALID_GEOMETRY_ID; shadow.mask = -1; shadow.time = 0; } N++; /* trace shadow rays */ RTCIntersectContext shadow_context; shadow_context.flags = iflags; shadow_context.userRayExt = &shadow_stream; rtcOccluded1M(g_scene,&shadow_context,(RTCRay*)&shadow_stream,N,sizeof(RTCRay)); /* add light contribution */ N = -1; for (int y=y0; y<y1; y++) for (int x=x0; x<x1; x++) { N++; /* ISPC workaround for mask == 0 */ if (all(1 == 0)) continue; /* ignore invalid rays */ if (valid_stream[N] == false) continue; /* calculate shading normal in world space */ RTCRay& primary = primary_stream[N]; Vec3fa Ns = primary.Ng; if (primary.instID != -1) Ns = xfmVector(normal_xfm[primary.instID],Ns); Ns = normalize(Ns); /* calculate diffuse color of geometries */ Vec3fa diffuse = Vec3fa(1,1,1); if (primary.instID != -1) diffuse = colors[primary.instID][primary.geomID]; /* add light contrinution */ RTCRay& shadow = shadow_stream[N]; if (shadow.geomID) { color_stream[N] = color_stream[N] + diffuse*clamp(-dot(lightDir,Ns),0.0f,1.0f); } } N++; /* framebuffer writeback */ N = 0; for (int y=y0; y<y1; y++) for (int x=x0; x<x1; x++) { /* ISPC workaround for mask == 0 */ if (all(1 == 0)) continue; /* write color to framebuffer */ unsigned int r = (unsigned int) (255.0f * clamp(color_stream[N].x,0.0f,1.0f)); unsigned int g = (unsigned int) (255.0f * clamp(color_stream[N].y,0.0f,1.0f)); unsigned int b = (unsigned int) (255.0f * clamp(color_stream[N].z,0.0f,1.0f)); pixels[y*width+x] = (b << 16) + (g << 8) + r; N++; } }
int convertTriangleMesh(Ref<SceneGraph::TriangleMeshNode> mesh, const AffineSpace3fa& space0, const AffineSpace3fa& space1) { int materialID = convert(mesh->material); TutorialScene::TriangleMesh* objmesh = new TutorialScene::TriangleMesh(); const LinearSpace3fa nspace0 = rcp(space0.l).transposed(); objmesh->v. resize(mesh->v. size()); for (size_t i=0; i<mesh->v. size(); i++) objmesh->v [i] = xfmPoint ( space0,mesh->v [i]); objmesh->v2.resize(mesh->v2.size()); for (size_t i=0; i<mesh->v2.size(); i++) objmesh->v2[i] = xfmPoint ( space1,mesh->v2[i]); objmesh->vn.resize(mesh->vn.size()); for (size_t i=0; i<mesh->vn.size(); i++) objmesh->vn[i] = xfmVector(nspace0,mesh->vn[i]); objmesh->vt = mesh->vt; objmesh->triangles.resize(mesh->triangles.size()); for (size_t i=0; i<mesh->triangles.size(); i++) { SceneGraph::TriangleMeshNode::Triangle& tri = mesh->triangles[i]; objmesh->triangles[i] = TutorialScene::Triangle(tri.v0,tri.v1,tri.v2,materialID); } objmesh->meshMaterialID = materialID; scene->geometries.push_back(objmesh); return scene->geometries.size()-1; }
void motionFunc(int x, int y) { float dClickX = float(clickX - x), dClickY = float(clickY - y); clickX = x; clickY = y; // Rotate camera around look-at point (LMB + mouse move) if (mouseMode == 1) { #define ROTATE_WITH_FIXED_UPVECTOR 1 #if ROTATE_WITH_FIXED_UPVECTOR float angularSpeed = 0.05f / 180.0f * float(pi); float theta = dClickX * angularSpeed; float phi = dClickY * angularSpeed; const Vector3f viewVec = normalize(g_camLookAt - g_camPos); float dist = length(g_camLookAt - g_camPos); const Vector3f dX = normalize(cross(viewVec,g_camUp)); const Vector3f dY = normalize(cross(viewVec,dX)); AffineSpace3f rot_x = AffineSpace3f::rotate(g_camLookAt,dX,phi); g_camSpace = rot_x * g_camSpace; g_camSpace = AffineSpace3f::rotate(g_camLookAt,dY,theta) * g_camSpace; g_camPos = g_camLookAt-dist*xfmVector(g_camSpace,Vector3f(0,0,1)); #else float angularSpeed = 0.05f / 180.0f * float(pi); float mapping = 1.0f; if (g_camUp[1] < 0) mapping = -1.0f; theta -= mapping * dClickX * angularSpeed; phi += dClickY * angularSpeed; if (theta < 0) theta += 2.0f * float(pi); if (theta > 2.0f*float(pi)) theta -= 2.0f * float(pi); if (phi < -1.5f*float(pi)) phi += 2.0f*float(pi); if (phi > 1.5f*float(pi)) phi -= 2.0f*float(pi); float cosPhi = cosf(phi); float sinPhi = sinf(phi); float cosTheta = cosf(theta); float sinTheta = sinf(theta); float dist = length(g_camLookAt - g_camPos); g_camPos = g_camLookAt + dist * Vector3f(cosPhi * sinTheta, -sinPhi, cosPhi * cosTheta); Vector3f viewVec = normalize(g_camLookAt - g_camPos); Vector3f approxUp(0.0f, 1.0f, 0.0f); if (phi < -0.5f*float(pi) || phi > 0.5*float(pi)) approxUp = -approxUp; Vector3f rightVec = normalize(cross(viewVec, approxUp)); AffineSpace3f rotate = AffineSpace3f::rotate(viewVec, psi); g_camUp = xfmVector(rotate, cross(rightVec, viewVec)); #endif } // Pan camera (MMB + mouse move) if (mouseMode == 2) { float panSpeed = 0.00025f; float dist = length(g_camLookAt - g_camPos); Vector3f viewVec = normalize(g_camLookAt - g_camPos); Vector3f strafeVec = cross(g_camUp, viewVec); Vector3f deltaVec = strafeVec * panSpeed * dist * float(dClickX) + g_camUp * panSpeed * dist * float(-dClickY); g_camPos += deltaVec; g_camLookAt += deltaVec; } // Dolly camera (RMB + mouse move) if (mouseMode == 3) { float dollySpeed = 0.01f; float delta; if (fabsf(dClickX) > fabsf(dClickY)) delta = float(dClickX); else delta = float(-dClickY); float k = powf((1-dollySpeed), delta); float dist = length(g_camLookAt - g_camPos); Vector3f viewVec = normalize(g_camLookAt - g_camPos); g_camPos += dist * (1-k) * viewVec; } // Roll camera (ALT + LMB + mouse move) if (mouseMode == 4) { float angularSpeed = 0.1f / 180.0f * float(pi); psi -= dClickX * angularSpeed; Vector3f viewVec = normalize(g_camLookAt - g_camPos); Vector3f approxUp(0.0f, 1.0f, 0.0f); if (phi < -0.5f*float(pi) || phi > 0.5*float(pi)) approxUp = -approxUp; Vector3f rightVec = normalize(cross(viewVec, approxUp)); AffineSpace3f rotate = AffineSpace3f::rotate(viewVec, psi); g_camUp = xfmVector(rotate, cross(rightVec, viewVec)); } g_camSpace = AffineSpace3f::lookAtPoint(g_camPos, g_camLookAt, g_camUp); g_resetAccumulation = true; }