Color LambertianMaterial::shade(const RenderContext& rc, const Ray& ray, const HitRecord& hrec, int depth) const{ Point hp = ((Ray&)ray).pointOn(((HitRecord&)hrec).GetT()); Vector normal = ((HitRecord&)hrec).GetPrimitive()->normal(hp); hp += 0.0001f * normal; Scene* scene = (Scene*)rc.getScene(); int numlights = scene->num_lights(); Color finalc(0.f,0.f,0.f); for(int i=0; i<numlights; i++){ Vector ldir; Color lcolor; float ldist = scene->get_light(i)->getLight(lcolor, ldir, rc, hp); HitRecord shadowhr; Ray shadowray(hp, ldir); scene->get_object()->intersect(shadowhr, rc, shadowray); if(shadowhr.GetT()>=ldist || shadowhr.GetT()<0.01){ float dp = dot(normal, ldir); if(dp > 0) finalc += dp*lcolor; } } return color*(finalc*kd + scene->get_ambient()*ka); }
HitRecord* CrossSectionMouseProc::HitTest( ViewExp *vpt, IPoint2 *p, int type, int flags ) { HitRecord *bestRec = NULL; vpt->ClearSubObjHitList(); SetSplineHitOverride(SS_SPLINE); ip->SubObHitTest(ip->GetTime(),type,ip->GetCrossing(),flags,p,vpt); ClearSplineHitOverride(); if ( vpt->NumSubObjHits() ) { HitLog &hits = vpt->GetSubObjHitList(); DWORD best; for (HitRecord *rec = hits.First(); rec != NULL; rec = rec->Next()) { if (mCreating) { ShapeHitData *hit = ((ShapeHitData *)rec->hitData); if (hit->poly >= mPolys) continue; } if(bestRec == NULL || rec->distance < best) { best = rec->distance; bestRec = rec; } } } return bestRec; }
// add extra methods here void MyScene::rayTrace(Point3 point, Vector3 ray){ HitRecord* hits = new HitRecord(); transformStack.clear(); transformStack.push_back(Matrix4::identity()); castRayAgainstSubgraph(point, ray, root, hits); bool gotHit; double tH, uH, vH; Point3 pH; Vector3 nH; gotHit = hits->getFirstHit(tH, uH, vH, pH, nH); delete hits; int col, row; getScreenCoord(point+ray, col, row); int idx = pxIdx(col, row); if (gotHit){ for (Light& l : lights){ Point3 lPos = l.getPos(); castLight(lPos, pH, l, 0, 0, NULL); } } else{ pixelArray[idx] = (unsigned char)(background[0] * 255); pixelArray[idx + 1] = (unsigned char)(background[1] * 255); pixelArray[idx + 2] = (unsigned char)(background[2] * 255); } }
void MyScene::castRayAgainstSubgraph(Point3 p, Vector3 v, Tree* graph, HitRecord* hits){ for (Node* n : graph->rootNodes){ Matrix4 trans = transformStack.back(); trans = trans*n->transformations; Matrix4 invTrans = trans.inverse(); if (n->object){ Vector4 pObj4 = invTrans*Vector4(p[0], p[1], p[2], 1); Vector4 vObj4 = invTrans*Vector4(v[0], v[1], v[2], 0); vObj4.normalize(); Shape* s; switch (n->object->type){ case CUBE:{ s = cube; } break; case SPHERE:{ s = sphere; } break; case CONE:{ s = cone; } break; case CYLINDER:{ s = cylinder; } break; } Point3 pObj = Point3(pObj4[0], pObj4[1], pObj4[2]); Vector3 vObj = Vector3(vObj4[0], vObj4[1], vObj4[2]); HitRecord* hr = s->intersect(pObj, vObj); hr->sortHits(); bool gotHit; double tH,uH,vH; Point3 pH; Vector3 nH; gotHit = hr->getFirstHit(tH, uH, vH, pH, nH); delete hr; if (gotHit && tH > 0){ pH = trans * pH; nH = invTrans.transpose() * nH; nH.normalize(); tH = (pH - p).length(); if (tH < hits->getMinT()){ hits->clear(); hits->addHit(tH, uH, vH, pH, nH, (void*)n->object); } } } else if (n->subgraph){ transformStack.push_back(trans); castRayAgainstSubgraph(p, v, n->subgraph, hits); transformStack.pop_back(); } } }
HitRecord BezierCurve::intersect(const Ray &ray, const double dist, const double time) const { HitRecord hit = HitRecord(dist); //These are the endpoints of the line segment double t = findIntersection(0.0, 1.0, ray); if (t != 0.0){ hit.hit(t, this, matl, ray, n); } return hit; }
int SegRefineMouseProc::proc( HWND hwnd, int msg, int point, int flags, IPoint2 m ) { ViewExp *vpt = ip->GetViewport(hwnd); int res = TRUE; switch ( msg ) { case MOUSE_PROPCLICK: ip->SetStdCommandMode(CID_OBJMOVE); break; case MOUSE_POINT: if(HitTest(vpt,&m,HITTYPE_POINT,0) ) { HitLog &hits = vpt->GetSubObjHitList(); HitRecord *rec = hits.First(); HitRecord *bestRec = rec; DWORD best = rec->distance; while(rec) { rec = rec->Next(); if(rec) { if(rec->distance < best) { best = rec->distance; bestRec = rec; } } } ShapeHitData *hit = ((ShapeHitData *)bestRec->hitData); es->DoSegRefine(vpt, hit->shape, hit->poly, hit->index, m); } res = FALSE; break; case MOUSE_FREEMOVE: vpt->SnapPreview(m,m,NULL, SNAP_IN_3D); if ( HitTest(vpt,&m,HITTYPE_POINT,HIT_ABORTONHIT) ) { SetCursor(GetTransformCursor()); } else { SetCursor(LoadCursor(NULL,IDC_ARROW)); } break; } if ( vpt ) ip->ReleaseViewport(vpt); return res; }
int TrimMouseProc::proc( HWND hwnd, int msg, int point, int flags, IPoint2 m ) { ViewExp *vpt = ip->GetViewport(hwnd); int res = TRUE; // IntersectPt fromPt, toPt; BOOL extend = FALSE; switch ( msg ) { case MOUSE_PROPCLICK: ip->SetStdCommandMode(CID_OBJMOVE); break; case MOUSE_POINT: if(HitTest(vpt,&m,HITTYPE_POINT,0) ) { HitLog &hits = vpt->GetSubObjHitList(); HitRecord *rec = hits.First(); HitRecord *bestRec = rec; DWORD best = rec->distance; while(rec) { rec = rec->Next(); if(rec) { if(rec->distance < best) { best = rec->distance; bestRec = rec; } } } ShapeHitData *hit = ((ShapeHitData *)bestRec->hitData); es->HandleTrimExtend(vpt, hit, m, SHAPE_TRIM); } res = FALSE; break; case MOUSE_FREEMOVE: if ( HitTest(vpt,&m,HITTYPE_POINT,HIT_ABORTONHIT) ) { SetCursor(GetTransformCursor()); } else { SetCursor(LoadCursor(NULL,IDC_ARROW)); } break; } if ( vpt ) ip->ReleaseViewport(vpt); return res; }
cv::Vec3f BlinnMaterial::brdf(const HitRecord &hit, QVector3D direction) const { QVector3D normal = hit.getSurfaceNormal(); normal.normalize(); QVector3D wo = -hit.getRay().getDirection().normalized(); QVector3D wi = -direction.normalized(); if(signum(QVector3D::dotProduct(normal, wo)) != signum(QVector3D::dotProduct(normal, wi))) { return cv::Vec3f(); } if(QVector3D::dotProduct(normal, wo) < 0) normal *= -1; QVector3D wh = wi + wo; wh.normalize(); return kd * (1 / M_PI) + ks * D(wh, normal) * G(wi, wo, normal) / (4 * QVector3D::dotProduct(wo, normal) * QVector3D::dotProduct(wi, normal)); }
void Plane::intersect(HitRecord& hit, const RenderContext& rc, const Ray& ray)const{ //Vector p(ray.p().x(),ray.p().y(),ray.p().z()); //Vector o(point.x(),point.y(),point.z()); //float d = dot(o, norm); float num = dot(-norm, ray.p()-point); float denom = dot(norm, ray.d()); float t=num/denom; if(denom==0 || num==0 || t<0) hit.hit(std::numeric_limits<float>::infinity(), this, material); else hit.hit(num/denom, this, material); //float num = -(dot(norm,p)+d); //float denom = dot(norm, ray.d()); //if((denom==0 || num==0)) hit.hit(std::numeric_limits<float>::infinity(), this, material); //else hit.hit(num/denom, this, material); }
void Sphere::intersect(HitRecord& hit, const RenderContext& rc, const Ray& ray)const{ /*float a = dot(ray.d(), ray.d()); Vector v = ray.p()-p;/*Vector(ray.p().x(), ray.p().y(), ray.p().z());*/ /*float b = 2 * dot(ray.d(), v); float c = dot(v, v) - r2(); float disc = b * b - 4 * a * c; if (disc < 0.f){ hit.hit(std::numeric_limits<float>::infinity(), this, material); return; } float distSqrt = sqrtf(disc); float q; if (b < 0) q = (-b - distSqrt)/2.0f; else q = (-b + distSqrt)/2.0f; float t0 = q / a; float t1 = c / q; if (t0 > t1){ float temp = t0; t0 = t1; t1 = temp; } if (t1 < 0) hit.hit(std::numeric_limits<float>::infinity(), this, material); if (t0 < 0) hit.hit(t1, this, material); else hit.hit(t0, this, material);*/ Vector dist = ray.p() - p; float b = dot(dist, ray.d()); float c = dot(dist, dist) - r2(); float d = b*b - c; float t = d > 0 ? -b - sqrt(d) : std::numeric_limits<float>::infinity(); hit.hit(t, this, this->material); }
BOOL BindMouseProc::HitASegment(ViewExp *vpt, IPoint2 *p, BezierShape *shape, int poly, int vert, BezierShape **shapeOut, int *polyOut, int *vertOut) { int first = 1; SetSplineHitOverride(SS_SEGMENT); if(HitTest(vpt, p, HITTYPE_POINT, 0) ) { HitLog &hits = vpt->GetSubObjHitList(); HitRecord *rec = hits.First(); DWORD best = 9999; HitRecord *bestRec; while(rec) { ShapeHitData *hit = ((ShapeHitData *)rec->hitData); // If there's an exclusion shape, this must be a part of it! Spline3D *spline = hit->shape->splines[hit->poly]; int scount = spline->KnotCount()-1; if ((poly == hit->poly) && ((vert-1) == 0) && (hit->index == 0)) { } else if ((poly == hit->poly) && (vert == ((scount+1)*3-2)) && (hit->index == (scount-1))) { } else if(first || rec->distance < best) { first = 0; best = rec->distance; bestRec = rec; } rec = rec->Next(); } if(!first) { ShapeHitData *hit = ((ShapeHitData *)bestRec->hitData); if(shapeOut) *shapeOut = hit->shape; if(polyOut) *polyOut = hit->poly; if(vertOut) *vertOut = hit->index; ClearSplineHitOverride(); return TRUE; } } ClearSplineHitOverride(); return FALSE; }
cv::Vec3f AreaLight::getIntensity(const HitRecord & hit, QVector3D &direction, const Intersectable &scene, const Sample &sample) const { QVector3D at = hit.getIntersectingPoint().toVector3DAffine(); QPointF p = sample.getSample(); QVector3D lightLocation = getLocation(p); direction = at - lightLocation; HitRecord shadowHit = scene.intersect(Ray(at, -direction.normalized(), EPSILON, direction.length() - EPSILON)); if(shadowHit.intersects() && &shadowHit.getMaterial() != this) { return cv::Vec3f(); } else { return getIntensity(direction); } }
void Game::hitRacket(const Player* pPlayer, const Racket* pRacket, HitRecord& lhr, HitRecord& hr, bool& hit) { if (Calculator::hit(*m_pBall, *pRacket, *m_pField, lhr) == true) { hit = true; hr = lhr; float x = (hr.getHitPoint().getX() - pRacket->getPosition().getX()) / Racket::WIDTH; if (x > 0.5f) x = 0.5f; if (x < -0.5f) x = -0.5f; math::Normal2<float> norm = hr.getNormal(); const float coef = 1.0f; norm.setX(norm.getX() + (x * coef)); norm.normalize(); hr.setNormal(norm); setBallOwner(pPlayer); } }
bool Box::intersect(HitRecord& hit, const RenderContext& context, const Ray& ray) const { bool hasHit = false; float txMin, txMax, tymMin, tymMax, tzmMin, tzmMax; if (ray.d.x() >= 0) { txMin = (mMin.x() - ray.o.x()) / ray.d.x(); txMax = (mMax.x() - ray.o.x()) / ray.d.x(); } else { txMin = (mMax.x() - ray.o.x()) / ray.d.x(); txMax = (mMin.x() - ray.o.x()) / ray.d.x(); } if (ray.d.y() >= 0) { tymMin = (mMin.y() - ray.o.y()) / ray.d.y(); tymMax = (mMax.y() - ray.o.y()) / ray.d.y(); } else { tymMin = (mMax.y() - ray.o.y()) / ray.d.y(); tymMax = (mMin.y() - ray.o.y()) / ray.d.y(); } if ((txMin > tymMax) || (tymMin > txMax)) return false; if (tymMin > txMin) txMin = tymMin; if (tymMax < txMax) txMax = tymMax; if (ray.d.z() >= 0) { tzmMin = (mMin.z() - ray.o.z()) / ray.d.z(); tzmMax = (mMax.z() - ray.o.z()) / ray.d.z(); } else { tzmMin = (mMax.z() - ray.o.z()) / ray.d.z(); tzmMax = (mMin.z() - ray.o.z()) / ray.d.z(); } if ( (txMin > tzmMax) || (tzmMin > txMax) ) return false; if (tzmMin > txMin) txMin = tzmMin; if (tzmMax < txMax) txMax = tzmMax; hasHit = (hit.hit(txMin, this, material)) || hasHit; hasHit = (hit.hit(txMax, this, material)) || hasHit; return hasHit; }
HitRecord Scene::intersections(shared_ptr<Object> avoid, const Vector3f& p0, const Vector3f& d) { HitRecord hrTree; bool hitTree; // Check tree hitTree = bvhTree.intersection(avoid, p0, d, &hrTree); // Check planes float best = numeric_limits<float>::infinity(); float t; shared_ptr<Object> object; for (unsigned int i = 0; i < planes.size(); i++) { Vector4f pXForm = Vector4f(p0(0), p0(1), p0(2), 1); Vector4f dXForm = Vector4f(d(0), d(1), d(2), 0); Matrix4f inv = planes[i]->getInvXForm(); Vector4f modelpos = inv * pXForm; Vector4f modelray = inv * dXForm; float t = planes[i]->intersection(modelpos.head(3), modelray.head(3)); if ( t >= 0 && t < best && planes[i] != avoid ) { best = t; object = planes[i]; } } if (!hitTree && best < 0) { return HitRecord(-1.0, NULL); } else { if (!hitTree) { return HitRecord(best, object); } if (best < 0) { return hrTree; } return hrTree.getT() < best ? hrTree : HitRecord(best, object); } }
BOOL VertConnectMouseProc::HitAnEndpoint(ViewExp *vpt, IPoint2 *p, BezierShape *shape, int poly, int vert, BezierShape **shapeOut, int *polyOut, int *vertOut) { int first = 1; if(HitTest(vpt, p, HITTYPE_POINT, 0) ) { HitLog &hits = vpt->GetSubObjHitList(); HitRecord *rec = hits.First(); DWORD best = 9999; HitRecord *bestRec; while(rec) { ShapeHitData *hit = ((ShapeHitData *)rec->hitData); // If there's an exclusion shape, this must be a part of it! if(!shape || shape == hit->shape) { // If there's an exclusion shape, the vert & poly can't be the same! if(!shape || (shape && !(poly == hit->poly && vert == hit->index))) { Spline3D *spline = hit->shape->splines[hit->poly]; if(!spline->Closed()) { int hitKnot = hit->index / 3; if(hitKnot == 0 || hitKnot == (spline->KnotCount() - 1)) { if(first || rec->distance < best) { first = 0; best = rec->distance; bestRec = rec; } } } } } rec = rec->Next(); } if(!first) { ShapeHitData *hit = ((ShapeHitData *)bestRec->hitData); if(shapeOut) *shapeOut = hit->shape; if(polyOut) *polyOut = hit->poly; if(vertOut) *vertOut = hit->index; return TRUE; } } return FALSE; }
int CrossInsertMouseProc::proc( HWND hwnd, int msg, int point, int flags, IPoint2 m ) { ViewExp *vpt = ip->GetViewport(hwnd); int res = TRUE; switch ( msg ) { case MOUSE_PROPCLICK: ip->SetStdCommandMode(CID_OBJMOVE); break; case MOUSE_POINT: if(HitTest(vpt,&m,HITTYPE_POINT,0) ) { HitLog &hits = vpt->GetSubObjHitList(); HitRecord *rec = hits.First(); ShapeHitData *h1 = (ShapeHitData *)rec->hitData; rec = rec->Next(); assert(rec); ShapeHitData *h2 = (ShapeHitData *)rec->hitData; assert(h1->shape == h2->shape); es->DoCrossInsert(vpt, h1->shape, h1->poly, h1->index, h2->poly, h2->index, m); } res = FALSE; break; case MOUSE_FREEMOVE: if ( HitTest(vpt,&m,HITTYPE_POINT,0) ) { SetCursor(GetTransformCursor()); } else { SetCursor(LoadCursor(NULL,IDC_ARROW)); } break; } if ( vpt ) ip->ReleaseViewport(vpt); return res; }
BOOL CreateLineMouseProc::InsertWhere(ViewExp *vpt, IPoint2 *p, BezierShape **shapeOut, int *polyOut, int *segOut, int *vertOut) { int first = 1; // Reset these! *segOut = -1; *vertOut = -1; // Only valid insertion vertices are endpoints of the spline if(HitTest(vpt, p, HITTYPE_POINT, 0, ES_VERTEX) ) { HitLog &hits = vpt->GetSubObjHitList(); HitRecord *rec = hits.First(); DWORD best = 9999; HitRecord *bestRec; while(rec) { ShapeHitData *hit = ((ShapeHitData *)rec->hitData); int hitKnot = hit->index / 3; Spline3D *spline = hit->shape->splines[hit->poly]; if(!spline->Closed() && (hitKnot == 0 || hitKnot == (spline->KnotCount() - 1))) { if(first || rec->distance < best) { first = 0; best = rec->distance; bestRec = rec; } } rec = rec->Next(); } if(!first) { ShapeHitData *hit = ((ShapeHitData *)bestRec->hitData); if(shapeOut) *shapeOut = hit->shape; if(polyOut) *polyOut = hit->poly; if(vertOut) *vertOut = hit->index; return TRUE; } } return FALSE; }
BOOL CrossInsertMouseProc::HitTest( ViewExp *vpt, IPoint2 *p, int type, int flags ) { vpt->ClearSubObjHitList(); SetSplineHitOverride(SS_SPLINE); ip->SubObHitTest(ip->GetTime(),type,ip->GetCrossing(),flags,p,vpt); ClearSplineHitOverride(); // Make sure that there are exactly two hits and they are on different polygons of // the same shape if ( vpt->NumSubObjHits() == 2 ) { HitLog &hits = vpt->GetSubObjHitList(); HitRecord *rec = hits.First(); ShapeHitData *h1 = (ShapeHitData *)rec->hitData; rec = rec->Next(); assert(rec); ShapeHitData *h2 = (ShapeHitData *)rec->hitData; if((h1->shape == h2->shape) && (h1->poly != h2->poly)) return TRUE; } return FALSE; }
void IntersectionUI::drawHits(HitRecord& hr) { double t, u, v; Point3 p; Vector3 n; glDisable(GL_LIGHTING); while (hr.getFirstHit(t, u, v, p, n)) { glPointSize(8.0f); glLineWidth(6.0f); glColor3f(1.0f, 0.0f, 0.0f); glBegin(GL_POINTS); glVertex3d(p[0], p[1], p[2]); glEnd(); glColor3f(0.2f, 0.2f, 0.2f); glBegin(GL_LINES); glVertex3d(p[0], p[1], p[2]); glVertex3d(p[0] + 0.5 * n[0], p[1] + 0.5 * n[1], p[2] + 0.5 * n[2]); glEnd(); glLineWidth(1.0f); glPointSize(1.0f); hr.removeFirstHit(); } }
QVector3D BlinnMaterial::outDirection(const HitRecord &hit, Sample s, float &pdf, cv::Vec3f &brdf) const { QVector3D normal = hit.getSurfaceNormal(); normal.normalize(); QVector3D wo = -hit.getRay().getDirection().normalized(); if(QVector3D::dotProduct(normal, wo) < 0) normal *= -1; QVector3D wh = s.getCosinePowerWeightedDirection(normal, pdf, exponent); if(QVector3D::dotProduct(wo, wh) < 0) { pdf = 0; brdf = cv::Vec3f(); return QVector3D(); } //if(QVector3D::dotProduct(wh, normal) < 0) wh *= -1; QVector3D out = -reflect(wo, wh); assert(pdf >= 0); pdf /= 4 * std::max(QVector3D::dotProduct(wo, wh), .0001f); assert(pdf >= 0); brdf = this->brdf(hit, out); assert(brdf[0] >= 0 && brdf[1] >= 0 && brdf[2] >= 0); return out; }
HitRecord* PasteTangentMouseProc::HitTest( ViewExp *vpt, IPoint2 *p, int type, int flags ) { HitRecord *bestRec = NULL; vpt->ClearSubObjHitList(); SetSplineHitOverride(SS_VERTEX); ip->SubObHitTest(ip->GetTime(),type,ip->GetCrossing(),flags,p,vpt); ClearSplineHitOverride(); if ( vpt->NumSubObjHits() ) { HitLog &hits = vpt->GetSubObjHitList(); DWORD best; for (HitRecord *rec = hits.First(); rec != NULL; rec = rec->Next()) { ShapeHitData *hit = ((ShapeHitData *)rec->hitData); if ((hit->index % 3) == 1) continue; if(bestRec == NULL || rec->distance < best) { best = rec->distance; bestRec = rec; } } } return bestRec; }
bool Sphere::intersect(HitRecord& hit, const RenderContext& context, const Ray& ray) const { Vector o_minus_c = ray.o - mCenter; double a = dot(ray.d, ray.d); double b = 2.0 * dot(ray.d, o_minus_c); double c = dot(o_minus_c, o_minus_c) - (mRadius2); double disc = b*b - 4.0*a*c; //Does it intersect? if (disc > 0) { disc = sqrt(disc); double t = (-b - disc) / (2.0*a); //Early termination if (hit.hit(t, this, material)) return true; t = ( -b + disc) / (2.0*a); return (hit.hit(t, this, material)); } return false; }
void EditFaceDataMod::SelectSubComponent (HitRecord *hitRec, BOOL selected, BOOL all, BOOL invert) { EditFaceDataModData *d = NULL, *od = NULL; ModContextList mcList; INodeTab nodes; ip->GetModContexts(mcList,nodes); BitArray nsel; for (int nd=0; nd<mcList.Count(); nd++) { d = (EditFaceDataModData*) mcList[nd]->localData; if (d==NULL) continue; HitRecord *hr = hitRec; if (!all && (hr->modContext->localData != d)) continue; for (; hr!=NULL; hr=hr->Next()) if (hr->modContext->localData == d) break; if (hr==NULL) continue; Mesh *mesh = d->GetCacheMesh(); MNMesh *mnmesh = d->GetCacheMNMesh(); if (!mesh && !mnmesh) continue; if (theHold.Holding() && !d->GetHeld()) theHold.Put (new SelectRestore (this, d)); switch (selLevel) { case SEL_FACE: nsel = d->GetFaceSel(); for (; hr != NULL; hr=hr->Next()) { if (d != hr->modContext->localData) continue; nsel.Set (hr->hitInfo, invert ? !d->GetFaceSel()[hr->hitInfo] : selected); if (!all) break; } d->GetFaceSel() = nsel; break; } } nodes.DisposeTemporary (); SelectionChanged (); }
Color PhongMaterial::shade(const RenderContext& rc, const Ray& ray, const HitRecord& hrec, int depth) const{ Scene* scene = (Scene*)rc.getScene(); Point hp = ((Ray&)ray).pointOn(((HitRecord&)hrec).GetT()); Vector normal = ((HitRecord&)hrec).GetPrimitive()->normal(hp); Vector v = scene->get_camera()->getEye() - hp; v.normalize(); hp += 0.0001f * normal; int numlights = scene->num_lights(); Color finalc(0.f,0.f,0.f); for(int i=0; i<numlights; i++){ Vector ldir; Color lcolor; float ldist = scene->get_light(i)->getLight(lcolor, ldir, rc, hp); HitRecord shadowhr; Ray shadowray(hp, ldir); scene->get_object()->intersect(shadowhr, rc, shadowray); if((shadowhr.GetT()>=ldist || shadowhr.GetT()<0.01)){ float dp = dot(normal, ldir) * kd; if(!(dp > 0)) dp = 0; Vector r = 2*(dot(ldir, normal))*normal - ldir; r.normalize(); float spec = dot(r, v); if(!(spec > 0)) spec = 0; else spec = pow(spec,n); finalc += (dp*kd+spec*ks)*lcolor; } } return color*(finalc + scene->get_ambient()*ka); }
bool Disk::hit(HitRecord& record, const RenderContext& context, const Ray& ray) const { bool hasHit = false; float t = dot(-normal, ray.origin() - center)/dot(normal, ray.direction()); Point temp_point = ray.point(t); Vector D = temp_point - center; if(dot(D, D) < (radius*radius)) { hasHit = record.hit(t, this, ray); } return hasHit; }
Path Renderer::createPath(const Ray& primaryRay, const Intersectable &scene, const Sample pathSamples[], cv::Vec3f alpha, int pathLength, float russianRoulettePdf, int russianRouletteStartIndex) { Path result; HitRecord hit = scene.intersect(primaryRay); for(int i = 0; i < pathLength; i++) { if(!hit.intersects()) return result; float pdf; cv::Vec3f brdf; QVector3D outDirection = hit.getMaterial().outDirection(hit, pathSamples[i], pdf, brdf); if(hit.getMaterial().emitsLight()) { result.alphaValues.push_back(alpha); result.hitRecords.push_back(hit); return result; } else if(hit.getMaterial().isSpecular()) { //Try not to terminate on refractive vertices if(i == pathLength - 1 && pathLength < MAX_DEPTH) pathLength++; } else { result.alphaValues.push_back(alpha); result.hitRecords.push_back(hit); if(pdf == 0 || alpha == cv::Vec3f()) return result; float cos = fabs(QVector3D::dotProduct(outDirection.normalized(), hit.getSurfaceNormal().normalized())); assert(cos >= 0 && !isnan(pdf)); assert(pdf > 0 && !isnan(pdf)); alpha = alpha.mul(brdf) * (cos / pdf); if(i > russianRouletteStartIndex) alpha *= (1 / russianRoulettePdf); } hit = scene.intersect(Ray(hit.getIntersectingPoint(), outDirection)); } return result; }
cv::Vec3f AreaLight::emission(const HitRecord & hit) const { assert(&hit.getMaterial() == this); return getIntensity(-hit.getRay().getDirection()); }
void Game::setBallPosition(const HitRecord& hr) { m_pBall->position() = hr.getNewPosition(); Calculator::bounce(*m_pBall, hr.getNormal()); Calculator::move(*m_pBall, hr.getRollback() + 0.1f); }
void Game::tick() { ballMove(); forceRacketIntoField(); while (true) { bool hit = false; Brick* pBrickRef = nullptr; HitRecord hr; HitRecord lhr; if (hitTopField(lhr) == true && lhr.getRollback() > hr.getRollback()) { hit = true; hr = lhr; } if (hitRightField(lhr) == true && lhr.getRollback() > hr.getRollback()) { hit = true; hr = lhr; } //Bottom border if (hitBottomField(lhr) == true && lhr.getRollback() > hr.getRollback()) { setBallOwner(); ballExit(); hr = lhr; break; } if (hitLeftField(lhr) && lhr.getRollback() > hr.getRollback()) { hit = true; hr = lhr; } hitRacket(lhr, hr, hit); pBrickRef = hitBrick(lhr, hr, hit); if (hit) { setBallPosition(hr); if (pBrickRef != nullptr) { pBrickRef->strength()--; incrementScore(); if (pBrickRef->strength() == 0) { removeBrick(pBrickRef); } } } else { break; } } }