Esempio n. 1
0
MF_API void MFCollision_BuildField(MFCollisionItem *pField)
{
	MFCollisionField *pFieldData = (MFCollisionField*)pField->pTemplate;

	int numItems = pFieldData->itemList.GetLength();

	if(numItems <= 0)
	{
		MFDebug_Warn(4, "EmptyField can not be generated.");
		return;
	}

	// find the min and max range of the objects
	MFVector fieldMin = MakeVector(10e+30f), fieldMax = MakeVector(-10e+30f);

	MFCollisionItem **ppI = pFieldData->itemList.Begin();

	while(*ppI)
	{
		MFCollisionItem *pI = *ppI;
		MFCollisionTemplate *pT = pI->pTemplate;

		MFVector tMin = ApplyMatrixH(pT->boundingVolume.min, pI->worldPos);
		MFVector tMax = ApplyMatrixH(pT->boundingVolume.max, pI->worldPos);

		fieldMin = MFMin(fieldMin, tMin);
		fieldMax = MFMax(fieldMax, tMax);

		ppI++;
	}

	pFieldData->fieldMin = fieldMin;
	pFieldData->fieldMax = fieldMin;

	MFVector numCells;
	MFVector fieldRange = fieldMax - fieldMin;
	numCells.Rcp3(pFieldData->cellSize);
	numCells.Mul3(fieldRange, numCells);

	pFieldData->width = (int)MFCeil(numCells.x);
	pFieldData->height = (int)MFCeil(numCells.y);
	pFieldData->depth = (int)MFCeil(numCells.z);

	// this is TOTALLY broken!! .. if a big object lies in many cell's, it could easilly overflow the array.
	int totalCells = pFieldData->width * pFieldData->height * pFieldData->depth;
	int numPointers = totalCells * 2 + numItems * 16;

	MFCollisionItem **ppItems = (MFCollisionItem**)MFHeap_Alloc(sizeof(MFCollisionItem*) * numPointers);
	pFieldData->pppItems = (MFCollisionItem***)ppItems;
	ppItems += totalCells;

	for(int z=0; z<pFieldData->depth; z++)
	{
		for(int y=0; y<pFieldData->height; y++)
		{
			for(int x=0; x<pFieldData->width; x++)
			{
				pFieldData->pppItems[z*pFieldData->height*pFieldData->width + y*pFieldData->width + x] = ppItems;

				MFVector thisCell = fieldMin + pFieldData->cellSize * MakeVector((float)x, (float)y, (float)z);
				MFVector thisCellEnd = thisCell + pFieldData->cellSize;

				MFCollisionItem **ppI = pFieldData->itemList.Begin();

				while(*ppI)
				{
					MFCollisionItem *pI = *ppI;
					MFCollisionTemplate *pT = pI->pTemplate;

					// if this item fits in this cell, insert it into this cells list.
					MFVector tMin = ApplyMatrixH(pT->boundingVolume.min, pI->worldPos);
					MFVector tMax = ApplyMatrixH(pT->boundingVolume.max, pI->worldPos);

					// test of bounding boxes overlap
					if(MFCollision_TestAABB(tMin, tMax, thisCell, thisCellEnd))
					{
						*ppItems = pI;
						++ppItems;
					}

					ppI++;
				}

				*ppItems = NULL;
				++ppItems;
			}
		}
	}

	MFHeap_ValidateMemory(pFieldData->pppItems);
}
Esempio n. 2
0
void dBFrame::Draw()
{
	if(!pMat)
	{
		MFPrimitive_DrawUntexturedQuad(rect.x-10, rect.y-10, rect.width+20, rect.height+20, colours[0]);
	}
	else
	{
		// draw background
		float x, y, xRemaining, yRemaining;

		// calculate number of tiles (including edges)
		int h = (int)MFCeil(rect.width / borderWidth);
		int w = (int)MFCeil(rect.height / borderWidth);
		int numTiles = (h + 2) * (w + 2);

		// begin immediate renderer
		MFMaterial_SetMaterial(pMat);
		MFPrimitive(PT_QuadList);
		MFBegin(numTiles*2);

		MFSetColourV(colours[0]);

		// render tiled background
		yRemaining = rect.height;
		for(y = 0.0f; y < rect.height; y += borderWidth)
		{
			xRemaining = rect.width;
			for(x = 0.0f; x < rect.width; x += borderWidth)
			{
				float xuv = xRemaining < borderWidth ? 0.25f * (xRemaining / borderWidth) : 0.25f;
				float yuv = yRemaining < borderWidth ? 0.25f * (yRemaining / borderWidth) : 0.25f;

				MFSetTexCoord1(0.25f, 0.25f);
				MFSetPosition(rect.x + x, rect.y + y, 0);
				MFSetTexCoord1(0.25f + xuv, 0.25f + yuv);		
				MFSetPosition(rect.x + x + MFMin(borderWidth, xRemaining), rect.y + y + MFMin(borderWidth, yRemaining), 0);

				xRemaining -= borderWidth;
			}

			yRemaining -= borderWidth;
		}

		// draw frame
		// draw corners
		MFSetTexCoord1(0.0f, 0.0f);
		MFSetPosition(rect.x - borderWidth, rect.y - borderWidth, 0.0f);
		MFSetTexCoord1(0.25f, 0.25f);		
		MFSetPosition(rect.x, rect.y, 0.0f);
		MFSetTexCoord1(0.5f, 0.0f);
		MFSetPosition(rect.x + rect.width, rect.y - borderWidth, 0.0f);
		MFSetTexCoord1(0.75f, 0.25f);		
		MFSetPosition(rect.x + rect.width + borderWidth, rect.y, 0.0f);
		MFSetTexCoord1(0.0f, 0.50f);
		MFSetPosition(rect.x - borderWidth, rect.y + rect.height, 0.0f);
		MFSetTexCoord1(0.25f, 0.75f);		
		MFSetPosition(rect.x, rect.y + rect.height + borderWidth, 0.0f);
		MFSetTexCoord1(0.5f, 0.5f);
		MFSetPosition(rect.x + rect.width, rect.y + rect.height, 0.0f);
		MFSetTexCoord1(0.75f, 0.75f);		
		MFSetPosition(rect.x + rect.width + borderWidth, rect.y + rect.height + borderWidth, 0.0f);

		// draw vertical edges
		yRemaining = rect.height;
		for(y = 0.0f; y < rect.height; y += borderWidth)
		{
			float yuv = yRemaining < borderWidth ? 0.25f * (yRemaining / borderWidth) : 0.25f;

			MFSetTexCoord1(0.0f, 0.25f);
			MFSetPosition(rect.x - borderWidth, rect.y + y, 0.0f);
			MFSetTexCoord1(0.25f, 0.25f + yuv);		
			MFSetPosition(rect.x, rect.y + y + MFMin(borderWidth, yRemaining), 0.0f);

			MFSetTexCoord1(0.5f, 0.25f);
			MFSetPosition(rect.x + rect.width, rect.y + y, 0.0f);
			MFSetTexCoord1(0.75f, 0.25f + yuv);		
			MFSetPosition(rect.x + rect.width + borderWidth, rect.y + y + MFMin(borderWidth, yRemaining), 0.0f);

			yRemaining -= borderWidth;
		}

		// draw horizontal edges
		xRemaining = rect.width;
		for(x = 0.0f; x < rect.width; x += borderWidth)
		{
			float xuv = xRemaining < borderWidth ? 0.25f * (xRemaining / borderWidth) : 0.25f;

			MFSetTexCoord1(0.25f, 0.0f);
			MFSetPosition(rect.x + x, rect.y - borderWidth, 0.0f);
			MFSetTexCoord1(0.25f + xuv, 0.25f);		
			MFSetPosition(rect.x + x + MFMin(borderWidth, xRemaining), rect.y, 0.0f);

			MFSetTexCoord1(0.25f, 0.5f);
			MFSetPosition(rect.x + x, rect.y + rect.height, 0.0f);
			MFSetTexCoord1(0.25f + xuv, 0.75f);		
			MFSetPosition(rect.x + x + MFMin(borderWidth, xRemaining), rect.y + rect.height + borderWidth, 0.0f);

			xRemaining -= borderWidth;
		}

		MFEnd();
	}
}