Problem with creating a working skybox

While making a game in panda3d I have experienced a problem regarding my attempt to create a skybox.

The problem is this: I want it so that the camera cannot fly through the skybox or get closer to it. To achieve this I have created a task that gets the position of the camera and then moves the skybox to it. The task seems to work as the position of the camera remains the same as that of the skybox however in the game it looks as if the camera dos get closer. I have tried a few ideas to fix it but none have worked. Does anyone know what causes the problem and/or how to fix it ?

Here is the code:

This is main.py. The task that moves the skybox is at the bottom.

from direct.showbase.ShowBase import ShowBase
from panda3d.core import *
from player import *
from skybox import *
from direct.gui.OnscreenImage import OnscreenImage
import sys,time
class appclass (ShowBase) :
    def __init__ (self) :
        ShowBase.__init__(self)
        base.disableMouse ()
        base.enableParticles()
        self.player = PlayerShip ()
        self.spaceshipinteriorimageobject=OnscreenImage (image="textures/spaceships/spaceship1interior.png",scale=(2,1,1),pos= (0,0,0))
        self.spaceshipinteriorimageobject.setTransparency(TransparencyAttrib.MAlpha)
        self.skybox =SkyBox ()
        taskMgr.add (self.skyboxlocationset,"skybox mover",sort=2)
    def skyboxlocationset (self,task) :
        cameraposition=base.camera.getPos (render)
        self.skybox.model.setPos (render,cameraposition)
        self.skybox.model.clearTexture()
        self.skybox.model.setTexture(self.skybox.cubemap)
        return task.cont
app=appclass ()
app.run ()

Here is skybox.py where the code that makes the skybox is.

from direct.showbase.ShowBase import ShowBase
from panda3d.core import *
class SkyBox () :
    def __init__ (self):
        self.model=loader.loadModel ("models/SkySphere.bam")
        self.cubemap=loader.loadCubeMap ("textures/skybox/space_#.png")
        self.model.setTexture (self.cubemap)
        self.model.setScale (1000,1000,1000)
        self.model.reparentTo (render)

And finally here is player.py. The two tasks at the bottom are the camera controls.

from direct.showbase.ShowBase import ShowBase
from panda3d.core import *
from panda3d.physics import *
class PlayerShip () :
    def __init__ (self):
        self.model=loader.loadModel ("models/spaceships/spaceship0")
        self.model.setScale (8,8,8)
        self.time=0.01666666666666666666666666666667 #TO BE REPLACED
        self.model.setPos (0,0,0)
        self.mass=10000
        self.speed=0
        self.engineforce=3000
        self.ismovingforward=0
        self.ismovingbackward=0
        taskMgr.add (self.linearcontrols,"linearcontrols",sort=1)
        taskMgr.add (self.mouselook,"look",sort=1)
        
    def linearcontrols (self,task)  :
        self.acceleration=(self.engineforce/self.mass)
        if base.mouseWatcherNode.isButtonDown ("w"):
            self.speed+=(3*self.time)
        if base.mouseWatcherNode.isButtonDown ("s"):
            self.speed-=(3*self.time)
        base.camera.setY (base.camera,self.speed)

        return task.cont
    def mouselook (self,task):
        if base.mouseWatcherNode.hasMouse():
            mousex=base.mouseWatcherNode.getMouseX()
            mousey=base.mouseWatcherNode.getMouseY()
            base.camera.setP(base.camera.getP()+mousey)
            base.camera.setH(base.camera.getH()-mousex)
        return task.cont  

Would it not be simpler and more reliable to just parent the sky-box to the camera (or some other node involved in placing the camera), with a CompassEffect to prevent it from seeming to rotate?

Thanks for the suggestion. I tried parenting the sky-box to the camera using this :

 self.model.reparentTo (base.camera)

instead of the last line of skybox.py but this seems to have no affect at all. The same things happen as when I used a task. This is not what I would expect at all. :confused: I experimented with another model parented to the camera and that did keep its rotation and position relative to the camera. I don’t understand why this would not happen to the sky-box.

Help appreciated.

It is fixed.
I changed the model that it was using as the sky-box and now it works as intended. I also used the method that Thaumaturge suggested rather than the task. It works perfectly.

Hello Mr P how you resolve this. Pleas help me to overcome. I’m facing same issue

If I remember correctly I found the code and model here: Sky Sphere Script
The right model is available to download on the last reply on that link. The code there creates a bam file with the sky-sphere however that seemed to be the source of problem. To fix it I recommend only using this part of the code:

self.sphere = loader.loadModel("InvertedSphere.egg")
      # Load a sphere with a radius of 1 unit and the faces directed inward.
      
      self.sphere.setTexGen(TextureStage.getDefault(), TexGenAttrib.MWorldPosition)
      self.sphere.setTexProjector(TextureStage.getDefault(), render, self.sphere)
      self.sphere.setTexPos(TextureStage.getDefault(), 0, 0, 0)
      self.sphere.setTexScale(TextureStage.getDefault(), .5)
      # Create some 3D texture coordinates on the sphere. For more info on this, check the Panda3D manual.

I still don’t fully understand the nature of the problem so this may not work but I hope it does.

Maybe it’s really obvious and you have already looked at this, but could the problem be caused by a transform in the egg file? I had some behaviour I couldn’t explain because of this. If you read the egg file with notepad for instance, does the transformation matrix show this?:

<Group> YourObjectNameIn3dApplication {
  <Transform> {
    <Matrix4> {
      1 0 0 0
      0 1 0 0
      0 0 1 0
      0 0 0 1
    }
  }

If you do not want to rotate/translate/scale your model from your 3D application make sure it’s like this. In Blender for example, use “apply rotation and scale” before exporting on your objects.