In my game I got my usual collision handler:
base.cTrav = CollisionTraverser()
elf.collisionHandler = CollisionHandlerQueue()
That’s handling collisions of projectiles with ships. Now when ships attacks they test the line of sight to the target first. I do that via a collision test with a CollisionSegment. That works in general. It was too slow when I hooked it up to said base.cTrav, with FPS somewhere in the <10 range with 4 fighters attacking. So I created a second handler:
self.sightTrav = CollisionTraverser()
self.sightHandler = CollisionHandlerQueue()
and the code for the line of sight test:
def sightTarget(self, weapname, ID): # weapname - name of weapon (string), ID - ID of firing ship
if mccodebin.isTurret(weapname):
origH = self.ShipModel.getH()
self.ShipModel.lookAt(mcglobals.env.ShipObjects[ID].ShipModel)
gunpoint = render.getRelativePoint(self.ShipModel, Point3(0,self.GunDist,0))
traveldist = mccodebin.getWeapRange(weapname)*1.25
endpos = render.getRelativePoint(self.ShipModel, Point3(0,traveldist,0))
source.setH(origH)
else:
gunpoint = render.getRelativePoint(self.ShipModel, Point3(0,self.GunDist,0))
traveldist = mccodebin.getWeapRange(weapname)
endpos = render.getRelativePoint(self.ShipModel, Point3(0,traveldist,0))
SightCNode = render.attachNewNode(CollisionNode('SightCNode'))
SightCNode.node().addSolid(CollisionSegment(gunpoint, endpos)) # ! (ax, ay, az, bx, by, bz)
SightCNode.node().setFromCollideMask(BitMask32(1000))
SightCNode.node().setIntoCollideMask(BitMask32.allOff())
SightCNode.setTag("sourceid", str(self.ID))
SightCNode.node().modifySolid(0).setPointA(gunpoint)
SightCNode.node().modifySolid(0).setPointB(endpos)
mcglobals.env.sightTrav.addCollider(SightCNode, mcglobals.env.sightHandler)
# base.cTrav.addCollider(SightCNode, mcglobals.env.collisionHandler) # !
mcglobals.env.sightTrav.traverse(render)
# base.cTrav.traverse(render) # !
SightCNode.removeNode()
if mcglobals.env.sightHandler.getNumEntries() > 0:
# if mcglobals.env.collisionHandler.getNumEntries() > 0: # !
### weird. never collided with firing ship's collision node itself,
### hence no check for it's own ID
mcglobals.env.sightHandler.sortEntries()
entry = mcglobals.env.sightHandler.getEntry(0)
# mcglobals.env.collisionHandler.sortEntries() # !
# entry = mcglobals.env.collisionHandler.getEntry(0) # !
fromnode = entry.getFromNodePath()
fromshipid = int(fromnode.getTag("sourceid"))
intonode = entry.getIntoNodePath()
intoshipid = int(intonode.getTag("shipid"))
if intoshipid == ID:
return True
else:
return False
#return intoshipid
else:
return False
And as I hoped adding things to a different Queue/Traverser did speed things up. But still not enough. How could I further gain FPS? Do I for example have to traverse the whole render? Why can’t I just feed the SightCNode?
Another way would be to not request this every frame (as it is now) but only once a second or whatever. But that would complicate my code I guess, because the sightTarget() function is currently part of the general AI that is calculated every frame.
Switch to CollisionHandlerEvent?
Here’s a screenshot:
EDIT:
I do gain some FPS by adding
mcglobals.env.sightTrav.removeCollider(SightCNode)
before
SightCNode.removeNode()
but we are not there yet.