コード例 #1
0
ファイル: superellipsoid.cpp プロジェクト: SinaC/OldRaytrace
//   Try to find the root of a superquadric using Newtons method.
bool PrimitiveSuperellipsoid::checkHit2( const TRay &ray, const float t0,
					 TVector3 &P0, float v0,
					 const float t1,
					 float *t, TVector3 &Q ) const {
  float dt0 = t0;
  float dt1 = t0 + 0.0001f * (t1 - t0);
  float maxdelta = t1 - t0;

  for ( int i = 0; (dt0 < t1) && (i < MAX_ITERATIONS); i++ ) {
    float deltat = 0.0f;
    TPoint3 P1 = ray.origin + ( ray.direction * dt1 );
    float v1 = evaluateSuperellipsoid( P1 );
    if ( v0 * v1 < 0.0f ) {
      // Found a crossing point, go back and use normal root solving.
      solveHit1( v0, P0, v1, P1, Q );
      TVector3 P0 = Q - ray.origin;
      *t = P0.magnitude();
      return true;
    }
    else {
      if ( fabsf(v1) < ZERO_TOLERANCE) {
	Q = ray.origin + ( ray.direction * dt1 );
	*t = dt1;
	return true;
      }
      else {
        if (((v0 > 0.0f) && (v1 > v0)) || ((v0 < 0.0f) && (v1 < v0)))
          // We definitely failed
          break;
        else {
          if ( v1 == v0 )
            break;
          else
            deltat = v1 * (dt1 - dt0) / (v1 - v0);
        }
      }
    }

    if ( fabsf(deltat) > maxdelta )
       break;

    v0 = v1;
    dt0 = dt1;
    dt1 -= deltat;
  }

  return false;
}