Ray query fix.

This commit is contained in:
Andrzej Kapolka 2014-08-13 11:30:05 -07:00
parent 56c6c3c972
commit 8c42a3a848
3 changed files with 26 additions and 31 deletions

View file

@ -136,7 +136,6 @@ RayHeightfieldIntersectionVisitor::RayHeightfieldIntersectionVisitor(const glm::
} }
static const float EIGHT_BIT_MAXIMUM_RECIPROCAL = 1.0f / 255.0f; static const float EIGHT_BIT_MAXIMUM_RECIPROCAL = 1.0f / 255.0f;
static const int HEIGHT_BORDER = 1;
int RayHeightfieldIntersectionVisitor::visit(MetavoxelInfo& info, float distance) { int RayHeightfieldIntersectionVisitor::visit(MetavoxelInfo& info, float distance) {
if (!info.isLeaf) { if (!info.isLeaf) {
@ -151,12 +150,13 @@ int RayHeightfieldIntersectionVisitor::visit(MetavoxelInfo& info, float distance
const uchar* src = (const uchar*)contents.constData(); const uchar* src = (const uchar*)contents.constData();
int size = glm::sqrt((float)contents.size()); int size = glm::sqrt((float)contents.size());
int unextendedSize = size - HeightfieldBuffer::HEIGHT_EXTENSION; int unextendedSize = size - HeightfieldBuffer::HEIGHT_EXTENSION;
int highest = HEIGHT_BORDER + unextendedSize; int highest = HeightfieldBuffer::HEIGHT_BORDER + unextendedSize;
float heightScale = unextendedSize * EIGHT_BIT_MAXIMUM_RECIPROCAL; float heightScale = unextendedSize * EIGHT_BIT_MAXIMUM_RECIPROCAL;
// find the initial location in heightfield coordinates // find the initial location in heightfield coordinates
glm::vec3 entry = (_origin + distance * _direction - info.minimum + glm::vec3(HEIGHT_BORDER, 0.0f, HEIGHT_BORDER)) * glm::vec3 entry = (_origin + distance * _direction - info.minimum) * (float)unextendedSize / info.size;
(float)unextendedSize / info.size; entry.x += HeightfieldBuffer::HEIGHT_BORDER;
entry.z += HeightfieldBuffer::HEIGHT_BORDER;
glm::vec3 floors = glm::floor(entry); glm::vec3 floors = glm::floor(entry);
glm::vec3 ceils = glm::ceil(entry); glm::vec3 ceils = glm::ceil(entry);
if (floors.x == ceils.x) { if (floors.x == ceils.x) {
@ -178,10 +178,10 @@ int RayHeightfieldIntersectionVisitor::visit(MetavoxelInfo& info, float distance
float accumulatedDistance = 0.0f; float accumulatedDistance = 0.0f;
while (withinBounds) { while (withinBounds) {
// find the heights at the corners of the current cell // find the heights at the corners of the current cell
int floorX = qMin(qMax((int)floors.x, HEIGHT_BORDER), highest); int floorX = qMin(qMax((int)floors.x, HeightfieldBuffer::HEIGHT_BORDER), highest);
int floorZ = qMin(qMax((int)floors.z, HEIGHT_BORDER), highest); int floorZ = qMin(qMax((int)floors.z, HeightfieldBuffer::HEIGHT_BORDER), highest);
int ceilX = qMin(qMax((int)ceils.x, HEIGHT_BORDER), highest); int ceilX = qMin(qMax((int)ceils.x, HeightfieldBuffer::HEIGHT_BORDER), highest);
int ceilZ = qMin(qMax((int)ceils.z, HEIGHT_BORDER), highest); int ceilZ = qMin(qMax((int)ceils.z, HeightfieldBuffer::HEIGHT_BORDER), highest);
float upperLeft = src[floorZ * size + floorX] * heightScale; float upperLeft = src[floorZ * size + floorX] * heightScale;
float upperRight = src[floorZ * size + ceilX] * heightScale; float upperRight = src[floorZ * size + ceilX] * heightScale;
float lowerLeft = src[ceilZ * size + floorX] * heightScale; float lowerLeft = src[ceilZ * size + floorX] * heightScale;
@ -215,13 +215,13 @@ int RayHeightfieldIntersectionVisitor::visit(MetavoxelInfo& info, float distance
} else { } else {
// find the exit point and the next cell, and determine whether it's still within the bounds // find the exit point and the next cell, and determine whether it's still within the bounds
exit = entry + exitDistance * _direction; exit = entry + exitDistance * _direction;
withinBounds = (exit.y >= HEIGHT_BORDER && exit.y <= highest); withinBounds = (exit.y >= HeightfieldBuffer::HEIGHT_BORDER && exit.y <= highest);
if (exitDistance == xDistance) { if (exitDistance == xDistance) {
if (_direction.x > 0.0f) { if (_direction.x > 0.0f) {
nextFloors.x += 1.0f; nextFloors.x += 1.0f;
withinBounds &= (nextCeils.x += 1.0f) <= highest; withinBounds &= (nextCeils.x += 1.0f) <= highest;
} else { } else {
withinBounds &= (nextFloors.x -= 1.0f) >= HEIGHT_BORDER; withinBounds &= (nextFloors.x -= 1.0f) >= HeightfieldBuffer::HEIGHT_BORDER;
nextCeils.x -= 1.0f; nextCeils.x -= 1.0f;
} }
} }
@ -230,7 +230,7 @@ int RayHeightfieldIntersectionVisitor::visit(MetavoxelInfo& info, float distance
nextFloors.z += 1.0f; nextFloors.z += 1.0f;
withinBounds &= (nextCeils.z += 1.0f) <= highest; withinBounds &= (nextCeils.z += 1.0f) <= highest;
} else { } else {
withinBounds &= (nextFloors.z -= 1.0f) >= HEIGHT_BORDER; withinBounds &= (nextFloors.z -= 1.0f) >= HeightfieldBuffer::HEIGHT_BORDER;
nextCeils.z -= 1.0f; nextCeils.z -= 1.0f;
} }
} }
@ -337,19 +337,19 @@ int HeightfieldHeightVisitor::visit(MetavoxelInfo& info) {
const uchar* src = (const uchar*)contents.constData(); const uchar* src = (const uchar*)contents.constData();
int size = glm::sqrt((float)contents.size()); int size = glm::sqrt((float)contents.size());
int unextendedSize = size - HeightfieldBuffer::HEIGHT_EXTENSION; int unextendedSize = size - HeightfieldBuffer::HEIGHT_EXTENSION;
int highest = HEIGHT_BORDER + unextendedSize; int highest = HeightfieldBuffer::HEIGHT_BORDER + unextendedSize;
relative *= unextendedSize / info.size; relative *= unextendedSize / info.size;
relative.x += HEIGHT_BORDER; relative.x += HeightfieldBuffer::HEIGHT_BORDER;
relative.z += HEIGHT_BORDER; relative.z += HeightfieldBuffer::HEIGHT_BORDER;
// find the bounds of the cell containing the point and the shared vertex heights // find the bounds of the cell containing the point and the shared vertex heights
glm::vec3 floors = glm::floor(relative); glm::vec3 floors = glm::floor(relative);
glm::vec3 ceils = glm::ceil(relative); glm::vec3 ceils = glm::ceil(relative);
glm::vec3 fracts = glm::fract(relative); glm::vec3 fracts = glm::fract(relative);
int floorX = qMin(qMax((int)floors.x, HEIGHT_BORDER), highest); int floorX = qMin(qMax((int)floors.x, HeightfieldBuffer::HEIGHT_BORDER), highest);
int floorZ = qMin(qMax((int)floors.z, HEIGHT_BORDER), highest); int floorZ = qMin(qMax((int)floors.z, HeightfieldBuffer::HEIGHT_BORDER), highest);
int ceilX = qMin(qMax((int)ceils.x, HEIGHT_BORDER), highest); int ceilX = qMin(qMax((int)ceils.x, HeightfieldBuffer::HEIGHT_BORDER), highest);
int ceilZ = qMin(qMax((int)ceils.z, HEIGHT_BORDER), highest); int ceilZ = qMin(qMax((int)ceils.z, HeightfieldBuffer::HEIGHT_BORDER), highest);
float upperLeft = src[floorZ * size + floorX]; float upperLeft = src[floorZ * size + floorX];
float lowerRight = src[ceilZ * size + ceilX]; float lowerRight = src[ceilZ * size + ceilX];
float interpolatedHeight = glm::mix(upperLeft, lowerRight, fracts.z); float interpolatedHeight = glm::mix(upperLeft, lowerRight, fracts.z);
@ -593,6 +593,10 @@ void PointBuffer::render(bool cursor) {
_buffer.release(); _buffer.release();
} }
const int HeightfieldBuffer::HEIGHT_BORDER = 1;
const int HeightfieldBuffer::SHARED_EDGE = 1;
const int HeightfieldBuffer::HEIGHT_EXTENSION = 2 * HeightfieldBuffer::HEIGHT_BORDER + HeightfieldBuffer::SHARED_EDGE;
HeightfieldBuffer::HeightfieldBuffer(const glm::vec3& translation, float scale, HeightfieldBuffer::HeightfieldBuffer(const glm::vec3& translation, float scale,
const QByteArray& height, const QByteArray& color) : const QByteArray& height, const QByteArray& color) :
_translation(translation), _translation(translation),

View file

@ -135,9 +135,9 @@ private:
class HeightfieldBuffer : public BufferData { class HeightfieldBuffer : public BufferData {
public: public:
static const int HEIGHT_BORDER = 1; static const int HEIGHT_BORDER;
static const int SHARED_EDGE = 1; static const int SHARED_EDGE;
static const int HEIGHT_EXTENSION = 2 * HEIGHT_BORDER + SHARED_EDGE; static const int HEIGHT_EXTENSION;
HeightfieldBuffer(const glm::vec3& translation, float scale, const QByteArray& height, const QByteArray& color); HeightfieldBuffer(const glm::vec3& translation, float scale, const QByteArray& height, const QByteArray& color);
~HeightfieldBuffer(); ~HeightfieldBuffer();

View file

@ -1101,7 +1101,7 @@ HeightfieldBrushTool::HeightfieldBrushTool(MetavoxelEditor* editor, const QStrin
} }
void HeightfieldBrushTool::render() { void HeightfieldBrushTool::render() {
if (Application::getInstance()->isMouseHidden() && false) { if (Application::getInstance()->isMouseHidden()) {
return; return;
} }
@ -1115,15 +1115,6 @@ void HeightfieldBrushTool::render() {
} }
Application::getInstance()->getMetavoxels()->renderHeightfieldCursor( Application::getInstance()->getMetavoxels()->renderHeightfieldCursor(
_position = origin + distance * direction, _radius->value()); _position = origin + distance * direction, _radius->value());
glPushMatrix();
glTranslatef(_position.x, _position.y, _position.z);
glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
glutSolidSphere(1.0f, 10, 10);
glPopMatrix();
} }
bool HeightfieldBrushTool::eventFilter(QObject* watched, QEvent* event) { bool HeightfieldBrushTool::eventFilter(QObject* watched, QEvent* event) {