mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-02-12 19:31:41 +00:00
Improve ray intersection tests
This commit is contained in:
parent
568f889dbc
commit
6605ddc66a
1 changed files with 99 additions and 1 deletions
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue