History

Migrate getHeightfieldHeight to spanner heightfields.

Andrzej Kapolka committed 12 years ago

Commit 75e1cf81 parent dd87a456 files · +137 −88Browse files

Showing the changes to interface/src/MetavoxelSystem.cpp (1 of 6 files). Show all

Unified · Split

interface/src/MetavoxelSystem.cpp+0−83
@@ -393,89 +393,6 @@ bool MetavoxelSystem::findFirstRayVoxelIntersection(const glm::vec3& origin, con · 392 unmodified lines
393 return true;393 return true;
394}394}
395 395
396class HeightfieldHeightVisitor : public MetavoxelVisitor {
397public:
398
399 float height;
400
401 HeightfieldHeightVisitor(const MetavoxelLOD& lod, const glm::vec3& location);
402
403 virtual int visit(MetavoxelInfo& info);
404
405private:
406
407 glm::vec3 _location;
408};
409
410HeightfieldHeightVisitor::HeightfieldHeightVisitor(const MetavoxelLOD& lod, const glm::vec3& location) :
411 MetavoxelVisitor(QVector<AttributePointer>() <<
412 Application::getInstance()->getMetavoxels()->getHeightfieldBufferAttribute(), QVector<AttributePointer>(), lod),
413 height(-FLT_MAX),
414 _location(location) {
415}
416
417static const int REVERSE_ORDER = MetavoxelVisitor::encodeOrder(7, 6, 5, 4, 3, 2, 1, 0);
418
419int HeightfieldHeightVisitor::visit(MetavoxelInfo& info) {
420 glm::vec3 relative = _location - info.minimum;
421 if (relative.x < 0.0f || relative.z < 0.0f || relative.x > info.size || relative.z > info.size ||
422 height >= info.minimum.y + info.size) {
423 return STOP_RECURSION;
424 }
425 if (!info.isLeaf) {
426 return REVERSE_ORDER;
427 }
428 const HeightfieldBuffer* buffer = static_cast<HeightfieldBuffer*>(
429 info.inputValues.at(0).getInlineValue<BufferDataPointer>().data());
430 if (!buffer) {
431 return STOP_RECURSION;
432 }
433 const QByteArray& contents = buffer->getHeight();
434 const uchar* src = (const uchar*)contents.constData();
435 int size = glm::sqrt((float)contents.size());
436 int unextendedSize = size - HeightfieldBuffer::HEIGHT_EXTENSION;
437 int highest = HeightfieldBuffer::HEIGHT_BORDER + unextendedSize;
438 relative *= unextendedSize / info.size;
439 relative.x += HeightfieldBuffer::HEIGHT_BORDER;
440 relative.z += HeightfieldBuffer::HEIGHT_BORDER;
441
442 // find the bounds of the cell containing the point and the shared vertex heights
443 glm::vec3 floors = glm::floor(relative);
444 glm::vec3 ceils = glm::ceil(relative);
445 glm::vec3 fracts = glm::fract(relative);
446 int floorX = qMin(qMax((int)floors.x, HeightfieldBuffer::HEIGHT_BORDER), highest);
447 int floorZ = qMin(qMax((int)floors.z, HeightfieldBuffer::HEIGHT_BORDER), highest);
448 int ceilX = qMin(qMax((int)ceils.x, HeightfieldBuffer::HEIGHT_BORDER), highest);
449 int ceilZ = qMin(qMax((int)ceils.z, HeightfieldBuffer::HEIGHT_BORDER), highest);
450 float upperLeft = src[floorZ * size + floorX];
451 float lowerRight = src[ceilZ * size + ceilX];
452 float interpolatedHeight = glm::mix(upperLeft, lowerRight, fracts.z);
453
454 // the final vertex (and thus which triangle we check) depends on which half we're on
455 if (fracts.x >= fracts.z) {
456 float upperRight = src[floorZ * size + ceilX];
457 interpolatedHeight = glm::mix(interpolatedHeight, glm::mix(upperRight, lowerRight, fracts.z),
458 (fracts.x - fracts.z) / (1.0f - fracts.z));
459
460 } else {
461 float lowerLeft = src[ceilZ * size + floorX];
462 interpolatedHeight = glm::mix(glm::mix(upperLeft, lowerLeft, fracts.z), interpolatedHeight, fracts.x / fracts.z);
463 }
464 if (interpolatedHeight == 0.0f) {
465 return STOP_RECURSION; // ignore zero values
466 }
467
468 // convert the interpolated height into world space
469 height = qMax(height, info.minimum.y + interpolatedHeight * info.size * EIGHT_BIT_MAXIMUM_RECIPROCAL);
470 return SHORT_CIRCUIT;
471}
472
473float MetavoxelSystem::getHeightfieldHeight(const glm::vec3& location) {
474 HeightfieldHeightVisitor visitor(getLOD(), location);
475 guideToAugmented(visitor);
476 return visitor.height;
477}
478
479void MetavoxelSystem::paintHeightfieldColor(const glm::vec3& position, float radius, const QColor& color) {396void MetavoxelSystem::paintHeightfieldColor(const glm::vec3& position, float radius, const QColor& color) {
480 MetavoxelEditMessage edit = { QVariant::fromValue(PaintHeightfieldMaterialEdit(position, radius, SharedObjectPointer(), color)) };397 MetavoxelEditMessage edit = { QVariant::fromValue(PaintHeightfieldMaterialEdit(position, radius, SharedObjectPointer(), color)) };
481 applyEdit(edit, true);398 applyEdit(edit, true);