Physics/Collision Help

I hate to be the noob here, but I’ve been hitting my head against the wall for ages. Either my Google and searching skills have failed me, or the information I’m trying to find just isn’t there.

I’ve read through the Roaming Ralph example, and even mimicked some of it. I’ve loaded my own character model, my own level, and moved my character (a box) around.

I did not however, add the collision ray type deal RR had, I wanted something else, as that seemed…well, not right anyway. I want my character to move around, and respond to the world model I’ve got, don’t fall through the floor, don’t walk through walls, etc. The issue I have, is really how to do it.

So, I have a few questions. If you can answer them it’s appreciated, if you can point to a page that I overlooked, thats just as well.

  1. Is physics need to move around and collide into things player wise, if so, Panda or ODE?

  2. When I have my own mesh I import from blender, how do I make that a collision solid or mesh? We can assume that it is a low poly version.

  3. Once the collision solids are made for each model, how do I tackle responding to the collision?

The documentation is all well and good if I needed to know how to call the collision solid function, I have no idea what to do with it. After responding to key input it is an overwhelming amount of information with zero direction inside the manual.

Thanks

hi Rokmonkey
I gotta snippet for you with blender sources included that I guess should introduce you into the topic, to understand the raw basics on how it works this stuff.
As soon as you’ll got that then here another one that should clear some of your questions posted here.
Then if you want to pick into ODE collision system here there are another two snippets:

this to start
and this one to delve into some more

Thanks, those tutorials and some others that I overlooked somehow really helped out. I finally have simple walking around and collision working, so perhaps someone may help me figure out whats going wrong in my script. I use a ray to make sure the character is on the ground, and a sphere for wall collision. The sphere is causing god awful issues when it collides with things, sliding along, throwing me all over the place, glitching out when I approach the corner of a wall etc etc.

filedropper.com/dclfps

from direct.directbase import DirectStart
from direct.showbase.DirectObject import DirectObject
import sys

from pandac.PandaModules import *

class Main(DirectObject):

    def __init__(self):
    
        self.accept("escape", sys.exit)
        
        self.MouseSen = 0.1
        #Make some light to see
        plight = PointLight('plight')
        plight.setColor(VBase4(0.2, 0.2, 0.2, 1))
        plightNP = render.attachNewNode(plight)
        plightNP.setPos(0, 4, 6)
        
        alight = AmbientLight("ambientLight")
        alight.setColor(Vec4(.1, .1, .1, 1.0))
        alightNP = render.attachNewNode(alight)
        
        render.clearLight()
        render.setLight(alightNP)
        render.setLight(plightNP)
        
        #Create the world
        self.colCount = 0
        self.world = loader.loadModel("./NewWorld.egg")
        self.world.reparentTo(render)
        self.world.setPos(0,0,0)
        
        #Ground collision
        cGround = self.world.find("/Ground/groundColl")
        cGround.node().setIntoCollideMask(BitMask32.bit(1))
        cGround.show()
        
        #Stair Collision
        cStairs = self.world.find("/Stairs/StairsCol")
        cStairs.node().setIntoCollideMask(BitMask32.bit(1))
        cStairs.show()
        
        #Wall collision
        cWall = self.world.find("**/Room")
        cWall.node().setIntoCollideMask(BitMask32.bit(0))
        cWall.show()
        
        #Set up the collision handlers
        self.initCollision()

        #Create the player model
        self.initPlayer()
        
        #Muck the mouse countrols and stuff
        props = WindowProperties()
        props.setCursorHidden(True)
        base.win.requestProperties(props)
        base.disableMouse()
        
        
    def initCollision(self):
        """Setup the collision pushers and traverser"""
        #Generic traverser
        self.cTrav = CollisionTraverser('Collision Traverser')

        #Pusher Handler for walls
        self.cPush = CollisionHandlerPusher()
        
        #Queue Handler for the floor
        self.cQueue = CollisionHandlerQueue()
        
    def initPlayer(self):
        """Setup the player collision and camera setup"""
        
        #Move us
        startPos = self.world.find("**/StartPos").getPos()
        base.camera.setPos(startPos + Vec3(-1,-1,5))
        
        #Player varyiables
        self.height = 2.0
        
        #Add player controls
        self.keyMap = {"forward":0,"backward":0,"strafeleft":0,"straferight":0}
        self.accept("w",self.setKey, ["forward",1])
        self.accept("s",self.setKey, ["backward",1])
        self.accept("a",self.setKey, ["strafeleft",1])
        self.accept("d",self.setKey, ["straferight",1])
        self.accept("w-up",self.setKey, ["forward",0])
        self.accept("s-up",self.setKey, ["backward",0])
        self.accept("a-up",self.setKey, ["strafeleft",0])
        self.accept("d-up",self.setKey, ["straferight",0])
        
        taskMgr.add(self.move, "moveTask")
        
        #A collision ray for floor detection
        self.pGroundRay = CollisionRay()
        self.pGroundRay.setOrigin(0,0,10)
        self.pGroundRay.setDirection(0,0,-1)
        self.pGroundCol = CollisionNode('GroundRay')
        self.pGroundCol.addSolid(self.pGroundRay)
        self.pGroundCol.setFromCollideMask(BitMask32.bit(1))
        self.pGroundCol.setIntoCollideMask(BitMask32.allOff())
        
        self.pGroundColNP = base.camera.attachNewNode(self.pGroundCol)
        
        #Sphere for wall collision
        self.pSphere = CollisionSphere(0,0,0,1)
        self.pSphereNP = base.camera.attachNewNode(CollisionNode('pSphere'))
        self.pSphereNP.node().setFromCollideMask(BitMask32.bit(0))
        self.pSphereNP.node().setIntoCollideMask(BitMask32.allOff())
        self.pSphereNP.node().addSolid(self.pSphere)
        
        #Putting the nodes to the right collision handlers
        self.cTrav.addCollider(self.pGroundColNP,self.cQueue)
        self.cPush.addCollider(self.pSphereNP,base.camera)
        
        self.cTrav.addCollider(self.pSphereNP, self.cPush)
        
        
    def setKey(self, key, value):
        self.keyMap[key] = value
    
    def groundColHandler(self, entrys):
        newZ = None
        for entry in entrys:
            Z = entry.getSurfacePoint(render).getZ()
            if Z > newZ:
                newZ = Z
        
        base.camera.setZ(newZ + self.height)
        
    def wallColHandler(self, entry):
        pass
        
    def move(self, task):
        elapsed = globalClock.getDt()
        
        
        if base.mouseWatcherNode.hasMouse():
            # get the current location. it's in the range (-1 to 1)
            md = base.win.getPointer(0)
            x = md.getX()
            y = md.getY()
            # rotate the camera based on the mouse coordinates
            if base.win.movePointer(0, base.win.getXSize()/2, base.win.getYSize()/2):
                base.camera.setP((base.camera.getP() - (y-base.win.getYSize()/2)*self.MouseSen) % 360)
                base.camera.setH((base.camera.getH() - (x-base.win.getXSize()/2)*self.MouseSen) % 360)
                
        
        #Move the player around
        if (self.keyMap["strafeleft"]!=0):
            base.camera.setX(base.cam, -(elapsed*4))
        if (self.keyMap["straferight"]!=0):
            base.camera.setX(base.cam, (elapsed*4))
        if (self.keyMap["forward"]!=0):
            base.camera.setY(base.cam, (elapsed*5))
        if (self.keyMap["backward"]!=0):
            base.camera.setY(base.cam, -(elapsed*3))
            
        self.cTrav.traverse(render)
        groundCol = []
        for entry in self.cQueue.getEntries():
            name = entry.getIntoNode().getTag("col_type")
            if name == "ground_col": groundCol.append(entry)
            else: self.wallColHandler(entry)
            
        self.groundColHandler(groundCol)
        return task.cont
