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

📄 brush.cpp

📁 3D游戏场景编辑器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	if((sides&0x0c)==0)	//center y
	{
		VectorToSUB(ShearAxis, axidx[inidx][1])	=
			1.0f / VectorToSUB(b->BoundingBox.Max, axidx[inidx][1]);
	}

	Brush_Shear(b, fnscale, &ShearAxis);

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

	Brush_Bound(b);
}

// moves the passed in brush by the vector specified in trans
void	Brush_Move(Brush *b,  const geVec3d *trans)
{
	if (b == NULL)
		MessageBox(NULL, "Brush == NULL", "Brush_Move", MB_OK);	//	post 0.55

	assert(b && trans);

	if(b->Type==BRUSH_MULTI)
	{
		BrushList_Move(b->BList, trans);
	}
	else
	{
		FaceList_Move(b->Faces, trans);
	}

	Brush_Bound(b);
}

void	Brush_Rotate
	(
	  Brush *b,
	  const geXForm3d *pXfmRotate,
	  const geVec3d *pCenter
	)
{
	if (b == NULL)
		MessageBox(NULL, "Brush == NULL", "Brush_Rotate", MB_OK);	//	post 0.55

	assert (b != NULL);
	assert (pXfmRotate != NULL);
	assert (pCenter != NULL);

	if(b->Type==BRUSH_MULTI)
	{
		BrushList_Rotate(b->BList, pXfmRotate, pCenter);
	}
	else
	{
		FaceList_Rotate(b->Faces, pXfmRotate, pCenter);
	}

	Brush_Bound (b);
}

void	Brush_Transform 
	(
	  Brush *b, 
	  const geXForm3d *pXfm
	)
// Apply the transform to all points in all brush faces
{
	if (b == NULL)
		MessageBox(NULL, "Brush == NULL", "Brush_Transform", MB_OK);	//	post 0.55

	assert (b != NULL);
	assert (pXfm != NULL);

	if(b->Type==BRUSH_MULTI)
	{
		BrushList_Transform(b->BList, pXfm);
	}
	else
	{
		FaceList_Transform(b->Faces, pXfm);
	}

	Brush_Bound(b);
}

// calculates relative "center" of brush by finding midpoint between min and max
void	Brush_Center(const Brush *b, geVec3d *center)
{
	if (b == NULL)
		MessageBox(NULL, "Brush == NULL", "Brush_Center", MB_OK);	//	post 0.55

	assert(b && center);

	Box3d_GetCenter (&b->BoundingBox, center);
}

void	Brush_Scale (Brush *b, float ScaleFactor)
{

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

	assert (b != NULL);

	b->HullSize	*= ScaleFactor;
	if (b->Type == BRUSH_MULTI)
	{
		BrushList_Scale (b->BList, ScaleFactor);
	}
	else
	{
		geVec3d vecScale;

		geVec3d_Set (&vecScale, ScaleFactor, ScaleFactor, ScaleFactor);
		FaceList_Scale (b->Faces, &vecScale);
	}
	Brush_Bound (b);
}

void	Brush_Scale3d(Brush *b, const geVec3d *mag)
{
	if (b == NULL)
		MessageBox(NULL, "Brush == NULL", "Brush_Scale3d", MB_OK);	//	post 0.55

	assert(b);
	assert(mag);

	if(b->Type==BRUSH_MULTI)
	{
		BrushList_Scale3d(b->BList, mag);
	}
	else
	{
		FaceList_Scale(b->Faces, mag);
	}

	Brush_Bound(b);
}

void	Brush_Shear(Brush *b, const geVec3d *ShearVec, const geVec3d *ShearAxis)
{
	if (b == NULL)
		MessageBox(NULL, "Brush == NULL", "Brush_Shear", MB_OK);	//	post 0.55

	if (ShearVec == NULL)
		MessageBox(NULL, "ShearVec == NULL", "Brush_Shear", MB_OK);	//	post 0.55

	if (ShearAxis == NULL)
		MessageBox(NULL, "ShearAxis == NULL", "Brush_Shear", MB_OK);	//	post 0.55


	assert(b);
	assert(ShearVec);
	assert(ShearAxis);

	if(b->Type==BRUSH_MULTI)
	{
		BrushList_Shear(b->BList, ShearVec, ShearAxis);
	}
	else
	{
		FaceList_Shear(b->Faces, ShearVec, ShearAxis);
	}
	Brush_Bound(b);
}

