So, I’m not sure whether I can spam questions here, but hey since i cant figure it out myself, I decided it’ll be told if I overstay my welcome. So i have this issue at the moment that camera shifts its rotation point after the object its reparented to the child of gets stuck in collision.
Here’s the code for camera, (bit dirty as i tried a lot of things and messed it up few times):
from panda3d import core
from panda3d.core import CollisionRay, CollisionNode, CollideMask, CollisionHandlerQueue, BitMask32
class FollowCam(object):
NAMEID = 'camera_follow'
def __init__(self, cam, follow, ctrav, QQ, follow_model):
self.follow_model = follow_model
self.cam = cam
self.follow = follow
self.fake_node = self.follow_model.attachNewNode(self.NAMEID)
self.fake_node.setPos(self.follow_model,0,0,0)
self.cNode = CollisionNode(f'collision_{self.NAMEID}')
self.cNodeP = self.fake_node.attachNewNode(self.cNode)
self.cNodeP.setPos(self.fake_node, (70, 0, 0))
self.ray = CollisionRay()
self.ray.setOrigin(self.cNodeP.getPos())
self.ray.setDirection(0, 0, -1)
self.cNode.add_solid(self.ray)
self.cNode.setFromCollideMask(CollideMask.bit(1))
self.cam.reparentTo(self.cNodeP)
self.qq = QQ
ctrav.addCollider(self.cNodeP, self.qq)
def DBG(self):
print(f'pt.1 {self.cam.getX()},{self.cam.getY()}')
print(f'pt.2 {self.follow.getX()},{self.follow.getY()}')
def update(self):
entries = list(self.qq.entries)
for entry in entries:
self.cam.setZ(entry.getSurfacePoint(render).getZ()+12)
self.fake_node.setPos(self.follow_model.getPos())
self.cNodeP.setPos(self.fake_node, (70, 0, 0))
self.fake_node.setHpr(self.follow_model.getHpr())
self.cam.lookAt(self.follow_model)
And that’s the camera init cript:
from panda3d.core import Vec3, CollisionHandlerPusher, CollisionHandlerQueue
from panda3d.bullet import BulletWorld
from direct.showbase.ShowBase import ShowBase, CollisionTraverser
from panda3d.core import MouseWatcher
from panda3d.core import WindowProperties
from Char_spherecollision import Char
from dafollowcam import FollowCam
from cone import cone
from map import Map
from test_ground import test_ground
from wall import wall
import cv2
winder = cv2.namedWindow('oooooooooo')
def noting(nut):
pass
cv2.createTrackbar('x','oooooooooo',30,100,noting)
cv2.createTrackbar('y','oooooooooo',0,100,noting)
cv2.createTrackbar('z','oooooooooo',10,100,noting)
class MyApp(ShowBase):
def __init__(self):
ShowBase.__init__(self)
self.dx,self.dy = 0,0
# Showbase augmentations
self.disable_mouse()
self.taskMgr.add(self.update, 'update')
self.setBackgroundColor(0,0,220,1)
#Usefull objects monitor etc
self.cTrav = CollisionTraverser()
self.pusher = CollisionHandlerPusher()
self.queue = CollisionHandlerQueue()
self.rat = MouseWatcher()
self.winder = WindowProperties()
self.winder.setCursorHidden(True)
self.winder.setMouseMode(WindowProperties.M_relative)
self.win.requestProperties(self.winder)
self.pusher = CollisionHandlerPusher()
# events listeners
self.accept("a", self.UpdateKeyMap, ["left", True])
self.accept("a-up", self.UpdateKeyMap, ["left", False])
self.accept("d", self.UpdateKeyMap, ["right", True])
self.accept("d-up", self.UpdateKeyMap, ["right", False])
self.accept("w", self.UpdateKeyMap, ["up", True])
self.accept("w-up", self.UpdateKeyMap, ["up", False])
self.accept("s", self.UpdateKeyMap, ["down", True])
self.accept("s-up", self.UpdateKeyMap, ["down", False])
self.accept("q", self.UpdateKeyMap, ["shoot", True])
self.accept("q-up", self.UpdateKeyMap, ["shoot", False])
self.accept("e", self.UpdateKeyMap, ["not shoot", True])
self.accept("e-up", self.UpdateKeyMap, ["not shoot", False])
self.accept("z", self.UpdateKeyMap, ["top", True])
self.accept("z-up", self.UpdateKeyMap, ["top", False])
self.accept("x", self.UpdateKeyMap, ["bottom", True])
self.accept("x-up", self.UpdateKeyMap, ["bottom", False])
self.MsX,self.MsY = None,None
#keymap
self.keyMap = {
"up": False,
"down": False,
"left": False,
"right": False,
"shoot": False,
'not shoot': False,
'top': False,
'bottom': False
}
# object instanciation
#self.map = Map((0,0,0),self.cTrav,self.queue)
self.grnd = test_ground(self.cTrav,self.queue)
self.cones = []
a,b,c = 0,0,0
for i in range(5):
a = a + 4
placeholder = cone((a,b,c),self.cTrav,self.queue)
self.cones.append(placeholder)
self.character = Char(self.cTrav,self.pusher,self.queue)
self.FCAM = FollowCam(self.cam,self.character.floater,self.cTrav,self.queue, self.character.model)
#print(render.ls())
def UpdateKeyMap(self, key, state):
self.keyMap[key] = state
def update(self,task):
dt = globalClock.getDt()
if self.mouseWatcherNode.hasMouse():
self.MsX = ((base.mouseWatcherNode.get_mouse_x() + 1) / 2) * base.win.get_x_size()
self.MsY = self.mouseWatcherNode.getMouseY()
self.size = self.get_size()
self.dx,self.dy = int(self.size[0]/2) - self.MsX, int(self.size[1]/2) - self.MsY
x,y,z = cv2.getTrackbarPos('x','oooooooooo'),cv2.getTrackbarPos('y','oooooooooo'),cv2.getTrackbarPos('z','oooooooooo')
if x != 0 and y != 0 and z != 0:
pass
self.character.Update_state(self.keyMap, dt, (self.dx,self.dy))
self.FCAM.update()
self.queue.clear_entries()
if self.keyMap['shoot']:
self.FCAM.DBG()
return task.cont
app = MyApp()
app.run()
Yes, ik I need to clear collision queue after character, I’m still working on how to get second instance of it as .copy() causes error for some reason.(but that’s not the issue currently)
The original rotation of char comes from here:
from panda3d.bullet import BulletTriangleMeshShape, BulletTriangleMesh
from panda3d.bullet import BulletRigidBodyNode
from panda3d.core import CollisionHandlerPusher, CollideMask, CollisionNode, CollisionSphere, CollisionRay
from reference import REFERENCE
class Char():
speed = 20
NAMEID = 'apple_char'
ORIGIN = (0,0,0)
def __init__(self,ctrav,pusher,QQ):
x,y,z = self.ORIGIN
self.model = loader.loadModel(REFERENCE.loadTexturePath('toad.bam'))
self.node = render.attachNewNode(self.NAMEID)
self.model.setPos(x,y,z)
self.node.setPos(x,y,z)
self.model.reparentTo(self.node)
self.futurepos = self.node.getPos()
self.qq = QQ
self.cNode = CollisionNode(f'{self.NAMEID}')
self.cNodeP = self.model.attachNewNode(self.cNode)
self.cNodeP.setPos(x,y,z)
self.cNode.addSolid(CollisionSphere(center=(x, y, z), radius=2))
self.cNode.setFromCollideMask(CollideMask.bit(0))
self.cNode.setIntoCollideMask(CollideMask.bit(0))
#self.cNodeP.show()
self.gcNode = CollisionNode(f'Gcollision_{self.NAMEID}')
self.GroundColl = CollisionRay()
self.GroundColl.setOrigin(z, y, z)
self.GroundColl.setDirection(0, 0, -1)
self.gcNode.add_solid(self.GroundColl)
self.gcNode.setFromCollideMask(CollideMask.bit(1))
self.gcNodeP = self.node.attachNewNode(self.gcNode)
self.gcNodeP.setPos(self.node,0,0,0)
#self.gcNodeP.show()
self.floater = self.node.attachNewNode(f'camera_{self.NAMEID}')
self.floater.setPos(self.node,0,0,2)
self.floater.show()
ctrav.addCollider(self.gcNodeP, QQ)
#self.cNodeP.show()
pusher.horizontal = True
pusher.addCollider(self.cNodeP, self.model)
ctrav.addCollider(self.cNodeP, pusher)
self.lastDelta = [0,0]
self.node.setScale(2,2,2)
self.cmddict = {
"up": self.Up,
"down": self.Down,
"left": self.Left,
"right": self.Right,
"shoot": self.beep,
'not shoot': self.beep,
'top' : self.top,
'bottom' : self.bottom
}
def Update_state(self,keypass,dt, tup):
self.futurepos = self.node.getPos()
dx, dy = tup
for k, v in keypass.items():
if v:
self.cmddict[k](dt)
self.node.setPos(self.futurepos)
entries = list(self.qq.entries)
if len(entries) == 0:
print('none')
self.node.setZ(self.node.getZ()-0.1)
for entry in entries:
if entry.getIntoNode().getName() == "collision_tGround" or entry.getIntoNode().getName().startswith('cone'):
self.node.setZ(entry.getSurfacePoint(render).getZ()+5)
self.node.setHpr(dx, 0, 0)
self.floater.setPos(self.node.getPos())
def Up(self, dt):
self.futurepos.x -= self.speed * dt
def Down(self, dt):
self.futurepos.x += self.speed * dt
def Left(self, dt):
self.futurepos.y -= self.speed * dt
self.lastDelta = [-1,0]
def Right(self, dt):
self.futurepos.y += self.speed * dt
self.lastDelta = [1, 0]
def top(self, dt):
self.futurepos.z += self.speed * dt
def bottom(self, dt):
self.futurepos.z -= self.speed * dt
def beep(self,duduh):
#print(f'DBG: floater_pos = {self.floater.getPos()}, node_pos = {self.node.getPos()}')
pass
#DEBUG METHODS
def changecNode(self,tup):
x,y,z = tup
x = x/10
y = y/10
z = z/10
Ik its really bad code but, i just try to get grip of all this node mess, so if ireparented something to something wrong please dont be mad