Example #1
0
void Select_Delete( void )
{
	brush_s*    brush;
	
	g_ptrSelectedFaces.RemoveAll();
	g_ptrSelectedFaceBrushes.RemoveAll();
	//selected_face = NULL;
	
	clearSelection();
	
	g_qeglobals.d_select_count = 0;
	g_qeglobals.d_num_move_points = 0;
	while ( selected_brushes.next != &selected_brushes )
	{
		brush = selected_brushes.next;
		if ( brush->patchBrush )
		{
			//Patch_Delete(brush->nPatchID);
			Patch_Delete( brush->pPatch );
		}
		
		Brush_Free( brush );
	}
	
	// FIXME: remove any entities with no brushes
	
	Sys_UpdateWindows( W_ALL );
}
void CPlugInManager::DeleteBrushHandle(void * vp)
{
  CPtrArray* pHandles[3];
  pHandles[0] = &m_SelectedBrushHandles;
  pHandles[1] = &m_ActiveBrushHandles;
  pHandles[2] = &m_BrushHandles;

  for (int j = 0; j < 3; j++)
  {
    for (int i = 0; i < pHandles[j]->GetSize(); i++)
    {
      brush_t *pb = reinterpret_cast<brush_t*>(pHandles[j]->GetAt(i));
      if (pb == reinterpret_cast<brush_t*>(vp))
      {
        if (j == 2)
        {
          // only remove it from the list if it is work area
          // this allows the selected and active list indexes to remain constant
          // throughout a session (i.e. between an allocate and release)
          pHandles[j]->RemoveAt(i);
        }
        Brush_Free(pb);
		Sys_MarkMapModified();		// PGM
        return;
      }
    }
  }
}
Example #3
0
/*
=============
Undo_FreeFirstUndo
=============
*/
void Undo_FreeFirstUndo(void)
{
	undo_t *undo;
	brush_t *pBrush, *pNextBrush;
	entity_t *pEntity, *pNextEntity;

	//remove the oldest undo from the undo buffer
	undo = g_undolist;
	g_undolist = g_undolist->next;
	g_undolist->prev = NULL;
	//
	for (pBrush = undo->brushlist.next ; pBrush != NULL && pBrush != &undo->brushlist ; pBrush = pNextBrush)
	{
		pNextBrush = pBrush->next;
		g_undoMemorySize -= Brush_MemorySize(pBrush);
		Brush_Free(pBrush);
	}
	for (pEntity = undo->entitylist.next; pEntity != NULL && pEntity != &undo->entitylist; pEntity = pNextEntity)
	{
		pNextEntity = pEntity->next;
		g_undoMemorySize -= Entity_MemorySize(pEntity);
		Entity_Free(pEntity);
	}
	g_undoMemorySize -= sizeof(undo_t);
	free(undo);
	g_undoSize--;
}
Example #4
0
/*
=============
Undo_ClearRedo
=============
*/
void Undo_ClearRedo(void)
{
	undo_t *redo, *nextredo;
	brush_t *pBrush, *pNextBrush;
	entity_t *pEntity, *pNextEntity;

	for (redo = g_redolist; redo; redo = nextredo)
	{
		nextredo = redo->next;
		for (pBrush = redo->brushlist.next ; pBrush != NULL && pBrush != &redo->brushlist ; pBrush = pNextBrush)
		{
			pNextBrush = pBrush->next;
			Brush_Free(pBrush);
		}
		for (pEntity = redo->entitylist.next; pEntity != NULL && pEntity != &redo->entitylist; pEntity = pNextEntity)
		{
			pNextEntity = pEntity->next;
			Entity_Free(pEntity);
		}
		Mem_Free(redo);
	}
	g_redolist = NULL;
	g_lastredo = NULL;
	g_redoId = 1;
}
Example #5
0
/*
=============
Undo_Clear

  Clears the undo buffer.
=============
*/
void Undo_Clear(void)
{
	undo_t *undo, *nextundo;
	brush_t *pBrush, *pNextBrush;
	entity_t *pEntity, *pNextEntity;

	Undo_ClearRedo();
	for (undo = g_undolist; undo; undo = nextundo)
	{
		nextundo = undo->next;
		for (pBrush = undo->brushlist.next ; pBrush != NULL && pBrush != &undo->brushlist ; pBrush = pNextBrush)
		{
			pNextBrush = pBrush->next;
			g_undoMemorySize -= Brush_MemorySize(pBrush);
			Brush_Free(pBrush);
		}
		for (pEntity = undo->entitylist.next; pEntity != NULL && pEntity != &undo->entitylist; pEntity = pNextEntity)
		{
			pNextEntity = pEntity->next;
			g_undoMemorySize -= Entity_MemorySize(pEntity);
			Entity_Free(pEntity);
		}
		g_undoMemorySize -= sizeof(undo_t);
		Mem_Free(undo);
	}
	g_undolist = NULL;
	g_lastundo = NULL;
	g_undoSize = 0;
	g_undoMemorySize = 0;
	g_undoId = 1;
}
/*
 =======================================================================================================================
 =======================================================================================================================
 */
