vertsel.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. /*
  2. ===========================================================================
  3. Copyright (C) 1997-2006 Id Software, Inc.
  4. This file is part of Quake 2 Tools source code.
  5. Quake 2 Tools source code is free software; you can redistribute it
  6. and/or modify it under the terms of the GNU General Public License as
  7. published by the Free Software Foundation; either version 2 of the License,
  8. or (at your option) any later version.
  9. Quake 2 Tools source code is distributed in the hope that it will be
  10. useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with Quake 2 Tools source code; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16. ===========================================================================
  17. */
  18. #include "qe3.h"
  19. int FindPoint (vec3_t point)
  20. {
  21. int i, j;
  22. for (i=0 ; i<g_qeglobals.d_numpoints ; i++)
  23. {
  24. for (j=0 ; j<3 ; j++)
  25. if (fabs(point[j] - g_qeglobals.d_points[i][j]) > 0.1)
  26. break;
  27. if (j == 3)
  28. return i;
  29. }
  30. VectorCopy (point, g_qeglobals.d_points[g_qeglobals.d_numpoints]);
  31. g_qeglobals.d_numpoints++;
  32. return g_qeglobals.d_numpoints-1;
  33. }
  34. int FindEdge (int p1, int p2, face_t *f)
  35. {
  36. int i;
  37. for (i=0 ; i<g_qeglobals.d_numedges ; i++)
  38. if (g_qeglobals.d_edges[i].p1 == p2 && g_qeglobals.d_edges[i].p2 == p1)
  39. {
  40. g_qeglobals.d_edges[i].f2 = f;
  41. return i;
  42. }
  43. g_qeglobals.d_edges[g_qeglobals.d_numedges].p1 = p1;
  44. g_qeglobals.d_edges[g_qeglobals.d_numedges].p2 = p2;
  45. g_qeglobals.d_edges[g_qeglobals.d_numedges].f1 = f;
  46. g_qeglobals.d_numedges++;
  47. return g_qeglobals.d_numedges-1;
  48. }
  49. void MakeFace (face_t *f)
  50. {
  51. winding_t *w;
  52. int i;
  53. int pnum[128];
  54. w = MakeFaceWinding (selected_brushes.next, f);
  55. if (!w)
  56. return;
  57. for (i=0 ; i<w->numpoints ; i++)
  58. pnum[i] = FindPoint (w->points[i]);
  59. for (i=0 ; i<w->numpoints ; i++)
  60. FindEdge (pnum[i], pnum[(i+1)%w->numpoints], f);
  61. free (w);
  62. }
  63. void SetupVertexSelection (void)
  64. {
  65. face_t *f;
  66. brush_t *b;
  67. g_qeglobals.d_numpoints = 0;
  68. g_qeglobals.d_numedges = 0;
  69. if (!QE_SingleBrush())
  70. return;
  71. b = selected_brushes.next;
  72. for (f=b->brush_faces ; f ; f=f->next)
  73. MakeFace (f);
  74. Sys_UpdateWindows (W_ALL);
  75. }
  76. void SelectFaceEdge (face_t *f, int p1, int p2)
  77. {
  78. winding_t *w;
  79. int i, j, k;
  80. int pnum[128];
  81. w = MakeFaceWinding (selected_brushes.next, f);
  82. if (!w)
  83. return;
  84. for (i=0 ; i<w->numpoints ; i++)
  85. pnum[i] = FindPoint (w->points[i]);
  86. for (i=0 ; i<w->numpoints ; i++)
  87. if (pnum[i] == p1 && pnum[(i+1)%w->numpoints] == p2)
  88. {
  89. VectorCopy (g_qeglobals.d_points[pnum[i]], f->planepts[0]);
  90. VectorCopy (g_qeglobals.d_points[pnum[(i+1)%w->numpoints]], f->planepts[1]);
  91. VectorCopy (g_qeglobals.d_points[pnum[(i+2)%w->numpoints]], f->planepts[2]);
  92. for (j=0 ; j<3 ; j++)
  93. {
  94. for (k=0 ; k<3 ; k++)
  95. {
  96. f->planepts[j][k] = floor(f->planepts[j][k]/g_qeglobals.d_gridsize+0.5)*g_qeglobals.d_gridsize;
  97. }
  98. }
  99. AddPlanept (f->planepts[0]);
  100. AddPlanept (f->planepts[1]);
  101. break;
  102. }
  103. if (i == w->numpoints)
  104. Sys_Printf ("SelectFaceEdge: failed\n");
  105. free (w);
  106. }
  107. void SelectVertex (int p1)
  108. {
  109. brush_t *b;
  110. winding_t *w;
  111. int i, j, k;
  112. face_t *f;
  113. b = selected_brushes.next;
  114. for (f=b->brush_faces ; f ; f=f->next)
  115. {
  116. w = MakeFaceWinding (b, f);
  117. if (!w)
  118. continue;
  119. for (i=0 ; i<w->numpoints ; i++)
  120. {
  121. if (FindPoint (w->points[i]) == p1)
  122. {
  123. VectorCopy (w->points[(i+w->numpoints-1)%w->numpoints], f->planepts[0]);
  124. VectorCopy (w->points[i], f->planepts[1]);
  125. VectorCopy (w->points[(i+1)%w->numpoints], f->planepts[2]);
  126. for (j=0 ; j<3 ; j++)
  127. {
  128. for (k=0 ; k<3 ; k++)
  129. {
  130. f->planepts[j][k] = floor(f->planepts[j][k]/g_qeglobals.d_gridsize+0.5)*g_qeglobals.d_gridsize;
  131. }
  132. }
  133. AddPlanept (f->planepts[1]);
  134. break;
  135. }
  136. }
  137. free (w);
  138. }
  139. }
  140. void SelectEdgeByRay (vec3_t org, vec3_t dir)
  141. {
  142. int i, j, besti;
  143. float d, bestd;
  144. vec3_t mid, temp;
  145. pedge_t *e;
  146. // find the edge closest to the ray
  147. besti = -1;
  148. bestd = 8;
  149. for (i=0 ; i<g_qeglobals.d_numedges ; i++)
  150. {
  151. for (j=0 ; j<3 ; j++)
  152. mid[j] = 0.5*(g_qeglobals.d_points[g_qeglobals.d_edges[i].p1][j] + g_qeglobals.d_points[g_qeglobals.d_edges[i].p2][j]);
  153. VectorSubtract (mid, org, temp);
  154. d = DotProduct (temp, dir);
  155. VectorMA (org, d, dir, temp);
  156. VectorSubtract (mid, temp, temp);
  157. d = VectorLength (temp);
  158. if (d < bestd)
  159. {
  160. bestd = d;
  161. besti = i;
  162. }
  163. }
  164. if (besti == -1)
  165. {
  166. Sys_Printf ("Click didn't hit an edge\n");
  167. return;
  168. }
  169. Sys_Printf ("hit edge\n");
  170. // make the two faces that border the edge use the two edge points
  171. // as primary drag points
  172. g_qeglobals.d_num_move_points = 0;
  173. e = &g_qeglobals.d_edges[besti];
  174. SelectFaceEdge (e->f1, e->p1, e->p2);
  175. SelectFaceEdge (e->f2, e->p2, e->p1);
  176. }
  177. void SelectVertexByRay (vec3_t org, vec3_t dir)
  178. {
  179. int i, besti;
  180. float d, bestd;
  181. vec3_t temp;
  182. // find the point closest to the ray
  183. besti = -1;
  184. bestd = 8;
  185. for (i=0 ; i<g_qeglobals.d_numpoints ; i++)
  186. {
  187. VectorSubtract (g_qeglobals.d_points[i], org, temp);
  188. d = DotProduct (temp, dir);
  189. VectorMA (org, d, dir, temp);
  190. VectorSubtract (g_qeglobals.d_points[i], temp, temp);
  191. d = VectorLength (temp);
  192. if (d < bestd)
  193. {
  194. bestd = d;
  195. besti = i;
  196. }
  197. }
  198. if (besti == -1)
  199. {
  200. Sys_Printf ("Click didn't hit a vertex\n");
  201. return;
  202. }
  203. Sys_Printf ("hit vertex\n");
  204. SelectVertex (besti);
  205. }