Ok, this is a very dumb question...
I found jMonkeyEngine again about 2 weeks ago...I got it up and running (the old 1.something version) and went through all the tutorials and the FlagRush. Everything seemed to be going along fine.
Inspired by some Settlers of Catan-like code, and having several projects which could use tiles, I decided to throw together some tile code...locked camera, custom textures, move on to some game logic.
Well, I hit a problem. I wanted a hexagonal prism for a tile-piece. I tried building one, but my 3-d-by-hand skills are not very good, so I drew one up in a modeller (Art of Illusion actually) and tried it -- exported as an obj file and then imported and translated to jme file.
It worked fine with one exception -- the textures wouldn't show up. I tried other obj models...textures worked fine. I could change the color of the hex tile ...it looked like it was a background color of the texture...but the image woudn't show up.
I discovered that my model lacked texture coordinates...if I put some in by hand then I could make pieces of the texture show up...problem solved? I thought so. This led to a series of questions:
1) If I want to make a generic tile model and tile a terrain-like texture across it, do I have to have texture co-ordinates defined in the model?
2) If texture coordinates are required, is there a simple way to slide/warp/stretch those later? Or must the model (and hence the texture coordinates) be updated to match the new texture to the model?
3) Since the model is now a hodge-podge of triangles, is the only/best way to set these texture co-ordinates to wrap a "fake" texture around it and export it with those? Then change out images that exactly match the one originally wrapped around the model?
I could post code, but it's pointless. I simply copied the TestHexagon code and slipped in a model and different textures (from the jmetest directories...no textures I made myself).
I tried looking through the forum questions, sample code...even some of the jme code (I have quite a bit of java programming experience)...I know this is a very stupid question...I thought maybe someone could point out the very obvious thing I missed before I tracked it down...
I guess I could make a big heightmap for the whole board and tile terrain texture over it for the base and then write quads over it for individual tiles...hmm. That might even be faster...I wasn't going to worry about optimization before I got this solved.
I feel stupid. :)
I have tried to answer the questions below, but I think if I understand what you are trying to do that you are seeing it more complicated than it needs to be.
In a tile based game you are usually reusing a small set of textures. Eg. water, grass, mountain.
Each of your textures should conform to the same pattern. If they do, then you can apply any of them to the same tile shape without ever altering it's uv coordinates. So in this example, all you need is one hex model and three textures, and you can build a map as big as you like. All you need is to keep adding new instances of the hex, applying one of the textures to it and setting it's position.
The only time I think you might want to mess with uv coordinates, is if you were trying to spread one big map texture (eg. a map of the world) across all of your hex models. However, in this case I think using individual hex models would not be a good approach.
Generally, you shouldn't need to alter uv coordinates that often. They just need to be there to give some correlation between 3D and 2D.
These were my attempts at answering your questions.
- You do have to have texture coordinates if you want a texture. These would normally be saved with the model, but they can be created in code. If you look at any of the shape classes (eg. Hexagon.java), you will see texture coordinates being created.
- It is possible to modify them in code, just as it is possible to create them in code.
- Generally you "unwrap" the shape onto a plane, in your modeller such that you end up with an outline that corresponds to the model in some fairly intuitive way. You might call this a "fake" texture, a uv map, a template. From it you can produce real textures.
Texture coordinates define the point on any texture that a vertex of your model relates to. They are defined as fractions of the size of the texture. So if you say that the leftmost point of your hex has texture coords (0,0.5), then that point will be textured from half way down the left side of your texture. It doesn't matter what the texture is, or what size it is. Nor does it matter what you do with the 3d model, that point will always be tied to that part of the texture.
For basic geometric shapes, it is easy to generate texture coordinates. For example, a quad might have (0,0) (0,1) (1,1) (1,0).
More practically, one easy way of making a "hexagonal prism" is to use a 6-poited cylinder to form the tube, and a hexagon to form the end. This has the benefit that it wraps the texture better than if they shared vertices.
Node tileNode = new Node("Tile");
Cylinder cy = new Cylinder("cy", 2, 6, 1.0f, 1.0f);
cy.setLocalTranslation(0, 0, -0.5f);
Hexagon hex = new Hexagon("hex",1.0f);
tileNode.attachChild(hex);
tileNode.attachChild(cy);
I didn't know you could make a 6-pointed cylinder--that worked perfectly. I guess I have a lot more study of the "basic codebase" to do. (I found you can even make it closed with different parts of the texture mapped to the endcaps and the tube part...very nice.) I know I need to learn a lot more about texture mapping. Does anyone know of a good tutorial? :)
Thank you!