Showing the changes to interface/src/MetavoxelSystem.cpp (1 of 2 files). Show all
Unified · Split
| @@ -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 | ||
| 1037 | VoxelBuffer::VoxelBuffer(const QVector<VoxelPoint>& vertices, const QVector<int>& indices, const QVector<glm::vec3>& hermite, | 1036 | 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) : |
| 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 | ||
| 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 { | ||
| 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 the | 1766 | // 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 edges | 1767 | // 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 normals | 2171 | // 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 vertices | 2226 | // 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); |