|
@@ -602,6 +602,9 @@ public:
|
|
|
U32 mNumCollideBoxCalls;
|
|
|
U32 mNumCastRayRenderedCalls;
|
|
|
|
|
|
+ bool mReturnCastRay;
|
|
|
+ RayInfo mRayInfo;
|
|
|
+
|
|
|
bool onAdd()
|
|
|
{
|
|
|
if (Parent::onAdd())
|
|
@@ -611,6 +614,8 @@ public:
|
|
|
mNumBuildPolyListCalls = 0;
|
|
|
mNumCollideBoxCalls = 0;
|
|
|
mNumCastRayRenderedCalls = 0;
|
|
|
+ mReturnCastRay = false;
|
|
|
+ mRayInfo = {};
|
|
|
|
|
|
if (mAddCallback)
|
|
|
mAddCallback();
|
|
@@ -645,12 +650,22 @@ public:
|
|
|
virtual bool castRay(const Point3F& start, const Point3F& end, RayInfo* info)
|
|
|
{
|
|
|
mNumCastRayCalls++;
|
|
|
- return false;
|
|
|
+ if (!mReturnCastRay)
|
|
|
+ return false;
|
|
|
+
|
|
|
+ *info = mRayInfo;
|
|
|
+
|
|
|
+ return true;
|
|
|
}
|
|
|
|
|
|
virtual bool castRayRendered(const Point3F& start, const Point3F& end, RayInfo* info)
|
|
|
{
|
|
|
mNumCastRayRenderedCalls++;
|
|
|
+ if (!mReturnCastRay)
|
|
|
+ return false;
|
|
|
+
|
|
|
+ *info = mRayInfo;
|
|
|
+
|
|
|
return false;
|
|
|
}
|
|
|
|
|
@@ -848,6 +863,82 @@ TEST_F(SceneContainerTest, castRay)
|
|
|
gClientSceneGraph->getContainer()->removeObject(so1);
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+TEST_F(SceneContainerTest, castRay_order)
|
|
|
+{
|
|
|
+ SceneObjectTestVariant* so1 = NULL;
|
|
|
+ SceneObjectTestVariant* so2 = NULL;
|
|
|
+
|
|
|
+ Sim::findObject("SO1", so1);
|
|
|
+ Sim::findObject("SO2", so2);
|
|
|
+
|
|
|
+ MatrixF m(1);
|
|
|
+ m.setPosition(Point3F(0, 0, 0));
|
|
|
+ so1->setTypeMask(MarkerObjectType);
|
|
|
+ so1->setTransform(m);
|
|
|
+ so1->setWorldBox(Box3F(m.getPosition() - Point3F(5, 5, 5), m.getPosition() + Point3F(5,5,5)));
|
|
|
+
|
|
|
+ so2->setTypeMask(MarkerObjectType);
|
|
|
+ so2->setGlobalBounds();
|
|
|
+
|
|
|
+ so1->mReturnCastRay = true;
|
|
|
+ so2->mReturnCastRay = true;
|
|
|
+
|
|
|
+ gClientSceneGraph->getContainer()->addObject(so1);
|
|
|
+ gClientSceneGraph->getContainer()->addObject(so2);
|
|
|
+
|
|
|
+ // Here we need to ensure that so1 or so2 will be picked based on shortest distance
|
|
|
+ RayInfo closeInfo = {};
|
|
|
+ RayInfo farInfo = {};
|
|
|
+
|
|
|
+ closeInfo.t = 5 / 100.0;
|
|
|
+ farInfo.t = 10 / 100.0;
|
|
|
+
|
|
|
+ // so1=far, so2=close
|
|
|
+ {
|
|
|
+ so1->mRayInfo = farInfo;
|
|
|
+ so1->mRayInfo.object = so1;
|
|
|
+ so2->mRayInfo = closeInfo;
|
|
|
+ so2->mRayInfo.object = so2;
|
|
|
+
|
|
|
+ Point3F start(0, 0, 0);
|
|
|
+ Point3F end(0, 0, -100);
|
|
|
+ RayInfo info;
|
|
|
+ bool castCheck = gClientSceneGraph->getContainer()->castRay(start, end, MarkerObjectType, &info);
|
|
|
+
|
|
|
+ EXPECT_EQ(castCheck, true);
|
|
|
+ EXPECT_EQ(so1->mNumCastRayCalls, 1);
|
|
|
+ EXPECT_EQ(so2->mNumCastRayCalls, 1);
|
|
|
+
|
|
|
+ EXPECT_EQ(info.distance, 5);
|
|
|
+ EXPECT_EQ(info.object, so2);
|
|
|
+ }
|
|
|
+
|
|
|
+ // so2=far, so1=close
|
|
|
+ {
|
|
|
+ so2->mRayInfo = farInfo;
|
|
|
+ so2->mRayInfo.object = so2;
|
|
|
+ so1->mRayInfo = closeInfo;
|
|
|
+ so1->mRayInfo.object = so1;
|
|
|
+
|
|
|
+ Point3F start(0, 0, 0);
|
|
|
+ Point3F end(0, 0, -100);
|
|
|
+ RayInfo info;
|
|
|
+ bool castCheck = gClientSceneGraph->getContainer()->castRay(start, end, MarkerObjectType, &info);
|
|
|
+
|
|
|
+ EXPECT_EQ(castCheck, true);
|
|
|
+ EXPECT_EQ(so1->mNumCastRayCalls, 2);
|
|
|
+ EXPECT_EQ(so2->mNumCastRayCalls, 2);
|
|
|
+
|
|
|
+ EXPECT_EQ(info.distance, 5);
|
|
|
+ EXPECT_EQ(info.object, so1);
|
|
|
+ }
|
|
|
+
|
|
|
+ gClientSceneGraph->getContainer()->removeObject(so1);
|
|
|
+ gClientSceneGraph->getContainer()->removeObject(so2);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
TEST_F(SceneContainerTest, castRayRendered)
|
|
|
{
|
|
|
// Basically: only gets called on objects in the right bin
|
|
@@ -1324,8 +1415,15 @@ TEST_F(SceneContainerTest, getBinRange)
|
|
|
U32 minBin = 0;
|
|
|
U32 maxBin = 0;
|
|
|
SceneContainer::getBinRange(0, 0, minBin, maxBin);
|
|
|
+ EXPECT_EQ(minBin == 0 && maxBin == 0, true);
|
|
|
+ SceneContainer::getBinRange(0, SceneContainer::csmBinSize*0.5, minBin, maxBin);
|
|
|
+ EXPECT_EQ(minBin == 0 && maxBin == 0, true);
|
|
|
+ SceneContainer::getBinRange(SceneContainer::csmBinSize * 0.5, SceneContainer::csmBinSize * 0.5, minBin, maxBin);
|
|
|
+ EXPECT_EQ(minBin == 0 && maxBin == 0, true);
|
|
|
SceneContainer::getBinRange(0, SceneContainer::csmBinSize, minBin, maxBin);
|
|
|
EXPECT_EQ(minBin == 0 && maxBin == 1, true);
|
|
|
+ SceneContainer::getBinRange(SceneContainer::csmBinSize * 1.5, SceneContainer::csmBinSize * 1.5, minBin, maxBin);
|
|
|
+ EXPECT_EQ(minBin == 1 && maxBin == 1, true);
|
|
|
SceneContainer::getBinRange(SceneContainer::csmBinSize, SceneContainer::csmBinSize, minBin, maxBin);
|
|
|
EXPECT_EQ(minBin == 1 && maxBin == 1, true);
|
|
|
SceneContainer::getBinRange(SceneContainer::csmBinSize*2, SceneContainer::csmBinSize*2, minBin, maxBin);
|