Showing the changes to interface/src/MetavoxelSystem.cpp (1 of 4 files). Show all
Unified · Split
| @@ -328,6 +328,50 @@ bool MetavoxelSystem::findFirstRayHeightfieldIntersection(const glm::vec3& origi · 327 unmodified lines | |||
| 328 | return true; | 328 | return true; |
| 329 | } | 329 | } |
| 330 | 330 | ||
| 331 | class RayVoxelIntersectionVisitor : public RayIntersectionVisitor { | ||
| 332 | public: | ||
| 333 | |||
| 334 | float intersectionDistance; | ||
| 335 | |||
| 336 | RayVoxelIntersectionVisitor(const glm::vec3& origin, const glm::vec3& direction, const MetavoxelLOD& lod); | ||
| 337 | |||
| 338 | virtual int visit(MetavoxelInfo& info, float distance); | ||
| 339 | }; | ||
| 340 | |||
| 341 | RayVoxelIntersectionVisitor::RayVoxelIntersectionVisitor(const glm::vec3& origin, | ||
| 342 | const glm::vec3& direction, const MetavoxelLOD& lod) : | ||
| 343 | RayIntersectionVisitor(origin, direction, QVector<AttributePointer>() << | ||
| 344 | Application::getInstance()->getMetavoxels()->getVoxelBufferAttribute(), QVector<AttributePointer>(), lod), | ||
| 345 | intersectionDistance(FLT_MAX) { | ||
| 346 | } | ||
| 347 | |||
| 348 | int RayVoxelIntersectionVisitor::visit(MetavoxelInfo& info, float distance) { | ||
| 349 | if (!info.isLeaf) { | ||
| 350 | return _order; | ||
| 351 | } | ||
| 352 | const VoxelBuffer* buffer = static_cast<VoxelBuffer*>( | ||
| 353 | info.inputValues.at(0).getInlineValue<BufferDataPointer>().data()); | ||
| 354 | if (!buffer) { | ||
| 355 | return STOP_RECURSION; | ||
| 356 | } | ||
| 357 | glm::vec3 origin = ((_origin + distance * _direction) - info.minimum) / info.size; | ||
| 358 | if (buffer->findFirstRayIntersection(origin, _direction, intersectionDistance)) { | ||
| 359 | intersectionDistance = intersectionDistance * info.size + distance; | ||
| 360 | return SHORT_CIRCUIT; | ||
| 361 | } | ||
| 362 | return STOP_RECURSION; | ||
| 363 | } | ||
| 364 | |||
| 365 | bool MetavoxelSystem::findFirstRayVoxelIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance) { | ||
| 366 | RayVoxelIntersectionVisitor visitor(origin, direction, getLOD()); | ||
| 367 | guideToAugmented(visitor); | ||
| 368 | if (visitor.intersectionDistance == FLT_MAX) { | ||
| 369 | return false; | ||
| 370 | } | ||
| 371 | distance = visitor.intersectionDistance; | ||
| 372 | return true; | ||
| 373 | } | ||
| 374 | |||
| 331 | class HeightfieldHeightVisitor : public MetavoxelVisitor { | 375 | class HeightfieldHeightVisitor : public MetavoxelVisitor { |
| 332 | public: | 376 | public: |
| 333 | 377 | ||
| @@ -991,10 +1035,12 @@ void VoxelPoint::setNormal(const glm::vec3& normal) { · 657 unmodified lines | |||
| 991 | } | 1035 | } |
| 992 | 1036 | ||
| 993 | VoxelBuffer::VoxelBuffer(const QVector<VoxelPoint>& vertices, const QVector<int>& indices, const QVector<glm::vec3>& hermite, | 1037 | VoxelBuffer::VoxelBuffer(const QVector<VoxelPoint>& vertices, const QVector<int>& indices, const QVector<glm::vec3>& hermite, |
| 994 | const QVector<SharedObjectPointer>& materials) : | 1038 | const QHash<QRgb, glm::vec3>& points, int size, const QVector<SharedObjectPointer>& materials) : |
| 995 | _vertices(vertices), | 1039 | _vertices(vertices), |
| 996 | _indices(indices), | 1040 | _indices(indices), |
| 997 | _hermite(hermite), | 1041 | _hermite(hermite), |
| 1042 | _points(points), | ||
| 1043 | _size(size), | ||
| 998 | _vertexCount(vertices.size()), | 1044 | _vertexCount(vertices.size()), |
| 999 | _indexCount(indices.size()), | 1045 | _indexCount(indices.size()), |
| 1000 | _hermiteCount(hermite.size()), | 1046 | _hermiteCount(hermite.size()), |
| @@ -1002,6 +1048,68 @@ VoxelBuffer::VoxelBuffer(const QVector<VoxelPoint>& vertices, const QVector<int> · 1 unmodified line | |||
| 1002 | _materials(materials) { | 1048 | _materials(materials) { |
| 1003 | } | 1049 | } |
| 1004 | 1050 | ||
| 1051 | bool VoxelBuffer::findFirstRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance) const { | ||
| 1052 | float highest = _size - 1.0f; | ||
| 1053 | glm::vec3 position = origin * highest; | ||
| 1054 | glm::vec3 floors = glm::floor(position); | ||
| 1055 | int max = _size - 2; | ||
| 1056 | int x = qMin((int)floors.x, max), y = qMin((int)floors.y, max), z = qMin((int)floors.z, max); | ||
| 1057 | float combinedDistance = 0.0f; | ||
| 1058 | forever { | ||
| 1059 | if (_points.contains(qRgb(x + 1, y + 1, z + 1))) { | ||
| 1060 | distance = combinedDistance / highest; | ||
| 1061 | return true; | ||
| 1062 | } | ||
| 1063 | float xDistance = FLT_MAX, yDistance = FLT_MAX, zDistance = FLT_MAX; | ||
| 1064 | if (direction.x > 0.0f) { | ||
| 1065 | xDistance = (x + 1.0f - position.x) / direction.x; | ||
| 1066 | } else if (direction.x < 0.0f) { | ||
| 1067 | xDistance = (x - position.x) / direction.x; | ||
| 1068 | } | ||
| 1069 | if (direction.y > 0.0f) { | ||
| 1070 | yDistance = (y + 1.0f - position.y) / direction.y; | ||
| 1071 | } else if (direction.y < 0.0f) { | ||
| 1072 | yDistance = (y - position.y) / direction.y; | ||
| 1073 | } | ||
| 1074 | if (direction.z > 0.0f) { | ||
| 1075 | zDistance = (z + 1.0f - position.z) / direction.z; | ||
| 1076 | } else if (direction.z < 0.0f) { | ||
| 1077 | zDistance = (z - position.z) / direction.z; | ||
| 1078 | } | ||
| 1079 | float minimumDistance = qMin(xDistance, qMin(yDistance, zDistance)); | ||
| 1080 | if (minimumDistance == xDistance) { | ||
| 1081 | if (direction.x > 0.0f) { | ||
| 1082 | if (x++ == max) { | ||
| 1083 | return false; | ||
| 1084 | } | ||
| 1085 | } else if (x-- == 0) { | ||
| 1086 | return false; | ||
| 1087 | } | ||
| 1088 | } | ||
| 1089 | if (minimumDistance == yDistance) { | ||
| 1090 | if (direction.y > 0.0f) { | ||
| 1091 | if (y++ == max) { | ||
| 1092 | return false; | ||
| 1093 | } | ||
| 1094 | } else if (y-- == 0) { | ||
| 1095 | return false; | ||
| 1096 | } | ||
| 1097 | } | ||
| 1098 | if (minimumDistance == zDistance) { | ||
| 1099 | if (direction.z > 0.0f) { | ||
| 1100 | if (z++ == max) { | ||
| 1101 | return false; | ||
| 1102 | } | ||
| 1103 | } else if (z-- == 0) { | ||
| 1104 | return false; | ||
| 1105 | } | ||
| 1106 | } | ||
| 1107 | position += direction * minimumDistance; | ||
| 1108 | combinedDistance += minimumDistance; | ||
| 1109 | } | ||
| 1110 | return false; | ||
| 1111 | } | ||
| 1112 | |||
| 1005 | void VoxelBuffer::render(bool cursor) { | 1113 | void VoxelBuffer::render(bool cursor) { |
| 1006 | if (!_vertexBuffer.isCreated()) { | 1114 | if (!_vertexBuffer.isCreated()) { |
| 1007 | _vertexBuffer.create(); | 1115 | _vertexBuffer.create(); |
| @@ -1627,6 +1735,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 619 unmodified lines | |||
| 1627 | QVector<VoxelPoint> vertices; | 1735 | QVector<VoxelPoint> vertices; |
| 1628 | QVector<int> indices; | 1736 | QVector<int> indices; |
| 1629 | QVector<glm::vec3> hermiteSegments; | 1737 | QVector<glm::vec3> hermiteSegments; |
| 1738 | QHash<QRgb, glm::vec3> points; | ||
| 1630 | 1739 | ||
| 1631 | // see http://www.frankpetterson.com/publications/dualcontour/dualcontour.pdf for a description of the | 1740 | // see http://www.frankpetterson.com/publications/dualcontour/dualcontour.pdf for a description of the |
| 1632 | // dual contour algorithm for generating meshes from voxel data using Hermite-tagged edges | 1741 | // dual contour algorithm for generating meshes from voxel data using Hermite-tagged edges |
| @@ -2033,6 +2142,8 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 400 unmodified lines | |||
| 2033 | { (quint8)materialWeights[0], (quint8)materialWeights[1], (quint8)materialWeights[2], | 2142 | { (quint8)materialWeights[0], (quint8)materialWeights[1], (quint8)materialWeights[2], |
| 2034 | (quint8)materialWeights[3] } }; | 2143 | (quint8)materialWeights[3] } }; |
| 2035 | 2144 | ||
| 2145 | points.insert(qRgb(x + 1, y + 1, z + 1), (glm::vec3(clampedX, clampedY, clampedZ) + center) / highest); | ||
| 2146 | |||
| 2036 | // determine whether we must "crease" by generating directional normals | 2147 | // determine whether we must "crease" by generating directional normals |
| 2037 | const float CREASE_COS_NORMAL = glm::cos(glm::radians(40.0f)); | 2148 | const float CREASE_COS_NORMAL = glm::cos(glm::radians(40.0f)); |
| 2038 | AxisIndex index(vertices.size(), vertices.size(), vertices.size()); | 2149 | AxisIndex index(vertices.size(), vertices.size(), vertices.size()); |
| @@ -2158,7 +2269,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 119 unmodified lines | |||
| 2158 | colorZ += area; | 2269 | colorZ += area; |
| 2159 | } | 2270 | } |
| 2160 | } | 2271 | } |
| 2161 | buffer = new VoxelBuffer(vertices, indices, hermiteSegments, | 2272 | buffer = new VoxelBuffer(vertices, indices, hermiteSegments, points, size, |
| 2162 | material ? material->getMaterials() : QVector<SharedObjectPointer>()); | 2273 | material ? material->getMaterials() : QVector<SharedObjectPointer>()); |
| 2163 | } | 2274 | } |
| 2164 | BufferDataPointer pointer(buffer); | 2275 | BufferDataPointer pointer(buffer); |