Moving sun code

Can anybody tell me why I get this error?

/*

  • To change this license header, choose License Headers in Project Properties.
  • To change this template file, choose Tools | Templates
  • and open the template in the editor.
    */
    package mygame;

import com.jme3.light.DirectionalLight;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Geometry;
import com.jme3.scene.control.AbstractControl;

/**
*

  • @author Gebruiker
    */
    public class SunControl extends AbstractControl{

    float time;
    Camera cam;
    Vector3f position = new Vector3f();
    DirectionalLight directionalLight;
    float timeFactor = 1f;
    ColorRGBA dayColor;
    ColorRGBA eveningColor;
    ColorRGBA sunColor;
    float height;

    public void controlUpdate(float tpf){

     float x = FastMath.cos(time) * 10f;
     float z = FastMath.sin(time) * 10f;
     float y = FastMath.sin(time) * 5f;
     position.set(x, y, z);
     spatial.setLocalTranslation((cam.getLocation().add(position)));
     spatial.lookAt(cam.getLocation(), Vector3f.UNIT_Y);
     directionalLight.setDirection(position.negate());
     time += tpf * timeFactor;
     time = time % FastMath.TWO_PI;
     //height = y / 2;
     sunColor.interpolateLocal(eveningColor, dayColor, FastMath.sqr(height));
     directionalLight.setColor(sunColor);
     ((Geometry)spatial).getMaterial().setColor("Color", sunColor);
    

    }

    float getHeight(){
    return height;
    }

    public void controlRender(RenderManager rm, ViewPort vp){

    }

}

I get an NullPointerException on the following line.

spatial.setLocalTranslation((cam.getLocation().add(position)));

cam is null because you never set it to anything.

If you run your app in debug mode and mark the offending line (usually left-clicking beside the line number), it will tell you which object is null. Pretty much all IDEā€™s have this feature.

1 Like

Can you tell me more about setting the camera?
I tried this line: cam.setLocation(new Vector3f(0f,0f,0f));
but still I get an NullPointerException.

is null.

If you call anything on it then you will get a NullPointerException.

Itā€™s null because nowhere in your code do you ever have a line like:
cam = somethingā€¦ where ā€˜somethingā€™ is a camera.

I tried adding the following lines:

cam = new Camera(1,1);
cam.setLocation(new Vector3f(1f,1f,1f));

still I get an NullPointerException

Not there you didnā€™t.

Show the modified code and the latest stack trace with the line number.

This is pretty basic Java stuff hereā€¦ hopefully those willing to help out someone just learning Java will step in to help.

I donā€™t know what to add after the
cam =

Itā€™s ok for now the error is fixed. Still getting errors in the rest of the code.
I will try to fix it. Thanks for the help.

still got an error I canā€™t fix.

this line gives an NullPointerException.
((Geometry)spatial).getMaterial().setColor(ā€œColorā€, sunColor);

This is the Stack Trace:

SEVERE: Uncaught exception thrown in Thread[jME3 Main,5,main]
java.lang.NullPointerException
at mygame.SunControl.controlUpdate(SunControl.java:53)
at com.jme3.scene.control.AbstractControl.update(AbstractControl.java:128)
at com.jme3.scene.Spatial.runControlUpdate(Spatial.java:736)
at com.jme3.scene.Spatial.updateLogicalState(Spatial.java:879)
at com.jme3.scene.Node.updateLogicalState(Node.java:241)
at com.jme3.app.SimpleApplication.update(SimpleApplication.java:242)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:151)
at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:197)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:232)
at java.lang.Thread.run(Thread.java:748)

The error is in line 53

Does someone know why I get an NullPointerException?

I added this field so this canā€™t be it.
ColorRGBA sunColor= new ColorRGBA(1f,1f,1f,0f);

This is the code:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package mygame;

import com.jme3.light.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Geometry;
import com.jme3.scene.control.AbstractControl;

/**
 *
 * @author Gebruiker
 */
public class SunControl extends AbstractControl{
    
    float time;
    Camera cam = new Camera(1,1);
    Vector3f position = new Vector3f();
    DirectionalLight directionalLight = new DirectionalLight();
    float timeFactor = 1f;
    ColorRGBA dayColor = new ColorRGBA(3f,3f,3f,0f);
    ColorRGBA eveningColor = new ColorRGBA(2f,2f,2f,0f);
    ColorRGBA sunColor= new ColorRGBA(1f,1f,1f,0f);
    float height;
    
    
    public void controlUpdate(float tpf){
        
        cam.setLocation(new Vector3f(1f,1f,1f));
        float x = FastMath.cos(time) * 10f;
        float z = FastMath.sin(time) * 10f;
        float y = FastMath.sin(time) * 5f;
        position.set(x, y, z);
        spatial.setLocalTranslation((cam.getLocation().add(position)));
        spatial.lookAt(cam.getLocation(), Vector3f.UNIT_Y);
        directionalLight.setDirection(position.negate());
        time += tpf * timeFactor;
        time = time % FastMath.TWO_PI;
        //height = y / 2;
        sunColor.interpolateLocal(eveningColor, dayColor, FastMath.sqr(height));
        directionalLight.setColor(sunColor);
        ((Geometry)spatial).getMaterial().setColor("Color", sunColor);
    }   
    
    float getHeight(){
        return height;
    }
    
    public void controlRender(RenderManager rm, ViewPort vp){
        
    }
    
    
    
}

If someone else doesnā€™t step in to help, you may want to find some Java tutorials online to brush up on your Java skills. Trying to learn JME and Java at the same time is going to be very hardā€¦ and probably pretty discouraging.

You might really want to start with the jme tutorials and play around with them if not with some more general java tutorials as others have pointed out
but some hints to point you somewhere:

your nullpointerexception occurs on the line you mentioned, if sunColor was null, it would not throw a nullpointerexception on this line because your not doing anything other than passing the reference. however, either ā€œspatialā€ or ā€œgetMaterial()ā€ must be null and since youre using a control i assume spatial is not null (that is you added that control to a spatial if im not mistaken) which means getMaterial must return null. Since youre on the same line trying to set the color of that returned material you get a nullpointer exception.

one idea do figure out the reason for nullpointerexception is to split your line into several lines so instead of

((Geometry)spatial).getMaterial().setColor("Color", sunColor);

you do

Geometry geo = (Geometry) spatial;
Material mat = geo.getMaterial();
mat.setColor("Color", sunColor);

and if you then find yourself getting a npe on the line where you set the color you should check if you really set a material on that spatial before this line is executed

by the way, when you fixed the problem with the nullpointerexception regarding the camera, why didnt you just remove it?

greetings from the shire,
samwise

I find the fastest way to find npeā€™s that arenā€™t popping out at me is to System.out.println() every possible null value until I find the right one.

System.out.println("spatial:"+spatial+" material:"+((Geometry)spatial).getMaterial());

etc etc for every part of the line that is throwing an exception.

Null Pointer Exceptions are going to be very, very common. Youā€™ll need to learn how to spot possible exceptions as you go. Just be sure to erase the println once youā€™ve found the issue!

I would venture to guess that the camera should likely be a reference to the camera already provided by the main app (eg. passed into a constructor for SunControl), unless there is very specific use for a secondary camera just for the sun (like skybox or environment mapping).

Also, with height commented out, sunColor will be interpolated by the default 0.0f (squared), so with changeAmnt set to 0, this is virtually clamped to beginColor.
Presumably, the height could be set to the ratio of the spatialā€™s current height (local y) over the maximum height reachable (high noon), with any negative heights clamped to 0.

Finally, related to the latest null pointer exception; make certain that the spatial this control is being created for is actually an instance of a Geometry, and that it has a valid Material assigned (with lighting material def, of course), && that it is properly attached to that Geometry.

I get this in the Stack Trace after the folllowing code:

System.out.println(ā€œspatial:ā€+spatial+" material:"+((Geometry)spatial).getMaterial());

spatial:sun (Geometry) material:null

What do I have to do next to fix this?

I get an NullPointerException on this line:

mat.setColor(ā€œColorā€, sunColor);

basically, the engine wont know which material you want on that geometry which is why you have to set it before getting it
but this is not the hard stuff to fix and think about, its more the basics and you should get familiar with them

This may be useful:

https://wiki.jmonkeyengine.org/jme3/beginner/hello_material.html

1 Like

when I add the following line to try to set the material I get an error
saying it canā€™t find assetManager:

Material geoMat = new Material(assetManager,
ā€œCommon/MatDefs/Misc/Unshaded.j3mdā€);

I know it works in the Main class but not in this class.