Пример #1
0
trace_t Test_Ray (vec3_t origin, vec3_t dir, int flags)
{
	brush_t	*brush;
	face_t	*face;
	float	dist;
	trace_t	t;

	memset (&t, 0, sizeof(t));
	t.dist = DIST_START;

	if (! (flags & SF_SELECTED_ONLY) )
		for (brush = active_brushes.next ; brush != &active_brushes ; brush=brush->next)
		{
			if ( (flags & SF_ENTITIES_FIRST) && brush->owner == world_entity)
				continue;
			if (FilterBrush (brush))
				continue;
			face = Brush_Ray (origin, dir, brush, &dist);
			if (dist > 0 && dist < t.dist)
			{
				t.dist		= dist;
				t.brush		= brush;
				t.face		= face;
				t.selected	= FALSE;
			}
		}

	for (brush = selected_brushes.next ; brush != &selected_brushes ; brush=brush->next)
	{
		if ( (flags & SF_ENTITIES_FIRST) && brush->owner == world_entity)
			continue;
		if (FilterBrush (brush))
			continue;
		face = Brush_Ray (origin, dir, brush, &dist);
		if (dist > 0 && dist < t.dist)
		{
			t.dist		= dist;
			t.brush		= brush;
			t.face		= face;
			t.selected	= TRUE;
		}
	}

	// if entites first, but didn't find any, check regular

	if ( (flags & SF_ENTITIES_FIRST) && t.brush == NULL)
		return Test_Ray (origin, dir, flags - SF_ENTITIES_FIRST);

	return t;
}
Пример #2
0
/*
   ===========
   Map_RegionOff

   Other filtering options may still be on
   ===========
 */
