Exemplo n.º 1
0
// check if a clause subsumes another clause. subsumed clause
// must have MORE elements than the subsuming clause.
//
int
ST(Array<Literal> &C, Array<Literal> &D, int i, int j, Substitutions &theta)
{
	// check if clause D literals are exhausted
	if (j > D.getSize())
	{
		return(NOMATCH);
	}

	// search for a possible unifying literal
	int a = j;
	Literal Li(C[i]);
	if (theta.applyTo(Li) != OK)
	{
		ERROR("applyTo failed.", errno);
		return(NOTOK);
	}
	Substitutions mu;
	for ( ; a <= D.getSize(); a++)
	{
		mu.clear();
		Literal Ka(D[a]);
		if (unify(Li, Ka, mu) == OK)
			break;
	}
	if (a > D.getSize())
	{
		return(NOMATCH);
	}

	// attempt to extend the matching
	Substitutions theta_mu(theta*mu);
	// if (i == C.getSize() || ST(C, D, i+1, 1, theta*mu) == OK)
	if (i == C.getSize() || ST(C, D, i+1, 1, theta_mu) == OK)
	{
		return(OK);
	}
	else
		return(ST(C, D, i, a+1, theta));
}
Exemplo n.º 2
0
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * TRACE ALGORITHM * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
ngl::Colour Renderer::trace(ngl::Vec3 _from, ngl::Vec3 _direction, int depth)
{
  // create vector that will store intersection values for parameter t in the primary ray
  // a primary ray has a form like R = O + t * D where O is the origin vector, and D direction.
  std::vector<double> intersections;
  geo::Ray cam_ray(_from,_direction);

  // iterate over objects in the scene and find intersections
  for(unsigned int i = 0; i < m_scene->m_objects.size(); i++)
  {
    // each Shape subclass (Sphere, Plane...) has its own method for calculating intersections
    intersections.push_back( m_scene->m_objects.at(i)->getIntersection(cam_ray));
  }

  // find closest object
  int closest_index = getIndexClosest(intersections);

  // if no intersections are found RETURN black =
  if(closest_index == -1) {return ngl::Colour(0,0,0,1);}

  // calculate pHit (position of the new intersection) and nHit (normal at hit point)
  ngl::Vec3 pHit = _from + intersections.at(closest_index) * _direction;
  ngl::Vec3 nHit = m_scene->m_objects.at(closest_index)->getNormalAt(pHit);

  // calculate if we are inside or outside
  bool inside = false;
  if(_direction.dot(nHit) > 0)
  {
    nHit = -nHit;
    inside = true;
  }

 float bias = 0.01;
 // calculate if point is obscured or shadowed
 bool isObscured = raycast(pHit + nHit * bias, closest_index);

                      // // // // // // // // // // // // //
                      //  put all contributions together  //
                      // // // // // // // // // // // // //

  // is the object reflective or refractive???
  if ((m_scene->m_objects.at(closest_index)->getMaterial()->isReflective() ||
      m_scene->m_objects.at(closest_index)->getMaterial()->isRefractive()) &&
      depth < m_max_depth)
  {
    ngl::Colour crfr(0,0,0,1);
    ngl::Colour crfl(0,0,0,1);
    // check whether it is REFLECTIVE
    if (m_scene->m_objects.at(closest_index)->getMaterial()->isReflective())
    {
      // calculate reflection dir
      float bias = 0.01;
      ngl::Vec3 refl_dir = _direction - nHit * 2 * _direction.dot(nHit);
      refl_dir.normalize();

      // fire ray along reflection direction from hit point
      crfl = trace(pHit + bias*nHit, refl_dir, depth+1);
    }

    // check whether it is REFRACTIVE
    if (m_scene->m_objects.at(closest_index)->getMaterial()->isRefractive())
    {
      // calculate refrection dir (transmission ray)
      float ior = m_scene->m_objects.at(closest_index)->getMaterial()->getIOR();
      float eta = inside;
      float bias = 0.01;
      float cosi = -nHit.dot(_direction);

      if (eta == true) // we are inside
      {
        eta = ior;
      }
      else // we are outside
      {
        eta = 1 / ior;
      }

      float k = 1 - eta * eta * (1 - cosi * cosi);
      ngl::Vec3 refr_dir = _direction * eta + nHit * (eta * cosi - sqrt(k));
      refr_dir.normalize();
      crfr = trace(pHit - nHit * bias, refr_dir, depth+1);
    }

    ngl::Colour surfaceColor = m_scene->m_objects.at(closest_index)->getColour(pHit);
    float cosineFactor = std::max(-nHit.dot(cam_ray.getDirection()),(float)0);
    float attenuation;

    ngl::Colour Ka(1,0,0.4,1);
    ngl::Colour Kd;
    ngl::Colour Ks;

    float ambient_intensity = 0.05;

    ngl::Colour ambient_contrib = Ka * surfaceColor * ambient_intensity;
    ngl::Colour diffuse_contrib(0,0,0,1);
    ngl::Colour specular_contrib(0,0,0,1);

    for(unsigned int m = 0; m < m_scene->m_lights.size(); m++)
    {
      ngl::Vec3 v_distance = m_scene->m_lights.at(m)->m_pos - pHit;
      float distance = v_distance.length();
      float radius = 8;
      attenuation = 1 - pow(distance/radius,2);

      Kd = m_scene->m_lights.at(m)->m_diff_col;
      Ks = m_scene->m_lights.at(m)->m_spec_col;

      ngl::Vec3 L = m_scene->m_lights.at(m)->m_pos - pHit;
      L.normalize();
      ngl::Vec3 N = nHit;
      ngl::Vec3 R = 2 * (L.dot(N) * N) - L;
      R.normalize();

      diffuse_contrib  += (surfaceColor * (Kd * pow(std::max(L.dot(N),(float)0),2) * m_scene->m_lights.at(m)->m_diff_int))*attenuation;
      specular_contrib += ((Ks * pow(std::max(R.dot(-_direction),(float)0),900)*400 * m_scene->m_lights.at(m)->m_spec_int))*attenuation;
    }

    specular_contrib.clamp(0,0.8);

    ngl::Colour s01 = crfl * m_scene->m_objects.at(closest_index)->getMaterial()->getReflIntensity();
    ngl::Colour s02 = crfr * m_scene->m_objects.at(closest_index)->getMaterial()->getTransparency();
    ngl::Colour s03 = s01 + s02;
    ngl::Colour diffuseColor = m_scene->m_objects.at(closest_index)->getColour(pHit) * cosineFactor * m_scene->m_objects.at(closest_index)->getMaterial()->getDiffuseIntensity();

    // Do PHONG MODEL calculations stuff. By now I keep it VERY VERY simple
    ngl::Colour outRadiance = diffuseColor + s03 + specular_contrib + ambient_contrib;
    outRadiance.clamp(0,1);

    return isObscured ? outRadiance * 0.7f : outRadiance;
  }

  // if it is not REFLECTIVE nor REFRACTIVE
  else
  {
    ngl::Colour surfaceColor = m_scene->m_objects.at(closest_index)->getColour(pHit);
    float attenuation;

    ngl::Colour Ka(1,0,0.4,1);
    ngl::Colour Kd;
    ngl::Colour Ks;

    float ambient_intensity = 0.05;

    ngl::Colour ambient_contrib = Ka * surfaceColor * ambient_intensity;
    ngl::Colour diffuse_contrib(0,0,0,1);
    ngl::Colour specular_contrib(0,0,0,1);

    for(unsigned int m = 0; m < m_scene->m_lights.size(); m++)
    {
      ngl::Vec3 v_distance = m_scene->m_lights.at(m)->m_pos - pHit;
      float distance = v_distance.length();
      float radius = 8;
      attenuation = 1 - pow(distance/radius,2);

      Kd = m_scene->m_lights.at(m)->m_diff_col;
      Ks = m_scene->m_lights.at(m)->m_spec_col;

      ngl::Vec3 L = m_scene->m_lights.at(m)->m_pos - pHit;
      L.normalize();
      ngl::Vec3 N = nHit;
      ngl::Vec3 R = 2 * (L.dot(N) * N) - L;
      R.normalize();

      float spec_hardness = m_scene->m_objects.at(closest_index)->getMaterial()->m_spec_hardness;

      diffuse_contrib  += (surfaceColor * (Kd * pow(std::max(L.dot(N),(float)0),2) * m_scene->m_lights.at(m)->m_diff_int))*attenuation;
      specular_contrib += ((Ks * pow(std::max(R.dot(-_direction),(float)0),spec_hardness) * m_scene->m_lights.at(m)->m_spec_int))*attenuation;
    }

    diffuse_contrib.clamp(0,1);
    specular_contrib.clamp(0,1);

    ngl::Colour outRadiance = diffuse_contrib + specular_contrib + ambient_contrib;

    outRadiance.clamp(0,1);

    return isObscured ? outRadiance * 0.7f : outRadiance;
  }
}
Exemplo n.º 3
0
//------------------------------------------------------------------------------------------------------------------------------------
// called when we want to draw the 3D data in our app.
//------------------------------------------------------------------------------------------------------------------------------------
void draw3D()
{
	// draw the grid on the floor
	setColour(0.25f, 0.25f, 0.25f);
	for(float i = -10.0f; i <= 10.1f; i += 1.0f)
	{
		Vec3 zmin(i, 0, -10);
		Vec3 zmax(i, 0,  10);
		Vec3 xmin(-10, 0, i);
		Vec3 xmax(10, 0, i);
		drawLine(xmin, xmax);
		drawLine(zmin, zmax);
	}

	// If using the GPU to compute the lighting (which is what you want to do!)
	if(!g_manualLighting)
	{
		// turn on lighting
		enableLighting();

		// set the diffuse material colour (this will be modulated by the effect of the lighting)
		setColour(1.0f, 1.0f, 1.0f);

		// draw the cube geometry
		drawPrimitives(g_pointsVN, 24, kQuads);

		// turn off lighting
		disableLighting();
	}
	else
	{
		// otherwise, compute the lighting manually. Don't ever do this in practice! It's insane! (But it may be useful for educational purposes)

		// The direction from the vertex to the light (effectively sunlight in this case!).
		Vec3 L(-0.6f, 1.0f, -0.2f);

		// make sure L has been normalised!
		L = normalize(L);

		// start drawing some quads
		begin(kQuads);

		// loop through each vertex normal
		for(int i = 0; i < 24; ++i)
		{
			// compute N.L
			// Make sure we clamp this to zero (so that we ignore any negative values).
			float N_dot_L = std::max(dot(L, g_pointsVN[i].n), 0.0f);

			// the ambient material colour (always gets added to the final colour)
			Vec3 Ka(0.2f, 0.2f, 0.2f);

			// the diffuse material colour
			Vec3 Kd(1.0f, 1.0f, 1.0f);

			// Compute the final colour
			Vec3 colour = Ka + (Kd * N_dot_L);

			// set the vertex colour 
			setColour(colour);

			// specify the vertex
			addVertex(g_pointsVN[i].v);
		}

		// finish drawing our quads
		end();
	}

	// if we are displaying normals
	if(g_displayNormals)
	{
		// make colour pink
		setColour(1.0f, 0.0f, 1.0f);

		// loop through each vertex
		for(int i = 0; i < 24; ++i)
		{
			// compute an offset (along the normal direction) from the vertex
			Vec3 pn = g_pointsVN[i].v + (g_pointsVN[i].n * 0.2f);

			// draw a line to show the normal
			drawLine(g_pointsVN[i].v, pn);
		}
	}
}