Sign in to follow this  
Multiverse

J2ME mobile 3D texture swapping [SOLVED]

Recommended Posts

Hi again guys. I was wondering if anyone knew of a way to change the texture of an .m3g model while the game is running. I have a character which I am loading as an Object3D, and I want to change the texture on his face to show his mouth moving (for talking) or for showing emotions (angry, smiling etc). I figure that changing the texture would be the simplest way to do this. Is this actually possible using the mobile 3d api? Ive noticed the Appearance object seems to have some of the functionality that I might need, which is inherited from Object3D. Can anybody suggest a way of doing this? at the moment this is what i have:
testImage = Image.createImage("/smile.png"); 
testImage2D = new Image2D( Image2D.RGB, testImage );
testTexture = new Texture2D(testImage2D);
testTexture.setImage(testImage2D);
 
int ID = charGroup.getUserID();
		
testAppearance = (Appearance) charGroup.find(ID);
testAppearance.setTexture(0, testTexture);



So this gives me an appearance with the smile.png texture. But how do I get the .m3g model to be rendered with this texture/appearance? EDIT: I've been looking around, and I've come across an alternative method that I think *might* work but need confirmation. So, my idea is: 1) Load a standard body .m3g file as a 'Group', then load the appropriate head and add the head as a child node of the body. When swapping heads, I would remove the head, and add a new one as a child. Is this way possible? and if so, will the head inherit the body's animation/transforms? [Edited by - Multiverse on March 23, 2006 5:03:11 AM]

Share this post


Link to post
Share on other sites
Hi!
I'm spanish and I don't write very well.

First: You have to create a Image2D object. When you have created the Image2D, you have to pass this object to a Texture2D in the constructor.
And finally, you have to add the Texture2D to the apparence that you have to put to the object(Cube, Triangle,...)

See my source code:

try {
imagen = Image.createImage( "/logo.png" );
} catch (IOException e) {
System.out.println("Error al cargar imagen del cubo.");
e.printStackTrace();
}
Image2D image2D = new Image2D( Image2D.RGB, imagen );
Texture2D texture = new Texture2D(image2D);
aparencia.setTexture(0,texture);


aparencia is an object of type Aparence.

Good luck!!!

Share this post


Link to post
Share on other sites
Muchos Gracias Jador. ;)

Ive managed to change the appearance (just the texture) of a cube mesh (that I create procedurally) at runtime. The problem is changing the appearance/texture of a .m3g model loaded as an Object3D. The .m3g model has animation info in it so to render (in immediate mode) I do this:


//initialise
Object3D charGroup;
charGroup = LoadM3G("/Character.m3g");// 'LoadM3G' function uses Loader.load()

....
// do transforms etc
....

//animate
charGroup.animate(nFrame);
//render
iG3D.render((Node)charGroup, cCharTransform);





I'd like to point out that I didn't write this code initially, and I have no contact with the guy who did. Add that to the fact I'm a J2ME newbie and you have a pretty bad mix.
But there are things that strike me as strange. Such as the cast to a Node for rendering. Is this standard practice?

Anyway, I basically need to know if, with this current setup, it would be possible to change the texture/appearance of the model, or would have I have set up the rendering another way. perhaps retained mode?

From what I've found, to render with an Appearance, you need the render function that requires a vertex buffer and index buffer. But there is no way to get the vertex/index information from an Object3D.

So, quick recap of what I need. I need to know how I can load an m3g file with animation in a way that I can change it's appearance at will.

Share this post


Link to post
Share on other sites
Hi everyone, just in case anyone has the same problem I've managed to find a solution, so hopefully this should help some people out.

To use a different texture on a model you first need to find the 'appearance' entry in the .m3g's scene graph. To do this, you need to traverse the graph and find it.


World testWorld;
Object3D pcObjects[] = null;
Appearance testApp;
int appearanceID;

try
{
pcObjects = Loader.load("model.m3g");
for (i = 0; i < pcObjects.length; i++)
{
String s = pcObjects[i].getClass().getName();
if (s.endsWith("Appearance"))
{
appearanceID = pcObjects[i].getUserID();
}
if (s.endsWith("World"))
{
testWorld = pcObjects[i];
}
}
}
catch (Exception e)
{
e.printStackTrace();
}





This will give you the userID of the Appearance in the scene graph. It will also load your scene graph and store it as 'testWorld'. I'm assuming that the model only has one texture associated with it. If it doesn't you'll need to do more checks to make sure you get the Appearance that refers to the correct texture.
Now, if you've exported the model yourself (from 3D Studio Max etc) then you should be presented with a 'model_name.html' file. This file contains all the objects/nodes in your scene graph and their UserID. If you have access to this, then you already know the UserID, so theres no need to 'getUserID()' thing since you already know it. In which case you need to get a reference to the appearance like this:


static private int APPEARANCE_ID = 43
Appearance testApp = (Appearance)testWorld.find(APPEARANCE_ID);




Obviously the APPEARANCE_ID will be the correct ID for your appearance in the scene graph.

To swap the textures, you will need to have some different textures to swap with. You will need to do the following to load your different textures.


// define your stuff. say you want 2 textures
Texture2D Textures = new Texture2D[2];
Textures[0] = Textures[1] = null;
String Files[] = new String[2];
Image Images[] = new Image[2];
Image2D Images2D[] = new Image2D[2];
.
.
.
Files[0] = "fancytexture.png";
Files[1] = "normaltexture.png";

Images[0] = Image.createImage(Files[0]);
Images[1] = Image.createImage(Files[1]);

for (int i = 0; i < 2; i++)
{
Images2D[i] = new Image2D(Image2D.RGB, Images[i]);
Textures[i] = new Texture2D(Images2D[i]);
Textures[i].setWrapping(Texture2D.WRAP_REPEAT,Texture2D.WRAP_REPEAT);
Textures[i].setBlending(Texture2D.FUNC_MODULATE);
}




I've removed some try/catch blocks to make it more readable.

So now you have your textures, you need to be able to swap them around. to do it you simply do this:


testApp.setTexture(0, Textures[0]);
// or if you want the other texture, do
// testApp.setTexture(0, Textures[1]);





You will probably want to keep track of which texture is currently being displayed as the texture for the model.

I know this is similar to what Jador posted before, but i was still a little confused. Hopefully this will help other people out too. Now, I've got other problems to sort out!

EDIT: tidied up some of the code and got rid of a few errors

[Edited by - Multiverse on March 23, 2006 11:01:46 AM]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this