| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376 |
- /****************************************************************************
- * triangle.c
- *
- * This module implements primitives for triangles and smooth triangles.
- *
- * from Persistence of Vision(tm) Ray Tracer
- * Copyright 1996,1999 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 email to team-coord@povray.org or visit us on the web at
- * http://www.povray.org. The latest version of POV-Ray may be found at this site.
- *
- * 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 "povray.h"
- #include "vector.h"
- #include "povproto.h"
- #include "matrices.h"
- #include "objects.h"
- #include "triangle.h"
- /*****************************************************************************
- * Local preprocessor defines
- ******************************************************************************/
- #define DEPTH_TOLERANCE 1e-6
- #define max3_coordinate(x,y,z) \
- ((x > y) ? ((x > z) ? X : Z) : ((y > z) ? Y : Z))
- /*****************************************************************************
- * Static functions
- ******************************************************************************/
- static void find_triangle_dominant_axis (TRIANGLE *Triangle);
- static int compute_smooth_triangle (SMOOTH_TRIANGLE *Triangle);
- static int Intersect_Triangle (RAY *Ray, TRIANGLE *Triangle, DBL *Depth);
- static int All_Triangle_Intersections (OBJECT *Object, RAY *Ray, ISTACK *Depth_Stack);
- static int Inside_Triangle (VECTOR IPoint, OBJECT *Object);
- static void Triangle_Normal (VECTOR Result, OBJECT *Object, INTERSECTION *Inter);
- static TRIANGLE *Copy_Triangle (OBJECT *Object);
- static void Translate_Triangle (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
- static void Rotate_Triangle (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
- static void Scale_Triangle (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
- static void Transform_Triangle (OBJECT *Object, TRANSFORM *Trans);
- static void Invert_Triangle (OBJECT *Object);
- static void Smooth_Triangle_Normal (VECTOR Result, OBJECT *Object, INTERSECTION *Inter);
- static SMOOTH_TRIANGLE *Copy_Smooth_Triangle (OBJECT *Object);
- static void Translate_Smooth_Triangle (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
- static void Rotate_Smooth_Triangle (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
- static void Scale_Smooth_Triangle (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
- static void Transform_Smooth_Triangle (OBJECT *Object, TRANSFORM *Trans);
- static void Invert_Smooth_Triangle (OBJECT *Object);
- static void Destroy_Triangle (OBJECT *Object);
- /*****************************************************************************
- * Local variables
- ******************************************************************************/
- METHODS Triangle_Methods =
- {
- All_Triangle_Intersections,
- Inside_Triangle, Triangle_Normal,
- (COPY_METHOD)Copy_Triangle,
- Translate_Triangle, Rotate_Triangle,
- Scale_Triangle, Transform_Triangle, Invert_Triangle, Destroy_Triangle
- };
- METHODS Smooth_Triangle_Methods =
- {
- All_Triangle_Intersections,
- Inside_Triangle, Smooth_Triangle_Normal,
- (COPY_METHOD)Copy_Smooth_Triangle,
- Translate_Smooth_Triangle, Rotate_Smooth_Triangle,
- Scale_Smooth_Triangle, Transform_Smooth_Triangle,
- Invert_Smooth_Triangle, Destroy_Triangle
- };
- /*****************************************************************************
- *
- * FUNCTION
- *
- * find_triangle_dominant_axis
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
- static void find_triangle_dominant_axis(TRIANGLE *Triangle)
- {
- DBL x, y, z;
- x = fabs(Triangle->Normal_Vector[X]);
- y = fabs(Triangle->Normal_Vector[Y]);
- z = fabs(Triangle->Normal_Vector[Z]);
- Triangle->Dominant_Axis = max3_coordinate(x, y, z);
- }
- /*****************************************************************************
- *
- * FUNCTION
- *
- * compute_smooth_triangle
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
- static int compute_smooth_triangle(SMOOTH_TRIANGLE *Triangle)
- {
- VECTOR P3MinusP2, VTemp1, VTemp2;
- DBL x, y, z, uDenominator, Proj;
- VSub(P3MinusP2, Triangle->P3, Triangle->P2);
- x = fabs(P3MinusP2[X]);
- y = fabs(P3MinusP2[Y]);
- z = fabs(P3MinusP2[Z]);
- Triangle->vAxis = max3_coordinate(x, y, z);
- VSub(VTemp1, Triangle->P2, Triangle->P3);
- VNormalize(VTemp1, VTemp1);
- VSub(VTemp2, Triangle->P1, Triangle->P3);
- VDot(Proj, VTemp2, VTemp1);
- VScaleEq(VTemp1, Proj);
- VSub(Triangle->Perp, VTemp1, VTemp2);
- VNormalize(Triangle->Perp, Triangle->Perp);
- VDot(uDenominator, VTemp2, Triangle->Perp);
- VInverseScaleEq(Triangle->Perp, -uDenominator);
-
- /* Degenerate if smooth normals are more than 90 from actual normal
- or its inverse. */
- VDot(x,Triangle->Normal_Vector,Triangle->N1);
- VDot(y,Triangle->Normal_Vector,Triangle->N2);
- VDot(z,Triangle->Normal_Vector,Triangle->N3);
- if ( ((x<0.0) && (y<0.0) && (z<0.0)) ||
- ((x>0.0) && (y>0.0) && (z>0.0)) )
- {
- return(TRUE);
- }
- Set_Flag(Triangle, DEGENERATE_FLAG);
- return(FALSE);
- }
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Compute_Triangle
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
- int Compute_Triangle(TRIANGLE *Triangle,int Smooth)
- {
- int swap,degn;
- VECTOR V1, V2, Temp;
- DBL Length;
- VSub(V1, Triangle->P1, Triangle->P2);
- VSub(V2, Triangle->P3, Triangle->P2);
- VCross(Triangle->Normal_Vector, V1, V2);
- VLength(Length, Triangle->Normal_Vector);
- /* Set up a flag so we can ignore degenerate triangles */
- if (Length == 0.0)
- {
- Set_Flag(Triangle, DEGENERATE_FLAG);
- return(FALSE);
- }
- /* Normalize the normal vector. */
- VInverseScaleEq(Triangle->Normal_Vector, Length);
- VDot(Triangle->Distance, Triangle->Normal_Vector, Triangle->P1);
- Triangle->Distance *= -1.0;
- find_triangle_dominant_axis(Triangle);
- swap = FALSE;
- switch (Triangle->Dominant_Axis)
- {
- case X:
- if ((Triangle->P2[Y] - Triangle->P3[Y])*(Triangle->P2[Z] - Triangle->P1[Z]) <
- (Triangle->P2[Z] - Triangle->P3[Z])*(Triangle->P2[Y] - Triangle->P1[Y]))
- {
- swap = TRUE;
- }
- break;
- case Y:
- if ((Triangle->P2[X] - Triangle->P3[X])*(Triangle->P2[Z] - Triangle->P1[Z]) <
- (Triangle->P2[Z] - Triangle->P3[Z])*(Triangle->P2[X] - Triangle->P1[X]))
- {
- swap = TRUE;
- }
- break;
- case Z:
- if ((Triangle->P2[X] - Triangle->P3[X])*(Triangle->P2[Y] - Triangle->P1[Y]) <
- (Triangle->P2[Y] - Triangle->P3[Y])*(Triangle->P2[X] - Triangle->P1[X]))
- {
- swap = TRUE;
- }
- break;
- }
- if (swap)
- {
- Assign_Vector(Temp, Triangle->P2);
- Assign_Vector(Triangle->P2, Triangle->P1);
- Assign_Vector(Triangle->P1, Temp);
- if (Smooth)
- {
- Assign_Vector(Temp, ((SMOOTH_TRIANGLE *)Triangle)->N2);
- Assign_Vector(((SMOOTH_TRIANGLE *)Triangle)->N2, ((SMOOTH_TRIANGLE *)Triangle)->N1);
- Assign_Vector(((SMOOTH_TRIANGLE *)Triangle)->N1, Temp);
- }
- }
-
- degn=TRUE;
- if (Smooth)
- {
- degn=compute_smooth_triangle((SMOOTH_TRIANGLE *)Triangle);
- }
- /* Build the bounding information from the vertices. */
- Compute_Triangle_BBox(Triangle);
- return(degn);
- }
- /*****************************************************************************
- *
- * FUNCTION
- *
- * All_Triangle_Intersections
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
- static int All_Triangle_Intersections(OBJECT *Object, RAY *Ray, ISTACK *Depth_Stack)
- {
- DBL Depth;
- VECTOR IPoint;
- if (Intersect_Triangle(Ray, (TRIANGLE *)Object, &Depth))
- {
- VEvaluateRay(IPoint, Ray->Initial, Depth, Ray->Direction);
- if (Point_In_Clip(IPoint,Object->Clip))
- {
- push_entry(Depth,IPoint,Object,Depth_Stack);
- return(TRUE);
- }
- }
- return(FALSE);
- }
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Intersect_Triangle
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
- static int Intersect_Triangle(RAY *Ray, TRIANGLE *Triangle, DBL *Depth)
- {
- DBL NormalDotOrigin, NormalDotDirection;
- DBL s, t;
- Increase_Counter(stats[Ray_Triangle_Tests]);
- if (Test_Flag(Triangle, DEGENERATE_FLAG))
- {
- return(FALSE);
- }
- VDot(NormalDotDirection, Triangle->Normal_Vector, Ray->Direction);
- if (fabs(NormalDotDirection) < EPSILON)
- {
- return(FALSE);
- }
- VDot(NormalDotOrigin, Triangle->Normal_Vector, Ray->Initial);
- *Depth = -(Triangle->Distance + NormalDotOrigin) / NormalDotDirection;
- if ((*Depth < DEPTH_TOLERANCE) || (*Depth > Max_Distance))
- {
- return(FALSE);
- }
- switch (Triangle->Dominant_Axis)
- {
- case X:
- s = Ray->Initial[Y] + *Depth * Ray->Direction[Y];
- t = Ray->Initial[Z] + *Depth * Ray->Direction[Z];
- if ((Triangle->P2[Y] - s) * (Triangle->P2[Z] - Triangle->P1[Z]) <
- (Triangle->P2[Z] - t) * (Triangle->P2[Y] - Triangle->P1[Y]))
- {
- return(FALSE);
- }
- if ((Triangle->P3[Y] - s) * (Triangle->P3[Z] - Triangle->P2[Z]) <
- (Triangle->P3[Z] - t) * (Triangle->P3[Y] - Triangle->P2[Y]))
- {
- return(FALSE);
- }
- if ((Triangle->P1[Y] - s) * (Triangle->P1[Z] - Triangle->P3[Z]) <
- (Triangle->P1[Z] - t) * (Triangle->P1[Y] - Triangle->P3[Y]))
- {
- return(FALSE);
- }
- Increase_Counter(stats[Ray_Triangle_Tests_Succeeded]);
- return(TRUE);
- case Y:
- s = Ray->Initial[X] + *Depth * Ray->Direction[X];
- t = Ray->Initial[Z] + *Depth * Ray->Direction[Z];
- if ((Triangle->P2[X] - s) * (Triangle->P2[Z] - Triangle->P1[Z]) <
- (Triangle->P2[Z] - t) * (Triangle->P2[X] - Triangle->P1[X]))
- {
- return(FALSE);
- }
- if ((Triangle->P3[X] - s) * (Triangle->P3[Z] - Triangle->P2[Z]) <
- (Triangle->P3[Z] - t) * (Triangle->P3[X] - Triangle->P2[X]))
- {
- return(FALSE);
- }
- if ((Triangle->P1[X] - s) * (Triangle->P1[Z] - Triangle->P3[Z]) <
- (Triangle->P1[Z] - t) * (Triangle->P1[X] - Triangle->P3[X]))
- {
- return(FALSE);
- }
- Increase_Counter(stats[Ray_Triangle_Tests_Succeeded]);
- return(TRUE);
- case Z:
- s = Ray->Initial[X] + *Depth * Ray->Direction[X];
- t = Ray->Initial[Y] + *Depth * Ray->Direction[Y];
- if ((Triangle->P2[X] - s) * (Triangle->P2[Y] - Triangle->P1[Y]) <
- (Triangle->P2[Y] - t) * (Triangle->P2[X] - Triangle->P1[X]))
- {
- return(FALSE);
- }
- if ((Triangle->P3[X] - s) * (Triangle->P3[Y] - Triangle->P2[Y]) <
- (Triangle->P3[Y] - t) * (Triangle->P3[X] - Triangle->P2[X]))
- {
- return(FALSE);
- }
- if ((Triangle->P1[X] - s) * (Triangle->P1[Y] - Triangle->P3[Y]) <
- (Triangle->P1[Y] - t) * (Triangle->P1[X] - Triangle->P3[X]))
- {
- return(FALSE);
- }
- Increase_Counter(stats[Ray_Triangle_Tests_Succeeded]);
- return(TRUE);
- }
- return(FALSE);
- }
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Inside_Triangle
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
- static int Inside_Triangle(VECTOR IPoint, OBJECT *Object)
- {
- return(FALSE);
- }
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Triangle_Normal
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
- static void Triangle_Normal(VECTOR Result, OBJECT *Object, INTERSECTION *Inter)
- {
- Assign_Vector(Result, ((TRIANGLE *)Object)->Normal_Vector);
- }
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Smooth_Triangle_Normal
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * Calculate the Phong-interpolated vector within the triangle
- * at the given intersection point. The math for this is a bit
- * bizarre:
- *
- * - P1
- * | /|\ \
- * | / |Perp\
- * | / V \ \
- * | / | \ \
- * u | /____|_____PI___\
- * | / | \ \
- * - P2-----|--------|----P3
- * Pbase PIntersect
- * |-------------------|
- * v
- *
- * Triangle->Perp is a unit vector from P1 to Pbase. We calculate
- *
- * u = (PI - P1) DOT Perp / ((P3 - P1) DOT Perp).
- *
- * We then calculate where the line from P1 to PI intersects the line P2 to P3:
- * PIntersect = (PI - P1)/u.
- *
- * We really only need one coordinate of PIntersect. We then calculate v as:
- *
- * v = PIntersect[X] / (P3[X] - P2[X])
- * or v = PIntersect[Y] / (P3[Y] - P2[Y])
- * or v = PIntersect[Z] / (P3[Z] - P2[Z])
- *
- * depending on which calculation will give us the best answers.
- *
- * Once we have u and v, we can perform the normal interpolation as:
- *
- * NTemp1 = N1 + u(N2 - N1);
- * NTemp2 = N1 + u(N3 - N1);
- * Result = normalize (NTemp1 + v(NTemp2 - NTemp1))
- *
- * As always, any values which are constant for the triangle are cached
- * in the triangle.
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
- static void Smooth_Triangle_Normal(VECTOR Result, OBJECT *Object, INTERSECTION *Inter)
- {
- int Axis;
- DBL u, v;
- VECTOR PIMinusP1;
- SMOOTH_TRIANGLE *Triangle = (SMOOTH_TRIANGLE *)Object;
- VSub(PIMinusP1, Inter->IPoint, Triangle->P1);
- VDot(u, PIMinusP1, Triangle->Perp);
- if (u < EPSILON)
- {
- Assign_Vector(Result, Triangle->N1);
- return;
- }
- Axis = Triangle->vAxis;
- v = (PIMinusP1[Axis] / u + Triangle->P1[Axis] - Triangle->P2[Axis]) / (Triangle->P3[Axis] - Triangle->P2[Axis]);
- /* This is faster. [DB 8/94] */
- Result[X] = Triangle->N1[X] + u * (Triangle->N2[X] - Triangle->N1[X] + v * (Triangle->N3[X] - Triangle->N2[X]));
- Result[Y] = Triangle->N1[Y] + u * (Triangle->N2[Y] - Triangle->N1[Y] + v * (Triangle->N3[Y] - Triangle->N2[Y]));
- Result[Z] = Triangle->N1[Z] + u * (Triangle->N2[Z] - Triangle->N1[Z] + v * (Triangle->N3[Z] - Triangle->N2[Z]));
- VNormalize(Result, Result);
- }
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Translate_Triangle
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
- static void Translate_Triangle(OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
- {
- TRIANGLE *Triangle = (TRIANGLE *)Object;
- VECTOR Translation;
- if (!Test_Flag(Triangle, DEGENERATE_FLAG))
- {
- VEvaluate(Translation, Triangle->Normal_Vector, Vector);
- Triangle->Distance -= Translation[X] + Translation[Y] + Translation[Z];
- VAddEq(Triangle->P1, Vector);
- VAddEq(Triangle->P2, Vector);
- VAddEq(Triangle->P3, Vector);
- Compute_Triangle(Triangle, FALSE);
- }
- }
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Rotate_Triangle
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
- static void Rotate_Triangle(OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
- {
- if (!Test_Flag(Object, DEGENERATE_FLAG))
- {
- Transform_Triangle(Object, Trans);
- }
- }
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Scale_Triangle
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
- static void Scale_Triangle(OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
- {
- DBL Length;
- TRIANGLE *Triangle = (TRIANGLE *)Object;
- if (!Test_Flag(Object, DEGENERATE_FLAG))
- {
- Triangle->Normal_Vector[X] = Triangle->Normal_Vector[X] / Vector[X];
- Triangle->Normal_Vector[Y] = Triangle->Normal_Vector[Y] / Vector[Y];
- Triangle->Normal_Vector[Z] = Triangle->Normal_Vector[Z] / Vector[Z];
- VLength(Length, Triangle->Normal_Vector);
- VInverseScaleEq(Triangle->Normal_Vector, Length);
- Triangle->Distance /= Length;
- VEvaluateEq(Triangle->P1, Vector);
- VEvaluateEq(Triangle->P2, Vector);
- VEvaluateEq(Triangle->P3, Vector);
- Compute_Triangle(Triangle, FALSE);
- }
- }
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Transfrom_Triangle
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
- static void Transform_Triangle(OBJECT *Object, TRANSFORM *Trans)
- {
- TRIANGLE *Triangle = (TRIANGLE *)Object;
- if (!Test_Flag(Object, DEGENERATE_FLAG))
- {
- MTransPoint(Triangle->Normal_Vector,Triangle->Normal_Vector, Trans);
- MTransPoint(Triangle->P1, Triangle->P1, Trans);
- MTransPoint(Triangle->P2, Triangle->P2, Trans);
- MTransPoint(Triangle->P3, Triangle->P3, Trans);
- Compute_Triangle(Triangle, FALSE);
- }
- }
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Invert_Triangle
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
- static void Invert_Triangle(OBJECT *Object)
- {
- }
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Create_Triangle
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
- TRIANGLE *Create_Triangle()
- {
- TRIANGLE *New;
- New = (TRIANGLE *)POV_MALLOC(sizeof(TRIANGLE), "triangle");
- INIT_OBJECT_FIELDS(New,TRIANGLE_OBJECT,&Triangle_Methods)
- Make_Vector(New->Normal_Vector, 0.0, 1.0, 0.0);
- New->Distance = 0.0;
- Make_Vector(New->P1, 0.0, 0.0, 0.0);
- Make_Vector(New->P2, 1.0, 0.0, 0.0);
- Make_Vector(New->P3, 0.0, 1.0, 0.0);
- /*
- * NOTE: Dominant_Axis is computed when Parse_Triangle calls
- * Compute_Triangle. vAxis is used only for smooth triangles.
- */
- return(New);
- }
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Copy_Triangle
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
- static TRIANGLE *Copy_Triangle(OBJECT *Object)
- {
- TRIANGLE *New;
- New = Create_Triangle();
- *New = *((TRIANGLE *)Object);
- return(New);
- }
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Destroy_Triangle
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
- static void Destroy_Triangle(OBJECT *Object)
- {
- POV_FREE (Object);
- }
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Translate_Smooth_Triangle
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
- static void Translate_Smooth_Triangle(OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
- {
- SMOOTH_TRIANGLE *Triangle = (SMOOTH_TRIANGLE *)Object;
- VECTOR Translation;
- if (!Test_Flag(Object, DEGENERATE_FLAG))
- {
- VEvaluate(Translation, Triangle->Normal_Vector, Vector);
- Triangle->Distance -= Translation[X] + Translation[Y] + Translation[Z];
- VAddEq(Triangle->P1, Vector);
- VAddEq(Triangle->P2, Vector);
- VAddEq(Triangle->P3, Vector);
- Compute_Triangle((TRIANGLE *)Triangle, TRUE);
- }
- }
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Rotate_Smooth_Triangle
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
- static void Rotate_Smooth_Triangle(OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
- {
- if (!Test_Flag(Object, DEGENERATE_FLAG))
- {
- Transform_Smooth_Triangle(Object, Trans);
- }
- }
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Scale_Smooth_Triangle
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
- static void Scale_Smooth_Triangle(OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
- {
- DBL Length;
- SMOOTH_TRIANGLE *Triangle = (SMOOTH_TRIANGLE *)Object;
- if (!Test_Flag(Object, DEGENERATE_FLAG))
- {
- Triangle->Normal_Vector[X] = Triangle->Normal_Vector[X] / Vector[X];
- Triangle->Normal_Vector[Y] = Triangle->Normal_Vector[Y] / Vector[Y];
- Triangle->Normal_Vector[Z] = Triangle->Normal_Vector[Z] / Vector[Z];
- VLength(Length, Triangle->Normal_Vector);
- VScaleEq(Triangle->Normal_Vector, 1.0 / Length);
- Triangle->Distance /= Length;
- VEvaluateEq(Triangle->P1, Vector);
- VEvaluateEq(Triangle->P2, Vector);
- VEvaluateEq(Triangle->P3, Vector);
- Compute_Triangle((TRIANGLE *)Triangle,TRUE);
- }
- }
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Transform_Smooth_Triangle
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
- static void Transform_Smooth_Triangle(OBJECT *Object, TRANSFORM *Trans)
- {
- SMOOTH_TRIANGLE *Triangle = (SMOOTH_TRIANGLE *)Object;
- if (!Test_Flag(Object, DEGENERATE_FLAG))
- {
- MTransPoint(Triangle->Normal_Vector,Triangle->Normal_Vector, Trans);
- MTransPoint(Triangle->P1, Triangle->P1, Trans);
- MTransPoint(Triangle->P2, Triangle->P2, Trans);
- MTransPoint(Triangle->P3, Triangle->P3, Trans);
- MTransPoint(Triangle->N1, Triangle->N1, Trans);
- MTransPoint(Triangle->N2, Triangle->N2, Trans);
- MTransPoint(Triangle->N3, Triangle->N3, Trans);
- Compute_Triangle((TRIANGLE *)Triangle, TRUE);
- }
- }
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Invert_Smooth_Triangle
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
- static void Invert_Smooth_Triangle(OBJECT *Object)
- {
- }
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Create_Smooth_Triangle
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
- SMOOTH_TRIANGLE *Create_Smooth_Triangle()
- {
- SMOOTH_TRIANGLE *New;
- New = (SMOOTH_TRIANGLE *)POV_MALLOC(sizeof(SMOOTH_TRIANGLE), "smooth triangle");
- INIT_OBJECT_FIELDS(New,SMOOTH_TRIANGLE_OBJECT,&Smooth_Triangle_Methods)
- Make_Vector(New->Normal_Vector, 0.0, 1.0, 0.0);
- New->Distance = 0.0;
- Make_Vector(New->P1, 0.0, 0.0, 0.0);
- Make_Vector(New->P2, 1.0, 0.0, 0.0);
- Make_Vector(New->P3, 0.0, 1.0, 0.0);
- Make_Vector(New->N1, 0.0, 1.0, 0.0);
- Make_Vector(New->N2, 0.0, 1.0, 0.0);
- Make_Vector(New->N3, 0.0, 1.0, 0.0);
- /*
- * NOTE: Dominant_Axis and vAxis are computed when
- * Parse_Triangle calls Compute_Triangle.
- */
- return(New);
- }
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Copy_Smooth_Triangle
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
- static SMOOTH_TRIANGLE *Copy_Smooth_Triangle(OBJECT *Object)
- {
- SMOOTH_TRIANGLE *New;
- New = Create_Smooth_Triangle();
- *New = *((SMOOTH_TRIANGLE *)Object);
- return(New);
- }
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Compute_Triangle_BBox
- *
- * INPUT
- *
- * Triangle - Triangle
- *
- * OUTPUT
- *
- * Triangle
- *
- * RETURNS
- *
- * AUTHOR
- *
- * Dieter Bayer
- *
- * DESCRIPTION
- *
- * Calculate the bounding box of a triangle.
- *
- * CHANGES
- *
- * Aug 1994 : Creation.
- *
- ******************************************************************************/
- void Compute_Triangle_BBox(TRIANGLE *Triangle)
- {
- VECTOR Min, Max, Epsilon;
- Make_Vector(Epsilon, EPSILON, EPSILON, EPSILON);
- Min[X] = min3(Triangle->P1[X], Triangle->P2[X], Triangle->P3[X]);
- Min[Y] = min3(Triangle->P1[Y], Triangle->P2[Y], Triangle->P3[Y]);
- Min[Z] = min3(Triangle->P1[Z], Triangle->P2[Z], Triangle->P3[Z]);
- Max[X] = max3(Triangle->P1[X], Triangle->P2[X], Triangle->P3[X]);
- Max[Y] = max3(Triangle->P1[Y], Triangle->P2[Y], Triangle->P3[Y]);
- Max[Z] = max3(Triangle->P1[Z], Triangle->P2[Z], Triangle->P3[Z]);
- VSubEq(Min, Epsilon);
- VAddEq(Max, Epsilon);
- Make_BBox_from_min_max(Triangle->BBox, Min, Max);
- }
|