void Map_RegionOff( void ){
	brush_t *b, *next;
	int i;

	region_active = false;
	for ( i = 0 ; i < 3 ; i++ )
	{
		region_maxs[i] = g_MaxWorldCoord - 64;
		region_mins[i] = g_MinWorldCoord + 64;
	}

	for ( b = filtered_brushes.next ; b != &filtered_brushes ; b = next )
	{
		next = b->next;
		if ( Map_IsBrushFiltered( b ) ) {
			continue;       // still filtered
		}
		Brush_RemoveFromList( b );
		if ( active_brushes.next == NULL || active_brushes.prev == NULL ) {
			active_brushes.next = &active_brushes;
			active_brushes.prev = &active_brushes;
		}
		Brush_AddToList( b, &active_brushes );
		b->bFiltered = FilterBrush( b );
	}
	Sys_UpdateWindows( W_ALL );
}
Пример #3
0
void Select_Inside( void )
{
	brush_s*    b, *next;
	int     i;
	edVec3_c    mins, maxs;
	
	if ( !QE_SingleBrush() )
		return;
		
	clearSelection();
	
	mins = selected_brushes.next->getMins();
	maxs = selected_brushes.next->getMaxs();
	Select_Delete();
	
	for ( b = active_brushes.next ; b != &active_brushes ; b = next )
	{
		next = b->next;
		
		if ( FilterBrush( b ) )
			continue;
			
		for ( i = 0 ; i < 3 ; i++ )
			if ( b->getMaxs()[i] > maxs[i] || b->getMins()[i] < mins[i] )
				break;
		if ( i == 3 )
		{
			Brush_RemoveFromList( b );
			Brush_AddToList( b, &selected_brushes );
		}
	}
	Sys_UpdateWindows( W_ALL );
}
Пример #4
0
void Select_Inside (void)
{
	brush_t	*b, *next;
	int		i;
	vec3_t	mins, maxs;

	if (!QE_SingleBrush ())
		return;

	g_qeglobals.d_select_mode = sel_brush;

	VectorCopy (selected_brushes.next->mins, mins);
	VectorCopy (selected_brushes.next->maxs, maxs);
	Select_Delete ();

	for (b=active_brushes.next ; b != &active_brushes ; b=next)
	{
		next = b->next;

	 	if (FilterBrush (b))
	 		continue;

		for (i=0 ; i<3 ; i++)
			if (b->maxs[i] > maxs[i] || b->mins[i] < mins[i])
				break;
		if (i == 3)
		{
			Brush_RemoveFromList (b);
			Brush_AddToList (b, &selected_brushes);
		}
	}
	Sys_UpdateWindows (W_ALL);
}
Пример #5
0
/*
====================
Entity_UpdateSoundEmitter

Deletes the soundEmitter if the entity should not emit a sound due
to it not having one, being filtered away, or the sound mode being turned off.

Creates or updates the soundEmitter if needed
====================
*/
void Entity_UpdateSoundEmitter( entity_t *ent ) {
	bool	playing = false;

	// if an entity doesn't have any brushes at all, don't do anything
	// if the brush isn't displayed (filtered or culled), don't do anything
	if ( g_pParentWnd->GetCamera()->GetSoundMode() 
		&& ent->brushes.onext != &ent->brushes && !FilterBrush(ent->brushes.onext) ) {
		// check for sounds
		const char *v = ValueForKey( ent, "s_shader" );
		if ( v[0] ) {
			refSound_t	sound;

			gameEdit->ParseSpawnArgsToRefSound( &ent->epairs, &sound );
			if ( !sound.waitfortrigger ) {	// waitfortrigger will not start playing immediately
				if ( !ent->soundEmitter ) {
					ent->soundEmitter = g_qeglobals.sw->AllocSoundEmitter();
				}
				playing = true;
				ent->soundEmitter->UpdateEmitter( ent->origin, 0, &sound.parms );
				// always play on a single channel, so updates always override
				ent->soundEmitter->StartSound( sound.shader, SCHANNEL_ONE );
			}
		}
	}

	// delete the soundEmitter if not used
	if ( !playing && ent->soundEmitter ) {
		ent->soundEmitter->Free( true );
		ent->soundEmitter = NULL;
	}

}
Пример #6
0
void Select_Touching (void)
{
	brush_t	*b, *next;
	int		i;
	vec3_t	mins, maxs;

	if (!QE_SingleBrush ())
		return;

	clearSelection();

	VectorCopy (selected_brushes.next->mins, mins);
	VectorCopy (selected_brushes.next->maxs, maxs);

	for (b=active_brushes.next ; b != &active_brushes ; b=next)
	{
		next = b->next;

		if (FilterBrush (b))
			continue;

		for (i=0 ; i<3 ; i++)
			if (b->mins[i] > maxs[i]+1 || b->maxs[i] < mins[i]-1)
				break;

		if (i == 3)
		{
			Brush_RemoveFromList (b);
			Brush_AddToList (b, &selected_brushes);
		}
	}
	Sys_UpdateWindows (W_ALL);
}
Пример #7
0
/*
=============
CSG_Subtract
=============
*/
void CSG_Subtract (void)
{
	brush_t		*b, *s, *frag, *front, *back, *next, *snext;
	face_t		*f;
	int			i;

	Sys_Printf ("Subtracting...\n");

	for (b = selected_brushes.next ; b != &selected_brushes ; b=next)
	{
		next = b->next;

		if (b->owner->eclass->fixedsize)
			continue;	// can't use texture from a fixed entity, so don't subtract

		for (s=active_brushes.next ; s != &active_brushes ; s=snext)
		{
			snext = s->next;

      if (s->owner->eclass->fixedsize || s->patchBrush || s->hiddenBrush)
			continue;

	  	if (FilterBrush (s))
			continue;

      //face_t *pFace = s->brush_faces;	// not used
      if (s->brush_faces->d_texture->bFromShader && (s->brush_faces->d_texture->nShaderFlags & QER_NOCARVE))
      {
        continue;
      }

			for (i=0 ; i<3 ; i++)
				if (b->mins[i] >= s->maxs[i] - ON_EPSILON 
				|| b->maxs[i] <= s->mins[i] + ON_EPSILON)
					break;
			if (i != 3)
				continue;	// definately don't touch

			frag = s;
			for (f = b->brush_faces ; f && frag ; f=f->next)
			{
				CSG_SplitBrushByFace (frag, f, &front, &back);
				Brush_Free (frag);
				frag = back;
				if (front)
					Brush_AddToList (front, &active_brushes);
			}
			if (frag)
				Brush_Free (frag);
		}
	}

	Sys_Printf ("done.\n");
	Sys_UpdateWindows (W_ALL);
}
Пример #8
0
void Select_PartialTall( void )
{
	brush_s*    b, *next;
	//int       i;
	edVec3_c    mins, maxs;
	
	if ( !QE_SingleBrush() )
		return;
		
	clearSelection();
	
	mins = selected_brushes.next->getMins();
	maxs = selected_brushes.next->getMaxs();
	Select_Delete();
	
	int nDim1 = ( g_pParentWnd->ActiveXY()->GetViewType() == YZ ) ? 1 : 0;
	int nDim2 = ( g_pParentWnd->ActiveXY()->GetViewType() == XY ) ? 1 : 2;
	
	for ( b = active_brushes.next ; b != &active_brushes ; b = next )
	{
		next = b->next;
		
		if ( ( b->getMins()[nDim1] > maxs[nDim1] || b->getMaxs()[nDim1] < mins[nDim1] )
				|| ( b->getMins()[nDim2] > maxs[nDim2] || b->getMaxs()[nDim2] < mins[nDim2] ) )
			continue;
			
		if ( FilterBrush( b ) )
			continue;
			
		Brush_RemoveFromList( b );
		Brush_AddToList( b, &selected_brushes );
		
		
#if 0
		// old stuff
		for ( i = 0 ; i < 2 ; i++ )
			if ( b->mins[i] > maxs[i] || b->maxs[i] < mins[i] )
				break;
		if ( i == 2 )
		{
			Brush_RemoveFromList( b );
			Brush_AddToList( b, &selected_brushes );
		}
#endif
	}
	Sys_UpdateWindows( W_ALL );
}
Пример #9
0
void Select_CompleteTall (void)
{
	brush_t	*b, *next;
	//int		i;
	vec3_t	mins, maxs;

	if (!QE_SingleBrush ())
		return;

	g_qeglobals.d_select_mode = sel_brush;

	VectorCopy (selected_brushes.next->mins, mins);
	VectorCopy (selected_brushes.next->maxs, maxs);
	Select_Delete ();

  int nDim1 = (g_pParentWnd->ActiveXY()->GetViewType() == YZ) ? 1 : 0;
  int nDim2 = (g_pParentWnd->ActiveXY()->GetViewType() == XY) ? 1 : 2;

	for (b=active_brushes.next ; b != &active_brushes ; b=next)
	{
		next = b->next;

    if ( (b->maxs[nDim1] > maxs[nDim1] || b->mins[nDim1] < mins[nDim1]) 
      || (b->maxs[nDim2] > maxs[nDim2] || b->mins[nDim2] < mins[nDim2]) )
      continue;

	 	if (FilterBrush (b))
	 		continue;

		Brush_RemoveFromList (b);
		Brush_AddToList (b, &selected_brushes);
#if 0
    // old stuff
    for (i=0 ; i<2 ; i++)
			if (b->maxs[i] > maxs[i] || b->mins[i] < mins[i])
				break;
		if (i == 2)
		{
			Brush_RemoveFromList (b);
			Brush_AddToList (b, &selected_brushes);
		}
#endif
	}
	Sys_UpdateWindows (W_ALL);
}
Пример #10
0
/*
==============
XY_Draw
==============
*/
void XY_Draw (void)
{
    brush_t	*brush;
	float	w, h;
	entity_t	*e;
	double	start, end;
	vec3_t	mins, maxs;
	int		drawn, culled;
	int		i;

	if (!active_brushes.next)
		return;	// not valid yet

	if (g_qeglobals.d_xy.timing)
		start = Sys_DoubleTime ();

	//
	// clear
	//
	g_qeglobals.d_xy.d_dirty = false;

	glViewport(0, 0, g_qeglobals.d_xy.width, g_qeglobals.d_xy.height);
	glClearColor (
		g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][0],
		g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][1],
		g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][2],
		0);

    glClear(GL_COLOR_BUFFER_BIT);

	//
	// set up viewpoint
	//
	glMatrixMode(GL_PROJECTION);
    glLoadIdentity ();

	w = g_qeglobals.d_xy.width/2 / g_qeglobals.d_xy.scale;
	h = g_qeglobals.d_xy.height/2 / g_qeglobals.d_xy.scale;
	mins[0] = g_qeglobals.d_xy.origin[0] - w;
	maxs[0] = g_qeglobals.d_xy.origin[0] + w;
	mins[1] = g_qeglobals.d_xy.origin[1] - h;
	maxs[1] = g_qeglobals.d_xy.origin[1] + h;

	glOrtho (mins[0], maxs[0], mins[1], maxs[1], -8000, 8000);

	//
	// now draw the grid
	//
	XY_DrawGrid ();

	//
	// draw stuff
	//
    glShadeModel (GL_FLAT);
	glDisable(GL_TEXTURE_2D);
	glDisable(GL_TEXTURE_1D);
	glDisable(GL_DEPTH_TEST);
	glDisable(GL_BLEND);
	glColor3f(0, 0, 0);
