示例#1
0
/*******************************
 * For the binder construction *
 *******************************/
void binder_geo_nappe (GEO *Generic, INDEX *Index, VECTOR *Min, VECTOR *Max, void **Info)
{
  GEO_NAPPE   *Geo;
  FCT         *Fct;
  PNT         *Pnt;

  Geo = (GEO_NAPPE *) Generic;

  if (*Index == 0)
    *Index = Geo->NbrFct;
  *Index -= 1;
  Fct = Geo->TabFct + *Index;
  *Info = Fct;
  Min->x = Min->y = Min->z = INFINITY;
  Max->x = Max->y = Max->z = -INFINITY;
  Pnt = Geo->TabPnt + Fct->i;
  VEC_MIN (*Min, Pnt->Point);
  VEC_MAX (*Max, Pnt->Point);
  Pnt = Geo->TabPnt + Fct->j;
  VEC_MIN (*Min, Pnt->Point);
  VEC_MAX (*Max, Pnt->Point);
  Pnt = Geo->TabPnt + Fct->k;
  VEC_MIN (*Min, Pnt->Point);
  VEC_MAX (*Max, Pnt->Point);
  Pnt = Geo->TabPnt + Fct->l;
  VEC_MIN (*Min, Pnt->Point);
  VEC_MAX (*Max, Pnt->Point);
}
示例#2
0
/*****************************************
 * Read nappe characterization in a file *
 *****************************************/
