From 924f223e8f5e7a09d9de4cecd9c5e45d5a1d833b Mon Sep 17 00:00:00 2001 From: yamahigashi Date: Sun, 6 Aug 2023 14:36:49 +0900 Subject: [PATCH 1/5] Fixed mis detection --- src/kernel/EmbreeKernel.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/kernel/EmbreeKernel.cpp b/src/kernel/EmbreeKernel.cpp index 759fbc6..43af502 100644 --- a/src/kernel/EmbreeKernel.cpp +++ b/src/kernel/EmbreeKernel.cpp @@ -206,11 +206,31 @@ std::vector EmbreeKernel::queryIntersected(const TriangleData& tri } if (isALeaf) { + + // FIXME: + // Ideally, we should use box-to-box checks for collisions. However, + // due to the occurrence of extremely small boxes, collisions + // might be missed. Therefore, we're opting to skip the check. + // if (!intersectBoxBox(currentNode->leaf()->bounds, triangle.bbox)) { + int index = currentNode->leaf()->id; TriangleData triangleData = this->triangles[index]; if (intersectTriangleTriangle(triangle, triangleData)) { intersectingA.push_back(triangleData); } + + if (index > 0) { + triangleData = this->triangles[index-1]; + if (intersectTriangleTriangle(triangle, triangleData)) { + intersectingA.push_back(triangleData); + } + } + if (index < this->triangles.size()-1) { + triangleData = this->triangles[index+1]; + if (intersectTriangleTriangle(triangle, triangleData)) { + intersectingA.push_back(triangleData); + } + } } }; From a1f8f26b45e4177d6a8d6e2881e3867c03437d79 Mon Sep 17 00:00:00 2001 From: yamahigashi Date: Sun, 6 Aug 2023 16:01:16 +0900 Subject: [PATCH 2/5] wip embree kernel vs kernel --- src/kernel/EmbreeKernel.cpp | 161 +++++++++++++++++++----------------- src/kernel/EmbreeKernel.h | 3 + 2 files changed, 86 insertions(+), 78 deletions(-) diff --git a/src/kernel/EmbreeKernel.cpp b/src/kernel/EmbreeKernel.cpp index 43af502..049d432 100644 --- a/src/kernel/EmbreeKernel.cpp +++ b/src/kernel/EmbreeKernel.cpp @@ -239,6 +239,66 @@ std::vector EmbreeKernel::queryIntersected(const TriangleData& tri } +void intersectBvhNodesRecursive( + Node* nodeA, + Node* nodeB, + std::vector>& intersectedNodes +) { + if (!nodeA || !nodeB) { + return; + } + + bool isAInner = nodeA->branch() != nullptr; + bool isBInner = nodeB->branch() != nullptr; + bool isALeaf = nodeA->leaf() != nullptr; + bool isBLeaf = nodeB->leaf() != nullptr; + + if (nodeA->isLeaf() && nodeB->isLeaf()) { + intersectedNodes.push_back({nodeA, nodeB}); + return; + } + + if (nodeA->isLeaf()) { // A is leaf, B is inner + if (intersectBoxBox(nodeA->leaf()->bounds, nodeB->branch()->bounds[0])) { + intersectBvhNodesRecursive(nodeA, nodeB->branch()->children[0], intersectedNodes); + } + + if (intersectBoxBox(nodeA->leaf()->bounds, nodeB->branch()->bounds[1])) { + intersectBvhNodesRecursive(nodeA, nodeB->branch()->children[1], intersectedNodes); + } + return; + } + + if (nodeB->isLeaf()) { // A is inner, B is leaf + if (intersectBoxBox(nodeB->leaf()->bounds, nodeA->branch()->bounds[0])) { + intersectBvhNodesRecursive(nodeA->branch()->children[0], nodeB, intersectedNodes); + } + + if (intersectBoxBox(nodeB->leaf()->bounds, nodeA->branch()->bounds[1])) { + intersectBvhNodesRecursive(nodeA->branch()->children[1], nodeB, intersectedNodes); + } + return; + } + + // Both are inner nodes + if (intersectBoxBox(nodeA->branch()->bounds[0], nodeB->branch()->bounds[0])) { + intersectBvhNodesRecursive(nodeA->branch()->children[0], nodeB->branch()->children[0], intersectedNodes); + } + + if (intersectBoxBox(nodeA->branch()->bounds[0], nodeB->branch()->bounds[1])) { + intersectBvhNodesRecursive(nodeA->branch()->children[0], nodeB->branch()->children[1], intersectedNodes); + } + + if (intersectBoxBox(nodeA->branch()->bounds[1], nodeB->branch()->bounds[0])) { + intersectBvhNodesRecursive(nodeA->branch()->children[1], nodeB->branch()->children[0], intersectedNodes); + } + + if (intersectBoxBox(nodeA->branch()->bounds[1], nodeB->branch()->bounds[1])) { + intersectBvhNodesRecursive(nodeA->branch()->children[1], nodeB->branch()->children[1], intersectedNodes); + } +} + + K2KIntersection EmbreeKernel::intersectKernelKernel( SpatialDivisionKernel& otherKernel @@ -246,88 +306,33 @@ K2KIntersection EmbreeKernel::intersectKernelKernel( ) const { // MGlobal::displayInfo(MString("Intersecting EmbreeKernel with ")); - std::vector intersectingA; - std::vector intersectingB; + std::vector intersectedTrianglesA; + std::vector intersectedTrianglesB; EmbreeKernel* other = dynamic_cast(&otherKernel); if (!other) { // MGlobal::displayError("Failed to cast SpatialDivisionKernel to EmbreeKernel"); - return std::make_pair(intersectingA, intersectingB); + return std::make_pair(intersectedTrianglesA, intersectedTrianglesB); + } + + std::vector> intersectedNodes; + intersectBvhNodesRecursive(this->root, other->root, intersectedNodes); + + for (const auto& pair : intersectedNodes) { + Node* nodeA = pair.first; + Node* nodeB = pair.second; + + if (nodeA->isLeaf() && nodeB->isLeaf()) { + for (TriangleData triA : nodeA->triangles) { + for (TriangleData triB : nodeB->triangles) { + if (intersectTriangleTriangle(triA, triB)) { + intersectedTrianglesA.push_back(triA); + intersectedTrianglesB.push_back(triB); + } + } + } + } } - // FIXME: change this to stackless traversal - // // Start with root nodes of both BVHs - // std::stack stack; - // stack.push({root, other->root}); - // - // while (!stack.empty()) { - // - // NodePair currentPair = stack.top(); - // stack.pop(); - // - // // Cast the base Node type to their respective subtypes - // bool isAInner = currentPair.nodeA->branch() != nullptr; - // bool isBInner = currentPair.nodeB->branch() != nullptr; - // bool isALeaf = currentPair.nodeA->leaf() != nullptr; - // bool isBLeaf = currentPair.nodeB->leaf() != nullptr; - // - // Node *nodeA = currentPair.nodeA; - // Node *nodeB = currentPair.nodeB; - // - // // Iterate over the bounds of each node and check for intersections - // bool anyIntersected = false; - // for (int i = 0; i < 2; ++i) { - // if (anyIntersected){ break; } - // - // // Assign the bounds for A and B depending on their type - // MBoundingBox bboxA, bboxB; - // if (isAInner){ bboxA = nodeA->branch()->bounds[i]; } - // else if (isALeaf){ bboxA = nodeA->leaf()->bounds; } - // else { throw std::runtime_error("Node A is neither a leaf nor an inner node"); } - // - // for (int j = 0; j < 2; ++j) { - // if (isBInner){ bboxB = nodeB->branch()->bounds[i]; } - // else if (isBLeaf){ bboxB = nodeB->leaf()->bounds; } - // else throw std::runtime_error("Node B is neither a leaf nor an inner node"); - // - // // Check if the bounds intersect - // if (intersectBoxBox(bboxA, bboxB)) { - // anyIntersected = true; - // break; - // } - // } - // } - // - // // Skip if bounding boxes of current nodes do not intersect - // if (!anyIntersected) { - // continue; - // } - // - // if (isALeaf && isBLeaf) { - // LeafNode* leafNodeA = nodeA->leaf(); - // LeafNode* leafNodeB = nodeB->leaf(); - // - // intersectingA.push_back( this->triangles[leafNodeA->id]); - // intersectingB.push_back(other->triangles[leafNodeB->id]); - // - // } else { - // // If one or both nodes are not leaves, push their children onto the stack - // if (isAInner) { - // InnerNode* innerNodeA = nodeA->branch(); - // for (Node* child : nodeA->branch()->children) { - // stack.push({child, nodeB}); - // } - // - // } - // if (isBInner) { - // InnerNode* innerNodeB = nodeB->branch(); - // - // for (Node* child : nodeB->branch()->children) { - // stack.push({nodeA, child}); - // } - // } - // } - // } - - return std::make_pair(intersectingA, intersectingB); + return std::make_pair(intersectedTrianglesA, intersectedTrianglesB); } diff --git a/src/kernel/EmbreeKernel.h b/src/kernel/EmbreeKernel.h index bd890e4..f314510 100644 --- a/src/kernel/EmbreeKernel.h +++ b/src/kernel/EmbreeKernel.h @@ -23,6 +23,7 @@ struct Node { virtual InnerNode* branch() { return nullptr; } virtual LeafNode* leaf() { return nullptr; } + virtual bool isLeaf() { return false; } InnerNode* parent() { return nullptr; } TriangleList triangles; @@ -40,6 +41,7 @@ struct InnerNode : public Node { MBoundingBox bounds[2]; Node* children[2]; + bool isLeaf() { return false; } InnerNode() { bounds[0] = bounds[1] = MBoundingBox(); @@ -82,6 +84,7 @@ struct LeafNode : public Node { unsigned id; MBoundingBox bounds; + bool isLeaf() { return true; } LeafNode (unsigned id, const MBoundingBox& bounds) : id(id), bounds(bounds) {} From 5a3d7596706899f4267fecfcfac8eb37cabbfdcf Mon Sep 17 00:00:00 2001 From: yamahigashi Date: Sun, 6 Aug 2023 17:23:06 +0900 Subject: [PATCH 3/5] Added toggle show/hide result meshes options --- scripts/AEintersectionMarkerTemplate.mel | 68 ++++++++++++++++++++++++ src/intersectionMarkerDrawOverride.cpp | 16 ++++-- src/intersectionMarkerNode.cpp | 40 +++++++++++++- src/intersectionMarkerNode.h | 4 ++ 4 files changed, 124 insertions(+), 4 deletions(-) create mode 100644 scripts/AEintersectionMarkerTemplate.mel diff --git a/scripts/AEintersectionMarkerTemplate.mel b/scripts/AEintersectionMarkerTemplate.mel new file mode 100644 index 0000000..e956016 --- /dev/null +++ b/scripts/AEintersectionMarkerTemplate.mel @@ -0,0 +1,68 @@ +proc _registerNodeHelp(string $type, string $cmd) +{ + global string $gAttributeEditorNodeTypeArray[]; + global string $gAttributeEditorHelpCommandArray[]; + + int $idx, $len = size($gAttributeEditorNodeTypeArray); + for ($idx = 0; $idx < $len; ++$idx) { + if ($type == $gAttributeEditorNodeTypeArray[$idx]) break; + } + + if ($idx < $len) { + $gAttributeEditorHelpCommandArray[$idx] = $cmd; + } else { + $gAttributeEditorNodeTypeArray[$idx] = $type; + $gAttributeEditorHelpCommandArray[$idx] = $cmd; + } +} + + +global proc AEintersectionMarkerTemplate(string $nodename) +{ + editorTemplate -beginLayout "Intersection Marker Attributes" -collapse 0; + + { + string $url = "https://github.com/yamahigashi/MayaIntersectionMarker"; + _registerNodeHelp("intersectionMarker", "showHelp -a \""+ $url +"\""); + + // editorTemplate -beginLayout "Mesh Inputs" -collapse 0; + // editorTemplate -addControl "meshA"; + // editorTemplate -addControl "meshB"; + // editorTemplate -endLayout; + // + // editorTemplate -beginLayout "Offset Matrices" -collapse 0; + // editorTemplate -addControl "offsetMatrixA"; + // editorTemplate -addControl "offsetMatrixB"; + // editorTemplate -endLayout; + + editorTemplate -beginLayout "Display Options" -collapse 0; + editorTemplate -addControl "showMeshA"; + editorTemplate -addControl "showMeshB"; + // editorTemplate -addControl "restIntersected"; + editorTemplate -endLayout; + + editorTemplate -beginLayout "Checksums" -collapse 0; + editorTemplate -addControl "vertexChecksumA"; + editorTemplate -addControl "vertexChecksumB"; + editorTemplate -endLayout; + + editorTemplate -beginLayout "Kernel Options" -collapse 0; + editorTemplate -addControl "kernel"; + editorTemplate -addControl "collisionMode"; + editorTemplate -endLayout; + + // editorTemplate -beginLayout "Output" -collapse 0; + // editorTemplate -addControl "outputIntersected"; + // editorTemplate -endLayout; + } + + // End layout for IntersectionMarkerNode + editorTemplate -endLayout; + + AEdependNodeTemplate($nodename); + + editorTemplate("-addExtraControls"); + editorTemplate("-endScrollLayout"); +} + +// AEIntersectionMarkerNodeTemplate($gAECurrentTab); diff --git a/src/intersectionMarkerDrawOverride.cpp b/src/intersectionMarkerDrawOverride.cpp index 7e59913..33cdc10 100644 --- a/src/intersectionMarkerDrawOverride.cpp +++ b/src/intersectionMarkerDrawOverride.cpp @@ -109,10 +109,10 @@ MUserData* IntersectionMarkerDrawOverride::prepareForDraw( prevChecksum = newChecksum; MFnMesh meshAFn; - MFnMesh meshBFn; status = node->getInputDagMesh(node->meshA, meshAFn); CHECK_MSTATUS_AND_RETURN_DATA("prepareForDraw: meshAFn is null"); + MFnMesh meshBFn; status = node->getInputDagMesh(node->meshB, meshBFn); CHECK_MSTATUS_AND_RETURN_DATA("prepareForDraw: meshBFn is null"); @@ -122,8 +122,18 @@ MUserData* IntersectionMarkerDrawOverride::prepareForDraw( node->getOffsetMatrix(node->offsetMatrixA, outMatrixA); node->getOffsetMatrix(node->offsetMatrixB, outMatrixB); - addIntersectedVertices(meshAFn, data, node->intersectedFaceIdsA, outMatrixA); - addIntersectedVertices(meshBFn, data, node->intersectedFaceIdsB, outMatrixB); + MPlug showMeshAPlug = depNodeFn.findPlug("showMeshA", false, &status); + bool showMeshA = showMeshAPlug.asBool(); + MPlug showMeshBPlug = depNodeFn.findPlug("showMeshB", false, &status); + bool showMeshB = showMeshBPlug.asBool(); + + if (showMeshA) { + addIntersectedVertices(meshAFn, data, node->intersectedFaceIdsA, outMatrixA); + } + + if (showMeshB) { + addIntersectedVertices(meshBFn, data, node->intersectedFaceIdsB, outMatrixB); + } return data; } diff --git a/src/intersectionMarkerNode.cpp b/src/intersectionMarkerNode.cpp index bf03289..33856e7 100644 --- a/src/intersectionMarkerNode.cpp +++ b/src/intersectionMarkerNode.cpp @@ -52,6 +52,8 @@ MObject IntersectionMarkerNode::restIntersected; MObject IntersectionMarkerNode::vertexChecksumA; MObject IntersectionMarkerNode::vertexChecksumB; +MObject IntersectionMarkerNode::showMeshA; +MObject IntersectionMarkerNode::showMeshB; MObject IntersectionMarkerNode::kernelType; MObject IntersectionMarkerNode::collisionMode; @@ -96,6 +98,23 @@ MStatus IntersectionMarkerNode::initialize() status = addAttribute(offsetMatrixB); CHECK_MSTATUS_AND_RETURN_IT(status); + // Showing Result of Intersection + showMeshA = nAttr.create(SHOW_MESH_A, SHOW_MESH_A, MFnNumericData::kBoolean, 1); + status = addAttribute(showMeshA); + nAttr.setStorable(true); + nAttr.setWritable(true); + nAttr.setReadable(false); + nAttr.setKeyable(true); + CHECK_MSTATUS_AND_RETURN_IT(status); + + showMeshB = nAttr.create(SHOW_MESH_B, SHOW_MESH_B, MFnNumericData::kBoolean, 1); + status = addAttribute(showMeshB); + nAttr.setStorable(true); + nAttr.setWritable(true); + nAttr.setReadable(false); + nAttr.setKeyable(true); + CHECK_MSTATUS_AND_RETURN_IT(status); + // Initialize Rest Intersected restIntersected = nAttr.create(REST_INTERSECTED, REST_INTERSECTED, MFnNumericData::kInt, -1); nAttr.setStorable(true); @@ -157,6 +176,8 @@ MStatus IntersectionMarkerNode::initialize() status = attributeAffects(offsetMatrixB, outputIntersected); status = attributeAffects(meshA, outputIntersected); status = attributeAffects(meshB, outputIntersected); + status = attributeAffects(showMeshA, outputIntersected); + status = attributeAffects(showMeshB, outputIntersected); CHECK_MSTATUS_AND_RETURN_IT(status); status = attributeAffects(kernelType, outputIntersected); @@ -190,9 +211,14 @@ MStatus IntersectionMarkerNode::preEvaluation( CHECK_MSTATUS_AND_RETURN_IT(status); dirty = dirty || evaluationNode.dirtyPlugExists(collisionMode, &status); + dirty = dirty || evaluationNode.dirtyPlugExists(showMeshA, &status); + CHECK_MSTATUS_AND_RETURN_IT(status); + + dirty = dirty || evaluationNode.dirtyPlugExists(showMeshB, &status); CHECK_MSTATUS_AND_RETURN_IT(status); if (dirty) { + MGlobal::displayInfo("node Pre Evaluation"); MHWRender::MRenderer::setGeometryDrawDirty(thisMObject()); } } @@ -222,7 +248,9 @@ MStatus IntersectionMarkerNode::postEvaluation( (evaluationNode.dirtyPlugExists(offsetMatrixA, &status) && status ) || (evaluationNode.dirtyPlugExists(offsetMatrixB, &status) && status ) || (evaluationNode.dirtyPlugExists(kernelType, &status) && status ) || - (evaluationNode.dirtyPlugExists(collisionMode, &status) && status ) + (evaluationNode.dirtyPlugExists(collisionMode, &status) && status ) || + (evaluationNode.dirtyPlugExists(showMeshA, &status) && status ) || + (evaluationNode.dirtyPlugExists(showMeshB, &status) && status ) ) { MDataBlock block = forceCache(); MDataHandle meshAHandle = block.inputValue(meshA, &status); @@ -277,6 +305,13 @@ MStatus IntersectionMarkerNode::compute(const MPlug &plug, MDataBlock &dataBlock MMatrix offsetA = offsetAHandle.asMatrix(); MMatrix offsetB = offsetBHandle.asMatrix(); + MDataHandle showMeshAHandle = dataBlock.inputValue(showMeshA); + MDataHandle showMeshBHandle = dataBlock.inputValue(showMeshB); + bool showA = showMeshAHandle.asBool(); + bool showB = showMeshBHandle.asBool(); + showMeshAHandle.setClean(); + showMeshBHandle.setClean(); + // ------------------------------------------------------------------------------------------- // update checksums // MGlobal::displayInfo("update checksums..."); @@ -288,12 +323,15 @@ MStatus IntersectionMarkerNode::compute(const MPlug &plug, MDataBlock &dataBlock int checkA = vertexChecksumAHandle.asInt(); int checkB = vertexChecksumBHandle.asInt(); + newCheckA = newCheckA ^ int(showA); + newCheckB = newCheckB ^ int(showB); // If the checksums are the same, then we don't need to do anything // because the meshes have not changed. if (checkA == newCheckA && checkB == newCheckB) { vertexChecksumAHandle.setClean(); vertexChecksumBHandle.setClean(); + return MS::kSuccess; } diff --git a/src/intersectionMarkerNode.h b/src/intersectionMarkerNode.h index fe185ee..b93181a 100644 --- a/src/intersectionMarkerNode.h +++ b/src/intersectionMarkerNode.h @@ -30,6 +30,8 @@ #define REST_INTERSECTED "restIntersected" #define VERTEX_CHECKSUM_A "vertexChecksumA" #define VERTEX_CHECKSUM_B "vertexChecksumB" +#define SHOW_MESH_A "showMeshA" +#define SHOW_MESH_B "showMeshB" #define KERNEL "kernel" #define COLLISION_MODE "collisionMode" @@ -153,6 +155,8 @@ std::shared_ptr getActiveKernel() const; static MObject vertexChecksumA; static MObject vertexChecksumB; + static MObject showMeshA; + static MObject showMeshB; static MObject kernelType; static MObject collisionMode; From 45323013233b76deb7626eafc493937f7f85791a Mon Sep 17 00:00:00 2001 From: yamahigashi Date: Sun, 6 Aug 2023 21:55:51 +0900 Subject: [PATCH 4/5] Removed debug message --- src/intersectionMarkerDrawOverride.cpp | 2 +- src/intersectionMarkerNode.cpp | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/intersectionMarkerDrawOverride.cpp b/src/intersectionMarkerDrawOverride.cpp index 33cdc10..71cb00f 100644 --- a/src/intersectionMarkerDrawOverride.cpp +++ b/src/intersectionMarkerDrawOverride.cpp @@ -193,7 +193,7 @@ void IntersectionMarkerDrawOverride::addUIDrawables( // cast the user data back to our to our struct const IntersectionMarkerData* markerData = dynamic_cast(data); if (!markerData) { - MGlobal::displayInfo("addUIDrawables: markerData is null"); + // MGlobal::displayInfo("addUIDrawables: markerData is null"); return; } diff --git a/src/intersectionMarkerNode.cpp b/src/intersectionMarkerNode.cpp index 33856e7..16f50ee 100644 --- a/src/intersectionMarkerNode.cpp +++ b/src/intersectionMarkerNode.cpp @@ -218,7 +218,6 @@ MStatus IntersectionMarkerNode::preEvaluation( CHECK_MSTATUS_AND_RETURN_IT(status); if (dirty) { - MGlobal::displayInfo("node Pre Evaluation"); MHWRender::MRenderer::setGeometryDrawDirty(thisMObject()); } } From ab2cf75c6f34b94f0202d7489e155949388b05cc Mon Sep 17 00:00:00 2001 From: yamahigashi Date: Sun, 6 Aug 2023 21:56:39 +0900 Subject: [PATCH 5/5] Updated to work embree bvh kernel vs kernel --- src/kernel/EmbreeKernel.cpp | 76 ++++++++++++++++++++----------------- src/kernel/EmbreeKernel.h | 9 +++-- 2 files changed, 48 insertions(+), 37 deletions(-) diff --git a/src/kernel/EmbreeKernel.cpp b/src/kernel/EmbreeKernel.cpp index 049d432..d1f0214 100644 --- a/src/kernel/EmbreeKernel.cpp +++ b/src/kernel/EmbreeKernel.cpp @@ -145,14 +145,15 @@ MStatus EmbreeKernel::build(const MObject& meshObject, const MBoundingBox& bbox, arguments.byteSize = sizeof(arguments); // arguments.buildFlags = RTC_BUILD_FLAG_NONE; arguments.buildFlags = RTC_BUILD_FLAG_DYNAMIC; - arguments.buildQuality = RTC_BUILD_QUALITY_MEDIUM; + arguments.buildQuality = RTC_BUILD_QUALITY_LOW; + // arguments.buildQuality = RTC_BUILD_QUALITY_MEDIUM; arguments.maxBranchingFactor = 2; arguments.maxDepth = 1024; arguments.sahBlockSize = 1; arguments.minLeafSize = 1; arguments.maxLeafSize = 8; arguments.traversalCost = 1.0f; - arguments.intersectionCost = 1.0f; + arguments.intersectionCost = 2.0f; arguments.bvh = this->bvh; arguments.primitives = primitives.data(); arguments.primitiveCount = primitives.size(); @@ -176,8 +177,7 @@ MStatus EmbreeKernel::build(const MObject& meshObject, const MBoundingBox& bbox, } - -std::vector EmbreeKernel::queryIntersected(const TriangleData& triangle) const +std::vector EmbreeKernel::queryIntersected(const TriangleData& triangleB) const { std::vector intersectingA; @@ -197,40 +197,47 @@ std::vector EmbreeKernel::queryIntersected(const TriangleData& tri MBoundingBox bboxL = currentNode->branch()->bounds[0]; MBoundingBox bboxR = currentNode->branch()->bounds[1]; - if (intersectBoxBox(bboxL, triangle.bbox)) { + if (intersectBoxBox(bboxL, triangleB.bbox)) { stack.push(currentNode->branch()->children[0]); } - if (intersectBoxBox(bboxR, triangle.bbox)) { + if (intersectBoxBox(bboxR, triangleB.bbox)) { stack.push(currentNode->branch()->children[1]); } } if (isALeaf) { - // FIXME: - // Ideally, we should use box-to-box checks for collisions. However, - // due to the occurrence of extremely small boxes, collisions - // might be missed. Therefore, we're opting to skip the check. - // if (!intersectBoxBox(currentNode->leaf()->bounds, triangle.bbox)) { + // While it's possible to determine intersections between bounding boxes and + // decide if they can be skipped, the subsequent code for triangle-to-triangle + // intersection checks is quite similar. Therefore, it might be more efficient + // to leave this task to the triangle-to-triangle intersection checks + // if (!intersectBoxBox(currentNode->leaf()->bounds, triangleB.bbox)) { + // continue; + // } int index = currentNode->leaf()->id; - TriangleData triangleData = this->triangles[index]; - if (intersectTriangleTriangle(triangle, triangleData)) { - intersectingA.push_back(triangleData); + TriangleData triangleA = this->triangles[index]; + if (intersectTriangleTriangle(triangleB, triangleA)) { + intersectingA.push_back(triangleA); } - if (index > 0) { - triangleData = this->triangles[index-1]; - if (intersectTriangleTriangle(triangle, triangleData)) { - intersectingA.push_back(triangleData); - } - } - if (index < this->triangles.size()-1) { - triangleData = this->triangles[index+1]; - if (intersectTriangleTriangle(triangle, triangleData)) { - intersectingA.push_back(triangleData); - } - } + // Depending on the quality of the BVH, overlapping regions might cause + // adjacent faces to be skipped. It's essential to address this issue. + // If this happens, we can check the adjacent triangles as well. + // + // if (index > 0) { + // triangleA = this->triangles[index-1]; + // if (intersectTriangleTriangle(triangleB, triangleA)) { + // intersectingA.push_back(triangleA); + // } + // } + // + // if (index < this->triangles.size()-1) { + // triangleA = this->triangles[index+1]; + // if (intersectTriangleTriangle(triangleB, triangleA)) { + // intersectingA.push_back(triangleA); + // } + // } } }; @@ -311,7 +318,6 @@ K2KIntersection EmbreeKernel::intersectKernelKernel( EmbreeKernel* other = dynamic_cast(&otherKernel); if (!other) { - // MGlobal::displayError("Failed to cast SpatialDivisionKernel to EmbreeKernel"); return std::make_pair(intersectedTrianglesA, intersectedTrianglesB); } @@ -323,13 +329,15 @@ K2KIntersection EmbreeKernel::intersectKernelKernel( Node* nodeB = pair.second; if (nodeA->isLeaf() && nodeB->isLeaf()) { - for (TriangleData triA : nodeA->triangles) { - for (TriangleData triB : nodeB->triangles) { - if (intersectTriangleTriangle(triA, triB)) { - intersectedTrianglesA.push_back(triA); - intersectedTrianglesB.push_back(triB); - } - } + int nodeAId = nodeA->leaf()->id; + int nodeBId = nodeB->leaf()->id; + + TriangleData triA = this->triangles[nodeAId]; + TriangleData triB = other->triangles[nodeBId]; + + if (intersectTriangleTriangle(triA, triB)) { + intersectedTrianglesA.push_back(triA); + intersectedTrianglesB.push_back(triB); } } } diff --git a/src/kernel/EmbreeKernel.h b/src/kernel/EmbreeKernel.h index f314510..96be155 100644 --- a/src/kernel/EmbreeKernel.h +++ b/src/kernel/EmbreeKernel.h @@ -18,7 +18,6 @@ struct InnerNode; struct LeafNode; -using TriangleList = std::vector; struct Node { virtual InnerNode* branch() { return nullptr; } @@ -26,7 +25,6 @@ struct Node virtual bool isLeaf() { return false; } InnerNode* parent() { return nullptr; } - TriangleList triangles; }; @@ -94,8 +92,13 @@ struct LeafNode : public Node assert(numPrims == 1); void* ptr = rtcThreadLocalAlloc(alloc,sizeof(LeafNode),16); // return (void*) new (ptr) LeafNode(prims->primID,*(MBoundingBox*)prims); + MBoundingBox box( + MPoint(prims->lower_x, prims->lower_y, prims->lower_z), + MPoint(prims->upper_x, prims->upper_y, prims->upper_z) + ); - Node *node = new (ptr) LeafNode(prims->primID, *(MBoundingBox*)prims); + Node *node = new (ptr) LeafNode(prims->primID, box); + // Node *node = new (ptr) LeafNode(prims->primID, *(MBoundingBox*)prims); return (void *)node; }