Exemple #1
1
vec3 Scene::calculPixel(const Rayon& ray, float dist, const vec3& oeil, float &oclu) const
{
    #if 0
        return vec3(dist*0.17, dist*0.19, dist*0.23);
    #else

        const vec3 dRay = ray.getDirection();
        vec3 p(ray.getOrigine() + dRay*dist);
        node->repositionne(p);
        const vec3 n(node->getNormal(p));

        Material texture = node->getMaterial(p);
        //return texture.getColor();

        std::vector<Lumiere> lumieres2;
        //lumieres2.reserve(NB_RAYONS_CIEL+this->lumieres.size());
        float ombre = calculPoisson(p, n, lumieres2);
        oclu = ombre;
        if(ombre > 0)
        {
            //for(const Lumiere& l: this->lumieres)
                //lumieres2.push_back(l);

            vec3 color = phong(texture, p, lumieres2, n, oeil);
            //color *= ombre;
            color = glm::clamp(color, vec3(0,0,0), vec3(1,1,1));
            return color;
        }
        else
            return NOIR;


    #endif
}
Exemple #2
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;
}
Exemple #3
0
 bool Sphere::intersect(const Rayon &rayon, float& dist) const
 {
     Vector OC(sphereOrigin-rayon.getOrigin());
     float k(dotProduct(OC,rayon.getDirect()));
     float h(dotProduct(OC,OC) - k*k);
     if (h <= radius*radius)
     {
         return true;
     }
     else
     {
         return false;
     }
 }
Exemple #4
0
 bool Sphere::intersect(const Rayon &rayon, Hit &hit, float& dist) const
 {
    const float m_Pi = 3.14159265358979323846;
    Vector OC(sphereOrigin-rayon.getOrigin());
    float k(dotProduct(OC,rayon.getDirect()));
    float h(dotProduct(OC,OC) - k*k);
    float radiusSquare = radius*radius ;
    if (h <= radiusSquare)
    {
        float delta = sqrt(radiusSquare-h);
        hit.setImpactPoint(rayon.getDistantPoint(k-delta));
        dist = k-delta ;
        if (dist <0)
        {
            return false ;
        }
        Vector  normal(hit.getImpactPoint()-sphereOrigin);
        normal.normalize();
        hit.setNormal(normal);
        hit.setV( (hit.getImpactPoint().z -  (sphereOrigin.z - radius)) / (2*radius) );
        Vector A (radius,0.0,0.0);
        Vector B (hit.getImpactPoint().x-sphereOrigin.x,hit.getImpactPoint().y-sphereOrigin.y,0.0);
        A.normalize();
        B.normalize();
        float cosAlpha = dotProduct(A,B) ;
        float alphaAlpha = acos(cosAlpha) ;
        float alpha ;
        if (B.getY() >0)
        {
           alpha = alphaAlpha;
        }
        else
        {
            alpha = 2*m_Pi - alphaAlpha ;
        }
        hit.setU(alpha/(2*m_Pi));
        return true;
    }
    else
    {
        return false;
    }
 }