//		glEnable (GL_LINE_SMOOTH);

	drawn = culled = 0;

	e = NULL;
	for (brush = active_brushes.next ; brush != &active_brushes ; brush=brush->next)
	{
		if (brush->mins[0] > maxs[0]
			|| brush->mins[1] > maxs[1]
			|| brush->maxs[0] < mins[0]
			|| brush->maxs[1] < mins[1]	)
		{
			culled++;
			continue;		// off screen
		}

		if (FilterBrush (brush))
			continue;
		drawn++;
		if (brush->owner != e)
		{
			e = brush->owner;
			glColor3fv(e->eclass->color);
		}
		Brush_DrawXY( brush );
	}

	DrawPathLines ();

	//
	// draw pointfile
	//
	if ( g_qeglobals.d_pointfile_display_list)
		glCallList (g_qeglobals.d_pointfile_display_list);

	//
	// draw block grid
	//
	if ( g_qeglobals.show_blocks)
		XY_DrawBlockGrid ();

	//
	// now draw selected brushes
	//
	glTranslatef( g_qeglobals.d_select_translate[0], g_qeglobals.d_select_translate[1], g_qeglobals.d_select_translate[2]);

	glColor3f(1.0, 0.0, 0.0);
	glEnable (GL_LINE_STIPPLE);
	glLineStipple (3, 0xaaaa);
	glLineWidth (2);

	for (brush = selected_brushes.next ; brush != &selected_brushes ; brush=brush->next)
	{
		drawn++;
		Brush_DrawXY( brush );
	}

	glDisable (GL_LINE_STIPPLE);
	glLineWidth (1);

	// edge / vertex flags

	if (g_qeglobals.d_select_mode == sel_vertex)
	{
		glPointSize (4);
		glColor3f (0,1,0);
		glBegin (GL_POINTS);
		for (i=0 ; i<g_qeglobals.d_numpoints ; i++)
			glVertex3fv (g_qeglobals.d_points[i]);
		glEnd ();
		glPointSize (1);
	}
	else if (g_qeglobals.d_select_mode == sel_edge)
	{
		float	*v1, *v2;

		glPointSize (4);
		glColor3f (0,0,1);
		glBegin (GL_POINTS);
		for (i=0 ; i<g_qeglobals.d_numedges ; i++)
		{
			v1 = g_qeglobals.d_points[g_qeglobals.d_edges[i].p1];
			v2 = g_qeglobals.d_points[g_qeglobals.d_edges[i].p2];
			glVertex3f ( (v1[0]+v2[0])*0.5,(v1[1]+v2[1])*0.5,(v1[2]+v2[2])*0.5);
		}
		glEnd ();
		glPointSize (1);
	}
	glTranslatef (-g_qeglobals.d_select_translate[0], -g_qeglobals.d_select_translate[1], -g_qeglobals.d_select_translate[2]);

	//
	// now draw camera point
	//
	DrawCameraIcon ();
	DrawZIcon ();

    glFinish();
	QE_CheckOpenGLForErrors();

	if (g_qeglobals.d_xy.timing)
	{
		end = Sys_DoubleTime ();
		Sys_Printf ("xy: %i ms\n", (int)(1000*(end-start)));
	}
}
Пример #11
0
trace_t Test_Ray( vec3_t origin, vec3_t dir, int flags )
{
	brush_s*    brush;
	face_s* face;
	float   dist;
	trace_t t;
	
	memset( &t, 0, sizeof( t ) );
	t.dist = DIST_START;
	
	if ( flags & SF_CYCLE )
	{
		CPtrArray array;
		brush_s* pToSelect = ( selected_brushes.next != &selected_brushes ) ? selected_brushes.next : NULL;
		Select_Deselect();
		
		// go through active brushes and accumulate all "hit" brushes
		for ( brush = active_brushes.next ; brush != &active_brushes ; brush = brush->next )
		{
			//if ( (flags & SF_ENTITIES_FIRST) && brush->owner == world_entity)
			//  continue;
			
			if ( FilterBrush( brush ) )
				continue;
				
			if ( !g_PrefsDlg.m_bSelectCurves && brush->patchBrush )
				continue;
				
			if ( !g_PrefsDlg.m_bSelectTerrain && brush->terrainBrush )
				continue;
				
			//if (!g_bShowPatchBounds && brush->patchBrush)
			//  continue;
			
			face = Brush_Ray( origin, dir, brush, &dist );
			
			if ( face )
			{
				array.Add( brush );
			}
		}
		
		int nSize = array.GetSize();
		if ( nSize > 0 )
		{
			bool bFound = false;
			for ( int i = 0; i < nSize; i++ )
			{
				brush_s* b = reinterpret_cast<brush_s*>( array.GetAt( i ) );
				// did we hit the last one selected yet ?
				if ( b == pToSelect )
				{
					// yes we want to select the next one in the list
					int n = ( i > 0 ) ? i - 1 : nSize - 1;
					pToSelect = reinterpret_cast<brush_s*>( array.GetAt( n ) );
					bFound = true;
					break;
				}
			}
			if ( !bFound )
				pToSelect = reinterpret_cast<brush_s*>( array.GetAt( 0 ) );
		}
		if ( pToSelect )
		{
			face = Brush_Ray( origin, dir, pToSelect, &dist );
			
			t.dist = dist;
			t.brush = pToSelect;
			t.face = face;
			t.selected = false;
			return t;
		}
	}
	
	if ( !( flags & SF_SELECTED_ONLY ) )
	{
		for ( brush = active_brushes.next ; brush != &active_brushes ; brush = brush->next )
		{
			if ( ( flags & SF_ENTITIES_FIRST ) && brush->owner == world_entity )
				continue;
				
			if ( FilterBrush( brush ) )
				continue;
				
			if ( !g_PrefsDlg.m_bSelectCurves && brush->patchBrush )
				continue;
				
			if ( !g_PrefsDlg.m_bSelectTerrain && brush->terrainBrush )
				continue;
				
			//if (!g_bShowPatchBounds && brush->patchBrush)
			//  continue;
			
			face = Brush_Ray( origin, dir, brush, &dist );
			if ( dist > 0 && dist < t.dist )
			{
				t.dist = dist;
				t.brush = brush;
				t.face = face;
				t.selected = false;
			}
		}
	}
	
	
	for ( brush = selected_brushes.next ; brush != 0 && brush != &selected_brushes ; brush = brush->next )
	{
		if ( ( flags & SF_ENTITIES_FIRST ) && brush->owner == world_entity )
			continue;
			
		if ( FilterBrush( brush ) )
			continue;
			
		if ( !g_PrefsDlg.m_bSelectCurves && brush->patchBrush )
			continue;
			
		if ( !g_PrefsDlg.m_bSelectTerrain && brush->terrainBrush )
			continue;
			
		face = Brush_Ray( origin, dir, brush, &dist );
		if ( dist > 0 && dist < t.dist )
		{
			t.dist = dist;
			t.brush = brush;
			t.face = face;
			t.selected = true;
		}
	}
	
	// if entites first, but didn't find any, check regular
	
	if ( ( flags & SF_ENTITIES_FIRST ) && t.brush == NULL )
		return Test_Ray( origin, dir, flags - SF_ENTITIES_FIRST );
		
	return t;
	
}
Пример #12
0
void Select_AllOfType()
{
	brush_s*    b, *next;
	entity_s*   e;
	if ( ( selected_brushes.next == &selected_brushes )
			|| ( selected_brushes.next->next != &selected_brushes ) )
	{
	
		CString strName;
		if ( g_ptrSelectedFaces.GetSize() == 0 )
		{
			strName = g_qeglobals.d_texturewin.texdef.name;
		}
		else
		{
			face_s* selFace = reinterpret_cast<face_s*>( g_ptrSelectedFaces.GetAt( 0 ) );
			strName = selFace->texdef.name;
		}
		
		Select_Deselect();
		for ( b = active_brushes.next ; b != &active_brushes ; b = next )
		{
			next = b->next;
			
			if ( FilterBrush( b ) )
				continue;
				
			if ( b->patchBrush )
			{
				if ( strcmpi( strName, b->pPatch->d_texture->name ) == 0 )
				{
					Brush_RemoveFromList( b );
					Brush_AddToList( b, &selected_brushes );
				}
			}
			else
			{
				for ( face_s* pFace = b->brush_faces; pFace; pFace = pFace->next )
				{
					if ( strcmpi( strName, pFace->texdef.name ) == 0 )
					{
						Brush_RemoveFromList( b );
						Brush_AddToList( b, &selected_brushes );
					}
				}
			}
		}
		Sys_UpdateWindows( W_ALL );
		return;
	}
	
	
	b = selected_brushes.next;
	e = b->owner;
	
	if ( e != NULL )
	{
		if ( e != world_entity )
		{
			CString strName = e->eclass->name;
			CString strKey, strVal;
			bool bCriteria = GetSelectAllCriteria( strKey, strVal );
			Sys_Printf( "Selecting all %s(s)\n", strName );
			Select_Deselect();
			
			for ( b = active_brushes.next ; b != &active_brushes ; b = next )
			{
				next = b->next;
				
				if ( FilterBrush( b ) )
					continue;
					
				e = b->owner;
				if ( e != NULL )
				{
					if ( strcmpi( e->eclass->name, strName ) == 0 )
					{
						bool doIt = true;
						if ( bCriteria )
						{
							CString str = ValueForKey( e, strKey );
							if ( str.CompareNoCase( strVal ) != 0 )
							{
								doIt = false;
							}
						}
						if ( doIt )
						{
							Brush_RemoveFromList( b );
							Brush_AddToList( b, &selected_brushes );
						}
					}
				}
			}
		}
	}
	Sys_UpdateWindows( W_ALL );
	
}
Пример #13
0
void Select_AutoCaulk()
{
	/*Sys_Printf*/common->Printf("Caulking...\n");

	FacesToCaulk.Clear();

	int iSystemBrushesSkipped = 0;
	face_t *pSelectedFace;

	brush_t *next;
	for (brush_t *pSelectedBrush = selected_brushes.next ; pSelectedBrush != &selected_brushes ; pSelectedBrush = next)
	{
		next = pSelectedBrush->next;

		if (pSelectedBrush->owner->eclass->fixedsize)
			continue;	// apparently this means it's a model, so skip it...

		// new check, we can't caulk a brush that has any "system/" faces...
		//
		bool bSystemFacePresent = false;
		for ( pSelectedFace = pSelectedBrush->brush_faces; pSelectedFace; pSelectedFace = pSelectedFace->next)
		{
			if (!strnicmp(pSelectedFace->d_texture->GetName(),"system/",7))
			{
				bSystemFacePresent = true;
				break;
			}
		}
		if (bSystemFacePresent)
		{
			iSystemBrushesSkipped++;
			continue;	// verboten to caulk this.
		}

		for (int iBrushListToScan = 0; iBrushListToScan<2; iBrushListToScan++)
		{
			brush_t	*snext;
			for (brush_t *pScannedBrush = (iBrushListToScan?active_brushes.next:selected_brushes.next); pScannedBrush != (iBrushListToScan?&active_brushes:&selected_brushes) ; pScannedBrush = snext)
			{
				snext = pScannedBrush->next;

				if ( pScannedBrush == pSelectedBrush)
					continue;

				if (pScannedBrush->owner->eclass->fixedsize || pScannedBrush->pPatch || pScannedBrush->hiddenBrush)
					continue;

				if (FilterBrush(pScannedBrush))
					continue;

// idMaterial stuff no longer support this, not sure what else to do.
//   Searching for other occurences of QER_NOCARVE just shows people REMing the code and ignoring ths issue...
//
//				if (pScannedBrush->brush_faces->d_texture->bFromShader && (pScannedBrush->brush_faces->d_texture->TestMaterialFlag(QER_NOCARVE)))
//					continue;

				// basic-reject first to see if brushes can even possibly touch (coplanar counts as touching)
				//
				int i;
				for (i=0 ; i<3 ; i++)
				{
					if (pSelectedBrush->mins[i] > pScannedBrush->maxs[i] ||
						pSelectedBrush->maxs[i] < pScannedBrush->mins[i])
					{
						break;
					}
				}
				if (i != 3)
					continue;	// can't be touching

				// ok, now for the clever stuff, we need to detect only those faces that are both coplanar and smaller
				//	or equal to the face they're coplanar with...
				//
				for (pSelectedFace = pSelectedBrush->brush_faces; pSelectedFace; pSelectedFace = pSelectedFace->next)
				{
					idWinding *pSelectedWinding = pSelectedFace->face_winding;

					if (!pSelectedWinding)
						continue;	// freed face, probably won't happen here, but who knows with this program?

	//				SquaredFace_t SelectedSquaredFace;
	//				WindingToSquaredFace( &SelectedSquaredFace, pSelectedWinding);

					for (face_t *pScannedFace = pScannedBrush->brush_faces; pScannedFace; pScannedFace = pScannedFace->next)
					{
						// don't even try caulking against a system face, because these are often transparent and will leave holes
						//
						if (!strnicmp(pScannedFace->d_texture->GetName(),"system/",7))
							continue;

						// and don't try caulking against something inherently transparent...
						//
						if (pScannedFace->d_texture->TestMaterialFlag(QER_TRANS))
							continue;

						idWinding *pScannedWinding = pScannedFace->face_winding;

						if (!pScannedWinding)
							continue;	// freed face, probably won't happen here, but who knows with this program?

	//					SquaredFace_t ScannedSquaredFace;
	//					WindingToSquaredFace( &ScannedSquaredFace, pScannedWinding);

	/*					if (VectorCompare(ScannedSquaredFace.v3NormalisedRotationVector, SelectedSquaredFace.v3NormalisedRotationVector)
							&&
							VectorCompare(ScannedSquaredFace.v3NormalisedElevationVector, SelectedSquaredFace.v3NormalisedElevationVector)
							)
	*/
						{
							// brush faces are in parallel planes to each other, so check that their normals
							//	are opposite, by adding them together and testing for zero...
							// (if normals are opposite, then faces can be against/touching each other?)
							//
							idVec3 v3ZeroTest;
							idVec3 v3Zero;v3Zero.Zero();	//static idVec3 v3Zero={0,0,0};

							VectorAdd(pSelectedFace->plane.Normal(),pScannedFace->plane.Normal(),v3ZeroTest);
							if (v3ZeroTest == v3Zero)
							{
								// planes are facing each other...
								//
								// coplanar? (this is some maths of Gil's, which I don't even pretend to understand)
								//
								float fTotalDist = 0;
								for (int _i=0; _i<3; _i++)
								{
									fTotalDist += fabs(	DotProduct(pSelectedFace->plane.Normal(),(*pSelectedWinding)[0])
														-
														DotProduct(pSelectedFace->plane.Normal(),(*pScannedWinding)[i])
														);
								}
								//OutputDebugString(va("Dist = %g\n",fTotalDist));

								if (fTotalDist > 0.01)
									continue;

								// every point in the selected face must be within (or equal to) the bounds of the
								//	scanned face...
								//
								// work out the bounds first...
								//
								idVec3 v3ScannedBoundsMins, v3ScannedBoundsMaxs;
								ClearBounds (v3ScannedBoundsMins, v3ScannedBoundsMaxs);
								int iPoint;
								for (iPoint=0; iPoint<pScannedWinding->GetNumPoints(); iPoint++)
								{
									AddPointToBounds( (*pScannedWinding)[iPoint].ToVec3(), v3ScannedBoundsMins, v3ScannedBoundsMaxs);
								}
								// floor 'em... (or .001 differences mess things up...
								//
								FloorBounds(v3ScannedBoundsMins, v3ScannedBoundsMaxs);


								// now check points from selected face...
								//
								bool bWithin = true;
								for (iPoint=0; iPoint < pSelectedWinding->GetNumPoints(); iPoint++)
								{
									for (int iXYZ=0; iXYZ<3; iXYZ++)
									{
										float f = floor((*pSelectedWinding)[iPoint][iXYZ] + 0.5);
										if (!
												(
												f >= v3ScannedBoundsMins[iXYZ]
												&&
												f <= v3ScannedBoundsMaxs[iXYZ]
												)
											 )
										{
											bWithin = false;
										}
									}
								}

								if (bWithin)
								{
									PairBrushFace_t PairBrushFace;
													PairBrushFace.pFace = pSelectedFace;
													PairBrushFace.pBrush= pSelectedBrush;
									FacesToCaulk.Append(PairBrushFace);
								}
							}
						}
					}
				}
			}
		}
	}


	// apply caulk...
	//
	int iFacesCaulked = 0;
	if (FacesToCaulk.Num())
	{
		LPCSTR psCaulkName = "textures/common/caulk";
		const idMaterial *pCaulk = Texture_ForName(psCaulkName);

		if (pCaulk)
		{
			//
			// and call some other junk that Radiant wants so so we can use it later...
			//
			texdef_t tex;
			memset (&tex, 0, sizeof(tex));
			tex.scale[0] = 1;
			tex.scale[1] = 1;
			//tex.flags = pCaulk->flags;	// field missing in Q4
			//tex.value = pCaulk->value;	// ditto
			//tex.contents = pCaulk->contents;	// ditto
			tex.SetName( pCaulk->GetName() );

			//Texture_SetTexture (&tex);

			for (int iListEntry = 0; iListEntry < FacesToCaulk.Num(); iListEntry++)
			{
				PairBrushFace_t &PairBrushFace = FacesToCaulk[iListEntry];
				face_t *pFace = PairBrushFace.pFace;
				brush_t*pBrush= PairBrushFace.pBrush;

				pFace->d_texture = pCaulk;
				pFace->texdef = tex;

				Face_FitTexture(pFace, 1, 1);	// this doesn't work here for some reason... duh.
				Brush_Build(pBrush);

				iFacesCaulked++;
			}
		}
		else
		{
			/*Sys_Printf*/common->Printf(" Unable to locate caulk texture at: \"%s\"!\n",psCaulkName);
		}
	}

	/*Sys_Printf*/common->Printf("( %d faces caulked )\n",iFacesCaulked);

	if (iSystemBrushesSkipped)
	{
		/*Sys_Printf*/common->Printf("( %d system-faced brushes skipped )\n",iSystemBrushesSkipped);
	}

	Sys_UpdateWindows (W_ALL);
}
Пример #14
0
void CCamWnd::Cam_Draw()
{
	brush_t	*brush;
	face_t	*face;
	float	screenaspect;
	float	yfov;
	double	start, end;
	int		i;

	/*
  FILE *f = fopen("g:/nardo/raduffy/editorhack.dat", "w");
  if (f != NULL) {
    fwrite(&m_Camera.origin[0], sizeof(float), 1, f);
    fwrite(&m_Camera.origin[1], sizeof(float), 1, f);
    fwrite(&m_Camera.origin[2], sizeof(float), 1, f);
		fwrite(&m_Camera.angles[PITCH], sizeof(float), 1, f);
		fwrite(&m_Camera.angles[YAW], sizeof(float), 1, f);
    fclose(f);
  }
	*/
	
	if (!active_brushes.next)
		return;	// not valid yet
	
	if (m_Camera.timing)
		start = Sys_DoubleTime ();
	
	//
	// clear
	//
	QE_CheckOpenGLForErrors();
	
	qglViewport(0, 0, m_Camera.width, m_Camera.height);
	qglScissor(0, 0, m_Camera.width, m_Camera.height);
	qglClearColor (g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][0],
		g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][1],
		g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][2], 0);
	qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	
	//
	// set up viewpoint
	//
	vec5_t lightPos;
	
	if (g_PrefsDlg.m_bGLLighting)
	{
		qglEnable(GL_LIGHTING);
		//qglEnable(GL_LIGHT0);
		
		lightPos[0] = lightPos[1] = lightPos[2] = 3.5;
		lightPos[3] = 1.0;
		qglLightModelfv(GL_LIGHT_MODEL_AMBIENT, lightPos);
		//qglLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
		//lightPos[0] = lightPos[1] = lightPos[2] = 3.5;
    //qglLightfv(GL_LIGHT0, GL_AMBIENT, lightPos);
	}
	else
	{
		qglDisable(GL_LIGHTING);
	}
	
	qglMatrixMode(GL_PROJECTION);
	qglLoadIdentity ();
	
	screenaspect = (float)m_Camera.width / m_Camera.height;
	yfov = 2*atan((float)m_Camera.height / m_Camera.width)*180/Q_PI;
	qgluPerspective (yfov,  screenaspect,  2,  8192);
	
	qglRotatef (-90,  1, 0, 0);	    // put Z going up
	qglRotatef (90,  0, 0, 1);	    // put Z going up
	qglRotatef (m_Camera.angles[0],  0, 1, 0);
	qglRotatef (-m_Camera.angles[1],  0, 0, 1);
	qglTranslatef (-m_Camera.origin[0],  -m_Camera.origin[1],  -m_Camera.origin[2]);
	
	Cam_BuildMatrix ();
	
	
	//if (m_Camera.draw_mode == cd_light)
	//{
