Hi all,
I am busy integrating the point and spot light into my scene editor when I noticed some strange behaviour when making use of the LightControl. It seems like the position of the pointlight and the spatial does not match up.
I then wrote my own control just to make the position of the pointlight the same as the world position of the spatial I want it to follow and it still seems to be an issue.
This let me think there is something wrong in the way jME renders or position the Pointlight.
If there is anyone who knows about the problem or who has a solution, please let me know.
Here is an example code to recreate the problem:
import com.jme3.app.SimpleApplication;
import com.jme3.light.PointLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.AbstractControl;
import com.jme3.scene.control.LightControl;
import com.jme3.scene.shape.Box;
import com.jme3.scene.shape.Sphere;
import com.jme3.system.AppSettings;
import com.jme3.system.JmeContext;
/**
*
* Light Control Test, where the point light does not exactly follow the node.
*
* @author nicki
*/
public class TestLightControl extends SimpleApplication {
private Node sceneNode;
private Node light1Node;
private Node light2Node;
private Node light3Node;
private float boardExtend = 50;
public static void main(String[] args) {
TestLightControl app = new TestLightControl();
AppSettings settings = new AppSettings(true);
settings.setWidth(1280);
settings.setHeight(720);
app.setSettings(settings);
app.start(JmeContext.Type.Display);
}
@Override
public void simpleInitApp() {
loadScene();
loadCamera();
}
private void loadScene() {
Node sceneNode = new Node("scene");
rootNode.attachChild(sceneNode);
Spatial floor = addBox(sceneNode, boardExtend, 0.1f, boardExtend);
addColor(floor, ColorRGBA.Gray, 1);
light1Node = addLight(sceneNode, 0, ColorRGBA.Red, 2);
light2Node = addLight(sceneNode, 0, ColorRGBA.Green, 2);
light3Node = addLight(sceneNode, 0, ColorRGBA.Blue, 2);
}
private void loadCamera() {
cam.setLocation(new Vector3f(-boardExtend, boardExtend * 0.5f, boardExtend));
cam.lookAt(new Vector3f(0, 0, 0), Vector3f.UNIT_Y);
flyCam.setMoveSpeed(10);
}
private Node addLight(Node parent, float radius, ColorRGBA colorRGBA, float height) {
Node lightNode = new Node("light");
parent.attachChild(lightNode);
lightNode.move(0, height, 0);
Spatial sphere = addSphere(lightNode, 0.5f);
addColor(sphere, colorRGBA, 0);
PointLight pointLight = new PointLight(new Vector3f(0, 0, 0));
pointLight.setRadius(radius);
pointLight.setEnabled(true);
pointLight.setColor(colorRGBA);
rootNode.addLight(pointLight);
lightNode.addControl(new LightControl(pointLight));
lightNode.addControl(new AbstractControl() {
private Vector3f targetPosition;
private Vector3f direction;
private float speed = 8f;
@Override
protected void controlUpdate(float tpf) {
//Pick a new target position
if (targetPosition == null) {
targetPosition = new Vector3f(FastMath.nextRandomInt(-(int) boardExtend, (int) boardExtend),
spatial.getWorldTranslation().y,
FastMath.nextRandomInt(-(int) boardExtend, (int) boardExtend));
}
if (targetPosition != null) {
spatial.lookAt(targetPosition, Vector3f.UNIT_Y);
direction = spatial.getWorldRotation().getRotationColumn(2).normalize();
spatial.move(direction.x * tpf * speed, 0, direction.z * tpf * speed);
if (spatial.getWorldTranslation().distance(targetPosition) <= 0.1f) {
targetPosition = null; //Reset the target position so that a new one can be generated.
}
}
}
@Override
protected void controlRender(RenderManager rm, ViewPort vp) {
}
});
return lightNode;
}
private Spatial addBox(Node parent, float xExtend, float yExtend, float zExtend) {
Box box = new Box(xExtend, yExtend, zExtend);
Geometry geometry = new Geometry("box", box);
parent.attachChild(geometry);
return geometry;
}
private Spatial addSphere(Node parent, float radius) {
Sphere sphere = new Sphere(30, 30, radius);
Geometry geometry = new Geometry("sphere", sphere);
parent.attachChild(geometry);
return geometry;
}
private Material addColor(Spatial spatial, ColorRGBA colorRGBA, int type) {
Material material = null;
if (type == 1) {
material = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
material.setBoolean("UseMaterialColors", true);
material.setColor("Ambient", colorRGBA);
material.setColor("Diffuse", colorRGBA);
} else if (type == 2) {
material = new Material(assetManager, "Common/MatDefs/Light/PBRLighting.j3md");
material.setColor("BaseColor", colorRGBA);
material.setFloat("Metallic", 0f);
material.setFloat("Roughness", 0.5f);
spatial.setMaterial(material);
} else {
material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
material.setColor("Color", colorRGBA);
}
spatial.setMaterial(material);
return material;
}
}
And a screenshot: