mirror of
https://github.com/copyrighttxt/watrbx-game-engine.git
synced 2026-09-04 20:57:49 +00:00
fahhh
This commit is contained in:
@@ -0,0 +1,206 @@
|
||||
#pragma once
|
||||
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <ostream>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Defines voxels at the cellular and sub-cellular level
|
||||
|
||||
namespace RBX { namespace Voxel {
|
||||
|
||||
enum CellMaterial
|
||||
{
|
||||
CELL_MATERIAL_Deprecated_Empty = 0,
|
||||
CELL_MATERIAL_Grass = 1,
|
||||
CELL_MATERIAL_Sand = 2,
|
||||
CELL_MATERIAL_Brick = 3,
|
||||
CELL_MATERIAL_Granite = 4,
|
||||
CELL_MATERIAL_Asphalt = 5,
|
||||
CELL_MATERIAL_Iron = 6,
|
||||
CELL_MATERIAL_Aluminum = 7,
|
||||
CELL_MATERIAL_Gold = 8,
|
||||
CELL_MATERIAL_Wood_Plank = 9,
|
||||
CELL_MATERIAL_Wood_Log = 10,
|
||||
CELL_MATERIAL_Gravel = 11,
|
||||
CELL_MATERIAL_Cinder_Block = 12,
|
||||
CELL_MATERIAL_Stone_Block = 13,
|
||||
CELL_MATERIAL_Cement = 14,
|
||||
CELL_MATERIAL_Red_Plastic = 15,
|
||||
CELL_MATERIAL_Blue_Plastic = 16,
|
||||
CELL_MATERIAL_Water = 17,
|
||||
CELL_MATERIAL_Unspecified = 255,
|
||||
MAX_CELL_MATERIALS = 18,
|
||||
};
|
||||
|
||||
enum CellBlock
|
||||
{
|
||||
CELL_BLOCK_Solid = 0,
|
||||
CELL_BLOCK_VerticalWedge = 1,
|
||||
CELL_BLOCK_CornerWedge = 2,
|
||||
CELL_BLOCK_InverseCornerWedge = 3,
|
||||
CELL_BLOCK_HorizontalWedge = 4,
|
||||
|
||||
// Enum values below this line are intentionally not reflected!
|
||||
// Talk with dignatoff@ before exposing these enums!
|
||||
CELL_BLOCK_Empty = 5,
|
||||
|
||||
//InverseVerticalWedge = 4,
|
||||
//TopCornerWedge = 5,
|
||||
MAX_CELL_BLOCKS = 8,
|
||||
};
|
||||
|
||||
// Viewed from a downwards vertical perspective,
|
||||
// orientation defines the corner that the block starts in in a clockwise fashion
|
||||
enum CellOrientation
|
||||
{
|
||||
CELL_ORIENTATION_NegZ = 0, // upper left
|
||||
CELL_ORIENTATION_X = 1, // upper right
|
||||
CELL_ORIENTATION_Z = 2, // lower right
|
||||
CELL_ORIENTATION_NegX = 3, // lower left
|
||||
MAX_CELL_ORIENTATIONS = 4
|
||||
};
|
||||
|
||||
enum WaterCellForce
|
||||
{
|
||||
WATER_CELL_FORCE_None = 0,
|
||||
WATER_CELL_FORCE_Small = 1,
|
||||
WATER_CELL_FORCE_Medium = 2,
|
||||
WATER_CELL_FORCE_Strong = 3,
|
||||
WATER_CELL_FORCE_MaxForce = 4,
|
||||
MAX_WATER_CELL_FORCES = 5
|
||||
};
|
||||
|
||||
enum WaterCellDirection
|
||||
{
|
||||
WATER_CELL_DIRECTION_NegX = 0,
|
||||
WATER_CELL_DIRECTION_X = 1,
|
||||
WATER_CELL_DIRECTION_NegY = 2,
|
||||
WATER_CELL_DIRECTION_Y = 3,
|
||||
WATER_CELL_DIRECTION_NegZ = 4,
|
||||
WATER_CELL_DIRECTION_Z = 5,
|
||||
MAX_WATER_CELL_DIRECTIONS = 6
|
||||
};
|
||||
|
||||
class SolidTerrainCell {
|
||||
// Material used to be stored in solid terrain voxel; it has
|
||||
// subsequently been moved to a completely separate storage mechanism.
|
||||
// The field is here to preserve memory layout with the earlier version.
|
||||
unsigned char DEPRECATED_material : 3;
|
||||
unsigned char block : 3;
|
||||
unsigned char orientation : 2;
|
||||
|
||||
public:
|
||||
CellBlock getBlock() const { return (CellBlock) block; }
|
||||
CellOrientation getOrientation() const {
|
||||
return (CellOrientation) orientation;
|
||||
}
|
||||
|
||||
void setBlock(CellBlock block) { this->block = block; }
|
||||
void setOrientation(CellOrientation orientation) {
|
||||
this->orientation = orientation;
|
||||
}
|
||||
};
|
||||
|
||||
class WaterCell {
|
||||
// Water voxels are implemented to be bit-compatible with solid voxels,
|
||||
// so this bit layout matches the bit layout of SolidTerrainCell.
|
||||
unsigned char dataPart2 : 3;
|
||||
unsigned char blockMustBeEmpty : 3;
|
||||
unsigned char dataPart1 : 2;
|
||||
|
||||
unsigned int getWaterData() const {
|
||||
return ((dataPart1 << 3) | dataPart2) - 1;
|
||||
}
|
||||
public:
|
||||
WaterCellForce getForce() const {
|
||||
return (WaterCellForce) ((getWaterData() / MAX_WATER_CELL_DIRECTIONS) % MAX_WATER_CELL_FORCES);
|
||||
}
|
||||
WaterCellDirection getDirection() const {
|
||||
return (WaterCellDirection) (getWaterData() % MAX_WATER_CELL_DIRECTIONS);
|
||||
}
|
||||
|
||||
void setForceAndDirection(WaterCellForce force, WaterCellDirection direction) {
|
||||
unsigned int rawData = (force * MAX_WATER_CELL_DIRECTIONS + direction) + 1;
|
||||
dataPart2 = rawData & 0x7;
|
||||
dataPart1 = (rawData >> 3) & 0x3;
|
||||
}
|
||||
};
|
||||
|
||||
// Data structure that represents one voxel cell. The cell can either be water or solid terrain,
|
||||
// so this class is a union of WaterCell and SolidTerrainCell.
|
||||
union Cell {
|
||||
SolidTerrainCell solid;
|
||||
WaterCell water;
|
||||
|
||||
Cell() {
|
||||
// There isn't a simple way to make sure all of the members are
|
||||
// zero by going through setter methods. SolidTerrainCell, for example,
|
||||
// has no way to control the bits in DEPRECATED_material.
|
||||
// Performance testing has shown this to not be a perf hit compared to
|
||||
// casting this to unsigned char* and setting that to zero.
|
||||
memset(this, 0, sizeof(Cell));
|
||||
}
|
||||
|
||||
// True if the voxel is completely empty (no solid terrain and no water)
|
||||
inline bool isEmpty() const;
|
||||
|
||||
// Indicates if this cell has been set to water explicitly by the user.
|
||||
// Note that water can also exist in wedge cells. Use Region and/or
|
||||
// Region::iterator methods for a way to detect all kinds of water
|
||||
// simultaneously.
|
||||
inline bool isExplicitWaterCell() const { return !isEmpty() && solid.getBlock() == CELL_BLOCK_Empty; }
|
||||
|
||||
inline bool operator==(const Cell& other) const {
|
||||
return ((const unsigned char*)this)[0] == ((const unsigned char*)&other)[0];
|
||||
}
|
||||
inline bool operator!=(const Cell& other) const {
|
||||
return !((*this) == other);
|
||||
}
|
||||
|
||||
// Convert to/from unsigned char, for networking and saving to file
|
||||
static inline unsigned char serializeAsUnsignedChar(const Cell v) {
|
||||
return ((unsigned char*)&v)[0];
|
||||
}
|
||||
static inline Cell deserializeFromUnsignedChar(unsigned char cell) {
|
||||
return ((Cell*)&cell)[0];
|
||||
}
|
||||
static inline unsigned char convertToUnsignedCharForFile(const Cell v) {
|
||||
return ((unsigned char*)&v)[0];
|
||||
}
|
||||
static inline Cell readUnsignedCharFromFile(unsigned char cell) {
|
||||
return ((Cell*)&cell)[0];
|
||||
}
|
||||
// Old style voxel access. Avoid using these methods where possible.
|
||||
static inline unsigned char asUnsignedCharForDeprecatedUses(const Cell v) {
|
||||
return ((unsigned char*)&v)[0];
|
||||
}
|
||||
static inline Cell readUnsignedCharFromDeprecatedUse(unsigned char cell) {
|
||||
return ((Cell*)&cell)[0];
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_STATIC_ASSERT(sizeof(Cell) == 1);
|
||||
|
||||
namespace Constants {
|
||||
// There is exactly one way to represent an empty cell. This constant stores that representation.
|
||||
extern const Cell kUniqueEmptyCellRepresentation;
|
||||
// When there is water in a cell that has a solid wedge, the water state is always the same. This
|
||||
// constant stores the water state for water-on-wedge cells.
|
||||
extern const Cell kWaterOnWedgeCell;
|
||||
}
|
||||
|
||||
bool Cell::isEmpty() const {
|
||||
return (*this) == Constants::kUniqueEmptyCellRepresentation;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const RBX::Voxel::Cell& v);
|
||||
|
||||
const int kXZ_CHUNK_SIZE = 32;
|
||||
const int kY_CHUNK_SIZE = 16;
|
||||
|
||||
const int kCELL_SIZE = 4;
|
||||
const int kHALF_CELL = kCELL_SIZE / 2;
|
||||
const int kCELL_SIZE_AS_BIT_SHIFT = 2;
|
||||
|
||||
} }
|
||||
|
||||
Reference in New Issue
Block a user