Working on voxel representations.

This commit is contained in:
Andrzej Kapolka 2014-08-25 15:44:12 -07:00
parent 6fbde0f42b
commit 7aa2a1d53f
5 changed files with 149 additions and 78 deletions

View file

@ -623,7 +623,7 @@ HeightfieldBuffer::HeightfieldBuffer(const glm::vec3& translation, float scale,
_textureTextureID(0),
_heightSize(glm::sqrt(height.size())),
_heightIncrement(scale / (_heightSize - HEIGHT_EXTENSION)),
_colorSize(glm::sqrt(color.size() / HeightfieldData::COLOR_BYTES)),
_colorSize(glm::sqrt(color.size() / DataBlock::COLOR_BYTES)),
_colorIncrement(scale / (_colorSize - SHARED_EDGE)) {
_heightBounds.minimum.x -= _heightIncrement * HEIGHT_BORDER;
@ -660,13 +660,13 @@ QByteArray HeightfieldBuffer::getUnextendedHeight() const {
}
QByteArray HeightfieldBuffer::getUnextendedColor() const {
int srcSize = glm::sqrt(_color.size() / HeightfieldData::COLOR_BYTES);
int srcSize = glm::sqrt(_color.size() / DataBlock::COLOR_BYTES);
int destSize = srcSize - 1;
QByteArray unextended(destSize * destSize * HeightfieldData::COLOR_BYTES, 0);
QByteArray unextended(destSize * destSize * DataBlock::COLOR_BYTES, 0);
const char* src = _color.constData();
int srcStride = srcSize * HeightfieldData::COLOR_BYTES;
int srcStride = srcSize * DataBlock::COLOR_BYTES;
char* dest = unextended.data();
int destStride = destSize * HeightfieldData::COLOR_BYTES;
int destStride = destSize * DataBlock::COLOR_BYTES;
for (int z = 0; z < destSize; z++, src += srcStride, dest += destStride) {
memcpy(dest, src, destStride);
}
@ -705,7 +705,7 @@ void HeightfieldBuffer::render(bool cursor) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, WHITE_COLOR);
} else {
int colorSize = glm::sqrt(_color.size() / HeightfieldData::COLOR_BYTES);
int colorSize = glm::sqrt(_color.size() / DataBlock::COLOR_BYTES);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, colorSize, colorSize, 0, GL_RGB, GL_UNSIGNED_BYTE, _color.constData());
}
@ -1289,13 +1289,13 @@ int HeightfieldFetchVisitor::visit(MetavoxelInfo& info) {
destY = (overlap.minimum.z - colorBounds.minimum.z) / colorIncrement;
destWidth = glm::ceil((overlap.maximum.x - overlap.minimum.x) / colorIncrement);
destHeight = glm::ceil((overlap.maximum.z - overlap.minimum.z) / colorIncrement);
dest = _buffer->getColor().data() + (destY * colorSize + destX) * HeightfieldData::COLOR_BYTES;
int destStride = colorSize * HeightfieldData::COLOR_BYTES;
int destBytes = destWidth * HeightfieldData::COLOR_BYTES;
dest = _buffer->getColor().data() + (destY * colorSize + destX) * DataBlock::COLOR_BYTES;
int destStride = colorSize * DataBlock::COLOR_BYTES;
int destBytes = destWidth * DataBlock::COLOR_BYTES;
const QByteArray& srcColor = color->getContents();
srcSize = glm::sqrt(srcColor.size() / HeightfieldData::COLOR_BYTES);
int srcStride = srcSize * HeightfieldData::COLOR_BYTES;
srcSize = glm::sqrt(srcColor.size() / DataBlock::COLOR_BYTES);
int srcStride = srcSize * DataBlock::COLOR_BYTES;
srcIncrement = info.size / srcSize;
if (srcIncrement == colorIncrement) {
@ -1303,7 +1303,7 @@ int HeightfieldFetchVisitor::visit(MetavoxelInfo& info) {
int srcX = (overlap.minimum.x - info.minimum.x) / srcIncrement;
int srcY = (overlap.minimum.z - info.minimum.z) / srcIncrement;
const char* src = srcColor.constData() + (srcY * srcSize + srcX) * HeightfieldData::COLOR_BYTES;
const char* src = srcColor.constData() + (srcY * srcSize + srcX) * DataBlock::COLOR_BYTES;
for (int y = 0; y < destHeight; y++, src += srcStride, dest += destStride) {
memcpy(dest, src, destBytes);
}
@ -1315,9 +1315,9 @@ int HeightfieldFetchVisitor::visit(MetavoxelInfo& info) {
for (int y = 0; y < destHeight; y++, dest += destStride, srcY += srcAdvance) {
const char* src = srcColor.constData() + (int)srcY * srcStride;
float lineSrcX = srcX;
for (char* lineDest = dest, *end = dest + destBytes; lineDest != end; lineDest += HeightfieldData::COLOR_BYTES,
for (char* lineDest = dest, *end = dest + destBytes; lineDest != end; lineDest += DataBlock::COLOR_BYTES,
lineSrcX += srcAdvance) {
const char* lineSrc = src + (int)lineSrcX * HeightfieldData::COLOR_BYTES;
const char* lineSrc = src + (int)lineSrcX * DataBlock::COLOR_BYTES;
lineDest[0] = lineSrc[0];
lineDest[1] = lineSrc[1];
lineDest[2] = lineSrc[2];
@ -1372,9 +1372,9 @@ int HeightfieldRegionVisitor::visit(MetavoxelInfo& info) {
int colorContentsSize = 0;
if (color) {
const QByteArray& colorContents = color->getContents();
int colorSize = glm::sqrt(colorContents.size() / HeightfieldData::COLOR_BYTES);
int colorSize = glm::sqrt(colorContents.size() / DataBlock::COLOR_BYTES);
int extendedColorSize = colorSize + HeightfieldBuffer::SHARED_EDGE;
colorContentsSize = extendedColorSize * extendedColorSize * HeightfieldData::COLOR_BYTES;
colorContentsSize = extendedColorSize * extendedColorSize * DataBlock::COLOR_BYTES;
}
HeightfieldTextureDataPointer texture = info.inputValues.at(2).getInlineValue<HeightfieldTextureDataPointer>();

View file

@ -966,7 +966,7 @@ void ImportHeightfieldTool::apply() {
QByteArray color;
if (buffer->getColor().isEmpty()) {
const int WHITE_VALUE = 0xFF;
color = QByteArray(height.size() * HeightfieldData::COLOR_BYTES, WHITE_VALUE);
color = QByteArray(height.size() * DataBlock::COLOR_BYTES, WHITE_VALUE);
} else {
color = buffer->getUnextendedColor();
}
@ -1032,22 +1032,22 @@ void ImportHeightfieldTool::updatePreview() {
int rows = qMin(heightSize - offsetY, _heightImage.height() - extendedI);
int columns = qMin(heightSize - offsetX, _heightImage.width() - extendedJ);
for (int y = 0; y < rows; y++) {
uchar* src = _heightImage.scanLine(extendedI + y) + extendedJ * HeightfieldData::COLOR_BYTES;
uchar* src = _heightImage.scanLine(extendedI + y) + extendedJ * DataBlock::COLOR_BYTES;
char* dest = height.data() + (y + offsetY) * heightSize + offsetX;
for (int x = 0; x < columns; x++) {
*dest++ = *src;
src += HeightfieldData::COLOR_BYTES;
src += DataBlock::COLOR_BYTES;
}
}
QByteArray color;
if (!_colorImage.isNull()) {
color = QByteArray(colorSize * colorSize * HeightfieldData::COLOR_BYTES, 0);
color = QByteArray(colorSize * colorSize * DataBlock::COLOR_BYTES, 0);
rows = qMax(0, qMin(colorSize, _colorImage.height() - i));
columns = qMax(0, qMin(colorSize, _colorImage.width() - j));
for (int y = 0; y < rows; y++) {
memcpy(color.data() + y * colorSize * HeightfieldData::COLOR_BYTES,
_colorImage.scanLine(i + y) + j * HeightfieldData::COLOR_BYTES,
columns * HeightfieldData::COLOR_BYTES);
memcpy(color.data() + y * colorSize * DataBlock::COLOR_BYTES,
_colorImage.scanLine(i + y) + j * DataBlock::COLOR_BYTES,
columns * DataBlock::COLOR_BYTES);
}
}
buffers.append(BufferDataPointer(new HeightfieldBuffer(glm::vec3(x, 0.0f, z), 1.0f, height, color)));

View file

@ -497,11 +497,7 @@ AttributeValue SpannerPackedNormalAttribute::inherit(const AttributeValue& paren
return AttributeValue(parentValue.getAttribute());
}
HeightfieldData::HeightfieldData(const QByteArray& contents) :
_contents(contents) {
}
HeightfieldData::~HeightfieldData() {
DataBlock::~DataBlock() {
}
enum HeightfieldImage { NULL_HEIGHTFIELD_IMAGE, NORMAL_HEIGHTFIELD_IMAGE, DEFLATED_HEIGHTFIELD_IMAGE };
@ -548,7 +544,7 @@ const QImage decodeHeightfieldImage(const QByteArray& data) {
}
HeightfieldHeightData::HeightfieldHeightData(const QByteArray& contents) :
HeightfieldData(contents) {
_contents(contents) {
}
HeightfieldHeightData::HeightfieldHeightData(Bitstream& in, int bytes) {
@ -562,7 +558,7 @@ HeightfieldHeightData::HeightfieldHeightData(Bitstream& in, int bytes, const Hei
}
QMutexLocker locker(&reference->getEncodedDeltaMutex());
reference->setEncodedDelta(in.readAligned(bytes));
reference->setDeltaData(HeightfieldDataPointer(this));
reference->setDeltaData(DataBlockPointer(this));
_contents = reference->getContents();
QImage image = decodeHeightfieldImage(reference->getEncodedDelta());
if (image.isNull()) {
@ -685,7 +681,7 @@ void HeightfieldHeightData::writeDelta(Bitstream& out, const HeightfieldHeightDa
}
image.setOffset(QPoint(minX + 1, minY + 1));
reference->setEncodedDelta(encodeHeightfieldImage(image));
reference->setDeltaData(HeightfieldDataPointer(this));
reference->setDeltaData(DataBlockPointer(this));
}
out << reference->getEncodedDelta().size();
out.writeAligned(reference->getEncodedDelta());
@ -744,7 +740,7 @@ void HeightfieldHeightData::set(const QImage& image) {
}
HeightfieldColorData::HeightfieldColorData(const QByteArray& contents) :
HeightfieldData(contents) {
_contents(contents) {
}
HeightfieldColorData::HeightfieldColorData(Bitstream& in, int bytes) {
@ -758,7 +754,7 @@ HeightfieldColorData::HeightfieldColorData(Bitstream& in, int bytes, const Heigh
}
QMutexLocker locker(&reference->getEncodedDeltaMutex());
reference->setEncodedDelta(in.readAligned(bytes));
reference->setDeltaData(HeightfieldDataPointer(this));
reference->setDeltaData(DataBlockPointer(this));
_contents = reference->getContents();
QImage image = decodeHeightfieldImage(reference->getEncodedDelta());
if (image.isNull()) {
@ -875,7 +871,7 @@ void HeightfieldColorData::writeDelta(Bitstream& out, const HeightfieldColorData
}
image.setOffset(QPoint(minX + 1, minY + 1));
reference->setEncodedDelta(encodeHeightfieldImage(image));
reference->setDeltaData(HeightfieldDataPointer(this));
reference->setDeltaData(DataBlockPointer(this));
}
out << reference->getEncodedDelta().size();
out.writeAligned(reference->getEncodedDelta());
@ -954,7 +950,7 @@ static QByteArray decodeTexture(const QByteArray& encoded, int& offsetX, int& of
}
HeightfieldTextureData::HeightfieldTextureData(const QByteArray& contents, const QVector<SharedObjectPointer>& textures) :
HeightfieldData(contents),
_contents(contents),
_textures(textures) {
}
@ -970,7 +966,7 @@ HeightfieldTextureData::HeightfieldTextureData(Bitstream& in, int bytes, const H
QMutexLocker locker(&reference->getEncodedDeltaMutex());
reference->setEncodedDelta(in.readAligned(bytes));
in.readDelta(_textures, reference->getTextures());
reference->setDeltaData(HeightfieldDataPointer(this));
reference->setDeltaData(DataBlockPointer(this));
_contents = reference->getContents();
int offsetX, offsetY, width, height;
@ -1042,7 +1038,7 @@ void HeightfieldTextureData::writeDelta(Bitstream& out, const HeightfieldTexture
}
}
reference->setEncodedDelta(encodeTexture(minX + 1, minY + 1, width, height, delta));
reference->setDeltaData(HeightfieldDataPointer(this));
reference->setDeltaData(DataBlockPointer(this));
}
out << reference->getEncodedDelta().size();
out.writeAligned(reference->getEncodedDelta());
@ -1251,8 +1247,8 @@ bool HeightfieldColorAttribute::merge(void*& parent, void* children[], bool post
*(HeightfieldColorDataPointer*)&parent = HeightfieldColorDataPointer();
return true;
}
int size = glm::sqrt(maxSize / (float)HeightfieldData::COLOR_BYTES);
QByteArray contents(size * size * HeightfieldData::COLOR_BYTES, 0);
int size = glm::sqrt(maxSize / (float)DataBlock::COLOR_BYTES);
QByteArray contents(size * size * DataBlock::COLOR_BYTES, 0);
int halfSize = size / 2;
for (int i = 0; i < MERGE_COUNT; i++) {
HeightfieldColorDataPointer child = decodeInline<HeightfieldColorDataPointer>(children[i]);
@ -1260,7 +1256,7 @@ bool HeightfieldColorAttribute::merge(void*& parent, void* children[], bool post
continue;
}
const QByteArray& childContents = child->getContents();
int childSize = glm::sqrt(childContents.size() / (float)HeightfieldData::COLOR_BYTES);
int childSize = glm::sqrt(childContents.size() / (float)DataBlock::COLOR_BYTES);
const int INDEX_MASK = 1;
int xIndex = i & INDEX_MASK;
const int Y_SHIFT = 1;
@ -1270,24 +1266,24 @@ bool HeightfieldColorAttribute::merge(void*& parent, void* children[], bool post
}
int Z_SHIFT = 2;
int zIndex = (i >> Z_SHIFT) & INDEX_MASK;
char* dest = contents.data() + ((zIndex * halfSize * size) + (xIndex * halfSize)) * HeightfieldData::COLOR_BYTES;
char* dest = contents.data() + ((zIndex * halfSize * size) + (xIndex * halfSize)) * DataBlock::COLOR_BYTES;
uchar* src = (uchar*)childContents.data();
int childStride = childSize * HeightfieldData::COLOR_BYTES;
int stride = size * HeightfieldData::COLOR_BYTES;
int childStride = childSize * DataBlock::COLOR_BYTES;
int stride = size * DataBlock::COLOR_BYTES;
int halfStride = stride / 2;
int childStep = 2 * HeightfieldData::COLOR_BYTES;
int redOffset3 = childStride + HeightfieldData::COLOR_BYTES;
int greenOffset1 = HeightfieldData::COLOR_BYTES + 1;
int childStep = 2 * DataBlock::COLOR_BYTES;
int redOffset3 = childStride + DataBlock::COLOR_BYTES;
int greenOffset1 = DataBlock::COLOR_BYTES + 1;
int greenOffset2 = childStride + 1;
int greenOffset3 = childStride + HeightfieldData::COLOR_BYTES + 1;
int blueOffset1 = HeightfieldData::COLOR_BYTES + 2;
int greenOffset3 = childStride + DataBlock::COLOR_BYTES + 1;
int blueOffset1 = DataBlock::COLOR_BYTES + 2;
int blueOffset2 = childStride + 2;
int blueOffset3 = childStride + HeightfieldData::COLOR_BYTES + 2;
int blueOffset3 = childStride + DataBlock::COLOR_BYTES + 2;
if (childSize == size) {
// simple case: one destination value for four child values
for (int z = 0; z < halfSize; z++) {
for (char* end = dest + halfSize * HeightfieldData::COLOR_BYTES; dest != end; src += childStep) {
*dest++ = ((int)src[0] + (int)src[HeightfieldData::COLOR_BYTES] +
for (char* end = dest + halfSize * DataBlock::COLOR_BYTES; dest != end; src += childStep) {
*dest++ = ((int)src[0] + (int)src[DataBlock::COLOR_BYTES] +
(int)src[childStride] + (int)src[redOffset3]) >> 2;
*dest++ = ((int)src[1] + (int)src[greenOffset1] + (int)src[greenOffset2] + (int)src[greenOffset3]) >> 2;
*dest++ = ((int)src[2] + (int)src[blueOffset1] + (int)src[blueOffset2] + (int)src[blueOffset3]) >> 2;
@ -1300,14 +1296,14 @@ bool HeightfieldColorAttribute::merge(void*& parent, void* children[], bool post
int halfChildSize = childSize / 2;
int destPerSrc = size / childSize;
for (int z = 0; z < halfChildSize; z++) {
for (uchar* end = src + childSize * HeightfieldData::COLOR_BYTES; src != end; src += childStep) {
*dest++ = ((int)src[0] + (int)src[HeightfieldData::COLOR_BYTES] +
for (uchar* end = src + childSize * DataBlock::COLOR_BYTES; src != end; src += childStep) {
*dest++ = ((int)src[0] + (int)src[DataBlock::COLOR_BYTES] +
(int)src[childStride] + (int)src[redOffset3]) >> 2;
*dest++ = ((int)src[1] + (int)src[greenOffset1] + (int)src[greenOffset2] + (int)src[greenOffset3]) >> 2;
*dest++ = ((int)src[2] + (int)src[blueOffset1] + (int)src[blueOffset2] + (int)src[blueOffset3]) >> 2;
for (int j = 1; j < destPerSrc; j++) {
memcpy(dest, dest - HeightfieldData::COLOR_BYTES, HeightfieldData::COLOR_BYTES);
dest += HeightfieldData::COLOR_BYTES;
memcpy(dest, dest - DataBlock::COLOR_BYTES, DataBlock::COLOR_BYTES);
dest += DataBlock::COLOR_BYTES;
}
}
dest += halfStride;
@ -1390,6 +1386,51 @@ bool HeightfieldTextureAttribute::merge(void*& parent, void* children[], bool po
return maxSize == 0;
}
VoxelSignData::VoxelSignData(const QByteArray& contents) :
_contents(contents) {
}
VoxelSignData::VoxelSignData(Bitstream& in, int bytes) {
read(in, bytes);
}
VoxelSignData::VoxelSignData(Bitstream& in, int bytes, const VoxelSignDataPointer& reference) {
if (!reference) {
read(in, bytes);
return;
}
QMutexLocker locker(&reference->getEncodedDeltaMutex());
reference->setEncodedDelta(in.readAligned(bytes));
reference->setDeltaData(DataBlockPointer(this));
_contents = reference->getContents();
}
void VoxelSignData::write(Bitstream& out) {
QMutexLocker locker(&_encodedMutex);
if (_encoded.isEmpty()) {
}
out << _encoded.size();
out.writeAligned(_encoded);
}
void VoxelSignData::writeDelta(Bitstream& out, const VoxelSignDataPointer& reference) {
if (!reference || reference->getContents().size() != _contents.size()) {
write(out);
return;
}
QMutexLocker locker(&reference->getEncodedDeltaMutex());
if (reference->getEncodedDelta().isEmpty() || reference->getDeltaData() != this) {
}
out << reference->getEncodedDelta().size();
out.writeAligned(reference->getEncodedDelta());
}
void VoxelSignData::read(Bitstream& in, int bytes) {
}
SharedObjectAttribute::SharedObjectAttribute(const QString& name, const QMetaObject* metaObject,
const SharedObjectPointer& defaultValue) :
InlineAttribute<SharedObjectPointer>(name, defaultValue),

View file

@ -29,14 +29,15 @@ class QScriptEngine;
class QScriptValue;
class Attribute;
class DataBlock;
class HeightfieldColorData;
class HeightfieldData;
class HeightfieldHeightData;
class HeightfieldTextureData;
class MetavoxelData;
class MetavoxelLOD;
class MetavoxelNode;
class MetavoxelStreamState;
class VoxelSignData;
typedef SharedObjectPointerTemplate<Attribute> AttributePointer;
@ -100,13 +101,13 @@ public:
/// Returns a reference to the standard "spannerMask" attribute.
const AttributePointer& getSpannerMaskAttribute() const { return _spannerMaskAttribute; }
/// Returns a reference to the standard HeightfieldDataPointer "heightfield" attribute.
/// Returns a reference to the standard HeightfieldHeightDataPointer "heightfield" attribute.
const AttributePointer& getHeightfieldAttribute() const { return _heightfieldAttribute; }
/// Returns a reference to the standard HeightfieldDataPointer "heightfieldColor" attribute.
/// Returns a reference to the standard HeightfieldColorDataPointer "heightfieldColor" attribute.
const AttributePointer& getHeightfieldColorAttribute() const { return _heightfieldColorAttribute; }
/// Returns a reference to the standard HeightfieldDataPointer "heightfieldTexture" attribute.
/// Returns a reference to the standard HeightfieldTextureDataPointer "heightfieldTexture" attribute.
const AttributePointer& getHeightfieldTextureAttribute() const { return _heightfieldTextureAttribute; }
private:
@ -435,21 +436,18 @@ public:
virtual AttributeValue inherit(const AttributeValue& parentValue) const;
};
typedef QExplicitlySharedDataPointer<HeightfieldData> HeightfieldDataPointer;
typedef QExplicitlySharedDataPointer<DataBlock> DataBlockPointer;
/// Contains a block of heightfield data.
class HeightfieldData : public QSharedData {
/// Base class for blocks of data.
class DataBlock : public QSharedData {
public:
static const int COLOR_BYTES = 3;
HeightfieldData(const QByteArray& contents = QByteArray());
virtual ~HeightfieldData();
virtual ~DataBlock();
const QByteArray& getContents() const { return _contents; }
void setDeltaData(const HeightfieldDataPointer& deltaData) { _deltaData = deltaData; }
const HeightfieldDataPointer& getDeltaData() const { return _deltaData; }
void setDeltaData(const DataBlockPointer& deltaData) { _deltaData = deltaData; }
const DataBlockPointer& getDeltaData() const { return _deltaData; }
void setEncodedDelta(const QByteArray& encodedDelta) { _encodedDelta = encodedDelta; }
const QByteArray& getEncodedDelta() const { return _encodedDelta; }
@ -458,17 +456,16 @@ public:
protected:
QByteArray _contents;
QByteArray _encoded;
QMutex _encodedMutex;
HeightfieldDataPointer _deltaData;
DataBlockPointer _deltaData;
QByteArray _encodedDelta;
QMutex _encodedDeltaMutex;
class EncodedSubdivision {
public:
HeightfieldDataPointer ancestor;
DataBlockPointer ancestor;
QByteArray data;
};
QVector<EncodedSubdivision> _encodedSubdivisions;
@ -478,7 +475,7 @@ protected:
typedef QExplicitlySharedDataPointer<HeightfieldHeightData> HeightfieldHeightDataPointer;
/// Contains a block of heightfield height data.
class HeightfieldHeightData : public HeightfieldData {
class HeightfieldHeightData : public DataBlock {
public:
HeightfieldHeightData(const QByteArray& contents);
@ -487,6 +484,8 @@ public:
HeightfieldHeightData(Bitstream& in, int bytes, const HeightfieldHeightDataPointer& ancestor,
const glm::vec3& minimum, float size);
const QByteArray& getContents() const { return _contents; }
void write(Bitstream& out);
void writeDelta(Bitstream& out, const HeightfieldHeightDataPointer& reference);
void writeSubdivided(Bitstream& out, const HeightfieldHeightDataPointer& ancestor,
@ -496,12 +495,14 @@ private:
void read(Bitstream& in, int bytes);
void set(const QImage& image);
QByteArray _contents;
};
typedef QExplicitlySharedDataPointer<HeightfieldColorData> HeightfieldColorDataPointer;
/// Contains a block of heightfield color data.
class HeightfieldColorData : public HeightfieldData {
class HeightfieldColorData : public DataBlock {
public:
HeightfieldColorData(const QByteArray& contents);
@ -510,6 +511,8 @@ public:
HeightfieldColorData(Bitstream& in, int bytes, const HeightfieldColorDataPointer& ancestor,
const glm::vec3& minimum, float size);
const QByteArray& getContents() const { return _contents; }
void write(Bitstream& out);
void writeDelta(Bitstream& out, const HeightfieldColorDataPointer& reference);
void writeSubdivided(Bitstream& out, const HeightfieldColorDataPointer& ancestor,
@ -519,12 +522,14 @@ private:
void read(Bitstream& in, int bytes);
void set(const QImage& image);
QByteArray _contents;
};
typedef QExplicitlySharedDataPointer<HeightfieldTextureData> HeightfieldTextureDataPointer;
/// Contains a block of heightfield texture data.
class HeightfieldTextureData : public HeightfieldData {
class HeightfieldTextureData : public DataBlock {
public:
HeightfieldTextureData(const QByteArray& contents,
@ -532,6 +537,8 @@ public:
HeightfieldTextureData(Bitstream& in, int bytes);
HeightfieldTextureData(Bitstream& in, int bytes, const HeightfieldTextureDataPointer& reference);
const QByteArray& getContents() const { return _contents; }
const QVector<SharedObjectPointer>& getTextures() const { return _textures; }
void write(Bitstream& out);
@ -541,6 +548,7 @@ private:
void read(Bitstream& in, int bytes);
QByteArray _contents;
QVector<SharedObjectPointer> _textures;
};
@ -618,6 +626,28 @@ public:
virtual bool merge(void*& parent, void* children[], bool postRead = false) const;
};
typedef QExplicitlySharedDataPointer<VoxelSignData> VoxelSignDataPointer;
/// Contains a block of voxel sign data.
class VoxelSignData : public DataBlock {
public:
VoxelSignData(const QByteArray& contents);
VoxelSignData(Bitstream& in, int bytes);
VoxelSignData(Bitstream& in, int bytes, const VoxelSignDataPointer& reference);
const QByteArray& getContents() const { return _contents; }
void write(Bitstream& out);
void writeDelta(Bitstream& out, const VoxelSignDataPointer& reference);
private:
void read(Bitstream& in, int bytes);
QByteArray _contents;
};
/// An attribute that takes the form of QObjects of a given meta-type (a subclass of SharedObject).
class SharedObjectAttribute : public InlineAttribute<SharedObjectPointer> {
Q_OBJECT

View file

@ -442,7 +442,7 @@ static void paintColor(MetavoxelInfo& info, int index, const glm::vec3& position
return;
}
QByteArray contents(pointer->getContents());
int size = glm::sqrt((float)contents.size() / HeightfieldData::COLOR_BYTES);
int size = glm::sqrt((float)contents.size() / DataBlock::COLOR_BYTES);
int highest = size - 1;
float heightScale = size / info.size;
@ -456,14 +456,14 @@ static void paintColor(MetavoxelInfo& info, int index, const glm::vec3& position
// paint all points within the radius
float z = qMax(start.z, 0.0f);
float startX = qMax(start.x, 0.0f), endX = qMin(end.x, (float)highest);
int stride = size * HeightfieldData::COLOR_BYTES;
char* lineDest = contents.data() + (int)z * stride + (int)startX * HeightfieldData::COLOR_BYTES;
int stride = size * DataBlock::COLOR_BYTES;
char* lineDest = contents.data() + (int)z * stride + (int)startX * DataBlock::COLOR_BYTES;
float squaredRadius = scaledRadius * scaledRadius;
char red = color.red(), green = color.green(), blue = color.blue();
bool changed = false;
for (float endZ = qMin(end.z, (float)highest); z <= endZ; z += 1.0f) {
char* dest = lineDest;
for (float x = startX; x <= endX; x += 1.0f, dest += HeightfieldData::COLOR_BYTES) {
for (float x = startX; x <= endX; x += 1.0f, dest += DataBlock::COLOR_BYTES) {
float dx = x - center.x, dz = z - center.z;
if (dx * dx + dz * dz <= squaredRadius) {
dest[0] = red;