Example #1
0
float Ray::intersect (const Vec3Df & p0, const Vec3Df & p1, const Vec3Df & p2, Vec3Df & intersectionPoint) const {
    Vec3Df e0 = p1-p0;
    Vec3Df e1 = p2-p0;
    Vec3Df n = Vec3Df::crossProduct(e0,e1);
    n.normalize();
    Vec3Df q = Vec3Df::crossProduct(direction,e1);
    float a = Vec3Df::dotProduct(e0,q);

    if (Vec3Df::dotProduct(n,direction) >= 0 || a < epsilon)
        return -1;

    Vec3Df s = (origin-p0)/a;
    Vec3Df r = Vec3Df::crossProduct(s,e0);

    intersectionPoint[1] = Vec3Df::dotProduct(s,q);
    intersectionPoint[2] = Vec3Df::dotProduct(r,direction);
    intersectionPoint[0] = 1 - intersectionPoint[2] - intersectionPoint[1];

    if (intersectionPoint[0] < 0 || intersectionPoint[1] < 0 || intersectionPoint[2] < 0)
        return -1;

    float t = Vec3Df::dotProduct(e1,r);

    if (t < 0)
        return -1;
    else
        return t;
}
Example #2
0
float Ray::intersect (const Vec3Df & p0, const Vec3Df & p1, const Vec3Df & p2, Vec3Df & intersectionPoint, Vec3Df & bary) const {
    Vec3Df e0 = p1-p0;
    Vec3Df e1 = p2-p0;
    Vec3Df n = Vec3Df::crossProduct(e0,e1);
    Vec3Df dir (this->direction);
    n.normalize();
    Vec3Df q = Vec3Df::crossProduct(dir,e1);
    float a = Vec3Df::dotProduct(e0,q);

    if (Vec3Df::dotProduct(n,dir) >= 0 || std::abs(a) < epsilon)
        return -1;

    Vec3Df s = (this->origin-p0)/a;
    Vec3Df r = Vec3Df::crossProduct(s,e0);

    bary[1] = Vec3Df::dotProduct(s,q);
    bary[2] = Vec3Df::dotProduct(r,dir);
    bary[0] = 1 - bary[2] - bary[1];

    if (bary[0] < 0 || bary[1] < 0 || bary[2] < 0)
        return -1;

    float t = Vec3Df::dotProduct(e1,r);
    intersectionPoint = Vec3Df(p0 * bary[0] + p1 * bary[1] + p2 * bary[2])/(bary[0] + bary[1] + bary[2]);

    if (t < 0)
        return -1;
    else
        return t;
}
Example #3
0
Vec3Df Glass::genColor (const Vec3Df & camPos,
                        Ray *r,
                        const std::vector<Light> &lights, Brdf::Type type) const {
    const Object *o = r->getIntersectedObject();
    float size = o->getBoundingBox().getRadius();
    const Vertex &closestIntersection = r->getIntersection();
    const Vec3Df & pos = closestIntersection.getPos();
    Vec3Df dir = camPos-pos;

    Vec3Df normal = normalTexture->getNormal(r);

    dir = dir.refract(1, normal, coeff);
    dir.normalize();

    //Works well only for convex object
    Ray ray(pos-o->getTrans()+3*size*dir, -dir);
    if (!o->getKDtree().intersect(ray)) {
        return controller->getRayTracer()->getColor(pos+size*dir, pos-camPos);
    }

    const Vertex i = ray.getIntersection();
    dir = (-dir).refract(coeff,-normalTexture->getNormal(&ray), 1);

    Vec3Df glassColor = controller->getRayTracer()->getColor(dir, i.getPos()+o->getTrans(), false);

    Vec3Df brdfColor = Vec3Df();
    // If at least slightly opaque
    if (alpha) {
        brdfColor = Material::genColor(camPos, r, lights, type);
    }
    return Vec3Df::interpolate(brdfColor, glassColor, alpha);
}
Example #4
0
void Camera::rotate (float theta, float phi) {
    Vec3Df up (getUpVector ());
    Vec3Df right (getRightVector ());
    Vec3Df ce (eye - center);
    float d = ce.getLength ();
    ce.normalize ();
    Vec3Df c = Vec3Df (sin (theta), sin (phi), cos (theta));
    eye = center + d * (c[0]*right + c[1]*up + c[2]*ce);
}
Example #5
0
bool Shadow::hard(const Vec3Df & pos, const Vec3Df& light) const {
    Ray riShadow;

    Vec3Df dir = light - pos;
    float dist = dir.normalize();

    bool inter = rt->intersect(dir, pos, riShadow);
    if(inter && dynamic_cast<const Glass *>(&riShadow.getIntersectedObject()->getMaterial()))
        return true;

    return !inter || (inter && riShadow.getIntersectionDistance() > dist);
}
Example #6
0
Vec3Df Sphere::shade(const Vec3Df& cam_pos, const Vec3Df& intersect, const Vec3Df& light_pos, const Vec3Df& normal){
	if (!_mat.has_tex()) return Shape::shade(cam_pos, intersect, light_pos, normal);
	float u, v;
	Vec3Df mid = this->_origin;
	Vec3Df dir = intersect - mid;
	dir.normalize();
	u = 0.5 + (atan2(dir[2], dir[0]))/(2*M_PI);
	v = 0.5 - asin(dir[1])/M_PI;
	Vec3Df diffuse = this->_tex->getColor(u,v);
	this->_mat.set_Kd(diffuse[0], diffuse[1], diffuse[2]);
	return Shape::shade(cam_pos, intersect, light_pos, normal);
}
Example #7
0
void Scene::buildOriginalScene2 () {

    Mesh groundMesh;
    groundMesh.loadOFF ("models/ground.off");
    groundMesh.scale(Vec3Df(20.f, 25.f, 1.f));
    Material groundMat;
    Object ground (groundMesh, groundMat);
    ground.setTrans(Vec3Df(0.f, -15.f, 0.f));
    objects.push_back (ground);

    Mesh killerooMesh;
    killerooMesh.loadOFF ("models/killeroo.off");
    killerooMesh.scale(0.3f);
    killerooMesh.rotate(0);
    killerooMesh.rotate(0);
    killerooMesh.rotate(0);
    killerooMesh.rotate(2);
    killerooMesh.rotate(2);
    Material killerooMat (1.f, 1.f, 2.f, 0.f, Vec3Df (0.1f, .6f, 0.5f));
    Object killeroo (killerooMesh, killerooMat);
    killeroo.setTrans (Vec3Df (0., 29.f, 4.f));
    objects.push_back (killeroo);


    float stepX = 2.2f;
    float stepY = 2.2f;
    float offsetX = -2.8f;
    float offsetY = 3.f;

    for (int i = 0; i < 3; ++i) {
        for (int j = 0; j < 3; ++j) {
            Mesh ramMesh;
            ramMesh.loadOFF ("models/ram.off");
            Material ramMat (1.f, 1.f, 2.f, 0.f, Vec3Df (1.f, .6f, .2f));
            Object ram (ramMesh, ramMat);
            float randX = (rand()%100)/100.f - 0.5f;
            float randY = (rand()%100)/100.f - 0.5f;
            ram.setTrans (Vec3Df (offsetX + i*stepX + randX, offsetY + j*stepY + randY, 0.f));
            objects.push_back (ram);
        }
    }

    Vec3Df lightPos(Vec3Df (2.0f, 25.0f, 15.0f));
    Vec3Df dir = -lightPos;
    dir.normalize();

    Light l0 (lightPos , dir, 2.f, Vec3Df (1.0f, 1.0f, 1.0f), 1.0f);
    lights.push_back (l0);

}
Example #8
0
bool Sphere::intersect(const Vec3Df& origin, const Vec3Df& dir, Vec3Df& new_origin, Vec3Df& normal) {
	Vec3Df trans_origin = origin - this->_origin;
	float a = Vec3Df::dotProduct(dir, dir);
	float b = 2 * Vec3Df::dotProduct(trans_origin, dir);
	float c = Vec3Df::dotProduct(trans_origin, trans_origin) - this->_radius * this->_radius;

	float disc = b * b - 4 * a * c;
	if (disc < 0)	return false;

	// We use the following in place of the quadratic formula for
	// more numeric precision.
	float q = (b > 0) ?
				-0.5 * (b + sqrtf(disc)) :
				-0.5 * (b - sqrtf(disc));
	float t0 = q / a;
	float t1 = c / q;
	if (t0 < t1) std::swap(t0,t1);

	float t;
	if (t0 < EPSILON)	return false;
	if (t1 < 0)		t = t0;
	else			t = t1;

	normal = trans_origin + t * dir;
	normal.normalize();
	new_origin = origin + t * dir;
	return true;
}
Example #9
0
/************************************************************
* draw
************************************************************/
void Mesh::drawSmooth() {

	glBegin(GL_TRIANGLES);

	for (unsigned int i = 0;i<triangles.size();++i)
	{
		Vec3Df col = this->materials[triangleMaterials[i]].Kd();

		glColor3fv(col.pointer());
		for (int v = 0; v < 3; v++) {
			glNormal3f(vertices[triangles[i].v[v]].n[0], vertices[triangles[i].v[v]].n[1], vertices[triangles[i].v[v]].n[2]);
			glVertex3f(vertices[triangles[i].v[v]].p[0], vertices[triangles[i].v[v]].p[1], vertices[triangles[i].v[v]].p[2]);
		}

	}
	glEnd();
}
Example #10
0
void Mesh::draw(){
    glBegin(GL_TRIANGLES);

    for (int i=0;i<triangles.size();++i)
    {
        Vec3Df edge01 = vertices[triangles[i].v[1]].p -  vertices[triangles[i].v[0]].p;
        Vec3Df edge02 = vertices[triangles[i].v[2]].p -  vertices[triangles[i].v[0]].p;
        Vec3Df n = Vec3Df::crossProduct (edge01, edge02);
        n.normalize ();
        glNormal3f(n[0], n[1], n[2]);
        for(int v = 0; v < 3 ; v++){
            glVertex3f(vertices[triangles[i].v[v]].p[0], vertices[triangles[i].v[v]].p[1] , vertices[triangles[i].v[v]].p[2]);
        }

    }
    glEnd();
}
Example #11
0
/************************************************************
 * Fonctions de calcul des normales pour chaque sommet
 ************************************************************/
