Page 1 of 1

Trigger Class

Posted: Fri Mar 30, 2007 2:21 am
by franklyn
hey guys i've created a small trigger class for my game. it basicaly works by finding the distance between the player and the trigger and comparing the value to a certain radius. when the player is within the radius a user defined function is called.
heres what it looks like.

Code: Select all

Trigger.h

#if !defined(AFX_TRIGGER_H__C34EFEF3_49CB_4A1F_A5E6_710CF9E38969__INCLUDED_)
#define AFX_TRIGGER_H__C34EFEF3_49CB_4A1F_A5E6_710CF9E38969__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif
class Trigger
{
vector3df pos;
ISceneNode* node;
float dist;
void (* callback)();
public:
	Trigger (vector3df,ISceneNode*,float,void(*)());
void eval();
};
#endif 

Code: Select all

Trigger.cpp

#include "stdafx.h"
#include "Trigger.h"
Trigger::Trigger(vector3df NodePosition, ISceneNode* CameraNode,float Distance,void(*CallBackFunction)())
{
pos=NodePosition;
node=CameraNode;
dist=Distance;
callback=*CallBackFunction;
}

void Trigger::eval()
{
	if((pos.getDistanceFrom(node->getPosition()))<=dist)
{
		(*callback)();
}

}
and here is how i use it.

Code: Select all

	Trigger *r;

	r=new Trigger(vector3df (0,5,0),Game.FPSCam,100,&shoot);
/*The first parameter is the trigger position , the second is a node that you want to check , the third is the radius and the last parameter is the address to a function.*/
	while(Game.device->run())
	{
		r->eval();

		Game.MainLoop();
		
	}
as you can see it just evaluates the IF statement for every cycle of the loop. i was wondering if this was the most efficient way of going about this as i'd imagine it would get quite slow if i had an array of triggers and had to use a for loop to check all of them.

Posted: Fri Mar 30, 2007 9:33 pm
by franklyn
anyone ?

Posted: Fri Mar 30, 2007 10:47 pm
by buhatkj
should be fast enough. i guess maybe if you are going to have a lot of triggers (i mean a LOT) maybe you could speed it up by using the bounding box of the trigger instead of using a radius.

Posted: Fri Mar 30, 2007 11:22 pm
by vitek
Doing a bounding box test would be slower than doing a bounding sphere test. The code could be optimized a bit to avoid an unnecessary sqrt call by using getDistanceSquared() and storing the radius squared. Also, it might be a good idea to use getAbsolutePosition() instead of getPosition in case the node in question is a child of some other node that is not at the origin.

Since you are keeping a pointer to a scene node in your trigger, you should probably grab the scene node in the constructor and drop it in the destructor. If you don't do this and the scene node is destroyed, you'll get a crash when eval() is called the next time.

As the code is right now, when the node is within the bounding sphere of the trigger, the trigger will repeatedly execute. You might not want to repeatedly invoke the trigger in this case. You might keep a flag that indicates the previous node state [either inside or outside the bounds]. If the node was outside and is now inside you could invoke the trigger.

You might also not want to specify the node in the constructor and instead pass it to the eval function. This way you can test multiple nodes against the same trigger without having to create many triggers that are virutally the same. Of course that conflicts with my last suggestion, but I'm just throwing out ideas.

Another thing you could do would be to make trigger able to call member functions. It is a nice extension sometimes, but not really necessary most of the time.

Also, I believe that the callback assignment line is incorrect...

Code: Select all

//callback=*CallBackFunction; // wrong
callback = CallBackFunction; // right
Travis

Posted: Sat Mar 31, 2007 12:07 am
by franklyn
thanks a LOT for the sugestions vitek im definitely going to implement some of the fixes you mentioned. this is going to be the base class for an entity parser im going to create so that i can have triggers for doors,fire and other entities that react to the player.

Posted: Mon Apr 02, 2007 5:52 pm
by stodge
Maybe you need two callbacks:

onEnterTrigger
onExitTrigger