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
354 if (!buffer) {354 if (!buffer) {
355 return STOP_RECURSION;355 return STOP_RECURSION;
356 }356 }
357 glm::vec3 origin = ((_origin + distance * _direction) - info.minimum) / info.size;357 glm::vec3 entry = ((_origin + distance * _direction) - info.minimum) / info.size;
358 if (buffer->findFirstRayIntersection(origin, _direction, intersectionDistance)) {358 if (buffer->findFirstRayIntersection(entry, _origin, _direction, intersectionDistance)) {
359 intersectionDistance = intersectionDistance * info.size + distance;
360 return SHORT_CIRCUIT;359 return SHORT_CIRCUIT;
361 }360 }
362 return STOP_RECURSION;361 return STOP_RECURSION;
@@ -1035,11 +1034,11 @@ void VoxelPoint::setNormal(const glm::vec3& normal) { · 672 unmodified lines
1035}1034}
1036 1035
1037VoxelBuffer::VoxelBuffer(const QVector<VoxelPoint>& vertices, const QVector<int>& indices, const QVector<glm::vec3>& hermite,1036VoxelBuffer::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) :
1039 _vertices(vertices),1038 _vertices(vertices),
1040 _indices(indices),1039 _indices(indices),
1041 _hermite(hermite),1040 _hermite(hermite),
1042 _points(points),1041 _quadIndices(quadIndices),
1043 _size(size),1042 _size(size),
1044 _vertexCount(vertices.size()),1043 _vertexCount(vertices.size()),
1045 _indexCount(indices.size()),1044 _indexCount(indices.size()),
@@ -1048,17 +1047,47 @@ VoxelBuffer::VoxelBuffer(const QVector<VoxelPoint>& vertices, const QVector<int> · 2 unmodified lines
1048 _materials(materials) {1047 _materials(materials) {
1049}1048}
1050 1049
1051bool VoxelBuffer::findFirstRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance) const {1050static 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
1074bool VoxelBuffer::findFirstRayIntersection(const glm::vec3& entry, const glm::vec3& origin,
1075 const glm::vec3& direction, float& distance) const {
1052 float highest = _size - 1.0f;1076 float highest = _size - 1.0f;
1053 glm::vec3 position = origin * highest;1077 glm::vec3 position = entry * highest;
1054 glm::vec3 floors = glm::floor(position);1078 glm::vec3 floors = glm::floor(position);
1055 int max = _size - 2;1079 int max = _size - 2;
1056 int x = qMin((int)floors.x, max), y = qMin((int)floors.y, max), z = qMin((int)floors.z, max);1080 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 {1081 forever {
1059 if (_points.contains(qRgb(x + 1, y + 1, z + 1))) {1082 for (QMultiHash<QRgb, int>::const_iterator it = _quadIndices.constFind(qRgb(x + 1, y + 1, z + 1));
1060 distance = combinedDistance / highest;1083 it != _quadIndices.constEnd(); it++) {
1061 return true;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 }
1062 }1091 }
1063 float xDistance = FLT_MAX, yDistance = FLT_MAX, zDistance = FLT_MAX;1092 float xDistance = FLT_MAX, yDistance = FLT_MAX, zDistance = FLT_MAX;
1064 if (direction.x > 0.0f) {1093 if (direction.x > 0.0f) {
@@ -1105,7 +1134,6 @@ bool VoxelBuffer::findFirstRayIntersection(const glm::vec3& origin, const glm::v · 40 unmodified lines
1105 }1134 }
1106 }1135 }
1107 position += direction * minimumDistance;1136 position += direction * minimumDistance;
1108 combinedDistance += minimumDistance;
1109 }1137 }
1110 return false;1138 return false;
1111}1139}
@@ -1115,13 +1143,11 @@ void VoxelBuffer::render(bool cursor) { · 3 unmodified lines
1115 _vertexBuffer.create();1143 _vertexBuffer.create();
1116 _vertexBuffer.bind();1144 _vertexBuffer.bind();
1117 _vertexBuffer.allocate(_vertices.constData(), _vertices.size() * sizeof(VoxelPoint));1145 _vertexBuffer.allocate(_vertices.constData(), _vertices.size() * sizeof(VoxelPoint));
1118 _vertices.clear();1146
1119
1120 _indexBuffer.create();1147 _indexBuffer.create();
1121 _indexBuffer.bind();1148 _indexBuffer.bind();
1122 _indexBuffer.allocate(_indices.constData(), _indices.size() * sizeof(int));1149 _indexBuffer.allocate(_indices.constData(), _indices.size() * sizeof(int));
1123 _indices.clear();1150
1124
1125 if (!_materials.isEmpty()) {1151 if (!_materials.isEmpty()) {
1126 _networkTextures.resize(_materials.size());1152 _networkTextures.resize(_materials.size());
1127 for (int i = 0; i < _materials.size(); i++) {1153 for (int i = 0; i < _materials.size(); i++) {
@@ -1735,7 +1761,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 607 unmodified lines
1735 QVector<VoxelPoint> vertices;1761 QVector<VoxelPoint> vertices;
1736 QVector<int> indices;1762 QVector<int> indices;
1737 QVector<glm::vec3> hermiteSegments;1763 QVector<glm::vec3> hermiteSegments;
1738 QHash<QRgb, glm::vec3> points;1764 QMultiHash<QRgb, int> quadIndices;
1739 1765
1740 // see http://www.frankpetterson.com/publications/dualcontour/dualcontour.pdf for a description of the1766 // see http://www.frankpetterson.com/publications/dualcontour/dualcontour.pdf for a description of the
1741 // dual contour algorithm for generating meshes from voxel data using Hermite-tagged edges1767 // 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
2142 { (quint8)materialWeights[0], (quint8)materialWeights[1], (quint8)materialWeights[2],2168 { (quint8)materialWeights[0], (quint8)materialWeights[1], (quint8)materialWeights[2],
2143 (quint8)materialWeights[3] } };2169 (quint8)materialWeights[3] } };
2144 2170
2145 points.insert(qRgb(x + 1, y + 1, z + 1), (glm::vec3(clampedX, clampedY, clampedZ) + center) / highest);
2146
2147 // determine whether we must "crease" by generating directional normals2171 // determine whether we must "crease" by generating directional normals
2148 const float CREASE_COS_NORMAL = glm::cos(glm::radians(40.0f));2172 const float CREASE_COS_NORMAL = glm::cos(glm::radians(40.0f));
2149 AxisIndex index(vertices.size(), vertices.size(), vertices.size());2173 AxisIndex index(vertices.size(), vertices.size(), vertices.size());
@@ -2202,6 +2226,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 52 unmodified lines
2202 // quads for each edge that includes a transition, using indices of previously generated vertices2226 // quads for each edge that includes a transition, using indices of previously generated vertices
2203 if (x != 0 && y != 0 && z != 0) {2227 if (x != 0 && y != 0 && z != 0) {
2204 if (alpha0 != alpha1) {2228 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());
2205 indices.append(index.x);2233 indices.append(index.x);
2206 int index1 = lastLineIndices.at(x).x;2234 int index1 = lastLineIndices.at(x).x;
2207 int index2 = lastPlaneIndices.at((y - 1) * expanded + x).x;2235 int index2 = lastPlaneIndices.at((y - 1) * expanded + x).x;
@@ -2218,6 +2246,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 10 unmodified lines
2218 }2246 }
2219 2247
2220 if (alpha0 != alpha2) {2248 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());
2221 indices.append(index.y);2253 indices.append(index.y);
2222 int index1 = lastIndex.y;2254 int index1 = lastIndex.y;
2223 int index2 = lastPlaneIndices.at(y * expanded + x - 1).y;2255 int index2 = lastPlaneIndices.at(y * expanded + x - 1).y;
@@ -2234,6 +2266,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 10 unmodified lines
2234 }2266 }
2235 2267
2236 if (alpha0 != alpha4) {2268 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());
2237 indices.append(index.z);2273 indices.append(index.z);
2238 int index1 = lastIndex.z;2274 int index1 = lastIndex.z;
2239 int index2 = lastLineIndices.at(x - 1).z;2275 int index2 = lastLineIndices.at(x - 1).z;
@@ -2269,7 +2305,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 29 unmodified lines
2269 colorZ += area;2305 colorZ += area;
2270 }2306 }
2271 }2307 }
2272 buffer = new VoxelBuffer(vertices, indices, hermiteSegments, points, size,2308 buffer = new VoxelBuffer(vertices, indices, hermiteSegments, quadIndices, size,
2273 material ? material->getMaterials() : QVector<SharedObjectPointer>());2309 material ? material->getMaterials() : QVector<SharedObjectPointer>());
2274 }2310 }
2275 BufferDataPointer pointer(buffer);2311 BufferDataPointer pointer(buffer);