void Mesh::computeVertexNormals () {
    //initialisation des normales des vertex
    for (unsigned int i = 0; i < vertices.size (); i++)
        vertices[i].n = Vec3Df (0.0, 0.0, 0.0);

    //Somme des normales du 1 voisinage du vertex
    for (unsigned int i = 0; i < triangles.size (); i++) {
        Vec3Df edge01 = vertices[triangles[i].v[1]].p -  vertices[triangles[i].v[0]].p;
        Vec3Df edge02 = vertices[triangles[i].v[2]].p -  vertices[triangles[i].v[0]].p;
        Vec3Df n = Vec3Df::crossProduct (edge01, edge02);
        n.normalize ();
        for (unsigned int j = 0; j < 3; j++)
            vertices[triangles[i].v[j]].n += n;
    }

    //Normalisation
    for (unsigned int i = 0; i < vertices.size (); i++)
        vertices[i].n.normalize ();
}
Example #12
0
void GridAARayIterator::raysForPixel(int i, int j, std::vector<Ray>& res)
{
    res.clear();

    float tanX = tan (_fieldOfView)*_aspectRatio;
    float tanY = tan (_fieldOfView);

    for (int k = 0; k < gridSize; k++) {
        for(int l = 0; l < gridSize; l++)
        {
            Vec3Df stepX = (float (k+gridSize*i) - gridSize*_screenWidth/2.f)/(gridSize * _screenWidth) * tanX * _rightVector;
            Vec3Df stepY = (float (l+gridSize*j) - gridSize*_screenHeight/2.f)/(gridSize * _screenHeight) * tanY * _upVector;
            Vec3Df step = stepX + stepY;
            Vec3Df dir = _direction + step;
            dir.normalize ();
            res.push_back(Ray(_camPos, dir));

        }
    }
}
Example #13
0
void Mesh::draw() {
	glBegin(GL_TRIANGLES);

	for (unsigned int i = 0;i<triangles.size();++i)
	{
		unsigned int triMat = triangleMaterials.at(i);
		Vec3Df col = this->materials.at(triMat).Kd();
		glColor3fv(col.pointer());
		Vec3Df edge01 = vertices[triangles[i].v[1]].p - vertices[triangles[i].v[0]].p;
		Vec3Df edge02 = vertices[triangles[i].v[2]].p - vertices[triangles[i].v[0]].p;
		Vec3Df n = Vec3Df::crossProduct(edge01, edge02);
		n.normalize();
		glNormal3f(n[0], n[1], n[2]);
		for (int v = 0; v < 3; v++) {
			glVertex3f(vertices[triangles[i].v[v]].p[0], vertices[triangles[i].v[v]].p[1], vertices[triangles[i].v[v]].p[2]);
		}

	}
	glEnd();
}
Example #14
0
File: gmini.cpp Project: pierr/tp1
void draw () {
    //On récupère la matrice objet monde
    GLfloat	modl[16];
    glGetFloatv( GL_MODELVIEW_MATRIX, modl );
    GLfloat lightPos[4];
    glGetLightfv(GL_LIGHT1, GL_POSITION, lightPos);
    
    //Vec3Df lightPosition()
    const vector<Vertex> & V = mesh.V;
    const vector<Triangle> & T = mesh.T;
    glBegin (GL_TRIANGLES);
    
    for (unsigned int i = 0; i < T.size (); i++) {
        /*if(i < (unsigned int)T.size()/2){
            glColor3ub(255, 12, 4);
        }  else{    
            glColor3ub(1, 12, 200);
        }*/
        if (polygonMode != Gouraud) {
            Vec3Df e01 = V[T[i].v[1]].p -  V[T[i].v[0]].p;
            Vec3Df e02 = V[T[i].v[2]].p -  V[T[i].v[0]].p;
            Vec3Df n = Vec3Df::crossProduct (e01, e02);
            n.normalize ();
            glNormal3f (n[0], n[1], n[2]);
            //glColorMaterial(GLenum face, GLenum mode)
            //modl.V[T[i].v]
        }
        
        //glGetFloatv(GLenum pname, GLfloat *params)
        for (unsigned int j = 0; j < 3; j++) {
            const Vertex & v = V[T[i].v[j]];
            if (polygonMode == Gouraud)
                glNormal3f (v.n[0], v.n[1], v.n[2]);
            
            glVertex3f (v.p[0], v.p[1], v.p[2]);
            
        }
        
    }
    glEnd ();
}
Example #15
0
/************************************************************
* Normal calculations
************************************************************/
void Mesh::computeVertexNormals() {
	for (unsigned int i = 0; i < vertices.size(); i++)
		vertices[i].n = Vec3Df(0.0, 0.0, 0.0);

	//Sum up neighboring normals
	for (unsigned int i = 0; i < triangles.size(); i++) {
		Vec3Df edge01 = vertices[triangles[i].v[1]].p - vertices[triangles[i].v[0]].p;
		Vec3Df edge02 = vertices[triangles[i].v[2]].p - vertices[triangles[i].v[0]].p;
		Vec3Df n = Vec3Df::crossProduct(edge01, edge02);

		n.normalize();
		//triangles[i].normal = new Vec3Df(n.p[0], n.p[1], n.p[2]);

		for (unsigned int j = 0; j < 3; j++)
			vertices[triangles[i].v[j]].n += n;
	}

	//Normalize
	for (unsigned int i = 0; i < vertices.size(); i++)
		vertices[i].n.normalize();
}
Example #16
0
void Surfel::BuildFromVertices (
    const Vertex&       iA,
    const Vertex&       iB,
    const Vertex&       iC,
    const Vec3Df&       iTranslation
) {
    // Edge eX is opposed to vertex X.
    Vec3Df eA = iC.getPos () - iB.getPos ();
    Vec3Df eB = iC.getPos () - iA.getPos ();
    Vec3Df eC = iA.getPos () - iB.getPos ();

    float a = eA.getLength ();
    float b = eB.getLength ();
    float c = eC.getLength ();
    
    eA.normalize ();
    eB.normalize ();
    eC.normalize ();
   
    // The perimeter of the triangle.
    float p = (a + b + c);
    // The semiperimeter of the triangle.
    float s = 0.5f * p;
    // The area of the triangle.
    float k = sqrt ( s * ( s - a ) * ( s - b ) * ( s - c ) );
    
    // The surfel radius equals the radius of the circle inscribed
    // in the triangle defined by vertices iA, iB and iC.
    m_radius = k / s;

    // The surfel's position is defined by the center of the inscribed
    // circle, which is subsequently defined by the intersection point
    // of the angle bisections.
    m_position  = a * iA.getPos () 
                + b * iB.getPos () 
                + c * iC.getPos ();
    m_position /= p;
    m_position += iTranslation;

    // We interpolate the normals the same way.
    m_normal    = a * iA.getNormal () 
                + b * iB.getNormal () 
                + c * iC.getNormal ();
    m_normal   /= p;
}
Example #17
0
Vec3Df Material::genColor (const Vec3Df & camPos,
                           Ray *intersectingRay,
                           const std::vector<Light> & lights, Brdf::Type type) const {
    const Vertex &closestIntersection = intersectingRay->getIntersection();
    float ambientOcclusionContribution = (type & Brdf::Ambient)?
        controller->getRayTracer()->getAmbientOcclusion(closestIntersection):
        0.f;

    Vec3Df usedColor = colorTexture->getColor(intersectingRay);

    const Brdf brdf(lights,
                    usedColor,
                    controller->getRayTracer()->getBackgroundColor(),
                    diffuse,
                    specular,
                    ambientOcclusionContribution,
                    alpha);

    Vec3Df normal = normalTexture->getNormal(intersectingRay);

    if(glossyRatio == 0)
        return brdf(closestIntersection.getPos(), normal, camPos, type);

    /* Glossy Material */
    const Vec3Df spec = brdf(closestIntersection.getPos(), normal, camPos,
                             Brdf::Type(Brdf::Specular&type));
    const Vec3Df glossyColor = glossyRatio<1?
        brdf(closestIntersection.getPos(), normal, camPos,
             Brdf::Type((Brdf::Ambient|Brdf::Diffuse)&type)):
        Vec3Df();
    const Vec3Df & pos = closestIntersection.getPos();
    Vec3Df dir = (camPos-pos).reflect(normal);
    dir.normalize();

    const Vec3Df reflectedColor = controller->getRayTracer()->getColor(dir, pos, false);

    return spec + Vec3Df::interpolate(glossyColor, reflectedColor, glossyRatio);
}
Example #18
0
File: Mesh.cpp Project: B-C/gminis
void Mesh::recomputeNormals () {
  for (unsigned int i = 0; i < V.size (); i++)
	V[i].n = Vec3Df (0.0, 0.0, 0.0);
  for (unsigned int i = 0; i < T.size (); i++) {
	Vec3Df e01 = V[T[i].v[1]].p -  V[T[i].v[0]].p;
	Vec3Df e02 = V[T[i].v[2]].p -  V[T[i].v[0]].p;

	if(ponderate_normal) {
	  Vec3Df e12 = V[T[i].v[2]].p -  V[T[i].v[1]].p;
	  e01.normalize(); e02.normalize(); e12.normalize();

	  Vec3Df n[3] = {
		Vec3Df::crossProduct (e01, e02),
		Vec3Df::crossProduct (e12,-e01),
		Vec3Df::crossProduct (-e02,-e12)
	  };

	  float angles[3] = {
		acos(Vec3Df::dotProduct(e01, e02)),
		acos(Vec3Df::dotProduct(-e01, e12)),
		acos(Vec3Df::dotProduct(-e12, -e02)),
	  };

	  for (unsigned int j = 0; j < 3; j++) {
		n[j].normalize();
		V[T[i].v[j]].n += angles[j]* n[j];
	  }
	}
	else {
	  Vec3Df n = Vec3Df::crossProduct (e01, e02);
	  n.normalize ();
	  for (unsigned int j = 0; j < 3; j++)
		V[T[i].v[j]].n += n;
	}
  }
  for (unsigned int i = 0; i < V.size (); i++)
	V[i].n.normalize ();
}
Example #19
0
RotationMatrix::RotationMatrix(double _teta, Vec3Df axis){
    axis.normalize();
    float c = std::cos(_teta*PI/180.);
    float s = std::sin(_teta*PI/180.);
    float ux = axis[0];
    float uy = axis[1];
    float uz = axis[2];
    new (this) RotationMatrix( ux*ux +(1.-ux*ux)*c , ux*uy*(1-c) - uz*s ,ux*uz*(1-c) + uy*s , 0.,
                               ux*uy*(1-c) + uz*s, uy*uy +(1.-uy*uy)*c, uy*uz*(1-c) - ux*s , 0. ,
                               ux*uz*(1-c) - uy*s, uy*uz*(1-c) + ux*s ,uz*uz +(1.-uz*uz)*c  , 0.,
                               0., 0., 0., 0.,
                               _teta
                             );
}
Example #20
0
Projectile spawnProjectile(Vec3Df direction)
{
	Vec3Df spawnPos = character.getAngleRefPos();
	direction.normalize();
	spawnPos += direction * character.getArmRadius();

    Projectile projectile = Projectile(spawnPos, direction);
	projectile.movementSpeed = 3.0;
	projectile.width = 0.5;
	projectile.height = 0.5;

	projectiles.push_back(projectile);
	return projectile;
}
Example #21
0
void GLViewer::mousePressEvent(QMouseEvent * event) {
    const WindowModel *windowModel = controller->getWindowModel();
    if (windowModel->isDragEnabled()) {
        float fov, ar;
        float screenWidth;
        float screenHeight;
        Vec3Df camPos;
        Vec3Df viewDirection;
        Vec3Df upVector;
        Vec3Df rightVector;
        getCameraInformation(fov, ar, screenWidth, screenHeight, camPos, viewDirection, upVector, rightVector);
        float tanX = tan(fov)*ar;
        float tanY = tan(fov);
        Vec3Df stepX = (float (event->x()) - screenWidth/2.f)/screenWidth * tanX * rightVector;
        Vec3Df stepY = (float (screenHeight-event->y()) - screenHeight/2.f)/screenHeight * tanY * upVector;
        Vec3Df step = stepX + stepY;
        Vec3Df dir = viewDirection + step;
        float distanceCameraScreen = dir.getLength();
        dir.normalize();
        Ray ray;
        if (controller->getRayTracer()->intersect(dir, camPos, ray)) {
            Object *o=ray.getIntersectedObject();
            QPoint p = event->globalPos();
            Vec3Df oPos = o->getTrans();
            float ratio = distanceCameraScreen/sqrt(ray.getIntersectionDistance());
            controller->viewerStartsDragging(o, oPos, p, ratio);
        }
    }
    if (!controller->getWindowModel()->isRealTime()) {
        controller->viewerSetDisplayMode(WindowModel::OpenGLDisplayMode);
    }
    else {
        controller->forceThreadUpdate();
    }
    QGLViewer::mousePressEvent(event);
}
Example #22
0
bool Plane::intersect(const Vec3Df& origin, const Vec3Df& dir, Vec3Df& new_origin, Vec3Df& normal)
{
	normal = _coeff;
	normal.normalize();

	float denom = Vec3Df::dotProduct(dir,normal);
	if (denom > -EPSILON && denom < EPSILON) return false;

	// Calculate term t in the expressen 'p = o + tD'
	float t = Vec3Df::dotProduct(_origin - origin, normal) / denom;
	if (t < EPSILON) return false;

	new_origin = origin + t * dir;
	return true;
}
Example #23
0
/// Computes lighting for a single vertex with given calculation model.
Vec3Df computeLighting(Vec3Df &vertexPos, Vec3Df &normal, LightModel lightModel)
{
    const Vec3Df lightColor = Vec3Df(1,1,1);
	const Vec3Df lightColorBoss = Vec3Df(1, 0, 0);
    
    switch (lightModel) {
        case DIFFUSE_LIGHTING:
        {
            // We cheat here: assuming a distant sun, this is an reasonable approximation
            Vec3Df l = (Vec3Df(LightPos[0],LightPos[1],LightPos[2]) - Vec3Df(0,0,0));
            l.normalize();
            return Vec3Df::dotProduct(l, normal) * lightColor;
        }
		case PHONG_LIGHTNING:
		{
			Vec3Df lightDir = boss.position - vertexPos;
			lightDir.normalize();

			Vec3Df reflDir = 2 * Vec3Df::dotProduct(lightDir, normal) * normal - lightDir;
			reflDir.normalize();

			Vec3Df viewDir = camPos - vertexPos;
			viewDir.normalize();

			//Using only 1 light source
			float ambiant = std::fmax(0, ka*ia);
			float diffuse = std::fmax(0, kd*Vec3Df::dotProduct(lightDir, normal)*id);
			float specular = std::fmax(0, ks*std::pow(std::fmax(0, Vec3Df::dotProduct(reflDir, viewDir)), alpha)*is);

			float intensity = ambiant + diffuse + specular;

			Vec3Df final = intensity * lightColorBoss;

			return final;
		}
        default:
            return Vec3Df(0, 0, 0);
    }
}
Hit ComplexObject::intersectMesh(Vec3Df origin, Vec3Df dest) {
  // hit is is where we keep track of hits with backfaces
  // For the moment we use noHit as a symbol
  Hit hit = noHit;

   //Material that is displayed if no material is found in Mesh
   Material errorMat = Material();
   errorMat.set_Kd(1,1,0);
   errorMat.set_Ka(1,1,0);
   errorMat.set_Ks(1,1,0);
   errorMat.set_Ns(96.7f);
   errorMat.set_illum(2);
   Material actualMat = errorMat;
    

  for (int i = 0; i < mesh.triangles.size(); i++) {
    Triangle T = mesh.triangles[i];

    //now return the actual material which is defined in the mesh
    int materialIndex = 999;
    if(mesh.triangleMaterials.size()>0){
  	materialIndex = mesh.triangleMaterials[i]; 
    }
    if(0 <= materialIndex && materialIndex < mesh.materials.size()){
   	actualMat = mesh.materials[materialIndex];
    }

    // Our implementation is based on the proposed algorithm of Dan Sunday at: http://geomalgorithms.com/a06-_intersect-2.html
    Vertex v0 = mesh.vertices[T.v[0]];
    Vertex v1 = mesh.vertices[T.v[1]];
    Vertex v2 = mesh.vertices[T.v[2]];

    // Edge vectors
    Vec3Df u = v1.p-v0.p;
    Vec3Df v = v2.p-v0.p;
    Vec3Df n = Vec3Df::crossProduct(u, v);  // Normal of the triangle

    Vec3Df w0 = origin - v0.p;
    float a = -Vec3Df::dotProduct(n, w0);
    float b = Vec3Df::dotProduct(n, dest);

    // Use this as a threshold to avoid division overflow
    if (fabs(b) < 0.0000001) {
      // ray is parallel to triangle plane (either precisely on or disjoint from plane)
      continue;
    }
    
    // Get intersection point of ray with triangle plane
    float r = a / b;
    if (r < 0.01)  // ray goes away from triangle
    {
	continue;
    }

    // intersect point of ray and plane
    Vec3Df I = origin + (r * dest);

    // Next up; triangle text; is I inside T?
    float uu, uv, vv, wu, wv, D;
    uu = Vec3Df::dotProduct(u, u);
    uv = Vec3Df::dotProduct(u, v);
    vv = Vec3Df::dotProduct(v, v);
    Vec3Df w = I - v0.p;
    wu = Vec3Df::dotProduct(w, u);
    wv = Vec3Df::dotProduct(w, v);
    D = uv * uv - uu * vv;

    // get and test parametric coords
    float s, t;
    s = (uv * wv - vv * wu) / D;
    if (s < 0.0 || s > 1.0)         // I is outside T
       continue;
    t = (uv * wu - uu * wv) / D;
    if (t < 0.0 || (s + t) > 1.0)  // I is outside T
       continue;

    n.normalize();  // We can now truncate the normal to length of 1

    // If we get here I (the ray hitpoint) is in T (the triangle):
    // We check if we already found a hit before
    if (hit.isHit == 0) {
      // In that case we can just assign the current hit as the first one
      hit = Hit(1, I, n, actualMat);
    } else {
      // If so, we check whether this one is closer to the origin
      float previousDistance = (hit.hitPoint - origin).getLength();
      float currentDistance  = (I - origin).getLength();

      // Now check if it's closer
      if (currentDistance < previousDistance) {
        // If it is then we save the current hit
         hit = Hit(1, I, n, actualMat);
      } else {
        // If not we discard this hit and continue looking for one which is
        continue;
      }
    }
  }
  return hit;
}
 irr::core::vector3df fromVec3Df(const Vec3Df& vec)
 {
     return irr::core::vector3df(vec.getY(), vec.getZ(), vec.getX());
 }
