home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************
- * planes.c
- *
- * This module implements functions that manipulate planes.
- *
- * from Persistence of Vision Raytracer
- * Copyright 1993 Persistence of Vision Team
- *---------------------------------------------------------------------------
- * NOTICE: This source code file is provided so that users may experiment
- * with enhancements to POV-Ray and to port the software to platforms other
- * than those supported by the POV-Ray Team. There are strict rules under
- * which you are permitted to use this file. The rules are in the file
- * named POVLEGAL.DOC which should be distributed with this file. If
- * POVLEGAL.DOC is not available or for more info please contact the POV-Ray
- * Team Coordinator by leaving a message in CompuServe's Graphics Developer's
- * Forum. The latest version of POV-Ray may be found there as well.
- *
- * This program is based on the popular DKB raytracer version 2.12.
- * DKBTrace was originally written by David K. Buck.
- * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
- *
- *****************************************************************************/
-
- #include "frame.h"
- #include "vector.h"
- #include "povproto.h"
-
- METHODS Plane_Methods =
- {
- All_Plane_Intersections,
- Inside_Plane, Plane_Normal,
- Copy_Plane,
- Translate_Plane, Rotate_Plane,
- Scale_Plane, Transform_Plane, Invert_Plane, Destroy_Plane
- };
-
- extern RAY *CM_Ray;
- extern long Ray_Plane_Tests, Ray_Plane_Tests_Succeeded;
-
- #ifndef Plane_Tolerance
- #define Plane_Tolerance 1.0e-8
- #endif
-
- int All_Plane_Intersections (Object, Ray, Depth_Stack)
- OBJECT *Object;
- RAY *Ray;
- ISTACK *Depth_Stack;
- {
- DBL Depth;
- VECTOR IPoint;
-
- if (Intersect_Plane (Ray, (PLANE *)Object, &Depth))
- if (Depth > Plane_Tolerance)
- {
- VScale (IPoint, Ray -> Direction, Depth);
- VAddEq (IPoint, Ray -> Initial);
- if (Point_In_Clip (&IPoint, Object->Clip))
- {
- push_entry(Depth,IPoint,Object,Depth_Stack);
- return (TRUE);
- }
- }
- return (FALSE);
- }
-
- int Intersect_Plane (Ray, Plane, Depth)
- RAY *Ray;
- PLANE *Plane;
- DBL *Depth;
- {
- DBL NormalDotOrigin, NormalDotDirection;
-
- Ray_Plane_Tests++;
- if (Ray == CM_Ray)
- {
- VDot (NormalDotDirection, Plane->Normal_Vector, Ray->Direction);
- if ((NormalDotDirection < Plane_Tolerance) &&
- (NormalDotDirection > -Plane_Tolerance))
- return (FALSE);
-
- if (!Plane->CMCached)
- {
- VDot (Plane->CMNormDotOrigin, Plane->Normal_Vector, Ray->Initial);
- Plane->CMNormDotOrigin += Plane->Distance;
- Plane->CMNormDotOrigin *= -1.0;
- Plane->CMCached = TRUE;
- }
-
- *Depth = Plane->CMNormDotOrigin / NormalDotDirection;
- if ((*Depth >= Plane_Tolerance) && (*Depth <= Max_Distance))
- {
- Ray_Plane_Tests_Succeeded++;
- return (TRUE);
- }
- else
- return (FALSE);
- }
- else
- {
- VDot (NormalDotDirection, Plane->Normal_Vector, Ray->Direction);
- if ((NormalDotDirection < Plane_Tolerance) &&
- (NormalDotDirection > -Plane_Tolerance))
- return (FALSE);
-
- VDot (NormalDotOrigin, Plane->Normal_Vector, Ray->Initial);
- NormalDotOrigin += Plane->Distance;
- NormalDotOrigin *= -1.0;
-
- *Depth = NormalDotOrigin / NormalDotDirection;
- if ((*Depth >= Plane_Tolerance) && (*Depth <= Max_Distance))
- {
- Ray_Plane_Tests_Succeeded++;
- return (TRUE);
- }
- else
- return (FALSE);
- }
- }
-
- int Inside_Plane (IPoint, Object)
- VECTOR *IPoint;
- OBJECT *Object;
- {
- DBL Temp;
-
- VDot (Temp, *IPoint, ((PLANE *)Object)->Normal_Vector);
- return ((Temp + ((PLANE *)Object)->Distance) <= Plane_Tolerance);
- }
-
- void Plane_Normal (Result, Object, IPoint)
- OBJECT *Object;
- VECTOR *Result, *IPoint;
- {
- *Result = ((PLANE *)Object)->Normal_Vector;
- }
-
- void Translate_Plane (Object, Vector)
- OBJECT *Object;
- VECTOR *Vector;
- {
- VECTOR Translation;
-
- VEvaluate (Translation, ((PLANE *)Object)->Normal_Vector, *Vector);
- ((PLANE *)Object)->Distance -= Translation.x + Translation.y + Translation.z;
- }
-
- void Rotate_Plane (Object, Vector)
- OBJECT *Object;
- VECTOR *Vector;
- {
- TRANSFORM Trans;
-
- Compute_Rotation_Transform (&Trans, Vector);
- Transform_Plane (Object, &Trans);
- }
-
- void Scale_Plane (Object, Vector)
- OBJECT *Object;
- VECTOR *Vector;
- {
- DBL Length;
-
- PLANE *Plane = (PLANE *) Object;
-
- VDivEq(Plane->Normal_Vector, *Vector);
-
- VLength(Length, ((PLANE *)Object)->Normal_Vector);
- VScaleEq (((PLANE *)Object)->Normal_Vector, 1.0 / Length);
- ((PLANE *)Object)->Distance /= Length;
- }
-
- void Invert_Plane (Object)
- OBJECT *Object;
- {
- VScaleEq (((PLANE *) Object)->Normal_Vector, -1.0);
- ((PLANE *) Object)->Distance *= -1.0;
- }
-
- PLANE *Create_Plane()
- {
- PLANE *New;
-
- if ((New = (PLANE *) malloc (sizeof (PLANE))) == NULL)
- MAError ("plane");
-
- INIT_OBJECT_FIELDS(New,PLANE_OBJECT,&Plane_Methods)
-
- Make_Vector (&(New -> Normal_Vector), 0.0, 1.0, 0.0);
- New -> Distance = 0.0;
- New -> CMNormDotOrigin = 0.0;
- New -> CMCached = 0;
- return (New);
- }
-
- void *Copy_Plane (Object)
- OBJECT *Object;
- {
- PLANE *New;
-
- New = Create_Plane ();
- *New = * ((PLANE *)Object);
-
- return (New);
- }
-
- void Transform_Plane (Object, Trans)
- OBJECT *Object;
- TRANSFORM *Trans;
- {
- MTransPoint (&((PLANE *) Object)->Normal_Vector,
- &((PLANE *) Object)->Normal_Vector, Trans);
- }
-
- void Destroy_Plane (Object)
- OBJECT *Object;
- {
- free (Object);
- }
-