⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 brush.cpp

📁 3D游戏场景编辑器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/****************************************************************************************/
/*  brush.c                                                                             */
/*                                                                                      */
/*  Author:       Jim Mischel, Ken Baird, Jeff Lomax, John Pollard                      */
/*  Description:  Brush management, io, csg, list management, and transform operations  */
/*                                                                                      */
/*  The contents of this file are subject to the Genesis3D Public License               */
/*  Version 1.01 (the "License"); you may not use this file except in                   */
/*  compliance with the License. You may obtain a copy of the License at                */
/*  http://www.genesis3d.com                                                            */
/*                                                                                      */
/*  Software distributed under the License is distributed on an "AS IS"                 */
/*  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See                */
/*  the License for the specific language governing rights and limitations              */
/*  under the License.                                                                  */
/*                                                                                      */
/*  The Original Code is Genesis3D, released March 25, 1999.                            */
/*Genesis3D Version 1.1 released November 15, 1999                            */
/*  Copyright (C) 1999 WildTangent, Inc. All Rights Reserved           */
/*                                                                                      */
/*  Modified by Tom Morris for GenEdit-Classic ver. 0.57, Feb. 3, 2001					*/
/****************************************************************************************/
#include "StdAfx.h"
#include "Globals.h"
#include "brush.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "Vec3d.h"
#include "basetype.h"
#include "typeio.h"
#include "facelist.h"
#include "units.h"
#include "ram.h"
#include "util.h"
//#include "ConsoleTab.h"	//for conprintf
#include "Globals.h"

/*
	Our brushes work as three different objects.  The basic square box is a leaf brush
	that contains the original verts and info from the template dialog.  Leaf brushes
	will have a facelist, and possibly a brushlist containing pieces of the original
	brush that have been cut up by others.  Leaf is a bit confusing, since these
	brushes aren't actually leaf regions in a tree or anything.
	
	Multi brushes such as hollows and arches and other nonconvex brushes will contain
	a series of leaf brushes.  Multi brushes should contain no faces themselves.

	CSG brushes are the end result of cuts.  They are stored beneath the parent leaf.

	Brushes are not exclusive to volume in our system.  We don't csg multiple solid
	areas away.  Only drastic content changes will cause this. (cuts)

	There's alot of work done to keep the data structures hidden to other files.  This
	is a standard practice here at WildTangent and brush, face, facelist are all good
	examples of how "opaque" objects work.
*/


static const int		axidx[3][2]	={ 2, 1, 0, 2, 0, 1 };
static const geVec3d	VecOrigin	={ 0.0f, 0.0f, 0.0f };


struct tag_BrushList
{
	Brush *First;
	Brush *Last;
};

#define	VectorToSUB(a, b)			(*((((geFloat *)(&a))) + (b)))
#define	VCOMPARE_EPSILON			0.001f
#define BOGUS_RANGE					32000.0f

enum BrushFlags
{
	BRUSH_SOLID			=0x0001,
	BRUSH_WINDOW		=0x0002, 
	BRUSH_WAVY			=0x0004,
	BRUSH_DETAIL		=0x0008,	//not included in vis calculations		
	BRUSH_HOLLOWCUT		=0x0010,
	BRUSH_TRANSLUCENT	=0x0020,
	BRUSH_EMPTY			=0x0040,
	BRUSH_SUBTRACT		=0x0080,
	BRUSH_CLIP			=0x0100,
	BRUSH_FLOCKING		=0x0200,	
	BRUSH_HOLLOW		=0x0400,
	BRUSH_SHEET			=0x0800,
	BRUSH_HIDDEN		=0x1000,
	BRUSH_LOCKED		=0x2000,
	BRUSH_HINT			=0x4000,
	BRUSH_AREA			=0x8000
	// All flags larger than 0x8000 (i.e. 0x00010000 through 0x80000000)
	// are reserved for user contents.
};

// Brush flags output to GBSPLIB
enum
{
	bfSolid			= (1<<0),
	bfWindow		= (1<<1),
	bfEmpty			= (1<<2),
	bfTranslucent	= (1<<3),
	bfWavy			= (1<<4),
	bfDetail		= (1<<5),
	bfClip			= (1<<6),
	bfHint			= (1<<7),
	bfArea			= (1<<8),
	bfFlocking		= (1<<9),
	bfSheet			= (1<<10)
	// flags 11 through 15 are reserved for future expansion.
	// flags 16 through 31 are user flags.
};

#define USER_FLAGS_MASK		(0xffff0000ul)
#define SYSTEM_FLAGS_MASK	(0x0000fffful)

