Triggers and Shapes
by Ken Finney · in Torque Game Engine · 06/13/2002 (10:14 pm) · 8 replies
Much to my chagrin, I've discovered that that Item shapes don't activate triggers like players do. Does anyone know which needs to be modified, the trigger code, or the Items ?
I can get the item to bounce on top of the polyhedron and other things, but the OnEnterTrigger doesn't fire.
example:
I can get the item to bounce on top of the polyhedron and other things, but the OnEnterTrigger doesn't fire.
example:
datablock TriggerData(GoalTrigger)
{
tickPeriodMS = 100;
};
//-----------------------------------------------------------------------------
function GoalTrigger::onEnterTrigger(%this,%trigger,%obj)
{
if (!strstr( %trigger.getName(),"home") ) // is the home team's net ?
{
messageAll('MsgGoalScored','VISITING TEAM SCORES !!!');
}
else if (!strstr( %trigger.getName(),"visit") ) // is the visiting team's net ?
{
messageAll('MsgGoalScored','HOME TEAM SCORES !!!');
}
Parent::onEnterTrigger(%this,%trigger,%obj);
}About the author
#2
06/14/2002 (10:05 am)
This is similar to the problem I encountered with bots. However, I was under the impression that AIPlayers derived actions from the player class. Is this true? I can't get bots to trigger events.
#3
11/16/2002 (3:24 am)
I too would like item shapes to activate triggers. I have already copied the following code from player.cc to item.cc:Item::updatePos, block "Normal Contact"
if (isServerObject() && (typeMask & TriggerObjectType))
{
Trigger* pTrigger = static_cast<Trigger*>(rinfo.object);
pTrigger->potentialEnterObject(this);
}But that didn't help so far. Has anybody got items to collide with triggers yet?
#4
The sServerCollisionMask should contain TriggerObjectType so the trigger objects are collected during updateWorkingCollisionSet.
Then trigger activation code like the one above needs to be added to Item::updatePos but later in the function during the tough collision check while processing the working list from mConvex.
All other mask checks in Item::updatePos (those used for actual movement) should be excluding TriggerObjectType (like sCollisionMoveMask in player.cc) so that the items don't bounce off the invisible trigger (in which case they might not even trigger it).
All done, now you can throw stuff to activate triggers.
11/16/2002 (1:58 pm)
Ok, I got it to work. The sServerCollisionMask should contain TriggerObjectType so the trigger objects are collected during updateWorkingCollisionSet.
Then trigger activation code like the one above needs to be added to Item::updatePos but later in the function during the tough collision check while processing the working list from mConvex.
All other mask checks in Item::updatePos (those used for actual movement) should be excluding TriggerObjectType (like sCollisionMoveMask in player.cc) so that the items don't bounce off the invisible trigger (in which case they might not even trigger it).
All done, now you can throw stuff to activate triggers.
#5
I'm glad i found this resource because I really needed it, so to help everyone out I offer this:
Here is what I did exactly as instructed by Matthes above:
added/changed code is in bold
in item.cc
05/25/2005 (6:21 pm)
Thank the lord!~I'm glad i found this resource because I really needed it, so to help everyone out I offer this:
Here is what I did exactly as instructed by Matthes above:
added/changed code is in bold
in item.cc
...
#include "collision/extrudedPolyList.h"
#include "math/mathIO.h"
[b]#include "game/trigger.h"[/b]
...
const U32 sClientCollisionMask = (TerrainObjectType | InteriorObjectType |
StaticShapeObjectType | VehicleObjectType |
PlayerObjectType | StaticTSObjectType);
const U32 sServerCollisionMask = (sClientCollisionMask | [b]TriggerObjectType[/b]);
const S32 Item::csmAtRestTimer = 64;
...
void Item::updatePos(const U32 /*mask*/, const F32 dt)
{
// Try and move
Point3F pos;
mObjToWorld.getColumn(3,&pos);
delta.posVec = pos;
...
if (doToughCollision)
{
U32 count;
for (count = 0; count < 3; count++)
{
// Build list from convex states here...
end = pos + mVelocity * time;
collisionMatrix.setColumn(3, end);
Box3F wBox = getObjBox();
collisionMatrix.mul(wBox);
Box3F testBox = wBox;
Point3F oldMin = testBox.min;
Point3F oldMax = testBox.max;
testBox.min.setMin(oldMin + (mVelocity * time));
testBox.max.setMin(oldMax + (mVelocity * time));
sEarlyOutPolyList.clear();
sEarlyOutPolyList.mNormal.set(0,0,0);
sEarlyOutPolyList.mPlaneList.setSize(6);
sEarlyOutPolyList.mPlaneList[0].set(wBox.min,VectorF(-1,0,0));
sEarlyOutPolyList.mPlaneList[1].set(wBox.max,VectorF(0,1,0));
sEarlyOutPolyList.mPlaneList[2].set(wBox.max,VectorF(1,0,0));
sEarlyOutPolyList.mPlaneList[3].set(wBox.min,VectorF(0,-1,0));
sEarlyOutPolyList.mPlaneList[4].set(wBox.min,VectorF(0,0,-1));
sEarlyOutPolyList.mPlaneList[5].set(wBox.max,VectorF(0,0,1));
CollisionWorkingList& eorList = mConvex.getWorkingList();
CollisionWorkingList* eopList = eorList.wLink.mNext;
while (eopList != &eorList) {
[b] if (eopList->mConvex->getObject()->getType() & TriggerObjectType) {
Trigger* pTrigger = static_cast<Trigger*>(eopList->mConvex->getObject());
pTrigger->potentialEnterObject(this);
}
[/b]
if ((eopList->mConvex->getObject()->getType() & [b] sClientCollisionMask [/b] ) != 0)
{
Box3F convexBox = eopList->mConvex->getBoundingBox();
if (testBox.isOverlapped(convexBox))
{
eopList->mConvex->getPolyList(&sEarlyOutPolyList);
if (sEarlyOutPolyList.isEmpty() == false)
break;
}
}
eopList = eopList->wLink.mNext;
}
if (sEarlyOutPolyList.isEmpty())
{
pos = end;
break;
}
collisionMatrix.setColumn(3, pos);
sBoxPolyhedron.buildBox(collisionMatrix, mObjBox);
// Build extruded polyList...
VectorF vector = end - pos;
sExtrudedPolyList.extrude(sBoxPolyhedron, vector);
sExtrudedPolyList.setVelocity(mVelocity);
sExtrudedPolyList.setCollisionList(&collisionList);
CollisionWorkingList& rList = mConvex.getWorkingList();
CollisionWorkingList* pList = rList.wLink.mNext;
while (pList != &rList) {
if ((pList->mConvex->getObject()->getType() & [b]sClientCollisionMask[/b]) != 0)
{
Box3F convexBox = pList->mConvex->getBoundingBox();
if (testBox.isOverlapped(convexBox))
{
pList->mConvex->getPolyList(&sExtrudedPolyList);
}
}
pList = pList->wLink.mNext;
}
...
#6
Trigger* pTrigger = static_cast(rinfo.object);
pTrigger->potentialEnterObject(this);
Approach this the right way and you can actually remove a few dozen lines of code instead of putting them in.
05/26/2005 (8:59 pm)
The ultimate solution to this problem lies right here in these lines of code. Trigger* pTrigger = static_cast
pTrigger->potentialEnterObject(this);
Approach this the right way and you can actually remove a few dozen lines of code instead of putting them in.
#7
In the section of UpdatePos that begins with the comment:
if (!(rinfo.object->getType() & TriggerObjectType))
It looks like this in my code:
Failing to do this, your item may actually collide with and have its motion stopped by the mean ol' trigger volume.
07/09/2006 (3:23 pm)
One additional modification:In the section of UpdatePos that begins with the comment:
// Subtract out velocity into surface and frictionYou need to enclose it with an if clause checking to make sure it is not a trigger object
if (!(rinfo.object->getType() & TriggerObjectType))
It looks like this in my code:
if (!(rinfo.object->getType() & TriggerObjectType))
{
// Subtract out velocity into surface and friction
VectorF fv = mVelocity + rinfo.normal * bd;
F32 fvl = fv.len();
if (fvl)
{
F32 ff = bd * mDataBlock->friction;
if (ff < fvl)
{
fv *= ff / fvl;
fvl = ff;
}
}
bd *= 1 + mDataBlock->elasticity;
VectorF dv = rinfo.normal * (bd + 0.002);
mVelocity += dv;
mVelocity -= fv;
// Keep track of what we hit
contact = true;
U32 typeMask = rinfo.object->getTypeMask();
if (!(typeMask & StaticObjectType))
nonStatic = true;
if (isServerObject() && (typeMask & ShapeBaseObjectType))
{
ShapeBase* col = static_cast<ShapeBase*>(rinfo.object);
queueCollision(col,mVelocity - col->getVelocity());
}
}
}Failing to do this, your item may actually collide with and have its motion stopped by the mean ol' trigger volume.
#8
11/02/2006 (9:21 pm)
Shouldn't rinfo.object be collision->object instead? :)
Torque 3D Owner Joel Baxter
Item does (like Player) include TriggerObjectType objects in its collision working list, but (unlike Player) does not ever do anything with them.