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

📄 brush.cpp

📁 3D游戏场景编辑器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	{
		// version 1.24 and later we quoted the texture names...
		if (!Parse3dt_GetLiteral (Parser, (*Expected = "Brush"), szTemp)) return NULL;
	}
	else
	{
		if (!Parse3dt_GetIdentifier (Parser, (*Expected = "Brush"), szTemp)) return NULL;
	}

	if (!Parse3dt_GetInt (Parser, (*Expected = "Flags"), &tmpFlags)) return NULL;

	if ((VersionMajor == 1) && (VersionMinor <= 10))
	{
		// Clear unused flags from older file versions
		// All brushes are solid by default.
		tmpFlags &= (BRUSH_DETAIL | BRUSH_HOLLOW | BRUSH_SUBTRACT | BRUSH_HOLLOWCUT | BRUSH_HIDDEN | BRUSH_LOCKED);
		tmpFlags |= BRUSH_SOLID;
		tmpFlags &= (~(BRUSH_HINT | BRUSH_CLIP | BRUSH_AREA | BRUSH_TRANSLUCENT | BRUSH_EMPTY));
	}
	if ((VersionMajor == 1) && (VersionMinor < 25))
	{
		// clear flocking flag on old file versions.
		tmpFlags &= ~BRUSH_FLOCKING;
	}
	if ((VersionMajor == 1) && (VersionMinor < 29))
	{
		// clear sheet flag on older file versions
		tmpFlags &= ~BRUSH_SHEET;
	}

	if((VersionMajor > 1) || ((VersionMajor == 1) && (VersionMinor >= 3)))
	{
		if (!Parse3dt_GetInt (Parser, (*Expected = "ModelId"), &tmpModelId)) return NULL;
		if (!Parse3dt_GetInt (Parser, (*Expected = "GroupId"), &tmpGroupId)) return NULL;
	}
	else
	{
		if (!Parse3dt_GetInt (Parser, (*Expected = "EntityId"), &tmpModelId)) return NULL;
		tmpGroupId	=0;
	}
	
	if (!Parse3dt_GetFloat (Parser, (*Expected = "HullSize"), &tmpHullSize)) return NULL;
	if (tmpHullSize < 1.0f)
	{
		tmpHullSize = 1.0f;
	}

	if ((VersionMajor == 1) && (VersionMinor <= 16))
	{
		tmpTranslucency = 0;
	}
	else if ((VersionMajor > 1) || ((VersionMajor == 1) && (VersionMinor < 27)))
	{
		if (!Parse3dt_GetInt (Parser, (*Expected = "Translucency"), &tmpTranslucency)) return NULL;
		if (tmpTranslucency > 255) tmpTranslucency = 255;
		if (tmpTranslucency < 0) tmpTranslucency = 0;
	}
	else
	{
		tmpTranslucency = 0;
	}

	tmpType = BRUSH_LEAF;	// default is leaf brush
	if ((VersionMajor > 1) || ((VersionMajor == 1) && (VersionMinor >= 15)))
	{
		if (!Parse3dt_GetInt (Parser, (*Expected = "Type"), &tmpType)) return NULL;
	}

	fl = NULL;
	blist = NULL;
	switch (tmpType)
	{
		case BRUSH_LEAF :
		{
			fl = FaceList_CreateFromFile (Parser, VersionMajor, VersionMinor, Expected);
			if (fl == NULL)
			{
				goto DoneLoad;
			}
			break;
		}
		case BRUSH_MULTI :
			blist = BrushList_CreateFromFile (Parser, VersionMajor, VersionMinor, Expected);
			if (blist == NULL)
			{
				goto DoneLoad;
			}
			break;
		default :
			assert (0);		//bad stuff here
			return NULL;
	}

	//drop trans into faces from old maps
	if ((VersionMajor > 1) || ((VersionMajor == 1) && (VersionMinor < 27)))
	{
		if(fl)
		{
			FaceList_SetTranslucency(fl, (float)tmpTranslucency);
		}
	}

	if (tmpFlags & BRUSH_TRANSLUCENT)
	{
		// set faces as translucent
		if (fl != NULL)
		{
			FaceList_SetTransparent (fl, GE_TRUE);
		}
		tmpFlags &= ~BRUSH_TRANSLUCENT;
	}

	b = Brush_Create (tmpType, fl, blist);
	if (b == NULL)
	{
		if (fl != NULL)
		{
			FaceList_Destroy (&fl);
		}
		if (blist != NULL)
		{
			BrushList_Destroy (&blist);
		}
	}
	else
	{
		b->Flags	=tmpFlags;
		b->HullSize	=tmpHullSize;
		b->ModelId	=tmpModelId;
		b->GroupId	=tmpGroupId;
		Brush_SetName (b, szTemp);
	}

