Пример #1
0
//////////////////////////////////////////////////////////////////////////
// Given the position, normal, and set of rays compute the bent normal and
// occlusion term.
//////////////////////////////////////////////////////////////////////////
void
ComputeOcclusion (NmRawPointD* newPos, NmRawPointD* newNorm, int numTris,
                  NmRawTriangle* tri, AtiOctree* octree, int numRays,
                  NmRawPointD* rays, double* rayWeights,
                  NmRawPointD* bentNormal, double* occlusion,
                  int& gMaxCells, AtiOctreeCell** &gCell)
{
#ifdef _DEBUG
 if ((newPos == NULL) || (newNorm == NULL) || (tri == NULL) ||
  (octree == NULL) || (rays == NULL) || (rayWeights == NULL) ||
  (bentNormal == NULL) || (occlusion == NULL))
 {
  //NmPrint ("ERROR: Incorrect arguments passed!\n");
  exit (-1);
 }
#endif
 // Clear results. 
 // Bent normal should at minimum be the regular normal (I think).
 bentNormal->x = newNorm->x;
 bentNormal->y = newNorm->y;
 bentNormal->z = newNorm->z;
 (*occlusion) = 0.0;
 double hit = 0.0f;
 double num = 0.0f;

 // Compute offset vertex
 NmRawPointD pos;
 pos.x = newPos->x + (newNorm->x * gDistanceOffset);
 pos.y = newPos->y + (newNorm->y * gDistanceOffset);
 pos.z = newPos->z + (newNorm->z * gDistanceOffset);

 // Compute rotation matrix to match hemisphere to normal
 double rotMat[16];
 FromToRotation (rotMat, gZVec, newNorm->v);

 // Shoot the rays
 for (int r = 0; r < numRays; r++)
 {
  // First rotate the ray into position
  NmRawPointD oRay;
  oRay.x = rays[r].x*rotMat[0] + rays[r].y*rotMat[4] + rays[r].z*rotMat[8];
  oRay.y = rays[r].x*rotMat[1] + rays[r].y*rotMat[5] + rays[r].z*rotMat[9];
  oRay.z = rays[r].x*rotMat[2] + rays[r].y*rotMat[6] + rays[r].z*rotMat[10];

  // Walk the Octree to find triangle intersections.
  bool intersect = false;
  int numCells = 0;
  int cellCount = 0;
  int triCount = 0;
  AddCell (octree->m_root, &numCells, gMaxCells, gCell);
  while ((numCells > 0) && !intersect)
  {
   // Take the cell from the list.
   cellCount++;
   numCells--;
   AtiOctreeCell* currCell = gCell[numCells];

   // See if this is a leaf node
   bool leaf = true;
   for (int c = 0; c < 8; c++)
   {
    if (currCell->m_children[c] != NULL)
    {
     leaf = false;
     break;
    }
   }

   // If we are a leaf check the triangles
   if (leaf)
   {
    // Run through the triangles seeing if the ray intersects.
    for (int t = 0; t < currCell->m_numItems; t++)
    {
     // Save off current triangle.
     NmRawTriangle* currTri = &(tri[currCell->m_item[t]]);
     triCount++;

     // See if it intersects.
     double oT, oU, oV;
     if (IntersectTriangle (pos.v, oRay.v, currTri->vert[0].v,
      currTri->vert[1].v, currTri->vert[2].v,
      &oT, &oU, &oV))
     {
      if (oT > 0.0f)
      {
       intersect = true;
       break;
      }
     }
    } // end for t (num triangles in this cell)
   } // end if leaf
   else
   {  // Non-leaf, add the children to the list if their bounding
    // box intersects the ray.
    for (int c = 0; c < 8; c++)
    {
     if (currCell->m_children[c] != NULL)
     {
      // Save off current child.
      AtiOctreeCell* child = currCell->m_children[c];

      // If the ray intersects the box
      if (RayIntersectsBox (&pos, &oRay, &child->m_boundingBox))
      {
       AddCell (child, &numCells, gMaxCells, gCell);
      } // end if the ray intersects this bounding box.
      // else do nothing, we'll never intersect any triangles
      // for it's children.
     } // end if we have a cell
    } // end for c (8 children)
   } // end else non-leaf node.
  } // end while cells

  // Update our running results based on if we found and intersection.
  num += rayWeights[r];
  if (!intersect)
  {
   bentNormal->x += (oRay.x * rayWeights[r]);
   bentNormal->y += (oRay.y * rayWeights[r]);
   bentNormal->z += (oRay.z * rayWeights[r]);
  }
  else
  {
   hit += rayWeights[r];
  }
  /*      
  // Save off some stats.
  if (triCount > gAOMaxTrisTested)
  {
  gAOMaxTrisTested = triCount;
  }
  if (cellCount > gAOMaxCellsTested)
  {
  gAOMaxCellsTested = cellCount;
  }
  */
 } // end for r (number of rays)

 // Normalize result
 Normalize (bentNormal->v);
 (*occlusion) = (num - hit) / num;
} // end of ComputeOcclusion
Пример #2
0
Matrix3	Matrix3::CreateRotation( const Vec3D& vFrom, const Vec3D& vTo )
{
	FLOAT mat[3][3];
	FromToRotation( vFrom.ToPtr(), vTo.ToPtr(), mat );
	return Matrix3( mat );
}