Files
firestorm/Gameleap/code/mw4/Code/MW4/SensorCellMap.hpp
T
Cyd 2b8ca921cb Initial full mirror of c:\VWE (source + assets + toolchain + outputs) via Git LFS
Complete disaster-recovery snapshot: engine/game source, game data assets,
VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive.
Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false,
no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
2026-06-24 21:28:16 -05:00

281 lines
5.3 KiB
C++

#ifndef SENSORCELLMAP_HPP
#define SENSORCELLMAP_HPP
#pragma warning(disable : 4284)
#pragma warning(push)
#include <stlport\slist>
#include <stlport\vector>
#pragma warning(pop)
class SensorCellMap
{
public:
SensorCellMap()
{
}
~SensorCellMap()
{
}
typedef stlport::slist<MechWarrior4::MWObject*> list_type;
typedef stlport::vector<int> checksum_type;
class Cell
{
public:
Cell()
: m_Checksum(0)
{
}
list_type::const_iterator begin()
{
return (entries.begin());
}
list_type::const_iterator end()
{
return (entries.end());
}
void Add(MechWarrior4::MWObject* ptr)
{
Verify(std::find(begin(),end(),ptr) == end());
entries.insert(entries.begin(),ptr);
RecalcChecksum();
}
void Remove(MechWarrior4::MWObject* ptr)
{
Verify(std::find(begin(),end(),ptr) != end());
entries.remove(ptr);
RecalcChecksum();
}
void RecalcChecksum()
{
m_Checksum = entries.size() << 24;
{for (list_type::const_iterator i = begin();
i != end();
++i)
{
m_Checksum += ((*i)->objectID & 0x00FFFFFF);
}}
}
int GetChecksum() const
{
return (m_Checksum);
}
private:
stlport::slist<MechWarrior4::MWObject*> entries;
int m_Checksum;
};
Cell& GetCell(int x, int z)
{
Verify(x >= 0);
Verify(x < WIDTH);
Verify(z >= 0);
Verify(z < HEIGHT);
return (m_Entries[x][z]);
}
void Fill(int x1, int z1,
int x2, int z2,
list_type& output,
checksum_type& checksums)
{
{for (int i_x = x1;
i_x <= x2;
++i_x)
{
{for (int i_z = z1;
i_z <= z2;
++i_z)
{
Cell& cell = GetCell(i_x,i_z);
{for (list_type::const_iterator i = cell.begin();
i != cell.end();
++i)
{
output.insert(output.begin(),*i);
}}
checksums.push_back(cell.GetChecksum());
}}
}}
}
int CellIndex(Stuff::Scalar pos)
{
Verify(CELL_WIDTH == 256);
Verify(CELL_HEIGHT == 256);
int p((int)(pos + (Scalar)COORD_ADD));
return (p >> 8);
}
void ClampIndex(int& index, int min, int max)
{
if (index < min)
{
index = min;
}
else
{
if (index > max)
{
index = max;
}
}
}
void GetCellPos(int& x, int& z, const Stuff::LinearMatrix4D& local_to_world)
{
x = CellIndex(local_to_world(W_Axis, X_Axis));
z = CellIndex(local_to_world(W_Axis, Z_Axis));
ClampIndex(x,0,WIDTH - 1);
ClampIndex(z,0,HEIGHT - 1);
}
void GetRect(int& x1, int& z1, int& x2, int& z2, const Stuff::LinearMatrix4D& local_to_world, Stuff::Scalar radius)
{
Scalar x = local_to_world(W_Axis, X_Axis);
Scalar z = local_to_world(W_Axis, Z_Axis);
Scalar _x1 = x - radius;
if (_x1 < (Stuff::Scalar)LEFT_BOUNDS)
{
_x1 = (Stuff::Scalar)LEFT_BOUNDS;
}
x1 = CellIndex(_x1);
Scalar _x2 = x + radius;
if (_x2 >= (Stuff::Scalar)RIGHT_BOUNDS)
{
_x2 = (Stuff::Scalar)RIGHT_BOUNDS;
}
x2 = CellIndex(_x2);
Scalar _z1 = z - radius;
if (_z1 < (Stuff::Scalar)TOP_BOUNDS)
{
_z1 = (Stuff::Scalar)TOP_BOUNDS;
}
z1 = CellIndex(_z1);
Scalar _z2 = z + radius;
if (_z2 >= (Stuff::Scalar)BOTTOM_BOUNDS)
{
_z2 = (Stuff::Scalar)BOTTOM_BOUNDS;
}
z2 = CellIndex(_z2);
}
void Fill(const Stuff::LinearMatrix4D& local_to_world,
Stuff::Scalar radius,
list_type& output,
checksum_type& checksums)
{
checksums.clear();
int x1, z1, x2, z2;
GetRect(x1,z1,x2,z2,local_to_world,radius);
Fill(x1,z1,x2,z2,output,checksums);
}
bool ChecksumMatches(const Stuff::LinearMatrix4D& local_to_world,
Stuff::Scalar radius,
checksum_type& checksums)
{
int x1, z1, x2, z2;
GetRect(x1,z1,x2,z2,local_to_world,radius);
if (checksums.size() != (x2 - x1 + 1) * (z2 - z1 + 1))
{
return (false);
}
checksum_type::const_iterator i_checksum = checksums.begin();
{for (int i_x = x1;
i_x <= x2;
++i_x)
{
{for (int i_z = z1;
i_z <= z2;
++i_z)
{
// TODO: REWRITE THIS BEFORE CHECKING IN!!!
Cell& cell = GetCell(i_x,i_z);
if (cell.GetChecksum() != *(i_checksum))
{
return (false);
}
++i_checksum;
}}
}}
return (true);
}
void Add(MechWarrior4::MWObject* ptr, int x, int z)
{
Cell& cell = GetCell(x,z);
cell.Add(ptr);
}
void Add(MechWarrior4::MWObject* ptr, const Stuff::LinearMatrix4D& local_to_world)
{
int x, z;
GetCellPos(x,z,local_to_world);
Add(ptr,x,z);
}
void Remove(MechWarrior4::MWObject* ptr, int x, int z)
{
Cell& cell = GetCell(x,z);
cell.Remove(ptr);
}
void Remove(MechWarrior4::MWObject* ptr, const Stuff::LinearMatrix4D& local_to_world)
{
int x, z;
GetCellPos(x,z,local_to_world);
Remove(ptr,x,z);
}
private:
enum { CELL_WIDTH = 256 };
enum { CELL_HEIGHT = CELL_WIDTH };
enum { WIDTH = 20 };
enum { HEIGHT = 20 };
enum { COORD_ADD = 2560 };
enum { GRID_WIDTH = WIDTH * CELL_WIDTH };
enum { GRID_HEIGHT = HEIGHT * CELL_HEIGHT };
enum { LEFT_BOUNDS = -COORD_ADD + 1 };
enum { TOP_BOUNDS = -COORD_ADD + 1 };
enum { RIGHT_BOUNDS = COORD_ADD - 1 };
enum { BOTTOM_BOUNDS = COORD_ADD - 1 };
Cell m_Entries[WIDTH][HEIGHT];
};
#endif // SENSORCELLMAP_HPP