Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

194 lines
5.6 KiB

  1. /**************************************************************************
  2. * *
  3. * Copyright (C) 1989, Silicon Graphics, Inc. *
  4. * *
  5. * These coded instructions, statements, and computer programs contain *
  6. * unpublished proprietary information of Silicon Graphics, Inc., and *
  7. * are protected by Federal copyright law. They may not be disclosed *
  8. * to third parties or copied or duplicated in any form, in whole or *
  9. * in part, without the prior written consent of Silicon Graphics, Inc. *
  10. * *
  11. **************************************************************************/
  12. /* ray.c */
  13. /* Derrick Burns - 1989 */
  14. #include <glos.h>
  15. #include <GL/gl.h>
  16. #include <GL/glu.h>
  17. #include "monotone.h"
  18. #include "bufpool.h"
  19. #define ZERO 0.000001
  20. /*----------------------------------------------------------------------------
  21. * init_raylist - create dummy rays at y = +/- infinity
  22. *----------------------------------------------------------------------------
  23. */
  24. void
  25. __gl_init_raylist( GLUtriangulatorObj *tobj )
  26. {
  27. Ray *ray1, *ray2;
  28. if( ! tobj->raypool )
  29. tobj->raypool = __gl_new_pool( sizeof( Ray ), 32, "tobj->raypool" );
  30. ray1 = __gl_new_ray( tobj, 1 );
  31. ray2 = __gl_new_ray( tobj, 0 );
  32. ray1->next = ray1->prev = ray2;
  33. ray2->next = ray2->prev = ray1;
  34. ray1->coords[0] = ray1->coords[1] = (float)0.0; ray1->coords[2] = (float)-1.0;
  35. ray2->coords[0] = ray2->coords[1] = (float)0.0; ray2->coords[2] = (float)1.0;
  36. ray1->vertex = 0;
  37. ray2->vertex = 0;
  38. #ifdef LAZYRECALC
  39. ray1->end1 = ray1->end2 = ray2->end1 = ray2->end2 = 0;
  40. #endif
  41. tobj->raylist = ray1;
  42. }
  43. /*----------------------------------------------------------------------------
  44. * add2_raylist - add two rays to the ray list
  45. *----------------------------------------------------------------------------
  46. */
  47. void
  48. __gl_add2_raylist( Ray *prev, Ray *ray1, Ray *ray2 )
  49. {
  50. ray1->prev = prev;
  51. ray1->next = ray2;
  52. ray2->prev = ray1;
  53. ray2->next = prev->next;
  54. ray1->prev->next = ray1;
  55. ray2->next->prev = ray2;
  56. }
  57. /*----------------------------------------------------------------------------
  58. * remove2_raylist - remove two rays from the ray list
  59. *----------------------------------------------------------------------------
  60. */
  61. void
  62. __gl_remove2_raylist( GLUtriangulatorObj *tobj, Ray *ray )
  63. {
  64. if( ray == tobj->raylist ||
  65. ray == tobj->raylist->prev ||
  66. ray->next == tobj->raylist ) {
  67. __gl_in_error( tobj, 7 );
  68. } else {
  69. ray->prev->next = ray->next->next;
  70. ray->next->next->prev = ray->prev;
  71. }
  72. }
  73. /*----------------------------------------------------------------------------
  74. * findray_raylist - find first ray below given vertex
  75. *----------------------------------------------------------------------------
  76. */
  77. Ray *
  78. __gl_findray_raylist( GLUtriangulatorObj *tobj, Vert *v )
  79. {
  80. Ray *ray;
  81. for( ray=tobj->raylist; __gl_above_ray(ray, v) < -ZERO; ray=ray->next );
  82. return ray;
  83. }
  84. /*----------------------------------------------------------------------------
  85. * free_raylist - reclaim all rays
  86. *----------------------------------------------------------------------------
  87. */
  88. void
  89. __gl_free_raylist( GLUtriangulatorObj *tobj )
  90. {
  91. if (tobj->raypool) {
  92. __gl_clear_pool(tobj->raypool);
  93. }
  94. }
  95. /*----------------------------------------------------------------------------
  96. * new_ray - create a new ray
  97. *----------------------------------------------------------------------------
  98. */
  99. Ray *
  100. __gl_new_ray( GLUtriangulatorObj *tobj, int orientation )
  101. {
  102. Ray *ray = (Ray *) __gl_new_buffer( tobj->raypool );
  103. ray->orientation = orientation;
  104. ray->mustconnect = 0;
  105. ray->vertex = 0;
  106. return ray;
  107. }
  108. /*----------------------------------------------------------------------------
  109. * delete_ray - free ray
  110. *----------------------------------------------------------------------------
  111. */
  112. void
  113. __gl_delete_ray( GLUtriangulatorObj *tobj, Ray *ray )
  114. {
  115. __gl_free_buffer( tobj->raypool, ray );
  116. }
  117. /*----------------------------------------------------------------------------
  118. * above_ray - determine if a vertex is above_ray a ray
  119. *----------------------------------------------------------------------------
  120. */
  121. int
  122. __gl_above_ray( Ray *ray, Vert *vert )
  123. {
  124. /* returns 1 if the vertex is above_ray the ray (is in the region
  125. * associated with the ray) 0 if it's on the ray, and -1 if it is
  126. * below. */
  127. float dot;
  128. #ifdef LAZYRECALC
  129. if( ray->end1 != 0 ) {
  130. ray->coords[0] = ray->end1->t - ray->end2->t;
  131. ray->coords[1] = ray->end2->s - ray->end1->s;
  132. ray->coords[2] = - ray->coords[1] * ray->end2->t
  133. - ray->coords[0] * ray->end2->s;
  134. ray->end1 = ray->end2 = 0;
  135. }
  136. #endif
  137. dot = ray->coords[0]*vert->s + ray->coords[1]*vert->t + ray->coords[2];
  138. if (dot > (float)0.0) return 1;
  139. if (dot < (float)0.0) return -1;
  140. /* XXX
  141. If we reach this point, it means that an input vertex lies on
  142. an edge connecting two other veritces. This is officially
  143. disallowed. In some cases this will be detected in monotonize
  144. and in others it won't. When it is not detected, it will NOT
  145. cause the program to die, and it WILL give reasonable results.
  146. */
  147. return 0;
  148. }
  149. /*----------------------------------------------------------------------------
  150. * recalc_ray - calculate the vector perpindicular to the line through v0/v1
  151. *----------------------------------------------------------------------------
  152. */
  153. void
  154. __gl_recalc_ray( Ray *ray, Vert *v0, Vert *v1 )
  155. {
  156. #ifdef LAZYRECALC
  157. ray->end1 = v0;
  158. ray->end2 = v1;
  159. #else
  160. ray->coords[0] = v0->t - v1->t;
  161. ray->coords[1] = v1->s - v0->s;
  162. ray->coords[2] = - ray->coords[1]*v1->t - ray->coords[0]*v1->s;
  163. #endif
  164. }