Home >> Python >> Panda3D Collision Detection


■衝突感知

☆CollisionHandlerPusherを用いる

from direct.showbase.ShowBase import ShowBase
from pandac.PandaModules import CollisionTraverser, CollisionHandlerPusher
from pandac.PandaModules import CollisionNode, CollisionSphere
from pandac.PandaModules import Point3
 
# Initialize the scene.
ShowBase()
 
base.cTrav = CollisionTraverser()
pusher = CollisionHandlerPusher()
 
# Load a model.
smiley = loader.loadModel('smiley')
# Reparent the model to the camera so we can move it.
smiley.reparentTo(camera)
# Set the initial position of the model in the scene.
smiley.setPos(0, 25.5, 0.5)
 
# Create a collision node for this object.
cNode = CollisionNode('smiley')
# Attach a collision sphere solid to the collision node.
cNode.addSolid(CollisionSphere(0, 0, 0, 1.1))
# Attach the collision node to the object's model.
smileyC = smiley.attachNewNode(cNode)
# Set the object's collision node to render as visible.
smileyC.show()
 
# Load another model.
frowney = loader.loadModel('frowney')
# Reparent the model to render.
frowney.reparentTo(render)
# Set the position of the model in the scene.
frowney.setPos(5, 25, 0)
 
# Create a collsion node for this object.
cNode = CollisionNode('frowney')
# Attach a collision sphere solid to the collision node.
cNode.addSolid(CollisionSphere(0, 0, 0, 1.1))
# Attach the collision node to the object's model.
frowneyC = frowney.attachNewNode(cNode)
# Set the object's collision node to render as visible.
frowneyC.show()
 
# Add the Pusher collision handler to the collision traverser.
base.cTrav.addCollider(frowneyC, pusher)
# Add the 'frowney' collision node to the Pusher collision handler.
pusher.addCollider(frowneyC, frowney, base.drive.node())
 
# Have the 'smiley' sphere moving to help show what is happening.
frowney.posInterval(5, Point3(5, 25, 0), startPos=Point3(-5, 25, 0), fluid=1).loop()
 
# Run the scene. Move around with the mouse to see how the moving sphere changes 
# course to avoid the one attached to the camera.
run()
	

☆Collision Handler Eventsのためのクラスを作る

from direct.showbase.ShowBase import ShowBase
from direct.showbase.DirectObject import DirectObject
from direct.interval.IntervalGlobal import Sequence, Func, Wait
from pandac.PandaModules import CollisionTraverser, CollisionHandlerEvent
from pandac.PandaModules import CollisionNode, CollisionSphere
from pandac.PandaModules import VBase4
 
 
class World(DirectObject):
 
    def __init__( self ):
        # Initialize the traverser.
        base.cTrav = CollisionTraverser()
 
        # Initialize the handler.
        self.collHandEvent = CollisionHandlerEvent()
        self.collHandEvent.addInPattern('into-%in')
        self.collHandEvent.addOutPattern('outof-%in')
 
        # Make a variable to store the unique collision string count.
        self.collCount = 0
 
        # Load a model. Reparent it to the camera so we can move it.
        s = loader.loadModel('smiley')	
        s.reparentTo(camera)
        s.setPos(0, 25, 0)
 
        # Setup a collision solid for this model.
        sColl = self.initCollisionSphere(s, True)
 
        # Add this object to the traverser.
        base.cTrav.addCollider(sColl[0], self.collHandEvent)
 
        # Accept the events sent by the collisions.
        self.accept('into-' + sColl[1], self.collide3)
        self.accept('outof-' + sColl[1], self.collide4)
        print(sColl[1])
 
        # Load another model.
        t = loader.loadModel('smiley')
        t.reparentTo(render)
        t.setPos(5, 25, 0)
 
        # Setup a collision solid for this model.
        tColl = self.initCollisionSphere(t, True)
 
        # Add this object to the traverser.
        base.cTrav.addCollider(tColl[0], self.collHandEvent)
 
        # Accept the events sent by the collisions.
        self.accept('into-' + tColl[1], self.collide)
        self.accept('outof-' + tColl[1], self.collide2)
        print(tColl[1])
 
        print("WERT")
 
    def collide(self, collEntry):
        print("WERT: object has collided into another object")
        Sequence(Func(collEntry.getFromNodePath().getParent().setColor,
                      VBase4(1, 0, 0, 1)),
                 Wait(0.2),
                 Func(collEntry.getFromNodePath().getParent().setColor,
                      VBase4(0, 1, 0, 1)),
                 Wait(0.2),
                 Func(collEntry.getFromNodePath().getParent().setColor,
                      VBase4(1, 1, 1, 1))).start()
 
 
    def collide2(self, collEntry):
        print("WERT.: object is no longer colliding with another object")
 
    def collide3(self, collEntry):
        print("WERT2: object has collided into another object")
 
    def collide4(self, collEntry):
        print("WERT2: object is no longer colliding with another object")
 
    def initCollisionSphere(self, obj, show=False):
        # Get the size of the object for the collision sphere.
        bounds = obj.getChild(0).getBounds()
        center = bounds.getCenter()
        radius = bounds.getRadius() * 1.1
 
        # Create a collision sphere and name it something understandable.
        collSphereStr = 'CollisionHull' + str(self.collCount) + "_" + obj.getName()
        self.collCount += 1
        cNode = CollisionNode(collSphereStr)
        cNode.addSolid(CollisionSphere(center, radius))
 
        cNodepath = obj.attachNewNode(cNode)
        if show:
            cNodepath.show()
 
        # Return a tuple with the collision node and its corrsponding string so
        # that the bitmask can be set.
        return (cNodepath, collSphereStr)
 
ShowBase()
# Run the world. Move around with the mouse to create collisions.
w = World()
run()
	

Panda 3d GUI Components Python Python 3d Physical Simulation