bool octreeSolid::isColidWithBox(octreeSNode* node, Box &b) { GeometricFunc geoF; if (geoF.collisionBtwBox(b, Box(node->leftDownTight, node->rightUpTight))) { if (node->bEnd) { if (geoF.isPointInBox(b.leftDown, b.rightUp, (node->leftDownTight+node->rightUpTight)/2)) { return true; } return false; } else { for (int i = 0; i < 8; i++) { if (node->children[i]) { if (isColidWithBox(node->children[i], b)) { return true; } } } return false; } } else return false; }
void octreeSolid::intersectWithBox(octreeSNode* node, Vec3f &ldf, Vec3f &ruf, arrayInt &idxs) { if (!node) { return; } GeometricFunc geoFc; Box boxNode(node->leftDownTight, node->rightUpTight); if (geoFc.collisionBtwBox(Box(ldf, ruf), boxNode)) { if (node->bEnd && geoFc.isPointInBox(ldf, ruf, boxNode.center)) { // Sine boxIn may slightly cover the node box, we check the center point idxs.push_back(node->idxInLeaf); } else { for (int i = 0; i < 8; i++) { intersectWithBox(node->children[i], ldf, ruf, idxs); } } } }
neighborPos poseManager::possibleNeighbor(meshPiece* parent, meshPiece* child) { // To be neighbor, they should be in contact or there is no other box between them // Best is to check overlap. maximum is the size of voxel GeometricFunc geoF; Vec3f diag(voxelSizef, voxelSizef, voxelSizef); if(geoF.collisionBtwBox(Box(parent->leftDown, parent->rightUp), Box(child->leftDown - diag/2.0, child->rightUp + diag/2.0))) { Vec3f parentLD = parent->leftDown; Vec3f parentRU = parent->rightUp; Vec3f childLD = child->leftDown; Vec3f childRU = child->rightUp; neighborPos *pp = posArray(); float error = 0.001*voxelSizef; for (int xyzd = 0; xyzd < 3; xyzd++) // Test on three direction { // Check if Plus if (childLD[xyzd] > parentRU[xyzd]-error) { return pp[xyzd * 2]; } if (childRU[xyzd] < parentLD[xyzd] + error) { return pp[xyzd * 2 + 1]; } } } return NONE_NB; }
neighborPos poseGroupCutManager::possibleNeighbor(meshPiece* parent, meshPiece* child) { // To be neighbor, they should be in contact or there is no other box between them // Best is to check overlap. maximum is the size of voxel GeometricFunc geoF; Vec3f diag(voxelSizef, voxelSizef, voxelSizef); // Otherwise, use center distance if (geoF.collisionBtwBox(Box(parent->leftDown, parent->rightUp), Box(child->leftDown - diag / 2.0, child->rightUp + diag / 2.0))) { // If have face contact int direct; if (geoF.isBoxFaceContactBox(Box(parent->leftDown, parent->rightUp), Box(child->leftDown, child->rightUp), direct)) { int p = direct*2; if (parent->leftDown[direct] > child->leftDown[direct]) { p++; } return (neighborPos)p; } else { Vec3f pSizef = parent->rightUp - parent->leftDown; Vec3f centerP = (parent->rightUp + parent->leftDown) / 2.0; Vec3f centerC = (child->rightUp + child->leftDown) / 2.0; Vec3f dd = centerC - centerP; // scale float longest = 0; int idx = -1; for (int j = 0; j < 3; j++) { dd[j] = dd[j] / (pSizef[j] / 2.0); if (longest < abs(dd[j])) { longest = abs(dd[j]); idx = j; } } neighborPos *pp = posArray(); if (dd[idx] > 0) return pp[idx * 2]; // plus axis direction else return pp[idx * 2 + 1]; // minus axis direction } } return NONE_NB; }
void octreeSolid::intersectWithBox(octreeSNode* node, Box boxIn, Box &intersectBox, float &volumeSide) { if (!node) return; GeometricFunc geoFc; BOOL isInside; if (geoFc.isBoxInBox(boxIn.leftDown, boxIn.rightUp, node->leftDownTight, node->rightUpTight)) { // Cover entirely. Fit intersect box volumeSide += node->volumef; geoFc.fitBoxToCoverBox(intersectBox, node->leftDownTight, node->rightUpTight); } else { Box boxNode(node->leftDownTight, node->rightUpTight); if(geoFc.collisionBtwBox(boxIn, boxNode)) { if (node->bEnd && geoFc.isPointInBox(boxIn.leftDown, boxIn.rightUp, boxNode.center)) { // Sine boxIn may slightly cover the node box, we check the center point volumeSide += node->volumef; geoFc.fitBoxToCoverBox(intersectBox, node->leftDownTight, node->rightUpTight); } else { for (int i = 0; i < 8; i++) { intersectWithBox(node->children[i], boxIn, intersectBox, volumeSide); } } } } }
void octreeSolid::intersectWithBox(octreeSNode* node, meshPiece &boxOut, meshPiece &boxIn) { if (!node) return; GeometricFunc geoFc; BOOL isInside; if (geoFc.isBoxInBox(boxIn.leftDown, boxIn.rightUp, node->leftDownTight, node->rightUpTight)) { // Cover entirely. Fit intersect box boxOut.volumef += node->volumef; enlargerToCoverBox(boxOut, node->leftDownTight, node->rightUpTight); } else { Box boxNode(node->leftDownTight, node->rightUpTight); if(geoFc.collisionBtwBox(Box(boxIn.leftDown, boxIn.rightUp), boxNode)) { if (node->bEnd && geoFc.isPointInBox(boxIn.leftDown, boxIn.rightUp, boxNode.center)) { // Sine boxIn may slightly cover the node box, we check the center point boxOut.volumef += node->volumef; enlargerToCoverBox(boxOut, node->leftDownTight, node->rightUpTight); } else { for (int i = 0; i < 8; i++) { intersectWithBox(node->children[i], boxOut, boxIn); } } } } }