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 | 354 | if (!buffer) { |
| 355 | 355 | return STOP_RECURSION; |
| 356 | 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; | |
| 357 | + glm::vec3 entry = ((_origin + distance * _direction) - info.minimum) / info.size; | |
| 358 | + if (buffer->findFirstRayIntersection(entry, _origin, _direction, intersectionDistance)) { | |
| 360 | 359 | return SHORT_CIRCUIT; |
| 361 | 360 | } |
| 362 | 361 | return STOP_RECURSION; |
| @@ -1035,11 +1034,11 @@ void VoxelPoint::setNormal(const glm::vec3& normal) { · 672 unmodified lines | ||
| 1035 | 1034 | } |
| 1036 | 1035 | |
| 1037 | 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 | 1038 | _vertices(vertices), |
| 1040 | 1039 | _indices(indices), |
| 1041 | 1040 | _hermite(hermite), |
| 1042 | − _points(points), | |
| 1041 | + _quadIndices(quadIndices), | |
| 1043 | 1042 | _size(size), |
| 1044 | 1043 | _vertexCount(vertices.size()), |
| 1045 | 1044 | _indexCount(indices.size()), |
| @@ -1048,17 +1047,47 @@ VoxelBuffer::VoxelBuffer(const QVector<VoxelPoint>& vertices, const QVector<int> · 2 unmodified lines | ||
| 1048 | 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 | 1076 | float highest = _size - 1.0f; |
| 1053 | − glm::vec3 position = origin * highest; | |
| 1077 | + glm::vec3 position = entry * highest; | |
| 1054 | 1078 | glm::vec3 floors = glm::floor(position); |
| 1055 | 1079 | int max = _size - 2; |
| 1056 | 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 | 1081 | 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 | + } | |
| 1062 | 1091 | } |
| 1063 | 1092 | float xDistance = FLT_MAX, yDistance = FLT_MAX, zDistance = FLT_MAX; |
| 1064 | 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 | 1136 | position += direction * minimumDistance; |
| 1108 | − combinedDistance += minimumDistance; | |
| 1109 | 1137 | } |
| 1110 | 1138 | return false; |
| 1111 | 1139 | } |
| @@ -1115,13 +1143,11 @@ void VoxelBuffer::render(bool cursor) { · 3 unmodified lines | ||
| 1115 | 1143 | _vertexBuffer.create(); |
| 1116 | 1144 | _vertexBuffer.bind(); |
| 1117 | 1145 | _vertexBuffer.allocate(_vertices.constData(), _vertices.size() * sizeof(VoxelPoint)); |
| 1118 | − _vertices.clear(); | |
| 1119 | − | |
| 1146 | + | |
| 1120 | 1147 | _indexBuffer.create(); |
| 1121 | 1148 | _indexBuffer.bind(); |
| 1122 | 1149 | _indexBuffer.allocate(_indices.constData(), _indices.size() * sizeof(int)); |
| 1123 | − _indices.clear(); | |
| 1124 | − | |
| 1150 | + | |
| 1125 | 1151 | if (!_materials.isEmpty()) { |
| 1126 | 1152 | _networkTextures.resize(_materials.size()); |
| 1127 | 1153 | for (int i = 0; i < _materials.size(); i++) { |
| @@ -1735,7 +1761,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 607 unmodified lines | ||
| 1735 | 1761 | QVector<VoxelPoint> vertices; |
| 1736 | 1762 | QVector<int> indices; |
| 1737 | 1763 | QVector<glm::vec3> hermiteSegments; |
| 1738 | − QHash<QRgb, glm::vec3> points; | |
| 1764 | + QMultiHash<QRgb, int> quadIndices; | |
| 1739 | 1765 | |
| 1740 | 1766 | // see http://www.frankpetterson.com/publications/dualcontour/dualcontour.pdf for a description of the |
| 1741 | 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 | 2168 | { (quint8)materialWeights[0], (quint8)materialWeights[1], (quint8)materialWeights[2], |
| 2143 | 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 | 2171 | // determine whether we must "crease" by generating directional normals |
| 2148 | 2172 | const float CREASE_COS_NORMAL = glm::cos(glm::radians(40.0f)); |
| 2149 | 2173 | AxisIndex index(vertices.size(), vertices.size(), vertices.size()); |
| @@ -2202,6 +2226,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 52 unmodified lines | ||
| 2202 | 2226 | // quads for each edge that includes a transition, using indices of previously generated vertices |
| 2203 | 2227 | if (x != 0 && y != 0 && z != 0) { |
| 2204 | 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 | 2233 | indices.append(index.x); |
| 2206 | 2234 | int index1 = lastLineIndices.at(x).x; |
| 2207 | 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 | 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 | 2253 | indices.append(index.y); |
| 2222 | 2254 | int index1 = lastIndex.y; |
| 2223 | 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 | 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 | 2273 | indices.append(index.z); |
| 2238 | 2274 | int index1 = lastIndex.z; |
| 2239 | 2275 | int index2 = lastLineIndices.at(x - 1).z; |
| @@ -2269,7 +2305,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 29 unmodified lines | ||
| 2269 | 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 | 2309 | material ? material->getMaterials() : QVector<SharedObjectPointer>()); |
| 2274 | 2310 | } |
| 2275 | 2311 | BufferDataPointer pointer(buffer); |