Face	*Brush_RayCast(const Brush *b, geVec3d *CamOrg, geVec3d *dir, geFloat *dist)
{
	Face		*f, *firstface;
	geVec3d		p1, p2;
	geFloat		mid, d1, d2;
	int32		i;
	const Plane	*p;
	geFloat		minBDist;
	Face		*curFace	=NULL;
	const Brush	*b2;

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

	minBDist	=999999.0f;

	//this multi section isn't used currently
	//but might be needed later
	if(b->Type & BRUSH_MULTI)
	{
		for(b2=b->BList->First;b2;b2=b2->Next)
		{
			if(!(b2->Flags & BRUSH_SUBTRACT))
			{
				f	=Brush_RayCast(b2, CamOrg, dir, dist);
				if(f)
				{
					if((*dist >= 8.0f) && (*dist < minBDist))
					{ 
						minBDist	=*dist;
						curFace		=f;
					}
				}
			}
		}
		if(curFace)
		{
			*dist	=minBDist;
			return	curFace;
		}
		else
		{
			*dist	=0;
			return	NULL;
		}
	}

	geVec3d_Copy(CamOrg, &p1);
	geVec3d_AddScaled (&p1, dir, 2*BOGUS_RANGE, &p2);

	firstface	=NULL;

	assert(!(b->Flags & BRUSH_SUBTRACT));

	for(i=0;i < FaceList_GetNumFaces(b->Faces);i++)
	{
		geVec3d tempVec;

		f	=FaceList_GetFace(b->Faces, i);
		p	=Face_GetPlane(f);

		d1	=geVec3d_DotProduct(&p1, &p->Normal)	-p->Dist;
		d2	=geVec3d_DotProduct(&p2, &p->Normal)	-p->Dist;
		if(d1 >= 0 && d2 >= 0)
		{
			*dist	=0;
			return	NULL;
		}
		if(d1 <=0 && d2 <= 0)
			continue;

		mid	=d1 / (d1 - d2);

		geVec3d_Subtract (&p2, &p1, &tempVec);
		geVec3d_AddScaled (&p1, &tempVec, mid, &tempVec);
		if (d1 > 0)
		{
			firstface = f;
			p1 = tempVec;
		}
		else
		{
			p2 = tempVec;
		}
	}
	geVec3d_Subtract(&p1, CamOrg, &p1);

	d1		=geVec3d_DotProduct(&p1, dir);
	*dist	=d1;

	return	firstface;
}



/*******************************************************************/
/**************  BRUSH LIST HANDLERS *******************************/
/*******************************************************************/

BrushList *BrushList_Create 
	(
	  void
	)
{
	BrushList *pList;

	pList = (BrushList*)geRam_Allocate (sizeof (BrushList));
	if (pList != NULL)
	{
		pList->First = NULL;
		pList->Last = NULL;
	}
	return pList;
}

BrushList *BrushList_CreateFromFile 
	(
	  Parse3dt *Parser, 
	  int VersionMajor, 
	  int VersionMinor, 
	  const char **Expected
	)
{
	int NumBrushes;
	BrushList *blist;

	if (!Parse3dt_GetInt (Parser, (*Expected = "Brushlist"), &NumBrushes)) return NULL;
	blist = BrushList_Create ();
	if (blist != NULL)
	{
		int i;

		for (i = 0; i < NumBrushes; ++i)
		{
			Brush *pBrush;

			pBrush = Brush_CreateFromFile (Parser, VersionMajor, VersionMinor, Expected);
			if (pBrush == NULL)
			{
				BrushList_Destroy (&blist);
				break;
			}
			else
			{
				BrushList_Append (blist, pBrush);
			}
		}
	}
	return blist;
}

void BrushList_Destroy 
	(
	  BrushList **ppList
	)
{
	BrushList *pList;

	if (ppList == NULL)		//	post 0.55
	{
		MessageBox(NULL, "ppList == NULL", "BrushList_Destroy", MB_OK);
		return;
	}

	if (*ppList == NULL)		//	post 0.55
	{
		MessageBox(NULL, "*ppList == NULL", "BrushList_Destroy", MB_OK);
		return;
	}

	assert (ppList != NULL);
	assert (*ppList != NULL);

	pList = *ppList;
	BrushList_DeleteAll (pList);

	geRam_Free (*ppList);
	*ppList = NULL;
}

void BrushList_Append 
	(
	  BrushList *pList, 
	  Brush *pBrush
	)
{
	if (pList == NULL)		//	post 0.55
	{
		MessageBox(NULL, "pList == NULL", "BrushList_Append", MB_OK);
		return;
	}

	if (pBrush == NULL)		//	post 0.55
	{
		MessageBox(NULL, "pBrush == NULL", "BrushList_Append", MB_OK);
		return;
	}
	
	
	assert (pList != NULL);
	assert (pBrush != NULL);

	if (pList->First == NULL)
	{
		// the list is empty
		assert (pList->Last == NULL);
		pList->First = pBrush;
		pList->Last = pBrush;
		pBrush->Next = NULL;
		pBrush->Prev = NULL;
	}
	else
	{
		// add it to the end of the list
		assert (pList->Last != NULL);
		assert (pList->Last->Next == NULL);

		pBrush->Next = NULL;			// it's the end of the list
		pBrush->Prev = pList->Last;		// point back to previous end
		pList->Last->Next = pBrush;		// previous end points to me
		pList->Last = pBrush;			// and we're now the list end
	}
}

