mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-13 23:54:35 +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 mNumCollideBoxCalls;
|
||||||
U32 mNumCastRayRenderedCalls;
|
U32 mNumCastRayRenderedCalls;
|
||||||
|
|
||||||
|
bool mReturnCastRay;
|
||||||
|
RayInfo mRayInfo;
|
||||||
|
|
||||||
bool onAdd()
|
bool onAdd()
|
||||||
{
|
{
|
||||||
if (Parent::onAdd())
|
if (Parent::onAdd())
|
||||||
|
|
@ -611,6 +614,8 @@ public:
|
||||||
mNumBuildPolyListCalls = 0;
|
mNumBuildPolyListCalls = 0;
|
||||||
mNumCollideBoxCalls = 0;
|
mNumCollideBoxCalls = 0;
|
||||||
mNumCastRayRenderedCalls = 0;
|
mNumCastRayRenderedCalls = 0;
|
||||||
|
mReturnCastRay = false;
|
||||||
|
mRayInfo = {};
|
||||||
|
|
||||||
if (mAddCallback)
|
if (mAddCallback)
|
||||||
mAddCallback();
|
mAddCallback();
|
||||||
|
|
@ -645,12 +650,22 @@ public:
|
||||||
virtual bool castRay(const Point3F& start, const Point3F& end, RayInfo* info)
|
virtual bool castRay(const Point3F& start, const Point3F& end, RayInfo* info)
|
||||||
{
|
{
|
||||||
mNumCastRayCalls++;
|
mNumCastRayCalls++;
|
||||||
return false;
|
if (!mReturnCastRay)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
*info = mRayInfo;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool castRayRendered(const Point3F& start, const Point3F& end, RayInfo* info)
|
virtual bool castRayRendered(const Point3F& start, const Point3F& end, RayInfo* info)
|
||||||
{
|
{
|
||||||
mNumCastRayRenderedCalls++;
|
mNumCastRayRenderedCalls++;
|
||||||
|
if (!mReturnCastRay)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
*info = mRayInfo;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -848,6 +863,82 @@ TEST_F(SceneContainerTest, castRay)
|
||||||
gClientSceneGraph->getContainer()->removeObject(so1);
|
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)
|
TEST_F(SceneContainerTest, castRayRendered)
|
||||||
{
|
{
|
||||||
// Basically: only gets called on objects in the right bin
|
// Basically: only gets called on objects in the right bin
|
||||||
|
|
@ -1324,8 +1415,15 @@ TEST_F(SceneContainerTest, getBinRange)
|
||||||
U32 minBin = 0;
|
U32 minBin = 0;
|
||||||
U32 maxBin = 0;
|
U32 maxBin = 0;
|
||||||
SceneContainer::getBinRange(0, 0, minBin, maxBin);
|
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);
|
SceneContainer::getBinRange(0, SceneContainer::csmBinSize, minBin, maxBin);
|
||||||
EXPECT_EQ(minBin == 0 && maxBin == 1, true);
|
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);
|
SceneContainer::getBinRange(SceneContainer::csmBinSize, SceneContainer::csmBinSize, minBin, maxBin);
|
||||||
EXPECT_EQ(minBin == 1 && maxBin == 1, true);
|
EXPECT_EQ(minBin == 1 && maxBin == 1, true);
|
||||||
SceneContainer::getBinRange(SceneContainer::csmBinSize*2, SceneContainer::csmBinSize*2, minBin, maxBin);
|
SceneContainer::getBinRange(SceneContainer::csmBinSize*2, SceneContainer::csmBinSize*2, minBin, maxBin);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue