Пример #1
0
/*
============
Select_SetTexture
Timo : bFitScale to compute scale on the plane and counteract plane / axial plane snapping
Timo :  brush primitive texturing
        the brushprimit_texdef given must be understood as a qtexture_t width=2 height=2 ( HiRes )
Timo :  texture plugin, added an IPluginTexdef* parameter
        must be casted to an IPluginTexdef!
        if not NULL, get ->Copy() of it into each face or brush ( and remember to hook )
        if NULL, means we have no information, ask for a default
============
*/
void WINAPI Select_SetTexture( texdef_t* texdef, brushprimit_texdef_s* brushprimit_texdef, bool bFitScale, void* pPlugTexdef )
{
	brush_s*    b;
	int nCount = g_ptrSelectedFaces.GetSize();
	if ( nCount > 0 )
	{
		Undo_Start( "set face textures" );
		ASSERT( g_ptrSelectedFaces.GetSize() == g_ptrSelectedFaceBrushes.GetSize() );
		for ( int i = 0; i < nCount; i++ )
		{
			face_s* selFace = reinterpret_cast<face_s*>( g_ptrSelectedFaces.GetAt( i ) );
			brush_s* selBrush = reinterpret_cast<brush_s*>( g_ptrSelectedFaceBrushes.GetAt( i ) );
			Undo_AddBrush( selBrush );
			SetFaceTexdef( selBrush, selFace, texdef, brushprimit_texdef, bFitScale, static_cast<IPluginTexdef*>( pPlugTexdef ) );
			Brush_Build( selBrush, bFitScale );
			Undo_EndBrush( selBrush );
		}
		Undo_End();
	}
	else if ( selected_brushes.next != &selected_brushes )
	{
		Undo_Start( "set brush textures" );
		for ( b = selected_brushes.next ; b != &selected_brushes ; b = b->next )
			if ( !b->owner->eclass->fixedsize )
			{
				Undo_AddBrush( b );
				Brush_SetTexture( b, texdef, brushprimit_texdef, bFitScale, static_cast<IPluginTexdef*>( pPlugTexdef ) );
				Undo_EndBrush( b );
			}
		Undo_End();
	}
	Sys_UpdateWindows( W_ALL );
}
Пример #2
0
void SI_SetTexdef_FaceList(texdef_to_face_t* texdef_face_list, bool b_SetUndoPoint, bool bFit_to_Scale)
{
    texdef_to_face_t* texdef_to_face;
    bool b_isQuake2;

    if (g_pGameDescription->quake2)
        b_isQuake2 = true;
    else
        b_isQuake2 = false;

    if (!texdef_face_list)
        return;

    if (b_SetUndoPoint)
    {
        if(g_ptrSelectedFaces.GetSize() > 1)
            Sys_FPrintf(SYS_WRN, "WARNING: Undo NOT supported for multiple face selections\n");
        else if( (selected_brushes.next != &selected_brushes) || (g_ptrSelectedFaces.GetSize() == 1))
        {
            // Give something to undo to
            for(texdef_to_face = texdef_face_list; texdef_to_face; texdef_to_face = texdef_to_face->next)
                if (b_isQuake2)
                    SetFaceTexdef_Q2(texdef_to_face->face, &texdef_to_face->orig_texdef, bFit_to_Scale);
                else
                    SetFaceTexdef(texdef_to_face->face, &texdef_to_face->orig_texdef, &texdef_to_face->orig_bp_texdef, bFit_to_Scale);

            Undo_Start("set facelist texdefs");

            if( selected_brushes.next != &selected_brushes )
                Undo_AddBrushList(&selected_brushes);
            else
                Undo_AddBrush(texdef_face_list->brush);

        }
    }

    for(texdef_to_face = texdef_face_list; texdef_to_face; texdef_to_face = texdef_to_face->next)
    {
        if (b_isQuake2)
            SetFaceTexdef_Q2(texdef_to_face->face, &texdef_to_face->texdef,  bFit_to_Scale);
        else
        {
            brushprimit_texdef_t brushprimit_texdef;
            FakeTexCoordsToTexMat(texdef_to_face->texdef.shift, texdef_to_face->texdef.rotate, texdef_to_face->texdef.scale, brushprimit_texdef.coords);
            SetFaceTexdef(texdef_to_face->face, &texdef_to_face->texdef, &brushprimit_texdef , bFit_to_Scale);
        }
        Brush_Build(texdef_to_face->brush);
        if(bFit_to_Scale)
            texdef_to_face->texdef = texdef_to_face->face->texdef;
    }

    if ( b_SetUndoPoint )
    {
        if( (selected_brushes.next != &selected_brushes) || (g_ptrSelectedFaces.GetSize() == 1) )
        {
            if(selected_brushes.next != &selected_brushes)
                Undo_EndBrushList(&selected_brushes);
            else
                Undo_EndBrush(texdef_face_list->brush);

            Undo_End();
            // Over-write the orig_texdef list, cementing the change.
            for(texdef_to_face = texdef_face_list; texdef_to_face; texdef_to_face = texdef_to_face->next)
            {
                texdef_to_face->orig_texdef = texdef_to_face->texdef;
                texdef_to_face->orig_bp_texdef = texdef_to_face->face->brushprimit_texdef;
            }
        }
    }

    Sys_UpdateWindows (W_ALL);
}
Пример #3
0
/*
=============
CSG_Subtract
=============
*/
void CSG_Subtract (void)
{
	brush_t		*b, *s, *fragments, *nextfragment, *frag, *next, *snext;
	brush_t		fragmentlist;
	int			i, numfragments, numbrushes;

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

	if (selected_brushes.next == &selected_brushes)
	{
		Sys_Status("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 || b->modelHandle > 0)
			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->pPatch || s->hiddenBrush || s->modelHandle > 0)
				continue;

			//face_t *pFace = s->brush_faces;
			if ( s->brush_faces->d_texture && ( s->brush_faces->d_texture->GetContentFlags()& CONTENTS_NOCSG ) )
			{
				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;
			//
			Undo_AddBrush(s);
			// 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);
		Undo_EndBrush(frag);
	}

	if (numfragments == 0)
	{
		common->Printf("Selected brush%s did not intersect with any other brushes.\n",
					(selected_brushes.next->next == &selected_brushes) ? "":"es");
		return;
	}
	Sys_Status("done.");
	common->Printf(" (created %d fragment%s out of %d brush%s)\n", numfragments, (numfragments == 1)?"":"s",
							numbrushes, (numbrushes == 1)?"":"es");
	Sys_UpdateWindows(W_ALL);
}
Пример #4
0
//
// =======================================================================================================================
//    Map_ImportFile Timo 09/01/99:: called by CXYWnd::Paste & Map_ImportFile if Map_ImportFile ( prefab ), the buffer
//    may contain brushes in old format ( conversion needed )
// =======================================================================================================================
//
void Map_ImportBuffer(char *buf, bool renameEntities) {
	entity_t	*ent;
	brush_t		*b = NULL;
	CPtrArray	ptrs;

	Select_Deselect();

	Undo_Start("import buffer");

	g_qeglobals.d_parsed_brushes = 0;
	if (buf) {
		CMapStringToString	mapStr;
		StartTokenParsing(buf);
		g_qeglobals.d_num_entities = 0;

		//
		// Timo will be used in Entity_Parse to detect if a conversion between brush
		// formats is needed
		//
		g_qeglobals.bNeedConvert = false;
		g_qeglobals.bOldBrushes = false;
		g_qeglobals.bPrimitBrushes = false;
		g_qeglobals.mapVersion = 1.0;

		if (GetToken(true)) {
			if (stricmp(token, "Version") == 0) {
				GetToken(false);
				g_qeglobals.mapVersion = atof(token);
				common->Printf("Map version: %1.2f\n", g_qeglobals.mapVersion);
			} else {
				UngetToken();
			}
		}

		idDict RemappedNames;	// since I can't use "map <string, string>"... sigh. So much for STL...

		while (1) {
			//
			// use the selected brushes list as it's handy ent = Entity_Parse (false,
			// &selected_brushes);
			//
			ent = Entity_Parse(false, &active_brushes);
			if (!ent) {
				break;
			}

			// end entity for undo
			Undo_EndEntity(ent);

			// end brushes for undo
			for (b = ent->brushes.onext; b && b != &ent->brushes; b = b->onext) {
				Undo_EndBrush(b);
			}

			if (!strcmp(ValueForKey(ent, "classname"), "worldspawn")) {
				// world brushes need to be added to the current world entity
				b = ent->brushes.onext;
				while (b && b != &ent->brushes) {
					brush_t *bNext = b->onext;
					Entity_UnlinkBrush(b);
					Entity_LinkBrush(world_entity, b);
					ptrs.Add(b);
					b = bNext;
				}
			}
			else {
				// the following bit remaps conflicting target/targetname key/value pairs
				CString str = ValueForKey(ent, "target");
				CString strKey;
				CString strTarget("");
				if (str.GetLength() > 0) {
					if (FindEntity("target", str.GetBuffer(0))) {
						if (!mapStr.Lookup(str, strKey)) {
							idStr key;
							UniqueTargetName(key);
							strKey = key;
							mapStr.SetAt(str, strKey);
						}

						strTarget = strKey;
						SetKeyValue(ent, "target", strTarget.GetBuffer(0));
					}
				}

				/*
				 * str = ValueForKey(ent, "name"); if (str.GetLength() > 0) { if
				 * (FindEntity("name", str.GetBuffer(0))) { if (!mapStr.Lookup(str, strKey)) {
				 * UniqueTargetName(strKey); mapStr.SetAt(str, strKey); } Entity_SetName(ent,
				 * strKey.GetBuffer(0)); } }
				 */
				CString cstrNameOld = ValueForKey(ent, "name");
				Entity_Name(ent, renameEntities);
				CString cstrNameNew = ValueForKey(ent, "name");
				if (cstrNameOld != cstrNameNew)
				{
					RemappedNames.Set(cstrNameOld, cstrNameNew);
				}
				//
				// if (strTarget.GetLength() > 0) SetKeyValue(ent, "target",
				// strTarget.GetBuffer(0));
				// add the entity to the end of the entity list
				//
				ent->next = &entities;
				ent->prev = entities.prev;
				entities.prev->next = ent;
				entities.prev = ent;
				g_qeglobals.d_num_entities++;

				for (b = ent->brushes.onext; b != &ent->brushes; b = b->onext) {
					ptrs.Add(b);
				}
			}
		}

		// now iterate through the remapped names, and see if there are any target-connections that need remaking...
		//
		// (I could probably write this in half the size with STL, but WTF, work with what we have...)
		//
		int iNumKeyVals = RemappedNames.GetNumKeyVals();
		for (int iKeyVal=0; iKeyVal < iNumKeyVals; iKeyVal++)
		{
			const idKeyValue *pKeyVal = RemappedNames.GetKeyVal( iKeyVal );

			LPCSTR psOldName = pKeyVal->GetKey().c_str();
			LPCSTR psNewName = pKeyVal->GetValue().c_str();

			entity_t *pEntOld = FindEntity("name", psOldName);	// original ent we cloned from
			entity_t *pEntNew = FindEntity("name", psNewName);	// cloned ent

			if (pEntOld && pEntNew)
			{
				CString cstrTargetNameOld = ValueForKey(pEntOld, "target");
				if (!cstrTargetNameOld.IsEmpty())
				{
					// ok, this ent was targeted at another ent, so it's clone needs updating to point to
					//	the clone of that target, so...
					//
					entity_t *pEntOldTarget = FindEntity("name", cstrTargetNameOld);
					if ( pEntOldTarget )
					{
						LPCSTR psNewTargetName = RemappedNames.GetString( cstrTargetNameOld );
						if (psNewTargetName && psNewTargetName[0])
						{
							SetKeyValue(pEntNew, "target", psNewTargetName);
						}
					}
				}
			}
		}
	}

	//
	// ::ShowWindow(g_qeglobals.d_hwndEntity, FALSE);
	// ::LockWindowUpdate(g_qeglobals.d_hwndEntity);
	//
	g_bScreenUpdates = false;
	for (int i = 0; i < ptrs.GetSize(); i++) {
		Brush_Build(reinterpret_cast < brush_t * > (ptrs[i]), true, false);
		Select_Brush(reinterpret_cast < brush_t * > (ptrs[i]), true, false);
	}

	// ::LockWindowUpdate(NULL);
	g_bScreenUpdates = true;

	ptrs.RemoveAll();

	//
	// reset the "need conversion" flag conversion to the good format done in
	// Map_BuildBrushData
	//
	g_qeglobals.bNeedConvert = false;

	Sys_UpdateWindows(W_ALL);

	// Sys_MarkMapModified();
	mapModified = 1;

	Undo_End();
}
Пример #5
0
//
//================
//Map_ImportFile
// Timo 09/01/99 : called by CXYWnd::Paste & Map_ImportFile
// if Map_ImportFile ( prefab ), the buffer may contain brushes in old format ( conversion needed )
//================
//
void Map_ImportBuffer (char* buf)
{
	entity_t* ent;
	brush_t* b = NULL;
	CPtrArray ptrs;

	Select_Deselect();

	Undo_Start("import buffer");

	g_qeglobals.d_parsed_brushes = 0;
	if (buf)
	{
		CMapStringToString mapStr;
		StartTokenParsing (buf);
		g_qeglobals.d_num_entities = 0;

		// Timo
		// will be used in Entity_Parse to detect if a conversion between brush formats is needed
		g_qeglobals.bNeedConvert = false;
		g_qeglobals.bOldBrushes = false;
		g_qeglobals.bPrimitBrushes = false;

		while (1)
		{

			// use the selected brushes list as it's handy
			//ent = Entity_Parse (false, &selected_brushes);
			ent = Entity_Parse (false, &active_brushes);
			if (!ent)
				break;
			//end entity for undo
			Undo_EndEntity(ent);
			//end brushes for undo
			for(b = ent->brushes.onext; b && b != &ent->brushes; b = b->onext)
			{
				Undo_EndBrush(b);
			}

			if (!strcmp(ValueForKey (ent, "classname"), "worldspawn"))
			{
				// world brushes need to be added to the current world entity

				b=ent->brushes.onext;
				while (b && b != &ent->brushes)
				{
					brush_t* bNext = b->onext;
					Entity_UnlinkBrush(b);
					Entity_LinkBrush(world_entity, b);
					ptrs.Add(b);
					b = bNext;
				}
			}
			else
			{
				// the following bit remaps conflicting target/targetname key/value pairs
				CString str = ValueForKey(ent, "target");
				CString strKey;
				CString strTarget("");
				if (str.GetLength() > 0)
				{
					if (FindEntity("target", str.GetBuffer(0)))
					{
						if (!mapStr.Lookup(str, strKey))
						{
							UniqueTargetName(strKey);
							mapStr.SetAt(str, strKey);
						}
						strTarget = strKey;
						SetKeyValue(ent, "target", strTarget.GetBuffer(0));
					}
				}
				str = ValueForKey(ent, "targetname");
				if (str.GetLength() > 0)
				{
					if (FindEntity("targetname", str.GetBuffer(0)))
					{
						if (!mapStr.Lookup(str, strKey))
						{
							UniqueTargetName(strKey);
							mapStr.SetAt(str, strKey);
						}
						SetKeyValue(ent, "targetname", strKey.GetBuffer(0));
					}
				}
				//if (strTarget.GetLength() > 0)
				//  SetKeyValue(ent, "target", strTarget.GetBuffer(0));

				// add the entity to the end of the entity list
				ent->next = &entities;
				ent->prev = entities.prev;
				entities.prev->next = ent;
				entities.prev = ent;
				g_qeglobals.d_num_entities++;

				for (b=ent->brushes.onext ; b != &ent->brushes ; b=b->onext)
				{
					ptrs.Add(b);
				}
			}
		}
	}

	//::ShowWindow(g_qeglobals.d_hwndEntity, FALSE);
	//::LockWindowUpdate(g_qeglobals.d_hwndEntity);
	g_bScreenUpdates = false; 
	for (int i = 0; i < ptrs.GetSize(); i++)
	{
		Brush_Build(reinterpret_cast<brush_t*>(ptrs[i]), true, false);
		Select_Brush(reinterpret_cast<brush_t*>(ptrs[i]), true, false);
	}
	//::LockWindowUpdate(NULL);
	g_bScreenUpdates = true; 

	ptrs.RemoveAll();

	// reset the "need conversion" flag
	// conversion to the good format done in Map_BuildBrushData
	g_qeglobals.bNeedConvert=false;

	Sys_UpdateWindows (W_ALL);
  //Sys_MarkMapModified();
	modified = true;

	Undo_End();

}