Example #1
0
void Display::keyUp(SDLKey key)
{
    Vector3 velocity = app->getVelocity();
    Vector3 angularVelocity = app->getAngularVelocity();

    switch(key)
    {
    case SDLK_a:
        if(velocity.x < 0)
            velocity.x = 0;
        break;
    case SDLK_d:
        if(velocity.x > 0)
            velocity.x = 0;
        break;
    case SDLK_w:
        if(velocity.z > 0)
            velocity.z = 0;
        break;
    case SDLK_s:
        if(velocity.z < 0)
            velocity.z = 0;
        break;
    case SDLK_LCTRL:
        if(velocity.y < 0)
            velocity.y = 0;
        break;
    case SDLK_SPACE:
        if(velocity.y > 0)
            velocity.y = 0;
        break;
    case SDLK_LEFT:
        if(angularVelocity.y > 0)
            angularVelocity.y = 0;
        break;
    case SDLK_RIGHT:
        if(angularVelocity.y < 0)
            angularVelocity.y = 0;
        break;
    case SDLK_UP:
        if(angularVelocity.x > 0)
            angularVelocity.x = 0;
        break;
    case SDLK_DOWN:
        if(angularVelocity.x < 0)
            angularVelocity.x = 0;
        break;
    default:
        break;
    }

    if(velocity.length2() > 0.1)
        velocity = velocity.normalized();
    if(angularVelocity.length2() > 0.01)
        angularVelocity = angularVelocity.normalized();
    app->setVelocity(velocity*Speed);
    app->setAngularVelocity(angularVelocity*AngularSpeed);
}
Example #2
0
void Display::keyDown(SDLKey key)
{
    Vector3 velocity = app->getVelocity();
    Vector3 angularVelocity = app->getAngularVelocity();

    switch(key)
    {
    case SDLK_a:
        velocity.x = -1;
        break;
    case SDLK_d:
        velocity.x = 1;
        break;
    case SDLK_w:
        velocity.z = 1;
        break;
    case SDLK_s:
        velocity.z = -1;
        break;
    case SDLK_LCTRL:
        velocity.y = -1;
        break;
    case SDLK_SPACE:
        velocity.y = 1;
        break;
    case SDLK_ESCAPE:
        quit = true;
        break;
    case SDLK_LEFT:
        angularVelocity.y = 1;
        break;
    case SDLK_RIGHT:
        angularVelocity.y = -1;
        break;
    case SDLK_UP:
        angularVelocity.x = 1;
        break;
    case SDLK_DOWN:
        angularVelocity.x = -1;
        break;
    default:
        break;
    }

    if(velocity.length2() > 0.01)
        velocity = velocity.normalized();
    if(angularVelocity.length2() > 0.01)
        angularVelocity = angularVelocity.normalized();
    app->setVelocity(velocity*Speed);
    app->setAngularVelocity(angularVelocity*AngularSpeed);
}
Example #3
0
void WFace::computeNormal() {
  WEdge *u,*v,*start;
  Vector3 uvect,vvect;
  Vector3 n;
  start=edge();
  u=edge();
  if (u->left()==this) uvect=u->direction(); else uvect=-u->direction();
  do {
    if (u->left()==this) {
      v=u->succLeft();
    }
    else {
      v=u->succRight();
    }
    vvect=v->direction();
    if (v->right()==this) vvect=-vvect;
    n=uvect.cross(vvect);
    u=v;
    uvect=vvect;
  } while (n.length2()<0.000000001 && (u!=start));
  if (u==start) {
    normal(Vector3(0,0,0)); // cas particulier : face aplatie
  }
  else {
    n.normalize();
    normal(n);
  }
}
Example #4
0
Vector3
Lambert::shade(const Ray& ray, const HitInfo& hit, const Scene& scene) const
{
	Vector3 L = Vector3(0.0f, 0.0f, 0.0f);

	const Vector3 viewDir = -ray.d; // d is a unit vector

	const Lights *lightlist = scene.lights();

	// loop over all of the lights
	Lights::const_iterator lightIter;
	for (lightIter = lightlist->begin(); lightIter != lightlist->end(); lightIter++)
	{
		PointLight* pLight = *lightIter;

		Vector3 l = pLight->position() - hit.P;

		// the inverse-squared falloff
		float falloff = l.length2();

		// normalize the light direction
		l /= sqrt(falloff);

		// get the irradiance
		Vector3 irradiance = (pLight->color() * pLight->wattage()) * std::max(0.0f, dot(hit.N, l)) / (4.0 * PI * falloff);

		L += irradiance * (m_kd / PI);
	}

	return L;
}
bool within(const Scatter& pos, Vector3 r, double rMax, const Grid& g) {
  const int n = pos.length();
  double r2 = rMax*rMax;
  for (int p = 0; p < n; p++) {
    Vector3 d = g.wrapDiff(pos.get(p) - r);
    if (d.length2() < r2) return true;
  }
  return false;
}
Example #6
0
	int Object::createPlane( Material* mat , float w , float h , float* color , float xTile , float yTile , 
		                       Vector3 const& normal , Vector3 const& alignDir , Vector3 const& offset , bool invYDir )
	{
		Vector3 yLen =  normal.cross( alignDir );
		assert( yLen.length2() > 1e-4 );

		yLen.normalize();
		Vector3 xLen = yLen.cross( normal );

		xLen *= 0.5f * w;
		yLen *= 0.5f * h;

		if ( invYDir )
			yLen = -yLen;

		Vector3 n = normal;
		n.normalize();

		int texLen = 2;
		VertexType type = ( color ) ? CFVT_XYZ_N_CF1 : CFVT_XYZ_N;
		//VertexType type = ( color ) ? CFVT_XYZ_CF1 : CFVT_XYZ;

		MeshBuilder builder = MeshBuilder( type | CFVF_TEX1( 2 ) );

		if ( color )
			builder.setColor( color );

		builder.setNormal( n );

		builder.reserveVexterBuffer( 4 );
		builder.reserveIndexBuffer( 12 );

		builder.setPosition( offset - xLen - yLen );
		builder.setTexCoord( 0 , 0 , 0 );
		builder.addVertex();

		builder.setPosition( offset + xLen - yLen );
		builder.setTexCoord( 0 ,xTile, 0 );
		builder.addVertex();

		builder.setPosition( offset + xLen + yLen );
		builder.setTexCoord( 0 , xTile , yTile );
		builder.addVertex();

		builder.setPosition( offset - xLen + yLen );
		builder.setTexCoord( 0 , 0 , yTile );
		builder.addVertex();

		builder.addQuad( 0 , 1 , 2 , 3 );

		return builder.createIndexTrangle( this , mat );
	}