Example #26
0
Vec3Df RayTracer::Brdf(const Vec3Df & camPos,
                       const Vec3Df & normal,
                       int idObj,
                       const Vec3Df & intersectionPoint,
                       float occlusion,
                       int PTRays){

    Scene * scene = Scene::getInstance ();
    std::vector<Light> lights = scene->getLights();
    Object & object = scene->getObjects()[idObj];
    Vec3Df ci;
    for(unsigned int i =0;i<lights.size();i++)
    {
        Light light = lights[i];
        Vec3Df n = normal;
        n.normalize();
        Vec3Df wi = light.getPos() - intersectionPoint;
        wi.normalize();
        Vec3Df w0 = (camPos-intersectionPoint);
        w0.normalize();
        Vec3Df r = 2*(Vec3Df::dotProduct(wi,n))*n-wi;
        r.normalize();
        float diffuse = Vec3Df::dotProduct(wi, n);
        float shininess = 11;
        float spec = pow(std::max(Vec3Df::dotProduct(r,w0),0.f),shininess);
        diffuse = std::max(diffuse,0.0f);
        Vec3Df lightColor = light.getColor();
        Material material = object.getMaterial();
        float matDiffuse = material.getDiffuse();
        float matSpecular = material.getSpecular();
        Vec3Df matDiffuseColor = material.getColor();
        Vec3Df matSpecularColor = material.getColor();

        Vec3Df intersectionPoint2;
        Vec3Df IntersPointNormal2;

        //Area Lighting
        float radius=0.3f;

        //Miroir
        if(scene->getObjects()[idObj].getRefl()>0 && activeMirror)
        {
            Vec3Df vDir= intersectionPoint-camPos;
            vDir.normalize();
            Vec3Df planA = Vec3Df::crossProduct(n, Vec3Df::crossProduct(vDir, n));
            Vec3Df newDir = Vec3Df::dotProduct(planA, vDir)*planA - Vec3Df::dotProduct(vDir, n)*n;
            float occ;
            int obj = getIntersectionPoint(intersectionPoint, newDir, intersectionPoint2, IntersPointNormal2, occ);
            if(obj>-1)
            {

                if(activeShadow)
                {
                    if(getIntersectionPoint(intersectionPoint,-intersectionPoint+light.getPos(),intersectionPoint2,IntersPointNormal2)==-1)
                    {
                        ci += Brdf(intersectionPoint,IntersPointNormal2,obj,intersectionPoint2,occ,0)*scene->getObjects()[idObj].getRefl();
                    }
                }
                else
                    ci += Brdf(intersectionPoint,IntersPointNormal2,obj,intersectionPoint2,occ,0)*scene->getObjects()[idObj].getRefl();
            }
        }

        //PathTracing
        if(activePT)
        {
            if(PTRays < depthPT)
            {
               for(int h=0; h< nbRayPT; h++)
                {
                    Vec3Df n1;
                    Vec3Df n2;

                    normal.getTwoOrthogonals(n1,n2);


                    float a = ((float)std::rand())/((float)RAND_MAX);
                    float b = ((float)std::rand())/((float)RAND_MAX)*2.-1.;
                    float c = ((float)std::rand())/((float)RAND_MAX)*2.-1.;

                    Vec3Df dir = normal*a+n1*b+n2*c;
                    dir.normalize();

                    int objPT = getIntersectionPoint(intersectionPoint,dir,intersectionPoint2,IntersPointNormal2);

                    ci+=Brdf(intersectionPoint,IntersPointNormal2,objPT,intersectionPoint2,0.,PTRays+1)/(nbRayPT*depthPT);
                }


            }



            //si pt<pt_max

            //lancer plein de rayons

            //contribution+=brdf(pt+1)
        }

        if(scene->getObjects()[idObj].getRefl()<1.0 || true)
        {
            if(nbRayShadow>0 && activeShadow)
                for(int p = 0;p<nbRayShadow;p++)
                {
                    float a = ((float)std::rand())/((float)RAND_MAX)*2.-1.;
                    float b = ((float)std::rand())/((float)RAND_MAX)*2.-1.;
                    float c = ((float)std::rand())/((float)RAND_MAX)*2.-1.;

                    float sum = a+b+c;
                    a=a/sum*radius;
                    b=b/sum*radius;
                    c=c/sum*radius;
                    Vec3Df lightposbis;

                    lightposbis[0]=light.getPos()[0]+a;
                    lightposbis[1]=light.getPos()[1]+b;
                    lightposbis[2]=light.getPos()[2]+c;

                    if(getIntersectionPoint(intersectionPoint,-intersectionPoint+lightposbis,intersectionPoint2,IntersPointNormal2)==-1)
                    {
                        ci += (((matDiffuse * diffuse * matDiffuseColor) +( matSpecular * spec * matSpecularColor*0.5))*lightColor)*255/nbRayShadow;
                    }
                }
            else if(activeShadow)
            {
                if(getIntersectionPoint(intersectionPoint,-intersectionPoint+light.getPos(),intersectionPoint2,IntersPointNormal2)==-1)
                {
                    ci += (((matDiffuse * diffuse * matDiffuseColor) +( matSpecular * spec * matSpecularColor*0.5))*lightColor)*255;
                }
            }
            else //sans ombre
            {
                ci += (((matDiffuse * diffuse * matDiffuseColor) +( matSpecular * spec * matSpecularColor*0.5))*lightColor)*255;
            }
            //ci += (((matDiffuse * diffuse * matDiffuseColor) +( matSpecular * spec * matSpecularColor*0.5))*lightColor)*255/nbrayshadow;
        }



    }

    if(activeAO) return ci*(1.f-occlusion);
    else return ci;
}
Example #27
0
QImage RayTracer::render (const Vec3Df & camPos,
                          const Vec3Df & direction,
                          const Vec3Df & upVector,
                          const Vec3Df & rightVector,
                          float fieldOfView,
                          float aspectRatio,
                          unsigned int screenWidth,
                          unsigned int screenHeight) {
    QImage image (QSize (screenWidth, screenHeight), QImage::Format_RGB888);
    Scene * scene = Scene::getInstance ();
    std::vector<Light> lights = scene->getLights();
    Light light = lights[0];

    QProgressDialog progressDialog ("Raytracing...", "Cancel", 0, 100);
    progressDialog.show ();

    //#pragma omp parallel for
    for (unsigned int i = 0; i < screenWidth; i++) {
        progressDialog.setValue ((100*i)/screenWidth);
        for (unsigned int j = 0; j < screenHeight; j++) {


            float tanX = tan (fieldOfView)*aspectRatio;
            float tanY = tan (fieldOfView);

            //Nombre de découpe par dimension du pixel (Antialiasing)
            int aliaNb = 2;
            if(!activeAA) aliaNb=1;
            aliaNb++;

            Vec3Df c (backgroundColor);
            Vec3Df tempc(0.,0.,0.);
            for(int pixi=1; pixi<aliaNb; pixi++){
                for(int pixj=1; pixj<aliaNb; pixj++){
                    Vec3Df stepX = (float (i)-0.5+float(pixi)/float(aliaNb) - screenWidth/2.f)/screenWidth * tanX * rightVector;
                    Vec3Df stepY = (float (j)-0.5+float(pixj)/float(aliaNb) - screenHeight/2.f)/screenHeight * tanY * upVector;
                    Vec3Df step = stepX + stepY;

                    Vec3Df dir = direction + step;
                    dir.normalize ();
                    Vec3Df intersectionPoint;
                    Vec3Df IntersPointNormal;
                    float occlusion;

                    int idObj = getIntersectionPoint(camPos,dir,intersectionPoint,IntersPointNormal,occlusion);

                    if(idObj>=0)
                    {

                        tempc += Brdf(camPos, IntersPointNormal, idObj,intersectionPoint,occlusion,0)/std::pow(aliaNb-1,2);
                        c=tempc;

                    }
                }
            }

            image.setPixel (i, j, qRgb (clamp (c[0], 0, 255), clamp (c[1], 0, 255), clamp (c[2], 0, 255)));
        }
    }
    progressDialog.setValue (100);
    return image;
}
Example #28
0
void KDTree::Node::buildNode(const KDTree& tree, int maxDepth)
{
    
    // Find the median plan
    Vec3Df n;
    if (boundingBox.getSize() == boundingBox.getWidth() ){
        n = Vec3Df (boundingBox.getMax()[0] - boundingBox.getMin()[0], 0.0, 0.0);
    } else if (boundingBox.getSize() == boundingBox.getHeight()){
        n = Vec3Df (0.0, boundingBox.getMax()[1] - boundingBox.getMin()[1], 0.0);
    } else{
        n = Vec3Df( 0.0, 0.0, boundingBox.getMax()[2] - boundingBox.getMin()[2]);
    }
    
    n.normalize();
    Vec3Df position = getMedianPoint(tree.getMesh(), n);;
    
    plan.n = n;
    plan.position = position;
    
    if (depth == maxDepth) {
        return;
    }
    
    //seperate triangles
    
    vector<int> leftIndexes, rightIndexes;
    for (int idx : triangleIndexes){
        
        const Triangle& t = tree.getMesh().getTriangles()[idx];
        
        const Vec3Df& a = tree.getMesh().getVertices()[ t.getVertex(0)].getPos();
        const Vec3Df& b = tree.getMesh().getVertices()[ t.getVertex(1)].getPos();
        const Vec3Df& c = tree.getMesh().getVertices()[ t.getVertex(2)].getPos();
        
        
        //regarder si tous les sommets sont du même côté du plan...
        if ( plan.isLeft(a) && plan.isLeft(b) && plan.isLeft(c) ){
            //Ils sont tous à gauche
            leftIndexes.push_back(idx);
            
        } else if( plan.isRight(a) && plan.isRight(b) && plan.isRight(c) ){
            //Ils sont tous à droite
            rightIndexes.push_back(idx);
        } else {
            // Le triangle doit être ajouté des deux côtés
            rightIndexes.push_back(idx);
            leftIndexes.push_back(idx);
        }
        
    }
    
    if(rightIndexes == leftIndexes)
        return;
    
    if (triangleIndexes.size() == rightIndexes.size() || triangleIndexes.size() == leftIndexes.size())
        return;
    
    
    if(rightIndexes.size() != 0){
        right_node = new KDTree::Node(rightIndexes, depth + 1, tree);
        right_node->buildNode(tree, maxDepth);
    }
    
    if(leftIndexes.size() != 0){
        left_node = new KDTree::Node(leftIndexes, depth + 1, tree);
        left_node->buildNode(tree, maxDepth);
    }
    
}
    Ecs::Entity createAttackArea(
        Threading::ConcurrentWriter<Ecs::World>& world,
        const Ecs::Entity& character
    ) {
        Ecs::Entity area = world->createEntity();
        Vec3Df basePosition;
        Vec3Df rotation;
        unsigned int damages = 0;

        {
            Ecs::ComponentGroup::ComponentTypeCollection types;
            types.insert(StatisticsComponent::Type);
            types.insert(CharacterComponent::Type);
            types.insert(PositionComponent::Type);
            types.insert(RotationComponent::Type);
            Ecs::ComponentGroup prototype(types);

            Ecs::ComponentGroup group = world->getEntityComponents(
                character,
                prototype
            );

            Threading::ConcurrentWriter<CharacterComponent> characterComponent =
                Threading::getConcurrentWriter<Ecs::Component, CharacterComponent>(
                    group.getComponent(CharacterComponent::Type)
                );

            Threading::ConcurrentReader<StatisticsComponent> statComponent =
                Threading::getConcurrentReader<Ecs::Component, StatisticsComponent>(
                    group.getComponent(StatisticsComponent::Type)
                );

            Threading::ConcurrentReader<PositionComponent> posComponent =
                Threading::getConcurrentReader<Ecs::Component, PositionComponent>(
                    group.getComponent(PositionComponent::Type)
                );

            Threading::ConcurrentReader<RotationComponent> rotComponent =
                Threading::getConcurrentReader<Ecs::Component, RotationComponent>(
                    group.getComponent(RotationComponent::Type)
                );

            damages = statComponent->getStatistics().getAttack().getCurrentValue();
            characterComponent->setAttackArea(area);
            basePosition = posComponent->getPosition();
            rotation = rotComponent->getRotation();
        }

        Geometry::Vec2Df offset = Geometry::Vec2Df::fromPolar(
            rotation.getZ(),
            1.5
        ) - Geometry::Vec2Df(0.5, 0.5);

        Geometry::AxisAlignedBoundingBox bbox(
            Geometry::Vec3Df(0.0, 0.0, 0.0),
            Geometry::Vec3Df(1.0, 1.0, 1.0)
        );

        world->addComponent(area, new PositionComponent(
            basePosition + Vec3Df(offset.getX(), offset.getY(), 0)
        ));
        world->addComponent(area, new RotationComponent(
            Vec3Df(0, 0, 0)
        ));
        world->addComponent(area, new Physics::CollisionComponent(
            new Physics::AABBCollisionBody(bbox)
        ));
        world->addComponent(area, new HarmComponent(
            damages
        ));

        return area;
    }
