Problem Loading Textures from Models on Mac

Hi,



I'm wondering if anybody has seen this problem before. I built a sample application that works perfectly on Windows. I loads and displays milkshape models using SimpleGame. However, I get an interesting error when running it on the Mac. When loading the sample, jME seems to be incorrectly resolving the path to my texture.



First, I use setOverridingLocation to set the location of my textures.

URL texturedir = Main.class.getClassLoader().getResource("texture/");      
TextureKey.setOverridingLocation(texturedir);



Then, I simply load my model. My texture is located in
/Users/gemini/Documents/workspace/noa/bin/Textures/CubixStudioFemaleCasual.jpg

However, when jMe resolves the path, it resolves it as
/Users/gemini/Documents/workspace/noa/bin/..TexturesCubixStudioFemaleCasual.jpg

and thus doesn't find the texture. Any ideas? I've included the full trace bellow.

Here is the complete trace:


java.io.FileNotFoundException: /Users/gemini/Documents/workspace/noa/bin/..TexturesCubixStudioFemaleCasual.jpg (No such file or directory)
    at java.io.FileInputStream.open(Native Method)
    at java.io.FileInputStream.<init>(FileInputStream.java:106)
    at java.io.FileInputStream.<init>(FileInputStream.java:66)
    at sun.net.www.protocol.file.FileURLConnection.connect(FileURLConnection.java:70)
    at sun.net.www.protocol.file.FileURLConnection.getInputStream(FileURLConnection.java:161)
    at java.net.URL.openStream(URL.java:1007)
    at com.jme.util.TextureManager.loadImage(Unknown Source)
    at com.jme.util.TextureManager.loadImage(Unknown Source)
    at com.jme.util.TextureManager.loadTexture(Unknown Source)
    at com.jme.util.TextureManager.loadTexture(Unknown Source)
    at com.jme.image.Texture.read(Unknown Source)
    at com.jme.util.export.binary.BinaryImporter.readObject(Unknown Source)
    at com.jme.util.export.binary.BinaryInputCapsule.resolveIDs(Unknown Source)
    at com.jme.util.export.binary.BinaryInputCapsule.readSavableArray(Unknown Source)
    at com.jme.util.export.binary.BinaryInputCapsule.readSavableArrayList(Unknown Source)
    at com.jme.scene.state.TextureState.read(Unknown Source)
    at com.jme.util.export.binary.BinaryImporter.readObject(Unknown Source)
    at com.jme.util.export.binary.BinaryInputCapsule.resolveIDs(Unknown Source)
    at com.jme.util.export.binary.BinaryInputCapsule.readSavableArray(Unknown Source)
    at com.jme.scene.SceneElement.read(Unknown Source)
    at com.jme.scene.Spatial.read(Unknown Source)
    at com.jme.scene.Geometry.read(Unknown Source)
    at com.jmex.model.JointMesh.read(Unknown Source)
    at com.jme.util.export.binary.BinaryImporter.readObject(Unknown Source)
    at com.jme.util.export.binary.BinaryInputCapsule.resolveIDs(Unknown Source)
    at com.jme.util.export.binary.BinaryInputCapsule.readSavableArray(Unknown Source)
    at com.jme.util.export.binary.BinaryInputCapsule.readSavableArrayList(Unknown Source)
    at com.jmex.model.animation.JointController.read(Unknown Source)
    at com.jme.util.export.binary.BinaryImporter.readObject(Unknown Source)
    at com.jme.util.export.binary.BinaryInputCapsule.resolveIDs(Unknown Source)
    at com.jme.util.export.binary.BinaryInputCapsule.readSavableArray(Unknown Source)
    at com.jme.util.export.binary.BinaryInputCapsule.readSavableArrayList(Unknown Source)
    at com.jme.scene.Spatial.read(Unknown Source)
    at com.jme.scene.Node.read(Unknown Source)
    at com.jme.util.export.binary.BinaryImporter.readObject(Unknown Source)
    at com.jme.util.export.binary.BinaryImporter.load(Unknown Source)
    at com.jme.util.export.binary.BinaryImporter.load(Unknown Source)
    at WorldObject.<init>(WorldObject.java:43)
    at Main.simpleInitGame(Main.java:43)
    at com.jme.app.BaseSimpleGame.initGame(Unknown Source)
    at com.jme.app.BaseGame.start(Unknown Source)
    at Main.main(Main.java:28)

