History

Working on ray/voxel intersection testing.

Andrzej Kapolka committed 12 years ago

Commit 7b0d0021 parent 2a502ae4 files · +193 −3Browse files

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

Unified · Split

interface/src/MetavoxelSystem.cpp+113−2
@@ -328,6 +328,50 @@ bool MetavoxelSystem::findFirstRayHeightfieldIntersection(const glm::vec3& origi · 327 unmodified lines
328328 return true;
329329 }
330330
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+
331375 class HeightfieldHeightVisitor : public MetavoxelVisitor {
332376 public:
333377
@@ -991,10 +1035,12 @@ void VoxelPoint::setNormal(const glm::vec3& normal) { · 657 unmodified lines
9911035 }
9921036
9931037 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) :
9951039 _vertices(vertices),
9961040 _indices(indices),
9971041 _hermite(hermite),
1042+ _points(points),
1043+ _size(size),
9981044 _vertexCount(vertices.size()),
9991045 _indexCount(indices.size()),
10001046 _hermiteCount(hermite.size()),
@@ -1002,6 +1048,68 @@ VoxelBuffer::VoxelBuffer(const QVector<VoxelPoint>& vertices, const QVector<int> · 1 unmodified line
10021048 _materials(materials) {
10031049 }
10041050
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+
10051113 void VoxelBuffer::render(bool cursor) {
10061114 if (!_vertexBuffer.isCreated()) {
10071115 _vertexBuffer.create();
@@ -1627,6 +1735,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 619 unmodified lines
16271735 QVector<VoxelPoint> vertices;
16281736 QVector<int> indices;
16291737 QVector<glm::vec3> hermiteSegments;
1738+ QHash<QRgb, glm::vec3> points;
16301739
16311740 // see http://www.frankpetterson.com/publications/dualcontour/dualcontour.pdf for a description of the
16321741 // 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
20332142 { (quint8)materialWeights[0], (quint8)materialWeights[1], (quint8)materialWeights[2],
20342143 (quint8)materialWeights[3] } };
20352144
2145+ points.insert(qRgb(x + 1, y + 1, z + 1), (glm::vec3(clampedX, clampedY, clampedZ) + center) / highest);
2146+
20362147 // determine whether we must "crease" by generating directional normals
20372148 const float CREASE_COS_NORMAL = glm::cos(glm::radians(40.0f));
20382149 AxisIndex index(vertices.size(), vertices.size(), vertices.size());
@@ -2158,7 +2269,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 119 unmodified lines
21582269 colorZ += area;
21592270 }
21602271 }
2161− buffer = new VoxelBuffer(vertices, indices, hermiteSegments,
2272+ buffer = new VoxelBuffer(vertices, indices, hermiteSegments, points, size,
21622273 material ? material->getMaterials() : QVector<SharedObjectPointer>());
21632274 }
21642275 BufferDataPointer pointer(buffer);