bool Terrain::intersect(const Rayon& rayon, float &coeffDistance, int &i) const
{
    float dmin;
    float dmax;

    if(!box.intersect(rayon, dmin, dmax ))
        return false;

    //à modifier à cause de la précision des floats, mais c'est bizarre que ça marche comme un gant. faire attention que le point de départ ne soit pas en dehors de la box.
    //dmin = 0.0;
    //dmax = 3000.0;

    coeffDistance = dmin;

    for(i = 0;  i<128;  i++)
    {
        vec3 pos = rayon.getOrigine() + coeffDistance*rayon.getDirection();
        float h = getHauteur( pos );
        if(h == HAUTEUR_HORS_MAP)        {
            if(i == 0)  {
                coeffDistance += 0.01f;
                continue;
            }
            else
                break;
        }
        h = fabsf(pos.z - h);

        if( h <(0.002 * coeffDistance) ) {
                return true;
        }else if(coeffDistance > dmax )
                break;

        coeffDistance += 0.3*h;

    }

    return false;
}
bool Triangle::calculIntersection(const Rayon &r, Intersection &I){
	//MINIMUM STORAGE RAY TRIANGLE INTERSECTION BY TRUMBORE AND MULLER
	/*glm::vec3 edge1, edge2, tvec, pvec, qvec;
	float det, inv_det;
	float u, v, t;
	Intersection inter;

	edge1 = V1 - V0;
	edge2 = V2 - V0;

	pvec = glm::cross(r.Vect(), edge2);

	det = glm::dot(edge1, pvec);



	//bool i = glm::intersectRayTriangle(r.Orig(), r.Vect(), V0, V1, V2, edge1);
	if (det < 0.000001){
		return false;
	}

	tvec = r.Orig() - V0;

	u = glm::dot(tvec, pvec);
	if (u < 0.0f || u > det){
		return false;
	}

	qvec = glm::cross(tvec, edge1);

	v = glm::dot(r.Vect(), qvec);
	if (v < 0.0f || u + v > det){
		return false;
	}

	t = glm::dot(edge2, qvec);
	inv_det = 1.0f / det;
	t *= inv_det;
	u *= inv_det;
	v *= inv_det;

	//Intersection inter;
	inter.dist = t;
	inter.Objet = this;
	inter.normal = glm::normalize(glm::cross(edge1, edge2));
	I = inter;
	
	


	if (det > -0.000001 && det < 0.000001){
		return false;
	}
	//inv_det = 1.0f / det;

	tvec = r.Orig() - V0;

	u = glm::dot(tvec, pvec) * inv_det;
	if (u < 0.0f || u > 1.0f){
		return false;
	}

	qvec = glm::cross(tvec, edge1);

	v = glm::dot(r.Vect(), qvec)*inv_det;
	if (v < 0.0f || u + v > 1.0f){
		return false;
	}

	t = glm::dot(edge2, qvec) * inv_det;
	//Intersection inter;
	inter.dist = t;
	inter.Objet = this;
	glm::vec3 normal = glm::cross(edge1, edge2);
	if (normal.z > 0){
		normal.z = -normal.z;
		inter.normal = glm::normalize(normal);
		I = inter;
		return true;
	}

	inter.normal = glm::normalize(normal);
	I = inter;
	
	return true;*/
	//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	/*
	glm::vec3 edge1 = V1 - V0;
	glm::vec3 edge2 = V2 - V0;
	glm::vec3 pvec = glm::cross(r.Vect(), edge2);
	float det = glm::dot(edge1, pvec);
	if (det == 0){ return false; }
	float invDet = 1.0f / det;
	glm::vec3 tvec = r.Orig() - V0;
	float u;
	if (det < 0){
		u = glm::dot(tvec, pvec) * invDet;
	}
	else{
		u = glm::dot(tvec, pvec);
	}
	
	if (u < 0 || u > 1.0f){ return false; }
	glm::vec3 qvec = glm::cross(tvec, edge1);
	float v = glm::dot(r.Orig(), qvec) * invDet;
	if (v < 0 || u + v > 1.0f){ return false; }
	float t = glm::dot(edge2, qvec) * invDet;

	Intersection inter;
	inter.dist = t;
	inter.Objet = this;
	glm::vec3 normale = glm::normalize(glm::cross(edge1, edge2));
	inter.normal = glm::normalize(glm::cross(edge2, edge1));
	if (inter.normal.z > 0){ inter.normal.z = -inter.normal.z; }
	I = inter;
	return true;*/
	////////////////////////////////////////////////////////////////////////////////////////////////////////////

	double det, invdet;
	glm::vec3 edge1 = V1 - V0;
	glm::vec3 edge2 = V2 - V0;

	/* Find the cross product of edge2 and the ray direction */
	glm::vec3 s1 = glm::cross(r.Vect(), edge2);

	det = glm::dot(edge1, s1);
	if (det > -0.000001 && det < 0.000001) {
		return false;
	}

	invdet = 1 / det;

	glm::vec3 s2 = r.Orig() - V0;

	double u = glm::dot(s2, s1) * invdet;

	if (u < 0 || u > 1) {
		return false;
	}

	glm::vec3 s3 = glm::cross(s2, edge1);

	double v = glm::dot(r.Vect(), s3) * invdet;

	if (v < 0 || (u + v) > 1) {
		return false;
	}

	double tmp = glm::dot(edge2, s3) * invdet;

	if (tmp < 0) {
		return false;
	}

	/* subtract tiny amount - otherwise artifacts due to floating point imprecisions... */
	float dist = tmp /*- 0.005*/;
	glm::vec3 normal = glm::normalize(glm::cross(edge2, edge1));
	Intersection inter;
	inter.dist = dist;
	inter.Objet = this;
	inter.normal = -normal;
	//if (inter.normal.z >= 0){ inter.normal.z = -inter.normal.z; }
	I = inter;
	return true;
}
Exemple #7
0
bool Scene::intersect(const Rayon& r, float& dist, int& i) const
{
    return intersect(r.getOrigine(), r.getDirection(), dist, i);
}
Exemple #8
0
inline float Box::intersectIn(const Rayon& r) const
{
    float tmax, tymax, tzmax;

    if(r.getDirection()(0) == 0)
        tmax = FLT_MAX;
    else if(r.getDirection()(0) > 0)
        tmax = (max(0) - r.getOrigine()(0)) / r.getDirection()(0);
    else
        tmax = (min(0) - r.getOrigine()(0)) / r.getDirection()(0);

    if(r.getDirection()(1) == 0)
        tymax = FLT_MAX;
    else if(r.getDirection()(1) >= 0)
        tymax = (max(1) - r.getOrigine()(1)) / r.getDirection()(1);
    else
        tymax = (min(1) - r.getOrigine()(1)) / r.getDirection()(1);

    if(tymax < tmax)
        tmax = tymax;


    if(r.getDirection()(2) == 0)
        return tmax;
    else if(r.getDirection()(2) > 0)
        tzmax = (max(2) - r.getOrigine()(2)) / r.getDirection()(2);
    else
        tzmax = (min(2) - r.getOrigine()(2)) / r.getDirection()(2);

    if(tzmax < tmax)
        return tzmax;
    return tmax;
}
Exemple #9
0
bool Box::intersect(const Rayon &r, float &distanceMin, float &distanceMax) const
{
    if(this->isIn(r.getOrigine()))  {
        distanceMin = 0;
        distanceMax = intersectIn(r);
        return true;
    }

    float tmin, tmax, tymin, tymax, tzmin, tzmax;
    float div;

    if(r.getDirection()(0) == 0)    {
        tmin = FLT_MIN;
        tmax = FLT_MAX;
    }
    else if(r.getDirection()(0) > 0)    {
        div = 1 / r.getDirection()(0);
        tmin = (min(0) - r.getOrigine()(0)) * div;
        tmax = (max(0) - r.getOrigine()(0)) * div;
    }
    else    {
        div = 1 / r.getDirection()(0);
        tmin = (max(0) - r.getOrigine()(0)) * div;
        tmax = (min(0) - r.getOrigine()(0)) * div;
    }

    if(r.getDirection()(1) == 0)    {
        tymin = FLT_MIN;
        tymax = FLT_MAX;
    }
    else if(r.getDirection()(1) >= 0)    {
        div = 1 / r.getDirection()(1);
        tymin = (min(1) - r.getOrigine()(1)) * div;
        tymax = (max(1) - r.getOrigine()(1)) * div;
    }
    else    {
        div = 1 / r.getDirection()(1);
        tymin = (max(1) - r.getOrigine()(1)) * div;
        tymax = (min(1) - r.getOrigine()(1)) * div;
    }

    if( (tmin > tymax) || (tymin > tmax) )
        return false;

    if(tymin > tmin)
        tmin = tymin;

    if(tymax < tmax)
        tmax = tymax;


    if(r.getDirection()(2) == 0)    {
        tzmin = FLT_MIN;
        tzmax = FLT_MAX;
    }
    else if(r.getDirection()(2) > 0)    {
        div = 1 / r.getDirection()(2);
        tzmin = (min(2) - r.getOrigine()(2)) * div;
        tzmax = (max(2) - r.getOrigine()(2)) * div;
    }
    else    {
        div = 1 / r.getDirection()(2);
        tzmin = (max(2) - r.getOrigine()(2)) * div;
        tzmax = (min(2) - r.getOrigine()(2)) * div;
    }

    if( (tmin > tzmax) || (tzmin > tmax) )
        return false;

    if(tzmin > tmin)
        tmin = tzmin;

    if(tzmax < tmax)
        tmax = tzmax;

    if(tmin>=0)
        distanceMin = tmin;
    //else
    //    return false; //inutile apparament
    //distanceMin += 0.002;

    if(tmax>0)
        distanceMax = tmax;

    return true;
}