DoneLoad:
	return	b;
}

void	Brush_Resize(Brush *b, float dx, float dy, int sides, int inidx, geVec3d *fnscale, int *ScaleNum)
{
	int		i;
	geVec3d	FixOrg, BrushOrg, ScaleVec;

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

	assert(b);
	assert(fnscale);
	assert(ScaleNum);

	geVec3d_Add(&b->BoundingBox.Min, &b->BoundingBox.Max, &BrushOrg);
	geVec3d_Scale(&BrushOrg, 0.5f, &BrushOrg);

	//find the corner of the bounds to keep fixed
	VectorToSUB(FixOrg, inidx)			=0.0f;
	if((sides&3)==0)	//center x
	{
		dx=-dx;
		VectorToSUB(FixOrg, axidx[inidx][0])	=VectorToSUB(BrushOrg, axidx[inidx][0]);
	}
	else if((sides&3)==2)	//less x
	{
		VectorToSUB(FixOrg, axidx[inidx][0])	=VectorToSUB(b->BoundingBox.Min, axidx[inidx][0]);
	}
	else if((sides&3)==1)	//greater x
	{
		dx=-dx;
		VectorToSUB(FixOrg, axidx[inidx][0])	=VectorToSUB(b->BoundingBox.Max, axidx[inidx][0]);
	}

	if((sides&0x0c)==0)	//center y
	{
		VectorToSUB(FixOrg, axidx[inidx][1])	=VectorToSUB(BrushOrg, axidx[inidx][1]);
	}
	else if((sides&0x0c)==4)	//less y
	{
		dy=-dy;
		if(inidx!=1)
			VectorToSUB(FixOrg, axidx[inidx][1])	=VectorToSUB(b->BoundingBox.Min, axidx[inidx][1]);
		else
			VectorToSUB(FixOrg, axidx[inidx][1])	=VectorToSUB(b->BoundingBox.Max, axidx[inidx][1]);
	}
	else if((sides&0x0c)==8)	//greater y
	{
		if(inidx!=1)
			VectorToSUB(FixOrg, axidx[inidx][1])	=VectorToSUB(b->BoundingBox.Max, axidx[inidx][1]);
		else
			VectorToSUB(FixOrg, axidx[inidx][1])	=VectorToSUB(b->BoundingBox.Min, axidx[inidx][1]);
	}

	if((sides&3)==0)	//center x
		dx	=0;
	if((sides&0x0c)==0)	//center x
		dy	=0;

	//translate to fixed origin
	geVec3d_Inverse(&FixOrg);
	Brush_Move(b, &FixOrg);

	dx	*=0.005f;
	dy	*=0.005f;

	dx	=1-dx;
	dy	=1-dy;

	VectorToSUB(ScaleVec, inidx)			=1.0f;
	VectorToSUB(ScaleVec, axidx[inidx][0])	=dx;
	VectorToSUB(ScaleVec, axidx[inidx][1])	=dy;

	for(i=0;i<3;i++)
		VectorToSUB(*fnscale, i)	*=VectorToSUB(ScaleVec, i);

	(*ScaleNum)++;

	Brush_Scale3d(b, &ScaleVec);

	//translate back
	geVec3d_Inverse(&FixOrg);
	Brush_Move(b, &FixOrg);

	Brush_Bound(b);
}

void Brush_Bound(Brush *b)
{
	if (b == NULL)
		MessageBox(NULL, "Brush == NULL", "Brush_Bound", MB_OK);	//	post 0.55
	
	assert(b);
	
	Box3d_SetBogusBounds(&b->BoundingBox);
	if(b->Type==BRUSH_MULTI)
	{
		BrushList_GetBounds(b->BList, &b->BoundingBox);
	}
	else
	{
		FaceList_GetBounds(b->Faces, &b->BoundingBox);
	}
}

geBoolean	Brush_TestBoundsIntersect(const Brush *b, const Box3d *pBox)
{
	if (b == NULL)
		MessageBox(NULL, "Brush == NULL", "Brush_TestBoundsIntersect", MB_OK);	//	post 0.55

	if (pBox == NULL)
		MessageBox(NULL, "Box3d == NULL", "Brush_TestBoundsIntersect", MB_OK);	//	post 0.55

	assert(b);
	assert(pBox);

	return Box3d_Intersection (&b->BoundingBox, pBox, NULL);
}

