Objectloader

Hi,

got another problem…
I tried to load a simple cube, exported from wings3D or Blender.
The loaded cube from the Blender-file is black or white depending on some settings; the wings3D-file is loadable with texture but (that’s my problem) I want to change the texture or material of the cube but i can’t reach the cube.
I load it that way: scene = objL.load(“Test.obj”);
Some posted codes load it like BranchGroup xy = null; -> null = new OBJLOader().load(“xy”);
I used to test it but if I try to load the object that way, I got a classCastException… ???
The only thing working is loading the file as scene, but no chance to set material or texture there.
Where is the mistake? Wrong export?

thx for help

Hmm… Sorry. I can’t help you with this. But certainly Amos can. I guess he worked quite a lot with the loaders.

But I think, I can tell you, why the following is not working:

The loader base currently used by ObjLoader returns an instance of “Scene”, which is an interface and therefore doesn’t extend BranchGroup ao another GroupNode extension. Even the concrete class used internally inside the loaders doesn’t extend GroupNode. You’ll have to use xy.getSceneGroup() as the Node to add to the scenegraph.
This is different in the new loader base, where any scene or model extends BranchGroup resp. Group. So they can directly be attached to the scenegraph. They’re TransformNode as well and can therefore be directly transformed (like scaled), which was also not possible in the old system.

You can always traverse the model ( getSceneGroup() ) and find any Shape3D and apply a Materail to it. But I guess it is better to wait for the failure to be fixed inside the loader. Maybe you could yourself dig into the code and try to find the solution.

Marvin

Yes I know!
That’s why I dont understand that someone works with loading as BranchGroup…
Was it possible in an older version?

O.k. I try that…
Where is a documentation for traverse ? ::slight_smile:

Don’t know.

When I said “traverse” I wasn’t talking about myNode.traverse(). I guess, you don’t want to apply the same appearance or material to all Shape3Ds in the model. So you’ll have to traverse “manually”. This means, that you’ll have to know the exact “path” in the model’s graph and apply the specific materials to the shapes.
If you do want to apply the same material (or something like that) to all the shapes, then you should use model.getSceneGroup().traverse().

There’re two overloaded versions of the traverse() method. One taking a TraversalCallback instance and one taking a DetailedTraversalCallback instance. The letter one is just for really complicated traversals, where you whould have to cast again and again.
In your case have a look at org.xith3d.scenegraph.traversal.impl.MaterialTraversal and take it as an example for your traversal implementation or just use one of the implementations from that package.

The only documentation existing for that is the JavaDoc. But I guess it is sufficient. Please tell me if it is not.

Marvin

I’ll implement it soon. (Remind me).

What exactly ? :wink:

knock knock 8)

Hmm… I exported a cube with a texture from wings3D:

Exported from Wings 3D 0.98.35

mtllib Xith3D-Cube.mtl
o cube1
#8 vertices, 6 faces
v -1.00000000 -1.00000000 1.00000000
v -1.00000000 1.00000000 1.00000000
v 1.00000000 1.00000000 1.00000000
v 1.00000000 -1.00000000 1.00000000
v -1.00000000 -1.00000000 -1.00000000
v -1.00000000 1.00000000 -1.00000000
v 1.00000000 1.00000000 -1.00000000
v 1.00000000 -1.00000000 -1.00000000
vt 0.0000000e+0 0.0000000e+0
vt 0.0000000e+0 1.6653345e-16
vt 0.0000000e+0 2.2204460e-16
vt 0.0000000e+0 1.00000000
vt 1.6653345e-16 1.00000000
vt 1.00000000 0.0000000e+0
vt 1.00000000 1.00000000
vt 1.00000000 0.0000000e+0
vt 1.00000000 2.2204460e-16
vt 1.00000000 0.0000000e+0
vt 1.00000000 1.00000000
vt 1.00000000 1.00000000
g cube1
usemtl default
f 1/1/ 4/10/ 3/12/ 2/4/
f 1/8/ 5/11/ 8/5/ 4/2/
f 2/12/ 6/4/ 5/1/ 1/10/
f 3/6/ 7/7/ 6/4/ 2/1/
f 4/1/ 8/10/ 7/12/ 3/4/
f 6/12/ 7/5/ 8/3/ 5/9/

mtl:

Exported from Wings 3D 0.98.35

newmtl default
Ns 100.000
d 1.00000
illum 2
Kd 1.00000 1.00000 1.00000
Ka 1.00000 1.00000 1.00000
Ks 1.00000 1.00000 1.00000
Ke 0.00000e+0 0.00000e+0 0.00000e+0
map_Kd Xith3D.png

So there is nothing else but the cube. Scene.getSceneGroup().numChildren() returns a 1. Traversing the scene should be done with getChild(0) … correct? But I can’t cast it as shape3D or something else. And I am not able to set texture, material or something in that state.
What is the alternative? I need a good loader where I can change the appearance from the loaded object. And I need a free programm that allows me to export in this file. (e.g. Blender or wings3D…).

Thx for help ^^

Hi, very quick convenient method implementation, check the findFirst(String name) and findAll(String name) methods in all groups (all class extending GroupNode).

I haven’t tested it so it maybe doesn’t work i’ll make an example of that.

Hope it’s fine for you.

Cool idea to add these methods. But isn’t the toolkit a better place for them? I think, adding them to the org.xith3d.scenegraph.traversal.impl package in the toolkit and org.xith3d.scenegraph.traversal.impl.SGUtils was a better way, since all other traversal implementations resist there. Do you agree?

Marvin

I don’t know if every cool thing must absolutely be excluded from the core. For me here are the place they’re the more convenient.

Just to be able tp do
OBJLoader.load(“yourscene.obj”).getSceneGroup().get(“xy”).toShape().getAppearanceLazy().setTexture(TextureLoader.getInstance().getTexture(“mytexture.jpg”));
is just cool… (note : the toShape() and getAppearanceLazy() aren’t implemented)

Fine for me :). Just wanted to mention that.

Wow. Long line :). But easy…

Marvin

I tend to like long lines, I like block structures with function calls example,


// Load the model in a rotatable group with some adjustments
RotatableGroup rot; (rot = new RotatableGroup(.1f, .5f, .03f)).addChild(
  new Transform(
    OBJLoader.load("yourscene.obj").getSceneGroup()
  ).addTranslationX(-.3f).addRotationZ(45f).add(new Sphere(10f 10, 3f))
);
rot.findFirst("xy").toShape().getAppearanceLazy().setTexture(
  TextureLoader.getInstance().newTexture(512, 512).drawText(10, 10, "Xith3D rocks", Color.RED).drawImg("alpha-layer.png")
)

and htat’s even not that hard to do !
It’s a lot of fun ^^

I’ve just finished the porting of the OBJLoader to the loader base. So please either use the new one or pick the legacy-loaders.jar from xith.org download section as described in the other thread.

Marvin

Oh, there isn’t OBJLoader.load()-like methods anymore ?

There are. They’re called loadModel() and loadScene(). The only difference is that the returned type is OBJModel resp. OBJScene, which extend org.xith3d.loaders.models.base.Model resp. org.xith3d.loaders.models.base.Scene. org.xith3d.loaders.models.base.Model extends TransformGroup and org.xith3d.loaders.models.base.Scene extends BranchGroup.

But they’re not static and have never been for OBJLoader. And I think creating an instance for the loader is no problem, since GC is only created at load time. And it is necessary for inheritance of org.xith3d.loaders.models.base.Loader. Maybe we could add a getInstance() method to all loaders to make them usable as singletons.

Marvin

I tend to find getInstance() method long but for the sake of design maybe naming them simply “get()” wouldn’t be appropriate…

I agree, that it is too long. I just wanted to match the naming, you (or Matthias Mann?) selected for TextureLoader. Quite often I’ve seen a method called instance() (without the get prefix) for singleton classes. Maybe this would fit better. But then we should change that for TextureLoader, too (and make the old one deprecated).

How do you like that?

Marvin

Well that’s no problem for me but regular users may not be happy with such a not-so-important function renaming…

Hmm… They don’t need to rename it on user side. It’s just deprecated. And I think having a streamlined API at the end is worth a lot, isn’t it.

Well so why not, why not add a developer guideline for that kind of things also ?

Could you maybe stop that? I’m so happy, we finished the lazy discussion about code guidelines and found a quite fair consense. So we don’t need to proceed it on other threads and stay friends. OK?

Marvin