//	if (g_PrefsDlg.m_bGLLighting)
//	{
//		VectorCopy(m_Camera.origin, lightPos);
//		lightPos[3] = 1;
//		qglLightfv(GL_LIGHT0, GL_POSITION, lightPos);
//	}
	//}
	
	InitCull ();
	
	//
	// draw stuff
	//
	GLfloat lAmbient[] = {1.0, 1.0, 1.0, 1.0};
	
	switch (m_Camera.draw_mode)
	{
	case cd_wire:
		qglPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
		qglDisable(GL_TEXTURE_2D);
		qglDisable(GL_TEXTURE_1D);
		qglDisable(GL_BLEND);
		qglDisable(GL_DEPTH_TEST);
		qglColor3f(1.0, 1.0, 1.0);
		//		qglEnable (GL_LINE_SMOOTH);
		break;
		
	case cd_solid:
		qglCullFace(GL_FRONT);
		qglEnable(GL_CULL_FACE);
		qglShadeModel (GL_FLAT);
		qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
		qglDisable(GL_TEXTURE_2D);
		qglDisable(GL_BLEND);
		qglEnable(GL_DEPTH_TEST);
		qglDepthFunc (GL_LEQUAL);
		break;
		
	case cd_texture:
		qglCullFace(GL_FRONT);
		qglEnable(GL_CULL_FACE);
		qglShadeModel (GL_FLAT);
		qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
		qglEnable(GL_TEXTURE_2D);
		qglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
		qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
		qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
		qglDisable(GL_BLEND);
		qglEnable(GL_DEPTH_TEST);
		qglDepthFunc (GL_LEQUAL);
		break;
		
	case cd_blend:
		qglCullFace(GL_FRONT);
		qglEnable(GL_CULL_FACE);
		qglShadeModel (GL_FLAT);
		qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
		qglEnable(GL_TEXTURE_2D);
		qglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
		qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
		qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
		qglDisable(GL_DEPTH_TEST);
		qglEnable (GL_BLEND);
		qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		break;
	}
	
	qglMatrixMode(GL_TEXTURE);
	
	m_nNumTransBrushes = 0;
	
	for (brush = active_brushes.next ; brush != &active_brushes ; brush=brush->next)
	{
		//DrawLightRadius(brush);
		
		if (CullBrush (brush))
			continue;
		
		if (FilterBrush (brush))
			continue;
		
		if ((brush->brush_faces->texdef.flags & (SURF_TRANS33 | SURF_TRANS66)) || (brush->brush_faces->d_texture->bFromShader && brush->brush_faces->d_texture->fTrans != 1.0))
		{
			m_TransBrushes [ m_nNumTransBrushes++ ] = brush;
		} 
		else 
		{
			//--      if (brush->patchBrush)
			//--			  m_TransBrushes [ m_nNumTransBrushes++ ] = brush;
			//--      else
			Brush_Draw(brush);
		}
		
		
	}
	
	if (g_PrefsDlg.m_bGLLighting)
	{
		qglDisable (GL_LIGHTING);
	}
	
	//
	//qglDepthMask ( 0 ); // Don't write to depth buffer
	qglEnable ( GL_BLEND );
	qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	for ( i = 0; i < m_nNumTransBrushes; i++ ) 
		Brush_Draw (m_TransBrushes[i]);
	
	//qglDepthMask ( 1 ); // Ok, write now
	
	qglMatrixMode(GL_PROJECTION);
	
	//
	// now draw selected brushes
	//
	
	if (g_PrefsDlg.m_bGLLighting)
	{
		qglEnable (GL_LIGHTING);
	}
	
	qglTranslatef (g_qeglobals.d_select_translate[0], g_qeglobals.d_select_translate[1], g_qeglobals.d_select_translate[2]);
	qglMatrixMode(GL_TEXTURE);
	
	brush_t* pList = (g_bClipMode && g_pSplitList) ? g_pSplitList : &selected_brushes;
	// draw normally
	for (brush = pList->next ; brush != pList ; brush=brush->next)
	{
		//DrawLightRadius(brush);
		//if (brush->patchBrush && g_qeglobals.d_select_mode == sel_curvepoint)
		//  continue;
		
		Brush_Draw(brush);
	}
	
	// blend on top
	qglMatrixMode(GL_PROJECTION);
	
	
	qglDisable (GL_LIGHTING);
	qglColor4f(1.0, 0.0, 0.0, 0.3);
	qglEnable (GL_BLEND);
	qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
	qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	qglDisable (GL_TEXTURE_2D);
	for (brush = pList->next ; brush != pList ; brush=brush->next)
	{
		if ( (brush->patchBrush && g_qeglobals.d_select_mode == sel_curvepoint) || 
			(brush->terrainBrush && g_qeglobals.d_select_mode == sel_terrainpoint) )
			continue;
		
		for (face=brush->brush_faces ; face ; face=face->next)
			Face_Draw( face );
	}
	
 
  int nCount = g_ptrSelectedFaces.GetSize();
	if (nCount > 0)
  {
    for (int i = 0; i < nCount; i++)
    {
      face_t *selFace = reinterpret_cast<face_t*>(g_ptrSelectedFaces.GetAt(i));
		  Face_Draw(selFace);
    }
  }
		
	// non-zbuffered outline
	
	qglDisable (GL_BLEND);
	qglDisable (GL_DEPTH_TEST);
	qglPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
	qglColor3f (1, 1, 1);
	for (brush = pList->next ; brush != pList ; brush=brush->next)
	{
		if (g_qeglobals.dontDrawSelectedOutlines || (brush->patchBrush && g_qeglobals.d_select_mode == sel_curvepoint) ||
			(brush->terrainBrush && g_qeglobals.d_select_mode == sel_terrainpoint))
			continue;
		
		for (face=brush->brush_faces ; face ; face=face->next)
			Face_Draw( face );
	}
	
	
	// edge / vertex flags
	
	if (g_qeglobals.d_select_mode == sel_vertex)
	{
		qglPointSize (4);
		qglColor3f (0,1,0);
		qglBegin (GL_POINTS);
		for (i=0 ; i<g_qeglobals.d_numpoints ; i++)
			qglVertex3fv (g_qeglobals.d_points[i]);
		qglEnd ();
		qglPointSize (1);
	}
	else if (g_qeglobals.d_select_mode == sel_edge)
	{
		float	*v1, *v2;
		
		qglPointSize (4);
		qglColor3f (0,0,1);
		qglBegin (GL_POINTS);
		for (i=0 ; i<g_qeglobals.d_numedges ; i++)
		{
			v1 = g_qeglobals.d_points[g_qeglobals.d_edges[i].p1];
			v2 = g_qeglobals.d_points[g_qeglobals.d_edges[i].p2];
			qglVertex3f ( (v1[0]+v2[0])*0.5,(v1[1]+v2[1])*0.5,(v1[2]+v2[2])*0.5);
		}
		qglEnd ();
		qglPointSize (1);
	}
	
	
	g_splineList->draw(static_cast<qboolean>(g_qeglobals.d_select_mode == sel_addpoint || g_qeglobals.d_select_mode == sel_editpoint));
	if (g_qeglobals.selectObject && (g_qeglobals.d_select_mode == sel_addpoint || g_qeglobals.d_select_mode == sel_editpoint)) {
		g_qeglobals.selectObject->drawSelection();
	}

	//
	// draw pointfile
	//

	qglEnable(GL_DEPTH_TEST);
	

	DrawPathLines ();
	
	
	
	if (g_qeglobals.d_pointfile_display_list)
	{
		Pointfile_Draw();
		//		glCallList (g_qeglobals.d_pointfile_display_list);
	}
	
	// bind back to the default texture so that we don't have problems
	// elsewhere using/modifying texture maps between contexts
	qglBindTexture( GL_TEXTURE_2D, 0 );
	
#if 0
	// area selection hack
	if (g_qeglobals.d_select_mode == sel_area)
	{
		qglEnable (GL_BLEND);
		qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		qglColor4f(0.0, 0.0, 1.0, 0.25);
		qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
		qglRectfv(g_qeglobals.d_vAreaTL, g_qeglobals.d_vAreaBR);
		qglDisable (GL_BLEND);
	}
#endif
	
	qglFinish();
	QE_CheckOpenGLForErrors();
	//	Sys_EndWait();
	if (m_Camera.timing)
	{
		end = Sys_DoubleTime ();
		Sys_Printf ("Camera: %i ms\n", (int)(1000*(end-start)));
	}
}