/* Copyright (C) 1999-2004 by Peter Eastman

   This program is free software; you can redistribute it and/or modify it under the
   terms of the GNU General Public License as published by the Free Software
   Foundation; either version 2 of the License, or (at your option) any later version.

   This program is distributed in the hope that it will be useful, but WITHOUT ANY 
   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 
   PARTICULAR PURPOSE.  See the GNU General Public License for more details. */

package artofillusion.raytracer;

import artofillusion.*;
import artofillusion.material.*;
import artofillusion.math.*;
import artofillusion.texture.*;

/** RTObject represents an object which can be raytraced. */

public abstract class RTObject
{
  protected int lastRay;
  protected boolean lastRayResult;

  /** Get the TextureMapping for this object. */
  
  public abstract TextureMapping getTextureMapping();

  /** Get the MaterialMapping for this object. */
  
  public abstract MaterialMapping getMaterialMapping();
  
  /** Determine whether a ray intersects this object. */

  public boolean intersects(Ray r)
  {
    if (lastRay == r.getID())
      return lastRayResult;
    return checkIntersection(r);
  }
  
  /** Determine whether a ray intersects this object.  This is called by intersects(), which
      is designed to be very short so it can be inlined. */

  protected abstract boolean checkIntersection(Ray r);

  /** The following methods should be called after intersects() has returned true.  They 
      return information about the point(s) of intersection between the ray and the object. */
  
  /** Get the number of times the ray intersects the object. */
  
  public abstract int numIntersections();
  
  /** Get the first point of intersection. */
  
  public abstract void intersectionPoint(int n, Vec3 p);

  /** Get the distance from the ray origin to the nth point of intersection. */

  public abstract double intersectionDist(int n);

  /** Get the surface properties at the point of intersection.
      @param spec        the texture properties will be stored in this
      @param n           the surface normal will be stored in this
      @param viewDir     the direction from which the surface is being viewed
      @param size        the width of the region over which the texture should be averaged
  */
  
  public abstract void intersectionProperties(TextureSpec spec, Vec3 n, Vec3 viewDir, double size);
  
  /** Get the normal of the "true" surface (without interpolation, bump mapping, etc.)
      at the point of intersection. */
  
  public abstract void trueNormal(Vec3 n);
  
  /** Same as above, except only return the transparent color.  This can save time in cases
      where only the transparency is required, for example, when tracing shadow rays.  This
      also allows you to specify which intersection to get the transparency for. */

  public abstract void intersectionTransparency(int n, RGBColor trans, double angle, double size);

  /** Get a bounding box for this object. */
  
  public abstract BoundingBox getBounds();

  /** Determine whether any part of the object lies within a bounding box. */

  public abstract boolean intersectsBox(BoundingBox bb);
  
  /** Get the transformation from world coordinates to the object's local coordinates. */
  
  public abstract Mat4 toLocal();
}