[SOLVED] Jme3 Beginner: Asset Manager Null

I have 3 classes:

[java]

Animator.java // main class responsible of all the drawing (nodes, simpleApplication, etc)

Adapter.java // class that reads a trace file in order to animate it (using Cinematics)

CreateSpatial.java // using command pattern class that does what its called

RotateSpatial.java

MoveSpatia.java

[/java]



so as I read from the adapter let’s say a createSpatial event , to do so I create an instance of the animator in it (call it cinema) and call:



cinema.createSpatial(id, type, x, y, z); // the params get passed fine



however I do get an error

[java]WARNING: Asset Manager is null

Exception in thread “main” java.lang.ExceptionInInitializerError[/java]

Caused by: java.lang.NullPointerException



exactly here:



[java]if(assetManager == null)

{

System.out.println(“WARNING: Asset Manager is null”);

}

mySpatial = assetManager.loadModel("/Models/F_Drive_ver2.obj");[/java]



Note that it has nothing to do with the loading as if I run createSpatial from Animator.java it works just fine however it creates only one spatial (obviously). I want to create as many as we read from the trace file.

yeh we’re never gonna know without more info. How do you initialize it? post the code where you use it, where you initialize it

Since it happens in the main thread I guess you are doing this in the main() method, as stated in the docs, you have to do all initialization code in simpleInit()…

Another possibility is that you try to work by creating multiple classes that extend “SimpleApplication” to get access to an “assetManager” variable. In that case you will have to learn more about object oriented programming.

Nucular, its called nucular. Please read up on java, I don’t understand what you are talking about, you don’t call these “functions” in java for example.

hi i had this problem as well, so i used this to fix it :

[java]

public InputStream getFile(String file)

{

if (this.getAssetManager() != null) return loadFile(file, this.getAssetManager());

else

{

try

{

return new BufferedInputStream(new FileInputStream(new File("./assets/" + file)));

}

catch (Exception e)

{

e.printStackTrace();

throw new IllegalArgumentException("cannot find file ./assets/" + file);

}

}

}



public static InputStream loadFile(String filepath, AssetManager assetManager)

{

return assetManager.locateAsset(new AssetKey(filepath)).openStream();

}

[/java]

Thats a bad hack and will not work for distributed apps, just use the assetManager after its created. If assetManager is null you do it wrong!!

Basically i use that hack when i load swing ImageIcons, or scripts.

[swing is initialised before jme].

do any of these functions, or classes inside them call create3dDrives() anywhere?



[java]/** Constructor: starts reading the file */

public Jme3Adapter( ) {



// This function has all the available motion commands to date

attachCommands(hm); // hashmap attach



// reads trace file (reads .txt or .atf)

readFile();

}[/java]



if so you need this inside simpleInitApp(), put it inside simpleInitApp() and see if it works none-the-less

java.exe or whatever runs main(). Nothing at all has been setup at this point except any staticly initialized variables. In JME land, you basically do nothing in main but create your app and start it… because nothing will have been initialized until the app has started.



If you do anything before the app has started then you will find a lot of nulls. You can either do your initialization in simpleInit() (which is designed for initialization) or you can do your initialization in the init method of an AppState that you add to that application’s state manager. Just depends on what you are trying to do.



The part I miss from this thread is why you are trying to call create3dDrives before you’ve even started the 3D system.

Wezrule, no , one of them reads the trace file and one of them is just a hashmap definition (to fill it). create3dDrives is called from a separate java file called Adapter.



Pspeed, I realize that is the mistake →

trying to call create3dDrives before you’ve even started the 3D system.
but I don’t understand why is that the case in my program.



I start the app then read the file then call the function, however like you said apparently the function is called before the app is initialized otherwise I won’t be getting an null assetManager.

I don’t know. We don’t have all of the information because there is nowhere in that code where create3dDrives is called.

[java]Jme3Adapter cinema = new Jme3Adapter(); // CREATE INSTANCE hERE[/java] thats ur problem

for clarification, In the previous design I have an adapter (which is also the animator) called jme3Adapter and a separate event depending on what was called named Jme3CreateEvent, another design could be to have an Adapter (that parses the trace file), an animator (that contain the main) and separate event files. Which ones do you guys recommend?

How would I be able to call the method in the main otherwise?

you need a reference to your SimpleApplication instance, either pass it to the class’s constructor or make a static reference to it. There’s other ways as well. This should help:



http://hub.jmonkeyengine.org/groups/general-2/forum/topic/outsourcing-code-from-simpleapplication

1 Like

Great! now that it works which design would u recommend?



1)reading and putting everything in an arraylist? (more like an arraylist of arraylists where each sub array list is the event line read)



2) read trace file and execute animation on the fly?

it depends how big are they? an arraylist takes some time to build, but you can access the data instantly at runtime. If its sequential you may want to look at a normal LinkedList, quick to build, but traversing takes a long time

wezrule said:
traversing takes a long time

traversing a LinkedList sequentially is actually very fast, selectively accessing single items is pretty slow though.

Yeah my trace is time related and sequential like this for example:

[java]

time 0.00

create spatial1

time 1.3

move spatial1 x y z

rotate spatial1 O degrees

move spatial1 x y z

time 3.2

create spatial2[/java]



so the arralists would be:



al1 = [create, spatial1]

al2 = [ move, spatial1, x,y,z]





and I wanted to store them in a buffer.

so should I just run them on the fly whenever they are read to save on time?