if __name__ == '__main__':
    w = Main()
    run()

If I left out any pertinent information, let me know, I really just want a nice collision system to expand upon.

since I’m actually accidentally on the subject making related stuff for myself I dug yours and well I found many inconsistencies, starting from the egg file (there is a typo in one polyset you called ployset) and in the script. Anyhow i overhauled everything, script and model and now all is working out - you may find all packaged here - dig into and try to see what was wrong comparing what you did with how it is now. Use the flag self.DEBUG to see what’s going on from above and to see the collisions at work

Well, you certainly did overhaul everything. Everything that changed in the script makes perfect sense to me, I followed it all, and actually planned on making some of those changes myself. What I don’t follow though, are the changes you made in blender.

I guess I don’t follow what changed and what it affected. Especially the change to CollisionFloorHandler, the documentation doesn’t go much into how it works, just that it does, I don’t see where you link the ground collision geometry to the FloorHandler.

Everything is grouped differently, I notice that, but the naming scheme FLT_FaceList is foreign to me.

I appreciate you taking the time to help, it’s quite the learning experience.

EDIT
Well, I sort of figured out what is going on, but I have no idea how you did it. I noticed you have objects on many different layers, one for ground collision polys, another for wall collision polys, perhaps you could explain what you did there?

looks like you’re stuck in the easier part - I would have thought the script reorganization the harder. Anyhow since I had to import your egg stuff to see what were inside I had then remade the whole stuff on my way (far to say it is the best way though). So to make it short I organized the stuff in 3 layers: 1 for the actual geometry we see running, 1 for the walls an 1 for just the floors - of course the last two are just invisible collider geometry. In this way I found easier to work, thats all. BTW those FLT_* you see are just internal mesh names assigned by the flt importer, never mind it.
FYI I’m on my way to add more snippet steps to the serie I pointed you time ago and the topics are indeed concerning this stuff (wall push and floor) so if you need more infos you’ll find there - I’ll let you know here when they’ll be available.

as announced, today I posted the walls and floors snippets - go here to grab’em if still interested