mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-16 19:12:03 +02:00
Working on voxel bits.
This commit is contained in:
parent
e87556450e
commit
9a4d56b4e9
3 changed files with 154 additions and 6 deletions
|
@ -34,12 +34,18 @@ static int bufferPointVectorMetaTypeId = qRegisterMetaType<BufferPointVector>();
|
|||
void MetavoxelSystem::init() {
|
||||
MetavoxelClientManager::init();
|
||||
DefaultMetavoxelRendererImplementation::init();
|
||||
_pointBufferAttribute = AttributeRegistry::getInstance()->registerAttribute(new BufferDataAttribute("pointBuffer"));
|
||||
_heightfieldBufferAttribute = AttributeRegistry::getInstance()->registerAttribute(
|
||||
new BufferDataAttribute("heightfieldBuffer"));
|
||||
|
||||
_pointBufferAttribute = AttributeRegistry::getInstance()->registerAttribute(new BufferDataAttribute("pointBuffer"));
|
||||
|
||||
_heightfieldBufferAttribute = AttributeRegistry::getInstance()->registerAttribute(
|
||||
new BufferDataAttribute("heightfieldBuffer"));
|
||||
_heightfieldBufferAttribute->setLODThresholdMultiplier(
|
||||
AttributeRegistry::getInstance()->getHeightfieldAttribute()->getLODThresholdMultiplier());
|
||||
|
||||
_voxelBufferAttribute = AttributeRegistry::getInstance()->registerAttribute(
|
||||
new BufferDataAttribute("voxelBuffer"));
|
||||
_voxelBufferAttribute->setLODThresholdMultiplier(
|
||||
AttributeRegistry::getInstance()->getVoxelColorAttribute()->getLODThresholdMultiplier());
|
||||
}
|
||||
|
||||
MetavoxelLOD MetavoxelSystem::getLOD() {
|
||||
|
@ -972,6 +978,16 @@ void HeightfieldPreview::render(const glm::vec3& translation, float scale) const
|
|||
glEnable(GL_BLEND);
|
||||
}
|
||||
|
||||
VoxelBuffer::VoxelBuffer(const QVector<VoxelVertex>& vertices, const QVector<int>& indices,
|
||||
const QVector<SharedObjectPointer>& materials) :
|
||||
_vertices(vertices),
|
||||
_indices(indices),
|
||||
_materials(materials) {
|
||||
}
|
||||
|
||||
void VoxelBuffer::render(bool cursor) {
|
||||
}
|
||||
|
||||
BufferDataAttribute::BufferDataAttribute(const QString& name) :
|
||||
InlineAttribute<BufferDataPointer>(name) {
|
||||
}
|
||||
|
@ -1213,6 +1229,8 @@ HeightfieldFetchVisitor::HeightfieldFetchVisitor(const MetavoxelLOD& lod, const
|
|||
_intersections(intersections) {
|
||||
}
|
||||
|
||||
const int EIGHT_BIT_MAXIMUM = 255;
|
||||
|
||||
int HeightfieldFetchVisitor::visit(MetavoxelInfo& info) {
|
||||
Box bounds = info.getBounds();
|
||||
const Box& heightBounds = _buffer->getHeightBounds();
|
||||
|
@ -1263,7 +1281,6 @@ int HeightfieldFetchVisitor::visit(MetavoxelInfo& info) {
|
|||
shift++;
|
||||
size *= 2.0f;
|
||||
}
|
||||
const int EIGHT_BIT_MAXIMUM = 255;
|
||||
int subtract = (_buffer->getTranslation().y - info.minimum.y) * EIGHT_BIT_MAXIMUM / _buffer->getScale();
|
||||
for (int y = 0; y < destHeight; y++, dest += heightSize, srcY += srcAdvance) {
|
||||
const uchar* src = (const uchar*)srcHeight.constData() + (int)srcY * srcSize;
|
||||
|
@ -1479,6 +1496,71 @@ int HeightfieldUpdateVisitor::visit(MetavoxelInfo& info) {
|
|||
return STOP_RECURSION;
|
||||
}
|
||||
|
||||
class VoxelAugmentVisitor : public MetavoxelVisitor {
|
||||
public:
|
||||
|
||||
VoxelAugmentVisitor(const MetavoxelLOD& lod);
|
||||
|
||||
virtual int visit(MetavoxelInfo& info);
|
||||
};
|
||||
|
||||
VoxelAugmentVisitor::VoxelAugmentVisitor(const MetavoxelLOD& lod) :
|
||||
MetavoxelVisitor(QVector<AttributePointer>() << AttributeRegistry::getInstance()->getVoxelColorAttribute() <<
|
||||
AttributeRegistry::getInstance()->getVoxelMaterialAttribute(), QVector<AttributePointer>() <<
|
||||
Application::getInstance()->getMetavoxels()->getVoxelBufferAttribute(), lod) {
|
||||
}
|
||||
|
||||
int VoxelAugmentVisitor::visit(MetavoxelInfo& info) {
|
||||
if (!info.isLeaf) {
|
||||
return DEFAULT_ORDER;
|
||||
}
|
||||
VoxelBuffer* buffer = NULL;
|
||||
VoxelColorDataPointer color = info.inputValues.at(0).getInlineValue<VoxelColorDataPointer>();
|
||||
if (color) {
|
||||
QVector<VoxelVertex> vertices;
|
||||
QVector<int> indices;
|
||||
|
||||
const QVector<QRgb>& contents = color->getContents();
|
||||
int size = color->getSize();
|
||||
int area = size * size;
|
||||
int highest = size - 1;
|
||||
int offset3 = size + 1;
|
||||
int offset5 = area + 1;
|
||||
int offset6 = area + size;
|
||||
int offset7 = area + size + 1;
|
||||
|
||||
const QRgb* src = contents.constData();
|
||||
|
||||
const int ALPHA_OFFSET = 24;
|
||||
const int MAX_ALPHA_TOTAL = EIGHT_BIT_MAXIMUM * 8;
|
||||
for (int z = 0; z < highest; z++) {
|
||||
for (int y = 0; y < highest; z++) {
|
||||
for (int x = 0; x < highest; x++, src++) {
|
||||
int alpha0 = src[0] >> ALPHA_OFFSET;
|
||||
int alpha1 = src[1] >> ALPHA_OFFSET;
|
||||
int alpha2 = src[size] >> ALPHA_OFFSET;
|
||||
int alpha3 = src[offset3] >> ALPHA_OFFSET;
|
||||
int alpha4 = src[area] >> ALPHA_OFFSET;
|
||||
int alpha5 = src[offset5] >> ALPHA_OFFSET;
|
||||
int alpha6 = src[offset6] >> ALPHA_OFFSET;
|
||||
int alpha7 = src[offset7] >> ALPHA_OFFSET;
|
||||
int alphaTotal = alpha0 + alpha1 + alpha2 + alpha3 + alpha4 + alpha5 + alpha6 + alpha7;
|
||||
if (alphaTotal == 0 || alphaTotal == MAX_ALPHA_TOTAL) {
|
||||
continue; // no corners set/all corners set
|
||||
}
|
||||
|
||||
}
|
||||
src++;
|
||||
}
|
||||
src += size;
|
||||
}
|
||||
|
||||
buffer = new VoxelBuffer(vertices, indices);
|
||||
}
|
||||
info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(BufferDataPointer(buffer)));
|
||||
return STOP_RECURSION;
|
||||
}
|
||||
|
||||
void DefaultMetavoxelRendererImplementation::augment(MetavoxelData& data, const MetavoxelData& previous,
|
||||
MetavoxelInfo& info, const MetavoxelLOD& lod) {
|
||||
// copy the previous buffers
|
||||
|
@ -1509,6 +1591,9 @@ void DefaultMetavoxelRendererImplementation::augment(MetavoxelData& data, const
|
|||
HeightfieldUpdateVisitor heightfieldUpdateVisitor(lod, heightfieldRegionVisitor.regions,
|
||||
heightfieldRegionVisitor.regionBounds);
|
||||
data.guide(heightfieldUpdateVisitor);
|
||||
|
||||
VoxelAugmentVisitor voxelAugmentVisitor(lod);
|
||||
data.guideToDifferent(expandedPrevious, voxelAugmentVisitor);
|
||||
}
|
||||
|
||||
class SpannerSimulateVisitor : public SpannerVisitor {
|
||||
|
|
|
@ -39,6 +39,7 @@ public:
|
|||
|
||||
const AttributePointer& getPointBufferAttribute() { return _pointBufferAttribute; }
|
||||
const AttributePointer& getHeightfieldBufferAttribute() { return _heightfieldBufferAttribute; }
|
||||
const AttributePointer& getVoxelBufferAttribute() { return _voxelBufferAttribute; }
|
||||
|
||||
void simulate(float deltaTime);
|
||||
void render();
|
||||
|
@ -61,6 +62,7 @@ private:
|
|||
|
||||
AttributePointer _pointBufferAttribute;
|
||||
AttributePointer _heightfieldBufferAttribute;
|
||||
AttributePointer _voxelBufferAttribute;
|
||||
|
||||
MetavoxelLOD _lod;
|
||||
QReadWriteLock _lodLock;
|
||||
|
@ -212,6 +214,31 @@ private:
|
|||
QVector<BufferDataPointer> _buffers;
|
||||
};
|
||||
|
||||
/// Describes contents of a vertex in a voxel buffer.
|
||||
class VoxelVertex {
|
||||
public:
|
||||
glm::vec3 position;
|
||||
quint8 color[3];
|
||||
quint8 normal[3];
|
||||
};
|
||||
|
||||
/// Contains the information necessary to render a voxel block.
|
||||
class VoxelBuffer : public BufferData {
|
||||
public:
|
||||
|
||||
VoxelBuffer(const QVector<VoxelVertex>& vertices, const QVector<int>& indices,
|
||||
const QVector<SharedObjectPointer>& materials = QVector<SharedObjectPointer>());
|
||||
|
||||
virtual void render(bool cursor = false);
|
||||
|
||||
private:
|
||||
|
||||
QVector<VoxelVertex> _vertices;
|
||||
QVector<int> _indices;
|
||||
QVector<SharedObjectPointer> _materials;
|
||||
QVector<NetworkTexturePointer> _networkTextures;
|
||||
};
|
||||
|
||||
/// A client-side attribute that stores renderable buffers.
|
||||
class BufferDataAttribute : public InlineAttribute<BufferDataPointer> {
|
||||
Q_OBJECT
|
||||
|
|
|
@ -649,6 +649,11 @@ VoxelColorBoxEdit::VoxelColorBoxEdit(const Box& region, float granularity, const
|
|||
color(color) {
|
||||
}
|
||||
|
||||
const int VOXEL_BLOCK_SIZE = 16;
|
||||
const int VOXEL_BLOCK_SAMPLES = VOXEL_BLOCK_SIZE + 1;
|
||||
const int VOXEL_BLOCK_AREA = VOXEL_BLOCK_SAMPLES * VOXEL_BLOCK_SAMPLES;
|
||||
const int VOXEL_BLOCK_VOLUME = VOXEL_BLOCK_AREA * VOXEL_BLOCK_SAMPLES;
|
||||
|
||||
class VoxelColorBoxEditVisitor : public MetavoxelVisitor {
|
||||
public:
|
||||
|
||||
|
@ -659,18 +664,49 @@ public:
|
|||
private:
|
||||
|
||||
const VoxelColorBoxEdit& _edit;
|
||||
float _blockSize;
|
||||
};
|
||||
|
||||
VoxelColorBoxEditVisitor::VoxelColorBoxEditVisitor(const VoxelColorBoxEdit& edit) :
|
||||
MetavoxelVisitor(QVector<AttributePointer>() << AttributeRegistry::getInstance()->getVoxelColorAttribute(),
|
||||
QVector<AttributePointer>() << AttributeRegistry::getInstance()->getVoxelColorAttribute()),
|
||||
_edit(edit) {
|
||||
_edit(edit),
|
||||
_blockSize(edit.granularity * VOXEL_BLOCK_SIZE) {
|
||||
}
|
||||
|
||||
int VoxelColorBoxEditVisitor::visit(MetavoxelInfo& info) {
|
||||
if (!info.isLeaf) {
|
||||
Box bounds = info.getBounds();
|
||||
if (!bounds.intersects(_edit.region)) {
|
||||
return STOP_RECURSION;
|
||||
}
|
||||
if (!info.size > _blockSize) {
|
||||
return DEFAULT_ORDER;
|
||||
}
|
||||
VoxelColorDataPointer pointer = info.inputValues.at(0).getInlineValue<VoxelColorDataPointer>();
|
||||
QVector<QRgb> contents = (pointer && pointer->getSize() == VOXEL_BLOCK_SAMPLES) ? pointer->getContents() :
|
||||
QVector<QRgb>(VOXEL_BLOCK_VOLUME);
|
||||
|
||||
Box overlap = bounds.getIntersection(_edit.region);
|
||||
int minX = (overlap.minimum.x - info.minimum.x) / _edit.granularity;
|
||||
int minY = (overlap.minimum.y - info.minimum.y) / _edit.granularity;
|
||||
int minZ = (overlap.minimum.z - info.minimum.z) / _edit.granularity;
|
||||
int sizeX = (overlap.maximum.x - overlap.minimum.x) / _edit.granularity;
|
||||
int sizeY = (overlap.maximum.y - overlap.minimum.y) / _edit.granularity;
|
||||
int sizeZ = (overlap.maximum.z - overlap.minimum.z) / _edit.granularity;
|
||||
|
||||
QRgb color = _edit.color.rgb();
|
||||
for (QRgb* destZ = contents.data() + minZ * VOXEL_BLOCK_AREA + minY * VOXEL_BLOCK_SAMPLES + minX,
|
||||
*endZ = destZ + sizeZ * VOXEL_BLOCK_AREA; destZ != endZ; destZ += VOXEL_BLOCK_AREA) {
|
||||
for (QRgb* destY = destZ, *endY = destY + sizeY * VOXEL_BLOCK_SAMPLES; destY != endY; destY += VOXEL_BLOCK_SAMPLES) {
|
||||
for (QRgb* destX = destY, *endX = destX + sizeX; destX != endX; destX++) {
|
||||
*destX = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VoxelColorDataPointer newPointer(new VoxelColorData(contents, VOXEL_BLOCK_SAMPLES));
|
||||
info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline<VoxelColorDataPointer>(newPointer));
|
||||
|
||||
return STOP_RECURSION;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue