Tutorial 7: Hello Modelloading - Texture Problem (solved, useful information!)

Dear Community



i know, there are allready some threads about this topic, but they're all

rather old and related to older versions 0.09 and 0.10 of jme.



Several people had the problem that they forgot to specify the classpath to the

root of there relative texture-paths in their project for this tutorial.

For example: if you want to load the texture "data/picture.jpg" in your

absolute path "c:tempdata" you must add "c:temp" to your classpathes in

your project.



This is not the problem in the following description! :wink:


  • 1st *

    I tried to load a Milkshape-Model (with the correct converter: MilkToJme). The

    Model loaded fine (including animation) but without texture. The Console-Output

    says, it tried to locate the texture in .mytexture.jpg ("." of course

    doesn't exist).


  • 2nd *

    I tried to convert the Milkshape-Model to an obj-file with corresponding

    mtl-file. In the mtl-file i checked the material-path which is correct:

    "mytexture.jpg" (== mytexture.jpg is in the same path as mymodel.obj). I also

    set the Property "mtllib" to the same class which loads the resource.

    After that, jme tries to find the texture in <working-path>mytexture.jpg. That

    of course is also wrong but at least I am able to put the file mytexture.jpg in

    that location. That's what I did. After that: nothing went and the program

    abortet with following output to the console:

java.lang.ClassCastException: com.jme.scene.TriMesh cannot be cast to

com.jme.scene.Node
florian.privat said:

java.lang.ClassCastException: com.jme.scene.TriMesh cannot be cast to
com.jme.scene.Node
        at HelloWorld.simpleInitGame(HelloWorld.java:56)


Change (Node) in HelloWorld.java, line 56, to something more general, like (Spatial). Spooky how I know what your code looks like, rght? :D Seriously, though, it's a ClassCastException, that means you have tried to cast the loaded TriMesh to a Node, which TriMesh isn't a subclass of, so the cast fails.
The milkshape model texture loading problem is already being discussed elsewhere, so I won't comment on that here. About the "mtllib" property seemingly being ignored, I have no idea what's going on there. Maybe you could post the 3-4 lines surrounding the line where you set "mtllib"?

yepp, quite scary  :smiley:

It did work! Changing line 56 from

(Node) sheep=(Node)BinaryImporter.getInstance().load(new ByteArrayInputStream(BO.toByteArray()));

to

(Spatial) sheep=(Spatial)BinaryImporter.getInstance().load(new ByteArrayInputStream(BO.toByteArray()));



though I have to confess, that I don't know exactly what I did here, since I'm not only new to jme, but also rather new to java (got some experience in higher languages like VB & ASP though…)



Unfortunately, OBJ doesn't seem to support animation. So it looks like i have the choice between still objects with textures or animated objects without textures  :cry:



There's a demo of an animated and textured milkshape-model on the jme-website. How did THEY do it?  :-o



Thanks for your helpful post!



Besides, to answer your question:

URL model=HelloWorld.class.getClassLoader().getResource("/data/sheep.obj");

(…)

converter.setProperty("mtllib", model);

florian.privat said:

though I have to confess, that I don't know exactly what I did here, since I'm not only new to jme, but also rather new to java (got some experience in higher languages like VB & ASP though...)

Welcome to the world of statically typed languages :) Your problem was about type casting, which is handled transparently by dynamically typed languages, so you might not have got in contact with that until now. But isn't VB partially statically typed? There's got to be some kind of explicit type casting there then, too.

Anyway, type casting basically means handling an object of a certain class (let's assume TriMesh) like one of it's superclasses (like Spatial), for the sake of generalization. This is perfectly possible as long as TriMesh is a subclass of (extends) Spatial, and thus has all the properties Spatial has. Since TriMesh isn't a subclass of Node, however, casting it that way will not work as expected, hence the compiler refuses to to that, because there is no guarantee that TriMesh supports all the methods that Node does.
This is very basic OOP stuff, though, so you'll be better off following a good java basics tutorial before trying to write your own programs. Heck, maybe even read a book! That way, you'll be able to read, understand, and act according to the basic error messages java provides you to give you a clue on what's wrong with your code.

To understand why your texture loading fails, it will probably help to get an understanding of java's class path, and to check the url you obtain in

URL model=HelloWorld.class.getClassLoader().getResource("/data/sheep.obj");

to make sure it is not null. If it is, the class loader simply can't find the specified file (as stated in the documentation for the method ClassLoader.getResource()), which leaves you with the problem to figure out how to make the class loader find the file you want.

thanks for your more detailed explanation. I think I got it now :wink:

I did know what casting is, because in VB you can also (with "option explicit") force the compiler/interpreter to check that. Nevertheless, VB 6.0 supports only "types", which you could subscribe as "OOP"-light but many important concepts of OOP are rather new to me with Java. I've chosen the approach "learning by doing" so I'm reading a book (bout 300 Pages now) parallel to working with the jme-tutorials. Up until now, I was able to adapt the tutorial-code to my stuff that way. But i'm very gratefull to find such a nice and helpfull forum-community here.



That still leaves the question on how to load my animated objects including textures.  :?



Do you have a link to a docu which explains the basic classes used in jme? For example, i don't know what "Spatial" and "Node" exactly consist of.



Greetings

with help from other forum-posts (took me another hour

For relative paths, couldn't you simply create a File object, passing the relative path, then call the toURI().toURL() method on that object?  Or use the MyClassName.class.getClassLoader.getResource("path/to/file")

I just updated the code above to allow relativ paths (relativ to the working-path).

If someone experienced knows what

TextureKey.setOverridingLocation(texLocURL);


exactly does (is it setting a global default-value for the texture-search-path and can you overwrite this if you want specific textures loaded from another path?), please post a short explanation.  :) thanks
florian.privat said:

(is it setting a global default-value for the texture-search-path and can you overwrite this if you want specific textures loaded from another path?)

Exactly!

florian.privat said:

Do you have a link to a docu which explains the basic classes used in jme? For example, i don't know what "Spatial" and "Node" exactly consist of.

http://www.jmonkeyengine.com/doc/