Files
TeslaRel410/CODE/RP/MUNGA/BOXSPHR.CPP
T
CydandClaude Fable 5 fdd9ac9d97 Initial import: Tesla Release 4.10 (Tesla:BattleTech & Tesla:Red Planet)
Archival snapshot of the Virtual World Entertainment Tesla cockpit
software, 1994-1996: MUNGA engine and L4 pod layer source (Borland
C++ 5.0), BT/RP game code, and game content (models, audio, maps,
gauges, Division renderer data). Includes third-party libraries:
Division dVS/DPL graphics, HMI SOS audio, WATTCP networking.

Files are preserved byte-for-byte (.gitattributes disables all
line-ending conversion). README.md documents the layout, target
hardware, and toolchain.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 13:21:58 -05:00

261 lines
7.6 KiB
C++

//===========================================================================//
// File: boxsolid.cc //
// Project: MUNGA Brick: Spatializer Library //
// Contents: Implementation details of bounding-box collision subtypes //
//---------------------------------------------------------------------------//
// Date Who Modification //
// -------- --- ---------------------------------------------------------- //
// 01/11/95 JMA Initial port back to C++ //
//---------------------------------------------------------------------------//
// Copyright (C) 1993-1995, Virtual World Entertainment, Inc. //
// All Rights reserved worldwide //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
//===========================================================================//
#include <munga.hpp>
#pragma hdrstop
#if !defined(BOXSOLID_HPP)
# include <boxsolid.hpp>
#endif
#if !defined(ORIGIN_HPP)
# include <origin.hpp>
#endif
#if !defined(LINMTRX_HPP)
# include <linmtrx.hpp>
#endif
#if !defined(LINE_HPP)
# include <line.hpp>
#endif
//#############################################################################
//############################## BoxedSphere ############################
//#############################################################################
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
BoxedSphere::BoxedSphere(
const ExtentBox &extents,
BoxedSolid::Material material,
Simulation *owner,
BoxedSolid *next_solid
):
BoxedSolid(extents, SphereType, material, owner, next_solid)
{
Check_Pointer(this);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
BoxedSphere::~BoxedSphere()
{
Check_Pointer(this);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Logical
BoxedSphere::IntersectsBounded(const ExtentBox &extents)
{
Check(this);
Check(&extents);
Verify(minX <= extents.minX);
Verify(maxX >= extents.maxX);
Verify(minY <= extents.minY);
Verify(maxY >= extents.maxY);
Verify(minZ <= extents.minZ);
Verify(maxZ >= extents.maxZ);
//
//----------------------------------------------
// Find the centerpoint and radius of the sphere
//----------------------------------------------
//
Point3D center;
center.x = (minX + maxX) * 0.5f;
center.y = (minY + maxY) * 0.5f;
center.z = (minZ + maxZ) * 0.5f;
Scalar radius = maxX - center.x;
//
//--------------------------------------------------------------------------
// Constrain the centerpoint of the sphere to be within the bounded extents.
// Then see if the constrained point is within the radius of the sphere. If
// so, it is an intersection
//--------------------------------------------------------------------------
//
Point3D closest = center;
extents.Constrain(&closest);
closest -= center;
return radius*radius >= closest.LengthSquared();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Logical
BoxedSphere::ContainsBounded(const Point3D &point)
{
Check(this);
Check(&point);
Verify(minX <= point.x);
Verify(maxX >= point.x);
Verify(minY <= point.y);
Verify(maxY >= point.y);
Verify(minZ <= point.z);
Verify(maxZ >= point.z);
//
//----------------------------------------------
// Find the centerpoint and radius of the sphere
//----------------------------------------------
//
Point3D center;
center.x = (minX + maxX) * 0.5f;
center.y = (minY + maxY) * 0.5f;
center.z = (minZ + maxZ) * 0.5f;
Scalar radius = maxX - center.x;
//
//-------------------------------------------------------------------------
// translate the test point into the sphere's frame of reference and see if
// it is close enough
//-------------------------------------------------------------------------
//
center -= point;
return radius*radius >= center.LengthSquared();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Scalar
BoxedSphere::FindDistanceBelowBounded(const Point3D &point)
{
Check(this);
Check(&point);
Verify(minX <= point.x);
Verify(maxX >= point.x);
Verify(minY <= point.y);
Verify(minZ <= point.z);
Verify(maxZ >= point.z);
//
//----------------------------------------------
// Find the centerpoint and radius of the sphere
//----------------------------------------------
//
Point3D center;
center.x = (minX + maxX) * 0.5f;
center.y = (minY + maxY) * 0.5f;
center.z = (minZ + maxZ) * 0.5f;
Scalar radius = maxX - center.x;
//
//-----------------------------------------------------------------------
// Convert the point to the coordinates of the sphere, putting the center
// point of the sphere at the origin. Note that we are subtracting the
// point from the center point as opposed to the normal way. This will
// result in both X and Y being negated, but since we are squaring them,
// this will not matter
//-----------------------------------------------------------------------
//
Scalar x = center.x - point.x;
Scalar z = center.z - point.z;
Scalar h = radius*radius - x*x - z*z;
if (h < SMALL)
{
return -1.0f;
}
//
//-------------------------------------------------------------------
// If the point is in the XZ shadow of the sphere, then the height is
// determined by the height of the sphere at that point
//-------------------------------------------------------------------
//
Scalar height = point.y - (center.y + Sqrt(h));
return Abs(height);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Logical
BoxedSphere::HitByBounded(
Line *line,
Scalar enters,
Scalar leaves
)
{
Check(this);
Check(line);
Verify(enters <= leaves);
Verify(leaves >= 0.0f);
//
//----------------------------------------------
// Find the centerpoint and radius of the sphere
//----------------------------------------------
//
Point3D center;
center.x = (minX + maxX) * 0.5f;
center.y = (minY + maxY) * 0.5f;
center.z = (minZ + maxZ) * 0.5f;
Scalar radius = maxX - center.x;
//
//-------------------------------------------------------------------------
// Find the point of closest approach to the center of the sphere, and make
// sure that it is within the boundaries of the sphere
//-------------------------------------------------------------------------
//
Scalar midlen = line->LengthToClosestPointTo(center);
Point3D closest;
line->Project(midlen, &closest);
closest -= center;
Scalar v = radius*radius - closest.LengthSquared();
if (v < 0.0f)
{
return False;
}
//
//---------------------------------------------------------------------
// Find the closest possible length of ray traversal before hitting the
// sphere
//---------------------------------------------------------------------
//
v = Sqrt(v);
Scalar enter = midlen - v;
if (enter > enters)
{
enters = enter;
}
Scalar leave = midlen + v;
if (leave < leaves)
{
leaves = leave;
}
if (enters > leaves || enters > line->length || leaves < 0.0f)
{
return False;
}
line->length = Max(enters, 0.0f);
return True;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Logical
BoxedSphere::TestInstance() const
{
return solidType == SphereType;
}