| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599 |
- /****************************************************************************
- * vlbuffer.c
- *
- * This module implements functions that are used by the vista/light buffer.
- *
- * This module was written by Dieter Bayer [DB].
- *
- * 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.
- *
- *****************************************************************************/
- /****************************************************************************
- *
- * Explanation:
- *
- * -
- *
- * ---
- *
- * Mar 1994 : Creation.
- *
- *****************************************************************************/
- #include "frame.h"
- #include "vector.h"
- #include "povproto.h"
- #include "bbox.h"
- #include "vlbuffer.h"
- /*****************************************************************************
- * Local preprocessor defines
- ******************************************************************************/
- #define INITIAL_NUMBER_OF_ENTRIES 256
- /*****************************************************************************
- * Local typedefs
- ******************************************************************************/
- /*****************************************************************************
- * Local variables
- ******************************************************************************/
- /* Tree node queue. */
- PROJECT_QUEUE *Node_Queue;
- /* Priority queue. */
- PRIORITY_QUEUE *VLBuffer_Queue;
- /*****************************************************************************
- * Static functions
- ******************************************************************************/
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Initialize_VLBuffer_Code
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * Dieter Bayer
- *
- * DESCRIPTION
- *
- * Init queues used by the light and vista buffer.
- *
- * CHANGES
- *
- * May 1994 : Creation.
- *
- ******************************************************************************/
- void Initialize_VLBuffer_Code()
- {
- Node_Queue = (PROJECT_QUEUE *)POV_MALLOC(sizeof(PROJECT_QUEUE),
- "vista/light buffer node queue");
- Node_Queue->QSize = 0;
- Node_Queue->Max_QSize = INITIAL_NUMBER_OF_ENTRIES;
- Node_Queue->Queue = (PROJECT_TREE_NODE **)POV_MALLOC(Node_Queue->Max_QSize*sizeof(PROJECT_TREE_NODE *),
- "vista/light buffer node queue");
- VLBuffer_Queue = Create_Priority_Queue(INITIAL_NUMBER_OF_ENTRIES);
- }
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Reinitialize_VLBuffer_Code
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * Dieter Bayer
- *
- * DESCRIPTION
- *
- * Reinit queues used by the light and vista buffer.
- *
- * Note that only the node queue needs to be reinitialized.
- *
- * CHANGES
- *
- * Feb 1995 : Creation.
- *
- ******************************************************************************/
- void Reinitialize_VLBuffer_Code()
- {
- if (Node_Queue->QSize >= Node_Queue->Max_QSize)
- {
- if (Node_Queue->QSize >= INT_MAX/2)
- {
- Error("Node queue overflow.\n");
- }
- Node_Queue->Max_QSize *= 2;
- Node_Queue->Queue = (PROJECT_TREE_NODE **)POV_REALLOC(Node_Queue->Queue,
- Node_Queue->Max_QSize*sizeof(PROJECT_TREE_NODE *),
- "vista/light buffer node queue");
- }
- }
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Deinitialize_VLBuffer_Code
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * Dieter Bayer
- *
- * DESCRIPTION
- *
- * Deinit queues used by the light and vista buffer.
- *
- * CHANGES
- *
- * May 1994 : Creation.
- *
- ******************************************************************************/
- void Deinitialize_VLBuffer_Code()
- {
- if (Node_Queue != NULL)
- {
- POV_FREE(Node_Queue->Queue);
- POV_FREE(Node_Queue);
- }
- if (VLBuffer_Queue != NULL)
- {
- Destroy_Priority_Queue(VLBuffer_Queue);
- }
- Node_Queue = NULL;
- VLBuffer_Queue = NULL;
- }
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Clip_Polygon
- *
- * INPUT
- *
- * Points - polygon's points
- * PointCnt - Number of points in polygon
- * VX1, VY1, VX2, VY1 - Normal vectors of the clipping planes
- * DX1, DY1, DX2, DY2 - Distances of the clipping planes from
- * the origin
- *
- * OUTPUT
- *
- * Points, PointCnt
- *
- * RETURNS
- *
- * AUTHOR
- *
- * Dieter Bayer
- *
- * DESCRIPTION
- *
- * Clip polygon at the viewing pyramid define by the normal vectors
- * VX1, VX2, VY1, VY2 and the distances DX1, DX2, DY1, DY2.
- *
- * CHANGES
- *
- * May 1994 : Creation.
- *
- ******************************************************************************/
- void Clip_Polygon(VECTOR *Points, int *PointCnt, VECTOR VX1, VECTOR VX2, VECTOR VY1, VECTOR VY2, DBL DX1, DBL DX2, DBL DY1, DBL DY2)
- {
- DBL aktd, pred, fird, k;
- VECTOR aktP, intP, preP, firP, d;
- int i, pc;
- VECTOR ClipPoints[MAX_CLIP_POINTS];
- /********** clip polygon at "left" plane **********/
- pc = 0;
- Assign_Vector(firP, Points[0]);
- fird = VX1[X] * firP[X] + VX1[Y] * firP[Y] + VX1[Z] * firP[Z] - DX1;
- if (fird <= 0.0)
- {
- Assign_Vector(ClipPoints[pc++], firP);
- }
- Assign_Vector(aktP, firP);
- Assign_Vector(preP, firP);
- aktd = pred = fird;
- for (i = 1; i < *PointCnt; i++)
- {
- Assign_Vector(aktP, Points[i]);
- aktd = VX1[X] * aktP[X] + VX1[Y] * aktP[Y] + VX1[Z] * aktP[Z] - DX1;
- if (((aktd < 0.0) && (pred > 0.0)) || ((aktd > 0.0) && (pred < 0.0)))
- {
- d[X] = preP[X] - aktP[X];
- d[Y] = preP[Y] - aktP[Y];
- d[Z] = preP[Z] - aktP[Z];
- k = -aktd / (VX1[X] * d[X] + VX1[Y] * d[Y] + VX1[Z] * d[Z]);
- intP[X] = aktP[X] + k * d[X];
- intP[Y] = aktP[Y] + k * d[Y];
- intP[Z] = aktP[Z] + k * d[Z];
- Assign_Vector(ClipPoints[pc++], intP);
- }
- if (aktd <= 0.0)
- {
- Assign_Vector(ClipPoints[pc++], aktP);
- }
- Assign_Vector(preP, aktP);
- pred = aktd;
- }
- if (((fird < 0.0) && (aktd > 0.0)) || ((fird > 0.0) && (aktd < 0.0)))
- {
- d[X] = firP[X] - aktP[X];
- d[Y] = firP[Y] - aktP[Y];
- d[Z] = firP[Z] - aktP[Z];
- k = -aktd / (VX1[X] * d[X] + VX1[Y] * d[Y] + VX1[Z] * d[Z]);
- intP[X] = aktP[X] + k * d[X];
- intP[Y] = aktP[Y] + k * d[Y];
- intP[Z] = aktP[Z] + k * d[Z];
- Assign_Vector(ClipPoints[pc++], intP);
- }
- for (i = 0; i < pc; i++)
- {
- Assign_Vector(Points[i], ClipPoints[i]);
- }
- if ((*PointCnt = pc) == 0)
- return;
- /********** clip polygon at "right" plane **********/
- pc = 0;
- Assign_Vector(firP, Points[0]);
- fird = VX2[X] * firP[X] + VX2[Y] * firP[Y] + VX2[Z] * firP[Z] - DX2;
- if (fird <= 0.0)
- {
- Assign_Vector(ClipPoints[pc++], firP);
- }
- Assign_Vector(aktP, firP);
- Assign_Vector(preP, firP);
- aktd = pred = fird;
- for (i = 1; i < *PointCnt; i++)
- {
- Assign_Vector(aktP, Points[i]);
- aktd = VX2[X] * aktP[X] + VX2[Y] * aktP[Y] + VX2[Z] * aktP[Z] - DX2;
- if (((aktd < 0.0) && (pred > 0.0)) || ((aktd > 0.0) && (pred < 0.0)))
- {
- d[X] = preP[X] - aktP[X];
- d[Y] = preP[Y] - aktP[Y];
- d[Z] = preP[Z] - aktP[Z];
- k = -aktd / (VX2[X] * d[X] + VX2[Y] * d[Y] + VX2[Z] * d[Z]);
- intP[X] = aktP[X] + k * d[X];
- intP[Y] = aktP[Y] + k * d[Y];
- intP[Z] = aktP[Z] + k * d[Z];
- Assign_Vector(ClipPoints[pc++], intP);
- }
- if (aktd <= 0.0)
- {
- Assign_Vector(ClipPoints[pc++], aktP);
- }
- Assign_Vector(preP, aktP);
- pred = aktd;
- }
- if (((fird < 0.0) && (aktd > 0.0)) || ((fird > 0.0) && (aktd < 0.0)))
- {
- d[X] = firP[X] - aktP[X];
- d[Y] = firP[Y] - aktP[Y];
- d[Z] = firP[Z] - aktP[Z];
- k = -aktd / (VX2[X] * d[X] + VX2[Y] * d[Y] + VX2[Z] * d[Z]);
- intP[X] = aktP[X] + k * d[X];
- intP[Y] = aktP[Y] + k * d[Y];
- intP[Z] = aktP[Z] + k * d[Z];
- Assign_Vector(ClipPoints[pc++], intP);
- }
- for (i = 0; i < pc; i++)
- {
- Assign_Vector(Points[i], ClipPoints[i]);
- }
- if ((*PointCnt = pc) == 0)
- return;
- /********** clip polygon at "bottom" plane **********/
- pc = 0;
- Assign_Vector(firP, Points[0]);
- fird = VY1[X] * firP[X] + VY1[Y] * firP[Y] + VY1[Z] * firP[Z] - DY1;
- if (fird <= 0.0)
- {
- Assign_Vector(ClipPoints[pc++], firP);
- }
- Assign_Vector(aktP, firP);
- Assign_Vector(preP, firP);
- aktd = pred = fird;
- for (i = 1; i < *PointCnt; i++)
- {
- Assign_Vector(aktP, Points[i]);
- aktd = VY1[X] * aktP[X] + VY1[Y] * aktP[Y] + VY1[Z] * aktP[Z] - DY1;
- if (((aktd < 0.0) && (pred > 0.0)) || ((aktd > 0.0) && (pred < 0.0)))
- {
- d[X] = preP[X] - aktP[X];
- d[Y] = preP[Y] - aktP[Y];
- d[Z] = preP[Z] - aktP[Z];
- k = -aktd / (VY1[X] * d[X] + VY1[Y] * d[Y] + VY1[Z] * d[Z]);
- intP[X] = aktP[X] + k * d[X];
- intP[Y] = aktP[Y] + k * d[Y];
- intP[Z] = aktP[Z] + k * d[Z];
- Assign_Vector(ClipPoints[pc++], intP);
- }
- if (aktd <= 0.0)
- {
- Assign_Vector(ClipPoints[pc++], aktP);
- }
- Assign_Vector(preP, aktP);
- pred = aktd;
- }
- if (((fird < 0.0) && (aktd > 0.0)) || ((fird > 0.0) && (aktd < 0.0)))
- {
- d[X] = firP[X] - aktP[X];
- d[Y] = firP[Y] - aktP[Y];
- d[Z] = firP[Z] - aktP[Z];
- k = -aktd / (VY1[X] * d[X] + VY1[Y] * d[Y] + VY1[Z] * d[Z]);
- intP[X] = aktP[X] + k * d[X];
- intP[Y] = aktP[Y] + k * d[Y];
- intP[Z] = aktP[Z] + k * d[Z];
- Assign_Vector(ClipPoints[pc++], intP);
- }
- for (i = 0; i < pc; i++)
- {
- Assign_Vector(Points[i], ClipPoints[i]);
- }
- if ((*PointCnt = pc) == 0)
- return;
- /********** clip polygon at "top" plane **********/
- pc = 0;
- Assign_Vector(firP, Points[0]);
- fird = VY2[X] * firP[X] + VY2[Y] * firP[Y] + VY2[Z] * firP[Z] - DY2;
- if (fird <= 0.0)
- {
- Assign_Vector(ClipPoints[pc++], firP);
- }
- Assign_Vector(aktP, firP);
- Assign_Vector(preP, firP);
- aktd = pred = fird;
- for (i = pc = 0; i < *PointCnt; i++)
- {
- Assign_Vector(aktP, Points[i]);
- aktd = VY2[X] * aktP[X] + VY2[Y] * aktP[Y] + VY2[Z] * aktP[Z] - DY2;
- if (((aktd < 0.0) && (pred > 0.0)) || ((aktd > 0.0) && (pred < 0.0)))
- {
- d[X] = preP[X] - aktP[X];
- d[Y] = preP[Y] - aktP[Y];
- d[Z] = preP[Z] - aktP[Z];
- k = -aktd / (VY2[X] * d[X] + VY2[Y] * d[Y] + VY2[Z] * d[Z]);
- intP[X] = aktP[X] + k * d[X];
- intP[Y] = aktP[Y] + k * d[Y];
- intP[Z] = aktP[Z] + k * d[Z];
- Assign_Vector(ClipPoints[pc++], intP);
- }
- if (aktd <= 0.0)
- {
- Assign_Vector(ClipPoints[pc++], aktP);
- }
- Assign_Vector(preP, aktP);
- pred = aktd;
- }
- if (((fird < 0.0) && (aktd > 0.0)) || ((fird > 0.0) && (aktd < 0.0)))
- {
- d[X] = firP[X] - aktP[X];
- d[Y] = firP[Y] - aktP[Y];
- d[Z] = firP[Z] - aktP[Z];
- k = -aktd / (VY2[X] * d[X] + VY2[Y] * d[Y] + VY2[Z] * d[Z]);
- intP[X] = aktP[X] + k * d[X];
- intP[Y] = aktP[Y] + k * d[Y];
- intP[Z] = aktP[Z] + k * d[Z];
- Assign_Vector(ClipPoints[pc++], intP);
- }
- for (i = 0; i < pc; i++)
- {
- Assign_Vector(Points[i], ClipPoints[i]);
- }
- *PointCnt = pc;
- }
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Destroy_Project_Tree
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * Dieter Bayer
- *
- * DESCRIPTION
- *
- * Recursively destroy a node in a projection (i.e. vista/light) tree.
- *
- * CHANGES
- *
- * Sep 1994 : Creation.
- *
- * Dec 1994 : Fixed memory leakage due to pruned branches. [DB]
- * Mar 1996 : Added COOPERATE for GUIs. [esp]
- *
- ******************************************************************************/
- void Destroy_Project_Tree(PROJECT_TREE_NODE *Node)
- {
- unsigned short i;
- if (Node->is_leaf & TRUE)
- {
- COOPERATE_1
- POV_FREE(Node);
- }
- else
- {
- for (i = 0; i < Node->Entries; i++)
- {
- Destroy_Project_Tree(Node->Entry[i]);
- }
- POV_FREE(Node->Entry);
- POV_FREE(Node);
- }
- }
|