void RemoveRegionBrushes( void ) {
	int i;
	if( !region_active ) {
		return;
	}
	for( i = 0; i < 6; i++ ) {
		Brush_Free( region_sides[i] );
	}
}
Example #7
0
void RemoveRegionBrushes (void)
{
	int		i;

	if (!region_active)
		return;
	for (i=0 ; i<4 ; i++)
		Brush_Free (region_sides[i]);
}
Example #8
0
/*
================
Map_Free
================
*/
void Map_Free (void)
{
  g_bRestoreBetween = false;
	if (selected_brushes.next &&
		(selected_brushes.next != &selected_brushes) )
	{
    if (MessageBox(g_qeglobals.d_hwndMain, "Copy selection?", "", MB_YESNO) == IDYES)
		  Map_SaveBetween ();
	}

	Texture_ClearInuse ();
	Pointfile_Clear ();
	strcpy (currentmap, "unnamed.map");
	Sys_SetTitle (currentmap);
	g_qeglobals.d_num_entities = 0;
	g_qeglobals.d_numterrapoints = 0;

	if (!active_brushes.next)
	{	// first map
		active_brushes.prev = active_brushes.next = &active_brushes;
		selected_brushes.prev = selected_brushes.next = &selected_brushes;
		filtered_brushes.prev = filtered_brushes.next = &filtered_brushes;

		entities.prev = entities.next = &entities;
	}
	else
	{
		while (active_brushes.next != &active_brushes)
			Brush_Free (active_brushes.next);
		while (selected_brushes.next != &selected_brushes)
			Brush_Free (selected_brushes.next);
		while (filtered_brushes.next != &filtered_brushes)
			Brush_Free (filtered_brushes.next);

		while (entities.next != &entities)
			Entity_Free (entities.next);
	}

  if (world_entity)
    Entity_Free(world_entity);
	world_entity = NULL;
}
Example #9
0
void RemoveRegionBrushes( void ){
	int i;

	if ( !region_active ) {
		return;
	}
	for ( i = 0 ; i < 6 ; i++ )
		Brush_Free( region_sides[i] );

	CleanFilter( region_startpoint );
	Entity_Free( region_startpoint );
}
Example #10
0
/*
   ================
   Map_Free
   free all map elements, reinitialize the structures that depend on them
   ================
 */
void Map_Free( void ){
	g_bRestoreBetween = false;
	if ( selected_brushes.next &&
		 ( selected_brushes.next != &selected_brushes ) ) {
		if ( gtk_MessageBox( g_pParentWnd->m_pWidget, "Copy selection?", " ", MB_YESNO ) == IDYES ) {
			Map_SaveBetween();
		}
	}

	QERApp_ActiveShaders_SetInUse( false );
	Pointfile_Clear();
	g_qeglobals.d_num_entities = 0;

	if ( !active_brushes.next ) {
		// first map
		active_brushes.prev = active_brushes.next = &active_brushes;
		selected_brushes.prev = selected_brushes.next = &selected_brushes;
		filtered_brushes.prev = filtered_brushes.next = &filtered_brushes;
		entities.prev = entities.next = &entities;
	}
	else
	{
		// free selected faces array
		g_ptrSelectedFaces.RemoveAll();
		g_ptrSelectedFaceBrushes.RemoveAll();
		while ( active_brushes.next != &active_brushes )
			Brush_Free( active_brushes.next );
		while ( selected_brushes.next != &selected_brushes )
			Brush_Free( selected_brushes.next );
		while ( filtered_brushes.next != &filtered_brushes )
			Brush_Free( filtered_brushes.next );
		while ( entities.next != &entities )
			Entity_Free( entities.next );
	}

	if ( world_entity ) {
		Entity_Free( world_entity );
	}
	world_entity = NULL;
}
/*
 =======================================================================================================================
    Map_Free
 =======================================================================================================================
 */
