Creating a trigger that bounds an object
by Brett Fattori · in Torque Game Engine · 08/11/2003 (6:24 pm) · 8 replies
I have created a function based on the WorldEditor::Selection::rotate function in worldEditor.cc. It's so that I can get triggers to bound an object in script. It's almost working, but my math skills aren't up to par I guess. The trigger doesn't bound the object properly, but I know this is what I want to do. Others prolly want this to, so here is what I have:
Now, I had to add the %obj.getWorldTransform method in sceneObject.cc.
Add this function:
If someone knows what I'm doing wrong in the script above, please post the solution. Everyone would benefit from it.
Thanks,
Brett
function createTriggerBounding(%trigName, %obj) {
// Get the bounding box of the object
%boundBox = %obj.getObjectBox();
%maxX = getWord(%boundBox, 3);
%maxY = getWord(%boundBox, 4);
%maxZ = getWord(%boundBox, 5);
// Scale the trigger to the size of the bounding box
%trigWidX = %maxX * 2;
%trigWidY = %maxY * 2;
%trigWidZ = %maxZ * 2;
// Calculate the trigger's position
%trigPosX = -%maxX;
%trigPosY = %maxY;
%trigPosZ = -%maxZ;
%newPos = %trigPosX SPC %trigPosY SPC %trigPosZ;
// Build datablock values
%pos = VectorAdd(%obj.position, %newPos);
%rot = %obj.rotation;
%scale = %trigWidX SPC %trigWidY SPC %trigWidZ;
// Set the polyhedron size
%trigPoly = "0 0 0 1 0 0 0 -1 0 0 0 1";
// Create a trigger
%theTrigger = new Trigger(%trigName) {
position = %pos;
scale = %scale;
dataBlock = "basicTrigger";
polyhedron = %trigPoly;
};
%mat = %theTrigger.getTransform();
%pos = %theTrigger.getPosition();
// get offset in obj space
%offset = VectorSub(%pos, getBoxCenter(%theTrigger.getObjectBox()));
%wMat = %obj.getWorldTransform();
%offset = MatrixMulVector(%wMat,%offset);
// Convoluted way of rotating around center point
%transform = MatrixCreate(VectorScale(%offset,-1),"1 0 0 0");
%transform = MatrixMultiply(%transform,MatrixCreate("0 0 0",%rot));
%transformBack = MatrixCreate(%offset,"1 0 0 0");
%transform = MatrixMultiply(%transform,%transformBack);
%mat = MatrixMultiply(%mat,%transform);
%theTrigger.setTransform(%mat);
return %theTrigger;
}Now, I had to add the %obj.getWorldTransform method in sceneObject.cc.
Add this function:
const char* cGetWorldTransform(SimObject *obj, S32, const char **)
{
char *returnBuffer = Con::getReturnBuffer(256);
SceneObject *ptr = (SceneObject *) obj;
const MatrixF& mat = ptr->getWorldTransform();
Point3F pos;
mat.getColumn(3,&pos);
AngAxisF aa(mat);
dSprintf(returnBuffer,256,"%g %g %g %g %g %g %g",
pos.x,pos.y,pos.z,aa.axis.x,aa.axis.y,aa.axis.z,aa.angle);
return returnBuffer;
}Under the declaration for cGetTransform, then add:Con::addCommand("SceneObject", "getWorldTransform", cGetWorldTransform, "obj.getWorldTransform()", 2, 2);In void SceneObject::consoleInit()...If someone knows what I'm doing wrong in the script above, please post the solution. Everyone would benefit from it.
Thanks,
Brett
#2
12/29/2003 (9:26 am)
Did you find a solution?
#3
12/29/2003 (10:37 am)
He'll have to describe the problem... :)
#4
You're getting the max X,Y,Z, then using double those coordinates for your trigger box.
I STRONGLY SUSPECT (but I don't know, like I said: I'm new) that those coordinates are world coordinates, so if the object's center was at 50,50,0 and was 6 unit's in diameter, then your getWord calls would return 53, 53, 3. Doubling any of those coordinates doesn't give you a useful value.
IF I'm right, then you need to find the object's center, width, height, depth, and double those value around the center.
I would also think that you could use obj.position for the new trigger's position... the trigger should be centered on the object, right?
That's assuming that .position represents the center of the object. Like I said.. me == newbie.
If all else fails, I suggest you dump obj's bounding box and the trigger's bounding box to the console. In fact, start with that and go from there.
12/30/2003 (10:04 am)
I'm far from a torque expert, but let me take a stab at your problem anyway.You're getting the max X,Y,Z, then using double those coordinates for your trigger box.
I STRONGLY SUSPECT (but I don't know, like I said: I'm new) that those coordinates are world coordinates, so if the object's center was at 50,50,0 and was 6 unit's in diameter, then your getWord calls would return 53, 53, 3. Doubling any of those coordinates doesn't give you a useful value.
IF I'm right, then you need to find the object's center, width, height, depth, and double those value around the center.
I would also think that you could use obj.position for the new trigger's position... the trigger should be centered on the object, right?
That's assuming that .position represents the center of the object. Like I said.. me == newbie.
If all else fails, I suggest you dump obj's bounding box and the trigger's bounding box to the console. In fact, start with that and go from there.
#5
This one is still on a backburner to complete one day.
- Brett
01/02/2004 (6:44 am)
Ben: The problem was that the trigger didn't bound the object properly. When you rotated the object, the bounding trigger didn't rotate around the same center point. The actual issue is that the origin of an object is it's center. The origin of a trigger is one of the corners.This one is still on a backburner to complete one day.
- Brett
#7
The trick is setting the polyhedron value as above. Thus, the polyhedron rotates according to its center like the other objects do.
EDIT: I tested it now. Unfortunately, there is a bug about trigger polyhedrons. If you use some value other than the default, the trigger doesn't work. Looking for a solution right now.
01/23/2009 (7:02 am)
Try this:function createTriggerBounding(%trigName,%obj)
{
%objB = %obj.getObjectBox();
%scale = getWord(%objB, 3) - getWord(%objB, 0) SPC
getWord(%objB, 4) - getWord(%objB, 1) SPC
getWord(%objB, 5) - getWord(%objB, 2);
new Trigger(%trigName) {
position = %obj.getWorldBoxCenter();
rotation = %obj.rotation;
scale = %scale;
dataBlock = "BushTrigger";
polyhedron = "-0.5 -0.5 -0.5 1 0 0 0 1 0 0 0 1";
};
}The trick is setting the polyhedron value as above. Thus, the polyhedron rotates according to its center like the other objects do.
EDIT: I tested it now. Unfortunately, there is a bug about trigger polyhedrons. If you use some value other than the default, the trigger doesn't work. Looking for a solution right now.
#8
I changed the polyhedron as above and somehow it works.
01/26/2009 (12:45 am)
I just worked around the problem. Try this:function createTriggerBounding(%trigName,%obj)
{
%objB = %obj.getObjectBox();
%scale = getWord(%objB, 3) - getWord(%objB, 0) SPC
getWord(%objB, 4) - getWord(%objB, 1) SPC
getWord(%objB, 5) - getWord(%objB, 2);
new Trigger(%trigName) {
position = %obj.getWorldBoxCenter();
rotation = %obj.rotation;
scale = %scale;
dataBlock = "BushTrigger";
polyhedron = "-0.5 0.5 -0.5 1 0 0 0 -1 0 0 0 1";
};
}I changed the polyhedron as above and somehow it works.
Torque Owner Brett Fattori