// brush edit flags (not currently used, but please don't remove)
enum
{
	befHidden		= (1<<0),
	befLocked		= (1<<1),
	befSelected		= (1<<2),
	befEntity		= (1<<3),
//	befTexInvalid	= (1<<4),
	befHollow		= (1<<5),
	befRing			= (1<<6)
};
/*
typedef struct BrushTag		//	moved to brush.h for g3dc
{
	struct BrushTag	*Prev, *Next;
	FaceList		*Faces;			//null if multibrush
	BrushList		*BList;			//null if csgbrush
	unsigned long	Flags;
	int				Type;
	int				ModelId;
	int				GroupId;
	geFloat			HullSize;		//for hollows
	uint32			Color;
	char			*Name;
	Box3d			BoundingBox;
} Brush;
*/

typedef void (*BrushList_FlagCB)(Brush *pBrush, const geBoolean bState);
typedef void (*BrushList_IntCB)(Brush *pBrush, const int iVal);
typedef void (*BrushList_FloatCB)(Brush *pBrush, const float fVal);
typedef void (*BrushList_Uint32CB)(Brush *pBrush, const uint32 uVal);

static void	BrushList_SetFlag(BrushList *bl, const geBoolean bState, BrushList_FlagCB cbSetFlag)
{
	Brush	*b;

	if (bl == NULL)
		MessageBox(NULL, "Brush1 == NULL", "BrushList_SetFlag", MB_OK);	//	post 0.55

	assert(bl != NULL);

	for(b=bl->First;b;b=b->Next)
	{
		cbSetFlag(b, bState);
	}
}

static void	BrushList_SetInt(BrushList *bl, const int iVal, BrushList_IntCB cbSetInt)
{
	Brush	*b;

	if (bl == NULL)
		MessageBox(NULL, "Brush1 == NULL", "BrushList_SetInt", MB_OK);	//	post 0.55

	assert(bl != NULL);

	for(b=bl->First;b;b=b->Next)
	{
		cbSetInt(b, iVal);
	}
}

static void	BrushList_SetUint32(BrushList *bl, const uint32 uVal, BrushList_Uint32CB cbSetUint)
{
	Brush	*b;

	if (bl == NULL)
		MessageBox(NULL, "Brush1 == NULL", "BrushList_SetUINT32", MB_OK);	//	post 0.55

	assert(bl != NULL);

	for(b=bl->First;b;b=b->Next)
	{
		cbSetUint(b, uVal);
	}
}

static void	BrushList_SetFloat(BrushList *bl, const geFloat fVal, BrushList_FloatCB cbSetFloat)
{
	Brush	*b;

	if (bl == NULL)
		MessageBox(NULL, "Brush1 == NULL", "BrushList_SetFloat", MB_OK);	//	post 0.55

	assert(bl != NULL);

	for(b=bl->First;b;b=b->Next)
	{
		cbSetFloat(b, fVal);
	}
}

Brush	*Brush_Create(int Type, const FaceList *fl, const BrushList *BList)
{
	Brush	*pBrush;

	pBrush	=(Brush*)geRam_Allocate(sizeof (Brush));
	if(pBrush != NULL)
	{
		pBrush->Prev	=NULL;
		pBrush->Next	=NULL;
		pBrush->ModelId	=0;
		pBrush->GroupId	=0;
		pBrush->HullSize=1.0f;
		pBrush->Color	=0;
		pBrush->Name	=Util_Strdup("NoName");
		pBrush->Type	=Type;
		switch(Type)
		{
		case	BRUSH_MULTI:
			assert(fl==NULL);
			assert(BList);

			pBrush->Faces	=NULL;
			pBrush->BList	=(BrushList *)BList;
			pBrush->Flags	=BRUSH_SOLID;
			BrushList_GetBounds(BList, &pBrush->BoundingBox);
			break;

		case	BRUSH_LEAF:
		case	BRUSH_CSG:
			assert(fl);
			assert(BList==NULL);	//shouldn't create leaf from multiple

			pBrush->Faces	=(FaceList *)fl;
			pBrush->BList	=NULL;
			pBrush->Flags	=BRUSH_SOLID;
			FaceList_GetBounds(fl, &pBrush->BoundingBox);
			break;

		default:
			assert(0);
		}
	}
	return pBrush;
}