void Map_Free( void ) {
	g_bRestoreBetween = false;
	if( selected_brushes.next && ( selected_brushes.next != &selected_brushes ) ) {
		if( g_pParentWnd->MessageBox( "Copy selection?", "", MB_YESNO ) == IDYES ) {
			Map_SaveBetween();
		}
	}
	// clear all the render and sound system data
	g_qeglobals.rw->InitFromMap( NULL );
	g_qeglobals.sw->ClearAllSoundEmitters();
	Texture_ClearInuse();
	Pointfile_Clear();
	strcpy( currentmap, "unnamed.map" );
	Sys_SetTitle( currentmap );
	g_qeglobals.d_num_entities = 0;
	if( !active_brushes.next ) { // first map
		active_brushes.prev = active_brushes.next = &active_brushes;
		selected_brushes.prev = selected_brushes.next = &selected_brushes;
		filtered_brushes.prev = filtered_brushes.next = &filtered_brushes;
		entities.prev = entities.next = &entities;
	} else {
		while( active_brushes.next != &active_brushes ) {
			Brush_Free( active_brushes.next, false );
		}
		while( selected_brushes.next != &selected_brushes ) {
			Brush_Free( selected_brushes.next, false );
		}
		while( filtered_brushes.next != &filtered_brushes ) {
			Brush_Free( filtered_brushes.next, false );
		}
		while( entities.next != &entities ) {
			Entity_Free( entities.next );
		}
	}
	if( world_entity ) {
		Entity_Free( world_entity );
	}
	world_entity = NULL;
}
Example #12
0
/*
=============
Brush_Subtract

 Returns a list of brushes that remain after B is subtracted from A.
 May by empty if A is contained inside B.
 The originals are undisturbed.
=============
*/
brush_t *Brush_Subtract(brush_t *a, brush_t *b)
{
	// a - b = out (list)
	brush_t *front, *back;
	brush_t *in, *out, *next;
	face_t *f;

	in = a;
	out = NULL;
	for (f = b->brush_faces; f && in; f = f->next)
	{
		CSG_SplitBrushByFace(in, f, &front, &back);
		if (in != a) Brush_Free(in);
		if (front)
		{	// add to list
			front->next = out;
			out = front;
		}
		in = back;
	}
	//NOTE: in != a just in case brush b has no faces
	if (in && in != a)
	{
		Brush_Free(in);
	}
	else
	{	//didn't really intersect
		for (b = out; b; b = next)
		{
			next = b->next;
			b->next = b->prev = NULL;
			Brush_Free(b);
		}
		return a;
	}
	return out;
}
Example #13
0
/*
 =======================================================================================================================
    Entity_Free Frees the entity and any brushes is has. The entity is removed from the global entities list.
 =======================================================================================================================
 */
void Entity_Free( entity_t *e ) {

	while ( e->brushes.onext != &e->brushes ) {
		Brush_Free(e->brushes.onext);
	}

	if ( e->next ) {
		e->next->prev = e->prev;
		e->prev->next = e->next;
	}

	Entity_FreeEpairs( e );

	delete e;
}
void WINAPI QERApp_DeletePatch(int index)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());
	patchMesh_t *pPatch = g_pParentWnd->GetPlugInMgr().FindPatchHandle(index);
	if (pPatch)
	{
		brush_t *pb = pPatch->pSymbiot;
		Patch_Delete( pPatch );
		if (pb)
			Brush_Free( pb );
	}
#ifdef _DEBUG
	Sys_Printf("Warning: QERApp_DeletePatch: FindPatchHandle failed\n");
#endif
}
/*
 =======================================================================================================================
 =======================================================================================================================
 */
