Initial import of Red Planet v4.10 Win32 source
Imports the current Win32 source for the pod-racing game 'Red Planet', built on the MUNGA engine and its L4 (Win32/DirectX) platform layer: - MUNGA / MUNGA_L4: cross-platform engine core and Win32 backend - RP / RP_L4: Red Planet game logic and Win32 application - DivLoader, Setup1: asset loader and installer project - lib, MUNGA_L4/openal, MUNGA_L4/sos: third-party audio dependencies Removed stale Subversion metadata and added .gitignore/.gitattributes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,311 @@
|
||||
#include "munga.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "boxlist.h"
|
||||
|
||||
//#############################################################################
|
||||
//######################### BoundingBoxListNode #########################
|
||||
//#############################################################################
|
||||
|
||||
MemoryBlock *BoundingBoxListNode::GetAllocatedMemory()
|
||||
{
|
||||
static MemoryBlock allocatedMemory(sizeof(BoundingBoxListNode), 500, 50, "BoundingBoxList Nodes");
|
||||
return &allocatedMemory;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
Logical
|
||||
BoundingBoxListNode::TestInstance() const
|
||||
{
|
||||
return True;
|
||||
}
|
||||
|
||||
//#############################################################################
|
||||
//########################### BoundingBoxList ###########################
|
||||
//#############################################################################
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
BoundingBoxList::BoundingBoxList()
|
||||
{
|
||||
root = NULL;
|
||||
nodeCount = 0;
|
||||
scoreBoard = NULL;
|
||||
boundingBoxIndex = NULL;
|
||||
isXMajorAxis = True;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
BoundingBoxList::~BoundingBoxList()
|
||||
{
|
||||
if (scoreBoard)
|
||||
{
|
||||
Unregister_Pointer(scoreBoard);
|
||||
delete scoreBoard;
|
||||
}
|
||||
if (boundingBoxIndex)
|
||||
{
|
||||
Unregister_Pointer(boundingBoxIndex);
|
||||
delete boundingBoxIndex;
|
||||
}
|
||||
EraseList();
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
void
|
||||
BoundingBoxList::Add(
|
||||
BoundingBox* volume,
|
||||
const ExtentBox &slice
|
||||
)
|
||||
{
|
||||
Check(this);
|
||||
Check(volume);
|
||||
|
||||
++nodeCount;
|
||||
BoundingBoxListNode *node = new BoundingBoxListNode(volume, slice);
|
||||
Register_Object(node);
|
||||
node->previousNode = root;
|
||||
root = node;
|
||||
}
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
void
|
||||
BoundingBoxList::Remove(BoundingBox* volume)
|
||||
{
|
||||
Check(this);
|
||||
Check(volume);
|
||||
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
// Spin through all the boxes until we find the one we are after or until we
|
||||
// run off the list
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
BoundingBoxListNode
|
||||
*p = NULL,
|
||||
*c = root;
|
||||
while (c)
|
||||
{
|
||||
Check(c);
|
||||
if (c->boundingBox == volume)
|
||||
{
|
||||
break;
|
||||
}
|
||||
p = c;
|
||||
c = c->previousNode;
|
||||
}
|
||||
|
||||
//
|
||||
//----------------------------------------------
|
||||
// Unlink the node from the list if it was found
|
||||
//----------------------------------------------
|
||||
//
|
||||
if (!c)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Check(c);
|
||||
if (p)
|
||||
{
|
||||
Check(p);
|
||||
p->previousNode = c->previousNode;
|
||||
}
|
||||
else
|
||||
{
|
||||
root = c->previousNode;
|
||||
}
|
||||
|
||||
//
|
||||
//-----------------
|
||||
// Delete this node
|
||||
//-----------------
|
||||
//
|
||||
--nodeCount;
|
||||
Unregister_Object(c);
|
||||
delete c;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
void
|
||||
BoundingBoxList::EraseList()
|
||||
{
|
||||
Check(this);
|
||||
|
||||
//
|
||||
//-----------------------------
|
||||
// Delete each node in the list
|
||||
//-----------------------------
|
||||
//
|
||||
BoundingBoxListNode *p = root;
|
||||
while (p)
|
||||
{
|
||||
Check(p);
|
||||
BoundingBoxListNode *q = p;
|
||||
p = p->previousNode;
|
||||
Unregister_Object(q);
|
||||
delete q;
|
||||
}
|
||||
root = NULL;
|
||||
nodeCount = 0;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
BoundingBox*
|
||||
BoundingBoxList::FindBoundingBoxContaining(const Point3D &point)
|
||||
{
|
||||
Check(this);
|
||||
Check(&point);
|
||||
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
// Spin through each of the boxes in reverse order until we find a box which
|
||||
// contains the specified point. It will be default have priority over any
|
||||
// boxes put in before it
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
for (BoundingBoxListNode *p=root; p; p = p->previousNode)
|
||||
{
|
||||
Check(p);
|
||||
BoundingBox *box = p->boundingBox;
|
||||
Check(box);
|
||||
if (box->Contains(point))
|
||||
{
|
||||
return box;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
void
|
||||
BoundingBoxList::FindBoundingBoxesContaining(
|
||||
BoundingBox *volume,
|
||||
BoundingBoxCollisionList &list
|
||||
)
|
||||
{
|
||||
Check(this);
|
||||
Check(volume);
|
||||
Check(&list);
|
||||
|
||||
//
|
||||
//-------------------------------------------------------------
|
||||
// Spin through each of the boxes in reverse order, looking for
|
||||
// intesections between the test volume and the box list
|
||||
//-------------------------------------------------------------
|
||||
//
|
||||
for (BoundingBoxListNode *p=root; p; p = p->previousNode)
|
||||
{
|
||||
Check(p);
|
||||
BoundingBox *box = p->boundingBox;
|
||||
Check(box);
|
||||
if (box->ExtentBox::Intersects(*volume))
|
||||
{
|
||||
//
|
||||
//----------------------------------------------------------------
|
||||
// Build the intersection slice, and make sure that it really does
|
||||
// intersect the list box
|
||||
//----------------------------------------------------------------
|
||||
//
|
||||
ExtentBox slice;
|
||||
slice.Intersect(*volume, *box);
|
||||
if (box->IntersectsBounded(slice))
|
||||
{
|
||||
|
||||
//
|
||||
//------------------------------------------------------------
|
||||
// It intersects, so add this to the list. If we are out of
|
||||
// collisions in the list, we are finished detecting, and just
|
||||
// return
|
||||
//------------------------------------------------------------
|
||||
//
|
||||
Verify(list.collisionsLeft);
|
||||
list.AddCollisionToList(box, slice);
|
||||
if (!list.collisionsLeft)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
BoundingBox*
|
||||
BoundingBoxList::FindBoundingBoxUnder(
|
||||
const Point3D &point,
|
||||
Scalar *height
|
||||
)
|
||||
{
|
||||
Check(this);
|
||||
Check(&point);
|
||||
Check_Pointer(height);
|
||||
|
||||
//
|
||||
//-----------------------------------------------------------------------
|
||||
// Spin through each of the bounding boxes, keeping track of which box is
|
||||
// hit after the shortest distance
|
||||
//-----------------------------------------------------------------------
|
||||
//
|
||||
BoundingBox *best_box = NULL;
|
||||
*height = -1.0f;
|
||||
for (BoundingBoxListNode *p=root; p; p = p->previousNode)
|
||||
{
|
||||
Check(p);
|
||||
BoundingBox *box = p->boundingBox;
|
||||
Check(box);
|
||||
|
||||
Scalar h = box->FindDistanceBelow(point);
|
||||
if (h != -1.0f)
|
||||
{
|
||||
if (!best_box || *height > h)
|
||||
{
|
||||
best_box = box;
|
||||
*height = h;
|
||||
}
|
||||
}
|
||||
}
|
||||
return best_box;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
BoundingBox*
|
||||
BoundingBoxList::FindBoundingBoxHitBy(Line *line)
|
||||
{
|
||||
//
|
||||
//-----------------------------------------------------------------------
|
||||
// Spin through each of the boxes, letting each box in turn clip the line
|
||||
// lengths
|
||||
//-----------------------------------------------------------------------
|
||||
//
|
||||
BoundingBox *best_box = NULL;
|
||||
for (BoundingBoxListNode *p=root; p; p = p->previousNode)
|
||||
{
|
||||
Check(p);
|
||||
BoundingBox *box = p->boundingBox;
|
||||
Check(box);
|
||||
|
||||
Logical h = box->HitBy(line);
|
||||
if (h)
|
||||
{
|
||||
best_box = box;
|
||||
}
|
||||
}
|
||||
return best_box;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
Logical
|
||||
BoundingBoxList::TestInstance() const
|
||||
{
|
||||
return True;
|
||||
}
|
||||
Reference in New Issue
Block a user