Everything goes gray when I move away from center of map
Created a grid using lines and a bounding box,
The Idea was to have 8K world map, so 8000 units by 4000 units.
When I leave the center at some distance the screen just goes
completely grey. My background was set to black, but that goes grey too.
self.camLens.setFar(100000)
so my question dear friends, why?
is panda3D world limited to a small area around 0, 0, 0?
do we have to re-render every few thousand units.
Some Screenshot and references:
Here is the overview of SHENKO world map,
9 nodes, 9 different sectors, 4k being the center surrounded by 1080p areas
Here is a screenshot of what I have so far.
Suggestions from AI:
Original script:
I use a PS5 remote as my input device,
#!/usr/bin/env python3
"""
Drawing a 8K world map
"""
from panda3d.core import AmbientLight
from panda3d.core import Vec4
from direct.showbase.ShowBase import ShowBase
from panda3d.core import LineSegs # Used in 'grid' function
from panda3d.core import TextNode, InputDevice, loadPrcFileData, Vec3
from panda3d.core import TextPropertiesManager
from direct.gui.OnscreenText import OnscreenText
loadPrcFileData("", """
default-fov 60
notify-level-device debug
""")
# Informational text in the bottom-left corner. We use the special \5
# character to embed an image representing the gamepad buttons.
INFO_TEXT = """Move \5lstick\5 to strafe, \5rstick\5 to turn
Press \5ltrigger\5 and \5rtrigger\5 to go down/up
Press \5face_x\5 to reset camera"""
class App(ShowBase):
def __init__(self):
ShowBase.__init__(self)
# Print all events sent through the messenger
#self.messenger.toggleVerbose()
# Set the Background color
self.setBackgroundColor(0.0, 0.0, 0.0)
# Set camera far clipping plane to 10,000 units
self.camLens.setFar(100000)
# Increase ambient light intensity
ambientLight = AmbientLight('ambientLight')
ambientLight.setColor(Vec4(0.8, 0.8, 0.8, 1)) # Adjust intensity as needed
ambientLightNP = render.attachNewNode(ambientLight)
render.setLight(ambientLightNP)
self.lblWarning = OnscreenText(
text = "No devices found",
fg=(1,0,0,1),
scale = .25)
self.lblAction = OnscreenText(
text = "Action",
fg=(1,1,1,1),
scale = .15)
self.lblAction.hide()
# Is there a gamepad connected?
self.gamepad = None
devices = self.devices.getDevices(InputDevice.DeviceClass.gamepad)
if devices:
self.connect(devices[0])
# Accept device dis-/connection events
self.accept("connect-device", self.connect)
self.accept("disconnect-device", self.disconnect)
self.accept("escape", exit)
# Accept button events of the first connected gamepad
self.accept("gamepad-back", exit)
self.accept("gamepad-start", exit)
self.accept("gamepad-face_x", self.reset)
self.accept("gamepad-face_a", self.action, extraArgs=["face_a"])
self.accept("gamepad-face_a-up", self.actionUp)
self.accept("gamepad-face_b", self.action, extraArgs=["face_b"])
self.accept("gamepad-face_b-up", self.actionUp)
self.accept("gamepad-face_y", self.action, extraArgs=["face_y"])
self.accept("gamepad-face_y-up", self.actionUp)
self.environment = loader.loadModel("models/grid_master.gltf")
self.environment.reparentTo(render)
# Disable the default mouse-camera controls since we need to handle
# our own camera controls.
self.disableMouse()
self.reset()
self.grid()
self.bounding()
self.taskMgr.add(self.moveTask, "movement update task")
def connect(self, device):
"""Event handler that is called when a device is discovered."""
# We're only interested if this is a gamepad and we don't have a
# gamepad yet.
if device.device_class == InputDevice.DeviceClass.gamepad and not self.gamepad:
print("Found %s" % (device))
self.gamepad = device
# Enable this device to ShowBase so that we can receive events.
# We set up the events with a prefix of "gamepad-".
self.attachInputDevice(device, prefix="gamepad")
# Hide the warning that we have no devices.
self.lblWarning.hide()
def disconnect(self, device):
"""Event handler that is called when a device is removed."""
if self.gamepad != device:
# We don't care since it's not our gamepad.
return
# Tell ShowBase that the device is no longer needed.
print("Disconnected %s" % (device))
self.detachInputDevice(device)
self.gamepad = None
# Do we have any other gamepads? Attach the first other gamepad.
devices = self.devices.getDevices(InputDevice.DeviceClass.gamepad)
if devices:
self.connect(devices[0])
else:
# No devices. Show the warning.
self.lblWarning.show()
def reset(self):
"""Reset the camera to the initial position."""
self.camera.setPosHpr(0, -200, 10, 0, 0, 0)
def action(self, button):
# Just show which button has been pressed.
self.lblAction.text = "Pressed \5%s\5" % button
self.lblAction.show()
def actionUp(self):
# Hide the label showing which button is pressed.
self.lblAction.hide()
def moveTask(self, task):
dt = globalClock.getDt()
if not self.gamepad:
return task.cont
strafe_speed = 850
vert_speed = 5000
turn_speed = 1000
# If the left stick is pressed, we will go faster.
lstick = self.gamepad.findButton("lstick")
if lstick.pressed:
strafe_speed *= 5.0
# we will use the first found gamepad
# Move the camera left/right
strafe = Vec3(0)
left_x = self.gamepad.findAxis(InputDevice.Axis.left_x)
left_y = self.gamepad.findAxis(InputDevice.Axis.left_y)
strafe.x = left_x.value
strafe.y = left_y.value
# Apply some deadzone, since the sticks don't center exactly at 0
if strafe.lengthSquared() >= 0.01:
self.camera.setPos(self.camera, strafe * strafe_speed * dt)
# Use the triggers for the vertical position.
trigger_l = self.gamepad.findAxis(InputDevice.Axis.left_trigger)
trigger_r = self.gamepad.findAxis(InputDevice.Axis.right_trigger)
lift = trigger_r.value - trigger_l.value
self.camera.setZ(self.camera.getZ() + (lift * vert_speed * dt))
# Move the camera forward/backward
right_x = self.gamepad.findAxis(InputDevice.Axis.right_x)
right_y = self.gamepad.findAxis(InputDevice.Axis.right_y)
# Again, some deadzone
if abs(right_x.value) >= 0.1 or abs(right_y.value) >= 0.1:
self.camera.setH(self.camera, turn_speed * dt * -right_x.value)
self.camera.setP(self.camera, turn_speed * dt * right_y.value)
# Reset the roll so that the camera remains upright.
self.camera.setR(0)
return task.cont
def grid(self):
self.line1 = LineSegs("lines");
self.line1.setColor(0.5, 0.5, 0.5, 1); # R G B A, where A is tansparency or Alpha
self.line1.setThickness(1.0)
gridspacing = 1000.0
ax = -40000.0
ay = -20000.0
bx = 40000.0
by = -20000.0
for n in range(21):
self.line1.moveTo(ax, ay, 0.0);
self.line1.drawTo(bx, by, 0.0);
ay = ay + gridspacing
by = by + gridspacing
self.segsnode = self.line1.create(False);
render.attachNewNode(self.segsnode);
# Reset the
ax = -40000.0
ay = -20000.0
bx = -40000.0
by = 20000.0
for n in range(41):
self.line1.moveTo(ax, ay, 0.0);
self.line1.drawTo(bx, by, 0.0);
ax = ax + gridspacing
bx = bx + gridspacing
self.segsnode = self.line1.create(False);
render.attachNewNode(self.segsnode);
def bounding(self):
self.line1 = LineSegs("lines");
self.line1.setColor(1, 0, 0, 1); # R G B A, where A is tansparency or Alpha
self.line1.setThickness(1.0)
# X Y Z
p1 = (-40000.0, -20000.0, -20000.0)
p2 = (40000.0, -20000.0, -20000.0)
p3 = (40000.0, 20000.0, -20000.0)
p4 = (-40000.0, 20000.0, -20000.0)
p5 = (-40000.0, -20000.0, 20000.0)
p6 = (40000.0, -20000.0, 20000.0)
p7 = (40000.0, 20000.0, 20000.0)
p8 = (-40000.0, 20000.0, 20000.0)
nodes = [p1, p2, p3, p4, p5, p6, p7, p8]
ia = 0
ib = 0
ic = 0
# Start of line Segment
for a in nodes:
x1 = a[0]
y1 = a[1]
z1 = a[2]
# End of line Segment
for b in nodes:
x2 = b[0]
y2 = b[1]
z2 = b[2]
#---Bounding Box---#
# Lower bounding square border
self.line1.moveTo(p1);
self.line1.drawTo(p2);
self.line1.drawTo(p3);
self.line1.drawTo(p4);
self.line1.drawTo(p1);
# Upper bounding square border
self.line1.moveTo(p5);
self.line1.drawTo(p6);
self.line1.drawTo(p7);
self.line1.drawTo(p8);
self.line1.drawTo(p5);
self.line1.moveTo(p1);
self.line1.drawTo(p5);
self.line1.drawTo(p1);
self.line1.moveTo(p2);
self.line1.drawTo(p6);
self.line1.drawTo(p2);
self.line1.moveTo(p3);
self.line1.drawTo(p7);
self.line1.drawTo(p3);
self.line1.moveTo(p4);
self.line1.drawTo(p8);
self.line1.drawTo(p4);
self.segsnode = self.line1.create(False);
render.attachNewNode(self.segsnode);
app = App()
app.run()