How does one lock rotation on one axis?

Official Python bindings with a focus on reinforcement learning and robotics.
Post Reply
leoleoleo
Posts: 1
Joined: Tue Jul 14, 2020 10:54 pm

How does one lock rotation on one axis?

Post by leoleoleo »

My code works however even when my characters are moving without collisions they are rotating on the z axis. Of course once they collide with other characters this rotation gets even worse. Is there a way to prevent this?

Code: Select all

import sys
import direct.directbase.DirectStart

from direct.showbase.DirectObject import DirectObject
from direct.showbase.InputStateGlobal import inputState

from panda3d.core import *
from panda3d.bullet import *
#from GameObject import *

class Game(DirectObject):
    def __init__(self):
        base.setBackgroundColor(0.5, 0.5, 0.5, 1)
        base.setFrameRateMeter(True)
        base.cam.setPos(0, 0, 32)
        base.cam.setP(-90)
        base.cam.lookAt(0, 0, 0)

        # Light
        aLight = AmbientLight('ambientLight')
        aLight.setColor(Vec4(0.5, 0.5, 0.5, 1))
        aLightNP = render.attachNewNode(aLight)

        dLight = DirectionalLight('directionalLight')
        dLight.setDirection(Vec3(1, 1, -1))
        dLight.setColor(Vec4(1, 1, 1, 1))
        dLightNP = render.attachNewNode(dLight)

        render.clearLight()
        render.setLight(aLightNP)
        render.setLight(dLightNP)

        # Task
        taskMgr.add(self.update, 'updateWorld')

        # defines input vars
        self.wsad = {"w" : False, "s" : False, "a" : False, "d" : False}
        self.arrows = {"arrow_up" : False, "arrow_down" : False, "arrow_left" : False, "arrow_right" : False}

        # updates input vars
        for i in self.wsad:
            self.accept(i, self.updateKeyMap, [i, True])
            self.accept(i + "-up", self.updateKeyMap, [i, False])
        for i in self.arrows:
            self.accept(i, self.updateKeyMap, [i, True])
            self.accept(i + "-up", self.updateKeyMap, [i, False]) 

        # Physics
        self.setup()



    def update(self, task):
        dt = globalClock.getDt()
        
        # update input forces for each box that existes
        self.updateBox(dt, self.box[0], self.wsad, 0.2)
        self.updateBox(dt, self.box[1], self.arrows, 0.2)

        self.world.doPhysics(dt, 5, 1.0/180.0)

        return task.cont

    def updateKeyMap(self, controlName, controlState):
        self.wsad[controlName] = controlState
        self.arrows[controlName] = controlState    

    def setup(self):
        self.worldNP = render.attachNewNode('World')

        self.world = BulletWorld()
        self.world.setGravity(Vec3(0, 0, -9.81))

        # Ground (static)
        shape = BulletPlaneShape(Vec3(0, 0, 1), 1)

        self.groundNP = self.worldNP.attachNewNode(BulletRigidBodyNode('Ground'))
        self.groundNP.node().addShape(shape)
        self.groundNP.setPos(0, 0, -2)
        self.groundNP.setCollideMask(BitMask32.allOn())

        self.world.attachRigidBody(self.groundNP.node())

        # creates a list of adressable boxes and balls
        self.box = []
        self.ball = []

        self.createBox(4,0,0)
        self.createBox(-4,0,0)
        self.createBall(0,0,0)
    
    def createBox(self, x, y, z):
        # Box (dynamic)
        shape = BulletBoxShape(Vec3(0.5, 0.5, 0.5))

        boxNP = self.worldNP.attachNewNode(BulletRigidBodyNode('Box'))
        boxNP.node().setMass(1.0)
        boxNP.node().addShape(shape)
        boxNP.setPos(x, y, z)
        #self.boxNP.setScale(2, 1, 0.5)
        boxNP.setCollideMask(BitMask32.allOn())
        #self.boxNP.node().setDeactivationEnabled(False)

        self.world.attachRigidBody(boxNP.node())

        visualNP = loader.loadModel('Models/Box/plainbox.egg')
        visualNP.clearModelNodes()
        visualNP.reparentTo(boxNP)

        self.box.append(boxNP)

    def updateBox(self, dt, NP, keys, speed):
        force = Vec3(0, 0, 0)
        torque = Vec3(0, 0, 0)
        
        k=list(keys.keys())

        if keys[k[0]]:
            force.setY(speed)
        if keys[k[1]]:
            force.setY(-speed)
        if keys[k[2]]:
            force.setX(-speed)
        if keys[k[3]]:
            force.setX(speed)
        
        force *= 30.0
        torque *= 10.0

        force = render.getRelativeVector(NP, force)
        torque = render.getRelativeVector(NP, torque)

        NP.node().setActive(True)
        NP.node().applyCentralForce(force)
        NP.node().applyTorque(torque)

    def createBall(self, x, y, z):
        # Ball (dynamic)
        shape = BulletSphereShape(1)

        ballNP = self.worldNP.attachNewNode(BulletRigidBodyNode('Ball'))
        ballNP.node().setMass(1.0)
        ballNP.node().addShape(shape)
        ballNP.setPos(x, y, z)
        #self.ballNP.setScale(2, 1, 0.5)
        ballNP.setCollideMask(BitMask32.allOn())
        #self.ballNP.node().setDeactivationEnabled(False)

        self.world.attachRigidBody(ballNP.node())

        visualNP = loader.loadModel('Models/Ball/ball.egg')
        visualNP.clearModelNodes()
        visualNP.reparentTo(ballNP)

        self.ball.append(ballNP)

game = Game()
run()
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA
Contact:

Re: How does one lock rotation on one axis?

Post by Erwin Coumans »

This forum is for PyBullet not panda.bullet
Post Reply