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
328 return true;328 return true;
329}329}
330 330
331class RayVoxelIntersectionVisitor : public RayIntersectionVisitor {
332public:
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
341RayVoxelIntersectionVisitor::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
348int 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
365bool 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
331class HeightfieldHeightVisitor : public MetavoxelVisitor {375class HeightfieldHeightVisitor : public MetavoxelVisitor {
332public:376public:
333 377
@@ -991,10 +1035,12 @@ void VoxelPoint::setNormal(const glm::vec3& normal) { · 657 unmodified lines
991}1035}
992 1036
993VoxelBuffer::VoxelBuffer(const QVector<VoxelPoint>& vertices, const QVector<int>& indices, const QVector<glm::vec3>& hermite,1037VoxelBuffer::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
1051bool 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
1005void VoxelBuffer::render(bool cursor) {1113void 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 the1740 // 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 edges1741 // 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 normals2147 // 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);