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 | 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 | 396 | void MetavoxelSystem::paintHeightfieldColor(const glm::vec3& position, float radius, const QColor& color) { |
| 480 | 397 | MetavoxelEditMessage edit = { QVariant::fromValue(PaintHeightfieldMaterialEdit(position, radius, SharedObjectPointer(), color)) }; |
| 481 | 398 | applyEdit(edit, true); |