//creates a csg brush from a leaf or csg brush
static Brush	*Brush_CreateFromParent(const Brush *ParentBrush, const FaceList *fl)
{
	Brush	*pBrush;

	if (ParentBrush == NULL)
		MessageBox(NULL, "ParentBrush == NULL", "Brush_CreateFromParent", MB_OK);	//	post 0.55


	assert(ParentBrush);
	assert(fl != NULL);
	assert(ParentBrush->Type!=BRUSH_MULTI);

	pBrush	= (BrushTag*)geRam_Allocate(sizeof (Brush));
	if(pBrush != NULL)
	{
		pBrush->Prev	=NULL;
		pBrush->Next	=NULL;
		pBrush->Faces	=(FaceList *)fl;
		pBrush->BList	=NULL;
		pBrush->Flags	=ParentBrush->Flags;
		pBrush->ModelId	=ParentBrush->ModelId;
		pBrush->GroupId	=ParentBrush->GroupId;
		pBrush->HullSize=ParentBrush->HullSize;
		pBrush->Color	=ParentBrush->Color;
		pBrush->Name	=Util_Strdup(ParentBrush->Name);
		pBrush->Type	=BRUSH_CSG;
		FaceList_GetBounds(fl, &pBrush->BoundingBox);
	}
	return pBrush;
}

void	Brush_Destroy(Brush **b)
{
	if (b == NULL)
	{
		MessageBox(NULL, "Brush == NULL", "Brush_Destroy", MB_OK);	//	post 0.55
		return;
	}

	if (*b == NULL)
	{
		MessageBox(NULL, "Brush == NULL", "Brush_Destroy", MB_OK);	//	post 0.55
		return;
	}

	if ((*b)->Prev != NULL)
	{
		MessageBox(NULL, "Brush->Prev == NULL", "Brush_Destroy", MB_OK);	//	post 0.55
		return;
	}

	if ((*b)->Next != NULL)
	{
		MessageBox(NULL, "Brush->Next == NULL", "Brush_Destroy", MB_OK);	//	post 0.55
		return;
	}

	
	assert(b != NULL);
	assert(*b != NULL);
	assert((*b)->Prev == NULL);
	assert((*b)->Next == NULL);

	if((*b)->Type!=BRUSH_CSG)
	{
		if((*b)->BList)
		{
			BrushList_Destroy(&((*b)->BList));
		}
	}
	if((*b)->Type!=BRUSH_MULTI)
	{
		if((*b)->Faces)
		{
			FaceList_Destroy(&((*b)->Faces));
		}
	}

	if((*b)->Name)
	{
		geRam_Free ((*b)->Name);
	}
	geRam_Free (*b);
	*b	=NULL;
}

Brush	*Brush_Clone(Brush const *from)
{
	Brush		*to = NULL;
	FaceList	*NewFaces;
	BrushList	*MBList;

	if (from == NULL)
		MessageBox(NULL, "Brush == NULL", "Brush_Clone", MB_OK);	//	post 0.55

	assert(from != NULL);

	switch(from->Type)
	{
	case	BRUSH_MULTI:
		assert(from->Faces==NULL);
		assert(from->BList);

		MBList	=BrushList_Clone(from->BList);
		if(!MBList)
		{
			break;
		}
		to		=Brush_Create(from->Type, NULL, MBList);	
		break;

	case	BRUSH_LEAF:
	case	BRUSH_CSG:
		assert(from->Faces != NULL);

		NewFaces	=FaceList_Clone(from->Faces);
		if(NewFaces != NULL)
		{
			to	=Brush_Create(from->Type, NewFaces, NULL);
		}
		if(to==NULL)
		{
			geRam_Free (NewFaces);
		}
		break;

	default:
		assert(0);
		break;
	}

	if(to != NULL)
	{
		to->Flags		=from->Flags;
		to->Type		=from->Type;
		to->ModelId		=from->ModelId;
		to->GroupId		=from->GroupId;
		to->HullSize	=from->HullSize;
		to->Color		=from->Color;
		Brush_SetName (to, from->Name);
		to->BoundingBox	=from->BoundingBox;
	}

	return	to;
}

static void	Brush_CopyFaceInfo(Brush const *src, Brush *dst)
{
	assert(src);
	assert(dst);
	assert(src->Type!=BRUSH_MULTI);
	assert(dst->Type!=BRUSH_MULTI);
	assert(src->Faces);
	assert(dst->Faces);

	FaceList_CopyFaceInfo(src->Faces, dst->Faces);
}

int	Brush_GetNumFaces(const Brush *b)
{
	if (b == NULL)
		MessageBox(NULL, "Brush == NULL", "Brush_GetNumFaces", MB_OK);	//	post 0.55

	if (b->Faces == NULL)
		MessageBox(NULL, "Brush->Faces == NULL", "Brush_GetNumFaces", MB_OK);	//	post 0.55

	assert(b != NULL);
	assert(b->Faces != NULL);

	return	FaceList_GetNumFaces(b->Faces);
}

