Collision detection event: no impact detection

I try to reproduce the example of the doc but I don’t have the detection of the impact.

Compared to the example I’ve added physics. I do have a collision but not there is no event

from direct.showbase.ShowBase import ShowBase
from direct.showbase.DirectObject import DirectObject
from direct.interval.IntervalGlobal import Sequence, Func, Wait
from panda3d.core import CollisionTraverser, CollisionHandlerEvent
from panda3d.core import CollisionNode, CollisionSphere
from pandac.PandaModules import *
from direct.interval.IntervalGlobal import *


class World(DirectObject):

    def __init__(self):
        base.cam.setPos(0, -30, 10)
        base.cam.lookAt((0,0,4))

        base.cTrav = CollisionTraverser()
        base.enableParticles()

        collisionHandler = PhysicsCollisionHandler()
        self.collHandEvent = CollisionHandlerEvent()
        self.collHandEvent.addInPattern('into-%in')
        self.collHandEvent.addOutPattern('outof-%in')

        collisionPlane = CollisionPlane(Plane(Vec3(0, 0, 1), Point3(0,0,0)))
        plane = base.render.attachNewNode(CollisionNode('planecnode'))
        plane.node().addSolid(collisionPlane)
        plane.show()

        globalForcesForceNode = ForceNode('world-forces')
        globalForces = base.render.attachNewNode(globalForcesForceNode)

        globalForcesGravity = LinearVectorForce(0, 0, -9.81)
        globalForcesForceNode.addForce(globalForcesGravity)

        base.physicsMgr.addLinearForce(globalForcesGravity)

        scale=1.
        ball = NodePath(PandaNode('phisicsball'))
        ballActor = ActorNode('ballactornode')
        ballActorNP = ball.attachNewNode(ballActor)
        ballModel = loader.loadModel('smiley')
        ballModel.reparentTo(ballActorNP)
        ballModel.setScale(scale)
        ballModel.setPos(0, 0, 0)

        ballCollider = ballActorNP.attachNewNode(CollisionNode('ballcnode'))
        ballCollider.node().addSolid(CollisionSphere(0, 0, 0, 1))

        base.physicsMgr.attachPhysicalNode(ballActor)

        collisionHandler.addCollider(ballCollider, ballActorNP)
        base.cTrav.addCollider(ballCollider, self.collHandEvent)
        base.cTrav.addCollider(ballCollider, collisionHandler)
        ball.reparentTo(base.render)
        ball.setPos(0, 0, 10)
        self.accept('into-ballcnode', self.collide)
        self.accept('outof-ballcnode', self.collide)

    def collide(self, collEntry):
       print("COLLIDE !!!!")


base = ShowBase()
w = World()
base.run()

I think that the problem may well be that you can only have one collision-handler per object. Thus, when you inform base.cTrav to have the physics-handler handle the ball, it overrides your previous instruction to have the event-handler handle the ball.

However! A quick look at the API indicates that PhysicsCollisionHandler inherits from CollisionHandlerEvent. As a result, a PhysicsCollisionHandler should be able to produce events just as a CollisionHandlerEvent does.

So, what I suggest is that you remove your CollisionHandlerEvent-object, and have its logic–in this case the adding of in- and out- patterns, in short–be done by PhysicsCollisionHandler.

Thank you for your response, I have removed CollisionHandlerEvent and added the event to my PhysicsCollisionHandler.
the code is running but there is still no event :cry:

from direct.showbase.ShowBase import ShowBase
from direct.showbase.DirectObject import DirectObject
from direct.interval.IntervalGlobal import Sequence, Func, Wait
from panda3d.core import CollisionTraverser, CollisionHandlerEvent
from panda3d.core import CollisionNode, CollisionSphere
from pandac.PandaModules import *
from direct.interval.IntervalGlobal import *


class World(DirectObject):

    def __init__(self):
        base.cam.setPos(0, -30, 10)
        base.cam.lookAt((0,0,4))

        base.cTrav = CollisionTraverser()
        base.enableParticles()

        collisionHandler = PhysicsCollisionHandler()
        collisionHandler.addInPattern('into-%in')
        collisionHandler.addOutPattern('outof-%in')

        collisionPlane = CollisionPlane(Plane(Vec3(0, 0, 1), Point3(0,0,0)))
        plane = base.render.attachNewNode(CollisionNode('planecnode'))
        plane.node().addSolid(collisionPlane)
        plane.show()

        globalForcesForceNode = ForceNode('world-forces')
        globalForces = base.render.attachNewNode(globalForcesForceNode)

        globalForcesGravity = LinearVectorForce(0, 0, -9.81)
        globalForcesForceNode.addForce(globalForcesGravity)

        base.physicsMgr.addLinearForce(globalForcesGravity)

        scale=1.
        ball = NodePath(PandaNode('phisicsball'))
        ballActor = ActorNode('ballactornode')
        ballActorNP = ball.attachNewNode(ballActor)
        ballModel = loader.loadModel('smiley')
        ballModel.reparentTo(ballActorNP)
        ballModel.setScale(scale)
        ballModel.setPos(0, 0, 0)

        ballCollider = ballActorNP.attachNewNode(CollisionNode('ballcnode'))
        ballCollider.node().addSolid(CollisionSphere(0, 0, 0, 1))

        base.physicsMgr.attachPhysicalNode(ballActor)

        collisionHandler.addCollider(ballCollider, ballActorNP)
        base.cTrav.addCollider(ballCollider, collisionHandler)
        ball.reparentTo(base.render)
        ball.setPos(0, 0, 10)
        self.accept('into-ballcnode', self.collide)
        self.accept('outof-ballcnode', self.collide)

    def collide(self, collEntry):
       print("COLLIDE !!!!")


base = ShowBase()
w = World()
base.run()

Ah, doing some quick debugging on my end, I believe that I’ve found the problem:

When you add your patterns, you’re specifying “into-”- and “outof-”- “%in”. In these patterns, “%in” refers to the “into” NodePath involved in a given collision.

However, when you “accept” your events, you’re specifying events that end with the name of your “active” object, the falling ball. But as it’s the only “active” object in the collision, it’s always the “from” NodePath, and never the “into” NodePath!

As a result, the events generated by Panda–which, according to the patterns, always end in the name of the “into” NodePath–never match the events that you’re accepting–which all end with the name of the “from” NodePath.

What I suggest is changing your patterns to refer to the “from” NodePath instead of the “into” NodePath. This can be done by replacing “%in” with “%fn”, which refers to the “from” NodePath, I believe.

1 Like

Yes !
%fn to solve my problem

1 Like