/*
void Brush_SnapNearest(Brush *b, geFloat gsize, int sides, int inidx)
{
	int				i;
	geVec3d			dmin, vsnap, sbound;
	geFloat const	gsizeinv	=1.0f/(geFloat)gsize;

	//find the corner of the bounds to snap
	VectorToSUB(dmin, inidx)	=0.0f;
	if((sides&3)==0)	//center x
	{
		VectorToSUB(dmin, axidx[inidx][0])	=VectorToSUB(b->BoundingBox.Min, axidx[inidx][0]);
	}
	else if((sides&3)==1)	//less x
	{
		VectorToSUB(dmin, axidx[inidx][0])	=VectorToSUB(b->BoundingBox.Min, axidx[inidx][0]);
	}
	else if((sides&3)==2)	//greater x
	{
		VectorToSUB(dmin, axidx[inidx][0])	=VectorToSUB(b->BoundingBox.Max, axidx[inidx][0]);
	}

	if((sides&0x0c)==0)	//center y
	{
		VectorToSUB(dmin, axidx[inidx][1])	=VectorToSUB(b->BoundingBox.Min, axidx[inidx][1]);
	}
	else if((sides&0x0c)==4)	//less y
	{
		if(inidx != 1)	//check for top view (which has backwards y axis relation)
		{
			VectorToSUB(dmin, axidx[inidx][1])	=VectorToSUB(b->BoundingBox.Max, axidx[inidx][1]);
		}
		else
		{
			VectorToSUB(dmin, axidx[inidx][1])	=VectorToSUB(b->BoundingBox.Min, axidx[inidx][1]);
		}
	}
	else if((sides&0x0c)==8)	//greater y
	{
		if(inidx != 1)
		{
			VectorToSUB(dmin, axidx[inidx][1])	=VectorToSUB(b->BoundingBox.Min, axidx[inidx][1]);
		}
		else
		{
			VectorToSUB(dmin, axidx[inidx][1])	=VectorToSUB(b->BoundingBox.Max, axidx[inidx][1]);
		}
	}

	geVec3d_Scale(&dmin, gsizeinv, &sbound);	//get ratio to grid
	for(i=0;i<3;i++)
	{
		//get amount off in grid space
		VectorToSUB(vsnap, i)	=(geFloat)Units_Trunc(VectorToSUB(sbound, i));
	}
	geVec3d_Subtract(&sbound, &vsnap, &sbound);	//delta gridspace error
	geVec3d_Scale(&vsnap, gsize, &vsnap);		//return to worldspace
	geVec3d_Subtract(&dmin, &vsnap, &dmin);		//get worldspace delta

	//move to the nearest corner
	for(i=0;i<3;i++)
	{
		if(VectorToSUB(sbound, i) > 0.5f)
		{
			VectorToSUB(dmin, i)	-=gsize;
		}
		else if(VectorToSUB(sbound, i) < -0.5f)
		{
			VectorToSUB(dmin, i)	+=gsize;
		}
	}

	geVec3d_Inverse(&dmin);
	Brush_Move(b, &dmin);

	Brush_Bound(b);
}
*/

