Page 3 of 3

### Re: Suggestions how best to do this...

Posted: Sat Aug 27, 2016 10:38 am
@ TorqueFan Thanks for all the detail. It has given me some ideas and plenty to think about.
So it will continue to 'listen' but it won't execute the raycast search code unless the player object is within the bounds of the trigger.
My understanding that the trigger itself works by doing a raycast of the trigger area??
Looking at this would it not depend on how many items the player can interact with vs how many players there are? If you have 1 player with say a 100 doors then you only have one raycast doing it from the player vs 100 doing it from trigger events?

### Re: Suggestions how best to do this...

Posted: Sat Aug 27, 2016 5:51 pm
@ flysouth : That's a very good question, but likewise there is good news in return. I just cracked open some of the source code to be sure we are on the right page and uncovered just a tad more detail about Triggers.

mObjects
The first thing to understand is the Trigger class itself keeps track of a list of objects within its bounds, called mObjects. The important thing for us to figure out is exactly how the list of objects is updated. Luckily the Trigger itself is not constantly performing searches within its entire area even when there are no players inside. There is a function in the trigger.cpp file that will get the information from the GameBase object that hits the Trigger. The relevant function is potentialEnterObject(GameBase* enter). One good thing about it is it already takes care of client/server side stuff!

In trigger.cpp :

Code: Select all

void Trigger::potentialEnterObject(GameBase* enter) { ... }
This means that the Player object determines when there is a collision with a Trigger or not. The best part?? The Player already performs this check by default right now, so every test you've ever run already had the Player object searching for Triggers while moving. This is found in the player.cpp file in the findContact() function. Here's the relevant bit:

In player.cpp :

Code: Select all

void Player::findContact( bool *run, bool *jump, VectorF *contactNormal ) { ... if (objectMask & TriggerObjectType) { Trigger* pTrigger = static_cast<Trigger*>( obj ); pTrigger->potentialEnterObject(this); } ... } 
What this is doing is it is determining if the contact object is a Trigger or not. Then if it is it's 'getting ahold' of the Trigger object by creating a pointer. Lastly it uses that pointer to tell the Trigger object that there now is indeed a GameBase object that is within its bounds - a Player no less! The Trigger will test that object again( in the potentialEnterObject() ) function I posted above) and if it meets the criteria it will accept that there is a GameBase object within its bounds.

Now that the Trigger object is equipped with a proper GameBase object to add to its mObjects list it can finally begin to execute any of its code. As you can see, the Trigger really does pretty much sit around idle and do nothing at all until there are GameBase objects within its bounds and on its list!

I hope this helps further, tbh I learned a tad bit more about the contact code myself! Good luck, happy Torquing!

Notes:
Note that you still have to weigh for your game what's the biggest hit. The usefulness of one method or another will vary based on number of doors vs. number of players and so on. All of what I've described here is for the greater good of actually answering the question, "How best to do this?", although by now it should be clear that "best" is specific to the implementation. To truly get the answer I'd suggest giving either way a shot and profiling the results to find out exactly what's more efficient. Personally I usually design/develop classes and objects with multiplayer in mind at all times, so I tend to use approaches that can 'handle' high traffic scenarios.

### Re: Suggestions how best to do this...

Posted: Sat Aug 27, 2016 9:18 pm
I found this information, which is the approach I would probably use:

So you could add a collision shape in the model file that encompasses the area where you'd want the GUI popup to appear. The player hits that area, popup the GUI. If they confirm to open the door, setMeshHidden() on the collision shapes and animate the door.

This looks like the most elegant solution, although I hadn't scripted any of it to test. Long ago I did something similar with a garage door and it did indeed animate/kill the collision.

### Re: Suggestions how best to do this...

Posted: Sat Aug 27, 2016 10:41 pm
mmm interesting. I went to the page where Konrad Kiss writes about using collisions and just a bit further down Bryan Sawler makes this statement
A ray-cast will be, in most cases quicker, and any kind of complex object (convex hulls and up) generally use multiple ray-casts in their collision determination
So we are back to racasts lol.

But in your look at the code it appears if the player is constantly doing a raycasts to see if it collides with a trigger for example. If this is the case using the trigger might be better because you can take advantage of something that is happening already, It does make you wonder if you use script to do a player raycast does it just use the data that is already being gathered by the ray cast that the player is always doing?

### Re: Suggestions how best to do this...

Posted: Sat Aug 27, 2016 11:17 pm
A ray-cast will be, in most cases quicker, and any kind of complex object (convex hulls and up) generally use multiple ray-casts in their collision determination
That statement compares a single raycast vs. multiple raycasts occurring for a single collision determination.

We are comparing a single raycast being cast(300ms) constantly vs. multiple raycasts occurring for a single collison determination only when the player hits the door's collision area.

One way to look at it is like: Do you want the engine constantly idling in your driveway, or would you prefer to only start it up when you need to drive it?

### Re: Suggestions how best to do this...

Posted: Mon Aug 29, 2016 10:12 am
only when the player hits the door's collision area.
I am a bit puzzled by this... Collisions are dont have to be with a player. A non moving object can detect when something colides with it. Does this not mean thast the object is also constantly doing a check?

### Re: Suggestions how best to do this...

Posted: Mon Aug 29, 2016 3:17 pm
Without opening a great big can of worms...no, objects with collision meshes are not constantly doing collision checks while idling. All objects that could potentially collide against something else share one thing in common: they have to be moving to collide with something. This being the case, the moving object should be testing against things for collision - hence why we have the Player class searching for Triggers in its onContact() function.

Unfortunately I don't have the time this morning to break down T3D's collision system, but I'll try to touch on the important parts: Objects that support collision will have a castRay() function in the class's source file, to be used when another object queries against it for collision. So if %objA is a rock with a collision and %objB is any other moving object - if %objB collides against %objA(the nonmoving rock) then %objA's castRay() code will be called to check for the collision. Players specifically will keep track of a collisionWorkingList of objects they are colliding with to help keep things in sync client/server.

Off the top of my head I wanna say it was the physicsShape.cpp file where you could look for yourself and see what data is actually streamed and updated by a physics enabled object.IIRC the physics rep is only dealing with mass/buoyancy and things like that.