Ok, hello everybody.
For some time already, i “often” have a bug with the skybox: when i attach the skybox to node which is not the rootNode, i get some strange artifact that make my entire world disappear when i look in some directions.
This doesn’t happen on small projects, so it was impossible to find a test case.
After some research, i found that it’s because of the model bound : when the model bound of the node (the one that contains the sky spatial) doesn’t intersect with the camera’s fov, it’s just culled, and all of its children are also culled.
Ok, in a perfectly mathematical world, my node should have a bounding volume of at least the bounding volume of its children. As a skybox has a bounding volume of infinite in all directions, my node should have the same.
It happens that it’s not the case, for some reason i don’t know.
I still managed to do a test case, with that in mind.
[java]
package real.tests;
import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Box;
import com.jme3.util.SkyFactory;
import real.client.controllers.SkyBoxMover;
/**
*
-
@author Bubuche
*/
public class SkyBoxBug extends SimpleApplication
{
public static void main(String args[])
{
SkyBoxBug app = new SkyBoxBug();app.start();
}
@Override
public void simpleInitApp()
{
Node nodeWithSky = new Node(“i have a sky”);
flyCam.setMoveSpeed(15);
Box b = new Box(1, 1, 1);
Geometry geom = new Geometry("Box", b);
nodeWithSky.attachChild(geom);
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat.setColor("Color", ColorRGBA.Blue);
geom.setMaterial(mat);
nodeWithSky.attachChild(geom);
Spatial sky = SkyFactory.createSky(
assetManager, "Textures/Sky/Bright/BrightSky.dds", false);
//sky.addControl(new SkyBoxMover());
nodeWithSky.attachChild(sky);
rootNode.attachChild(nodeWithSky);
nodeWithSky.updateModelBound();
cam.setLocation(new Vector3f(0, 0, 20));
}
}
[/java]
If you turn the camera more than pi/4 on the left (or the right) all the scene just disappear (you got a black screen).
i KNOW that this line
nodeWithSky.updateModelBound();
is a bit strange, but without it the test doesn’t work. For a reason i don’t know, i don’t have bounds for my node without it. Maybe it’s done after. I don’t know where this method is called in jme, so i can’t say why i have problems with my programs.
Ok, that said i tried to create a solution. I wanted something generic enough.
Here we go :
[java]
package real.client.controllers;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.AbstractControl;
/**
*
-
@author Bubuche
*/
public class SkyBoxMover extends AbstractControl implements Cloneable
{
public Vector3f position;
public Vector3f out;
public SkyBoxMover()
{
position = new Vector3f();
out = new Vector3f();
}
@Override
protected void controlUpdate(float tpf)
{
}
@Override
protected void controlRender(RenderManager rm, ViewPort vp)
{
Camera camera;
camera = vp.getCamera();
position.set(camera.getLocation());
spatial.worldToLocal(position, out);
//spatial.updateModelBound();
spatial.setLocalTranslation(position);
}
@Override
public SkyBoxMover cloneForSpatial(Spatial spatial)
{
SkyBoxMover result = new SkyBoxMover();
spatial.addControl(result);
return result;
}
}
[/java]
To test it, just take the “test case” and remove the “//” in front of sky.addControl(new SkyBoxMover());
However, i don’t know what are the consequences of this fix. The way i do it, you can even have multiple camera to render your scene and it should still work, so i am not “delaying” the problem to bigger projects.
My solution is basically : move the skybox to the camera’s location every frame for each and every camera.
Fix the source of the bug is also a possibility ^^.