void Brush_SnapScaleNearest(Brush *b, geFloat gsize, int sides, int inidx, geVec3d *fnscale, int *ScaleNum)
{
	int		i;
	geVec3d	FixOrg, BrushOrg;
	geVec3d	dmin, vsnap, sbound;
	geFloat	const	gsizeinv	=1.0f/(geFloat)gsize;

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

	geVec3d_Add(&b->BoundingBox.Min, &b->BoundingBox.Max, &BrushOrg);
	geVec3d_Scale(&BrushOrg, 0.5f, &BrushOrg);

	//find the corner of the bounds to keep fixed
	VectorToSUB(FixOrg, inidx)			=0.0f;
	VectorToSUB(dmin, inidx)			=0.0f;
	if((sides&3)==0)
	{
		VectorToSUB(FixOrg, axidx[inidx][0])=VectorToSUB(b->BoundingBox.Min, axidx[inidx][0]);
		VectorToSUB(dmin, axidx[inidx][0])	=VectorToSUB(b->BoundingBox.Max, axidx[inidx][0]);
	}
	else if((sides&3)==2)
	{
		VectorToSUB(FixOrg, axidx[inidx][0])=VectorToSUB(b->BoundingBox.Max, axidx[inidx][0]);
		VectorToSUB(dmin, axidx[inidx][0])	=VectorToSUB(b->BoundingBox.Min, axidx[inidx][0]);
	}
	else if((sides&3)==1)
	{
		VectorToSUB(FixOrg, axidx[inidx][0])=VectorToSUB(b->BoundingBox.Min, axidx[inidx][0]);
		VectorToSUB(dmin, axidx[inidx][0])	=VectorToSUB(b->BoundingBox.Max, axidx[inidx][0]);
	}

	if((sides&0x0c)==0)
	{
		VectorToSUB(FixOrg, axidx[inidx][1])=VectorToSUB(b->BoundingBox.Min, axidx[inidx][1]);
		VectorToSUB(dmin, axidx[inidx][1])	=VectorToSUB(b->BoundingBox.Max, axidx[inidx][1]);
	}
	else if((sides&0x0c)==8)
	{
		if(inidx!=1)	//check for top view (which has backwards y axis relation)
		{
			VectorToSUB(FixOrg, axidx[inidx][1])=VectorToSUB(b->BoundingBox.Min, axidx[inidx][1]);
			VectorToSUB(dmin, axidx[inidx][1])	=VectorToSUB(b->BoundingBox.Max, axidx[inidx][1]);
		}
		else
		{
			VectorToSUB(FixOrg, axidx[inidx][1])=VectorToSUB(b->BoundingBox.Max, axidx[inidx][1]);
			VectorToSUB(dmin, axidx[inidx][1])	=VectorToSUB(b->BoundingBox.Min, axidx[inidx][1]);
		}
	}
	else if((sides&0x0c)==4)
	{
		if(inidx!=1)
		{
			VectorToSUB(FixOrg, axidx[inidx][1])=VectorToSUB(b->BoundingBox.Max, axidx[inidx][1]);
			VectorToSUB(dmin, axidx[inidx][1])	=VectorToSUB(b->BoundingBox.Min, axidx[inidx][1]);
		}
		else
		{
			VectorToSUB(FixOrg, axidx[inidx][1])=VectorToSUB(b->BoundingBox.Min, axidx[inidx][1]);
			VectorToSUB(dmin, axidx[inidx][1])	=VectorToSUB(b->BoundingBox.Max, axidx[inidx][1]);
		}
	}

	geVec3d_Scale(&FixOrg, gsizeinv, &sbound);

	for(i=0;i<3;i++)
	{
		VectorToSUB(vsnap, i)	=(geFloat)Units_Trunc(VectorToSUB(sbound, i));
	}

	geVec3d_Subtract(&sbound, &vsnap, &sbound);
	geVec3d_Scale(&vsnap, gsize, &vsnap);
	geVec3d_Subtract(&FixOrg, &dmin, &FixOrg);
	geVec3d_Subtract(&vsnap, &dmin, &vsnap);

	for(i=0;i<3;i++)
	{
		if(VectorToSUB(sbound, i) > 0.5f)
		{
			VectorToSUB(vsnap, i)	+=gsize;
		}
		else if(VectorToSUB(sbound, i) < -0.5f)
		{
			VectorToSUB(vsnap, i)	-=gsize;
		}
	}

	//find the magnitude to expand onto the boundary
	for(i=0;i<3;i++)
	{
		if(VectorToSUB(FixOrg, i))
		{
			VectorToSUB(sbound, i)	=(1.0f - (VectorToSUB(vsnap, i) / VectorToSUB(FixOrg, i)))* 200.0f;
		}
	}
	if((sides&3)==1)
	{
		VectorToSUB(sbound, axidx[inidx][0])=-VectorToSUB(sbound, axidx[inidx][0]);
	}
	if((sides&0x0c)==4)
	{
		VectorToSUB(sbound, axidx[inidx][1])=-VectorToSUB(sbound, axidx[inidx][1]);
	}

	Brush_Resize(b, VectorToSUB(sbound, axidx[inidx][0]), VectorToSUB(sbound, axidx[inidx][1]), sides, inidx, fnscale, ScaleNum);

	Brush_Bound(b);
}

void Brush_ResizeFinal(Brush *b, int sides, int inidx, geVec3d *fnscale)
{
	geVec3d	FixOrg, BrushOrg;

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

	geVec3d_Add(&b->BoundingBox.Min, &b->BoundingBox.Max, &BrushOrg);
	geVec3d_Scale(&BrushOrg, 0.5f, &BrushOrg);

	//find the corner of the bounds to keep fixed
	VectorToSUB(FixOrg, inidx)			=0.0f;
	if((sides&3)==0)	//center x
	{
		VectorToSUB(FixOrg, axidx[inidx][0])	=VectorToSUB(BrushOrg, axidx[inidx][0]);
	}
	else if((sides&3)==2)	//less x
	{
		VectorToSUB(FixOrg, axidx[inidx][0])	=VectorToSUB(b->BoundingBox.Min, axidx[inidx][0]);
	}
	else if((sides&3)==1)	//greater x
	{
		VectorToSUB(FixOrg, axidx[inidx][0])	=VectorToSUB(b->BoundingBox.Max, axidx[inidx][0]);
	}

	if((sides&0x0c)==0)	//center y
	{
		VectorToSUB(FixOrg, axidx[inidx][1])	=VectorToSUB(BrushOrg, axidx[inidx][1]);
	}
	else if((sides&0x0c)==4)	//less y
	{
		if(inidx!=1)
		{
			VectorToSUB(FixOrg, axidx[inidx][1])	=VectorToSUB(b->BoundingBox.Min, axidx[inidx][1]);
		}
		else
		{
			VectorToSUB(FixOrg, axidx[inidx][1])	=VectorToSUB(b->BoundingBox.Max, axidx[inidx][1]);
		}
	}
	else if((sides&0x0c)==8)	//greater y
	{
		if(inidx!=1)
		{
			VectorToSUB(FixOrg, axidx[inidx][1])	=VectorToSUB(b->BoundingBox.Max, axidx[inidx][1]);
		}
		else
		{
			VectorToSUB(FixOrg, axidx[inidx][1])	=VectorToSUB(b->BoundingBox.Min, axidx[inidx][1]);
		}
	}

	if((sides&3)==0)	//center x
	{
		VectorToSUB(*fnscale, axidx[inidx][0])	=1.0f;
	}

	if((sides&0x0c)==0)	//center y
	{
		VectorToSUB(*fnscale, axidx[inidx][1])	=1.0f;
	}

	//translate to fixed origin
	geVec3d_Inverse(&FixOrg);
	Brush_Move(b, &FixOrg);

	VectorToSUB(*fnscale, inidx)	=1.0f;

	Brush_Scale3d(b, fnscale);

	//translate back
	geVec3d_Inverse(&FixOrg);
	Brush_Move(b, &FixOrg);

	Brush_Bound(b);
}

void	Brush_ShearFinal(Brush *b, int sides, int inidx, geVec3d *fnscale)
{
	geVec3d	FixOrg, BrushOrg, ShearAxis;

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

	assert(b);
	assert(fnscale);

	if(!(((sides&3)==0) ^ ((sides&0x0c)==0)))
	{
		return;
	}

	geVec3d_Add(&b->BoundingBox.Min, &b->BoundingBox.Max, &BrushOrg);
	geVec3d_Scale(&BrushOrg, 0.5f, &BrushOrg);

	//find the corner of the bounds to keep fixed
	VectorToSUB(FixOrg, inidx)			=0.0f;
	if((sides&3)==0)	//center x
	{
		VectorToSUB(FixOrg, axidx[inidx][0])	=VectorToSUB(BrushOrg, axidx[inidx][0]);
	}
	else if((sides&3)==2)	//less x
	{
		VectorToSUB(FixOrg, axidx[inidx][0])	=VectorToSUB(b->BoundingBox.Min, axidx[inidx][0]);
	}
	else if((sides&3)==1)	//greater x
	{
		VectorToSUB(FixOrg, axidx[inidx][0])	=VectorToSUB(b->BoundingBox.Max, axidx[inidx][0]);
	}

	if((sides&0x0c)==0)	//center y
	{
		VectorToSUB(FixOrg, axidx[inidx][1])	=VectorToSUB(BrushOrg, axidx[inidx][1]);
	}
	else if((sides&0x0c)==4)	//less y
	{
		if(inidx!=1)
			VectorToSUB(FixOrg, axidx[inidx][1])	=VectorToSUB(b->BoundingBox.Min, axidx[inidx][1]);
		else
			VectorToSUB(FixOrg, axidx[inidx][1])	=VectorToSUB(b->BoundingBox.Max, axidx[inidx][1]);
	}
	else if((sides&0x0c)==8)	//greater y
	{
		if(inidx!=1)
			VectorToSUB(FixOrg, axidx[inidx][1])	=VectorToSUB(b->BoundingBox.Max, axidx[inidx][1]);
		else
			VectorToSUB(FixOrg, axidx[inidx][1])	=VectorToSUB(b->BoundingBox.Min, axidx[inidx][1]);
	}

	geVec3d_Clear(&ShearAxis);

	//translate to fixed origin
	geVec3d_Inverse(&FixOrg);
	Brush_Move(b, &FixOrg);

	if((sides&3)==0)	//center x
	{
		VectorToSUB(ShearAxis, axidx[inidx][0])	=
			1.0f / VectorToSUB(b->BoundingBox.Max, axidx[inidx][0]);
	}

⌨️ 快捷键说明

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