windows-nt/Source/XPSP1/NT/multimedia/opengl/glu/libtri/ray.c

195 lines
5.6 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/**************************************************************************
* *
* Copyright (C) 1989, Silicon Graphics, Inc. *
* *
* These coded instructions, statements, and computer programs contain *
* unpublished proprietary information of Silicon Graphics, Inc., and *
* are protected by Federal copyright law. They may not be disclosed *
* to third parties or copied or duplicated in any form, in whole or *
* in part, without the prior written consent of Silicon Graphics, Inc. *
* *
**************************************************************************/
/* ray.c */
/* Derrick Burns - 1989 */
#include <glos.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include "monotone.h"
#include "bufpool.h"
#define ZERO 0.000001
/*----------------------------------------------------------------------------
* init_raylist - create dummy rays at y = +/- infinity
*----------------------------------------------------------------------------
*/
void
__gl_init_raylist( GLUtriangulatorObj *tobj )
{
Ray *ray1, *ray2;
if( ! tobj->raypool )
tobj->raypool = __gl_new_pool( sizeof( Ray ), 32, "tobj->raypool" );
ray1 = __gl_new_ray( tobj, 1 );
ray2 = __gl_new_ray( tobj, 0 );
ray1->next = ray1->prev = ray2;
ray2->next = ray2->prev = ray1;
ray1->coords[0] = ray1->coords[1] = (float)0.0; ray1->coords[2] = (float)-1.0;
ray2->coords[0] = ray2->coords[1] = (float)0.0; ray2->coords[2] = (float)1.0;
ray1->vertex = 0;
ray2->vertex = 0;
#ifdef LAZYRECALC
ray1->end1 = ray1->end2 = ray2->end1 = ray2->end2 = 0;
#endif
tobj->raylist = ray1;
}
/*----------------------------------------------------------------------------
* add2_raylist - add two rays to the ray list
*----------------------------------------------------------------------------
*/
void
__gl_add2_raylist( Ray *prev, Ray *ray1, Ray *ray2 )
{
ray1->prev = prev;
ray1->next = ray2;
ray2->prev = ray1;
ray2->next = prev->next;
ray1->prev->next = ray1;
ray2->next->prev = ray2;
}
/*----------------------------------------------------------------------------
* remove2_raylist - remove two rays from the ray list
*----------------------------------------------------------------------------
*/
void
__gl_remove2_raylist( GLUtriangulatorObj *tobj, Ray *ray )
{
if( ray == tobj->raylist ||
ray == tobj->raylist->prev ||
ray->next == tobj->raylist ) {
__gl_in_error( tobj, 7 );
} else {
ray->prev->next = ray->next->next;
ray->next->next->prev = ray->prev;
}
}
/*----------------------------------------------------------------------------
* findray_raylist - find first ray below given vertex
*----------------------------------------------------------------------------
*/
Ray *
__gl_findray_raylist( GLUtriangulatorObj *tobj, Vert *v )
{
Ray *ray;
for( ray=tobj->raylist; __gl_above_ray(ray, v) < -ZERO; ray=ray->next );
return ray;
}
/*----------------------------------------------------------------------------
* free_raylist - reclaim all rays
*----------------------------------------------------------------------------
*/
void
__gl_free_raylist( GLUtriangulatorObj *tobj )
{
if (tobj->raypool) {
__gl_clear_pool(tobj->raypool);
}
}
/*----------------------------------------------------------------------------
* new_ray - create a new ray
*----------------------------------------------------------------------------
*/
Ray *
__gl_new_ray( GLUtriangulatorObj *tobj, int orientation )
{
Ray *ray = (Ray *) __gl_new_buffer( tobj->raypool );
ray->orientation = orientation;
ray->mustconnect = 0;
ray->vertex = 0;
return ray;
}
/*----------------------------------------------------------------------------
* delete_ray - free ray
*----------------------------------------------------------------------------
*/
void
__gl_delete_ray( GLUtriangulatorObj *tobj, Ray *ray )
{
__gl_free_buffer( tobj->raypool, ray );
}
/*----------------------------------------------------------------------------
* above_ray - determine if a vertex is above_ray a ray
*----------------------------------------------------------------------------
*/
int
__gl_above_ray( Ray *ray, Vert *vert )
{
/* returns 1 if the vertex is above_ray the ray (is in the region
* associated with the ray) 0 if it's on the ray, and -1 if it is
* below. */
float dot;
#ifdef LAZYRECALC
if( ray->end1 != 0 ) {
ray->coords[0] = ray->end1->t - ray->end2->t;
ray->coords[1] = ray->end2->s - ray->end1->s;
ray->coords[2] = - ray->coords[1] * ray->end2->t
- ray->coords[0] * ray->end2->s;
ray->end1 = ray->end2 = 0;
}
#endif
dot = ray->coords[0]*vert->s + ray->coords[1]*vert->t + ray->coords[2];
if (dot > (float)0.0) return 1;
if (dot < (float)0.0) return -1;
/* XXX
If we reach this point, it means that an input vertex lies on
an edge connecting two other veritces. This is officially
disallowed. In some cases this will be detected in monotonize
and in others it won't. When it is not detected, it will NOT
cause the program to die, and it WILL give reasonable results.
*/
return 0;
}
/*----------------------------------------------------------------------------
* recalc_ray - calculate the vector perpindicular to the line through v0/v1
*----------------------------------------------------------------------------
*/
void
__gl_recalc_ray( Ray *ray, Vert *v0, Vert *v1 )
{
#ifdef LAZYRECALC
ray->end1 = v0;
ray->end2 = v1;
#else
ray->coords[0] = v0->t - v1->t;
ray->coords[1] = v1->s - v0->s;
ray->coords[2] = - ray->coords[1]*v1->t - ray->coords[0]*v1->s;
#endif
}