All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
CollisionBvhRayCaster.h
1 // Copyright eeGeo Ltd (2012-2014), All Rights Reserved
2 
3 #pragma once
4 
5 #include "Collision.h"
6 #include "VectorMath.h"
7 #include "RayCasterResult.h"
8 #include "CollisionBvh.h"
9 #include "CollisionBvhIntersectionQueries.h"
10 #include "RayCasterFirstIntersectionBuilder.h"
11 
12 #include <vector>
13 #include <algorithm>
14 #include <iterator>
15 
16 namespace Eegeo
17 {
18  namespace Collision
19  {
20  template <typename TCollisionBvhContainer, typename TRayNodeIntersectionResults >
22  {
23  public:
24  typedef typename TCollisionBvhContainer::const_iterator TCollisionBvhIter;
25 
26  CollisionBvhRayCaster(const TCollisionBvhContainer& collisionBvhs,
27  TRayNodeIntersectionResults& rayNodeIntersectionsScratch,
28  std::function<SkewedRay(const v3&, const v3&, const dv3&, const float)> rayToWorldSpaceTransform,
29  const IVerifyRaycastResultDelegate& intersectionValidator)
30  : m_collisionBvhs(collisionBvhs)
31  , m_rayNodeIntersectionsScratch(rayNodeIntersectionsScratch)
32  , m_rayUnflatteningOperation(rayToWorldSpaceTransform)
33  , m_intersectionValidator(intersectionValidator)
34  {}
35 
36  inline RayCasterResult FindFirstRayIntersection(const float environmentFlatteningScale, const Eegeo::dv3& rayOrigin, const Eegeo::dv3& rayDirection) const;
37 
38  private:
39  const TCollisionBvhContainer& m_collisionBvhs;
40  TRayNodeIntersectionResults& m_rayNodeIntersectionsScratch;
41  std::function<SkewedRay(const v3&, const v3&, const dv3&, const float)> m_rayUnflatteningOperation;
42  const IVerifyRaycastResultDelegate& m_intersectionValidator;
43  };
44 
45  namespace
46  {
47  inline bool RayNodeIntersectionResultSortByT(const Eegeo::Collision::RayNodeIntersectionResult& _a, const Eegeo::Collision::RayNodeIntersectionResult& _b)
48  {
49  return _a.IntersectionParam() < _b.IntersectionParam();
50  }
51 
52  template <typename TCollisionBvhIter, typename TOutIter>
53  TOutIter GatherLeafNodesIntersectingRay(
54  std::function<SkewedRay(const v3&, const v3&, const dv3&, const float)> rayUnflatteningOperation,
55  const float environmentFlatteningScale,
56  const Eegeo::dv3& rayOrigin,
57  const Eegeo::v3& rayDirection,
58  TCollisionBvhIter first,
59  TCollisionBvhIter last,
60  TOutIter outIter)
61  {
62  for (TCollisionBvhIter iter = first; iter != last; ++iter)
63  {
64  const Eegeo::Collision::CollisionBvh& collisionBvh = **iter;
65 
66  v3 meshRelativeRayOrigin = (rayOrigin - collisionBvh.OriginEcef()).ToSingle();
67 
68  const SkewedRay& skewedRay = rayUnflatteningOperation(meshRelativeRayOrigin, rayDirection, collisionBvh.OriginEcef(), environmentFlatteningScale);
69 
70  GetLeafNodesIntersectingSkewedRay(collisionBvh, skewedRay, outIter);
71  }
72  return outIter;
73  }
74  }
75 
76  template <typename TCollisionBvhContainer, typename TRayNodeIntersectionResults>
77  inline RayCasterResult
78  CollisionBvhRayCaster<TCollisionBvhContainer, TRayNodeIntersectionResults>::FindFirstRayIntersection(
79  const float environmentFlatteningScale, const Eegeo::dv3& rayOrigin, const Eegeo::dv3& rayDirection) const
80  {
81  m_rayNodeIntersectionsScratch.clear();
82  GatherLeafNodesIntersectingRay(m_rayUnflatteningOperation, environmentFlatteningScale, rayOrigin, rayDirection.ToSingle(), m_collisionBvhs.begin(), m_collisionBvhs.end(), std::back_inserter(m_rayNodeIntersectionsScratch));
83 
84  std::sort(m_rayNodeIntersectionsScratch.begin(), m_rayNodeIntersectionsScratch.end(), RayNodeIntersectionResultSortByT);
85 
86  RayCasterFirstIntersectionBuilder firstIntersectionBuilder(rayOrigin, rayDirection, environmentFlatteningScale, m_intersectionValidator);
87 
88  for (const auto& intersection : m_rayNodeIntersectionsScratch)
89  {
90  bool shouldContinue = firstIntersectionBuilder(intersection);
91  if (!shouldContinue)
92  {
93  break;
94  }
95  }
96 
97  return firstIntersectionBuilder.BuildResult();
98  }
99  }
100 }