diff --git a/ray.cpp b/ray.cpp index 5030b5d..6e98d4e 100644 --- a/ray.cpp +++ b/ray.cpp @@ -7,16 +7,32 @@ using namespace std; namespace vb01{ - void Ray::retrieveCollisions(Vector3 rayPos, Vector3 rayDir, Node *node, std::vector &results, const float rayLength){ - castRay(rayPos, rayDir, node, results, rayLength); - - for(Node *c : node->getChildren()) - retrieveCollisions(rayPos, rayDir, c, results, rayLength); + vector RayCaster::cast(Vector3 rayPos, Vector3 rayDir, Node *node, const float rayLength){ + return cast(rayPos, rayDir, vector{node}, rayLength); } - void Ray::castRay(Vector3 rayPos, Vector3 rayDir, Node *node, vector &results, float rayLength){ + vector RayCaster::cast(Vector3 rayPos, Vector3 rayDir, vector nodes, const float rayLength){ + vector results; + + for(Node *node : nodes){ + vector descendants = vector{node}; + node->getDescendants(descendants); + + for(Node *desc : descendants){ + vector res = retrieveCollisions(rayPos, rayDir, desc, rayLength); + results.insert(results.end(), res.begin(), res.end()); + } + } + + if(!results.empty()) sortResults(results); + + return results; + } + + vector RayCaster::retrieveCollisions(Vector3 rayPos, Vector3 rayDir, Node *node, float rayLength){ Vector3 pos = node->localToGlobalPosition(Vector3::VEC_ZERO); Quaternion rot = node->localToGlobalOrientation(Quaternion::QUAT_W); + vector results; for(Mesh *m : node->getMeshes()){ const int numVerts = m->getMeshBase().numTris * 3; @@ -64,14 +80,15 @@ namespace vb01{ } } } + + return results; } - void Ray::sortResults(std::vector &results){ - if(!results.empty()) - for(int i = 0; i < results.size(); i++){ - for(int i2 = i; i2 < results.size(); i2++) - if(results[i].distance > results[i2].distance) - swap(results[i], results[i2]); - } + void RayCaster::sortResults(std::vector &results){ + for(int i = 0; i < results.size(); i++){ + for(int j = i; j < results.size(); j++) + if(results[i].distance > results[j].distance) + swap(results[i], results[j]); + } } } diff --git a/ray.h b/ray.h index 5c7d40b..2e8deb8 100644 --- a/ray.h +++ b/ray.h @@ -7,15 +7,18 @@ namespace vb01{ class Node; class Mesh; - class Ray{ + class RayCaster{ public: struct CollisionResult{ Vector3 pos, norm; float distance; Mesh *mesh = nullptr; }; - static void retrieveCollisions(Vector3, Vector3, Node*, std::vector&, const float = .0); - static void castRay(Vector3, Vector3, Node*, std::vector&, const float); + + static std::vector cast(Vector3, Vector3, Node*, const float = .0); + static std::vector cast(Vector3, Vector3, std::vector, const float = .0); + private: + static std::vector retrieveCollisions(Vector3, Vector3, Node*, const float); static void sortResults(std::vector&); }; diff --git a/raySample.cpp b/raySample.cpp index 536258e..d8b5ae9 100644 --- a/raySample.cpp +++ b/raySample.cpp @@ -76,11 +76,9 @@ int main(){ * Casts an infinite ray that checks for collision against meshes under * the icoshpere model node and paints it red upon collision */ - vector results; - Ray::retrieveCollisions(rayStart, rayEnd - rayStart, sphModel, results); - Ray::sortResults(results); mat->setVec4Uniform("diffuseColor", Vector4::VEC_L); + vector results = RayCaster::cast(rayStart, rayEnd - rayStart, sphModel); if(!results.empty()) mat->setVec4Uniform("diffuseColor", Vector4(1, 0, 0, 1));