Game Development Community

Adding "simple" collision for trigger and onCollision callback

by Thomas Huehn · in RTS Starter Kit · 05/01/2008 (4:18 am) · 15 replies

In the stock the onCollision callbacks and trigger does not work. The following changes will add this:

In RTSUnit.h:

1.1) Add the "bold" code:

[b]
protected:
	void findSimpleContact(); 
[/b]
public:
   RTSUnit();


In RTSUnit.cc:

2.1.) After
static S32 sMaxPredictionTicks = 30;   // Number of ticks to predict

add:
static U32 sCollisionMoveMask = (TerrainObjectType      | InteriorObjectType   |
                                 WaterObjectType        | PlayerObjectType     |
                                 StaticShapeObjectType  | VehicleObjectType    |
                                 StaticTSObjectType);

static U32 sServerCollisionContactMask = (sCollisionMoveMask |
                                          (ItemObjectType    |
                                           TriggerObjectType |
                                           CorpseObjectType));

static U32 sClientCollisionContactMask = sCollisionMoveMask | PhysicalZoneObjectType;

2.2.) At the end of the file add:
void RTSUnit::findSimpleContact()
{
   // Build list from convex states here...
   CollisionWorkingList& rList = mConvex.getWorkingList();
   CollisionWorkingList* pList = rList.wLink.mNext;
   U32 mask = isGhost() ? sClientCollisionContactMask : sServerCollisionContactMask;
   while (pList != &rList) {
      Convex* pConvex = pList->mConvex;

      U32 objectMask = pConvex->getObject()->getTypeMask();
      
      // Check: triggers, corpses and items...
      //
      if (objectMask & TriggerObjectType) {
         Trigger* pTrigger = static_cast<Trigger*>(pConvex->getObject());
         pTrigger->potentialEnterObject(this);
      }
      //else if (objectMask & CorpseObjectType){
	  else if (objectMask & ShapeBaseObjectType){
         // If we've overlapped the worldbounding boxes, then that's it...
         if (getWorldBox().isOverlapped(pConvex->getObject()->getWorldBox()))  {
            ShapeBase* col = static_cast<ShapeBase*>(pConvex->getObject());
            queueCollision(col,getVelocity() - col->getVelocity());
         }
      }
      else if (objectMask & ItemObjectType) {
         // If we've overlapped the worldbounding boxes, then that's it...
         Item* item = static_cast<Item*>(pConvex->getObject());
         if (getWorldBox().isOverlapped(item->getWorldBox()))
            if (this != item->getCollisionObject())
               queueCollision(item,getVelocity() - item->getVelocity());
      }
/*
      else if ((objectMask & mask) && !(objectMask & PhysicalZoneObjectType)) {
         Box3F convexBox = pConvex->getBoundingBox();
         if (plistBox.isOverlapped(convexBox) && serverParent == NULL)
            pConvex->getPolyList(&polyList);
      }
*/

      pList = pList->wLink.mNext;
   }


}

2.3.) Add the "bold" code in void RTSUnit::processTick(const Move *move):

PROFILE_START(RTSUnit_Misc);
[b]
      updateWorkingCollisionSet();
      if (!isMounted())
		findSimpleContact();

[/b]

      // Collisions are only queued on the server and can be
      // generated by either updateMove or updatePos
      notifyCollision();

Edit:
2.4) Add the following includes add the top after #include "game/RTS/RTSConnection.h":
#include "game/item.h"
#include "game/trigger.h"

#1
05/01/2008 (9:00 am)
Nice work!
#2
05/01/2008 (10:14 am)
Ty :) Trigger is a must have for me.
#3
05/01/2008 (4:33 pm)
Great. I was waiting for someone to write some simple collision detection into the RTS Kit.

Thanks
#4
05/02/2008 (11:20 pm)
Great !!!

Thanks !!!

^_^
#5
05/05/2008 (10:06 am)
Include in the top of RTSUnit.cc the next rows :

#include "game/item.h"
#include "game/trigger.h"

^_^
#6
05/06/2008 (2:40 am)
Ups yes i'll complete the post
#7
05/06/2008 (2:46 am)
Additional you may reduce some serverside load only executing the collision ( 2.3 ) if you move or every 5 tick like this:

if (mMoveState == ModeMove ) { //only check collisions if moving to save load on many units! 
		  static colskipcounter = 0;
		  colskipcounter++;
		  if (colskipcounter % 5 == 0) { //only each 5 ticks!
			updateWorkingCollisionSet();
			if (!isMounted())
				findSimpleContact();
			notifyCollision();
		  }
	  }
#8
05/06/2008 (7:01 am)
Cool Thomas :)
Good work!
#9
05/07/2008 (12:09 pm)
The next step in this way is to implement the collisions with Units !!!
Why is not so nice to have unit overlapping other unit .....;-)
#10
05/07/2008 (2:04 pm)
@andea I would not add a unit vs unit collision because of slower down the game on many units it's maybe better to handle oncollison and let the unit take a side step.

I just removed player vs player collision in my other game because I wont longer hear the player yelling "I stuck in the monsters and cant move...". As mentioned in another disscussion the collision of 2 (or more) players moving into each other does not work so well.
#11
05/07/2008 (10:20 pm)
Mm ok then how can add in my code this way ??

You suggest to use C code or Scripting ??

Is there a tutorial about it ??

Thanks for you attention

;-)
#12
05/10/2008 (10:39 pm)
Works perfectly, thanks so much! Man was I in luck that you just posted this. I was looking through posts 5 or 6 years old and people were discussing how to implement this, and then I find one that works great and it was only posted just the other day! Thanks!
#13
01/19/2009 (2:53 am)
@Thomas: I've beeing trying to contact you, but cant found any mail address. Hope you see this, in which case, please send me an email (look for the address in my profile).
#14
01/22/2009 (2:19 pm)
From what i can see, This adds collision support for the RTS Kit? (Is it just drop in, and ready?)
#15
01/24/2009 (4:07 pm)
Thankee, I've been able to do some cool stuff with this so far. (i.e getting units to push other units out of the way)

Next I hope to conquer building collision.


I must go as my units are pushing buildings aside now, I have to fix that.