WorldEditor object collision while moving
by Dave Young · in Torque Game Engine · 06/25/2008 (11:25 am) · 10 replies
I'm looking for a way to make sure an object will collide with an interior while I'm moving it in the World Editor. This is to ensure that I cannot move it underneath the floor or through a wall. I've tried a few different ways but can't get a selected object to collide with anything while dragging it around, even when I make sure collision is enabled on it. Anyone have any thoughts on a good approach?
#2
06/25/2008 (11:39 am)
It's not *that* useless, I thought of something that might work. Checkdismountpoint does a similar thing by doing a raycast between old and new positions to see if there is something in the way. WorldEditor uses a function to set the transform, so its the perfect place to do a similar check. I'll see how it works out.
#3
06/25/2008 (11:45 am)
Woot!! It worked unbelievably well!! When this modified version of the offset() function is in, I can drag an object around inside an interior and it collides precisely with the walls and floors. It adds the collision check in the middle and exits out. You could get fancy and continue instead of returning, to allow the rest of the objects in the selection a shot at moving.void WorldEditor::Selection::offset(const Point3F & offset)
{
for(U32 i = 0; i < mObjectList.size(); i++)
{
MatrixF mat = ((SceneObject*)mObjectList[i])->getTransform();
Point3F wPos;
Point3F nPos; //our test point
mat.getColumn(3, &wPos);
nPos = wPos;
nPos += offset;
RayInfo info;
disableCollision();
//Check to see if it collides with an interior. If so, dont let it move to the new position
if(gServerContainer.castRay(wPos, nPos, InteriorObjectType, &info))
{
enableCollision();
return;
}
// adjust
wPos += offset;
mat.setColumn(3, wPos);
((SceneObject*)mObjectList[i])->setTransform(mat);
}
mCentroidValid = false;
}
#4
06/25/2008 (12:46 pm)
This code could be used to form the basis of a series of "snap to" options in the world editor. There are many times when a designer wants something right on the terrain, or right on the floor of an interior, and they have to do a bunch of work (changing their view etc) to get that object exactly where they want it. With this they could just tick a box saying "snap to ground" then just drag it down "for a mile" and know that the object will stop when it hits the terrain. Good stuff.
#5
06/25/2008 (1:54 pm)
Doesn't TGEA 1.7.x already have a snap-to-ground function in the world editor?
#6
we're experimenting with a method like this for our in-game furniture positioning in vSide.
eg, cast a ray, and use the collision point and normal to automatically position & orient the object being moved.
06/25/2008 (2:13 pm)
> There are many times when a designer wants something right on the terrain, or right on the floor of an interiorwe're experimenting with a method like this for our in-game furniture positioning in vSide.
eg, cast a ray, and use the collision point and normal to automatically position & orient the object being moved.
#7
There is a drop to ground feature in TGE also, but it doesn't seem to work very well and seems to depend on the collision box or object origin. So far this works well, with an exception of letting the object sink into a wall up to their origin point. That's desirable behavior for my purposes anyway.
I was able to also let the group continue even if one object collided, which lets me drag a group and they all align appropriately against the wall/ground.
I also added a global flag as the collision mask (good idea Mark!) which enables/disables and specifies the objects which will block the movement. Here's an updated version:
In game.cc's GameInit() I added:
Con::addVariable( "$EditorMovementCollisionMask", TypeS32, &gEditorMovementCollisionMask);
and under the includes:
static S32 gEditorMovementCollisionMask = 0;
Then to toggle it all I use: $EditorMovementCollisionMask = 0; and $EditorMovementCollisionMask = $TypeMasks::InteriorObjectType;
respectively.
06/25/2008 (2:16 pm)
Orion, that's the similar purpose here actually.There is a drop to ground feature in TGE also, but it doesn't seem to work very well and seems to depend on the collision box or object origin. So far this works well, with an exception of letting the object sink into a wall up to their origin point. That's desirable behavior for my purposes anyway.
I was able to also let the group continue even if one object collided, which lets me drag a group and they all align appropriately against the wall/ground.
I also added a global flag as the collision mask (good idea Mark!) which enables/disables and specifies the objects which will block the movement. Here's an updated version:
void WorldEditor::Selection::offset(const Point3F & offset)
{
for(U32 i = 0; i < mObjectList.size(); i++)
{
MatrixF mat = ((SceneObject*)mObjectList[i])->getTransform();
Point3F wPos;
Point3F nPos;
Point3F hitPoint;
mat.getColumn(3, &wPos);
nPos = wPos;
nPos += offset;
RayInfo info;
hitPoint = offset;
S32 colMask = Con::getIntVariable("$EditorMovementCollisionMask");
if(colMask)
{
if(gServerContainer.castRay(wPos, nPos, colMask, &info))
{
hitPoint = info.point;
continue;
}
}
}
// adjust
wPos += hitPoint;
mat.setColumn(3, wPos);
((SceneObject*)mObjectList[i])->setTransform(mat);
}
mCentroidValid = false;
}In game.cc's GameInit() I added:
Con::addVariable( "$EditorMovementCollisionMask", TypeS32, &gEditorMovementCollisionMask);
and under the includes:
static S32 gEditorMovementCollisionMask = 0;
Then to toggle it all I use: $EditorMovementCollisionMask = 0; and $EditorMovementCollisionMask = $TypeMasks::InteriorObjectType;
respectively.
#8
06/25/2008 (2:21 pm)
Is there any noticable speed difference while editing?
#9
06/25/2008 (3:13 pm)
Nope.
#10
06/25/2008 (3:51 pm)
Sweet, it's going in right now.
Torque Owner Nathan Kent
*End of Useless Thought*