History

Basic ray/voxel intersection testing up and running.

Andrzej Kapolka committed 12 years ago

Commit 1911cfd1 parent c8c09a12 files · +62 −23Browse files

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

Unified · Split

interface/src/MetavoxelSystem.cpp+56−20
@@ -354,9 +354,8 @@ int RayVoxelIntersectionVisitor::visit(MetavoxelInfo& info, float distance) { · 353 unmodified lines
354354 if (!buffer) {
355355 return STOP_RECURSION;
356356 }
357− glm::vec3 origin = ((_origin + distance * _direction) - info.minimum) / info.size;
358− if (buffer->findFirstRayIntersection(origin, _direction, intersectionDistance)) {
359− intersectionDistance = intersectionDistance * info.size + distance;
357+ glm::vec3 entry = ((_origin + distance * _direction) - info.minimum) / info.size;
358+ if (buffer->findFirstRayIntersection(entry, _origin, _direction, intersectionDistance)) {
360359 return SHORT_CIRCUIT;
361360 }
362361 return STOP_RECURSION;
@@ -1035,11 +1034,11 @@ void VoxelPoint::setNormal(const glm::vec3& normal) { · 672 unmodified lines
10351034 }
10361035
10371036 VoxelBuffer::VoxelBuffer(const QVector<VoxelPoint>& vertices, const QVector<int>& indices, const QVector<glm::vec3>& hermite,
1038− const QHash<QRgb, glm::vec3>& points, int size, const QVector<SharedObjectPointer>& materials) :
1037+ const QMultiHash<QRgb, int>& quadIndices, int size, const QVector<SharedObjectPointer>& materials) :
10391038 _vertices(vertices),
10401039 _indices(indices),
10411040 _hermite(hermite),
1042− _points(points),
1041+ _quadIndices(quadIndices),
10431042 _size(size),
10441043 _vertexCount(vertices.size()),
10451044 _indexCount(indices.size()),
@@ -1048,17 +1047,47 @@ VoxelBuffer::VoxelBuffer(const QVector<VoxelPoint>& vertices, const QVector<int> · 2 unmodified lines
10481047 _materials(materials) {
10491048 }
10501049
1051−bool VoxelBuffer::findFirstRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance) const {
1050+static bool findRayTriangleIntersection(const glm::vec3& origin, const glm::vec3& direction,
1051+ const glm::vec3& v0, const glm::vec3& v1, const glm::vec3& v2, float& distance) {
1052+ glm::vec3 firstSide = v0 - v1;
1053+ glm::vec3 secondSide = v2 - v1;
1054+ glm::vec3 normal = glm::cross(secondSide, firstSide);
1055+ float dividend = glm::dot(normal, v1) - glm::dot(origin, normal);
1056+ if (dividend > 0.0f) {
1057+ return false; // origin below plane
1058+ }
1059+ float divisor = glm::dot(normal, direction);
1060+ if (divisor > -EPSILON) {
1061+ return false;
1062+ }
1063+ float t = dividend / divisor;
1064+ glm::vec3 point = origin + direction * t;
1065+ if (glm::dot(normal, glm::cross(point - v1, firstSide)) > 0.0f &&
1066+ glm::dot(normal, glm::cross(secondSide, point - v1)) > 0.0f &&
1067+ glm::dot(normal, glm::cross(point - v0, v2 - v0)) > 0.0f) {
1068+ distance = t;
1069+ return true;
1070+ }
1071+ return false;
1072+}
1073+
1074+bool VoxelBuffer::findFirstRayIntersection(const glm::vec3& entry, const glm::vec3& origin,
1075+ const glm::vec3& direction, float& distance) const {
10521076 float highest = _size - 1.0f;
1053− glm::vec3 position = origin * highest;
1077+ glm::vec3 position = entry * highest;
10541078 glm::vec3 floors = glm::floor(position);
10551079 int max = _size - 2;
10561080 int x = qMin((int)floors.x, max), y = qMin((int)floors.y, max), z = qMin((int)floors.z, max);
1057− float combinedDistance = 0.0f;
10581081 forever {
1059− if (_points.contains(qRgb(x + 1, y + 1, z + 1))) {
1060− distance = combinedDistance / highest;
1061− return true;
1082+ for (QMultiHash<QRgb, int>::const_iterator it = _quadIndices.constFind(qRgb(x + 1, y + 1, z + 1));
1083+ it != _quadIndices.constEnd(); it++) {
1084+ const int* indices = _indices.constData() + *it;
1085+ if (findRayTriangleIntersection(origin, direction, _vertices.at(indices[0]).vertex,
1086+ _vertices.at(indices[1]).vertex, _vertices.at(indices[2]).vertex, distance) ||
1087+ findRayTriangleIntersection(origin, direction, _vertices.at(indices[0]).vertex,
1088+ _vertices.at(indices[2]).vertex, _vertices.at(indices[3]).vertex, distance)) {
1089+ return true;
1090+ }
10621091 }
10631092 float xDistance = FLT_MAX, yDistance = FLT_MAX, zDistance = FLT_MAX;
10641093 if (direction.x > 0.0f) {
@@ -1105,7 +1134,6 @@ bool VoxelBuffer::findFirstRayIntersection(const glm::vec3& origin, const glm::v · 40 unmodified lines
11051134 }
11061135 }
11071136 position += direction * minimumDistance;
1108− combinedDistance += minimumDistance;
11091137 }
11101138 return false;
11111139 }
@@ -1115,13 +1143,11 @@ void VoxelBuffer::render(bool cursor) { · 3 unmodified lines
11151143 _vertexBuffer.create();
11161144 _vertexBuffer.bind();
11171145 _vertexBuffer.allocate(_vertices.constData(), _vertices.size() * sizeof(VoxelPoint));
1118− _vertices.clear();
1119−
1146+
11201147 _indexBuffer.create();
11211148 _indexBuffer.bind();
11221149 _indexBuffer.allocate(_indices.constData(), _indices.size() * sizeof(int));
1123− _indices.clear();
1124−
1150+
11251151 if (!_materials.isEmpty()) {
11261152 _networkTextures.resize(_materials.size());
11271153 for (int i = 0; i < _materials.size(); i++) {
@@ -1735,7 +1761,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 607 unmodified lines
17351761 QVector<VoxelPoint> vertices;
17361762 QVector<int> indices;
17371763 QVector<glm::vec3> hermiteSegments;
1738− QHash<QRgb, glm::vec3> points;
1764+ QMultiHash<QRgb, int> quadIndices;
17391765
17401766 // see http://www.frankpetterson.com/publications/dualcontour/dualcontour.pdf for a description of the
17411767 // dual contour algorithm for generating meshes from voxel data using Hermite-tagged edges
@@ -2142,8 +2168,6 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 400 unmodified lines
21422168 { (quint8)materialWeights[0], (quint8)materialWeights[1], (quint8)materialWeights[2],
21432169 (quint8)materialWeights[3] } };
21442170
2145− points.insert(qRgb(x + 1, y + 1, z + 1), (glm::vec3(clampedX, clampedY, clampedZ) + center) / highest);
2146−
21472171 // determine whether we must "crease" by generating directional normals
21482172 const float CREASE_COS_NORMAL = glm::cos(glm::radians(40.0f));
21492173 AxisIndex index(vertices.size(), vertices.size(), vertices.size());
@@ -2202,6 +2226,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 52 unmodified lines
22022226 // quads for each edge that includes a transition, using indices of previously generated vertices
22032227 if (x != 0 && y != 0 && z != 0) {
22042228 if (alpha0 != alpha1) {
2229+ quadIndices.insert(qRgb(x, y, z), indices.size());
2230+ quadIndices.insert(qRgb(x, y - 1, z), indices.size());
2231+ quadIndices.insert(qRgb(x, y - 1, z - 1), indices.size());
2232+ quadIndices.insert(qRgb(x, y, z - 1), indices.size());
22052233 indices.append(index.x);
22062234 int index1 = lastLineIndices.at(x).x;
22072235 int index2 = lastPlaneIndices.at((y - 1) * expanded + x).x;
@@ -2218,6 +2246,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 10 unmodified lines
22182246 }
22192247
22202248 if (alpha0 != alpha2) {
2249+ quadIndices.insert(qRgb(x, y, z), indices.size());
2250+ quadIndices.insert(qRgb(x - 1, y, z), indices.size());
2251+ quadIndices.insert(qRgb(x - 1, y, z - 1), indices.size());
2252+ quadIndices.insert(qRgb(x, y, z - 1), indices.size());
22212253 indices.append(index.y);
22222254 int index1 = lastIndex.y;
22232255 int index2 = lastPlaneIndices.at(y * expanded + x - 1).y;
@@ -2234,6 +2266,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 10 unmodified lines
22342266 }
22352267
22362268 if (alpha0 != alpha4) {
2269+ quadIndices.insert(qRgb(x, y, z), indices.size());
2270+ quadIndices.insert(qRgb(x - 1, y, z), indices.size());
2271+ quadIndices.insert(qRgb(x - 1, y - 1, z), indices.size());
2272+ quadIndices.insert(qRgb(x, y - 1, z), indices.size());
22372273 indices.append(index.z);
22382274 int index1 = lastIndex.z;
22392275 int index2 = lastLineIndices.at(x - 1).z;
@@ -2269,7 +2305,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 29 unmodified lines
22692305 colorZ += area;
22702306 }
22712307 }
2272− buffer = new VoxelBuffer(vertices, indices, hermiteSegments, points, size,
2308+ buffer = new VoxelBuffer(vertices, indices, hermiteSegments, quadIndices, size,
22732309 material ? material->getMaterials() : QVector<SharedObjectPointer>());
22742310 }
22752311 BufferDataPointer pointer(buffer);