Example #7
0
bool
Sphere::intersect(HitInfo& result, const Ray& ray,
                  float tMin, float tMax)
{
    const Vector3 toO = ray.o - m_center; 

    const float a = ray.d.length2(); 
    const float b = dot(2*ray.d, toO);
    const float c = toO.length2() - m_radius*m_radius;

    const float discrim = b*b-4.0f*a*c; 

    if (discrim < 0) 
        return false;   // quadratic equation would yield imaginary numbers

    const float sqrt_discrim = sqrt(discrim); 

    // solve the quadratic equation
    const float t[2] = {(-b-sqrt_discrim)/(2.0f*a), (-b+sqrt_discrim)/(2.0f*a)}; 

    // since we know that discrim >= 0, t[0] < t{1]
    // return the t closest to us that is within range
    if ((t[0] > tMin) && (t[0] < tMax))
    {
        result.t = t[0];
    }
    else if((t[1] > tMin) && (t[1] < tMax))
    {
        result.t = t[1];
    }
    else
    {
        // neither of the solutions are in the required range
        return false; 
    }

	if (result.t < 0.0001f)
	{
		return false;
	}
    result.P = ray.o + result.t*ray.d; 
    result.N = (result.P-m_center); 
    result.N.normalize(); 
    result.material = this->m_material; 
    return true;
}
Example #8
0
inline Vector3 pointOnSphere(float sx, float sy)
{
#if 0
	// Rejection sampling
	Vector3 v;
	do {
		v.x = randomFloat() * 2.0f - 1.0f;
		v.y = randomFloat() * 2.0f - 1.0f;
		v.z = randomFloat() * 2.0f - 1.0f;
	} while (v.length2() > 1.0f);
	return v;
#else
	sx = sx * 3.14159265f * 2.0f;
	sy = sy * 2.0f - 1.0f;
	float r = sqrtf(1.0f - sy * sy);
	return Vector3(cosf(sx) * r, sy, sinf(sx) * r);
#endif
}
Vector3
SpecularRefractionShading::shade(const Ray& ray, const HitInfo& hit, const Scene& scene) const
{
	Vector3 L = Vector3(0.0f, 0.0f, 0.0f);

	const Vector3 viewDir = -ray.d; // d is a unit vector

	const Lights *lightlist = scene.lights();

	// loop over all of the lights
	Lights::const_iterator lightIter;
	for (lightIter = lightlist->begin(); lightIter != lightlist->end(); lightIter++)
	{
		PointLight* pLight = *lightIter;

		Vector3 l = pLight->position() - hit.P;

		// the inverse-squared falloff
		float falloff = l.length2();

		// normalize the light direction
		l /= sqrt(falloff);

		// get the diffuse component
		float nDotL = dot(hit.N, l);
		Vector3 result = pLight->color();
		result *= m_kd;

		L += std::max(0.0f, nDotL / falloff * pLight->wattage() / PI) * result;

		Vector3 r = (-l + 2 * dot(l, hit.N) * hit.N).normalized();

		float eDotR = dot(viewDir, r);
		eDotR = 0.0f > eDotR ? 0.0f : 1.0f < eDotR ? 1.0f : eDotR; // clamp it to [0..1]
		eDotR = pow(eDotR, 3);
		L += std::max(0.0f, eDotR * falloff * pLight->wattage());
	}

	// add the ambient component
	L += m_ka;

	return L;
}
Example #10
0
Vector3
Lambert::shade(const Ray& ray, const HitInfo& hit, const Scene& scene, int bounce)
{
    Vector3 L = Vector3(0.0f, 0.0f, 0.0f);
    
    const Vector3 viewDir = -ray.d; // d is a unit vector
    
    const PointLights *lightlist = scene.lights();
    
    // loop over all of the lights
    PointLights::const_iterator lightIter;
    for (lightIter = lightlist->begin(); lightIter != lightlist->end(); lightIter++)
    {
        PointLight* pLight = *lightIter;
    
        Vector3 l = pLight->position() - hit.P;
        
        // the inverse-squared falloff
        float falloff = l.length2();
        
        // normalize the light direction
        l /= sqrt(falloff);

        // get the diffuse component
        float nDotL = dot(hit.N, l);
        Vector3 result = pLight->color();
        result *= m_kd;
        
        L += std::max(0.0f, nDotL/falloff * pLight->wattage() / PI) * result;
    }
    
    // add the ambient component
    L += m_ka;
    
    return L;
}
Example #11
0
    VOID Quaternion::setRotate( const Vector3& from, const Vector3& to )
	{
		// This routine takes any vector as argument but normalized 
		// vectors are necessary, if only for computing the dot product.
		// Too bad the API is that generic, it leads to performance loss.
		// Even in the case the 2 vectors are not normalized but same length,
		// the sqrt could be shared, but we have no way to know beforehand
		// at this point, while the caller may know.
		// So, we have to test... in the hope of saving at least a sqrt
		Vector3 sourceVector = from;
		Vector3 targetVector = to;
		
		F32 fromLen2 = from.length2();
		F32 fromLen;
		// normalize only when necessary, epsilon test
		if ((fromLen2 < 1.0-1e-7) || (fromLen2 > 1.0+1e-7)) 
		{
			fromLen = ::sqrtf(fromLen2);
			sourceVector /= fromLen;
		} 
		else 
			fromLen = 1.0;
		
		F32 toLen2 = to.length2();
		// normalize only when necessary, epsilon test
		if ((toLen2 < 1.0-1e-7) || (toLen2 > 1.0+1e-7)) 
		{
			F32 toLen;
			// re-use fromLen for case of mapping 2 vectors of the same length
			if ((toLen2 > fromLen2-1e-7) && (toLen2 < fromLen2+1e-7)) 
			{
				toLen = fromLen;
			} 
			else toLen = ::sqrtf(toLen2);
			targetVector /= toLen;
		}
		
		
		// Now let's get into the real stuff
		// Use "dot product plus one" as test as it can be re-used later on
		F32 dotProdPlus1 = 1.0f + sourceVector * targetVector;
		
		// Check for degenerate case of full u-turn. Use epsilon for detection
		if (dotProdPlus1 < 1e-7) 
		{
			// Get an orthogonal vector of the given vector
			// in a plane with maximum vector coordinates.
			// Then use it as quaternion axis with pi angle
			// Trick is to realize one value at least is >0.6 for a normalized vector.
			if (::fabs(sourceVector.x()) < 0.6f) 
			{
				const F32 norm = ::sqrtf(1.0f - sourceVector.x() * sourceVector.x());
				_v[0] = 0.0f; 
				_v[1] = sourceVector.z() / norm;
				_v[2] = -sourceVector.y() / norm;
				_v[3] = 0.0f;
			} 
			else if (::fabs(sourceVector.y()) < 0.6f) 
			{
				const F32 norm = ::sqrtf(1.0f - sourceVector.y() * sourceVector.y());
				_v[0] = -sourceVector.z() / norm;
				_v[1] = 0.0f;
				_v[2] = sourceVector.x() / norm;
				_v[3] = 0.0f;
			} 
			else 
			{
				const F32 norm = ::sqrtf(1.0f - sourceVector.z() * sourceVector.z());
				_v[0] = sourceVector.y() / norm;
				_v[1] = -sourceVector.x() / norm;
				_v[2] = 0.0f;
				_v[3] = 0.0f;
			}
		}		
		else 
		{
			// Find the shortest angle quaternion that transforms normalized vectors
			// into one other. Formula is still valid when vectors are colinear
			const F32 s = ::sqrtf(0.5f * dotProdPlus1);
			const Vector3 tmp = sourceVector ^ targetVector / (2.0f*s);
			_v[0] = tmp.x();
			_v[1] = tmp.y();
			_v[2] = tmp.z();
			_v[3] = s;
		}
	}