Face *Brush_GetFace(const Brush *b, int i)
{
	if (b == NULL)
		MessageBox(NULL, "Brush == NULL", "Brush_GetFaces", MB_OK);	//	post 0.55

	if (b->Faces == NULL)
		MessageBox(NULL, "Brush->Faces == NULL", "Brush_GetFaces", MB_OK);	//	post 0.55

	assert(b != NULL);
	assert(b->Faces != NULL);

	return	FaceList_GetFace(b->Faces, i);
}

int	Brush_GetModelId(const Brush *b)
{
	if (b == NULL)
		MessageBox(NULL, "Brush == NULL", "Brush_GetModelId", MB_OK);	//	post 0.55
	
	assert(b != NULL);

	return	b->ModelId;
}

int	Brush_GetGroupId(const Brush *b)
{
	if (b == NULL)
		MessageBox(NULL, "Brush == NULL", "Brush_GetGroupId", MB_OK);	//	post 0.55

	assert(b != NULL);
	
	return	b->GroupId;
}

geFloat	Brush_GetHullSize(const Brush *b)
{
	if (b == NULL)
		MessageBox(NULL, "Brush == NULL", "Brush_GetHullSize", MB_OK);	//	post 0.55

	assert(b != NULL);

	return	b->HullSize;
}

uint32	Brush_GetColor(const Brush *b)
{
	if (b == NULL)
		MessageBox(NULL, "Brush == NULL", "Brush_GetColor", MB_OK);	//	post 0.55
	
	assert(b != NULL);
	
	return	b->Color;
}

int			Brush_GetType (const Brush *b)
{
	if (b == NULL)
		MessageBox(NULL, "Brush == NULL", "Brush_GetType", MB_OK);	//	post 0.55
	
	return b->Type;
}

const char	*Brush_GetName(const Brush *b)
{
	if (b == NULL)
		MessageBox(NULL, "Brush == NULL", "Brush_GetName", MB_OK);	//	post 0.55

	assert(b != NULL);
	
	//are empty names ok?
	return	b->Name;
}

const BrushList	*Brush_GetBrushList(const Brush *b)
{
	if (b == NULL)
		MessageBox(NULL, "Brush == NULL", "Brush_GetBrushList", MB_OK);	//	post 0.55

	assert(b != NULL);
	
	//are empty names ok?
	return	b->BList;
}


void	Brush_SetModelId(Brush *b, const int mid)
{
	if (b == NULL)
		MessageBox(NULL, "Brush == NULL", "Brush_SetModelId", MB_OK);	//	post 0.55

	assert(b != NULL);
	
	if (b->Type == BRUSH_MULTI)
	{
		BrushList_SetInt (b->BList, mid, Brush_SetModelId);
	}
	b->ModelId	=mid;
}

//should this be set in child brushes too?
void	Brush_SetGroupId(Brush *b, const int gid)
{
	if (b == NULL)
		MessageBox(NULL, "Brush == NULL", "Brush_SetGroupId", MB_OK);	//	post 0.55

	assert(b != NULL);
	
	if (b->Type == BRUSH_MULTI)
	{
		BrushList_SetInt (b->BList, gid, Brush_SetGroupId);
	}
	b->GroupId	=gid;
}

void	Brush_SetHullSize(Brush *b, const geFloat hsize)
{
	geFloat RealHullSize = hsize;

	if (b == NULL)
		MessageBox(NULL, "Brush == NULL", "Brush_SetHullSize", MB_OK);	//	post 0.55

	assert(b != NULL);

	if (hsize < 1.0f)
	{
		RealHullSize = 1.0f;
	}
	if(b->Type==BRUSH_MULTI)
	{
		BrushList_SetFloat(b->BList, RealHullSize, Brush_SetHullSize);
	}

	b->HullSize	=RealHullSize;
}

void	Brush_SetColor(Brush *b, const uint32 newcolor)
{
	if (b == NULL)
		MessageBox(NULL, "Brush == NULL", "Brush_SetColor", MB_OK);	//	post 0.55

	assert(b != NULL);
	
	if(b->Type==BRUSH_MULTI)
	{
		BrushList_SetUint32(b->BList, newcolor, Brush_SetColor);
	}
	b->Color	=newcolor;
}

//should these go to child brushes?
void	Brush_SetName(Brush *b, const char *newname)
{
	if (b == NULL)
		MessageBox(NULL, "Brush == NULL", "Brush_SetName", MB_OK);	//	post 0.55

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -