mirror of
https://github.com/copyrighttxt/watrbx-game-engine.git
synced 2026-09-05 05:07:48 +00:00
fahhh
This commit is contained in:
@@ -0,0 +1,167 @@
|
||||
#pragma once
|
||||
|
||||
#include "Util/G3DCore.h"
|
||||
#include "Voxel/Cell.h"
|
||||
#include "rbx/Debug.h"
|
||||
#include "Util/Extents.h"
|
||||
#include "Util/Region3int16.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// This file has methods for reading and writing individual voxel cells
|
||||
|
||||
namespace RBX { namespace Voxel {
|
||||
|
||||
inline CellMaterial getCellMaterial_Deprecated( unsigned char cell ) { return (CellMaterial)(cell & 0x07); }
|
||||
inline void setCellMaterial_Deprecated( unsigned char& cell, CellMaterial material ) { cell = (cell & 0xf8) | ((int)material & 0x07); }
|
||||
|
||||
inline CellMaterial readMaterial(const unsigned char* materials, const unsigned int cellIndex, const Cell cell) {
|
||||
return (CellMaterial)(
|
||||
cell.solid.getBlock() == CELL_BLOCK_Empty ?
|
||||
CELL_MATERIAL_Water :
|
||||
((materials[cellIndex >> 1] >> (4 * (cellIndex & 0x1))) & 0x0f) + 1);
|
||||
}
|
||||
inline void writeMaterial(unsigned char* materials, unsigned int cellIndex, const CellMaterial newMaterial) {
|
||||
RBXASSERT(newMaterial > 0);
|
||||
unsigned char& wholeByte = materials[cellIndex >> 1];
|
||||
unsigned int shift = (4 * (cellIndex & 0x1));
|
||||
unsigned char mask = 0x0f << shift;
|
||||
wholeByte &= (~mask);
|
||||
wholeByte |= (((newMaterial-1) << shift) & mask);
|
||||
}
|
||||
|
||||
enum FaceDirection
|
||||
{
|
||||
PlusX = 0,
|
||||
PlusZ = 1,
|
||||
MinusX = 2,
|
||||
MinusZ = 3,
|
||||
PlusY = 4,
|
||||
MinusY = 5,
|
||||
Invalid = 6
|
||||
};
|
||||
|
||||
struct BlockAxisFace {
|
||||
enum SkippedCorner {
|
||||
TopRight = 0,
|
||||
TopLeft = 1,
|
||||
BottomLeft = 2,
|
||||
BottomRight = 3,
|
||||
EmptyAllSkipped = 4,
|
||||
FullNoneSkipped = 5
|
||||
};
|
||||
|
||||
SkippedCorner skippedCorner;
|
||||
|
||||
static inline SkippedCorner rotate(SkippedCorner corner, const CellOrientation orient) {
|
||||
return (SkippedCorner) (corner < 4 ? (corner + orient) % 4 : corner);
|
||||
}
|
||||
|
||||
static inline bool divideTopLeftToBottomRight(SkippedCorner corner) {
|
||||
return corner == TopRight || corner == BottomLeft || corner == FullNoneSkipped;
|
||||
}
|
||||
|
||||
static inline SkippedCorner XZAxisMirror(SkippedCorner corner) {
|
||||
static SkippedCorner MIRROR[6] =
|
||||
{ TopLeft, TopRight, BottomRight, BottomLeft, EmptyAllSkipped, FullNoneSkipped };
|
||||
return MIRROR[corner];
|
||||
}
|
||||
|
||||
static inline SkippedCorner YAxisMirror(SkippedCorner corner) {
|
||||
static SkippedCorner MIRROR[6] =
|
||||
{ BottomRight, BottomLeft, TopLeft, TopRight, EmptyAllSkipped, FullNoneSkipped };
|
||||
return MIRROR[corner];
|
||||
}
|
||||
|
||||
static BlockAxisFace inverse(const BlockAxisFace other) {
|
||||
static const SkippedCorner OPPOSITE_CORNER[6] = {
|
||||
BottomLeft,
|
||||
BottomRight,
|
||||
TopRight,
|
||||
TopLeft,
|
||||
FullNoneSkipped,
|
||||
EmptyAllSkipped
|
||||
};
|
||||
|
||||
BlockAxisFace out;
|
||||
out.skippedCorner = OPPOSITE_CORNER[other.skippedCorner];
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
struct BlockFaceInfo {
|
||||
// indexed by FaceDirection
|
||||
BlockAxisFace faces[6];
|
||||
};
|
||||
|
||||
extern const BlockFaceInfo UnOrientedBlockFaceInfos[6];
|
||||
extern BlockAxisFace OrientedFaceMap[ 1536 ]; // 2^8 * 6
|
||||
|
||||
// ComputeOrientedFace is not declared because it is an implementation detail
|
||||
void initBlockOrientationFaceMap();
|
||||
|
||||
inline const BlockAxisFace& GetOrientedFace(Cell cell, FaceDirection f)
|
||||
{
|
||||
return OrientedFaceMap[ Cell::asUnsignedCharForDeprecatedUses(cell)*6 + f ];
|
||||
}
|
||||
|
||||
inline bool isWedgeSideNotFull(Cell voxel, FaceDirection f) {
|
||||
return GetOrientedFace(voxel, f).skippedCorner != BlockAxisFace::FullNoneSkipped;
|
||||
}
|
||||
|
||||
inline Vector3int16 worldToCell_floor(const Vector3& worldPos) {
|
||||
const int kXZOffset = 0;
|
||||
return Vector3int16(
|
||||
(int)(floorf(worldPos.x / kCELL_SIZE)) + kXZOffset,
|
||||
(int)(floorf(worldPos.y / kCELL_SIZE)),
|
||||
(int)(floorf(worldPos.z / kCELL_SIZE)) + kXZOffset);
|
||||
}
|
||||
|
||||
inline Vector3 worldSpaceToCellSpace(const Vector3& worldPos) {
|
||||
return Vector3(
|
||||
(worldPos.x * (1.0f / kCELL_SIZE)),
|
||||
(worldPos.y * (1.0f / kCELL_SIZE)),
|
||||
(worldPos.z * (1.0f / kCELL_SIZE)));
|
||||
}
|
||||
|
||||
inline Vector3 cellSpaceToWorldSpace(const Vector3& cellPos)
|
||||
{
|
||||
return Vector3(
|
||||
(cellPos.x * kCELL_SIZE),
|
||||
(cellPos.y * kCELL_SIZE),
|
||||
(cellPos.z * kCELL_SIZE));
|
||||
}
|
||||
|
||||
|
||||
inline Vector3 cellToWorld_smallestCorner(const Vector3int16& cellPos) {
|
||||
const int kXZOffset = 0;
|
||||
return Vector3(
|
||||
(cellPos.x - kXZOffset) * kCELL_SIZE,
|
||||
cellPos.y * kCELL_SIZE,
|
||||
(cellPos.z - kXZOffset) * kCELL_SIZE);
|
||||
|
||||
}
|
||||
|
||||
inline Vector3 cellToWorld_center(const Vector3int16& cellPos) {
|
||||
Vector3 pos = cellToWorld_smallestCorner(cellPos);
|
||||
return pos + Vector3(kHALF_CELL, kHALF_CELL, kHALF_CELL);
|
||||
}
|
||||
|
||||
inline Vector3 cellToWorld_largestCorner(const Vector3int16& cellPos) {
|
||||
return cellToWorld_smallestCorner(cellPos + Vector3int16(1, 1, 1));
|
||||
}
|
||||
|
||||
inline Region3int16 getTerrainExtentsInCells()
|
||||
{
|
||||
const int kRadius = 32000;
|
||||
|
||||
return Region3int16(Vector3int16(-kRadius, -kRadius, -kRadius), Vector3int16(kRadius, kRadius, kRadius));
|
||||
}
|
||||
|
||||
inline Extents getTerrainExtents()
|
||||
{
|
||||
Region3int16 extents = getTerrainExtentsInCells();
|
||||
|
||||
return Extents(cellToWorld_smallestCorner(extents.getMinPos()), cellToWorld_largestCorner(extents.getMaxPos()));
|
||||
}
|
||||
|
||||
} }
|
||||
Reference in New Issue
Block a user