// PhBSurface.H: PhBSurface nodes.

// This file has been generated using nodegen 0.5a.
// Restrict manual editing to the sections delimited by
// . the comments "utility includes" and "end of utility includes"
// . the comments "utility members" and "end of utility members"

#ifndef _PhBSurface_H_
#define _PhBSurface_H_

#include "xrml.H"

// utility includes
#include "vector.H"
#include "spectrum.H"
#include "complex.H"
#include "matrix.H"
#include "granges.H"
#include "smodes.H"
// end of utility includes

namespace xrml {
#define PhBSurfaceTypeId 	"PhBSurface"
extern bool IsPhBSurface(SFNode*);

class PhBSurface: public virtual SFNode {
public:
  //
  virtual int major_version(void), minor_version(void);
  virtual bool is_leaf_class(void);
  
  PhBSurface();
  
  //
  virtual void     	render(void);
  
  // utility members
  // returns whether or not the surface is a light source
  virtual bool isLightSource(void)
    {
      Warning(NULL, "%s::isLightSource() not yet implemented", typeId);
      return false;
    }

  // returns whether or not the surface scatters incident 
  // light
  virtual bool isScatterer(void)
    {
      Warning(NULL, "%s::isScatterer() not yet implemented", typeId);
      return false;
    }

  virtual bool isTextured(void)
  {
    Warning(NULL, "%s::isTextured() not yet implemented", typeId);
    return false;
  }

  // NOTE: points are in local object coordinate system.
  // Directions are in a coordinate system in which
  // the Z-axis is the surface normal and the X-axis is
  // the Du, the direction along which the u-texture
  // coordinate varies at constant v. Directions shall always be
  // normalised and point away from the scattering of emission point.

  // Evaluates the surface EDF at the given surface point
  // for the given direction and glossiness range. Returned
  // spectrum is selfemitted spectral exitant radiance
  // [W/m^2sr/m] in the given direction. Probility
  // density of sampling the direction using sampleEDF
  // is returned in 'pdf' if pdf is not a null pointer.
  // If pdf is the null pointer, pdf computation is
  // avoided. specWeight is only needed in order to compute
  // the pdf, and shall be the same as used in sampleEDF().
  // Note that the pdf value may be zero. In that case,
  // a sample is to be considered invalid or yields
  // no information. This will be the case if no emission
  // in the specified range occurs, in which case also the emittance
  // will be zero. sampleEDF() below may however produce invalid
  // samples. it is left to the calling program to repeat the sampling
  // until a valid direction sample is found in such cases.
  virtual Spectrum evaluateEDF(const Vec3& point, const Vec3& texco, const Vec3& texco3d,
			       const Vec3& direction,
			       const Spectrum& specWeight,
			       int range,
			       float *pdf)
    {
      Warning(NULL, "%s::evaluateEDF() not yet implemented", typeId);
      if (pdf) *pdf = 0.;
      return Spectrum(0.);
    }

  // Samples a direction corresponding to the numbers 
  // xi1 and xi2. Sampling is only according to the specified
  // emission range. EDF value and pdf for the generated
  // direction are returned in value and pdf if the given
  // pointers are not null pointers.
  virtual Vec3 sampleEDF(const Vec3& point, const Vec3& texco, const Vec3& texco3d,
			 const Spectrum& specWeight,
			 float xi1, float xi2,
			 int range,
			 Spectrum *value, float *pdf)
    {
      Warning(NULL, "%s::sampleEDF() not yet implemented", typeId);
      if (pdf) *pdf = 0.;
      if (value) *value = Spectrum(0.);
      return Vec3(0.,0.,0.);
    }

  // Computes spectral self-emitted radiant exitance 
  // [W/m^2/m] of the surface at 'point'. That is: integral over
  // the hemisfere at 'point' outside the surface of selfemitted spectral
  // radiance times cosine of angle w.r.t. surface normal.
  // Only the specified emission range is taken into account.
  virtual Spectrum emittance(const Vec3& point, const Vec3& texco, const Vec3& texco3d,
			     int range)
    {
      Warning(NULL, "%s::emittance() not yet implemented", typeId);
      return Spectrum(0.);
    }

  // Evaluates BSDF [1/sr/m] at 'point' for incoming
  // direction 'inDir' and outgoing direction 'outDir'.
  // In 'pdf', the probability of sampling outDir for given inDir 
  // when using sampleBSDF() is returned if this pointer is not a
  // null pointer. Only the specified
  // scattering 'modes' are taken into account.
  // 'inSpec' is only needed for pdf evaluation and
  // shall be the same as used in sampleBSDF() for consistent results.
  // IndexIn is the index of refraction of the medium 
  // "inside" the surface. IndexOut is the index of refraction
  // of the medium "outside" the surface. The "outside" is
  // the side into which the surface normal (Z-axis) points
  // independent of 'inDir'.
  // The returned 'pdf' value may be zero, in which case
  // outDir is a invalid scattered direction for given inDir or if there
  // is no scattering in the specified modes. In the latter case,
  // the scattering albedo for the given modes is zero.
  // The sampleBSDF() routine below may generate invalid outgoing
  // directions. It is up to the calling program to repeat the sampling
  // until a valid direction is found in the former case (albedo not zero).
  virtual Spectrum evaluateBSDF(const Vec3& point, const Vec3& texco, const Vec3& texco3d,
				const Vec3& inDir,
				const Vec3& outDir,
				const Spectrum& inSpec,
				const complex& indexIn,
				const complex& indexOut,
				int modes,
				float *pdf)
    {
      Warning(NULL, "%s::evaluateBSDF() not yet implemented", typeId);
      if (pdf) *pdf = 0.;
      return Spectrum(0.);
    }

  // Computes outgoing direction corresponding to the numbers xi1 and 
  // xi2 (in the range [0,1) : not including 1) for given incoming
  // direction according to the BSDF at 'point'.
  // BSDF value and pdf for the generated outgoing direction are returned in
  // 'value' and 'pdf'. The meaning of the parameters is furthermore the same
  // as for the evaluateBSDF() function above.
  virtual Vec3 sampleBSDF(const Vec3& point, const Vec3& texco, const Vec3& texco3d,
			  const Vec3& inDir,
			  const Spectrum& inSpec,
			  const complex& indexIn,
			  const complex& indexOut,
			  float xi1, float xi2, 
			  int modes,
			  Spectrum *value, float *pdf)
    {
      Warning(NULL, "%s::sampleBSDF() not yet implemented", typeId);
      if (pdf) *pdf = 0.;
      if (value) *value = Spectrum(0.);
      return Vec3(0.,0.,1.);
    }

  // Computes spectral albedo [1/m] of the surface
  // at the given point. That is: the fraction of
  // incident light power being scattered in the 
  // specified modes. It is the
  // integral over the full sphere of BSDF times absolute cosine
  // w.r.t. surface normal. The meaning of the parameters is
  // the same as for evaluateBSDF() and sampleBSDF().
  virtual Spectrum albedo(const Vec3& point, const Vec3& texco, const Vec3& texco3d,
			  const Vec3& inDir,
			  const complex& indexIn,
			  const complex& indexOut,
			  int modes)
    {
      Warning(NULL, "%s::albedo() not yet implemented", typeId);
      return Spectrum(0.);
    }


  
protected:
  inline void util_init(void) { }
  inline void util_clone(const PhBSurface& src) { }
  inline void util_destruct(void) { }
};

// end of utility members
} // namespace xrml
#endif /*_PhBSurface_H_*/
