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

📄 box3d.c

📁 3D游戏场景编辑器
💻 C
字号:
/****************************************************************************************/
/*  box3d.c                                                                             */
/*                                                                                      */
/*  Author:       Jim Mischel                                                           */
/*  Description:  Bounding box related stuff                                            */
/*                                                                                      */
/*  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 "box3d.h"
#include <windows.h>	//	post 0.55
#include <Winuser.h>	//	post 0.55
#include <assert.h>
#include <float.h>
#include <stdlib.h>


void Box3d_Clear( Box3d *b)
{
	if (b == NULL)
		MessageBox(NULL, "Box == NULL", "Box3d_Clear", MB_OK);	//	post 0.55

	assert (b != NULL);

	Box3d_Set (b, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
}

void Box3d_SetBogusBounds(Box3d *b)
{

	if (b == NULL)
		MessageBox(NULL, "Box == NULL", "Box3d_SetBogusBounds", MB_OK);	//	post 0.55

	assert (b != NULL);

	geVec3d_Set (&b->Min, FLT_MAX, FLT_MAX, FLT_MAX);
	geVec3d_Set (&b->Max, -FLT_MAX, -FLT_MAX, -FLT_MAX);
}


void Box3d_Set(Box3d *b,
	  geFloat x1,
	  geFloat y1,
	  geFloat z1,
	  geFloat x2,
	  geFloat y2,
	  geFloat z2
	)
{
	if (b == NULL)
		MessageBox(NULL, "Box == NULL", "Box3d_Set", MB_OK);	//	post 0.55

	assert (b != NULL);

	geVec3d_Set 
	(
		&b->Min, 
		min (x1, x2),
		min (y1, y2),
		min (z1, z2)
	);
	geVec3d_Set
	(
		&b->Max,
		max (x1, x2),
		max (y1, y2),
		max (z1, z2)
	);
}

void Box3d_SetSize
	(
	  Box3d *b,
	  geFloat sx,
	  geFloat sy,
	  geFloat sz
	)
{
	// don't allow boxes with negative bounds...
	assert (sx >= 0.0f);
	assert (sy >= 0.0f);
	assert (sz >= 0.0f);

	Box3d_Set (b, -sx/2, -sy/2, -sz/2, sx/2, sy/2, sz/2);
}

void Box3d_AddPoint
	(
	  Box3d *b,
	  geFloat px,
	  geFloat py,
	  geFloat pz
	)
{
	if (b == NULL)
		MessageBox(NULL, "Box == NULL", "Box3d_AddPoint", MB_OK);	//	post 0.55

	if (px < b->Min.X) b->Min.X = px;
	if (px > b->Max.X) b->Max.X = px;
	if (py < b->Min.Y) b->Min.Y = py;
	if (py > b->Max.Y) b->Max.Y = py;
	if (pz < b->Min.Z) b->Min.Z = pz;
	if (pz > b->Max.Z) b->Max.Z = pz;
}

//#ifndef NDEBUG	//	post 0.55 //	commented out
static geBoolean Box3d_IsValid
	(
	  const Box3d *b
	)
{
	if (b == NULL)
	{
		MessageBox(NULL, "Box == NULL", "Box3d_IsValid", MB_OK);	//	post 0.55
		return GE_FALSE;
	}

	assert (b != NULL);

	return ((b->Min.X <= b->Max.X) &&
			(b->Min.Y <= b->Max.Y) &&
			(b->Min.Z <= b->Max.Z));
}
//#endif

static geBoolean Box3d_Intersects
	(
	  const Box3d *b1,
	  const Box3d *b2
	)
{
	if (b1 == NULL)
	{
		MessageBox(NULL, "Box1 == NULL", "Box3d_Intersects", MB_OK);	//	post 0.55
		return GE_FALSE;
	}
	
	if (b2 == NULL)
	{
		MessageBox(NULL, "Box2 == NULL", "Box3d_Intersects", MB_OK);	//	post 0.55
		return GE_FALSE;
	}
		
	if (!Box3d_IsValid(b1))
	{
		MessageBox(NULL, "Box1 is not Valid", "Box3d_Intersects", MB_OK);	//	post 0.55
		return GE_FALSE;
	}

	if (!Box3d_IsValid (b2))
	{
		MessageBox(NULL, "Box2 is not Valid", "Box3d_Intersects", MB_OK);	//	post 0.55
		return GE_FALSE;
	}
	
	assert (Box3d_IsValid (b1));
	assert (Box3d_IsValid (b2));

	if ((b1->Min.X > b2->Max.X) || (b1->Max.X < b2->Min.X)) return GE_FALSE;
	if ((b1->Min.Y > b2->Max.Y) || (b1->Max.Y < b2->Min.Y)) return GE_FALSE;
	if ((b1->Min.Z > b2->Max.Z) || (b1->Max.Z < b2->Min.Z)) return GE_FALSE;

	return GE_TRUE;
}

geBoolean Box3d_Intersection
	(
	  const Box3d *b1,
	  const Box3d *b2,
	  Box3d *bResult
	)
{
	geBoolean rslt;

	if (b1 == NULL)
	{
		MessageBox(NULL, "Box1 == NULL", "Box3d_Intersection", MB_OK);	//	post 0.55
		return GE_FALSE;
	}

	if (b2 == NULL)
	{
		MessageBox(NULL, "Box2 == NULL", "Box3d_Intersection", MB_OK);	//	post 0.55
		return GE_FALSE;
	}

	if (!Box3d_IsValid (b1))
	{
		MessageBox(NULL, "Box1 is not Valid", "Box3d_Intersects", MB_OK);	//	post 0.55
		return GE_FALSE;
	}

	if (!Box3d_IsValid (b2))
	{
		MessageBox(NULL, "Box2 is not Valid", "Box3d_Intersects", MB_OK);	//	post 0.55
		return GE_FALSE;
	}

	assert (Box3d_IsValid (b1));
	assert (Box3d_IsValid (b2));

	rslt = Box3d_Intersects (b1, b2);
	if (rslt && (bResult != NULL))
	{
		Box3d_Set
		(
			bResult,
			max (b1->Min.X, b2->Min.X),
			max (b1->Min.Y, b2->Min.Y),
			max (b1->Min.Z, b2->Min.Z),
			min (b1->Max.X, b2->Max.X),
			min (b1->Max.Y, b2->Max.Y),
			min (b1->Max.Z, b2->Max.Z)
		);
	}
	return rslt;
}

void Box3d_Union
	(
	  const Box3d *b1,
	  const Box3d *b2,
	  Box3d *bResult
	)
{
	assert (Box3d_IsValid (b1));
	assert (Box3d_IsValid (b2));
	assert (bResult != NULL);

	Box3d_Set
	(
		bResult,
		min (b1->Min.X, b2->Min.X),
		min (b1->Min.Y, b2->Min.Y),
		min (b1->Min.Z, b2->Min.Z),
		max (b1->Max.X, b2->Max.X),
		max (b1->Max.Y, b2->Max.Y),
		max (b1->Max.Z, b2->Max.Z)
	);
}

geBoolean Box3d_ContainsPoint
	(
	  const Box3d *b,
	  geFloat px,
	  geFloat py,
	  geFloat pz
	)
{
	if (b == NULL)
		MessageBox(NULL, "Box == NULL", "Box3d_ContainsPoint", MB_OK);	//	post 0.55

	assert (Box3d_IsValid (b));

	return ((px >= b->Min.X) && (px <= b->Max.X) &&
			(py >= b->Min.Y) && (py <= b->Max.Y) &&
			(pz >= b->Min.Z) && (pz <= b->Max.Z));
}

const geVec3d *Box3d_GetMin
	(
	  const Box3d *b
	)
{
	if (b == NULL)
		MessageBox(NULL, "Box == NULL", "Box3d_GetMin", MB_OK);	//	post 0.55

	assert (Box3d_IsValid (b));

	return &b->Min;
}

const geVec3d *Box3d_GetMax
	(
	  const Box3d *b
	)
{
	if (b == NULL)
		MessageBox(NULL, "Box == NULL", "Box3d_GetMax", MB_OK);	//	post 0.55

	assert (Box3d_IsValid (b));

	return &b->Max;
}

void Box3d_GetCenter
	(
	  const Box3d *b,
	  geVec3d *pCenter
	)
{
	if (b == NULL)
		MessageBox(NULL, "Box == NULL", "Box3d_GetCenter", MB_OK);	//	post 0.55

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

	geVec3d_Set 
	(
		pCenter,
		(b->Min.X + b->Max.X)/2,
		(b->Min.Y + b->Max.Y)/2,
		(b->Min.Z + b->Max.Z)/2
	);
}

geFloat Box3d_GetWidth
	(
	  const Box3d *b
	)
{
	if (b == NULL)
		MessageBox(NULL, "Box == NULL", "Box3d_GetWidth", MB_OK);	//	post 0.55

	assert (Box3d_IsValid (b));

	return (b->Max.X - b->Min.X + 1);
}

geFloat Box3d_GetHeight
	(
	  const Box3d *b
	)
{
	if (b == NULL)
		MessageBox(NULL, "Box == NULL", "Box3d_GetHeight", MB_OK);	//	post 0.55

	
	assert (Box3d_IsValid (b));

	return (b->Max.Y - b->Min.Y + 1);
}

geFloat Box3d_GetDepth
	(
	  const Box3d *b
	)
{
	if (b == NULL)
		MessageBox(NULL, "Box == NULL", "Box3d_GetDepth", MB_OK);	//	post 0.55

	assert (Box3d_IsValid (b));

	return (b->Max.Z - b->Min.Z + 1);
}

void Box3d_GetSize
	(
	  const Box3d *b,
	  geVec3d *pSize
	)
{
	if (b == NULL)
		MessageBox(NULL, "Box == NULL", "Box3d_GetSize", MB_OK);	//	post 0.55

	assert (Box3d_IsValid (b));
	assert (pSize != NULL);

	geVec3d_Set
	(
	  pSize,
	  (b->Max.X - b->Min.X + 1),
	  (b->Max.Y - b->Min.Y + 1),
	  (b->Max.Z - b->Min.Z + 1)
	);
}

void Box3d_Scale
	(
	  Box3d *b,
	  geFloat Scale
	)
{
	if (b == NULL)
		MessageBox(NULL, "Box == NULL", "Box3d_Scale", MB_OK);	//	post 0.55

	assert (Box3d_IsValid (b));
	assert (Scale >= 0.0f);

	geVec3d_Scale (&b->Min, Scale, &b->Min);
	geVec3d_Scale (&b->Max, Scale, &b->Max);

	assert (Box3d_IsValid (b));
}

void Box3d_Move
	(
	  Box3d *b,
	  geFloat dx,
	  geFloat dy,
	  geFloat dz
	)
{
	geVec3d VecDelta;

	if (b == NULL)
		MessageBox(NULL, "Box == NULL", "Box3d_Move", MB_OK);	//	post 0.55

	assert (Box3d_IsValid (b));

	geVec3d_Set (&VecDelta, dx, dy, dz);
	geVec3d_Add (&b->Min, &VecDelta, &b->Min);
	geVec3d_Add (&b->Max, &VecDelta, &b->Max);
}

void Box3d_Inflate
	(
	  Box3d *b,
	  geFloat dx,
	  geFloat dy,
	  geFloat dz
	)
{
	geVec3d VecDelta;

	if (b == NULL)
		MessageBox(NULL, "Box == NULL", "Box3d_Inflate", MB_OK);	//	post 0.55
	
	assert (Box3d_IsValid (b));

	geVec3d_Set (&VecDelta, dx, dy, dz);
	geVec3d_Subtract (&b->Min, &VecDelta, &b->Min);
	geVec3d_Add (&b->Max, &VecDelta, &b->Max);

	assert (Box3d_IsValid (b));
}

⌨️ 快捷键说明

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