Example #12
0
Vector3
Lambert::shade(const Ray& ray, const HitInfo& hit, const Scene& scene) const
{
    Vector3 L = Vector3(0.0f, 0.0f, 0.0f);
    
    const Vector3 viewDir = -ray.d; // d is a unit vector
    
    const Lights *lightlist = scene.lights();

    // reflectance
    if (m_ks != 0 && ray.times <3) {
      Vector3 Wr = -2 * dot(ray.d, hit.N) * hit.N + ray.d;
      Wr.normalize();
      Ray r(hit.P + (EPSILON * Wr), Wr);
      HitInfo hi;
      r.times = ray.times + 1;

      if(scene.trace(hi, r))
          L += m_spec * m_ks * hi.material->shade(r, hi, scene);
    }

    // cellular noise texture
    if(m_noisiness > 0) {
      float at[3] = { hit.P.x, hit.P.y, hit.P.z };
      const long mO = 3;
      float F[mO];
      float delta[mO][3];
      unsigned long *ID = new unsigned long();

      WorleyNoise::noise3D(at, mO, F, delta, ID);
      L += m_noisiness * (0.5f * (F[2] - F[1]));// + PerlinNoise::noise(at[0], at[1], at[2]));
    }

    // loop over all of the lights
    Lights::const_iterator lightIter;
    for (lightIter = lightlist->begin(); lightIter != lightlist->end(); lightIter++)
    {
        PointLight* pLight = *lightIter;
    
        Vector3 l = pLight->position() - hit.P;
        
        // the inverse-squared falloff
        float falloff = l.length2();
        
        // normalize the light direction
        l /= sqrt(falloff);

        // get the diffuse component
        float nDotL = dot(hit.N, l);
        Vector3 result = pLight->color();
        result *= f_diff * m_kd;
        
        L += std::max(0.0f, nDotL/falloff * pLight->wattage() / PI) * result;

        // highlights
        //if (m_ks != 0)
        L += m_spec * pLight->color() * m_ks * max(0.f, pow(dot(viewDir, l), SPECULAR_CONST));
          // / dot(hit.N, l);
    }

    // refraction
    if (m_trans != 0 && ray.times <3) {
      float n = (ray.times % 2 == 0) ? (ENV_INDEX / m_refInd) : (m_refInd / ENV_INDEX);
      float wn = dot(viewDir, hit.N);
      if (wn < 0) wn = -wn;

      Vector3 Wt = -1 * n * (viewDir - wn * hit.N) -
        sqrtf(1 - (n * n) * (1 - wn * wn)) * hit.N;
      Wt.normalize();

      Ray r(hit.P + (EPSILON * Wt), Wt);
      r.times = ray.times + 1;
      HitInfo hi;

      if (scene.trace(hi, r))
        L += m_trans * m_kt * hi.material->shade(r, hi, scene);
    }
    
    // add the ambient component
    L += m_ka;

    if(DO_BOUNCE && ray.times < BOUNCES) {
      float v = rand() / (float)RAND_MAX;
      float u = rand() / (float)RAND_MAX;
      Vector3 coord = hemisphereSample_cos(u,v);

      Vector3 unv = Vector3(rand() / (float)RAND_MAX, rand() / (float)RAND_MAX, rand() / (float)RAND_MAX);
      Vector3 v1 = cross(hit.N, unv);
      Vector3 v2 = cross(v1, hit.N);
      Vector3 dir = coord.x * v1 + coord.z * hit.N + coord.y * v2;
      dir.normalize();
      Ray r(hit.P, dir);
      r.times = ray.times + 1;
      HitInfo hi;

      if(scene.trace(hi, r))
        L+= m_kd * dot(r.d, hit.N) * hit.material->shade(r, hi, scene);
    }
    
    return L;
}
Example #13
0
Vector3
Specular::shade(const Ray& ray, const HitInfo& hit, const Scene& scene) const
{
    printf("Shading specular\n");
    Vector3 L = Vector3(0.0f, 0.0f, 0.0f);

    const Vector3 viewDir = -ray.d; // d is a unit vector

    const Lights *lightlist = scene.lights();
    Vector3 color = Vector3(m_kd);
    if (hit.material->hasTexture()) {
        Vector3 c = Vector3(hit.P);
		color = m_texture->getColor(c);
    }

    // loop over all of the lights

    HitInfo lightHitReflect = HitInfo(hit);
    HitInfo lightHitRefract = HitInfo(hit);
    lightHitReflect.hitNum = hit.hitNum;
    lightHitRefract.hitNum = hit.hitNum;

    Lights::const_iterator lightIter;
    for (lightIter = lightlist->begin(); lightIter != lightlist->end(); lightIter++)
    {
        PointLight* pLight = *lightIter;
        Ray lightRay;

        Vector3 l = pLight->position() - hit.P;
        float falloff = l.length2();
        l /= sqrt(falloff);

        /* Calculate the diffuse component - From Labertian Shading Model */
        float nDotL = dot(hit.N, l);
        Vector3 diffuseResult = pLight->color();
        diffuseResult *= color;
        L += std::max(0.0f, nDotL/falloff * pLight->wattage() / PI) * diffuseResult;

        /* Calculate the specular highlight - From Phong Shading Model */
        Vector3 h = (viewDir + l).normalize();
        float nDotH = dot(hit.N, h);
        Vector3 specResult = pLight->color();
        specResult *= m_ks;
        L += pow(std::max(0.0f, nDotH/falloff * pLight->wattage() / PI), m_p) * specResult;

        /* Calculate the specular reflectance */
        if(lightHitReflect.hitNum < 1){
            Vector3 r = reflect(hit.N, ray.d);
            lightRay.d = r.normalize();
            lightRay.o = hit.P;
            if(scene.trace(lightHitReflect, lightRay, 0.0001, r.length())){
                lightHitReflect.hitNum = lightHitReflect.hitNum+1;
                L += lightHitReflect.material->shade(lightRay, lightHitReflect, scene)*m_rl;
            }
        }

        /* Calculate the specular refractance */
        // Vector3 incident = viewDir - hit.P;

        if(lightHitRefract.hitNum < 1 && m_rf > 0.0f ){
            Vector3 t = refract(hit.N, ray.d, hit.material->n(), m_n);
            if(t != Vector3(0.0f))
            lightRay.d = t.normalize();
            else lightRay.d = t;
            lightRay.o = hit.P;
            if(scene.trace(lightHitRefract, lightRay, 0.0001, t.length())){
                lightHitRefract.hitNum = lightHitRefract.hitNum+1;
                    L+=lightHitRefract.material->shade(lightRay, lightHitRefract, scene)*m_rf;
            } else {
                L+=scene.getBGColor()*m_rf;
            }
        }
    }

    return L;
}
Example #14
0
void Quaternion::setRotation(const Vector3 &v1,const Vector3 &v2) {
  Quaternion q;
  Vector3 a = v1.cross(v2);
  this->set(sqrt(v1.length2() * v2.length2()) + v1.dot(v2),a);
  this->normalize();
}
Example #15
0
//Blinn-Phong shading model
Vector3
Specular::shade(Ray& ray, const HitInfo& hit, const Scene& scene) const
{
    Vector3 reflected = Vector3(0.0f, 0.0f, 0.0f);
    Vector3 L = Vector3(0.0f, 0.0f, 0.0f);
    
    //scale down intensity of light in proportion to num of ray bounces
    Vector3 attenuation = k_s * ( 1 / (ray.numBounces+1));
    
    const Lights *lightlist = scene.lights();
    
    // loop over all of the lights
    Lights::const_iterator lightIter;
    for (lightIter = lightlist->begin(); lightIter != lightlist->end(); lightIter++)
    {
        //find reflected vector, given normal and incident light direction
        PointLight* pLight = *lightIter;
        
        //light vector points from hit point to light
        Vector3 l = pLight->position() - hit.P;
        
        //why did we use ray.d here instead of l? Would just need to change calculation a bit
        //to use l
        reflected = ray.d - 2.0f * (dot(hit.N, ray.d)) * hit.N;

        if (ray.numBounces < maxBounces)
        {
            //trace from reflected vector now
            Ray reflect(ray.numBounces + 1);
            reflect.o = hit.P;
            reflect.d = reflected;
            HitInfo hitReflect;
        
            if (scene.trace(hitReflect, reflect, 0.008f))
            {
                //get color from object hit
                //printf("Bounced reflected ray hit something!\n");
                L += attenuation * hitReflect.material->shade(reflect, hitReflect, scene);
            }
            else
            {
                //get color from background
                L += Vector3(0,0,0.5f);//bgColor;
            }
        }

        //Get halfway vector
        Vector3 h = (L + -1 * ray.d).normalize();
        
        Ray shadow_ray(0);
        HitInfo hi;
        
        shadow_ray.o = hit.P;
        shadow_ray.d = l;
        
        //std::cout<<"M = "<<M<< " hit.N = "<<hit.N<<std::endl;

        if (scene.trace(hi, shadow_ray, 0.001f, sqrt(l.length2())))
        {
            // We are in shadow
        }
        else
        {
            //get color of light
            Vector3 color = pLight->color();
            
            //flip vector from eye so points from hit point back to eye
            //L += k_s * color * pow(std::max(0.0f, dot(h, hit.N)), shinyExp);
            //L += attenuation * color * pow(std::max(0.0f, dot(reflected, -ray.d)), shinyExp);
            
            //Specular Highlights
            //This is separate from the reflection calculation because it
            //needs to be dependent on just the shinyExp
            //https://en.wikipedia.org/wiki/Specular_highlight
            
            //Specular calculation for ABSORBED light
            L += attenuation * pow(std::max(0.0f, dot(h, hit.N)), 50* shinyExp);

	    //check entering or exiting and change n1/n2 n2/n1
           //dot product ray.dot.normal  
            //Specular Refraction
            //L += attenuation * color * pow(std::max(0.0f, dot(wt, -ray.d)), shinyExp);
            //std::cout<<"Final Refraction vector = "<<(k_s * color * pow(std::max(0.0f,
            //dot(wt,ray.d)), shinyExp))<<std::endl;
        }
    }
    
    return L;
}
Example #16
0
Vector3
PencilShader::shade(const Ray& ray, const HitInfo& hit, const Scene& scene) const
{

    int m = 0;
    int totalRays = 0;
    float step = (float)RAD_H/SAMPLES;
    std::vector<Vector3> normals;
    std::vector<HitInfo> hits;

    for(float r = step; r <= RAD_H; r+=step){
        float theta_step = (2.0*M_PI)/(pow(2, r+2));
        for(float theta = 0; theta <= 2.0*M_PI; theta += theta_step){
            totalRays++;
            float x = r*cos(theta);
            float y = r*sin(theta);
            Ray stencilRay;
            Vector3 dir = Vector3(ray.d);
            dir.x += x;
            dir.y += y;
            stencilRay.o = ray.o;
            stencilRay.d = dir;

            HitInfo h;
            if(scene.trace(h, stencilRay)){

                if(h.objId != hit.objId){
                    m++;
                } else{
                    normals.push_back(Vector3(h.N));
                    hits.push_back(h);

                }
            } else m++;
        }
    }

    //Hit other geometry, outline edge
    if(m > 0){
        return Vector3(0.0f);
    }

    float gradient = 0.0;
    //Check for creases or silhouettes
    for(int i = 0; i <= normals.size(); i++){
        gradient += (dot(normals[i], hit.N))/normals.size();
        if(gradient < 0.01)
            return Vector3(0.0f);
    }

    Vector3 L = Vector3(0.0f, 0.0f, 0.0f);
    const Lights *lightlist = scene.lights();
    Ray shadow;
    shadow.o = hit.P - ray.o;

    Lights::const_iterator lightIter;
    for (lightIter = lightlist->begin(); lightIter != lightlist->end(); lightIter++)
    {
        PointLight* pLight = *lightIter;

        Vector3 l = pLight->position() - hit.P;

        // the inverse-squared falloff
        float falloff = l.length2();

        // normalize the light direction
        l /= sqrt(falloff);

        // get the diffuse component
        shadow.d = l;
        float nDotL = dot(hit.N, l);
        //Map into color location
        L += getTextureColor(nDotL, hit);
    }
    return L;
}
bool within(Vector3 p, Vector3 r, double rMax, const Grid& g) {
  double r2 = rMax*rMax;
  Vector3 d = g.wrapDiff(p - r);
  return (d.length2() < r2);
}
const Vector3 RectangleLight::sampleLight(const unsigned int threadID, const Vector3 &from, const Vector3 &normal, const float time, const Scene &scene, const Vector3 &rVec, float &outSpec, bool isSecondary) const
{
	Ray sampleRay(threadID);
	HitInfo sampleHit;
	Vector3 randDir = 0, tmpResult = 0;
	float e1, e2, tmpSpec = 0;
	bool cutOff = false;
	int samplesDone = 0;
	float samplesDoneRecip = 1.0f;
	ALIGN_SSE float falloff = 1.0f;

	do
	{
		// Get a random vector into the light
		e1 = Scene::getRand(threadID);
		e2 = Scene::getRand(threadID);
		e2 = (e2 > 0.99) ? 0.99 : e2;
		randDir = ((m_v1 + e1*(m_v2-m_v1) + e2*(m_v3-m_v1)) - from);

		float nDotL = dot(normal, randDir);
		Vector3 E   = 0;
		float attenuate = 1.0f;

		if (nDotL > epsilon)															// Only do work if light can be hit
		{
			// the inverse-squared falloff
			falloff = randDir.length2();
			ALIGN_SSE float distanceRecip, distance;
#ifndef NO_SSE
			fastrsqrtss(setSSE(falloff), distanceRecip);
			recipss(setSSE(falloff), falloff);
			recipss(setSSE(distanceRecip), distance);
#else
			distance      = sqrtf(falloff);
			distanceRecip = 1.0f / distance;
			falloff       = 1.0f / falloff;
#endif
			randDir *= distanceRecip;
			nDotL   *= distanceRecip;

			if (m_castShadows)
			{
				sampleHit.t = distance - epsilon;									// We need this to account for the fact that we CAN hit geometry, to avoid false positives.
				if (m_fastShadows)
				{
					sampleRay.set(threadID, from, randDir, time, 1.001f, 0, 0, IS_SHADOW_RAY);		// Create shadow ray
					if (scene.trace(threadID, sampleHit, sampleRay, epsilon))					// Quick method, returns any hit
					{
						attenuate = 0.0f;
					}
				}
				else																// Full method, accounts for transparency effects
				{
					float distanceTraversed = 0.0f;
					sampleRay.set(threadID, from, randDir, time, 1.001f, 0, 0, IS_PRIMARY_RAY);		// Create primary ray
					while (distanceTraversed < distance && attenuate > epsilon)
					{
						if (scene.trace(threadID, sampleHit, sampleRay, epsilon))				
						{
							Vector3 hitN; sampleHit.getInterpolatedNormal(hitN);
							float nDL = dot(hitN, -randDir);
							if (nDL > 0.0)											// Only attenuate on incoming direction
							{
								attenuate *= sampleHit.obj->m_material->refractAmt();
							}
							Vector3 newP = Vector3(sampleRay.o[0], sampleRay.o[1], sampleRay.o[2]) + sampleHit.t * randDir;
							sampleRay.set(threadID, newP, randDir, time, 1.001f, 0, 0, IS_PRIMARY_RAY);
							distanceTraversed += sampleHit.t;
						}
						else
						{
							distanceTraversed = distance;
						}
					}
				}
			}
		}
		else
		{
			attenuate = 0.0f;														
		}

		E = m_power * falloff * _1_4PI;										// Light irradiance for this sample
		samplesDone++;
		samplesDoneRecip = 1.0f / (float)samplesDone;

		cutOff = (E * samplesDoneRecip).average() < m_noiseThreshold;		// Stop sampling if contribution is below the noise threshold

		tmpResult += E * attenuate;
		tmpSpec   += max(0.f, dot(rVec, randDir)) * attenuate;

	}  while (samplesDone < m_numSamples && !cutOff);

	outSpec = tmpSpec * samplesDoneRecip;
	return tmpResult * samplesDoneRecip;
}
Vector3
RefractiveInterface::shade(const Ray& ray, const HitInfo& hit, const Scene& scene, const bool& isFront) const
{
    Ray rayLight;
    HitInfo hitLight;
    Vector3 L = Vector3(0.0f, 0.0f, 0.0f);

    const Vector3 viewDir = -ray.d; // d is a unit vector

    const PointLights *plightlist = scene.pointLights();
    // loop over all of the POINT lights
    PointLights::const_iterator plightIter;
    for (plightIter = plightlist->begin(); plightIter != plightlist->end(); plightIter++)
    {
        PointLight* pLight = *plightIter;
        Vector3 l = pLight->position() - hit.P;
        rayLight.o = hit.P;
        rayLight.d = l.normalized();
        Vector3 brdf = BRDF(rayLight.d, hit.N, -ray.d, isFront);
        if (brdf == 0) continue;
        if (scene.trace(hitLight, rayLight, 0.0001, l.length())) continue;

        // the inverse-squared falloff
        float falloff = l.length2();

        float nDotL = fabs(dot(hit.N, l));
        Vector3 result = pLight->color();

        L += nDotL / falloff * pLight->wattage() *brdf * result;
    }

    const AreaLights *alightlist = scene.areaLights();
    // loop over all of the lights
    AreaLights::const_iterator alightIter;
    for (alightIter = alightlist->begin(); alightIter != alightlist->end(); alightIter++)
    {
        AreaLight* aLight = *alightIter;
        vec3pdf vp = aLight->randPt();
        Vector3 l = vp.v - hit.P; // shoot a shadow ray to a random point on the area light
        rayLight.o = hit.P;
        rayLight.d = l.normalized();

        Vector3 brdf = BRDF(rayLight.d, hit.N, -ray.d, isFront);
        if (brdf == 0) continue;
        // if the shadow ray hits the "backside of the light" continue to the next area light
        if (!aLight->intersect(hitLight, rayLight)){
            continue;
        }
        // if the shadow ray is occluded by another (hence the "skip") object continue the next light
        if (scene.trace(hitLight, rayLight, aLight, 0.0001, l.length())){
            continue;
        }

        // the inverse-squared falloff
        float falloff = l.length2();

        float nDotL = fabs(dot(hit.N, l));
        Vector3 result = aLight->color();

        L += std::max(0.0f, dot(hitLight.N, -l))* 0.0f, nDotL / falloff*
            aLight->wattage() / aLight->area() *brdf * result / (vp.p);
    }

    // add the ambient component
    L += m_ka;

    return L;
}
Example #20
0
Vector3
CoolWarmShader::shade(const Ray& ray, const HitInfo& hit, const Scene& scene) const
{
    if(m_edges){
        Vector3 hitPoint = hit.P - ray.o;
        int m = 0;
        int totalRays = 0;
        float step = (float)RAD_H/SAMPLES;
        std::vector<Vector3> normals;
        for(float r = step; r <= RAD_H; r+=step){
            float theta_step = (2.0*M_PI)/(pow(2, r+2));
            for(float theta = 0; theta <= 2.0*M_PI; theta += theta_step){
                totalRays++;
                float x = r*cos(theta);
                float y = r*sin(theta);
                Ray stencilRay;
                Vector3 dir = Vector3(ray.d);
                dir.x += x;
                dir.y += y;
                stencilRay.o = ray.o;
                stencilRay.d = dir;

                HitInfo h;
                if(scene.trace(h, stencilRay)){

                    if(h.objId != hit.objId){
                        m++;
                    } else{
                        normals.push_back(h.N);
                    }
                } else m++;
            }
        }


    }


    Vector3 L = Vector3(0.0f, 0.0f, 0.0f);

    const Vector3 viewDir = -ray.d; // d is a unit vector

    const Lights *lightlist = scene.lights();
    Vector3 color = Vector3(m_kd);
    if (hit.material->hasTexture()) {
        Vector3 c = Vector3(hit.P);
		color = m_texture->getColor(c);
    }
    // loop over all of the lights
    Lights::const_iterator lightIter;
    for (lightIter = lightlist->begin(); lightIter != lightlist->end(); lightIter++)
    {
        PointLight* pLight = *lightIter;

        Vector3 l = pLight->position() - hit.P;

        // the inverse-squared falloff
        float falloff = l.length2();

        // normalize the light direction
        l /= sqrt(falloff);

        // get the diffuse component
        float nDotL = dot(hit.N, l);
        //Map into color location
        L += getCellColor(nDotL);
    }
    
    return L;
}