void Map_BuildBrushData( void ) {
	brush_t *b, *next;
	if( active_brushes.next == NULL ) {
		return;
	}
	Sys_BeginWait();	// this could take a while
	int n = 0;
	for( b = active_brushes.next; b != NULL && b != &active_brushes; b = next ) {
		next = b->next;
		Brush_Build( b, true, false, false );
		if( !b->brush_faces || ( g_PrefsDlg.m_bCleanTiny && CheckForTinyBrush( b, n++, g_PrefsDlg.m_fTinySize ) ) ) {
			Brush_Free( b );
			common->Printf( "Removed degenerate brush\n" );
		}
	}
	Sys_EndWait();
}
Example #16
0
void Map_Read( IDataStream *in, CPtrArray *map ){
	entity_t *pEntity;
	char *buf;

	unsigned long len = in->GetLength();
	buf = new char[len + 1];
	in->Read( buf, len );
	buf[len] = '\0';
	StartTokenParsing( buf );
	abortcode = MAP_NOERROR;

	while ( abortcode == MAP_NOERROR )
	{
		if ( !GetToken( true ) ) { // { or NULL
			break;
		}
		pEntity = Entity_Alloc();
		pEntity->pData = new CPtrArray;
		Entity_Parse( pEntity );
		map->Add( pEntity );
	}

	delete [] buf;

	if ( abortcode != MAP_NOERROR ) {
		int num_ents, num_brushes,i,j;
		entity_t *e;
		CPtrArray *brushes;

		num_ents = map->GetSize();
		for ( i = 0; i < num_ents; i++ )
		{
			e = (entity_t*)map->GetAt( i );
			brushes = (CPtrArray*)e->pData;
			num_brushes = brushes->GetSize();
			for ( j = 0; j < num_brushes; j++ )
			{
				Brush_Free( (brush_t *)brushes->GetAt( j ), true );
			}
			brushes->RemoveAll();
			delete brushes;
			Entity_Free( e );
		}
		map->RemoveAll();
	}
}
void CPlugInManager::Cleanup()
{
	int i;
	for (i = 0; i < m_PlugIns.GetSize(); i++)
	{
		CPlugIn *plug = reinterpret_cast<CPlugIn*>(m_PlugIns.GetAt(i));
		plug->free();
		delete plug;
	}
	m_PlugIns.RemoveAll();
	
	for (i = 0; i < m_BrushHandles.GetSize(); i++)
	{
		brush_t *pb = reinterpret_cast<brush_t*>(m_BrushHandles.GetAt(i));
		Brush_Free(pb);
	}
	m_BrushHandles.RemoveAll();
	
	for (i = 0; i < m_EntityHandles.GetSize(); i++)
	{
		entity_t *pe = reinterpret_cast<entity_t*>(m_EntityHandles.GetAt(i));
		Entity_Free(pe);
	}
	m_EntityHandles.RemoveAll();
	
	// patches
	// these are linked into the map
	m_PatchesHandles.RemoveAll();
	// these patches were allocated by Radiant on plugin request
	// if the list is not empty, it means either the plugin asked for allocation and never commited them to the map
	// in which case we are supposed to delete them
	// or it commited them but never called m_pfnReleasePatchHandles, in case the patches may have already been
	// erased and we are trying a second time, therefore crashing ..
	//++timo FIXME: for now I leave a leak warning, we'd need a table to keep track of commited patches
#ifdef _DEBUG
	if (m_PluginPatches.GetSize() != 0)
		Sys_Printf("WARNING: m_PluginPatches.GetSize() != 0 in CPlugInManager::Cleanup, possible leak\n");
#endif
/*	for (i = 0; i < m_PluginPatches.GetSize(); i++)
	{
		patchMesh_t *pMesh = reinterpret_cast<patchMesh_t*>(m_PluginPatches.GetAt(i));
		if (pMesh->pSymbiot)
			delete pMesh;
	}
	m_PluginPatches.RemoveAll(); */
}
Example #18
0
/*
==============
NewBrushDrag
==============
*/
void NewBrushDrag (int x, int y)
{
	vec3_t	mins, maxs, junk;
	int		i;
	float	temp;
	brush_t	*n;

	if (!DragDelta (x,y, junk))
		return;
	// delete the current selection
	if (selected_brushes.next != &selected_brushes)
		Brush_Free (selected_brushes.next);
	XY_ToGridPoint (pressx, pressy, mins);
	mins[2] = g_qeglobals.d_gridsize * ((int)(g_qeglobals.d_new_brush_bottom_z/g_qeglobals.d_gridsize));
	XY_ToGridPoint (x, y, maxs);
	maxs[2] = g_qeglobals.d_gridsize * ((int)(g_qeglobals.d_new_brush_top_z/g_qeglobals.d_gridsize));
	if (maxs[2] <= mins[2])
		maxs[2] = mins[2] + g_qeglobals.d_gridsize;

	for (i=0 ; i<3 ; i++)
	{
		if (mins[i] == maxs[i])
			return;	// don't create a degenerate brush
		if (mins[i] > maxs[i])
		{
			temp = mins[i];
			mins[i] = maxs[i];
			maxs[i] = temp;
		}
	}

	n = Brush_Create (mins, maxs, &g_qeglobals.d_texturewin.texdef);
	if (!n)
		return;

	Brush_AddToList (n, &selected_brushes);

	Entity_LinkBrush (world_entity, n);

	Brush_Build( n );

//	Sys_UpdateWindows (W_ALL);
	Sys_UpdateWindows (W_XY| W_CAMERA);
}
Example #19
0
void Select_Delete (void)
{
	brush_t	*brush;

	selected_face = NULL;
	g_qeglobals.d_select_mode = sel_brush;

	g_qeglobals.d_select_count = 0;
	g_qeglobals.d_num_move_points = 0;
	while (selected_brushes.next != &selected_brushes)
	{
		brush = selected_brushes.next;
		Brush_Free (brush);
	}

	// FIXME: remove any entities with no brushes

	Sys_UpdateWindows (W_ALL);
}
Example #20
0
void Map_FreeEntities( CPtrArray *ents ){
	int i, j, num_ents, num_brushes;
	entity_t* e;
	CPtrArray* brushes;

	num_ents = ents->GetSize();
	for ( i = 0; i < num_ents; i++ )
	{
		e = (entity_t*)ents->GetAt( i );
		brushes = (CPtrArray*)e->pData;
		num_brushes = brushes->GetSize();
		for ( j = 0; j < num_brushes; j++ )
			Brush_Free( (brush_t*)brushes->GetAt( j ) );
		brushes->RemoveAll();
		delete (CPtrArray*)e->pData;
		e->pData = NULL;
		Entity_Free( e );
	}
	ents->RemoveAll();
}
Example #21
0
void Entity_Parse( entity_t *pEntity ){
	brush_t *pBrush;
//  CPtrArray *brushes = NULL;
	char temptoken[1024];

	char *token = Token();

	while ( 1 )
	{
		GetToken( true ); // { or } or epair
		if ( !strcmp( token, "}" ) ) {
			break;
		}
		else if ( !strcmp( token, "{" ) ) {

			pBrush = Brush_Alloc();
			if ( Primitive_Parse( pBrush ) ) {
				( (CPtrArray*)pEntity->pData )->Add( pBrush );
			}
			else {
				Brush_Free( pBrush, true );
			}

		}
		else {

			strcpy( temptoken, token );
			GetToken( false );

			SetKeyValue( pEntity, temptoken, token );

			if ( g_MapVersion == MAPVERSION_HL ) {
				// if we've not god a "wads" key/pair already, then break it into a list.
				if ( !g_WadList && ( stricmp( temptoken,"wad" ) == 0 ) ) {
					BuildWadList( token );
				}
			}

		}
	}
}
Example #22
0
/*
===============
Entity_Free

Frees the entity and any brushes is has.
The entity is removed from the global entities list.
===============
*/
void Entity_Free (entity_t *e)
{
	epair_t	*ep, *next;

	while (e->brushes.onext != &e->brushes)
		Brush_Free (e->brushes.onext);

	if (e->next)
	{
		e->next->prev = e->prev;
		e->prev->next = e->next;
	}

	for (ep = e->epairs ; ep ; ep=next)
	{
		next = ep->next;
    free (ep->key);
    free (ep->value);
		free (ep);
	}
	free (e);
}
Example #23
0
/*	Makes the current brushhave the given number of 2d sides
*/
void Brush_MakeSided(int sides)
{
	int			i;
	vec3_t		mins, maxs;
	brush_t		*b;
	texdef_t	*texdef;
	face_t		*f;
	vec3_t		mid;
	float		width,sv,cv;

	if(sides < 3)
	{
		Sys_Status ("Bad sides number", 0);
		return;
	}
	else if(!QE_SingleBrush())
	{
		Sys_Status ("Must have a single brush selected", 0 );
		return;
	}

	b = selected_brushes.next;
	Math_VectorCopy(b->mins,mins);
	Math_VectorCopy(b->maxs,maxs);
	texdef = &g_qeglobals.d_texturewin.texdef;

	Brush_Free (b);

	// find center of brush
	width = 8;
	for (i=0 ; i<2 ; i++)
	{
		mid[i] = (maxs[i] + mins[i])*0.5;
		if (maxs[i] - mins[i] > width)
			width = maxs[i] - mins[i];
	}
	width /= 2;

	b = qmalloc (sizeof(brush_t));

	// create top face
	f = Face_Alloc();
	f->texdef = *texdef;
	f->next = b->brush_faces;
	b->brush_faces = f;

	f->planepts[2][0] = mins[0];f->planepts[2][1] = mins[1];f->planepts[2][2] = maxs[2];
	f->planepts[1][0] = maxs[0];f->planepts[1][1] = mins[1];f->planepts[1][2] = maxs[2];
	f->planepts[0][0] = maxs[0];f->planepts[0][1] = maxs[1];f->planepts[0][2] = maxs[2];

	// create bottom face
	f = Face_Alloc();
	f->texdef	= *texdef;
	f->next		= b->brush_faces;

	b->brush_faces = f;

	f->planepts[0][0] = mins[0];f->planepts[0][1] = mins[1];f->planepts[0][2] = mins[2];
	f->planepts[1][0] = maxs[0];f->planepts[1][1] = mins[1];f->planepts[1][2] = mins[2];
	f->planepts[2][0] = maxs[0];f->planepts[2][1] = maxs[1];f->planepts[2][2] = mins[2];

	for (i=0 ; i<sides ; i++)
	{
		f = Face_Alloc();
		f->texdef = *texdef;
		f->next = b->brush_faces;
		b->brush_faces = f;

		sv = sin (i*3.14159265*2/sides);
		cv = cos (i*3.14159265*2/sides);

		f->planepts[0][0] = floor(mid[0]+width*cv+0.5);
		f->planepts[0][1] = floor(mid[1]+width*sv+0.5);
		f->planepts[0][2] = mins[2];

		f->planepts[1][0] = f->planepts[0][0];
		f->planepts[1][1] = f->planepts[0][1];
		f->planepts[1][2] = maxs[2];

		f->planepts[2][0] = floor(f->planepts[0][0] - width*sv + 0.5);
		f->planepts[2][1] = floor(f->planepts[0][1] + width*cv + 0.5);
		f->planepts[2][2] = maxs[2];

	}

	Brush_AddToList (b, &selected_brushes);

	Entity_LinkBrush (world_entity, b);

	Brush_Build( b );

	Sys_UpdateWindows (W_ALL);
}
Example #24
0
/*
=============
CSG_Merge
=============
*/
void CSG_Merge(void)
{
	brush_t *b, *next, *newlist, *newbrush;
	struct entity_s	*owner;

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

	if (selected_brushes.next == &selected_brushes)
	{
		Sys_Printf ("No brushes selected.\n");
		return;
	}

	if (selected_brushes.next->next == &selected_brushes)
	{
		Sys_Printf ("At least two brushes have to be selected.\n");
		return;
	}

	owner = selected_brushes.next->owner;

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

		if (b->owner->eclass->fixedsize)
		{
			// can't use texture from a fixed entity, so don't subtract
			Sys_Printf ("Cannot add fixed size entities.\n");
			return;
		}

		if (b->owner != owner)
		{
			Sys_Printf ("Cannot add brushes from different entities.\n");
			return;
		}

	}

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

		Brush_RemoveFromList(b);
		b->next = newlist;
		b->prev = NULL;
		newlist = b;
	}

	newbrush = Brush_MergeList(newlist, true);
	// if the new brush would not be convex
	if (!newbrush)
	{
		// add the brushes back into the selection
		for (b = newlist; b; b = next)
		{
			next = b->next;
			b->next = NULL;
			b->prev = NULL;
			Brush_AddToList(b, &selected_brushes);
		}
		Sys_Printf ("Cannot add a set of brushes with a concave hull.\n");
		return;
	}
	// free the original brushes
	for (b = newlist; b; b = next)
	{
		next = b->next;
		b->next = NULL;
		b->prev = NULL;
		Brush_Free(b);
	}
	Brush_AddToList(newbrush, &selected_brushes);

	Sys_Printf ("Done.\n");
	Sys_UpdateWindows (W_ALL);
}
Example #25
0
/*
=============
CSG_Subtract
=============
*/
void CSG_Subtract (void)
{
	brush_t		*b, *s, *fragments, *nextfragment, *frag, *next, *snext;
	brush_t		fragmentlist;
	int			i, numfragments, numbrushes;

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

	if (selected_brushes.next == &selected_brushes)
	{
		Sys_Printf ("No brushes selected.\n");
		return;
	}

	fragmentlist.next = &fragmentlist;
	fragmentlist.prev = &fragmentlist;

	numfragments = 0;
	numbrushes = 0;
	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

		// chop all fragments further up
		for (s = fragmentlist.next; s != &fragmentlist; s = snext)
		{
			snext = s->next;

			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
			fragments = Brush_Subtract(s, b);
			// if the brushes did not really intersect
			if (fragments == s)
				continue;
			// try to merge fragments
			fragments = Brush_MergeListPairs(fragments, true);
			// add the fragments to the list
			for (frag = fragments; frag; frag = nextfragment)
			{
				nextfragment = frag->next;
				frag->next = NULL;
				frag->owner = s->owner;
				Brush_AddToList(frag, &fragmentlist);
			}
			// free the original brush
			Brush_Free(s);
		}

		// chop any active brushes up
		for (s = active_brushes.next; s != &active_brushes; s = snext)
		{
			snext = s->next;

			if (s->owner->eclass->fixedsize || s->hiddenBrush)
				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

			fragments = Brush_Subtract(s, b);
			// if the brushes did not really intersect
			if (fragments == s)
				continue;

			// one extra brush chopped up
			numbrushes++;
			// try to merge fragments
			fragments = Brush_MergeListPairs(fragments, true);
			// add the fragments to the list
			for (frag = fragments; frag; frag = nextfragment)
			{
				nextfragment = frag->next;
				frag->next = NULL;
				frag->owner = s->owner;
				Brush_AddToList(frag, &fragmentlist);
			}
			// free the original brush
			Brush_Free(s);
		}
	}

	// move all fragments to the active brush list
	for (frag = fragmentlist.next; frag != &fragmentlist; frag = nextfragment)
	{
		nextfragment = frag->next;
		numfragments++;
		Brush_RemoveFromList(frag);
		Brush_AddToList(frag, &active_brushes);
	}

	if (numfragments == 0)
	{
		Sys_Printf ("Selected brush%s did not intersect with any other brushes.\n",
					(selected_brushes.next->next == &selected_brushes) ? "":"es");
		return;
	}
	Sys_Printf ("Done. (created %d fragment%s out of %d brush%s)\n", numfragments, (numfragments == 1)?"":"s",
							numbrushes, (numbrushes == 1)?"":"es");
	Sys_UpdateWindows(W_ALL);
}
Example #26
0
/*
================
Entity_Parse

If onlypairs is set, the classname info will not
be looked up, and the entity will not be added
to the global list.  Used for parsing the project.
================
*/
entity_t	*Entity_Parse (qboolean onlypairs, brush_t* pList)
{
	entity_t	*ent;
	eclass_t	*e;
	brush_t		*b;
	vec3_t		mins, maxs;
	epair_t		*ep;
	qboolean	has_brushes;
#ifdef SOF
	float		scale;
#endif

	if (!GetToken (true))
		return NULL;

	if (strcmp (token, "{") )
		Error ("ParseEntity: { not found");
	
	ent = (entity_t*)qmalloc (sizeof(*ent));
	ent->brushes.onext = ent->brushes.oprev = &ent->brushes;

	do
	{
		if (!GetToken (true))
    {
			Warning ("ParseEntity: EOF without closing brace");
      return NULL;
    }
		if (!strcmp (token, "}") )
			break;
		if (!strcmp (token, "{") )
		{
			b = Brush_Parse ();
      if (b != NULL)
      {
			  b->owner = ent;

			  // add to the end of the entity chain
			  b->onext = &ent->brushes;
			  b->oprev = ent->brushes.oprev;
			  ent->brushes.oprev->onext = b;
			  ent->brushes.oprev = b;
      }
      else
      {
        break;
      }
    
		}
		else
		{
			ep = ParseEpair ();
			{
				// update: the original code here may have been simple, but it meant that every map load/save
				//	the key/value pair fields were reversed in the save file, which messes up SourceSafe when it
				//	tries to delta the two versions during check-in... -slc
#if 0
				ep->next = ent->epairs;
				ent->epairs = ep;
#else
				// join this onto the END of the chain instead...
				//
				if (ent->epairs == NULL)	// special case for if there isn't a chain yet... :-)
				{
					ep->next = ent->epairs;
					ent->epairs = ep;
				}
				else
				{						
					for (epair_t* ep2 = ent->epairs ; ep2 ; ep2=ep2->next)
					{
						if (ep2->next == NULL)
						{
							// found the end, so...
							//
							ep2->next = ep;							
							ep->next = NULL;
							break;
						}
					}
				}
#endif
			}
		}
	} while (1);

	if (onlypairs)
		return ent;

	if (ent->brushes.onext == &ent->brushes)
		has_brushes = false;
	else
		has_brushes = true;

	GetVectorForKey (ent, "origin", ent->origin);

	e = Eclass_ForName (ValueForKey (ent, "classname"), has_brushes);
	ent->eclass = e;
	if (e->fixedsize)
	{	// fixed size entity
		if (ent->brushes.onext != &ent->brushes)
		{
			printf ("Warning: Fixed size entity with brushes\n");
#if 0
			while (ent->brushes.onext != &ent->brushes)
			{	// FIXME: this will free the entity and crash!
				Brush_Free (b);
			}
#endif
      ent->brushes.next = ent->brushes.prev = &ent->brushes;
		}

    // create a custom brush
		VectorAdd (e->mins, ent->origin, mins);
		VectorAdd (e->maxs, ent->origin, maxs);

    float a = 0;
    if (strnicmp(e->name, "misc_model",10) == 0)
    {
      char* p = ValueForKey(ent, "model");
      if (p != NULL && strlen(p) > 0)
      {
        vec3_t vMin, vMax;
        a = FloatForKey (ent, "angle");
		gEntityToSetBoundsOf = ent;
        if (GetCachedModel(ent, p, vMin, vMax))
        {
	      // create a custom brush
	      VectorAdd (ent->md3Class->mins, ent->origin, mins);
	      VectorAdd (ent->md3Class->maxs, ent->origin, maxs);
        }
      }
    }
#ifdef SOF
	if (strnicmp(e->name, "misc_",			5) == 0 ||
		strnicmp(e->name, "light_",			6) == 0 ||
		strnicmp(e->name, "m_",				2) == 0 ||
		strnicmp(e->name, "item_weapon_",	12)== 0 ||
		strnicmp(e->name, "item_ammo_",		10)== 0
		)
		a = FloatForKey (ent, "angle");
#endif		
		b = Brush_Create (mins, maxs, &e->texdef);
///////
		b->owner = ent;

		b->onext = ent->brushes.onext;
		b->oprev = &ent->brushes;
		ent->brushes.onext->oprev = b;
		ent->brushes.onext = b;
///////
		Brush_Build(b);

#ifdef SOF
		scale = FloatForKey (ent, "scale");
		if (scale)
		{
		  Brush_Scale2(e, b, scale, ent->origin,false);
		}
#endif

//		if (a)
//		{
//			vec3_t vAngle;
//			vAngle[0] = vAngle[1] = 0;
//			vAngle[2] = a;
//			Brush_Rotate(b, vAngle, ent->origin, false);
//		}

/*
		b->owner = ent;

		b->onext = ent->brushes.onext;
		b->oprev = &ent->brushes;
		ent->brushes.onext->oprev = b;
		ent->brushes.onext = b;
*/
		// do this AFTER doing the brush stuff just above, so don't join to the other "if (a)"...
		//
		if (a)
		{
			// pick any old value to rotate away to, then back from, to avoid 0/360 weirdness on key-compares
			//
			SetKeyValue(ent, "angle", "0",			false);	// false = no tracking, ie just set the angle and nothing else			
			SetKeyValue(ent, "angle", va("%g",a),	true);	// true = do tracking, ie actually do the brush rotate
		}
	}
	else
	{	// brush entity
		if (ent->brushes.next == &ent->brushes)
			printf ("Warning: Brush entity with no brushes\n");
	}

	// add all the brushes to the main list
  if (pList)
  {
	  for (b=ent->brushes.onext ; b != &ent->brushes ; b=b->onext)
    {
		  b->next = pList->next;
		  pList->next->prev = b;
		  b->prev = pList;
		  pList->next = b;
    }
  }

	return ent;
}
Example #27
0
/*
=============
CSG_Merge
=============
*/
void CSG_Merge(void)
{
	brush_t *b, *next, *newlist, *newbrush;
	entity_t	*owner;

	Sys_Status("Merging...\n");

	if (selected_brushes.next == &selected_brushes)
	{
		Sys_Status("No brushes selected.\n");
		return;
	}

	if (selected_brushes.next->next == &selected_brushes)
	{
		Sys_Status("At least two brushes have to be selected.\n");
		return;
	}

	owner = selected_brushes.next->owner;

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

		if (b->owner->eclass->fixedsize || b->modelHandle > 0)
		{
			// can't use texture from a fixed entity, so don't subtract
			Sys_Status("Cannot add fixed size entities.\n");
			return;
		}

		if (b->pPatch)
		{
			Sys_Status("Cannot add patches.\n");
			return;
		}

		if ( b->brush_faces->d_texture && ( b->brush_faces->d_texture->GetContentFlags() & CONTENTS_NOCSG ) )
		{
			Sys_Status("Cannot add brushes using shaders that don't allows CSG operations.\n");
			return;
		}

		if (b->owner != owner)
		{
			Sys_Status("Cannot add brushes from different entities.\n");
			return;
		}

	}

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

		Brush_RemoveFromList(b);
		b->next = newlist;
		b->prev = NULL;
		newlist = b;
	}

	newbrush = Brush_MergeList(newlist, true);
	// if the new brush would not be convex
	if (!newbrush)
	{
		// add the brushes back into the selection
		for (b = newlist; b; b = next)
		{
			next = b->next;
			b->next = NULL;
			b->prev = NULL;
			Brush_AddToList(b, &selected_brushes);
		}
		Sys_Status("Cannot add a set of brushes with a concave hull.\n");
		return;
	}
	// free the original brushes
	for (b = newlist; b; b = next)
	{
		next = b->next;
		b->next = NULL;
		b->prev = NULL;
		Brush_Free(b);
	}
	Brush_AddToList(newbrush, &selected_brushes);

	Sys_Status ("done.\n");
	Sys_UpdateWindows (W_ALL);
}