Example #30
0
// react to keyboard input
void keyboard(unsigned char key, int x, int y)
{
	    //printf("key %d pressed at %d,%d\n",key,x,y);
	    //fflush(stdout);
    switch (key)
    {
	//add/update a light based on the camera position.
	case 'L':
		MyLightPositions.push_back(getCameraPosition());
		break;
	case 'l':
		MyLightPositions[MyLightPositions.size()-1]=getCameraPosition();
		break;
	case 'r':
	{

		clock_t t;
		t = clock();

		//Pressing r will launch the raytracing.
		cout<<"\n\n"<<endl;


		//Setup an image with the size of the current image.
		Image result(WindowSize_X,WindowSize_Y);
		
		//produce the rays for each pixel, by first computing
		//the rays for the corners of the frustum.
		Vec3Df origin00, dest00;
		Vec3Df origin01, dest01;
		Vec3Df origin10, dest10;
		Vec3Df origin11, dest11;
		Vec3Df origin, dest;
		

		produceRay(0,0, &origin00, &dest00);
		produceRay(0,WindowSize_Y-1, &origin01, &dest01);
		produceRay(WindowSize_X-1,0, &origin10, &dest10);
		produceRay(WindowSize_X-1,WindowSize_Y-1, &origin11, &dest11);

		std::vector<std::future<Vec3Df> > threads;
		float progressc(0.f);	
		printf("\e[?25l"); /* hide the cursor */	

		for (unsigned int y=0; y<WindowSize_Y;++y)
		{
			for (unsigned int x=0; x<WindowSize_X;++x)
			{
				//produce the rays for each pixel, by interpolating 
				//the four rays of the frustum corners.
				float xscale=1.0f-float(x)/(WindowSize_X-1);
				float yscale=1.0f-float(y)/(WindowSize_Y-1);

				origin=yscale*(xscale*origin00+(1-xscale)*origin10)+
					(1-yscale)*(xscale*origin01+(1-xscale)*origin11);
				dest=yscale*(xscale*dest00+(1-xscale)*dest10)+
					(1-yscale)*(xscale*dest01+(1-xscale)*dest11);


				Vec3Df rgb;
				
				rgb.init(0,0,0);
				//launch raytracing for the given ray.
				threads.push_back(std::async(performRayTracing, 0, origin, dest));
			}
		}

		int count = 0;
		for (unsigned int y = 0; y < WindowSize_Y; ++y)
		{
			for (unsigned int x = 0; x < WindowSize_X; ++x)
			{
				++progressc;
				Vec3Df rgb = threads[count].get();
				//store the result in an image 
				result.setPixel(x, y, RGBValue(rgb[0], rgb[1], rgb[2]));
				printf("\r[Raytracing][%.0f%%]", (progressc / (WindowSize_X*WindowSize_Y)) * 100); // 
				++count;
			}
		}

		threads.resize(0);

		printf("\e[?25h"); /* hide the cursor */
		result.writeImage("result.ppm");
		
		t = clock() - t;

		std::vector<Triangle>& triangles = MyMesh.triangles;
		int size = triangles.size();
		printf ("\n[Render time: %f s | Triangles: %d | Resolution: %dx%d (%dpx)]\n\n\n",((float)t)/CLOCKS_PER_SEC, size, WindowSize_X, WindowSize_Y, WindowSize_X*WindowSize_Y);

		break;
	}
	case 27:     // touche ESC
        exit(0);
    }

	
	//produce the ray for the current mouse position
	Vec3Df testRayOrigin, testRayDestination;
	produceRay(x, y, &testRayOrigin, &testRayDestination);

	yourKeyboardFunc(key,x,y, testRayOrigin, testRayDestination);
}