bool Sphere::intersect(const Ray &r, Hit &h, float tmin)
{
	//直线方程 P = t*D + R    ①
	//圆方程  ||P||= raduis   ②
	//将①带入②, 由点乘的性质(满足分配率,交换律),求得t^2+2RDt+R^2-r^2=0
	//得t = -RD±sqrt(RD^2-R^2+r^2)
	//选择距离较近的那个点t = -RD-sqrt(RD^2-R^2+r^2)
	Vec3f D = r.getDirection();
	Vec3f R = r.getOrigin()-center;


	float R2 = R.Dot3(R);
	float RD = R.Dot3(D);
	
	float b2_4ac = RD*RD-R2+radius*radius;//R2 RD RDRD这些其实可以存在ray里,但是算法研究以程序清晰为要
	if(b2_4ac<0)return 0;
	float t;
	t = -RD - sqrt(b2_4ac);
	if(t<0){
		t = -RD + sqrt(b2_4ac);
		if(t < 0)return 0;
	}
	if(t<h.getT())
	{
		h.set(t, &color, r);
	}

	return 1;
}
bool Face::plane_intersect(const Ray &r, Hit &h, bool intersect_backfacing) const {

  // insert the explicit equation for the ray into the implicit equation of the plane

  // equation for a plane
  // ax + by + cz = d;
  // normal . p + direction = 0
  // plug in ray
  // origin + direction * t = p(t)
  // origin . normal + t * direction . normal = d;
  // t = d - origin.normal / direction.normal;

  glm::vec3 normal = computeNormal();
  float d = glm::dot(normal,(*this)[0]->get());

  float numer = d - glm::dot(r.getOrigin(),normal);
  float denom = glm::dot(r.getDirection(),normal);

  if (denom == 0) return 0;  // parallel to plane

  if (!intersect_backfacing && glm::dot(normal,r.getDirection()) >= 0) 
    return 0; // hit the backside

  float t = numer / denom;
  if (t > EPSILON && t < h.getT()) {
    h.set(t,this->getMaterial(),normal);
    assert (h.getT() >= EPSILON);
    return 1;
  }
  return 0;
}
Example #3
0
/*
The intersect routine will first transform the ray, 
then delegate to the intersect routine of the contained 
object. Make sure to correctly transform the resulting 
normal according to the rule seen in lecture. You may 
choose to normalize the direction of the transformed ray 
or leave it un-normalized. If you decide not to normalize 
the direction, you might need to update some of your intersection code.
*/
bool Transform::intersect(const Ray &r, Hit &h, float tmin)
{
	Vec3f r0 = r.getOrigin();
	Vec3f rd = r.getDirection();
	Matrix inv;
	matrix.Inverse(inv);
	inv.Transform(r0);
	inv.TransformDirection(rd);
	if (object != NULL)
	{
		//这里的h是有问题的,作如下修改:
		bool judge = object->intersect(Ray(r0,rd), h, tmin);
		Vec3f normal = h.getNormal();
		//这里很奇怪,normal的方向没有修正,然而结果却是对的
		//改了之后反而是错的!!
		//这里确定normal没有错,那么就是之后应用normal的
		//问题
		//好吧,就是这里的问题
		//经过把图形摆正,发现求的法向量没有问题,但是没有单位化…………!
		matrix.TransformDirection(normal);
		normal.Normalize();
		//or:
		//Matrix change,res;
		//matrix.Inverse(change);
		//change.Transpose(res);
		//res.TransformDirection(normal);
		h.set(h.getT(), h.getMaterial(), normal, r);
		return judge;
	}
	return false;
}
Example #4
0
void coTouchIntersection::intersect(const osg::Matrix &handMat, bool mouseHit)
{

    cerr << "coTouchIntersection::intersect info: called" << endl;

    Vec3 q0, q1, q2, q3, q4, q5;

    // 3 line segments for interscetion test hand-object
    // of course this test can fail
    q0.set(0.0f, -0.5f * handSize, 0.0f);
    q1.set(0.0f, 0.5f * handSize, 0.0f);
    q2.set(-0.5f * handSize, 0.0f, 0.0f);
    q3.set(0.5f * handSize, 0.0f, 0.0f);
    q4.set(0.0f, 0.0f, -0.5f * handSize);
    q5.set(0.0f, 0.0f, 0.5f * handSize);

    // xform the intersection line segment
    q0 = handMat.preMult(q0);
    q1 = handMat.preMult(q1);
    q2 = handMat.preMult(q2);
    q3 = handMat.preMult(q3);
    q4 = handMat.preMult(q4);
    q5 = handMat.preMult(q5);

    ref_ptr<LineSegment> ray1 = new LineSegment();
    ref_ptr<LineSegment> ray2 = new LineSegment();
    ref_ptr<LineSegment> ray3 = new LineSegment();
    ray1->set(q0, q1);
    ray2->set(q2, q3);
    ray3->set(q4, q5);

    IntersectVisitor visitor;
    visitor.addLineSegment(ray1.get());
    visitor.addLineSegment(ray2.get());
    visitor.addLineSegment(ray3.get());

    cover->getScene()->traverse(visitor);

    ref_ptr<LineSegment> hitRay = 0;

    if (visitor.getNumHits(ray1.get()))
        hitRay = ray1;
    else if (visitor.getNumHits(ray2.get()))
        hitRay = ray2;
    else if (visitor.getNumHits(ray3.get()))
        hitRay = ray3;

    if (visitor.getNumHits(hitRay.get()))
    {
        Hit hitInformation = visitor.getHitList(hitRay.get()).front();
        cover->intersectionHitPointWorld = hitInformation.getWorldIntersectPoint();
        cover->intersectionHitPointLocal = hitInformation.getLocalIntersectPoint();
        cover->intersectionMatrix = hitInformation._matrix;
        cover->intersectedNode = hitInformation._geode;
        // walk up to the root and call all coActions
        OSGVruiHit hit(hitInformation, mouseHit);
        OSGVruiNode node(cover->intersectedNode.get());
        callActions(&node, &hit);
    }
}
Example #5
0
RGBColor Matte::shade(Hit& h){
	msgfx::Vector3f wo = -h.ray.Direction();
	RGBColor L = _ambientBRDF->rho(h, wo) * h.scenePtr->ambientLight;
	int numLights = h.scenePtr->myNumberOfLights;
	msgfx::Vector3f wi;

	for(int i = 0; i < numLights; ++i)
	{
		wi = h.scenePtr->myLights[i]->Position() - h.Position();
		float d = wi.length();
		wi.normalize();
		float ndotwi = h.normal.dot(wi);

		if(ndotwi > 0.0){
			// Calculate attenuation factor
			if(h.scenePtr->isPointVisibleToLight(h.Position(), h.scenePtr->myLights[i]))
			{
				float attenuation = 1 / (d*d*h.scenePtr->myLights[i]->Attenuation().r + d*h.scenePtr->myLights[i]->Attenuation().g + h.scenePtr->myLights[i]->Attenuation().b);
				L = L + _diffuseBRDF->f(h, wo, wi) * h.scenePtr->myLights[i]->Color() * ndotwi * attenuation;
			}
		}
			
	}
	
	return L;
}
Example #6
0
// does the recursive (shadow rays & recursive/glossy rays) work
Vec3f RayTracer::TraceRay(const Ray &ray, Hit &hit, int bounce_count) const
{
        hit = Hit();
        bool intersect = CastRay(ray,hit,false);

        Vec3f answer(args->background_color_linear);

        if (intersect == true) {
                const Material *m = hit.getMaterial();
                assert (m != NULL);

                // rays coming from the light source are set to white, don't bother to ray trace further.
                if (m->getEmittedColor().Length() > 0.001) {
                        answer = Vec3f(1,1,1);
                } else {
                        // ambient light
                        answer = args->ambient_light_linear *
                                 m->getDiffuseColor(hit.get_s(),hit.get_t());

                        // Shadows
                        answer += shadows(ray, hit);

                        // Reflections
                        Vec3f reflectiveColor = m->getReflectiveColor();
                        double roughness = m->getRoughness();
                        if (bounce_count > 0 && reflectiveColor.Length() > MIN_COLOR_LEN) {
                        	answer += reflectiveColor * reflections(ray, hit, bounce_count, roughness);
                        }
                }
        }

        return answer;
}
Example #7
0
bool Face::plane_intersect(const Ray &r, Hit &h, bool intersect_backfacing, bool* backfacing_hit) {

	// insert the explicit equation for the ray into the implicit equation of the plane

	// equation for a plane
	// ax + by + cz = d;
	// normal . p + direction = 0
	// plug in ray
	// origin + direction * t = p(t)
	// origin . normal + t * direction . normal = d;
	// t = d - origin.normal / direction.normal;

	Vec3f normal = computeNormal();
	double d = normal.Dot3((*this)[0]->get());

	double numer = d - r.getOrigin().Dot3(normal);
	double denom = r.getDirection().Dot3(normal);

	if (denom == 0) return 0;	// parallel to plane

	if (!intersect_backfacing && normal.Dot3(r.getDirection()) >= 0) 
		return 0; // hit the backside

	double t = numer / denom;
	if (t > EPSILON && t < h.getT()) {
		h.set(t,this->getMaterial(),normal,this);
		assert (h.getT() >= EPSILON);
		//hit the backside but that's okay in this case
		if (normal.Dot3(r.getDirection()) >= 0){
			*backfacing_hit = true;
		}
		return 1;
	}
	return 0;
}
Example #8
0
Vec3f find_color(Ray ray,Hit hit,Group* group,Camera* camera)
{
	int num_lights = sceneParser->getNumLights();
	Vec3f cambient = sceneParser->getAmbientLight();
	if (group->intersect(ray, hit, camera->getTMin()))//撞到了
	{
		Vec3f cobject = hit.getMaterial()->getDiffuseColor();
		Vec3f canswer = cambient * cobject;
		Vec3f clight;
		Vec3f light_dir;
		Vec3f normal_dir = hit.getNormal();
		float distolight;
		for (int i = 0; i < num_lights; i++)
		{
			Light *light = sceneParser->getLight(i);
			//light_dir : the direction to the light
			// 该方法用于获得指向光的方向,光的颜色,和到达光的距离
			light->getIllumination(hit.getIntersectionPoint(), light_dir, clight, distolight);
			//cpixel  =  cambient * cobject + SUMi [ clamped(Li . N) * clighti * cobject ]
			//返回局部光
			canswer = canswer + hit.getMaterial()->Shade(ray, hit, light_dir, clight)*cobject;
			canswer.Clamp();
		}
		return canswer;
	}
	else
		return sceneParser->getBackgroundColor();
}
Example #9
0
bool Sphere::intersect(const Ray &r, Hit &h, float tmin)
{
	Vec3f v = center - r.getOrigin();
	float tp = v.Dot3(r.getDirection());
	float det = tp*tp - v.Dot3(v) + radius*radius;
	//intersect
	if(det > 0)
	{
		//t'
		det = sqrtf(det); 

		float t1 = tp - det;
		float t2 = tp + det;

		if(t1 > tmin && t1 < h.getT())
		{
			Vec3f normal = (r.pointAtParameter(t1) - center);
			normal /= radius;
			normal.Normalize();
			h.set(t1,material,normal,r);
			return 1;
		}
		else if(t2 > tmin && t2 < h.getT())
		{
			//sphere's normal
			Vec3f normal = (r.pointAtParameter(t2) - center);
			normal /= radius;
			normal.Normalize();
			h.set(t2,material,normal,r);
			return 1;
		}
	}
	return 0;
}
Example #10
0
bool Transform::Intersect(const Ray &r, Hit &h, float tmin) const
{
  bool result = false;
  
  Matrix m = m_matrix;
  if ( m.Inverse() )
    {
      Vec3f org = r.getOrigin();
      Vec3f dir = r.getDirection();
      m.Transform(org);
      m.TransformDirection(dir);
      Ray r2 (dir, org);
      result = m_pObject->Intersect(r2, h, tmin);
      
      if (result)
	{
	  Matrix m1 = m;
	  m1.Transpose();
	  Vec3f n = h.getNormal();
	  m1.TransformDirection(n);
	  n.Normalize();
	  h.set(h.getT(), h.getMaterial(), n, r);
	}
    }
  return result;
}
Example #11
0
bool Plane::intersect(const Ray & r, Hit & h, float tmin)
{
	assert (tmin >= 0.0f);

	Vec3f org = r.getOrigin();
	Vec3f dir = r.getDirection();

	if (dir.Dot3(normal) < 1.0e-7 && dir.Dot3(normal) > -1.0e-7) {
		return false;
	}					// Appromately parrell to plane

	float tempT = (offset - org.Dot3(normal)) / dir.Dot3(normal);
	if (tempT <= 1e-6) {
		return false;
	}
	else if (tempT >= tmin && tempT < h.getT()) 
	{
		// Update Hit Point
		normal.Normalize();
		h.set(tempT, NULL, normal, color, r);

		return true;
	}
	
	return false;
}
Example #12
0
boolean StandardPicker::pick(Canvas* c, Glyph* glyph, int depth, Hit& h) {
	if (!h.event()) {
		return false;
	}
	const Event& e = *h.event();
	if (e.grabber()) {
		h.target(depth, glyph, 0, e.grabber());
		return true;
	}
	event(e);
	
	long cnt = handlers_[ms_]->count();
	for (long i=0; i < cnt; ++i) {
		ButtonHandler& b = *handlers_[ms_]->item(i);
		if (b.eb_ == Event::any || b.eb_ == mb_) {
			if (b.handler_) {
				h.target(depth, glyph, 0, b.handler_);
			}else{
				b.rband_->canvas(c);
				h.target(depth, glyph, 0, b.rband_);
			}
			return true;
		}
	}
	return false;
}
Example #13
0
bool compare_rows(const Hit& lhs, const Hit& rhs){
	
	if(lhs.get_row() < rhs.get_row())
		return true;
	else{
		return false;
	}
}
Example #14
0
void Space::pick(Canvas*, const Allocation& a, int depth, Hit& h) {
    Coord x = h.left();
    Coord left = a.left();
    Coord right = a.right();
    if (x >= left && x < right) {
        h.target(depth, this, (x > (left+right)/2) ? 1 : 0);
    }
}
Example #15
0
bool Transform::intersect(const Ray& r, Hit& h, float tmin)
{

	bool b = o->intersect(Ray((mInverse*Vector4f(r.getOrigin(),1)).xyz(), mInverse3*r.getDirection()), h, tmin);
	if (b) { h.setNormal((mInverseT3*(h.getNormal())).normalized()); }
	return b;

}
Example #16
0
Color Scene::lanceRayon(const Rayon& ray, int iteration) const
{
    this->addObjectsTabToBinder();
    Color result(0.0,0.0,0.0);
    float minDist(1000.0) ;
    float dist (0.0) ;
    Hit hit ;

    if (binder->intersect(ray,0.0,100.0,hit))
    {
        //result = hit.getObject()->getOptic()->getColor(hit.getU(),hit.getV());
        //result = hit.getObject()->getOptic()->getColor(0.5,0.5);


    Color coulObj(hit.getObject()->getOptic()->getColor(hit.getU(),hit.getV()));
    for ( std::vector<std::shared_ptr<LightSource>>::const_iterator it = lightsTab.begin(); it != lightsTab.end() ; ++it)
   // pour chaque source
    {

        //d = calcul distance point intersection source
        Vector directi(it->get()->getOrigin()-hit.getImpactPoint());
        float distInterSource = directi.getNorm() ;
        directi.normalize();
        //initialiser Ray : point intersect, direction(point intersect, source), couleur = on s'en fout
        Color c(0.0,0.0,0.0);
        Color resultNorm(0.0,0.0,0.0);
        Rayon ray(hit.getImpactPoint(),directi,c);

        if (! binder->intersect(ray, 0, distInterSource))
        {
            Color diff(it->get()->getColor()*coulObj*(dotProduct(hit.getNormal(),ray.getDirect())));
            Vector moinsV(-directi.getX(),-directi.getY(),-directi.getZ());
            Vector miroirV(moinsV + hit.getNormal()*(2*(dotProduct(directi,hit.getNormal()))));
            //Vmir = V symétrique par rapport à N
            //spec = coulspec(obj)* (tronquerAZero(RayS.Vmir))^n * coul(source)
            Color spec(it->get()->getColor()*coulObj*dotProduct(ray.getDirect(),miroirV));
             resultNorm = diff + spec ;
             if ( iteration < 2)
             {
               //Res2 = influence rayon réfléchi
                Rayon reflected(hit.getImpactPoint(),miroirV,c);
                Color reflectedColor(0.0,0.0,0.0);
                reflectedColor = this->lanceRayon(reflected,iteration+1);
                //return pourcent1*Res + ourcent2*Res2
                result = resultNorm*0.8 + reflectedColor*0.2 ;
             }
             else
             {
                 result = resultNorm ;
             }

        }

    }
    }
    return result;
}
Example #17
0
float Cylindre::quantityIntersected(const qglviewer::Vec& _depart, const qglviewer::Vec& _arrivee, float _light_radius) const
{
	// On va construire un cylindre de taille br=br+rlr/2, tr = tr+rlr/2, h = h +rlr/2
	// on va créer un rayon d'origine depart et de direction arrivee - depart 
	// et vérifier si ce rayon intersecte les cylindres
	float penombre;


	Cylindre cylindre_penombre;
	cylindre_penombre.setTopRadius(topradius()+_light_radius/2);
	cylindre_penombre.setBottomRadius(bottomradius()+_light_radius/2);
	cylindre_penombre.setHeight(height()+_light_radius/2);
	
	Disque* disque_top = new Disque(cylindre_penombre.topradius());
	Disque* disque_bottom = new Disque(cylindre_penombre.bottomradius());

	disque_bottom->setMaterial(cylindre_penombre.material());
	disque_top->setMaterial(cylindre_penombre.material());

	Frame* frame_topdisque = new Frame();
	*frame_topdisque = cylindre_penombre.frame();
	frame_topdisque->setPosition(frame_topdisque->position()+Vec(0.0,0.0,cylindre_penombre.height()));
	disque_top->setFrame(*frame_topdisque);
	disque_bottom->setFrame(frame());	

	
	cylindre_penombre.setBottomDisque(disque_bottom);
	cylindre_penombre.setTopDisque(disque_top);

	Ray ray;
	Vec dir = (_arrivee-_depart);
	dir = dir / (dir.norm());
	ray.setStart(_depart);
	ray.setDirection(dir);

	Hit hit;

	if (this->intersect(ray,hit))
	{
		penombre = 1;
	}
	else
	{
		if (cylindre_penombre.intersect(ray,hit))
		{
			Vec I = hit.intersection();
			I = cylindre_penombre.frame().coordinatesOf(I);
			penombre = I.z/cylindre_penombre.height();		
		}
		else
		{			
			penombre = 0;
		}
	}

	return penombre;
}
void PhotonMapping::TracePhoton(const Vec3f &position, const Vec3f &direction, 
				const Vec3f &energy, int iter) {
  
  if(iter>args->num_bounces){
    return;
  }

  Hit h = Hit();
  Ray R = Ray(position, direction);
  bool intersect = raytracer->CastRay(R, h, false);
  if(!intersect){
    return;
  }
  Material *m = h.getMaterial();
  Vec3f normal = h.getNormal();
  Vec3f point = R.pointAtParameter(h.getT());
  Vec3f opDirec = direction;
  opDirec.Negate();
  opDirec.Normalize();
  Vec3f diffuse = m->getDiffuseColor(), reflec = m->getReflectiveColor();
  double diffuseAnswer = diffuse.x()+diffuse.y()+diffuse.z();
  double reflecAnswer = reflec.x()+reflec.y()+reflec.z();
  double total = reflecAnswer+diffuseAnswer;
  diffuseAnswer /= total;
  reflecAnswer /= total;
  double seed = GLOBAL_mtrand.rand();
  if(seed <= diffuseAnswer && seed >= 0){
    Vec3f newEnergy = energy * diffuse;
    Vec3f newPosition = point;
    Vec3f newDirection = Vec3f(GLOBAL_mtrand.rand(),GLOBAL_mtrand.rand(),GLOBAL_mtrand.rand());
    newDirection.Normalize();
    Photon answer = Photon(point,opDirec,newEnergy,iter+1);
    kdtree->AddPhoton(answer);
    TracePhoton(newPosition, newDirection, newEnergy, iter+1);
  }
  else if(seed>diffuseAnswer && seed <= 1){
    Vec3f newEnergy = energy * reflec;
    Vec3f newPosition = point;
    Vec3f newDirection = direction - 2 * direction.Dot3(normal) * normal;
    Photon answer = Photon(point,opDirec,newEnergy,iter+1);
    kdtree->AddPhoton(answer);
    TracePhoton(newPosition, newDirection, newEnergy, iter+1);
  }
  // ==============================================
  // ASSIGNMENT: IMPLEMENT RECURSIVE PHOTON TRACING
  // ==============================================

  // Trace the photon through the scene.  At each diffuse or
  // reflective bounce, store the photon in the kd tree.

  // One optimization is to *not* store the first bounce, since that
  // direct light can be efficiently computed using classic ray
  // tracing.



}
Example #19
0
void Deck::pick(Canvas* c, const Allocation& a, int depth, Hit& h) {
    if (card_ >= 0 && card_ < count()) {
	Glyph* g = component(card_);
        if (g != nil) {
	    h.begin(depth, this, card_);
	    g->pick(c, a, depth + 1, h);
	    h.end();
        }
    }
}
Example #20
0
void GlyphViewer::pick(Canvas* c, const Allocation& a, int depth, Hit& h) {
    const Event* e = h.event();
    if (e->control_is_down()) {
        InputHandler::pick(c, a, depth, h);
    } else if (e->type() == Event::down) {
        h.begin(depth, this, 0, _grabber);
        MonoGlyph::pick(c, a, depth, h);
        h.end();
    }
}
Example #21
0
void Clusters::matchWithEventIDs(Hits * eventIDs) {   
   Float_t     minDist = 1e5; // pixels
   Float_t     thisDist = 0;
   Cluster   * thisCluster = nullptr;
   Hit       * thisHit = nullptr;
   Int_t       layer = -1;
   Int_t       minIdx = -1;
   Bool_t      doLoop = true;
   Int_t       cWithoutEventID = 0;
   Float_t     cX, cY;
   Int_t       nClusters = GetEntries();
   Int_t       nHits = eventIDs->GetEntriesFast();

   for (Int_t c=0; c<GetEntriesFast(); c++) {
      thisCluster = At(c);
      if (!thisCluster) continue;

      layer = thisCluster->getLayer();

      cX = thisCluster->getX();
      cY = thisCluster->getY();

      minDist = 1e5;
      minIdx = -1;

      for (Int_t h=0; h<eventIDs->GetEntriesFast(); h++) {
         thisHit = eventIDs->At(h);
         
         if (!thisHit) continue;
         if (thisHit->getLayer() != layer) continue;

         if (fabs(cX - thisHit->getX()) < 10) {
            if (fabs(cY - thisHit->getY()) < 10) {
               thisDist = diffXY(thisCluster, thisHit);
               if (thisDist < minDist) {
                  minDist = thisDist;
                  minIdx = h;
               }
            }
         }
      }

      if (minIdx >= 0 && minDist < 10) {
         thisCluster->setEventID(eventIDs->getEventID(minIdx));
         eventIDs->removeHitAt(minIdx);
      }
   }

   for (Int_t c=0; c<GetEntriesFast(); c++) {
      if (!At(c)) continue;
      if (getEventID(c) < 0) cWithoutEventID++;
   }

// cout << "Number of clusters without eventID: " << cWithoutEventID << " (" << (float) cWithoutEventID / nClusters * 100 << "%)" << endl;
}
Example #22
0
void MonoKitFrame::pick(Canvas* c, const Allocation& a, int depth, Hit& h) {
    if (target_) {
        Coord x = h.left();
        Coord y = h.bottom();
        if (x >= a.left() && x < a.right() && y >= a.bottom() && y < a.top()) {
            h.target(depth, this, 0);
        }
    } else {
        BevelFrame::pick(c, a, depth, h);
    }
}
Example #23
0
void TransformSetter::pick(Canvas* c, const Allocation& a, int depth, Hit& h) {
    Transformer t(transformer_);
    transform(t, a, natural_allocation_);
    c->push_transform();
    c->transform(t);
    h.push_transform();
    h.transform(t);
    MonoGlyph::pick(c, natural_allocation_, depth, h);
    c->pop_transform();
    h.pop_transform();
}
Example #24
0
//Only use this as the condition after first running a row sort
bool compare_colsAfterRows(const Hit& lhs, const Hit& rhs){

	//Only interested in subsorting
	if(lhs.get_row() == rhs.get_row()){
		if(lhs.get_col() < rhs.get_col())
			return true;
		else{
			return false;
		}
	}
	return false;
}
Example #25
0
bool Triangle::intersect( const Ray& r , Hit& h , float tmin){

	Vector3f R_o = r.getOrigin();
	Vector3f R_d = r.getDirection();

	Matrix3f A( this->a.x()-this->b.x() , this->a.x()-this->c.x() , R_d.x() ,
		    this->a.y()-this->b.y() , this->a.y()-this->c.y() , R_d.y() ,
		    this->a.z()-this->b.z() , this->a.z()-this->c.z() , R_d.z()  );

	Matrix3f BetaM( this->a.x()-R_o.x() , this->a.x()-this->c.x() , R_d.x() ,
		        this->a.y()-R_o.y() , this->a.y()-this->c.y() , R_d.y() ,
		        this->a.z()-R_o.z() , this->a.z()-this->c.z() , R_d.z()  );
	
	float beta = BetaM.determinant() / A.determinant();

	Matrix3f GammaM( this->a.x()-this->b.x() , this->a.x()-R_o.x() , R_d.x() ,
		         this->a.y()-this->b.y() , this->a.y()-R_o.y() , R_d.y() ,
		         this->a.z()-this->b.z() , this->a.z()-R_o.z() , R_d.z()  );
	
	float gamma = GammaM.determinant() / A.determinant();

	float alpha = 1.0f - beta - gamma;

	Matrix3f tM( this->a.x()-this->b.x() , this->a.x()-this->c.x() , this->a.x()-R_o.x() ,
		     this->a.y()-this->b.y() , this->a.y()-this->c.y() , this->a.y()-R_o.y() ,
		     this->a.z()-this->b.z() , this->a.z()-this->c.z() , this->a.z()-R_o.z()  );
	
	float t = tM.determinant() / A.determinant();

	if (beta + gamma > 1){
	    return false;
	} 
	if (beta < 0){
	    return false;
	} 
	if (gamma < 0){
	    return false;
	} 

	if (t > tmin && t < h.getT()){

	    Vector3f newNormal = (alpha*this->normals[0] + beta*this->normals[1] + gamma*this->normals[2]).normalized();
	    h.set(t, this->material, newNormal);

	    Vector2f newTexCoord = (alpha*this->texCoords[0] + beta*this->texCoords[1] + gamma*this->texCoords[2]);
	    h.setTexCoord(newTexCoord);

	    return true;	
	} 
	else{
	    return false;
	} 
}
Example #26
0
const HitList &
PhraseQueryNode::evaluateHits(HitList & hl) const
{
    hl.clear();
    _fieldInfo.clear();
    if ( ! AndQueryNode::evaluate()) return hl;

    HitList tmpHL;
    unsigned int fullPhraseLen = size();
    unsigned int currPhraseLen = 0;
    std::vector<unsigned int> indexVector(fullPhraseLen, 0);
    auto curr = static_cast<const QueryTerm *> ((*this)[currPhraseLen].get());
    bool exhausted( curr->evaluateHits(tmpHL).empty());
    for (; !exhausted; ) {
        auto next = static_cast<const QueryTerm *>((*this)[currPhraseLen+1].get());
        unsigned int & currIndex = indexVector[currPhraseLen];
        unsigned int & nextIndex = indexVector[currPhraseLen+1];

        const auto & currHit = curr->evaluateHits(tmpHL)[currIndex];
        size_t firstPosition = currHit.pos();
        uint32_t currElemId = currHit.elemId();
        uint32_t currContext = currHit.context();

        const HitList & nextHL = next->evaluateHits(tmpHL);

        int diff(0);
        size_t nextIndexMax = nextHL.size();
        while ((nextIndex < nextIndexMax) &&
              ((nextHL[nextIndex].context() < currContext) ||
               ((nextHL[nextIndex].context() == currContext) && (nextHL[nextIndex].elemId() <= currElemId))) &&
             ((diff = nextHL[nextIndex].pos()-firstPosition) < 1))
        {
            nextIndex++;
        }
        if ((diff == 1) && (nextHL[nextIndex].context() == currContext) && (nextHL[nextIndex].elemId() == currElemId)) {
            currPhraseLen++;
            if ((currPhraseLen+1) == fullPhraseLen) {
                Hit h = nextHL[indexVector[currPhraseLen]];
                hl.push_back(h);
                const QueryTerm::FieldInfo & fi = next->getFieldInfo(h.context());
                updateFieldInfo(h.context(), hl.size() - 1, fi.getFieldLength());
                currPhraseLen = 0;
                indexVector[0]++;
            }
        } else {
            currPhraseLen = 0;
            indexVector[currPhraseLen]++;
        }
        curr = static_cast<const QueryTerm *>((*this)[currPhraseLen].get());
        exhausted = (nextIndex >= nextIndexMax) || (indexVector[currPhraseLen] >= curr->evaluateHits(tmpHL).size());
    }
    return hl;
}
Example #27
0
Vec3f RayTracer::reflection(const Ray &start_ray, int bounce_count) const
{
	Ray ray(start_ray);
	Hit h;
	Vec3f answer = TraceRay(ray, h, bounce_count);
	while (h.getT() < SURFACE_EPSILON) {
		ray = Ray(ray.pointAtParameter(SURFACE_EPSILON),
				ray.getDirection());
		answer = TraceRay(ray, h, bounce_count);
	}
	return answer;
}
Example #28
0
void XYView::pick(Canvas* c, const Allocation& a, int depth, Hit& h) {
    canvas_ = c;
    c->push_transform();
    if (h.event()->type() == Event::down) {
#if 0
        printf("XYView hit (%g, %g)  event (%g, %g)\n", h.left(), h.bottom(),
               h.event()->pointer_x(), h.event()->pointer_y());
#endif
    }
    TransformSetter::pick(c, a, depth, h);
    c->pop_transform();
}
Example #29
0
bool Grid::intersect(const Ray &r, Hit &h, float tmin)
{
	MarchingInfo march;
	initialRayMarch(march,r,tmin);

	int currentI = march.GetI();
	int currentJ = march.GetJ();    
	int currentK = march.GetK();
	float currentT = march.GetT();
	int numObjects;
	//Object3DVector currentVector; 绝对不能新建一个Object3DVector,然后把isOpaque的值赋给这个Object3DVector,因为当这个函数结束时,会把Object3DVector销毁,对应的指针指向的对象也会被销毁。
	//当然还有一种方法是定义一个Object3DVector指针
	//printf("i:%d j:%d currentI:%d currentJ:%d currentK:%d\n",i,j,currentI,currentJ,currentK);

	Object3DVector isAlreadyIntersect;

	while(currentI>=0 && currentI<nx && currentJ>=0 && currentJ<ny && currentK>=0 && currentK<nz)
	{
		RayTracingStats::IncrementNumGridCellsTraversed();
		Object3DVector* currentVector = &isOpaque[currentI][currentJ][currentK];
		numObjects = currentVector->getNumObjects();
		//printf("%d %d %d\n",currentI,currentJ,currentK);
		for(int i=0; i<numObjects; ++i)
		{
			//already intersected object don't need intersect again
			if(isAlreadyIntersect.isInside(currentVector->getObject(i)))
				continue;
			RayTracingStats::IncrementNumIntersections();
			currentVector->getObject(i)->intersect(r,h,tmin);
			isAlreadyIntersect.addObject(currentVector->getObject(i));
		}
		if(h.getMaterial()!=NULL && h.getT()>=currentT && h.getT()<=march.GetNext_x() && h.getT()<=march.GetNext_y() && h.getT()<=march.GetNext_z())
		{
			return true;
		}

		march.nextCell();
		currentI = march.GetI();
		currentJ = march.GetJ();
		currentK = march.GetK();
		currentT = march.GetT();  //折射或反射,shadow时,光线圆点会在grid内
	}
	numObjects = others.getNumObjects();
	for(int i=0; i<numObjects; i++)
	{
		others.getObject(i)->intersect(r,h,tmin);
	}
	if(h.getMaterial()!=NULL)   //这里有问题,因为如果没有和平面相交的话,h的material也有可能不是null
		return true;

	return false;
}
Example #30
0
//normal.(r.origin + t*r.direction) +d = 0
bool Plane::intersect(const Ray &r, Hit &h, float tmin)
{
	float isParallel = normal.Dot3(r.getDirection());
	if(!Utility::isZero(isParallel))
	{
		float dist = -(normal.Dot3(r.getOrigin())-d)/isParallel;  //当时没有理解d的含义,构造是应该是ax+by+cz-d=0
		if(dist > tmin && dist < h.getT())
		{
			h.set(dist,material,normal,r);
			return 1;
		}
	}
	return 0;
}