/* PhBBoxTextureProjection.C: PhBBoxTextureProjection nodes (public source) */

#include "PhBBoxTextureProjection.H"
#include <math.h>

namespace xrml {

void PhBBoxTextureProjection::render(void)
{
  if (fabs(size.x) < EPSILON) size.x = 1.;
  if (fabs(size.y) < EPSILON) size.y = 1.;
  if (fabs(size.z) < EPSILON) size.z = 1.;
}

Vec3 PhBBoxTextureProjection::object2surface(const Vec3& objectCoord,
					     Vec3 *x,
					     Vec3 *y,
					     Vec3 *z)
{
  Vec3 u = (Vec3)objectCoord / (Vec3)size;
  double xd = fabs(u.x);
  double yd = fabs(u.y);
  double zd = fabs(u.z);

  // generate (u,v) according to VRML-spec (6.07)
  // and generate axis (Z = surface-normal)
  if ((xd > yd) && (xd > zd))
    if (u.x > 0)                                  // X+
    {
      if (x && y && z) {
	*x = Vec3( 0,  0, -1);
	*y = Vec3( 0,  1,  0);
	*z = Vec3( 1,  0,  0);
      }
      return Vec3( .5 - u.z , .5 + u.y  , 0. );
    }                                           // X-
    else {
      if (x && y && z) {
	*x = Vec3( 0,  0,  1);
	*y = Vec3( 0,  1,  0);
	*z = Vec3(-1,  0,  0);
      }
      return Vec3( .5 + u.z , .5 + u.y , 0 );
    }
  else if (yd > zd) 
    if (u.y > 0)
    {                                           // Y+
      if (x && y && z) {
	*x = Vec3( 1, 0,  0);
	*y = Vec3( 0, 0, -1);
	*z = Vec3( 0, 1,  0);
      }
      return Vec3( .5 + u.x , .5 - u.z , 0 );
    }
    else {                                      // Y-
      if (x && y && z) {
	*x = Vec3( 1,  0,  0);
	*y = Vec3( 0,  0,  1);
	*z = Vec3( 0, -1,  0);
      }
      return Vec3( .5 + u.x , .5 + u.z , 0 );
    }
  else if(u.z > 0)                                // Z+
    {
      if (x && y && z) {
	if(x) *x = Vec3( 1,  0,  0);
	if(y) *y = Vec3( 0,  1,  0);
	if(z) *z = Vec3( 0,  0,  1);
      }
      return Vec3( .5 + u.x , .5 + u.y , 0 );
    }
    else {                                      // Z-
      if (x && y && z) {
	if(x) *x = Vec3(-1,  0,  0);
	if(y) *y = Vec3( 0,  1,  0);
	if(z) *z = Vec3( 0,  0, -1);
      }
      return Vec3( .5 - u.x , .5 + u.y , 0 );
    }
}

}  // namespace xrml
