Showing the changes to interface/src/MetavoxelSystem.cpp (1 of 6 files). Show all
Unified · Split
| @@ -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 | ||
| 396 | class HeightfieldHeightVisitor : public MetavoxelVisitor { | ||
| 397 | public: | ||
| 398 | |||
| 399 | float height; | ||
| 400 | |||
| 401 | HeightfieldHeightVisitor(const MetavoxelLOD& lod, const glm::vec3& location); | ||
| 402 | |||
| 403 | virtual int visit(MetavoxelInfo& info); | ||
| 404 | |||
| 405 | private: | ||
| 406 | |||
| 407 | glm::vec3 _location; | ||
| 408 | }; | ||
| 409 | |||
| 410 | HeightfieldHeightVisitor::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 | |||
| 417 | static const int REVERSE_ORDER = MetavoxelVisitor::encodeOrder(7, 6, 5, 4, 3, 2, 1, 0); | ||
| 418 | |||
| 419 | int 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 | |||
| 473 | float MetavoxelSystem::getHeightfieldHeight(const glm::vec3& location) { | ||
| 474 | HeightfieldHeightVisitor visitor(getLOD(), location); | ||
| 475 | guideToAugmented(visitor); | ||
| 476 | return visitor.height; | ||
| 477 | } | ||
| 478 | |||
| 479 | void MetavoxelSystem::paintHeightfieldColor(const glm::vec3& position, float radius, const QColor& color) { | 396 | void 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); |