The … is probably the oddest thing there.  We could potentially look through the given file name and replace platform specific file seperators (although I think Java can handle mixed seps) but the … would still cause issues.

I have that problem with all my Milkshape models, because the texture path is hardcoded. Even when the texture is in the same directory.



ava.io.FileNotFoundException: /Users/gemini/Documents/workspace/noa/bin/Textures/.art06.png (No such file or directory)
    at java.io.FileInputStream.open(Native Method)
    at java.io.FileInputStream.<init>(FileInputStream.java:106)
    at java.io.FileInputStream.<init>(FileInputStream.java:66)
    at sun.net.www.protocol.file.FileURLConnection.connect(FileURLConnection.java:70)
    at sun.net.www.protocol.file.FileURLConnection.getInputStream(FileURLConnection.java:161)



Is there anyway I can manually load the textures and assign them to the model?

Or is there anyway I can rewrite the texture location after it is converted into JME binary, but before it is loaded?

Alex

Ok, let me ask this question a different way. To fix this problem, is there any way I can preload textures and then manually assign them to a model?



Alex

where do those backslashes in the path come from.

is it possible that the model was created under win32 (the texture paths are saved in the model itself and in this case they could be win32 paths with backslashes)? that would explain why it works on win32 and not on your mac (it shouldn't work on linux either)

I got a response for this kind of problem in this post :



http://www.jmonkeyengine.com/jmeforum/index.php?topic=4357.0

sfera:

Yes, there were created in Windows. And milkshape hardcodes a path in the texture. And yes, the problem is with the mix of / and . However, a Java filestream should have been smart enough to see this and fix it.



Joseph Beaufils:

I've seen that response and that is exactly what I am doing. If you check out my first post, you'll see that I'm using the setOverridingLocation method.



What I'm wondering is can I load the textures separately and then just apply them to the model.

then file a bug report in the issue tracker, requiring that when saving binary files, the backslashes in paths should be converted in slashes

You mean on the Chumbalum Soft error board? I could do this, but would that change have major repercussions on the way other loaders use milkshape files … I'm wondering if this isn't something that should be dealt at the converter level …



Alex

i mean the jme issue tracker: https://jme.dev.java.net/servlets/ProjectIssues

not about how milkshape models are loaded, but how jme binary files are written (the converter level as you name it ) :slight_smile:

Sorry !

My mistake 

I do not know if this can help, but Java has a method to get the file separator of running Operative System;


System.getProperty("file.separator");

actually you can always use '/' . on win32 system the VM translates it to''.

but the correct way would be indeed to use that system property

sfera said:
but the correct way would be indeed to use that system property


Yes, thanks for the confirmation! I used it in many cases. That way I am always sure that the result is always correct. Even if I know that "/" works under Windows, too; I use the method call.

Anyway, it is strange that Sun had not implemented it as a static final String variable, something like;

System.FILE_SEPARATOR



that could be quickly accessible without the use of a getter method.

System.getProperty("file.separator") get's its separator from the VM i suppose, while a static field would be just the same for all VM's because it would be hardcoded in the System class.

File.pathSeparator

theprism said:

File.pathSeparator


This is for delimiting classpath information.  eg ';' or ':'

still there are File.separator and File.separatorChar - so theprism is right, you can access the property via a static final field.

I'm pretty sure now that the bug is in the Milkshape 3d converter. Using the unified model loader in the code signet section of this site :



http://www.jmonkeyengine.com/wiki/doku.php?id=unified_model_loading



I was able to convert my models to jbin. Those load flawlessly on a Mac.



Alex