//insert pbrush into the list after pBMarker
//went nuts on asserts here, but maybe they will save us someday
void BrushList_InsertAfter(BrushList *pList, Brush *pBMarker, Brush *pBrush)
{
	if (pList == NULL)		//	post 0.55
	{
		MessageBox(NULL, "pList == NULL", "BrushList_InsertAfter", MB_OK);
		return;
	}

	if (pBrush == NULL)		//	post 0.55
	{
		MessageBox(NULL, "pBrush == NULL", "BrushList_InsertAfter", MB_OK);
		return;
	}
	
	assert (pList != NULL);
	assert (pBMarker != NULL);
	assert (pBrush != NULL);
	assert (pList->First != NULL); //must be at least one
	assert (pList->Last != NULL);
	assert (pList->Last->Next == NULL);

	pBrush->Next	=pBMarker->Next;
	pBrush->Prev	=pBMarker;

	if(pBrush->Next==NULL)	//last in list?
	{
		pList->Last	=pBrush;
	}
	else
	{
		pBrush->Next->Prev	=pBrush;
	}
	pBMarker->Next	=pBrush;
}

//insert pbrush into the list before pBMarker
void BrushList_InsertBefore(BrushList *pList, Brush *pBMarker, Brush *pBrush)
{
	if (pList == NULL)		//	post 0.55
	{
		MessageBox(NULL, "pList == NULL", "BrushList_InsertBefore", MB_OK);
		return;
	}

	if (pBrush == NULL)		//	post 0.55
	{
		MessageBox(NULL, "pBrush == NULL", "BrushList_InsertBefore", MB_OK);
		return;
	}
	
	
	assert (pList != NULL);
	assert (pBMarker != NULL);
	assert (pBrush != NULL);
	assert (pList->First != NULL); //must be at least one
	assert (pList->Last != NULL);
	assert (pList->Last->Next == NULL);

	pBrush->Prev	=pBMarker->Prev;
	pBrush->Next	=pBMarker;

	if(pBrush->Prev==NULL)	//first in list?
	{
		pList->First	=pBrush;
	}
	else
	{
		pBrush->Prev->Next	=pBrush;
	}
	pBMarker->Prev	=pBrush;
}

void BrushList_Prepend 
	(
	  BrushList *pList, 
	  Brush *pBrush
	)
{
	if (pList == NULL)		//	post 0.55
	{
		MessageBox(NULL, "pList == NULL", "BrushList_Prepend", MB_OK);
		return;
	}

	if (pBrush == NULL)		//	post 0.55
	{
		MessageBox(NULL, "pBrush == NULL", "BrushList_Prepend", MB_OK);
		return;
	}
		
	assert (pList != NULL);
	assert (pBrush != NULL);

	if (pList->First == NULL)
	{
		// it's the first brush in the list
		assert (pList->Last == NULL);
		pList->First = pBrush;
		pList->Last = pBrush;
		pBrush->Next = NULL;
		pBrush->Prev = NULL;
	}
	else
	{
		// put it at the head of the list
		assert (pList->Last != NULL);
		assert (pList->First->Prev == NULL);

		pBrush->Prev = NULL;			// nothing before me
		pBrush->Next = pList->First;	// point to previous head
		pList->First->Prev = pBrush;	// previous head points to me
		pList->First = pBrush;			// and now we're the head of the list
	}
}

void BrushList_Remove 
	(
	  BrushList *pList, 
	  Brush *pBrush
	)
{
	Brush *pPrev;
	Brush *pNext;

	if (pList == NULL)		//	post 0.55
	{
		MessageBox(NULL, "pList == NULL", "BrushList_Remove", MB_OK);
		return;
	}

	if (pBrush == NULL)		//	post 0.55
	{
		MessageBox(NULL, "pBrush == NULL", "BrushList_Remove", MB_OK);
		return;
	}
	
	assert (pList != NULL);
	assert (pBrush != NULL);
	assert (pBrush->Prev != pBrush);

	pPrev = pBrush->Prev;
	pNext = pBrush->Next;

	// unlink the brush from the list
	pBrush->Prev = NULL;
	pBrush->Next = NULL;

	// update neighbors' previous/next links
	if (pPrev != NULL)
	{
		pPrev->Next = pNext;
	}
	if (pNext != NULL)
	{
		pNext->Prev = pPrev;
	}

	// if this is the first brush in the list,
	// then update the First pointer
	if (pList->First == pBrush)
	{
		assert (pPrev == NULL);
		pList->First = pNext;
	}
	// if it's the last brush in the list,
	// then update the Last pointer
	if (pList->Last == pBrush)
	{
		assert (pNext == NULL);
		pList->Last = pPrev;
	}
}

void BrushList_DeleteAll
	(
	  BrushList *pList
	)
{
	Brush *pBrush;
	BrushIterator bi;

	if (pList == NULL)		//	post 0.55
	{
		MessageBox(NULL, "pList == NULL", "BrushList_DeleteAll", MB_OK);
		return;
	}

	assert (pList != NULL);

	pBrush = BrushList_GetFirst (pList, &bi);

⌨️ 快捷键说明

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