Attempting to remove some number magic.

This commit is contained in:
Andrzej Kapolka 2014-08-12 12:01:07 -07:00
parent 24cc90c1db
commit ee01d85b5e
5 changed files with 95 additions and 73 deletions

View file

@ -333,12 +333,11 @@ void PointBuffer::render(bool cursor) {
} }
HeightfieldBuffer::HeightfieldBuffer(const glm::vec3& translation, float scale, HeightfieldBuffer::HeightfieldBuffer(const glm::vec3& translation, float scale,
const QByteArray& height, const QByteArray& color, bool clearAfterLoading) : const QByteArray& height, const QByteArray& color) :
_translation(translation), _translation(translation),
_scale(scale), _scale(scale),
_height(height), _height(height),
_color(color), _color(color),
_clearAfterLoading(clearAfterLoading),
_heightTextureID(0), _heightTextureID(0),
_colorTextureID(0), _colorTextureID(0),
_heightSize(glm::sqrt(height.size())) { _heightSize(glm::sqrt(height.size())) {
@ -355,6 +354,32 @@ HeightfieldBuffer::~HeightfieldBuffer() {
} }
} }
QByteArray HeightfieldBuffer::getUnextendedHeight() const {
int srcSize = glm::sqrt(_height.size());
int destSize = srcSize - 3;
QByteArray unextended(destSize * destSize, 0);
const char* src = _height.constData() + srcSize + 1;
char* dest = unextended.data();
for (int z = 0; z < destSize; z++, src += srcSize, dest += destSize) {
memcpy(dest, src, destSize);
}
return unextended;
}
QByteArray HeightfieldBuffer::getUnextendedColor() const {
int srcSize = glm::sqrt(_color.size() / HeightfieldData::COLOR_BYTES);
int destSize = srcSize - 1;
QByteArray unextended(destSize * destSize * HeightfieldData::COLOR_BYTES, 0);
const char* src = _color.constData();
int srcStride = srcSize * HeightfieldData::COLOR_BYTES;
char* dest = unextended.data();
int destStride = destSize * HeightfieldData::COLOR_BYTES;
for (int z = 0; z < destSize; z++, src += srcStride, dest += destStride) {
memcpy(dest, src, destStride);
}
return unextended;
}
class HeightfieldPoint { class HeightfieldPoint {
public: public:
glm::vec2 textureCoord; glm::vec2 textureCoord;
@ -372,9 +397,6 @@ void HeightfieldBuffer::render(bool cursor) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, _heightSize, _heightSize, 0, glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, _heightSize, _heightSize, 0,
GL_LUMINANCE, GL_UNSIGNED_BYTE, _height.constData()); GL_LUMINANCE, GL_UNSIGNED_BYTE, _height.constData());
if (_clearAfterLoading) {
_height.clear();
}
glGenTextures(1, &_colorTextureID); glGenTextures(1, &_colorTextureID);
glBindTexture(GL_TEXTURE_2D, _colorTextureID); glBindTexture(GL_TEXTURE_2D, _colorTextureID);
@ -386,15 +408,12 @@ void HeightfieldBuffer::render(bool cursor) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, WHITE_COLOR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, WHITE_COLOR);
} else { } else {
int colorSize = glm::sqrt(_color.size() / 3); int colorSize = glm::sqrt(_color.size() / HeightfieldData::COLOR_BYTES);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, colorSize, colorSize, 0, GL_RGB, GL_UNSIGNED_BYTE, _color.constData()); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, colorSize, colorSize, 0, GL_RGB, GL_UNSIGNED_BYTE, _color.constData());
if (_clearAfterLoading) {
_color.clear();
}
} }
} }
// create the buffer objects lazily // create the buffer objects lazily
int innerSize = _heightSize - 2; int innerSize = _heightSize - 2 * HeightfieldBuffer::HEIGHT_BORDER;
int vertexCount = _heightSize * _heightSize; int vertexCount = _heightSize * _heightSize;
int rows = _heightSize - 1; int rows = _heightSize - 1;
int indexCount = rows * rows * 4; int indexCount = rows * rows * 4;
@ -682,9 +701,9 @@ int HeightfieldAugmentVisitor::visit(MetavoxelInfo& info) {
if (height) { if (height) {
const QByteArray& heightContents = height->getContents(); const QByteArray& heightContents = height->getContents();
int size = glm::sqrt(heightContents.size()); int size = glm::sqrt(heightContents.size());
int extendedSize = size + 3; int extendedSize = size + HeightfieldBuffer::HEIGHT_EXTENSION;
QByteArray extendedHeightContents(extendedSize * extendedSize, 0); QByteArray extendedHeightContents(extendedSize * extendedSize, 0);
char* dest = extendedHeightContents.data() + extendedSize + 1; char* dest = extendedHeightContents.data() + (extendedSize + 1) * HeightfieldBuffer::HEIGHT_BORDER;
const char* src = heightContents.constData(); const char* src = heightContents.constData();
for (int z = 0; z < size; z++, src += size, dest += extendedSize) { for (int z = 0; z < size; z++, src += size, dest += extendedSize) {
memcpy(dest, src, size); memcpy(dest, src, size);
@ -693,14 +712,13 @@ int HeightfieldAugmentVisitor::visit(MetavoxelInfo& info) {
HeightfieldDataPointer color = info.inputValues.at(1).getInlineValue<HeightfieldDataPointer>(); HeightfieldDataPointer color = info.inputValues.at(1).getInlineValue<HeightfieldDataPointer>();
if (color) { if (color) {
const QByteArray& colorContents = color->getContents(); const QByteArray& colorContents = color->getContents();
const int BYTES_PER_PIXEL = 3; int colorSize = glm::sqrt(colorContents.size() / HeightfieldData::COLOR_BYTES);
int colorSize = glm::sqrt(colorContents.size() / BYTES_PER_PIXEL); int extendedColorSize = colorSize + HeightfieldBuffer::SHARED_EDGE;
int extendedColorSize = colorSize + 1; extendedColorContents = QByteArray(extendedColorSize * extendedColorSize * HeightfieldData::COLOR_BYTES, 0);
extendedColorContents = QByteArray(extendedColorSize * extendedColorSize * BYTES_PER_PIXEL, 0);
char* dest = extendedColorContents.data(); char* dest = extendedColorContents.data();
const char* src = colorContents.constData(); const char* src = colorContents.constData();
int srcStride = colorSize * BYTES_PER_PIXEL; int srcStride = colorSize * HeightfieldData::COLOR_BYTES;
int destStride = extendedColorSize * BYTES_PER_PIXEL; int destStride = extendedColorSize * HeightfieldData::COLOR_BYTES;
for (int z = 0; z < colorSize; z++, src += srcStride, dest += destStride) { for (int z = 0; z < colorSize; z++, src += srcStride, dest += destStride) {
memcpy(dest, src, srcStride); memcpy(dest, src, srcStride);
} }

View file

@ -131,10 +131,11 @@ private:
class HeightfieldBuffer : public BufferData { class HeightfieldBuffer : public BufferData {
public: public:
/// Creates a new heightfield buffer. static const int HEIGHT_BORDER = 1;
/// \param clearAfterLoading if true, clear the data arrays after we load them into textures in order to reclaim the space static const int SHARED_EDGE = 1;
HeightfieldBuffer(const glm::vec3& translation, float scale, const QByteArray& height, const QByteArray& color, static const int HEIGHT_EXTENSION = 2 * HEIGHT_BORDER + SHARED_EDGE;
bool clearAfterLoading = true);
HeightfieldBuffer(const glm::vec3& translation, float scale, const QByteArray& height, const QByteArray& color);
~HeightfieldBuffer(); ~HeightfieldBuffer();
const glm::vec3& getTranslation() const { return _translation; } const glm::vec3& getTranslation() const { return _translation; }
@ -142,6 +143,9 @@ public:
const QByteArray& getHeight() const { return _height; } const QByteArray& getHeight() const { return _height; }
const QByteArray& getColor() const { return _color; } const QByteArray& getColor() const { return _color; }
QByteArray getUnextendedHeight() const;
QByteArray getUnextendedColor() const;
virtual void render(bool cursor = false); virtual void render(bool cursor = false);
private: private:
@ -150,7 +154,6 @@ private:
float _scale; float _scale;
QByteArray _height; QByteArray _height;
QByteArray _color; QByteArray _color;
bool _clearAfterLoading;
GLuint _heightTextureID; GLuint _heightTextureID;
GLuint _colorTextureID; GLuint _colorTextureID;
int _heightSize; int _heightSize;

View file

@ -956,11 +956,11 @@ void ImportHeightfieldTool::apply() {
HeightfieldBuffer* buffer = static_cast<HeightfieldBuffer*>(bufferData.data()); HeightfieldBuffer* buffer = static_cast<HeightfieldBuffer*>(bufferData.data());
MetavoxelData data; MetavoxelData data;
data.setSize(scale); data.setSize(scale);
HeightfieldDataPointer heightPointer(new HeightfieldData(buffer->getHeight())); HeightfieldDataPointer heightPointer(new HeightfieldData(buffer->getUnextendedHeight()));
data.setRoot(AttributeRegistry::getInstance()->getHeightfieldAttribute(), new MetavoxelNode(AttributeValue( data.setRoot(AttributeRegistry::getInstance()->getHeightfieldAttribute(), new MetavoxelNode(AttributeValue(
AttributeRegistry::getInstance()->getHeightfieldAttribute(), encodeInline(heightPointer)))); AttributeRegistry::getInstance()->getHeightfieldAttribute(), encodeInline(heightPointer))));
if (!buffer->getColor().isEmpty()) { if (!buffer->getColor().isEmpty()) {
HeightfieldDataPointer colorPointer(new HeightfieldData(buffer->getColor())); HeightfieldDataPointer colorPointer(new HeightfieldData(buffer->getUnextendedColor()));
data.setRoot(AttributeRegistry::getInstance()->getHeightfieldColorAttribute(), new MetavoxelNode(AttributeValue( data.setRoot(AttributeRegistry::getInstance()->getHeightfieldColorAttribute(), new MetavoxelNode(AttributeValue(
AttributeRegistry::getInstance()->getHeightfieldColorAttribute(), encodeInline(colorPointer)))); AttributeRegistry::getInstance()->getHeightfieldColorAttribute(), encodeInline(colorPointer))));
} }
@ -1003,38 +1003,38 @@ void ImportHeightfieldTool::updatePreview() {
if (_heightImage.width() > 0 && _heightImage.height() > 0) { if (_heightImage.width() > 0 && _heightImage.height() > 0) {
float z = 0.0f; float z = 0.0f;
int blockSize = pow(2.0, _blockSize->value()); int blockSize = pow(2.0, _blockSize->value());
int heightSize = blockSize + 3; int heightSize = blockSize + HeightfieldBuffer::HEIGHT_EXTENSION;
int colorSize = blockSize + 1; int colorSize = blockSize + HeightfieldBuffer::SHARED_EDGE;
for (int i = 0; i < _heightImage.height(); i += blockSize, z++) { for (int i = 0; i < _heightImage.height(); i += blockSize, z++) {
float x = 0.0f; float x = 0.0f;
for (int j = 0; j < _heightImage.width(); j += blockSize, x++) { for (int j = 0; j < _heightImage.width(); j += blockSize, x++) {
QByteArray height(heightSize * heightSize, 0); QByteArray height(heightSize * heightSize, 0);
int extendedI = qMax(i - 1, 0); int extendedI = qMax(i - HeightfieldBuffer::HEIGHT_BORDER, 0);
int extendedJ = qMax(j - 1, 0); int extendedJ = qMax(j - HeightfieldBuffer::HEIGHT_BORDER, 0);
int offsetY = extendedI - i + 1; int offsetY = extendedI - i + HeightfieldBuffer::HEIGHT_BORDER;
int offsetX = extendedJ - j + 1; int offsetX = extendedJ - j + HeightfieldBuffer::HEIGHT_BORDER;
int rows = qMin(heightSize - offsetY, _heightImage.height() - extendedI); int rows = qMin(heightSize - offsetY, _heightImage.height() - extendedI);
int columns = qMin(heightSize - offsetX, _heightImage.width() - extendedJ); int columns = qMin(heightSize - offsetX, _heightImage.width() - extendedJ);
const int BYTES_PER_COLOR = 3;
for (int y = 0; y < rows; y++) { for (int y = 0; y < rows; y++) {
uchar* src = _heightImage.scanLine(extendedI + y) + extendedJ * BYTES_PER_COLOR; uchar* src = _heightImage.scanLine(extendedI + y) + extendedJ * HeightfieldData::COLOR_BYTES;
char* dest = height.data() + (y + offsetY) * heightSize + offsetX; char* dest = height.data() + (y + offsetY) * heightSize + offsetX;
for (int x = 0; x < columns; x++) { for (int x = 0; x < columns; x++) {
*dest++ = *src; *dest++ = *src;
src += BYTES_PER_COLOR; src += HeightfieldData::COLOR_BYTES;
} }
} }
QByteArray color; QByteArray color;
if (!_colorImage.isNull()) { if (!_colorImage.isNull()) {
color = QByteArray(colorSize * colorSize * BYTES_PER_COLOR, 0); color = QByteArray(colorSize * colorSize * HeightfieldData::COLOR_BYTES, 0);
rows = qMax(0, qMin(colorSize, _colorImage.height() - i)); rows = qMax(0, qMin(colorSize, _colorImage.height() - i));
columns = qMax(0, qMin(colorSize, _colorImage.width() - j)); columns = qMax(0, qMin(colorSize, _colorImage.width() - j));
for (int y = 0; y < rows; y++) { for (int y = 0; y < rows; y++) {
memcpy(color.data() + y * colorSize * BYTES_PER_COLOR, memcpy(color.data() + y * colorSize * HeightfieldData::COLOR_BYTES,
_colorImage.scanLine(i + y) + j * BYTES_PER_COLOR, columns * BYTES_PER_COLOR); _colorImage.scanLine(i + y) + j * HeightfieldData::COLOR_BYTES,
columns * HeightfieldData::COLOR_BYTES);
} }
} }
buffers.append(BufferDataPointer(new HeightfieldBuffer(glm::vec3(x, 0.0f, z), 1.0f, height, color, false))); buffers.append(BufferDataPointer(new HeightfieldBuffer(glm::vec3(x, 0.0f, z), 1.0f, height, color)));
} }
} }
} }

View file

@ -489,9 +489,6 @@ HeightfieldData::HeightfieldData(const QByteArray& contents) :
_contents(contents) { _contents(contents) {
} }
const int BYTES_PER_PIXEL = 3;
const int ZERO_OFFSET = 128;
HeightfieldData::HeightfieldData(Bitstream& in, int bytes, bool color) { HeightfieldData::HeightfieldData(Bitstream& in, int bytes, bool color) {
read(in, bytes, color); read(in, bytes, color);
} }
@ -515,10 +512,10 @@ HeightfieldData::HeightfieldData(Bitstream& in, int bytes, const HeightfieldData
int minX = offset.x() - 1; int minX = offset.x() - 1;
int minY = offset.y() - 1; int minY = offset.y() - 1;
if (color) { if (color) {
int size = glm::sqrt(_contents.size() / (float)BYTES_PER_PIXEL); int size = glm::sqrt(_contents.size() / (float)COLOR_BYTES);
char* dest = _contents.data() + (minY * size + minX) * BYTES_PER_PIXEL; char* dest = _contents.data() + (minY * size + minX) * COLOR_BYTES;
int destStride = size * BYTES_PER_PIXEL; int destStride = size * COLOR_BYTES;
int srcStride = image.width() * BYTES_PER_PIXEL; int srcStride = image.width() * COLOR_BYTES;
for (int y = 0; y < image.height(); y++) { for (int y = 0; y < image.height(); y++) {
memcpy(dest, image.constScanLine(y), srcStride); memcpy(dest, image.constScanLine(y), srcStride);
dest += destStride; dest += destStride;
@ -528,7 +525,7 @@ HeightfieldData::HeightfieldData(Bitstream& in, int bytes, const HeightfieldData
char* lineDest = _contents.data() + minY * size + minX; char* lineDest = _contents.data() + minY * size + minX;
for (int y = 0; y < image.height(); y++) { for (int y = 0; y < image.height(); y++) {
const uchar* src = image.constScanLine(y); const uchar* src = image.constScanLine(y);
for (char* dest = lineDest, *end = dest + image.width(); dest != end; dest++, src += BYTES_PER_PIXEL) { for (char* dest = lineDest, *end = dest + image.width(); dest != end; dest++, src += COLOR_BYTES) {
*dest = *src; *dest = *src;
} }
lineDest += size; lineDest += size;
@ -541,7 +538,7 @@ void HeightfieldData::write(Bitstream& out, bool color) {
if (_encoded.isEmpty()) { if (_encoded.isEmpty()) {
QImage image; QImage image;
if (color) { if (color) {
int size = glm::sqrt(_contents.size() / (float)BYTES_PER_PIXEL); int size = glm::sqrt(_contents.size() / (float)COLOR_BYTES);
image = QImage((uchar*)_contents.data(), size, size, QImage::Format_RGB888); image = QImage((uchar*)_contents.data(), size, size, QImage::Format_RGB888);
} else { } else {
int size = glm::sqrt((float)_contents.size()); int size = glm::sqrt((float)_contents.size());
@ -571,7 +568,7 @@ void HeightfieldData::writeDelta(Bitstream& out, const HeightfieldDataPointer& r
QImage image; QImage image;
int minX, minY; int minX, minY;
if (color) { if (color) {
int size = glm::sqrt(_contents.size() / (float)BYTES_PER_PIXEL); int size = glm::sqrt(_contents.size() / (float)COLOR_BYTES);
minX = size; minX = size;
minY = size; minY = size;
int maxX = -1, maxY = -1; int maxX = -1, maxY = -1;
@ -579,7 +576,7 @@ void HeightfieldData::writeDelta(Bitstream& out, const HeightfieldDataPointer& r
const char* ref = reference->_contents.constData(); const char* ref = reference->_contents.constData();
for (int y = 0; y < size; y++) { for (int y = 0; y < size; y++) {
bool difference = false; bool difference = false;
for (int x = 0; x < size; x++, src += BYTES_PER_PIXEL, ref += BYTES_PER_PIXEL) { for (int x = 0; x < size; x++, src += COLOR_BYTES, ref += COLOR_BYTES) {
if (src[0] != ref[0] || src[1] != ref[1] || src[2] != ref[2]) { if (src[0] != ref[0] || src[1] != ref[1] || src[2] != ref[2]) {
minX = qMin(minX, x); minX = qMin(minX, x);
maxX = qMax(maxX, x); maxX = qMax(maxX, x);
@ -594,9 +591,9 @@ void HeightfieldData::writeDelta(Bitstream& out, const HeightfieldDataPointer& r
int width = qMax(maxX - minX + 1, 0); int width = qMax(maxX - minX + 1, 0);
int height = qMax(maxY - minY + 1, 0); int height = qMax(maxY - minY + 1, 0);
image = QImage(width, height, QImage::Format_RGB888); image = QImage(width, height, QImage::Format_RGB888);
src = _contents.constData() + (minY * size + minX) * BYTES_PER_PIXEL; src = _contents.constData() + (minY * size + minX) * COLOR_BYTES;
int srcStride = size * BYTES_PER_PIXEL; int srcStride = size * COLOR_BYTES;
int destStride = width * BYTES_PER_PIXEL; int destStride = width * COLOR_BYTES;
for (int y = 0; y < height; y++) { for (int y = 0; y < height; y++) {
memcpy(image.scanLine(y), src, destStride); memcpy(image.scanLine(y), src, destStride);
src += srcStride; src += srcStride;
@ -652,14 +649,14 @@ void HeightfieldData::read(Bitstream& in, int bytes, bool color) {
void HeightfieldData::set(const QImage& image, bool color) { void HeightfieldData::set(const QImage& image, bool color) {
if (color) { if (color) {
_contents.resize(image.width() * image.height() * BYTES_PER_PIXEL); _contents.resize(image.width() * image.height() * COLOR_BYTES);
memcpy(_contents.data(), image.constBits(), _contents.size()); memcpy(_contents.data(), image.constBits(), _contents.size());
} else { } else {
_contents.resize(image.width() * image.height()); _contents.resize(image.width() * image.height());
char* dest = _contents.data(); char* dest = _contents.data();
for (const uchar* src = image.constBits(), *end = src + _contents.size() * BYTES_PER_PIXEL; for (const uchar* src = image.constBits(), *end = src + _contents.size() * COLOR_BYTES;
src != end; src += BYTES_PER_PIXEL) { src != end; src += COLOR_BYTES) {
*dest++ = *src; *dest++ = *src;
} }
} }
@ -856,8 +853,8 @@ bool HeightfieldColorAttribute::merge(void*& parent, void* children[], bool post
*(HeightfieldDataPointer*)&parent = HeightfieldDataPointer(); *(HeightfieldDataPointer*)&parent = HeightfieldDataPointer();
return true; return true;
} }
int size = glm::sqrt(maxSize / (float)BYTES_PER_PIXEL); int size = glm::sqrt(maxSize / (float)HeightfieldData::COLOR_BYTES);
QByteArray contents(size * size * BYTES_PER_PIXEL, 0); QByteArray contents(size * size * HeightfieldData::COLOR_BYTES, 0);
int halfSize = size / 2; int halfSize = size / 2;
for (int i = 0; i < MERGE_COUNT; i++) { for (int i = 0; i < MERGE_COUNT; i++) {
HeightfieldDataPointer child = decodeInline<HeightfieldDataPointer>(children[i]); HeightfieldDataPointer child = decodeInline<HeightfieldDataPointer>(children[i]);
@ -865,7 +862,7 @@ bool HeightfieldColorAttribute::merge(void*& parent, void* children[], bool post
continue; continue;
} }
const QByteArray& childContents = child->getContents(); const QByteArray& childContents = child->getContents();
int childSize = glm::sqrt(childContents.size() / (float)BYTES_PER_PIXEL); int childSize = glm::sqrt(childContents.size() / (float)HeightfieldData::COLOR_BYTES);
const int INDEX_MASK = 1; const int INDEX_MASK = 1;
int xIndex = i & INDEX_MASK; int xIndex = i & INDEX_MASK;
const int Y_SHIFT = 1; const int Y_SHIFT = 1;
@ -875,24 +872,25 @@ bool HeightfieldColorAttribute::merge(void*& parent, void* children[], bool post
} }
int Z_SHIFT = 2; int Z_SHIFT = 2;
int zIndex = (i >> Z_SHIFT) & INDEX_MASK; int zIndex = (i >> Z_SHIFT) & INDEX_MASK;
char* dest = contents.data() + ((zIndex * halfSize * size) + (xIndex * halfSize)) * BYTES_PER_PIXEL; char* dest = contents.data() + ((zIndex * halfSize * size) + (xIndex * halfSize)) * HeightfieldData::COLOR_BYTES;
uchar* src = (uchar*)childContents.data(); uchar* src = (uchar*)childContents.data();
int childStride = childSize * BYTES_PER_PIXEL; int childStride = childSize * HeightfieldData::COLOR_BYTES;
int stride = size * BYTES_PER_PIXEL; int stride = size * HeightfieldData::COLOR_BYTES;
int halfStride = stride / 2; int halfStride = stride / 2;
int childStep = 2 * BYTES_PER_PIXEL; int childStep = 2 * HeightfieldData::COLOR_BYTES;
int redOffset3 = childStride + BYTES_PER_PIXEL; int redOffset3 = childStride + HeightfieldData::COLOR_BYTES;
int greenOffset1 = BYTES_PER_PIXEL + 1; int greenOffset1 = HeightfieldData::COLOR_BYTES + 1;
int greenOffset2 = childStride + 1; int greenOffset2 = childStride + 1;
int greenOffset3 = childStride + BYTES_PER_PIXEL + 1; int greenOffset3 = childStride + HeightfieldData::COLOR_BYTES + 1;
int blueOffset1 = BYTES_PER_PIXEL + 2; int blueOffset1 = HeightfieldData::COLOR_BYTES + 2;
int blueOffset2 = childStride + 2; int blueOffset2 = childStride + 2;
int blueOffset3 = childStride + BYTES_PER_PIXEL + 2; int blueOffset3 = childStride + HeightfieldData::COLOR_BYTES + 2;
if (childSize == size) { if (childSize == size) {
// simple case: one destination value for four child values // simple case: one destination value for four child values
for (int z = 0; z < halfSize; z++) { for (int z = 0; z < halfSize; z++) {
for (char* end = dest + halfSize * BYTES_PER_PIXEL; dest != end; src += childStep) { for (char* end = dest + halfSize * HeightfieldData::COLOR_BYTES; dest != end; src += childStep) {
*dest++ = ((int)src[0] + (int)src[BYTES_PER_PIXEL] + (int)src[childStride] + (int)src[redOffset3]) >> 2; *dest++ = ((int)src[0] + (int)src[HeightfieldData::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[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; *dest++ = ((int)src[2] + (int)src[blueOffset1] + (int)src[blueOffset2] + (int)src[blueOffset3]) >> 2;
} }
@ -904,13 +902,14 @@ bool HeightfieldColorAttribute::merge(void*& parent, void* children[], bool post
int halfChildSize = childSize / 2; int halfChildSize = childSize / 2;
int destPerSrc = size / childSize; int destPerSrc = size / childSize;
for (int z = 0; z < halfChildSize; z++) { for (int z = 0; z < halfChildSize; z++) {
for (uchar* end = src + childSize * BYTES_PER_PIXEL; src != end; src += childStep) { for (uchar* end = src + childSize * HeightfieldData::COLOR_BYTES; src != end; src += childStep) {
*dest++ = ((int)src[0] + (int)src[BYTES_PER_PIXEL] + (int)src[childStride] + (int)src[redOffset3]) >> 2; *dest++ = ((int)src[0] + (int)src[HeightfieldData::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[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; *dest++ = ((int)src[2] + (int)src[blueOffset1] + (int)src[blueOffset2] + (int)src[blueOffset3]) >> 2;
for (int j = 1; j < destPerSrc; j++) { for (int j = 1; j < destPerSrc; j++) {
memcpy(dest, dest - BYTES_PER_PIXEL, BYTES_PER_PIXEL); memcpy(dest, dest - HeightfieldData::COLOR_BYTES, HeightfieldData::COLOR_BYTES);
dest += BYTES_PER_PIXEL; dest += HeightfieldData::COLOR_BYTES;
} }
} }
dest += halfStride; dest += halfStride;

View file

@ -428,6 +428,8 @@ typedef QExplicitlySharedDataPointer<HeightfieldData> HeightfieldDataPointer;
class HeightfieldData : public QSharedData { class HeightfieldData : public QSharedData {
public: public:
static const int COLOR_BYTES = 3;
HeightfieldData(const QByteArray& contents); HeightfieldData(const QByteArray& contents);
HeightfieldData(Bitstream& in, int bytes, bool color); HeightfieldData(Bitstream& in, int bytes, bool color);
HeightfieldData(Bitstream& in, int bytes, const HeightfieldDataPointer& reference, bool color); HeightfieldData(Bitstream& in, int bytes, const HeightfieldDataPointer& reference, bool color);