Quake-III-Arena

Quake III Arena GPL Source Release
Log | Files | Refs

VERTSEL.CPP (8287B)


      1 /*
      2 ===========================================================================
      3 Copyright (C) 1999-2005 Id Software, Inc.
      4 
      5 This file is part of Quake III Arena source code.
      6 
      7 Quake III Arena source code is free software; you can redistribute it
      8 and/or modify it under the terms of the GNU General Public License as
      9 published by the Free Software Foundation; either version 2 of the License,
     10 or (at your option) any later version.
     11 
     12 Quake III Arena source code is distributed in the hope that it will be
     13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 GNU General Public License for more details.
     16 
     17 You should have received a copy of the GNU General Public License
     18 along with Foobar; if not, write to the Free Software
     19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
     20 ===========================================================================
     21 */
     22 
     23 #include "stdafx.h"
     24 #include "qe3.h"
     25 #include "winding.h"
     26 
     27 #define NEWEDGESEL 1
     28 
     29 
     30 int	FindPoint (vec3_t point)
     31 {
     32 	int		i, j;
     33 
     34 	for (i=0 ; i<g_qeglobals.d_numpoints ; i++)
     35 	{
     36 		for (j=0 ; j<3 ; j++)
     37 			if (fabs(point[j] - g_qeglobals.d_points[i][j]) > 0.1)
     38 				break;
     39 		if (j == 3)
     40 			return i;
     41 	}
     42 
     43 	VectorCopy (point, g_qeglobals.d_points[g_qeglobals.d_numpoints]);
     44   if (g_qeglobals.d_numpoints < MAX_POINTS-1)
     45   {
     46 	  g_qeglobals.d_numpoints++;
     47   }
     48 
     49 	return g_qeglobals.d_numpoints-1;
     50 }
     51 
     52 int FindEdge (int p1, int p2, face_t *f)
     53 {
     54 	int		i;
     55 
     56 	for (i=0 ; i<g_qeglobals.d_numedges ; i++)
     57 		if (g_qeglobals.d_edges[i].p1 == p2 && g_qeglobals.d_edges[i].p2 == p1)
     58 		{
     59 			g_qeglobals.d_edges[i].f2 = f;
     60 			return i;
     61 		}
     62 
     63 	g_qeglobals.d_edges[g_qeglobals.d_numedges].p1 = p1;
     64 	g_qeglobals.d_edges[g_qeglobals.d_numedges].p2 = p2;
     65 	g_qeglobals.d_edges[g_qeglobals.d_numedges].f1 = f;
     66 
     67   if (g_qeglobals.d_numedges < MAX_EDGES-1)
     68   {
     69 	  g_qeglobals.d_numedges++;
     70   }
     71 
     72 	return g_qeglobals.d_numedges-1;
     73 }
     74 
     75 #ifdef NEWEDGESEL
     76 void MakeFace (brush_t* b, face_t *f)
     77 #else
     78 void MakeFace (face_t *f)
     79 #endif
     80 {
     81 	winding_t	*w;
     82 	int			i;
     83 	int			pnum[128];
     84 
     85 #ifdef NEWEDGESEL
     86 	w = Brush_MakeFaceWinding (b, f);
     87 #else
     88 	w = Brush_MakeFaceWinding (selected_brushes.next, f);
     89 #endif
     90 	if (!w)
     91 		return;
     92 	for (i=0 ; i<w->numpoints ; i++)
     93 		pnum[i] = FindPoint (w->points[i]);
     94 	for (i=0 ; i<w->numpoints ; i++)
     95 		FindEdge (pnum[i], pnum[(i+1)%w->numpoints], f);
     96 
     97 	free (w);
     98 }
     99 
    100 void SetupVertexSelection (void)
    101 {
    102 	face_t	*f;
    103 	brush_t *b;
    104 
    105 	g_qeglobals.d_numpoints = 0;
    106 	g_qeglobals.d_numedges = 0;
    107 
    108 #ifdef NEWEDGESEL
    109 	for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
    110   {
    111 	  for (f=b->brush_faces ; f ; f=f->next)
    112 		  MakeFace (b,f);
    113   }
    114 #else
    115 	if (!QE_SingleBrush())
    116 		return;
    117 
    118   b = selected_brushes.next;
    119   for (f=b->brush_faces ; f ; f=f->next)
    120     MakeFace (b,f);
    121 #endif
    122 
    123 }
    124 
    125 
    126 #ifdef NEWEDGESEL
    127 void SelectFaceEdge (brush_t* b, face_t *f, int p1, int p2)
    128 #else
    129 void SelectFaceEdge (face_t *f, int p1, int p2)
    130 #endif
    131 {
    132 	winding_t	*w;
    133 	int			i, j, k;
    134 	int			pnum[128];
    135 
    136 #ifdef NEWEDGESEL
    137 	w = Brush_MakeFaceWinding (b, f);
    138 #else
    139 	w = Brush_MakeFaceWinding (selected_brushes.next, f);
    140 #endif
    141 	if (!w)
    142 		return;
    143 	for (i=0 ; i<w->numpoints ; i++)
    144 		pnum[i] = FindPoint (w->points[i]);
    145 
    146   for (i=0 ; i<w->numpoints ; i++)
    147 		if (pnum[i] == p1 && pnum[(i+1)%w->numpoints] == p2)
    148 		{
    149 			VectorCopy (g_qeglobals.d_points[pnum[i]], f->planepts[0]);
    150 			VectorCopy (g_qeglobals.d_points[pnum[(i+1)%w->numpoints]], f->planepts[1]);
    151 			VectorCopy (g_qeglobals.d_points[pnum[(i+2)%w->numpoints]], f->planepts[2]);
    152 			for (j=0 ; j<3 ; j++)
    153 			{
    154 				for (k=0 ; k<3 ; k++)
    155 				{
    156 					f->planepts[j][k] = floor(f->planepts[j][k]/g_qeglobals.d_gridsize+0.5)*g_qeglobals.d_gridsize;
    157 				}
    158 			}
    159 
    160 			AddPlanept (f->planepts[0]);
    161 			AddPlanept (f->planepts[1]);
    162 			break;
    163 		}
    164 
    165 	if (i == w->numpoints)
    166 		Sys_Printf ("SelectFaceEdge: failed\n");
    167 	free (w);
    168 }
    169 
    170 
    171 void SelectVertex (int p1)
    172 {
    173 	brush_t		*b;
    174 	winding_t	*w;
    175 	int			i, j, k;
    176 	face_t		*f;
    177 
    178 #ifdef NEWEDGESEL
    179 	for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
    180   {
    181 	  for (f=b->brush_faces ; f ; f=f->next)
    182 	  {
    183 		  w =  Brush_MakeFaceWinding (b, f);
    184 		  if (!w)
    185 			  continue;
    186 		  for (i=0 ; i<w->numpoints ; i++)
    187 		  {
    188 			  if (FindPoint (w->points[i]) == p1)
    189 			  {
    190 				  VectorCopy (w->points[(i+w->numpoints-1)%w->numpoints], f->planepts[0]);
    191 				  VectorCopy (w->points[i], f->planepts[1]);
    192 				  VectorCopy (w->points[(i+1)%w->numpoints], f->planepts[2]);
    193 			    for (j=0 ; j<3 ; j++)
    194           {
    195 				    for (k=0 ; k<3 ; k++)
    196             {
    197 					    ;//f->planepts[j][k] = floor(f->planepts[j][k]/g_qeglobals.d_gridsize+0.5)*g_qeglobals.d_gridsize;
    198             } 
    199           }
    200 
    201 			    AddPlanept (f->planepts[1]);
    202           //MessageBeep(-1);
    203 
    204 			    break;
    205         }
    206 		  }
    207 		  free (w);
    208 	  }
    209   }
    210 #else
    211 	b = selected_brushes.next;
    212 	for (f=b->brush_faces ; f ; f=f->next)
    213 	{
    214 		w =  Brush_MakeFaceWinding (b, f);
    215 		if (!w)
    216 			continue;
    217 		for (i=0 ; i<w->numpoints ; i++)
    218 		{
    219 			if (FindPoint (w->points[i]) == p1)
    220 			{
    221 				VectorCopy (w->points[(i+w->numpoints-1)%w->numpoints], f->planepts[0]);
    222 				VectorCopy (w->points[i], f->planepts[1]);
    223 				VectorCopy (w->points[(i+1)%w->numpoints], f->planepts[2]);
    224 			  for (j=0 ; j<3 ; j++)
    225         {
    226 				  for (k=0 ; k<3 ; k++)
    227           {
    228 					  ;//f->planepts[j][k] = floor(f->planepts[j][k]/g_qeglobals.d_gridsize+0.5)*g_qeglobals.d_gridsize;
    229           } 
    230         }
    231 
    232 			  AddPlanept (f->planepts[1]);
    233         //MessageBeep(-1);
    234 
    235 			  break;
    236       }
    237 		}
    238 		free (w);
    239 	}
    240 #endif
    241 }
    242 
    243 void SelectEdgeByRay (vec3_t org, vec3_t dir)
    244 {
    245 	int		i, j, besti;
    246 	float	d, bestd;
    247 	vec3_t	mid, temp;
    248 	pedge_t	*e;
    249 
    250 	// find the edge closest to the ray
    251 	besti = -1;
    252 	bestd = 8;
    253 
    254 	for (i=0 ; i<g_qeglobals.d_numedges ; i++)
    255 	{
    256 		for (j=0 ; j<3 ; j++)
    257 			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]);
    258 
    259 		VectorSubtract (mid, org, temp);
    260 		d = DotProduct (temp, dir);
    261 		VectorMA (org, d, dir, temp);
    262 		VectorSubtract (mid, temp, temp);
    263 		d = VectorLength (temp);
    264 		if (d < bestd)
    265 		{
    266 			bestd = d;
    267 			besti = i;
    268 		}
    269 	}
    270 
    271 	if (besti == -1)
    272 	{
    273 		Sys_Printf ("Click didn't hit an edge\n");
    274 		return;
    275 	}
    276 	Sys_Printf ("hit edge\n");
    277 
    278 	// make the two faces that border the edge use the two edge points
    279 	// as primary drag points
    280 	g_qeglobals.d_num_move_points = 0;
    281 	e = &g_qeglobals.d_edges[besti];
    282 #ifdef NEWEDGESEL
    283 	for (brush_t* b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
    284   {
    285     SelectFaceEdge (b, e->f1, e->p1, e->p2);
    286 	  SelectFaceEdge (b, e->f2, e->p2, e->p1);
    287   }
    288 #else
    289   SelectFaceEdge (e->f1, e->p1, e->p2);
    290 	SelectFaceEdge (e->f2, e->p2, e->p1);
    291 #endif
    292 
    293 
    294 }
    295 
    296 void SelectVertexByRay (vec3_t org, vec3_t dir)
    297 {
    298 	int		i, besti;
    299 	float	d, bestd;
    300 	vec3_t	temp;
    301 
    302 	// find the point closest to the ray
    303 	besti = -1;
    304 	bestd = 8;
    305 
    306 	for (i=0 ; i<g_qeglobals.d_numpoints ; i++)
    307 	{
    308 		VectorSubtract (g_qeglobals.d_points[i], org, temp);
    309 		d = DotProduct (temp, dir);
    310 		VectorMA (org, d, dir, temp);
    311 		VectorSubtract (g_qeglobals.d_points[i], temp, temp);
    312 		d = VectorLength (temp);
    313 		if (d < bestd)
    314 		{
    315 			bestd = d;
    316 			besti = i;
    317 		}
    318 	}
    319 
    320 	if (besti == -1)
    321 	{
    322 		Sys_Printf ("Click didn't hit a vertex\n");
    323 		return;
    324 	}
    325 	Sys_Printf ("hit vertex\n");
    326 	g_qeglobals.d_move_points[g_qeglobals.d_num_move_points++] = g_qeglobals.d_points[besti];
    327 	//SelectVertex (besti);
    328 }
    329 
    330 
    331 
    332 extern void AddPatchMovePoint(vec3_t v, bool bMulti, bool bFull);
    333 void SelectCurvePointByRay (vec3_t org, vec3_t dir, int buttons)
    334 {
    335 	int		i, besti;
    336 	float	d, bestd;
    337 	vec3_t	temp;
    338 
    339 	// find the point closest to the ray
    340 	besti = -1;
    341 	bestd = 8;
    342 
    343 	for (i=0 ; i<g_qeglobals.d_numpoints ; i++)
    344 	{
    345 		VectorSubtract (g_qeglobals.d_points[i], org, temp);
    346 		d = DotProduct (temp, dir);
    347 		VectorMA (org, d, dir, temp);
    348 		VectorSubtract (g_qeglobals.d_points[i], temp, temp);
    349 		d = VectorLength (temp);
    350 		if (d <= bestd)
    351 		{
    352 			bestd = d;
    353 			besti = i;
    354 		}
    355 	}
    356 
    357 	if (besti == -1)
    358 	{
    359     if (g_pParentWnd->ActiveXY()->AreaSelectOK())
    360     {
    361       g_qeglobals.d_select_mode = sel_area;
    362       VectorCopy(org, g_qeglobals.d_vAreaTL);
    363       VectorCopy(org, g_qeglobals.d_vAreaBR);
    364     }
    365 		return;
    366 	}
    367 	//Sys_Printf ("hit vertex\n");
    368   AddPatchMovePoint(g_qeglobals.d_points[besti], buttons & MK_CONTROL, buttons & MK_SHIFT);
    369 }
    370 
    371 
    372