mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 00:10:52 +02:00
better handling of changes to the size of voxel space. limit each dimension to 32
This commit is contained in:
parent
175926736d
commit
43a1519e29
4 changed files with 172 additions and 63 deletions
|
@ -53,15 +53,35 @@ RenderablePolyVoxEntityItem::~RenderablePolyVoxEntityItem() {
|
||||||
delete _volData;
|
delete _volData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool inBounds(const PolyVox::SimpleVolume<uint8_t>* vol, PolyVoxEntityItem::PolyVoxSurfaceStyle surfaceStyle,
|
||||||
|
int x, int y, int z) {
|
||||||
|
switch (surfaceStyle) {
|
||||||
|
case PolyVoxEntityItem::SURFACE_MARCHING_CUBES:
|
||||||
|
case PolyVoxEntityItem::SURFACE_CUBIC:
|
||||||
|
if (x < 0 || y < 0 || z < 0 ||
|
||||||
|
x >= vol->getWidth() || y >= vol->getHeight() || z >= vol->getDepth()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case PolyVoxEntityItem::SURFACE_EDGED_CUBIC:
|
||||||
|
if (x < 1 || y < 1 || z < 1 ||
|
||||||
|
x >= vol->getWidth() - 1 || y >= vol->getHeight() - 1 || z >= vol->getDepth() - 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void RenderablePolyVoxEntityItem::setVoxelVolumeSize(glm::vec3 voxelVolumeSize) {
|
void RenderablePolyVoxEntityItem::setVoxelVolumeSize(glm::vec3 voxelVolumeSize) {
|
||||||
if (_volData && voxelVolumeSize == _voxelVolumeSize) {
|
if (_volData && voxelVolumeSize == _voxelVolumeSize) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug() << "resetting voxel-space size";
|
qDebug() << "resetting voxel-space size" << voxelVolumeSize.x << voxelVolumeSize.y << voxelVolumeSize.z;
|
||||||
|
|
||||||
|
|
||||||
glm::vec3 previousVolumeSize = _voxelVolumeSize;
|
|
||||||
PolyVoxEntityItem::setVoxelVolumeSize(voxelVolumeSize);
|
PolyVoxEntityItem::setVoxelVolumeSize(voxelVolumeSize);
|
||||||
|
|
||||||
if (_volData) {
|
if (_volData) {
|
||||||
|
@ -71,21 +91,43 @@ void RenderablePolyVoxEntityItem::setVoxelVolumeSize(glm::vec3 voxelVolumeSize)
|
||||||
_onCount = 0;
|
_onCount = 0;
|
||||||
|
|
||||||
if (_voxelSurfaceStyle == SURFACE_EDGED_CUBIC) {
|
if (_voxelSurfaceStyle == SURFACE_EDGED_CUBIC) {
|
||||||
|
// with _EDGED_ we maintain an extra box of voxels around those that the user asked for. This
|
||||||
|
// changes how the surface extractor acts -- mainly it becomes impossible to have holes in the
|
||||||
|
// generated mesh. The non _EDGED_ modes will leave holes in the mesh at the edges of the
|
||||||
|
// voxel space.
|
||||||
PolyVox::Vector3DInt32 lowCorner(0, 0, 0);
|
PolyVox::Vector3DInt32 lowCorner(0, 0, 0);
|
||||||
PolyVox::Vector3DInt32 highCorner(_voxelVolumeSize[0] + 1, // -1 + 2 because these corners are inclusive
|
PolyVox::Vector3DInt32 highCorner(_voxelVolumeSize.x + 1, // -1 + 2 because these corners are inclusive
|
||||||
_voxelVolumeSize[1] + 1,
|
_voxelVolumeSize.y + 1,
|
||||||
_voxelVolumeSize[2] + 1);
|
_voxelVolumeSize.z + 1);
|
||||||
_volData = new PolyVox::SimpleVolume<uint8_t>(PolyVox::Region(lowCorner, highCorner));
|
_volData = new PolyVox::SimpleVolume<uint8_t>(PolyVox::Region(lowCorner, highCorner));
|
||||||
} else {
|
} else {
|
||||||
PolyVox::Vector3DInt32 lowCorner(0, 0, 0);
|
PolyVox::Vector3DInt32 lowCorner(0, 0, 0);
|
||||||
PolyVox::Vector3DInt32 highCorner(_voxelVolumeSize[0] - 1, // -1 because these corners are inclusive
|
PolyVox::Vector3DInt32 highCorner(_voxelVolumeSize.x - 1, // -1 because these corners are inclusive
|
||||||
_voxelVolumeSize[1] - 1,
|
_voxelVolumeSize.y - 1,
|
||||||
_voxelVolumeSize[2] - 1);
|
_voxelVolumeSize.z - 1);
|
||||||
_volData = new PolyVox::SimpleVolume<uint8_t>(PolyVox::Region(lowCorner, highCorner));
|
_volData = new PolyVox::SimpleVolume<uint8_t>(PolyVox::Region(lowCorner, highCorner));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// having the "outside of voxel-space" value be 255 has helped me notice some problems.
|
||||||
_volData->setBorderValue(255);
|
_volData->setBorderValue(255);
|
||||||
decompressVolumeData(previousVolumeSize);
|
|
||||||
compressVolumeData();
|
qDebug() << " new size is" << _volData->getWidth() << _volData->getHeight() << _volData->getDepth();
|
||||||
|
|
||||||
|
// I'm not sure this is needed... the docs say that each element is initialized with its default
|
||||||
|
// constructor. I'll leave it here for now.
|
||||||
|
for (int z = 0; z < _volData->getDepth(); z++) {
|
||||||
|
for (int y = 0; y < _volData->getHeight(); y++) {
|
||||||
|
for (int x = 0; x < _volData->getWidth(); x++) {
|
||||||
|
_volData->setVoxelAt(x, y, z, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// It's okay to decompress the old data here, because the data includes its original dimensions along
|
||||||
|
// with the voxel data, and writing voxels outside the bounds of the new space is harmless. This allows
|
||||||
|
// adjusting of the voxel-space size without overly mangling the shape. Shrinking the space and then
|
||||||
|
// restoring the previous size (without any edits in between) will put the original shape back.
|
||||||
|
decompressVolumeData();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderablePolyVoxEntityItem::setVoxelSurfaceStyle(PolyVoxSurfaceStyle voxelSurfaceStyle) {
|
void RenderablePolyVoxEntityItem::setVoxelSurfaceStyle(PolyVoxSurfaceStyle voxelSurfaceStyle) {
|
||||||
|
@ -153,8 +195,7 @@ glm::mat4 RenderablePolyVoxEntityItem::worldToVoxelMatrix() const {
|
||||||
|
|
||||||
uint8_t RenderablePolyVoxEntityItem::getVoxel(int x, int y, int z) {
|
uint8_t RenderablePolyVoxEntityItem::getVoxel(int x, int y, int z) {
|
||||||
assert(_volData);
|
assert(_volData);
|
||||||
if (x < 0 || y < 0 || z < 0 ||
|
if (!inBounds(_volData, _voxelSurfaceStyle, x, y, z)) {
|
||||||
x >= _voxelVolumeSize[0] || y >= _voxelVolumeSize[1] || z >= _voxelVolumeSize[2]) {
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,8 +211,7 @@ uint8_t RenderablePolyVoxEntityItem::getVoxel(int x, int y, int z) {
|
||||||
|
|
||||||
void RenderablePolyVoxEntityItem::setVoxel(int x, int y, int z, uint8_t toValue) {
|
void RenderablePolyVoxEntityItem::setVoxel(int x, int y, int z, uint8_t toValue) {
|
||||||
assert(_volData);
|
assert(_volData);
|
||||||
if (x < 0 || y < 0 || z < 0 ||
|
if (!inBounds(_volData, _voxelSurfaceStyle, x, y, z)) {
|
||||||
x >= _voxelVolumeSize[0] || y >= _voxelVolumeSize[1] || z >= _voxelVolumeSize[2]) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,6 +225,10 @@ void RenderablePolyVoxEntityItem::setVoxel(int x, int y, int z, uint8_t toValue)
|
||||||
|
|
||||||
void RenderablePolyVoxEntityItem::updateOnCount(int x, int y, int z, uint8_t toValue) {
|
void RenderablePolyVoxEntityItem::updateOnCount(int x, int y, int z, uint8_t toValue) {
|
||||||
// keep _onCount up to date
|
// keep _onCount up to date
|
||||||
|
if (!inBounds(_volData, _voxelSurfaceStyle, x, y, z)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t uVoxelValue = getVoxel(x, y, z);
|
uint8_t uVoxelValue = getVoxel(x, y, z);
|
||||||
if (toValue != 0) {
|
if (toValue != 0) {
|
||||||
if (uVoxelValue == 0) {
|
if (uVoxelValue == 0) {
|
||||||
|
@ -201,9 +245,9 @@ void RenderablePolyVoxEntityItem::updateOnCount(int x, int y, int z, uint8_t toV
|
||||||
|
|
||||||
|
|
||||||
void RenderablePolyVoxEntityItem::setAll(uint8_t toValue) {
|
void RenderablePolyVoxEntityItem::setAll(uint8_t toValue) {
|
||||||
for (int z = 0; z < _voxelVolumeSize[2]; z++) {
|
for (int z = 0; z < _voxelVolumeSize.z; z++) {
|
||||||
for (int y = 0; y < _voxelVolumeSize[1]; y++) {
|
for (int y = 0; y < _voxelVolumeSize.y; y++) {
|
||||||
for (int x = 0; x < _voxelVolumeSize[0]; x++) {
|
for (int x = 0; x < _voxelVolumeSize.x; x++) {
|
||||||
updateOnCount(x, y, z, toValue);
|
updateOnCount(x, y, z, toValue);
|
||||||
setVoxel(x, y, z, toValue);
|
setVoxel(x, y, z, toValue);
|
||||||
}
|
}
|
||||||
|
@ -214,9 +258,9 @@ void RenderablePolyVoxEntityItem::setAll(uint8_t toValue) {
|
||||||
|
|
||||||
void RenderablePolyVoxEntityItem::setSphereInVolume(glm::vec3 center, float radius, uint8_t toValue) {
|
void RenderablePolyVoxEntityItem::setSphereInVolume(glm::vec3 center, float radius, uint8_t toValue) {
|
||||||
// This three-level for loop iterates over every voxel in the volume
|
// This three-level for loop iterates over every voxel in the volume
|
||||||
for (int z = 0; z < _voxelVolumeSize[2]; z++) {
|
for (int z = 0; z < _voxelVolumeSize.z; z++) {
|
||||||
for (int y = 0; y < _voxelVolumeSize[1]; y++) {
|
for (int y = 0; y < _voxelVolumeSize.y; y++) {
|
||||||
for (int x = 0; x < _voxelVolumeSize[0]; x++) {
|
for (int x = 0; x < _voxelVolumeSize.x; x++) {
|
||||||
// Store our current position as a vector...
|
// Store our current position as a vector...
|
||||||
glm::vec3 pos(x + 0.5f, y + 0.5f, z + 0.5f); // consider voxels cenetered on their coordinates
|
glm::vec3 pos(x + 0.5f, y + 0.5f, z + 0.5f); // consider voxels cenetered on their coordinates
|
||||||
// And compute how far the current position is from the center of the volume
|
// And compute how far the current position is from the center of the volume
|
||||||
|
@ -236,7 +280,7 @@ void RenderablePolyVoxEntityItem::setSphere(glm::vec3 centerWorldCoords, float r
|
||||||
// glm::vec3 centerVoxelCoords = worldToVoxelCoordinates(centerWorldCoords);
|
// glm::vec3 centerVoxelCoords = worldToVoxelCoordinates(centerWorldCoords);
|
||||||
glm::vec4 centerVoxelCoords = worldToVoxelMatrix() * glm::vec4(centerWorldCoords, 1.0f);
|
glm::vec4 centerVoxelCoords = worldToVoxelMatrix() * glm::vec4(centerWorldCoords, 1.0f);
|
||||||
glm::vec3 scale = _dimensions / _voxelVolumeSize; // meters / voxel-units
|
glm::vec3 scale = _dimensions / _voxelVolumeSize; // meters / voxel-units
|
||||||
float scaleY = scale[0];
|
float scaleY = scale.y;
|
||||||
float radiusVoxelCoords = radiusWorldCoords / scaleY;
|
float radiusVoxelCoords = radiusWorldCoords / scaleY;
|
||||||
setSphereInVolume(glm::vec3(centerVoxelCoords), radiusVoxelCoords, toValue);
|
setSphereInVolume(glm::vec3(centerVoxelCoords), radiusVoxelCoords, toValue);
|
||||||
}
|
}
|
||||||
|
@ -356,17 +400,17 @@ void RenderablePolyVoxEntityItem::render(RenderArgs* args) {
|
||||||
class RaycastFunctor
|
class RaycastFunctor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RaycastFunctor(PolyVox::SimpleVolume<uint8_t>* vol) :
|
RaycastFunctor(PolyVox::SimpleVolume<uint8_t>* vol, PolyVoxEntityItem::PolyVoxSurfaceStyle voxelSurfaceStyle) :
|
||||||
_result(glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)),
|
_result(glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)),
|
||||||
_vol(vol) {
|
_vol(vol),
|
||||||
|
_voxelSurfaceStyle(voxelSurfaceStyle) {
|
||||||
}
|
}
|
||||||
bool operator()(PolyVox::SimpleVolume<unsigned char>::Sampler& sampler)
|
bool operator()(PolyVox::SimpleVolume<unsigned char>::Sampler& sampler)
|
||||||
{
|
{
|
||||||
int x = sampler.getPosition().getX();
|
int x = sampler.getPosition().getX();
|
||||||
int y = sampler.getPosition().getY();
|
int y = sampler.getPosition().getY();
|
||||||
int z = sampler.getPosition().getZ();
|
int z = sampler.getPosition().getZ();
|
||||||
if (x < 0 || y < 0 || z < 0 ||
|
if (!inBounds(_vol, _voxelSurfaceStyle, x, y, z)) {
|
||||||
x > _vol->getWidth() || y > _vol->getHeight() || z > _vol->getDepth()) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -379,6 +423,7 @@ public:
|
||||||
}
|
}
|
||||||
glm::vec4 _result;
|
glm::vec4 _result;
|
||||||
const PolyVox::SimpleVolume<uint8_t>* _vol = nullptr;
|
const PolyVox::SimpleVolume<uint8_t>* _vol = nullptr;
|
||||||
|
PolyVoxEntityItem::PolyVoxSurfaceStyle _voxelSurfaceStyle;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool RenderablePolyVoxEntityItem::findDetailedRayIntersection(const glm::vec3& origin,
|
bool RenderablePolyVoxEntityItem::findDetailedRayIntersection(const glm::vec3& origin,
|
||||||
|
@ -400,19 +445,19 @@ bool RenderablePolyVoxEntityItem::findDetailedRayIntersection(const glm::vec3& o
|
||||||
|
|
||||||
// set ray cast length to long enough to cover all of the voxel space
|
// set ray cast length to long enough to cover all of the voxel space
|
||||||
float distanceToEntity = glm::distance(origin, _position);
|
float distanceToEntity = glm::distance(origin, _position);
|
||||||
float largestDimension = glm::max(_dimensions[0], _dimensions[1], _dimensions[2]) * 2.0f;
|
float largestDimension = glm::max(_dimensions.x, _dimensions.y, _dimensions.z) * 2.0f;
|
||||||
|
|
||||||
glm::vec3 farPoint = origin + normDirection * (distanceToEntity + largestDimension);
|
glm::vec3 farPoint = origin + normDirection * (distanceToEntity + largestDimension);
|
||||||
|
|
||||||
glm::vec4 originInVoxel = wtvMatrix * glm::vec4(origin, 1.0f);
|
glm::vec4 originInVoxel = wtvMatrix * glm::vec4(origin, 1.0f);
|
||||||
glm::vec4 farInVoxel = wtvMatrix * glm::vec4(farPoint, 1.0f);
|
glm::vec4 farInVoxel = wtvMatrix * glm::vec4(farPoint, 1.0f);
|
||||||
|
|
||||||
PolyVox::Vector3DFloat start(originInVoxel[0], originInVoxel[1], originInVoxel[2]);
|
PolyVox::Vector3DFloat start(originInVoxel.x, originInVoxel.y, originInVoxel.z);
|
||||||
// PolyVox::Vector3DFloat pvDirection(directionInVoxel[0], directionInVoxel[1], directionInVoxel[2]);
|
// PolyVox::Vector3DFloat pvDirection(directionInVoxel.x, directionInVoxel.y, directionInVoxel.z);
|
||||||
PolyVox::Vector3DFloat far(farInVoxel[0], farInVoxel[1], farInVoxel[2]);
|
PolyVox::Vector3DFloat far(farInVoxel.x, farInVoxel.y, farInVoxel.z);
|
||||||
|
|
||||||
PolyVox::RaycastResult raycastResult;
|
PolyVox::RaycastResult raycastResult;
|
||||||
RaycastFunctor callback(_volData);
|
RaycastFunctor callback(_volData, _voxelSurfaceStyle);
|
||||||
raycastResult = PolyVox::raycastWithEndpoints(_volData, start, far, callback);
|
raycastResult = PolyVox::raycastWithEndpoints(_volData, start, far, callback);
|
||||||
|
|
||||||
if (raycastResult == PolyVox::RaycastResults::Completed) {
|
if (raycastResult == PolyVox::RaycastResults::Completed) {
|
||||||
|
@ -445,31 +490,42 @@ bool RenderablePolyVoxEntityItem::findDetailedRayIntersection(const glm::vec3& o
|
||||||
// compress the data in _volData and save the results. The compressed form is used during
|
// compress the data in _volData and save the results. The compressed form is used during
|
||||||
// saves to disk and for transmission over the wire
|
// saves to disk and for transmission over the wire
|
||||||
void RenderablePolyVoxEntityItem::compressVolumeData() {
|
void RenderablePolyVoxEntityItem::compressVolumeData() {
|
||||||
int rawSize = _voxelVolumeSize[0] * _voxelVolumeSize[1] * _voxelVolumeSize[2];
|
quint16 voxelXSize = _voxelVolumeSize.x;
|
||||||
|
quint16 voxelYSize = _voxelVolumeSize.y;
|
||||||
|
quint16 voxelZSize = _voxelVolumeSize.z;
|
||||||
|
int rawSize = voxelXSize * voxelYSize * voxelZSize;
|
||||||
|
|
||||||
QByteArray uncompressedData = QByteArray(rawSize, '\0');
|
QByteArray uncompressedData = QByteArray(rawSize, '\0');
|
||||||
|
|
||||||
for (int z = 0; z < _voxelVolumeSize[2]; z++) {
|
for (int z = 0; z < voxelZSize; z++) {
|
||||||
for (int y = 0; y < _voxelVolumeSize[1]; y++) {
|
for (int y = 0; y < voxelYSize; y++) {
|
||||||
for (int x = 0; x < _voxelVolumeSize[0]; x++) {
|
for (int x = 0; x < voxelXSize; x++) {
|
||||||
uint8_t uVoxelValue = getVoxel(x, y, z);
|
uint8_t uVoxelValue = getVoxel(x, y, z);
|
||||||
int uncompressedIndex =
|
int uncompressedIndex =
|
||||||
z * _voxelVolumeSize[1] * _voxelVolumeSize[0] +
|
z * voxelYSize * voxelXSize +
|
||||||
y * _voxelVolumeSize[0] +
|
y * voxelXSize +
|
||||||
x;
|
x;
|
||||||
uncompressedData[uncompressedIndex] = uVoxelValue;
|
uncompressedData[uncompressedIndex] = uVoxelValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray newVoxelData = qCompress(uncompressedData, 9);
|
QByteArray newVoxelData;
|
||||||
// HACK -- until we have a way to allow for properties larger than MTU, don't update.
|
QDataStream writer(&newVoxelData, QIODevice::WriteOnly | QIODevice::Truncate);
|
||||||
if (newVoxelData.length() < 1200) {
|
writer << voxelXSize << voxelYSize << voxelZSize;
|
||||||
|
|
||||||
|
QByteArray compressedData = qCompress(uncompressedData, 9);
|
||||||
|
writer << compressedData;
|
||||||
|
|
||||||
|
// make sure the compressed data can be sent over the wire-protocol
|
||||||
|
if (newVoxelData.size() < 1150) {
|
||||||
_voxelData = newVoxelData;
|
_voxelData = newVoxelData;
|
||||||
qDebug() << "-------------- voxel compresss --------------";
|
qDebug() << "-------------- voxel compresss --------------";
|
||||||
qDebug() << "raw-size =" << rawSize << " compressed-size =" << newVoxelData.size();
|
qDebug() << "raw-size =" << rawSize << " compressed-size =" << newVoxelData.size();
|
||||||
} else {
|
} else {
|
||||||
|
// HACK -- until we have a way to allow for properties larger than MTU, don't update.
|
||||||
qDebug() << "voxel data too large, reverting change.";
|
qDebug() << "voxel data too large, reverting change.";
|
||||||
// revert
|
// revert the active voxel-space to the last version that fit.
|
||||||
decompressVolumeData();
|
decompressVolumeData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -478,25 +534,38 @@ void RenderablePolyVoxEntityItem::compressVolumeData() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// take compressed data and decompreess it into _volData.
|
// take compressed data and expand it into _volData.
|
||||||
void RenderablePolyVoxEntityItem::decompressVolumeData() {
|
void RenderablePolyVoxEntityItem::decompressVolumeData() {
|
||||||
decompressVolumeData(_voxelVolumeSize);
|
QDataStream reader(_voxelData);
|
||||||
}
|
quint16 voxelXSize, voxelYSize, voxelZSize;
|
||||||
|
reader >> voxelXSize;
|
||||||
|
reader >> voxelYSize;
|
||||||
|
reader >> voxelZSize;
|
||||||
|
|
||||||
|
if (voxelXSize == 0 || voxelXSize > MAX_VOXEL_DIMENSION ||
|
||||||
|
voxelYSize == 0 || voxelYSize > MAX_VOXEL_DIMENSION ||
|
||||||
|
voxelZSize == 0 || voxelZSize > MAX_VOXEL_DIMENSION) {
|
||||||
|
qDebug() << "vixelSize is not reasonable, skipping decompressions."
|
||||||
|
<< voxelXSize << voxelYSize << voxelZSize;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
void RenderablePolyVoxEntityItem::decompressVolumeData(glm::vec3 volumeSize) {
|
int rawSize = voxelXSize * voxelYSize * voxelZSize;
|
||||||
int rawSize = volumeSize[0] * volumeSize[1] * volumeSize[2];
|
|
||||||
QByteArray uncompressedData = QByteArray(rawSize, '\0');
|
|
||||||
|
|
||||||
uncompressedData = qUncompress(_voxelData);
|
QByteArray compressedData;
|
||||||
|
reader >> compressedData;
|
||||||
|
QByteArray uncompressedData = qUncompress(compressedData);
|
||||||
|
|
||||||
for (int z = 0; z < volumeSize[2]; z++) {
|
if (uncompressedData.size() != rawSize) {
|
||||||
for (int y = 0; y < volumeSize[1]; y++) {
|
qDebug() << "PolyVox decompress -- size is (" << voxelXSize << voxelYSize << voxelZSize << ")" <<
|
||||||
for (int x = 0; x < volumeSize[0]; x++) {
|
"so expected uncompressed length of" << rawSize << "but length is" << uncompressedData.size();
|
||||||
int uncompressedIndex =
|
return;
|
||||||
z * volumeSize[1] * volumeSize[0] +
|
}
|
||||||
y * volumeSize[0] +
|
|
||||||
x;
|
for (int z = 0; z < voxelZSize; z++) {
|
||||||
|
for (int y = 0; y < voxelYSize; y++) {
|
||||||
|
for (int x = 0; x < voxelXSize; x++) {
|
||||||
|
int uncompressedIndex = (z * voxelYSize * voxelXSize) + (y * voxelZSize) + x;
|
||||||
updateOnCount(x, y, z, uncompressedData[uncompressedIndex]);
|
updateOnCount(x, y, z, uncompressedData[uncompressedIndex]);
|
||||||
setVoxel(x, y, z, uncompressedData[uncompressedIndex]);
|
setVoxel(x, y, z, uncompressedData[uncompressedIndex]);
|
||||||
}
|
}
|
||||||
|
@ -544,9 +613,9 @@ void RenderablePolyVoxEntityItem::computeShapeInfo(ShapeInfo& info) {
|
||||||
|
|
||||||
AABox box;
|
AABox box;
|
||||||
|
|
||||||
for (int z = 0; z < _voxelVolumeSize[2]; z++) {
|
for (int z = 0; z < _voxelVolumeSize.z; z++) {
|
||||||
for (int y = 0; y < _voxelVolumeSize[1]; y++) {
|
for (int y = 0; y < _voxelVolumeSize.y; y++) {
|
||||||
for (int x = 0; x < _voxelVolumeSize[0]; x++) {
|
for (int x = 0; x < _voxelVolumeSize.x; x++) {
|
||||||
if (getVoxel(x, y, z) > 0) {
|
if (getVoxel(x, y, z) > 0) {
|
||||||
QVector<glm::vec3> pointsInPart;
|
QVector<glm::vec3> pointsInPart;
|
||||||
|
|
||||||
|
|
|
@ -70,9 +70,11 @@ public:
|
||||||
virtual void setAll(uint8_t toValue);
|
virtual void setAll(uint8_t toValue);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// The PolyVoxEntityItem class has _voxelData which contains dimensions and compressed voxel data. The dimensions
|
||||||
|
// may not match _voxelVolumeSize.
|
||||||
|
|
||||||
void compressVolumeData();
|
void compressVolumeData();
|
||||||
void decompressVolumeData();
|
void decompressVolumeData();
|
||||||
void decompressVolumeData(glm::vec3 volumeSize);
|
|
||||||
|
|
||||||
PolyVox::SimpleVolume<uint8_t>* _volData = nullptr;
|
PolyVox::SimpleVolume<uint8_t>* _volData = nullptr;
|
||||||
model::Geometry _modelGeometry;
|
model::Geometry _modelGeometry;
|
||||||
|
|
|
@ -22,7 +22,8 @@
|
||||||
|
|
||||||
|
|
||||||
const glm::vec3 PolyVoxEntityItem::DEFAULT_VOXEL_VOLUME_SIZE = glm::vec3(32, 32, 32);
|
const glm::vec3 PolyVoxEntityItem::DEFAULT_VOXEL_VOLUME_SIZE = glm::vec3(32, 32, 32);
|
||||||
const QByteArray PolyVoxEntityItem::DEFAULT_VOXEL_DATA(qCompress(QByteArray(0), 9));
|
const float PolyVoxEntityItem::MAX_VOXEL_DIMENSION = 32.0f;
|
||||||
|
const QByteArray PolyVoxEntityItem::DEFAULT_VOXEL_DATA(qCompress(QByteArray(0), 9)); // XXX
|
||||||
const PolyVoxEntityItem::PolyVoxSurfaceStyle PolyVoxEntityItem::DEFAULT_VOXEL_SURFACE_STYLE =
|
const PolyVoxEntityItem::PolyVoxSurfaceStyle PolyVoxEntityItem::DEFAULT_VOXEL_SURFACE_STYLE =
|
||||||
PolyVoxEntityItem::SURFACE_MARCHING_CUBES;
|
PolyVoxEntityItem::SURFACE_MARCHING_CUBES;
|
||||||
|
|
||||||
|
@ -41,6 +42,40 @@ PolyVoxEntityItem::PolyVoxEntityItem(const EntityItemID& entityItemID, const Ent
|
||||||
setProperties(properties);
|
setProperties(properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PolyVoxEntityItem::setVoxelVolumeSize(glm::vec3 voxelVolumeSize) {
|
||||||
|
assert((int)_voxelVolumeSize.x == _voxelVolumeSize.x);
|
||||||
|
assert((int)_voxelVolumeSize.y == _voxelVolumeSize.y);
|
||||||
|
assert((int)_voxelVolumeSize.z == _voxelVolumeSize.z);
|
||||||
|
|
||||||
|
_voxelVolumeSize = voxelVolumeSize;
|
||||||
|
if (_voxelVolumeSize.x < 1) {
|
||||||
|
qDebug() << "PolyVoxEntityItem::setVoxelVolumeSize clamping x of" << _voxelVolumeSize.x << "to 1";
|
||||||
|
_voxelVolumeSize.x = 1;
|
||||||
|
}
|
||||||
|
if (_voxelVolumeSize.x > MAX_VOXEL_DIMENSION) {
|
||||||
|
qDebug() << "PolyVoxEntityItem::setVoxelVolumeSize clamping x of" << _voxelVolumeSize.x << "to max";
|
||||||
|
_voxelVolumeSize.x = MAX_VOXEL_DIMENSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_voxelVolumeSize.y < 1) {
|
||||||
|
qDebug() << "PolyVoxEntityItem::setVoxelVolumeSize clamping y of" << _voxelVolumeSize.y << "to 1";
|
||||||
|
_voxelVolumeSize.y = 1;
|
||||||
|
}
|
||||||
|
if (_voxelVolumeSize.y > MAX_VOXEL_DIMENSION) {
|
||||||
|
qDebug() << "PolyVoxEntityItem::setVoxelVolumeSize clamping y of" << _voxelVolumeSize.y << "to max";
|
||||||
|
_voxelVolumeSize.y = MAX_VOXEL_DIMENSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_voxelVolumeSize.z < 1) {
|
||||||
|
qDebug() << "PolyVoxEntityItem::setVoxelVolumeSize clamping z of" << _voxelVolumeSize.z << "to 1";
|
||||||
|
_voxelVolumeSize.z = 1;
|
||||||
|
}
|
||||||
|
if (_voxelVolumeSize.z > MAX_VOXEL_DIMENSION) {
|
||||||
|
qDebug() << "PolyVoxEntityItem::setVoxelVolumeSize clamping z of" << _voxelVolumeSize.z << "to max";
|
||||||
|
_voxelVolumeSize.z = MAX_VOXEL_DIMENSION;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
EntityItemProperties PolyVoxEntityItem::getProperties() const {
|
EntityItemProperties PolyVoxEntityItem::getProperties() const {
|
||||||
EntityItemProperties properties = EntityItem::getProperties(); // get the properties from our base class
|
EntityItemProperties properties = EntityItem::getProperties(); // get the properties from our base class
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(voxelVolumeSize, getVoxelVolumeSize);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(voxelVolumeSize, getVoxelVolumeSize);
|
||||||
|
|
|
@ -49,7 +49,7 @@ class PolyVoxEntityItem : public EntityItem {
|
||||||
|
|
||||||
virtual void debugDump() const;
|
virtual void debugDump() const;
|
||||||
|
|
||||||
virtual void setVoxelVolumeSize(glm::vec3 voxelVolumeSize) { _voxelVolumeSize = voxelVolumeSize; }
|
virtual void setVoxelVolumeSize(glm::vec3 voxelVolumeSize);
|
||||||
virtual const glm::vec3& getVoxelVolumeSize() const { return _voxelVolumeSize; }
|
virtual const glm::vec3& getVoxelVolumeSize() const { return _voxelVolumeSize; }
|
||||||
|
|
||||||
virtual void setVoxelData(QByteArray voxelData) { _voxelData = voxelData; }
|
virtual void setVoxelData(QByteArray voxelData) { _voxelData = voxelData; }
|
||||||
|
@ -68,6 +68,8 @@ class PolyVoxEntityItem : public EntityItem {
|
||||||
virtual PolyVoxSurfaceStyle getVoxelSurfaceStyle() const { return _voxelSurfaceStyle; }
|
virtual PolyVoxSurfaceStyle getVoxelSurfaceStyle() const { return _voxelSurfaceStyle; }
|
||||||
|
|
||||||
static const glm::vec3 DEFAULT_VOXEL_VOLUME_SIZE;
|
static const glm::vec3 DEFAULT_VOXEL_VOLUME_SIZE;
|
||||||
|
static const float MAX_VOXEL_DIMENSION;
|
||||||
|
|
||||||
static const QByteArray DEFAULT_VOXEL_DATA;
|
static const QByteArray DEFAULT_VOXEL_DATA;
|
||||||
static const PolyVoxSurfaceStyle DEFAULT_VOXEL_SURFACE_STYLE;
|
static const PolyVoxSurfaceStyle DEFAULT_VOXEL_SURFACE_STYLE;
|
||||||
|
|
||||||
|
@ -82,6 +84,7 @@ class PolyVoxEntityItem : public EntityItem {
|
||||||
virtual uint8_t getVoxel(int x, int y, int z) { return 0; }
|
virtual uint8_t getVoxel(int x, int y, int z) { return 0; }
|
||||||
virtual void setVoxel(int x, int y, int z, uint8_t toValue) {}
|
virtual void setVoxel(int x, int y, int z, uint8_t toValue) {}
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
glm::vec3 _voxelVolumeSize; // this is always 3 bytes
|
glm::vec3 _voxelVolumeSize; // this is always 3 bytes
|
||||||
QByteArray _voxelData;
|
QByteArray _voxelData;
|
||||||
|
|
Loading…
Reference in a new issue