GEO *
file_geo_nappe (BYTE Type, FILE *File)
{
  GEO_NAPPE  *Geo;
  PNT        *Pnt, *PntA, *PntB, *PntC, *PntD;
  FCT        *Fct;
  VECTOR     U, V;
  REAL       Real;
  INDEX      Index;

  INIT_MEM (Geo, 1, GEO_NAPPE);
  Geo->Type = Type;
  GET_INDEX (Geo->NbrPnt);
  INIT_MEM (Geo->TabPnt, Geo->NbrPnt, PNT);
  GET_INDEX (Geo->NbrFct);
  INIT_MEM (Geo->TabFct, Geo->NbrFct, FCT);
  Geo->Min.x = Geo->Min.y = Geo->Min.z =  INFINITY;
  Geo->Max.x = Geo->Max.y = Geo->Max.z = -INFINITY;

  for (Index = 0, Pnt = Geo->TabPnt; Index < Geo->NbrPnt; Index++, Pnt++) {
    GET_VECTOR (Pnt->Point);
    VEC_MIN (Geo->Min, Pnt->Point);
    VEC_MAX (Geo->Max, Pnt->Point);
  }

  for (Index = 0, Fct = Geo->TabFct; Index < Geo->NbrFct; Index++, Fct++) {
    if (fscanf (File, " ( %d %d %d %d )", &Fct->i, &Fct->j, &Fct->k, &Fct->l) < 4)
      return (FALSE);
    Fct->NumFct = Index;
    PntA = Geo->TabPnt + Fct->i; 
    PntB = Geo->TabPnt + Fct->j;
    PntC = Geo->TabPnt + Fct->k;
    PntD = Geo->TabPnt + Fct->l;
    VEC_SUB (U, PntC->Point, PntA->Point);
    VEC_SUB (V, PntD->Point, PntB->Point);
    VEC_CROSS (Fct->Normal, U, V);
    VEC_UNIT (Fct->Normal, Real);
    VEC_INC (PntA->Normal, Fct->Normal);
    VEC_INC (PntB->Normal, Fct->Normal);
    VEC_INC (PntC->Normal, Fct->Normal);
    VEC_INC (PntD->Normal, Fct->Normal);
  }

  for (Index = 0, Pnt = Geo->TabPnt; Index < Geo->NbrPnt; Index++, Pnt++)
    VEC_UNIT (Pnt->Normal, Real);

  return ((GEO *) Geo);
}
示例#3
0
LTVector d3d_GetDims_PolyGrid(LTObject *pObject)
{
	//shortcut for most polygrids
	if(pObject->m_Rotation.IsIdentity())
		return pObject->m_Dims;

	//determine the orientation vectors
	LTVector vUp		= pObject->m_Rotation.Up();
	LTVector vRight		= pObject->m_Rotation.Right();
	LTVector vForward	= pObject->m_Rotation.Forward();

	//little array to help sign switching
	static const float knSign[] = {-1.0f, 1.0f};

	LTVector vDims(0, 0, 0);

	//and now run through and generate 8 box points and determine the extents
	for(uint32 nCurrPt = 0; nCurrPt < 8; nCurrPt++)
	{
		//this is a bit ugly, but essentially it just has a sin wave for the sign coefficients
		//each at a different octave which will thus hit each combination of +1/-1 and create
		//all possible combinations
		LTVector vPt =  (vRight		* pObject->m_Dims.x	* knSign[(nCurrPt / 1) % 2]) +
						(vUp		* pObject->m_Dims.y	* knSign[(nCurrPt / 2) % 2]) +
						(vForward	* pObject->m_Dims.z	* knSign[(nCurrPt / 4) % 2]);
		
		//now make it absolute
		vPt.x = fabsf(vPt.x);
		vPt.y = fabsf(vPt.y);
		vPt.z = fabsf(vPt.z);

		//and update the dims
		VEC_MAX(vDims, vDims, vPt);		
	}

	//success
	return vDims;	
}
示例#4
0
inline void linesystem_ExtendBounds(LineSystem *pSystem, LTVector *pPt)
{
	VEC_MIN(pSystem->m_MinPos, pSystem->m_MinPos, *pPt);

	VEC_MAX(pSystem->m_MaxPos, pSystem->m_MaxPos, *pPt);
}
示例#5
0
// Sets up pParams.
// pPos and pRotation are the view position and orientation.
// pRect is the rectangle on the screen that the viewing window maps into.
// pScale is an extra scale that scales all the coordinates up.
bool d3d_InitFrustum2(ViewParams *pParams, 
	ViewBoxDef *pViewBox, 
	float screenMinX, float screenMinY, float screenMaxX, float screenMaxY,
	const LTMatrix *pMat, const LTVector& vScale, ViewParams::ERenderMode eMode)
{
	LTMatrix mTempWorld, mRotation, mScale;
	LTMatrix mFOVScale, mBackTransform;
	LTMatrix mDevice, mBackTranslate;
	float leftX, rightX, topY, bottomY, normalZ;
	uint32 i;
	LTVector forwardVec, zPlanePos, vTrans;
	LTMatrix mProjectionTransform; //mUnit, mPerspective;
	
	pParams->m_mIdentity.Identity();
	pParams->m_mInvView = *pMat;


	// Here's how the viewing works:
	// The world to camera transformation rotates and translates
	// the world into camera space.
	// The camera to clip transformation just scales the sides so the
	// field of view is 90 degrees (faster to clip in).
	// Clipping takes place on NEARZ and g_ViewParams.m_FarZ.
	// In terms of Z buffer calculations, the maximum Z is MAX_FARZ (that way,
	// when the farZ clipping plane is changed, sz and rhw stay the same).



	/////// Copy stuff in and setup view limits.

	memcpy(&pParams->m_ViewBox, pViewBox, sizeof(pParams->m_ViewBox));
	pMat->GetTranslation(pParams->m_Pos);

	pParams->m_FarZ = pViewBox->m_FarZ;
	if(pParams->m_FarZ < 3.0f) pParams->m_FarZ = 3.0f;
	if(pParams->m_FarZ > MAX_FARZ) pParams->m_FarZ = MAX_FARZ;
	pParams->m_NearZ = pViewBox->m_NearZ;
	
	pParams->m_Rect.left = (int)RoundFloatToInt(screenMinX);
	pParams->m_Rect.top = (int)RoundFloatToInt(screenMinY);
	pParams->m_Rect.right = (int)RoundFloatToInt(screenMaxX);
	pParams->m_Rect.bottom = (int)RoundFloatToInt(screenMaxY);

	/////// Setup all the matrices.

	// Setup the rotation and translation transforms.
	mRotation = *pMat;
	mRotation.SetTranslation(0.0f, 0.0f, 0.0f);
	Mat_GetBasisVectors(&mRotation, &pParams->m_Right, &pParams->m_Up, &pParams->m_Forward);

	// We want to transpose (ie: when we're looking left, rotate the world to the right..)
	MatTranspose3x3(&mRotation);
	mBackTranslate.Init(
		1, 0, 0, -pParams->m_Pos.x,
		0, 1, 0, -pParams->m_Pos.y,
		0, 0, 1, -pParams->m_Pos.z,
		0, 0, 0, 1);
	MatMul(&mTempWorld, &mRotation, &mBackTranslate);
	
	// Scale it to get the full world transform.
	mScale.Init(
		vScale.x, 0, 0, 0,
		0, vScale.y, 0, 0,
		0, 0, vScale.z, 0,
		0, 0, 0, 1);
	MatMul(&pParams->m_mView, &mScale, &mTempWorld);

	// Shear so the center of projection is (0,0,COP.z)
	LTMatrix mShear;
	mShear.Init(
		1.0f, 0.0f, -pViewBox->m_COP.x/pViewBox->m_COP.z, 0.0f,
		0.0f, 1.0f, -pViewBox->m_COP.y/pViewBox->m_COP.z, 0.0f,
		0.0f, 0.0f, 1.0f, 0.0f,
		0.0f, 0.0f, 0.0f, 1.0f);

	// Figure out X and Y scale to get frustum into unit slopes.
	float fFovXScale = pViewBox->m_COP.z / pViewBox->m_WindowSize[0];
	float fFovYScale = pViewBox->m_COP.z / pViewBox->m_WindowSize[1];

	// Squash the sides to 45 degree angles.
	mFOVScale.Init(
		fFovXScale, 0.0f, 0.0f, 0.0f,
		0.0f, fFovYScale, 0.0f, 0.0f,
		0.0f, 0.0f, 1.0f, 0.0f,
		0.0f, 0.0f, 0.0f, 1.0f);

	// Setup the projection transform.
	d3d_SetupPerspectiveMatrix(&mProjectionTransform, pViewBox->m_NearZ, pParams->m_FarZ);

	// Setup the projection space (-1<x<1) to device space transformation.
	pParams->m_fScreenWidth = (screenMaxX - screenMinX);
	pParams->m_fScreenHeight = (screenMaxY - screenMinY);
	
	// Setup the device transform.  It subtracts 0.4 to account for the FP's tendency
	// to slip above and below 0.5.
	Mat_Identity(&mDevice);
	mDevice.m[0][0] = pParams->m_fScreenWidth * 0.5f - 0.0001f;
	mDevice.m[0][3] = screenMinX + pParams->m_fScreenWidth * 0.5f;
	mDevice.m[1][1] = -(pParams->m_fScreenHeight * 0.5f - 0.0001f);
	mDevice.m[1][3] = screenMinY + pParams->m_fScreenHeight * 0.5f;


	// Precalculate useful matrices.
	pParams->m_DeviceTimesProjection = mDevice * mProjectionTransform;
	pParams->m_FullTransform = pParams->m_DeviceTimesProjection * mFOVScale * mShear * pParams->m_mView;

	pParams->m_mProjection = mProjectionTransform * mFOVScale * mShear;
	
	/////// Setup the view frustum points in camera space.
	
	float xNearZ, yNearZ, xFarZ, yFarZ;
	xNearZ = (pParams->m_NearZ * pViewBox->m_WindowSize[0]) / pViewBox->m_COP.z;
	yNearZ = (pParams->m_NearZ * pViewBox->m_WindowSize[1]) / pViewBox->m_COP.z;
	xFarZ = (pParams->m_FarZ * pViewBox->m_WindowSize[0]) / pViewBox->m_COP.z;
	yFarZ = (pParams->m_FarZ * pViewBox->m_WindowSize[1]) / pViewBox->m_COP.z;

	pParams->m_ViewPoints[0].Init(-xNearZ, yNearZ,  pParams->m_NearZ);	// Near Top Left
	pParams->m_ViewPoints[1].Init(xNearZ,  yNearZ,  pParams->m_NearZ);	// Near Top Right
	pParams->m_ViewPoints[2].Init(-xNearZ, -yNearZ, pParams->m_NearZ);	// Near Bottom Left
	pParams->m_ViewPoints[3].Init(xNearZ,  -yNearZ, pParams->m_NearZ);	// Near Bottom Right

	pParams->m_ViewPoints[4].Init(-xFarZ, yFarZ,  pParams->m_FarZ);	// Far Top Left
	pParams->m_ViewPoints[5].Init(xFarZ,  yFarZ,  pParams->m_FarZ);	// Far Top Right
	pParams->m_ViewPoints[6].Init(-xFarZ, -yFarZ, pParams->m_FarZ);	// Far Bottom Left
	pParams->m_ViewPoints[7].Init(xFarZ,  -yFarZ, pParams->m_FarZ);	// Far Bottom Right

	// Transform them into world space.
	for(i=0; i < 8; i++)
	{
		MatVMul_InPlace_Transposed3x3(&pParams->m_mView, &pParams->m_ViewPoints[i]);
		pParams->m_ViewPoints[i] += pParams->m_Pos;
	}

	// Get the AABB of the view frustum
	pParams->m_ViewAABBMin = pParams->m_ViewPoints[0];
	pParams->m_ViewAABBMax = pParams->m_ViewPoints[0];
	for(i=1; i < 8; i++)
	{
		VEC_MIN(pParams->m_ViewAABBMin, pParams->m_ViewAABBMin, pParams->m_ViewPoints[i]);
		VEC_MAX(pParams->m_ViewAABBMax, pParams->m_ViewAABBMax, pParams->m_ViewPoints[i]);
	}

	/////// Setup the camera-space clipping planes.

	leftX = pViewBox->m_COP.x - pViewBox->m_WindowSize[0];
	rightX = pViewBox->m_COP.x + pViewBox->m_WindowSize[0];
	topY = pViewBox->m_COP.y + pViewBox->m_WindowSize[1];
	bottomY = pViewBox->m_COP.y - pViewBox->m_WindowSize[1];
	normalZ = pViewBox->m_COP.z;
	
	LTPlane CSClipPlanes[NUM_CLIPPLANES];
	CSClipPlanes[CPLANE_NEAR_INDEX].m_Normal.Init(0.0f, 0.0f, 1.0f);		// Near Z
	CSClipPlanes[CPLANE_NEAR_INDEX].m_Dist = 1.0f;

	CSClipPlanes[CPLANE_FAR_INDEX].m_Normal.Init(0.0f, 0.0f, -1.0f);			// Far Z
	CSClipPlanes[CPLANE_FAR_INDEX].m_Dist = -pParams->m_FarZ;
	
	CSClipPlanes[CPLANE_LEFT_INDEX].m_Normal.Init(normalZ,  0.0f, -leftX);		// Left
	CSClipPlanes[CPLANE_RIGHT_INDEX].m_Normal.Init(-normalZ, 0.0f, rightX);		// Right
	CSClipPlanes[CPLANE_TOP_INDEX].m_Normal.Init(0.0f,  -normalZ, topY);		// Top
	CSClipPlanes[CPLANE_BOTTOM_INDEX].m_Normal.Init(0.0f,  normalZ, -bottomY);	// Bottom

	CSClipPlanes[CPLANE_LEFT_INDEX].m_Normal.Norm();
	CSClipPlanes[CPLANE_TOP_INDEX].m_Normal.Norm();
	CSClipPlanes[CPLANE_RIGHT_INDEX].m_Normal.Norm();
	CSClipPlanes[CPLANE_BOTTOM_INDEX].m_Normal.Norm();

	CSClipPlanes[CPLANE_LEFT_INDEX].m_Dist = CSClipPlanes[CPLANE_RIGHT_INDEX].m_Dist = 0.0f;
	CSClipPlanes[CPLANE_TOP_INDEX].m_Dist = CSClipPlanes[CPLANE_BOTTOM_INDEX].m_Dist = 0.0f;

	// Now setup the world space clipping planes.
	mBackTransform = pParams->m_mView;
	MatTranspose3x3(&mBackTransform);
	for(i=0; i < NUM_CLIPPLANES; i++)
	{
		if(i != CPLANE_NEAR_INDEX && i != CPLANE_FAR_INDEX)
		{
			MatVMul_3x3(&pParams->m_ClipPlanes[i].m_Normal, &mBackTransform, &CSClipPlanes[i].m_Normal);
			pParams->m_ClipPlanes[i].m_Dist = pParams->m_ClipPlanes[i].m_Normal.Dot(pParams->m_Pos);
		}
	}

	// The Z planes need to be handled a little differently.
	forwardVec.Init(mRotation.m[2][0], mRotation.m[2][1], mRotation.m[2][2]);

	zPlanePos = forwardVec * pViewBox->m_NearZ;
	zPlanePos += pParams->m_Pos;

	MatVMul_3x3(&pParams->m_ClipPlanes[CPLANE_NEAR_INDEX].m_Normal, 
		&mBackTransform, &CSClipPlanes[CPLANE_NEAR_INDEX].m_Normal);

	pParams->m_ClipPlanes[CPLANE_NEAR_INDEX].m_Dist = 
		pParams->m_ClipPlanes[CPLANE_NEAR_INDEX].m_Normal.Dot(zPlanePos);

	zPlanePos = forwardVec * pParams->m_FarZ;
	zPlanePos += pParams->m_Pos;
	
	MatVMul_3x3(&pParams->m_ClipPlanes[CPLANE_FAR_INDEX].m_Normal,
		&mBackTransform, &CSClipPlanes[CPLANE_FAR_INDEX].m_Normal);

	pParams->m_ClipPlanes[CPLANE_FAR_INDEX].m_Dist = 
		pParams->m_ClipPlanes[CPLANE_FAR_INDEX].m_Normal.Dot(zPlanePos);

	// Remember AABB Corners the planes are pointing at
	for (uint32 nPlaneLoop = 0; nPlaneLoop < NUM_CLIPPLANES; ++nPlaneLoop)
	{
		pParams->m_AABBPlaneCorner[nPlaneLoop] = 
			GetAABBPlaneCorner(pParams->m_ClipPlanes[nPlaneLoop].m_Normal);
	}

	// Default the world transform to identity
	pParams->m_mInvWorld.Identity();

	//setup the environment mapping info
	pParams->m_mWorldEnvMap.SetBasisVectors(&pParams->m_Right, &pParams->m_Up, &pParams->m_Forward);

	//turn off glowing by default
	pParams->m_eRenderMode = eMode;

	d3d_SetupSkyStuff(g_pSceneDesc->m_SkyDef, pParams);
	return true;
}
示例#6
0
static bool RecursivelyBuildBSP(CLightBSPNode** ppNode, PrePolyArray& PolyList, CLightBSPPoly** ppBSPPolyList)
{
	//sanity check
	ASSERT(ppNode);
	ASSERT(PolyList.GetSize() > 0);

	//number of polies that lie on the plane
	uint32 nNumLieOn, nFront, nBack;

	//first off, find the best splitting plane
	uint32 nSplitPlane = FindBestSplitPlane(PolyList, nNumLieOn, nFront, nBack);

	//allocate the new node
	*ppNode = AllocateBSPNode(nNumLieOn);

	//check for memory failure
	if(*ppNode == NULL)
		return false;

	//setup the node
	(*ppNode)->m_vPlaneNorm = PolyList[nSplitPlane]->Normal();
	(*ppNode)->m_fPlaneDist = PolyList[nSplitPlane]->Dist();

	//create the front, back, and on arrays
	PrePolyArray	Front, Back, On;
	Front.SetSize(nFront);
	Back.SetSize(nBack);
	On.SetSize(nNumLieOn);

	//now fill up all the lists
	PVector vNormal = PolyList[nSplitPlane]->Normal();
	float	fDist	= PolyList[nSplitPlane]->Dist();

	//index to the coplanar poly offset
	uint32 nPolyIndex = 0;

	//indices for the lists
	uint32 nFrontIndex	= 0;
	uint32 nBackIndex	= 0;
	uint32 nOnIndex		= 0;

	uint32 nType;

	//now need to count up the split information
	for(uint32 nTestPoly = 0; nTestPoly < PolyList.GetSize(); nTestPoly++)
	{
		if(nTestPoly == nSplitPlane)
		{
			On[nOnIndex++] = PolyList[nTestPoly];
			(*ppNode)->m_pPolyList[nPolyIndex++] = ppBSPPolyList[PolyList[nTestPoly]->m_Index];
			continue;
		}

		nType = ClassifyPoly(vNormal, fDist, PolyList[nTestPoly]);

		if(nType & PLANE_FRONT)
			Front[nFrontIndex++] = PolyList[nTestPoly];
		if(nType & PLANE_BACK)
			Back[nBackIndex++] = PolyList[nTestPoly];
		if(nType == PLANE_ON)
		{
			On[nOnIndex++] = PolyList[nTestPoly];
			(*ppNode)->m_pPolyList[nPolyIndex++] = ppBSPPolyList[PolyList[nTestPoly]->m_Index];
		}
	}

	//sanity check
	ASSERT(nPolyIndex == (*ppNode)->m_nNumPolies);
	ASSERT(nFrontIndex == nFront);
	ASSERT(nBackIndex == nBack);
	ASSERT(nOnIndex == nNumLieOn);

	//build up the child lists
	bool bSuccess = true;

	if(Front.GetSize() > 0)
	{
		bSuccess = RecursivelyBuildBSP(&(*ppNode)->m_pFront, Front, ppBSPPolyList);
	}
	if(bSuccess && (Back.GetSize() > 0))
	{
		bSuccess = RecursivelyBuildBSP(&(*ppNode)->m_pBack, Back, ppBSPPolyList);
	}

	//see if we need to clean up
	if(!bSuccess)
	{
		FreeBSPNode(*ppNode);
		*ppNode = NULL;
		return false;
	}

	//we need to update the node's bounding sphere. This is done by running through all
	//the polygons on the plane and generating a bounding box, finding its center, and then
	//the maximum distance to the points
	PVector vMin((PReal)MAX_CREAL, (PReal)MAX_CREAL, (PReal)MAX_CREAL);
	PVector vMax(-vMin);

	uint32 nCurrPoly;
	for(nCurrPoly = 0; nCurrPoly < nNumLieOn; nCurrPoly++)
	{
		CPrePoly* pPoly = On[nCurrPoly];
		for(uint32 nCurrVert = 0; nCurrVert < pPoly->NumVerts(); nCurrVert++)
		{
			VEC_MIN(vMin, vMin, pPoly->Pt(nCurrVert));
			VEC_MAX(vMax, vMax, pPoly->Pt(nCurrVert));
		}
	}

	//found the center
	(*ppNode)->m_vBSphereCenter = ((vMin + vMax) / 2);

	//now update the radius
	(*ppNode)->m_fBSphereRadSqr = 0;

	PReal fDistSqr;

	for(nCurrPoly = 0; nCurrPoly < nNumLieOn; nCurrPoly++)
	{
		CPrePoly* pPoly = On[nCurrPoly];
		for(uint32 nCurrVert = 0; nCurrVert < pPoly->NumVerts(); nCurrVert++)
		{
			fDistSqr = (pPoly->Pt(nCurrVert) - (*ppNode)->m_vBSphereCenter).MagSqr();

			if(fDistSqr > (*ppNode)->m_fBSphereRadSqr)
			{
				(*ppNode)->m_fBSphereRadSqr = fDistSqr;
			}
		}
	}
	
	//add some padding to the radius to compensate for inaccuracy
	(*ppNode)->m_fBSphereRadSqr += NODE_RADIUS_PADDING;

	return bSuccess;	
}
示例#7
0
static void RecurseAndGrowDims(CWorldNode *pNode, LTVector &vMin, LTVector &vMax, LTMatrix& mTransMat)
{
	//sanity check
	if(pNode == NULL)
	{
		return;
	}

	// Grow the dims for this node
	switch (pNode->GetType())
	{
		case Node_Object :
		{
			CBaseEditObj *pObject = pNode->AsObject();
			LTVector vCenter;
			mTransMat.Apply(pObject->GetPos(), vCenter);

			//always include at least the object center
			VEC_MIN(vMin, vMin, vCenter);
			VEC_MAX(vMax, vMax, vCenter);

#ifdef DIRECTEDITOR_BUILD			
			
			//see if there are other dims we need
			for (uint32 nCurDim = pObject->GetNumDims(); nCurDim > 0; --nCurDim)
			{
				LTVector vDims = *pObject->GetDim(nCurDim - 1);
				LTVector vObjMin = vCenter - vDims;
				LTVector vObjMax = vCenter + vDims;
				VEC_MIN(vMin, vMin, vObjMin);
				VEC_MAX(vMax, vMax, vObjMax);
			}
#endif
		}
		break;
		case Node_Brush:
		{
			CEditBrush *pBrush = pNode->AsBrush();
			
			CBoundingBox BBox = pBrush->CalcBoundingBox();

			//transform the bounding box
			LTVector vBoxMin, vBoxMax;
			mTransMat.Apply(BBox.m_Min, vBoxMin);
			mTransMat.Apply(BBox.m_Max, vBoxMax);

			VEC_MIN(vMin, vMin, vBoxMin);
			VEC_MAX(vMax, vMax, vBoxMax);
		}
		break;
		case Node_PrefabRef:
		{
			//create the new transformation matrix
			LTMatrix mRot;
			::gr_SetupMatrixEuler(pNode->GetOr(), mRot.m);

			LTMatrix mTranslate;
			mTranslate.Identity();
			mTranslate.SetTranslation(pNode->GetPos());

			LTMatrix mNewTransMat = mTransMat * mTranslate * mRot;
			RecurseAndGrowDims((CWorldNode*)((CPrefabRef*)pNode)->GetPrefabTree(), vMin, vMax, mNewTransMat);
		}
		break;
	}

	// Go through the children
	GPOS iFinger = pNode->m_Children.GetHeadPosition();
	while (iFinger)
	{
		CWorldNode *pChild = pNode->m_Children.GetNext(iFinger);
		RecurseAndGrowDims(pChild, vMin, vMax, mTransMat);
	}
}