mirror of
https://github.com/overte-org/overte.git
synced 2025-08-10 10:43:21 +02:00
more work on polyvox threading
This commit is contained in:
parent
91254245e4
commit
7cb9968864
4 changed files with 281 additions and 78 deletions
|
@ -38,7 +38,6 @@
|
||||||
#include <PolyVoxCore/Material.h>
|
#include <PolyVoxCore/Material.h>
|
||||||
|
|
||||||
#include "model/Geometry.h"
|
#include "model/Geometry.h"
|
||||||
#include "gpu/Context.h"
|
|
||||||
#include "EntityTreeRenderer.h"
|
#include "EntityTreeRenderer.h"
|
||||||
#include "polyvox_vert.h"
|
#include "polyvox_vert.h"
|
||||||
#include "polyvox_frag.h"
|
#include "polyvox_frag.h"
|
||||||
|
@ -46,6 +45,8 @@
|
||||||
#include "EntityEditPacketSender.h"
|
#include "EntityEditPacketSender.h"
|
||||||
#include "PhysicalEntitySimulation.h"
|
#include "PhysicalEntitySimulation.h"
|
||||||
|
|
||||||
|
#define THREAD_POLYVOX 1
|
||||||
|
|
||||||
gpu::PipelinePointer RenderablePolyVoxEntityItem::_pipeline = nullptr;
|
gpu::PipelinePointer RenderablePolyVoxEntityItem::_pipeline = nullptr;
|
||||||
const float MARCHING_CUBE_COLLISION_HULL_OFFSET = 0.5;
|
const float MARCHING_CUBE_COLLISION_HULL_OFFSET = 0.5;
|
||||||
|
|
||||||
|
@ -56,21 +57,46 @@ EntityItemPointer RenderablePolyVoxEntityItem::factory(const EntityItemID& entit
|
||||||
RenderablePolyVoxEntityItem::RenderablePolyVoxEntityItem(const EntityItemID& entityItemID,
|
RenderablePolyVoxEntityItem::RenderablePolyVoxEntityItem(const EntityItemID& entityItemID,
|
||||||
const EntityItemProperties& properties) :
|
const EntityItemProperties& properties) :
|
||||||
PolyVoxEntityItem(entityItemID, properties),
|
PolyVoxEntityItem(entityItemID, properties),
|
||||||
|
_mesh(new model::Mesh()),
|
||||||
_xTexture(nullptr),
|
_xTexture(nullptr),
|
||||||
_yTexture(nullptr),
|
_yTexture(nullptr),
|
||||||
_zTexture(nullptr),
|
_zTexture(nullptr),
|
||||||
_async(DEFAULT_VOXEL_SURFACE_STYLE, DEFAULT_VOXEL_VOLUME_SIZE, this) {
|
_async(DEFAULT_VOXEL_SURFACE_STYLE, DEFAULT_VOXEL_VOLUME_SIZE, this) {
|
||||||
|
|
||||||
model::Mesh* mesh = new model::Mesh();
|
// model::Mesh* mesh = new model::Mesh();
|
||||||
model::MeshPointer meshPtr(mesh);
|
// model::MeshPointer meshPtr(mesh);
|
||||||
receiveNewMesh(meshPtr, _modelVersion);
|
|
||||||
|
// mesh->setIndexBuffer(nullptr);
|
||||||
|
|
||||||
|
// auto vertexBuffer = std::make_shared<gpu::Buffer>(0, (gpu::Byte*)"");
|
||||||
|
// auto vertexBufferPtr = gpu::BufferPointer(vertexBuffer);
|
||||||
|
// auto vertexBufferView = new gpu::BufferView(vertexBufferPtr,
|
||||||
|
// 0,
|
||||||
|
// vertexBufferPtr->getSize() - sizeof(float) * 3,
|
||||||
|
// sizeof(PolyVox::PositionMaterialNormal),
|
||||||
|
// gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::RAW));
|
||||||
|
// mesh->setVertexBuffer(*vertexBufferView);
|
||||||
|
|
||||||
|
// _mesh = meshPtr;
|
||||||
|
// _modelGeometry.setMesh(meshPtr);
|
||||||
|
|
||||||
|
// qDebug() << "5d301155-faf9-44dd-8e8b-061a03d42c0f" << "IN CONSTRUCTOR" << getID() << _voxelData;
|
||||||
|
// _async.decompressVolumeData(_voxelData, ++_modelVersion);
|
||||||
|
// _async.updateVoxelSurfaceStyle(_voxelSurfaceStyle, ++_modelVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderablePolyVoxEntityItem::~RenderablePolyVoxEntityItem() {
|
RenderablePolyVoxEntityItem::~RenderablePolyVoxEntityItem() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RenderablePolyVoxEntityItem::receiveNewVoxelData(QByteArray newVoxelData, uint64_t dataVersion) {
|
void RenderablePolyVoxEntityItem::receiveNewVoxelData(QByteArray newVoxelData, quint64 dataVersion) {
|
||||||
|
if (dataVersion <= _dataVersion) {
|
||||||
|
// qDebug() << _id << "OKOKOK NOPE" << QString(__PRETTY_FUNCTION__) << getName() << dataVersion << _dataVersion;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// qDebug() << _id << "OKOKOK!!!" << QString(__PRETTY_FUNCTION__) << getName() << dataVersion << _dataVersion << "mesh-size is" << _mesh->getNumVertices();
|
||||||
|
|
||||||
_voxelData = newVoxelData;
|
_voxelData = newVoxelData;
|
||||||
_dataVersion = dataVersion;
|
_dataVersion = dataVersion;
|
||||||
|
|
||||||
|
@ -93,44 +119,79 @@ void RenderablePolyVoxEntityItem::receiveNewVoxelData(QByteArray newVoxelData, u
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RenderablePolyVoxEntityItem::receiveNewMesh(model::MeshPointer newMeshPtr, uint64_t meshVersion) {
|
void RenderablePolyVoxEntityItem::receiveNewMesh(model::MeshPointer newMeshPtr, quint64 meshVersion) {
|
||||||
|
if (meshVersion <= _meshVersion) {
|
||||||
|
// qDebug() << _id << "OKOKOK NOPE" << QString(__PRETTY_FUNCTION__) << getName() << meshVersion << _meshVersion;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// int meshSize = -1;
|
||||||
|
// const model::MeshPointer mesh = _modelGeometry.getMesh();
|
||||||
|
// if (mesh) {
|
||||||
|
// mesh->getVertexBuffer()._size;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// qDebug() << _id << "OKOKOK!!!" << QString(__PRETTY_FUNCTION__) << getName() << meshVersion << _meshVersion << "mesh-size is" << meshSize;
|
||||||
|
// qDebug() << _id << "OKOKOK!!!" << QString(__PRETTY_FUNCTION__) << getName() << meshVersion << _meshVersion << "mesh-size is" << _mesh->getNumVertices() << "new mesh-size is" << newMeshPtr->getNumVertices();
|
||||||
|
|
||||||
_dirtyFlags |= EntityItem::DIRTY_SHAPE | EntityItem::DIRTY_MASS;
|
_dirtyFlags |= EntityItem::DIRTY_SHAPE | EntityItem::DIRTY_MASS;
|
||||||
_modelGeometryLock.lockForWrite();
|
_modelGeometryLock.lockForWrite();
|
||||||
_modelGeometry.setMesh(newMeshPtr);
|
// _modelGeometry.setMesh(newMeshPtr);
|
||||||
|
_mesh = newMeshPtr;
|
||||||
_meshVersion = meshVersion;
|
_meshVersion = meshVersion;
|
||||||
_modelGeometryLock.unlock();
|
_modelGeometryLock.unlock();
|
||||||
|
|
||||||
|
// qDebug() << _id << "OKOKOK after" << getName() << " mesh-size is" << _modelGeometry.getMesh()->getVertexBuffer()._size << "\n";
|
||||||
|
// qDebug() << _id << "OKOKOK after" << getName() << " mesh-size is" << _mesh->getNumVertices();
|
||||||
|
// qDebug() << _id << "OKOKOK after" << getName() << " mesh-size is" << newMeshPtr->getNumVertices();
|
||||||
|
|
||||||
computeShapeInfoWorker();
|
computeShapeInfoWorker();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderablePolyVoxEntityItem::setVoxelData(QByteArray voxelData) {
|
void RenderablePolyVoxEntityItem::setVoxelData(QByteArray voxelData) {
|
||||||
if (voxelData == _voxelData) {
|
// qDebug() << "5d301155-faf9-44dd-8e8b-061a03d42c0f setVoxelData for" << getName() << getID() << ((void *)this);
|
||||||
|
|
||||||
|
_voxelDataLock.lockForWrite();
|
||||||
|
if (/*_dataVersion > 1 &&*/ _voxelData == voxelData) {
|
||||||
|
// qDebug() << _id << "OKOKOK NOPE" << QString(__PRETTY_FUNCTION__) << getName() << _dataVersion << getID() << ((void *)this);
|
||||||
|
_voxelDataLock.unlock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// qDebug() << _id << "OKOKOK" << QString(__PRETTY_FUNCTION__) << getName() << _dataVersion;
|
||||||
|
|
||||||
_voxelData = voxelData;
|
_voxelData = voxelData;
|
||||||
_async.decompressVolumeData(_voxelData, ++_modelVersion);
|
_async.decompressVolumeData(_voxelData, ++_modelVersion);
|
||||||
|
_voxelDataLock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderablePolyVoxEntityItem::setVoxelVolumeSize(glm::vec3 voxelVolumeSize) {
|
void RenderablePolyVoxEntityItem::setVoxelVolumeSize(glm::vec3 voxelVolumeSize) {
|
||||||
if (voxelVolumeSize == _voxelVolumeSize) {
|
if (/*_meshVersion > 1 && _shapeVersion > 1 &&*/ _voxelVolumeSize == voxelVolumeSize) {
|
||||||
|
// qDebug() << _id << "OKOKOK NOPE" << QString(__PRETTY_FUNCTION__) << getName() << _meshVersion << ((void *)this);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// qDebug() << _id << "OKOKOK" << QString(__PRETTY_FUNCTION__) << getName() << ((void *)this);
|
||||||
|
|
||||||
PolyVoxEntityItem::setVoxelVolumeSize(voxelVolumeSize);
|
PolyVoxEntityItem::setVoxelVolumeSize(voxelVolumeSize);
|
||||||
_async.setVoxelVolumeSize(_voxelVolumeSize);
|
_async.setVoxelVolumeSize(_voxelVolumeSize);
|
||||||
// decompress the old data here, because the data includes its original dimensions along with the voxel data,
|
// 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
|
// 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
|
// 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.
|
// size (without any edits in between) will put the original shape back.
|
||||||
|
_voxelDataLock.lockForRead();
|
||||||
_async.decompressVolumeData(_voxelData, ++_modelVersion);
|
_async.decompressVolumeData(_voxelData, ++_modelVersion);
|
||||||
|
_voxelDataLock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderablePolyVoxEntityItem::setVoxelSurfaceStyle(PolyVoxSurfaceStyle voxelSurfaceStyle) {
|
void RenderablePolyVoxEntityItem::setVoxelSurfaceStyle(PolyVoxSurfaceStyle voxelSurfaceStyle) {
|
||||||
if (_voxelSurfaceStyle == voxelSurfaceStyle) {
|
if (/*_meshVersion > 1 && _shapeVersion > 1 &&*/ _voxelSurfaceStyle == voxelSurfaceStyle) {
|
||||||
|
// qDebug() << _id << "OKOKOK NOPE" << QString(__PRETTY_FUNCTION__) << getName() << _meshVersion;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// qDebug() << _id << "OKOKOK" << QString(__PRETTY_FUNCTION__) << getName();
|
||||||
|
|
||||||
_voxelSurfaceStyle = voxelSurfaceStyle;
|
_voxelSurfaceStyle = voxelSurfaceStyle;
|
||||||
_async.updateVoxelSurfaceStyle(_voxelSurfaceStyle, ++_modelVersion);
|
_async.updateVoxelSurfaceStyle(_voxelSurfaceStyle, ++_modelVersion);
|
||||||
}
|
}
|
||||||
|
@ -351,17 +412,15 @@ ShapeType RenderablePolyVoxEntityItem::getShapeType() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RenderablePolyVoxEntityItem::isReadyToComputeShape() {
|
bool RenderablePolyVoxEntityItem::isReadyToComputeShape() {
|
||||||
#ifdef WANT_DEBUG
|
|
||||||
qDebug() << "RenderablePolyVoxEntityItem::isReadyToComputeShape" << getName() << _shapeVersion << _modelVersion;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return (_shapeVersion == _modelVersion);
|
return (_shapeVersion == _modelVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RenderablePolyVoxEntityItem::computeShapeInfoWorker() {
|
bool RenderablePolyVoxEntityItem::computeShapeInfoWorker() {
|
||||||
ShapeType type = getShapeType();
|
ShapeType type = getShapeType();
|
||||||
if (type != SHAPE_TYPE_COMPOUND) {
|
if (type != SHAPE_TYPE_COMPOUND) {
|
||||||
|
_shapeInfoLock.lockForWrite();
|
||||||
EntityItem::computeShapeInfo(_shapeInfo);
|
EntityItem::computeShapeInfo(_shapeInfo);
|
||||||
|
_shapeInfoLock.unlock();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -374,12 +433,16 @@ bool RenderablePolyVoxEntityItem::computeShapeInfoWorker() {
|
||||||
/* pull each triangle in the mesh into a polyhedron which can be collided with */
|
/* pull each triangle in the mesh into a polyhedron which can be collided with */
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
|
|
||||||
_modelGeometryLock.lockForRead();
|
// _modelGeometryLock.lockForRead();
|
||||||
const model::MeshPointer mesh = _modelGeometry.getMesh();
|
// const model::MeshPointer mesh = _modelGeometry.getMesh();
|
||||||
_modelGeometryLock.unlock();
|
// _modelGeometryLock.unlock();
|
||||||
|
|
||||||
|
model::MeshPointer mesh = _mesh;
|
||||||
|
_modelGeometryLock.lockForRead();
|
||||||
const gpu::BufferView vertexBufferView = mesh->getVertexBuffer();
|
const gpu::BufferView vertexBufferView = mesh->getVertexBuffer();
|
||||||
const gpu::BufferView& indexBufferView = mesh->getIndexBuffer();
|
const gpu::BufferView& indexBufferView = mesh->getIndexBuffer();
|
||||||
|
_modelGeometryLock.unlock();
|
||||||
|
|
||||||
gpu::BufferView::Iterator<const uint32_t> it = indexBufferView.cbegin<uint32_t>();
|
gpu::BufferView::Iterator<const uint32_t> it = indexBufferView.cbegin<uint32_t>();
|
||||||
while (it != indexBufferView.cend<uint32_t>()) {
|
while (it != indexBufferView.cend<uint32_t>()) {
|
||||||
uint32_t p0Index = *(it++);
|
uint32_t p0Index = *(it++);
|
||||||
|
@ -482,21 +545,26 @@ bool RenderablePolyVoxEntityItem::computeShapeInfoWorker() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (points.isEmpty()) {
|
if (points.isEmpty()) {
|
||||||
|
_shapeInfoLock.lockForWrite();
|
||||||
EntityItem::computeShapeInfo(_shapeInfo);
|
EntityItem::computeShapeInfo(_shapeInfo);
|
||||||
|
_shapeInfoLock.unlock();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 collisionModelDimensions = box.getDimensions();
|
glm::vec3 collisionModelDimensions = box.getDimensions();
|
||||||
QByteArray b64 = _voxelData.toBase64();
|
QByteArray b64 = _voxelData.toBase64();
|
||||||
|
_shapeInfoLock.lockForWrite();
|
||||||
_shapeInfo.setParams(type, collisionModelDimensions, QString(b64));
|
_shapeInfo.setParams(type, collisionModelDimensions, QString(b64));
|
||||||
_shapeInfo.setConvexHulls(points);
|
_shapeInfo.setConvexHulls(points);
|
||||||
|
|
||||||
_shapeVersion = _modelVersion;
|
_shapeVersion = _modelVersion;
|
||||||
|
_shapeInfoLock.unlock();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderablePolyVoxEntityItem::computeShapeInfo(ShapeInfo& info) {
|
void RenderablePolyVoxEntityItem::computeShapeInfo(ShapeInfo& info) {
|
||||||
|
_shapeInfoLock.lockForRead();
|
||||||
info = _shapeInfo;
|
info = _shapeInfo;
|
||||||
|
_shapeInfoLock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderablePolyVoxEntityItem::setXTextureURL(QString xTextureURL) {
|
void RenderablePolyVoxEntityItem::setXTextureURL(QString xTextureURL) {
|
||||||
|
@ -516,6 +584,18 @@ void RenderablePolyVoxEntityItem::render(RenderArgs* args) {
|
||||||
assert(getType() == EntityTypes::PolyVox);
|
assert(getType() == EntityTypes::PolyVox);
|
||||||
Q_ASSERT(args->_batch);
|
Q_ASSERT(args->_batch);
|
||||||
|
|
||||||
|
if (_meshVersion < _modelVersion ||
|
||||||
|
_dataVersion < _modelVersion) {
|
||||||
|
_async.decompressVolumeData(_voxelData, _modelVersion);
|
||||||
|
_async.updateVoxelSurfaceStyle(_voxelSurfaceStyle, _modelVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
model::MeshPointer mesh = _mesh;
|
||||||
|
|
||||||
|
// if (_meshVersion == 0) {
|
||||||
|
// return; // we have no mesh
|
||||||
|
// }
|
||||||
|
|
||||||
if (!_pipeline) {
|
if (!_pipeline) {
|
||||||
gpu::ShaderPointer vertexShader = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(polyvox_vert)));
|
gpu::ShaderPointer vertexShader = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(polyvox_vert)));
|
||||||
gpu::ShaderPointer pixelShader = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(polyvox_frag)));
|
gpu::ShaderPointer pixelShader = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(polyvox_frag)));
|
||||||
|
@ -539,9 +619,8 @@ void RenderablePolyVoxEntityItem::render(RenderArgs* args) {
|
||||||
gpu::Batch& batch = *args->_batch;
|
gpu::Batch& batch = *args->_batch;
|
||||||
batch.setPipeline(_pipeline);
|
batch.setPipeline(_pipeline);
|
||||||
|
|
||||||
_modelGeometryLock.lockForRead();
|
// _modelGeometryLock.lockForRead();
|
||||||
auto mesh = _modelGeometry.getMesh();
|
// auto mesh = _modelGeometry.getMesh();
|
||||||
_modelGeometryLock.unlock();
|
|
||||||
|
|
||||||
Transform transform(voxelToWorldMatrix());
|
Transform transform(voxelToWorldMatrix());
|
||||||
batch.setModelTransform(transform);
|
batch.setModelTransform(transform);
|
||||||
|
@ -583,6 +662,7 @@ void RenderablePolyVoxEntityItem::render(RenderArgs* args) {
|
||||||
batch._glUniform3f(voxelVolumeSizeLocation, _voxelVolumeSize.x, _voxelVolumeSize.y, _voxelVolumeSize.z);
|
batch._glUniform3f(voxelVolumeSizeLocation, _voxelVolumeSize.x, _voxelVolumeSize.y, _voxelVolumeSize.z);
|
||||||
|
|
||||||
batch.drawIndexed(gpu::TRIANGLES, mesh->getNumIndices(), 0);
|
batch.drawIndexed(gpu::TRIANGLES, mesh->getNumIndices(), 0);
|
||||||
|
// _modelGeometryLock.unlock();
|
||||||
|
|
||||||
RenderableDebugableEntityItem::render(this, args);
|
RenderableDebugableEntityItem::render(this, args);
|
||||||
}
|
}
|
||||||
|
@ -648,21 +728,23 @@ RenderablePolyVoxAsynchronous::RenderablePolyVoxAsynchronous(PolyVoxEntityItem::
|
||||||
glm::vec3 voxelVolumeSize,
|
glm::vec3 voxelVolumeSize,
|
||||||
RenderablePolyVoxEntityItem* owner) :
|
RenderablePolyVoxEntityItem* owner) :
|
||||||
_voxelSurfaceStyle(voxelSurfaceStyle),
|
_voxelSurfaceStyle(voxelSurfaceStyle),
|
||||||
|
_onCount(0),
|
||||||
_owner(owner) {
|
_owner(owner) {
|
||||||
setVoxelVolumeSize(voxelVolumeSize);
|
setVoxelVolumeSize(voxelVolumeSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
RenderablePolyVoxAsynchronous::~RenderablePolyVoxAsynchronous() {
|
RenderablePolyVoxAsynchronous::~RenderablePolyVoxAsynchronous() {
|
||||||
|
_volDataLock.lockForWrite();
|
||||||
delete _volData;
|
delete _volData;
|
||||||
|
_volDataLock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RenderablePolyVoxAsynchronous::setVoxelVolumeSize(glm::vec3 voxelVolumeSize) {
|
void RenderablePolyVoxAsynchronous::setVoxelVolumeSize(glm::vec3 voxelVolumeSize) {
|
||||||
#ifdef WANT_DEBUG
|
// qDebug() << _owner->getID() << "OKOKOK" << QString(__PRETTY_FUNCTION__) << _owner->getName();
|
||||||
qDebug() << "resetting voxel-space size" << voxelVolumeSize.x << voxelVolumeSize.y << voxelVolumeSize.z;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
_volDataLock.lockForWrite();
|
||||||
_voxelVolumeSize = voxelVolumeSize;
|
_voxelVolumeSize = voxelVolumeSize;
|
||||||
|
|
||||||
if (_volData) {
|
if (_volData) {
|
||||||
|
@ -691,15 +773,16 @@ void RenderablePolyVoxAsynchronous::setVoxelVolumeSize(glm::vec3 voxelVolumeSize
|
||||||
|
|
||||||
// having the "outside of voxel-space" value be 255 has helped me notice some problems.
|
// having the "outside of voxel-space" value be 255 has helped me notice some problems.
|
||||||
_volData->setBorderValue(255);
|
_volData->setBorderValue(255);
|
||||||
|
_volDataLock.unlock();
|
||||||
#ifdef WANT_DEBUG
|
|
||||||
qDebug() << " new voxel-space size is" << _volData->getWidth() << _volData->getHeight() << _volData->getDepth();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RenderablePolyVoxAsynchronous::updateVoxelSurfaceStyle(PolyVoxEntityItem::PolyVoxSurfaceStyle voxelSurfaceStyle,
|
void RenderablePolyVoxAsynchronous::updateVoxelSurfaceStyle(PolyVoxEntityItem::PolyVoxSurfaceStyle voxelSurfaceStyle,
|
||||||
uint64_t modelVersion) {
|
quint64 modelVersion) {
|
||||||
|
|
||||||
|
// qDebug() << _owner->getID() << "OKOKOK" << QString(__PRETTY_FUNCTION__) << _owner->getName();
|
||||||
|
|
||||||
|
_volDataLock.lockForWrite();
|
||||||
// if we are switching to or from "edged" we need to force a resize of _volData.
|
// if we are switching to or from "edged" we need to force a resize of _volData.
|
||||||
bool wasEdged = (_voxelSurfaceStyle == PolyVoxEntityItem::SURFACE_EDGED_CUBIC ||
|
bool wasEdged = (_voxelSurfaceStyle == PolyVoxEntityItem::SURFACE_EDGED_CUBIC ||
|
||||||
_voxelSurfaceStyle == PolyVoxEntityItem::SURFACE_EDGED_MARCHING_CUBES);
|
_voxelSurfaceStyle == PolyVoxEntityItem::SURFACE_EDGED_MARCHING_CUBES);
|
||||||
|
@ -712,11 +795,23 @@ void RenderablePolyVoxAsynchronous::updateVoxelSurfaceStyle(PolyVoxEntityItem::P
|
||||||
}
|
}
|
||||||
_volData = nullptr;
|
_volData = nullptr;
|
||||||
_voxelSurfaceStyle = voxelSurfaceStyle;
|
_voxelSurfaceStyle = voxelSurfaceStyle;
|
||||||
|
_volDataLock.unlock();
|
||||||
setVoxelVolumeSize(_voxelVolumeSize);
|
setVoxelVolumeSize(_voxelVolumeSize);
|
||||||
|
# ifdef THREAD_POLYVOX
|
||||||
|
QtConcurrent::run(this, &RenderablePolyVoxAsynchronous::decompressVolumeDataAsync,
|
||||||
|
_owner->getVoxelData(), modelVersion);
|
||||||
|
# else
|
||||||
|
decompressVolumeDataAsync(_owner->getVoxelData(), modelVersion);
|
||||||
|
# endif
|
||||||
} else {
|
} else {
|
||||||
_voxelSurfaceStyle = voxelSurfaceStyle;
|
_voxelSurfaceStyle = voxelSurfaceStyle;
|
||||||
|
_volDataLock.unlock();
|
||||||
|
# ifdef THREAD_POLYVOX
|
||||||
|
QtConcurrent::run(this, &RenderablePolyVoxAsynchronous::getMeshAsync, modelVersion);
|
||||||
|
# else
|
||||||
|
getMeshAsync(modelVersion);
|
||||||
|
# endif
|
||||||
}
|
}
|
||||||
getModel(modelVersion);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -748,6 +843,13 @@ bool RenderablePolyVoxAsynchronous::inUserBounds(const PolyVox::SimpleVolume<uin
|
||||||
|
|
||||||
|
|
||||||
uint8_t RenderablePolyVoxAsynchronous::getVoxel(int x, int y, int z) {
|
uint8_t RenderablePolyVoxAsynchronous::getVoxel(int x, int y, int z) {
|
||||||
|
_volDataLock.lockForRead();
|
||||||
|
auto result = getVoxelInternal(x, y, z);
|
||||||
|
_volDataLock.unlock();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t RenderablePolyVoxAsynchronous::getVoxelInternal(int x, int y, int z) {
|
||||||
if (!inUserBounds(_volData, _voxelSurfaceStyle, x, y, z)) {
|
if (!inUserBounds(_volData, _voxelSurfaceStyle, x, y, z)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -795,7 +897,7 @@ bool RenderablePolyVoxAsynchronous::updateOnCount(int x, int y, int z, uint8_t t
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t uVoxelValue = getVoxel(x, y, z);
|
uint8_t uVoxelValue = getVoxelInternal(x, y, z);
|
||||||
if (toValue != 0) {
|
if (toValue != 0) {
|
||||||
if (uVoxelValue == 0) {
|
if (uVoxelValue == 0) {
|
||||||
_onCount++;
|
_onCount++;
|
||||||
|
@ -813,22 +915,31 @@ bool RenderablePolyVoxAsynchronous::updateOnCount(int x, int y, int z, uint8_t t
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool RenderablePolyVoxAsynchronous::setVoxel(int x, int y, int z, uint8_t toValue, uint64_t modelVersion) {
|
bool RenderablePolyVoxAsynchronous::setVoxel(int x, int y, int z, uint8_t toValue, quint64 modelVersion) {
|
||||||
|
_volDataLock.lockForWrite();
|
||||||
bool result = setVoxelInternal(x, y, z, toValue);
|
bool result = setVoxelInternal(x, y, z, toValue);
|
||||||
|
_volDataLock.unlock();
|
||||||
if (result) {
|
if (result) {
|
||||||
|
# ifdef THREAD_POLYVOX
|
||||||
|
QtConcurrent::run(this, &RenderablePolyVoxAsynchronous::compressVolumeData, modelVersion);
|
||||||
|
QtConcurrent::run(this, &RenderablePolyVoxAsynchronous::getMeshAsync, modelVersion);
|
||||||
|
# else
|
||||||
compressVolumeData(modelVersion);
|
compressVolumeData(modelVersion);
|
||||||
getModel(modelVersion);
|
getMeshAsync(modelVersion);
|
||||||
|
# endif
|
||||||
} else {
|
} else {
|
||||||
// nothing changed.
|
// nothing changed.
|
||||||
_owner->receiveNewVoxelData(_owner->getVoxelData(), modelVersion);
|
// _owner->receiveNewVoxelData(_owner->getVoxelData(), modelVersion);
|
||||||
|
_owner->setDataVersion(modelVersion);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool RenderablePolyVoxAsynchronous::setAll(uint8_t toValue, uint64_t modelVersion) {
|
bool RenderablePolyVoxAsynchronous::setAll(uint8_t toValue, quint64 modelVersion) {
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
|
_volDataLock.lockForWrite();
|
||||||
for (int z = 0; z < _voxelVolumeSize.z; z++) {
|
for (int z = 0; z < _voxelVolumeSize.z; z++) {
|
||||||
for (int y = 0; y < _voxelVolumeSize.y; y++) {
|
for (int y = 0; y < _voxelVolumeSize.y; y++) {
|
||||||
for (int x = 0; x < _voxelVolumeSize.x; x++) {
|
for (int x = 0; x < _voxelVolumeSize.x; x++) {
|
||||||
|
@ -836,20 +947,29 @@ bool RenderablePolyVoxAsynchronous::setAll(uint8_t toValue, uint64_t modelVersio
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_volDataLock.unlock();
|
||||||
if (result) {
|
if (result) {
|
||||||
|
# ifdef THREAD_POLYVOX
|
||||||
|
QtConcurrent::run(this, &RenderablePolyVoxAsynchronous::compressVolumeData, modelVersion);
|
||||||
|
QtConcurrent::run(this, &RenderablePolyVoxAsynchronous::getMeshAsync, modelVersion);
|
||||||
|
# else
|
||||||
compressVolumeData(modelVersion);
|
compressVolumeData(modelVersion);
|
||||||
|
getMeshAsync(modelVersion);
|
||||||
|
# endif
|
||||||
} else {
|
} else {
|
||||||
// nothing changed.
|
// nothing changed.
|
||||||
_owner->receiveNewVoxelData(_owner->getVoxelData(), modelVersion);
|
// _owner->receiveNewVoxelData(_owner->getVoxelData(), modelVersion);
|
||||||
|
_owner->setDataVersion(modelVersion);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool RenderablePolyVoxAsynchronous::setSphereInVolume(glm::vec3 center, float radius, uint8_t toValue, uint64_t modelVersion) {
|
bool RenderablePolyVoxAsynchronous::setSphereInVolume(glm::vec3 center, float radius, uint8_t toValue, quint64 modelVersion) {
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
// This three-level for loop iterates over every voxel in the volume
|
// This three-level for loop iterates over every voxel in the volume
|
||||||
|
_volDataLock.lockForWrite();
|
||||||
for (int z = 0; z < _voxelVolumeSize.z; z++) {
|
for (int z = 0; z < _voxelVolumeSize.z; z++) {
|
||||||
for (int y = 0; y < _voxelVolumeSize.y; y++) {
|
for (int y = 0; y < _voxelVolumeSize.y; y++) {
|
||||||
for (int x = 0; x < _voxelVolumeSize.x; x++) {
|
for (int x = 0; x < _voxelVolumeSize.x; x++) {
|
||||||
|
@ -864,11 +984,19 @@ bool RenderablePolyVoxAsynchronous::setSphereInVolume(glm::vec3 center, float ra
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_volDataLock.unlock();
|
||||||
if (result) {
|
if (result) {
|
||||||
|
# ifdef THREAD_POLYVOX
|
||||||
|
QtConcurrent::run(this, &RenderablePolyVoxAsynchronous::compressVolumeData, modelVersion);
|
||||||
|
QtConcurrent::run(this, &RenderablePolyVoxAsynchronous::getMeshAsync, modelVersion);
|
||||||
|
# else
|
||||||
compressVolumeData(modelVersion);
|
compressVolumeData(modelVersion);
|
||||||
|
getMeshAsync(modelVersion);
|
||||||
|
# endif
|
||||||
} else {
|
} else {
|
||||||
// nothing changed.
|
// nothing changed.
|
||||||
_owner->receiveNewVoxelData(_owner->getVoxelData(), modelVersion);
|
// _owner->receiveNewVoxelData(_owner->getVoxelData(), modelVersion);
|
||||||
|
_owner->setDataVersion(modelVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -880,8 +1008,10 @@ PolyVox::RaycastResult RenderablePolyVoxAsynchronous::doRayCast(glm::vec4 origin
|
||||||
PolyVox::Vector3DFloat startPoint(originInVoxel.x, originInVoxel.y, originInVoxel.z);
|
PolyVox::Vector3DFloat startPoint(originInVoxel.x, originInVoxel.y, originInVoxel.z);
|
||||||
PolyVox::Vector3DFloat endPoint(farInVoxel.x, farInVoxel.y, farInVoxel.z);
|
PolyVox::Vector3DFloat endPoint(farInVoxel.x, farInVoxel.y, farInVoxel.z);
|
||||||
|
|
||||||
|
_volDataLock.lockForRead();
|
||||||
RaycastFunctor callback(_volData);
|
RaycastFunctor callback(_volData);
|
||||||
PolyVox::RaycastResult raycastResult = PolyVox::raycastWithEndpoints(_volData, startPoint, endPoint, callback);
|
PolyVox::RaycastResult raycastResult = PolyVox::raycastWithEndpoints(_volData, startPoint, endPoint, callback);
|
||||||
|
_volDataLock.unlock();
|
||||||
|
|
||||||
// result is in voxel-space coordinates.
|
// result is in voxel-space coordinates.
|
||||||
result = callback._result - glm::vec4(0.5f, 0.5f, 0.5f, 0.0f);
|
result = callback._result - glm::vec4(0.5f, 0.5f, 0.5f, 0.0f);
|
||||||
|
@ -890,7 +1020,21 @@ PolyVox::RaycastResult RenderablePolyVoxAsynchronous::doRayCast(glm::vec4 origin
|
||||||
|
|
||||||
|
|
||||||
// take compressed data and expand it into _volData.
|
// take compressed data and expand it into _volData.
|
||||||
void RenderablePolyVoxAsynchronous::decompressVolumeData(QByteArray voxelData, uint64_t modelVersion) {
|
void RenderablePolyVoxAsynchronous::decompressVolumeData(QByteArray voxelData, quint64 modelVersion) {
|
||||||
|
// qDebug() << _owner->getID() << "OKOKOK" << QString(__PRETTY_FUNCTION__) << _owner->getName() << modelVersion;
|
||||||
|
|
||||||
|
# ifdef THREAD_POLYVOX
|
||||||
|
QtConcurrent::run(this, &RenderablePolyVoxAsynchronous::decompressVolumeDataAsync, voxelData, modelVersion);
|
||||||
|
# else
|
||||||
|
decompressVolumeDataAsync(voxelData, modelVersion);
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RenderablePolyVoxAsynchronous::decompressVolumeDataAsync(QByteArray voxelData, quint64 modelVersion) {
|
||||||
|
// qDebug() << _owner->getID() << "OKOKOK" << QString(__PRETTY_FUNCTION__)
|
||||||
|
// << _owner->getName() << _owner->getID() << modelVersion;
|
||||||
|
|
||||||
QDataStream reader(voxelData);
|
QDataStream reader(voxelData);
|
||||||
quint16 voxelXSize, voxelYSize, voxelZSize;
|
quint16 voxelXSize, voxelYSize, voxelZSize;
|
||||||
reader >> voxelXSize;
|
reader >> voxelXSize;
|
||||||
|
@ -901,7 +1045,10 @@ void RenderablePolyVoxAsynchronous::decompressVolumeData(QByteArray voxelData, u
|
||||||
voxelYSize == 0 || voxelYSize > PolyVoxEntityItem::MAX_VOXEL_DIMENSION ||
|
voxelYSize == 0 || voxelYSize > PolyVoxEntityItem::MAX_VOXEL_DIMENSION ||
|
||||||
voxelZSize == 0 || voxelZSize > PolyVoxEntityItem::MAX_VOXEL_DIMENSION) {
|
voxelZSize == 0 || voxelZSize > PolyVoxEntityItem::MAX_VOXEL_DIMENSION) {
|
||||||
qDebug() << "voxelSize is not reasonable, skipping decompressions."
|
qDebug() << "voxelSize is not reasonable, skipping decompressions."
|
||||||
<< voxelXSize << voxelYSize << voxelZSize;
|
<< voxelXSize << voxelYSize << voxelZSize << _owner->getName() << _owner->getID() << modelVersion
|
||||||
|
<< "5d301155-faf9-44dd-8e8b-061a03d42c0f";
|
||||||
|
// _owner->receiveNewVoxelData(_owner->getVoxelData(), modelVersion);
|
||||||
|
_owner->setDataVersion(modelVersion);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -912,11 +1059,15 @@ void RenderablePolyVoxAsynchronous::decompressVolumeData(QByteArray voxelData, u
|
||||||
QByteArray uncompressedData = qUncompress(compressedData);
|
QByteArray uncompressedData = qUncompress(compressedData);
|
||||||
|
|
||||||
if (uncompressedData.size() != rawSize) {
|
if (uncompressedData.size() != rawSize) {
|
||||||
qDebug() << "PolyVox decompress -- size is (" << voxelXSize << voxelYSize << voxelZSize << ")" <<
|
qDebug() << "PolyVox decompress -- size is (" << voxelXSize << voxelYSize << voxelZSize << ")"
|
||||||
"so expected uncompressed length of" << rawSize << "but length is" << uncompressedData.size();
|
<< "so expected uncompressed length of" << rawSize << "but length is" << uncompressedData.size()
|
||||||
|
<< _owner->getName() << _owner->getID() << modelVersion << "5d301155-faf9-44dd-8e8b-061a03d42c0f";
|
||||||
|
// _owner->receiveNewVoxelData(_owner->getVoxelData(), modelVersion);
|
||||||
|
_owner->setDataVersion(modelVersion);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_volDataLock.lockForWrite();
|
||||||
for (int z = 0; z < voxelZSize; z++) {
|
for (int z = 0; z < voxelZSize; z++) {
|
||||||
for (int y = 0; y < voxelYSize; y++) {
|
for (int y = 0; y < voxelYSize; y++) {
|
||||||
for (int x = 0; x < voxelXSize; x++) {
|
for (int x = 0; x < voxelXSize; x++) {
|
||||||
|
@ -925,18 +1076,27 @@ void RenderablePolyVoxAsynchronous::decompressVolumeData(QByteArray voxelData, u
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_volDataLock.unlock();
|
||||||
|
|
||||||
getModel(modelVersion);
|
_owner->receiveNewVoxelData(voxelData, modelVersion);
|
||||||
|
|
||||||
|
# ifdef THREAD_POLYVOX
|
||||||
|
QFuture<void> future = QtConcurrent::run(this, &RenderablePolyVoxAsynchronous::getMeshAsync, modelVersion);
|
||||||
|
# else
|
||||||
|
getMeshAsync(modelVersion);
|
||||||
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RenderablePolyVoxAsynchronous::getModel(uint64_t modelVersion) {
|
void RenderablePolyVoxAsynchronous::getMeshAsync(quint64 modelVersion) {
|
||||||
model::Mesh* mesh = new model::Mesh();
|
// qDebug() << _owner->getID() << "OKOKOK" << QString(__PRETTY_FUNCTION__) << _owner->getName() << modelVersion;
|
||||||
model::MeshPointer meshPtr(mesh);
|
|
||||||
|
model::MeshPointer mesh(new model::Mesh());
|
||||||
|
|
||||||
// A mesh object to hold the result of surface extraction
|
// A mesh object to hold the result of surface extraction
|
||||||
PolyVox::SurfaceMesh<PolyVox::PositionMaterialNormal> polyVoxMesh;
|
PolyVox::SurfaceMesh<PolyVox::PositionMaterialNormal> polyVoxMesh;
|
||||||
|
|
||||||
|
_volDataLock.lockForRead();
|
||||||
switch (_voxelSurfaceStyle) {
|
switch (_voxelSurfaceStyle) {
|
||||||
case PolyVoxEntityItem::SURFACE_EDGED_MARCHING_CUBES:
|
case PolyVoxEntityItem::SURFACE_EDGED_MARCHING_CUBES:
|
||||||
case PolyVoxEntityItem::SURFACE_MARCHING_CUBES: {
|
case PolyVoxEntityItem::SURFACE_MARCHING_CUBES: {
|
||||||
|
@ -953,6 +1113,7 @@ void RenderablePolyVoxAsynchronous::getModel(uint64_t modelVersion) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_volDataLock.unlock();
|
||||||
|
|
||||||
// convert PolyVox mesh to a Sam mesh
|
// convert PolyVox mesh to a Sam mesh
|
||||||
const std::vector<uint32_t>& vecIndices = polyVoxMesh.getIndices();
|
const std::vector<uint32_t>& vecIndices = polyVoxMesh.getIndices();
|
||||||
|
@ -966,10 +1127,11 @@ void RenderablePolyVoxAsynchronous::getModel(uint64_t modelVersion) {
|
||||||
auto vertexBuffer = std::make_shared<gpu::Buffer>(vecVertices.size() * sizeof(PolyVox::PositionMaterialNormal),
|
auto vertexBuffer = std::make_shared<gpu::Buffer>(vecVertices.size() * sizeof(PolyVox::PositionMaterialNormal),
|
||||||
(gpu::Byte*)vecVertices.data());
|
(gpu::Byte*)vecVertices.data());
|
||||||
auto vertexBufferPtr = gpu::BufferPointer(vertexBuffer);
|
auto vertexBufferPtr = gpu::BufferPointer(vertexBuffer);
|
||||||
auto vertexBufferView = new gpu::BufferView(vertexBufferPtr,
|
gpu::Resource::Size vertexBufferSize = 0;
|
||||||
0,
|
if (vertexBufferPtr->getSize() > sizeof(float) * 3) {
|
||||||
vertexBufferPtr->getSize() - sizeof(float) * 3,
|
vertexBufferSize = vertexBufferPtr->getSize() - sizeof(float) * 3;
|
||||||
sizeof(PolyVox::PositionMaterialNormal),
|
}
|
||||||
|
auto vertexBufferView = new gpu::BufferView(vertexBufferPtr, 0, vertexBufferSize, sizeof(PolyVox::PositionMaterialNormal),
|
||||||
gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::RAW));
|
gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::RAW));
|
||||||
mesh->setVertexBuffer(*vertexBufferView);
|
mesh->setVertexBuffer(*vertexBufferView);
|
||||||
mesh->addAttribute(gpu::Stream::NORMAL,
|
mesh->addAttribute(gpu::Stream::NORMAL,
|
||||||
|
@ -979,7 +1141,10 @@ void RenderablePolyVoxAsynchronous::getModel(uint64_t modelVersion) {
|
||||||
sizeof(PolyVox::PositionMaterialNormal),
|
sizeof(PolyVox::PositionMaterialNormal),
|
||||||
gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::RAW)));
|
gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::RAW)));
|
||||||
|
|
||||||
_owner->receiveNewMesh(meshPtr, modelVersion);
|
// qDebug() << _owner->getID() << "OKOKOK -- MADE NEW MESH" << "index-count =" << vecIndices.size()
|
||||||
|
// << "vertex-count =" << vecVertices.size() << "mesh-vertg-size =" << mesh->getVertexBuffer()._size;
|
||||||
|
|
||||||
|
_owner->receiveNewMesh(mesh, modelVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
int RenderablePolyVoxAsynchronous::getOnCount() const {
|
int RenderablePolyVoxAsynchronous::getOnCount() const {
|
||||||
|
@ -990,7 +1155,9 @@ int RenderablePolyVoxAsynchronous::getOnCount() const {
|
||||||
|
|
||||||
// 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 RenderablePolyVoxAsynchronous::compressVolumeData(uint64_t modelVersion) {
|
void RenderablePolyVoxAsynchronous::compressVolumeData(quint64 modelVersion) {
|
||||||
|
// qDebug() << _owner->getID() << "OKOKOK" << QString(__PRETTY_FUNCTION__) << _owner->getName() << modelVersion;
|
||||||
|
|
||||||
quint16 voxelXSize = _voxelVolumeSize.x;
|
quint16 voxelXSize = _voxelVolumeSize.x;
|
||||||
quint16 voxelYSize = _voxelVolumeSize.y;
|
quint16 voxelYSize = _voxelVolumeSize.y;
|
||||||
quint16 voxelZSize = _voxelVolumeSize.z;
|
quint16 voxelZSize = _voxelVolumeSize.z;
|
||||||
|
@ -998,10 +1165,11 @@ void RenderablePolyVoxAsynchronous::compressVolumeData(uint64_t modelVersion) {
|
||||||
|
|
||||||
QByteArray uncompressedData = QByteArray(rawSize, '\0');
|
QByteArray uncompressedData = QByteArray(rawSize, '\0');
|
||||||
|
|
||||||
|
_volDataLock.lockForRead();
|
||||||
for (int z = 0; z < voxelZSize; z++) {
|
for (int z = 0; z < voxelZSize; z++) {
|
||||||
for (int y = 0; y < voxelYSize; y++) {
|
for (int y = 0; y < voxelYSize; y++) {
|
||||||
for (int x = 0; x < voxelXSize; x++) {
|
for (int x = 0; x < voxelXSize; x++) {
|
||||||
uint8_t uVoxelValue = getVoxel(x, y, z);
|
uint8_t uVoxelValue = getVoxelInternal(x, y, z);
|
||||||
int uncompressedIndex =
|
int uncompressedIndex =
|
||||||
z * voxelYSize * voxelXSize +
|
z * voxelYSize * voxelXSize +
|
||||||
y * voxelXSize +
|
y * voxelXSize +
|
||||||
|
@ -1010,6 +1178,7 @@ void RenderablePolyVoxAsynchronous::compressVolumeData(uint64_t modelVersion) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_volDataLock.unlock();
|
||||||
|
|
||||||
QByteArray newVoxelData;
|
QByteArray newVoxelData;
|
||||||
QDataStream writer(&newVoxelData, QIODevice::WriteOnly | QIODevice::Truncate);
|
QDataStream writer(&newVoxelData, QIODevice::WriteOnly | QIODevice::Truncate);
|
||||||
|
@ -1025,7 +1194,10 @@ void RenderablePolyVoxAsynchronous::compressVolumeData(uint64_t modelVersion) {
|
||||||
} else {
|
} else {
|
||||||
// HACK -- until we have a way to allow for properties larger than MTU, don't update.
|
// HACK -- until we have a way to allow for properties larger than MTU, don't update.
|
||||||
// revert the active voxel-space to the last version that fit.
|
// revert the active voxel-space to the last version that fit.
|
||||||
qDebug() << "voxel data too large, reverting change.";
|
// QtConcurrent::run(this, &RenderablePolyVoxAsynchronous::decompressVolumeDataAsync,
|
||||||
decompressVolumeData(_owner->getVoxelData(), modelVersion);
|
// _owner->getVoxelData(), modelVersion);
|
||||||
|
// decompressVolumeDataAsync(_owner->getVoxelData(), modelVersion);
|
||||||
|
// _owner->receiveNewVoxelData(_owner->getVoxelData(), modelVersion);
|
||||||
|
_owner->setDataVersion(modelVersion);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,15 +13,17 @@
|
||||||
#define hifi_RenderablePolyVoxEntityItem_h
|
#define hifi_RenderablePolyVoxEntityItem_h
|
||||||
|
|
||||||
#include <QFuture>
|
#include <QFuture>
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
#include <PolyVoxCore/SimpleVolume.h>
|
#include <PolyVoxCore/SimpleVolume.h>
|
||||||
#include <PolyVoxCore/Raycast.h>
|
#include <PolyVoxCore/Raycast.h>
|
||||||
|
|
||||||
#include <TextureCache.h>
|
#include <TextureCache.h>
|
||||||
|
|
||||||
#include "PolyVoxEntityItem.h"
|
#include "PolyVoxEntityItem.h"
|
||||||
#include "RenderableDebugableEntityItem.h"
|
#include "RenderableDebugableEntityItem.h"
|
||||||
#include "RenderableEntityItem.h"
|
#include "RenderableEntityItem.h"
|
||||||
|
#include "gpu/Context.h"
|
||||||
|
|
||||||
class PolyVoxPayload {
|
class PolyVoxPayload {
|
||||||
public:
|
public:
|
||||||
|
@ -42,7 +44,8 @@ namespace render {
|
||||||
class RenderablePolyVoxEntityItem;
|
class RenderablePolyVoxEntityItem;
|
||||||
|
|
||||||
|
|
||||||
class RenderablePolyVoxAsynchronous {
|
class RenderablePolyVoxAsynchronous : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RenderablePolyVoxAsynchronous(PolyVoxEntityItem::PolyVoxSurfaceStyle voxelSurfaceStyle, glm::vec3 voxelVolumeSize,
|
RenderablePolyVoxAsynchronous(PolyVoxEntityItem::PolyVoxSurfaceStyle voxelSurfaceStyle, glm::vec3 voxelVolumeSize,
|
||||||
|
@ -50,20 +53,29 @@ class RenderablePolyVoxAsynchronous {
|
||||||
~RenderablePolyVoxAsynchronous();
|
~RenderablePolyVoxAsynchronous();
|
||||||
|
|
||||||
void setVoxelVolumeSize(glm::vec3 voxelVolumeSize);
|
void setVoxelVolumeSize(glm::vec3 voxelVolumeSize);
|
||||||
void updateVoxelSurfaceStyle(PolyVoxEntityItem::PolyVoxSurfaceStyle voxelSurfaceStyle, uint64_t modelVersion);
|
void updateVoxelSurfaceStyle(PolyVoxEntityItem::PolyVoxSurfaceStyle voxelSurfaceStyle, quint64 modelVersion);
|
||||||
uint8_t getVoxel(int x, int y, int z);
|
uint8_t getVoxel(int x, int y, int z);
|
||||||
bool setVoxel(int x, int y, int z, uint8_t toValue, uint64_t modelVersion);
|
bool setVoxel(int x, int y, int z, uint8_t toValue, quint64 modelVersion);
|
||||||
bool setAll(uint8_t toValue, uint64_t modelVersion);
|
bool setAll(uint8_t toValue, quint64 modelVersion);
|
||||||
bool setSphereInVolume(glm::vec3 center, float radius, uint8_t toValue, uint64_t modelVersion);
|
bool setSphereInVolume(glm::vec3 center, float radius, uint8_t toValue, quint64 modelVersion);
|
||||||
PolyVox::RaycastResult doRayCast(glm::vec4 originInVoxel, glm::vec4 farInVoxel, glm::vec4& result) const;
|
PolyVox::RaycastResult doRayCast(glm::vec4 originInVoxel, glm::vec4 farInVoxel, glm::vec4& result) const;
|
||||||
int getOnCount() const;
|
int getOnCount() const;
|
||||||
void decompressVolumeData(QByteArray voxelData, uint64_t modelVersion);
|
void decompressVolumeData(QByteArray voxelData, quint64 modelVersion);
|
||||||
|
|
||||||
|
// signals:
|
||||||
|
// void doDecompressVolumeDataAsync(QByteArray voxelData, quint64 modelVersion);
|
||||||
|
// void doGetMeshAsync(quint64 modelVersion);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void getModel(uint64_t modelVersion);
|
void decompressVolumeDataAsync(QByteArray voxelData, quint64 modelVersion);
|
||||||
|
void getMeshAsync(quint64 modelVersion);
|
||||||
|
|
||||||
|
uint8_t getVoxelInternal(int x, int y, int z);
|
||||||
bool updateOnCount(int x, int y, int z, uint8_t new_value);
|
bool updateOnCount(int x, int y, int z, uint8_t new_value);
|
||||||
bool setVoxelInternal(int x, int y, int z, uint8_t toValue);
|
bool setVoxelInternal(int x, int y, int z, uint8_t toValue);
|
||||||
void compressVolumeData(uint64_t modelVersion);
|
void compressVolumeData(quint64 modelVersion);
|
||||||
static bool inUserBounds(const PolyVox::SimpleVolume<uint8_t>* vol, PolyVoxEntityItem::PolyVoxSurfaceStyle surfaceStyle,
|
static bool inUserBounds(const PolyVox::SimpleVolume<uint8_t>* vol, PolyVoxEntityItem::PolyVoxSurfaceStyle surfaceStyle,
|
||||||
int x, int y, int z);
|
int x, int y, int z);
|
||||||
|
|
||||||
|
@ -71,7 +83,7 @@ private:
|
||||||
glm::vec3 _voxelVolumeSize;
|
glm::vec3 _voxelVolumeSize;
|
||||||
PolyVox::SimpleVolume<uint8_t>* _volData = nullptr;
|
PolyVox::SimpleVolume<uint8_t>* _volData = nullptr;
|
||||||
mutable QReadWriteLock _volDataLock; // lock for _volData
|
mutable QReadWriteLock _volDataLock; // lock for _volData
|
||||||
int _onCount = 0; // how many non-zero voxels are in _volData
|
std::atomic_int _onCount; // how many non-zero voxels are in _volData
|
||||||
|
|
||||||
RenderablePolyVoxEntityItem* _owner = nullptr;
|
RenderablePolyVoxEntityItem* _owner = nullptr;
|
||||||
};
|
};
|
||||||
|
@ -116,7 +128,6 @@ class RenderablePolyVoxEntityItem : public PolyVoxEntityItem {
|
||||||
virtual ShapeType getShapeType() const;
|
virtual ShapeType getShapeType() const;
|
||||||
virtual bool isReadyToComputeShape();
|
virtual bool isReadyToComputeShape();
|
||||||
virtual void computeShapeInfo(ShapeInfo& info);
|
virtual void computeShapeInfo(ShapeInfo& info);
|
||||||
virtual bool computeShapeInfoWorker();
|
|
||||||
|
|
||||||
virtual glm::vec3 voxelCoordsToWorldCoords(glm::vec3& voxelCoords) const;
|
virtual glm::vec3 voxelCoordsToWorldCoords(glm::vec3& voxelCoords) const;
|
||||||
virtual glm::vec3 worldCoordsToVoxelCoords(glm::vec3& worldCoords) const;
|
virtual glm::vec3 worldCoordsToVoxelCoords(glm::vec3& worldCoords) const;
|
||||||
|
@ -142,17 +153,21 @@ class RenderablePolyVoxEntityItem : public PolyVoxEntityItem {
|
||||||
std::shared_ptr<render::Scene> scene,
|
std::shared_ptr<render::Scene> scene,
|
||||||
render::PendingChanges& pendingChanges);
|
render::PendingChanges& pendingChanges);
|
||||||
|
|
||||||
void receiveNewVoxelData(QByteArray newVoxelData, uint64_t dataVersion);
|
void receiveNewVoxelData(QByteArray newVoxelData, quint64 dataVersion);
|
||||||
void receiveNewMesh(model::MeshPointer newMeshPtr, uint64_t meshVersion);
|
void receiveNewMesh(model::MeshPointer newMeshPtr, quint64 meshVersion);
|
||||||
|
void setDataVersion(quint64 dataVersion) { _dataVersion = dataVersion; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// The PolyVoxEntityItem class has _voxelData which contains dimensions and compressed voxel data. The dimensions
|
// The PolyVoxEntityItem class has _voxelData which contains dimensions and compressed voxel data. The dimensions
|
||||||
// may not match _voxelVolumeSize.
|
// may not match _voxelVolumeSize.
|
||||||
|
|
||||||
model::Geometry _modelGeometry;
|
virtual bool computeShapeInfoWorker();
|
||||||
mutable QReadWriteLock _modelGeometryLock;
|
|
||||||
|
|
||||||
QFuture<bool> _getModelWorker;
|
// model::Geometry _modelGeometry;
|
||||||
|
mutable QReadWriteLock _modelGeometryLock;
|
||||||
|
model::MeshPointer _mesh;
|
||||||
|
|
||||||
|
QFuture<bool> _getMeshWorker;
|
||||||
|
|
||||||
NetworkTexturePointer _xTexture;
|
NetworkTexturePointer _xTexture;
|
||||||
NetworkTexturePointer _yTexture;
|
NetworkTexturePointer _yTexture;
|
||||||
|
@ -163,16 +178,17 @@ private:
|
||||||
static gpu::PipelinePointer _pipeline;
|
static gpu::PipelinePointer _pipeline;
|
||||||
|
|
||||||
ShapeInfo _shapeInfo;
|
ShapeInfo _shapeInfo;
|
||||||
QFuture<bool> _shapeInfoWorker;
|
// QFuture<bool> _shapeInfoWorker;
|
||||||
|
mutable QReadWriteLock _shapeInfoLock;
|
||||||
|
|
||||||
// this does work outside of the main thread.
|
// this does work outside of the main thread.
|
||||||
RenderablePolyVoxAsynchronous _async;
|
RenderablePolyVoxAsynchronous _async;
|
||||||
|
|
||||||
uint64_t _modelVersion = 0; // local idea of how many changes have happened
|
quint64 _modelVersion = 1; // local idea of how many changes have happened
|
||||||
// the following are compared against _modelVersion
|
// the following are compared against _modelVersion
|
||||||
uint64_t _meshVersion = 0; // version of most recently computed mesh
|
quint64 _meshVersion = 0; // version of most recently computed mesh
|
||||||
uint64_t _dataVersion = 0; // version of most recently compressed voxel data
|
quint64 _dataVersion = 0; // version of most recently compressed voxel data
|
||||||
uint64_t _shapeVersion = 0; // version of most recently computed collision shape
|
quint64 _shapeVersion = 0; // version of most recently computed collision shape
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -184,3 +184,17 @@ void PolyVoxEntityItem::debugDump() const {
|
||||||
qCDebug(entities) << " dimensions:" << debugTreeVector(getDimensions());
|
qCDebug(entities) << " dimensions:" << debugTreeVector(getDimensions());
|
||||||
qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now);
|
qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PolyVoxEntityItem::setVoxelData(QByteArray voxelData)
|
||||||
|
{
|
||||||
|
qDebug() << "5d301155-faf9-44dd-8e8b-061a03d42c0f parent setVoxelData for" << getName() << getID() << ((void *)this)
|
||||||
|
<< typeid(*this).name();
|
||||||
|
|
||||||
|
_voxelDataLock.lockForWrite();
|
||||||
|
_voxelData = voxelData;
|
||||||
|
_voxelDataLock.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
const QByteArray PolyVoxEntityItem::getVoxelData() const {
|
||||||
|
return _voxelData;
|
||||||
|
}
|
||||||
|
|
|
@ -52,8 +52,8 @@ class PolyVoxEntityItem : public EntityItem {
|
||||||
virtual void setVoxelVolumeSize(glm::vec3 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);
|
||||||
virtual const QByteArray& getVoxelData() const { return _voxelData; }
|
virtual const QByteArray getVoxelData() const;
|
||||||
|
|
||||||
enum PolyVoxSurfaceStyle {
|
enum PolyVoxSurfaceStyle {
|
||||||
SURFACE_MARCHING_CUBES,
|
SURFACE_MARCHING_CUBES,
|
||||||
|
@ -105,6 +105,7 @@ class PolyVoxEntityItem : public EntityItem {
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
glm::vec3 _voxelVolumeSize; // this is always 3 bytes
|
glm::vec3 _voxelVolumeSize; // this is always 3 bytes
|
||||||
|
mutable QReadWriteLock _voxelDataLock;
|
||||||
QByteArray _voxelData;
|
QByteArray _voxelData;
|
||||||
PolyVoxSurfaceStyle _voxelSurfaceStyle;
|
PolyVoxSurfaceStyle _voxelSurfaceStyle;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue