I have 2 questions. The first involving placing 2D sprites on a simple tile based 3D map. I've asked this in the past, but am just getting started with re-starting the project I was working on and wanted to see if there are any new methods I might be able to use since I was gone. A Billboard node is the first thought, but I recall always having trouble getting them to the size I wanted. It seems that being able to set them in pixels would be better.
That led to pretending they were UI objects, but I do what them to zoom in/out some. Not much, but some. Is there anyway I can translate a pixel value into a Billboard node?
My other question involves loading map data. Lots of map data. How can I speed up a map load by building only what the user is currently seeing? I assume this is how games like World of Warcraft are able to load a complex map so quickly, and keep updating the work w/ no load screens. Are they (perhaps) loading a local object model and just keeps building on it as needed, or creating a huge object model w/ only textures for the local environment? Just trying to wrap my head around how it works.
Thanks for any help!
I'm caught up right now it some other jME work (aside from the usual kind of work that pays the bills) but I am close to a first release of a system of "streaming" terrain, where terrain data is decompressed and loaded as you go (the user can implement their own datasource), as well as the generation of the actual terrain. (all multithreaded)
It'll be basic at first (and somewhat experimental), no solution for texturing yet and just terrain (based on the com.jmex.terrain classes), though there are some provisions for adding your own custom data.
llama: could you tell us a little bit more about your terrain work? what kind of terrain do you have in mind for example?
i'm currently trying to implement geomipmapped terrain. my plan after implementing it, was to add terrain streaming (seamless loading and terrain creation). it would be silly if we would both do the same thing. that's why i'm asking
Hmpf… I typed a reply but it got lost…
Well the short version: it basically works by having a system for loading/unloading a grid of heightmaps. That data is used to dynamically create and delete (my modification of) TerrainsBlocks (see the com.jmex.terrain package) to the scene (also in the form of a "grid"). I have node that does that automatically based on camera position, as well as aumotically load, decompress and unload the heightmaps needed.
So all and all it's a rather simple system. Right now everything works, except the "unloading". Performance isn't that great yet however. I still have a large todo list, and am working on jME itself to help with that as well:
- switch from arrays to NIO buffers for terrainmaps.
- reduce object creation and collection (jME will switch to NIO Buffers for vertex, normal, etc. data)
- reduce memory used (mostly jME optimizations)
- simple form of LOD (probably a SwitchNode with lower detail models)
- make it possible to memory map heightmaps
- extending possibilities for custom data associated with heightmaps
- something for texturing
So as you can see it's a pretty simple, purely heightmap based, abstracted to use "blocks" rather than vertices for manipulations to simplify handeling within in jME.
I wasn't planning to release anything till most of these are done (working on jME itself first). However if you think it's advanced enough for your needs (don't expect to build WoW with this) I could perhaps slip in a pre release based on what I have now.
- simple form of LOD (probably a SwitchNode with lower detail models)
Havn't we got that one already?
Yes but I'm not using it yet
There is one that does LOD automatically I believe, but I think I'll prefer to calculate the lower detail models myself.
Not sure of what you mean exactly… it was a while since I looked into this but IIRC there was a SwitchNode or something, that did let you bind different models to different distances. Maybe you meant that the lowpoly models should be automatically created from a source model? It sounded like you meant the other way around, which IIRC already works :?
Or am I remembering this all wrong?
Yes yes like I said it works already. However I am not using it yet
Ah, I mistunderstood you; I thought the stuff on your todo-list was for the whole jME project, and not just what needed to get implemented in your new terrain-thingy
the "stream" concept had in mind was very similar to the "grid of heightmaps" concept you want to implement. the difference is that instead of using terrain blocks i wanted to use geomipmapped terrain blocks. so if you implement your "stream loader" to use interfaces, i could use it too. if you can slip a sample of your code, or a few concept ideas, i would be glad to test them and help. if you wish a sample of the geomipmapped terrain(wich is still not finished - but you can at least see the algorithm at work), just say so.
i suppose World of Warcraft uses some thechnique very similar to (geomipmapping + streaming) because you can see terrain details popping in when you get near, and they pop out whe you get far away.
a quick explanation of geomipmapping:
geomipmapped terrain is similar to TerrainPage. the thing they have in common is that they use quadtrees for frustrum culling. the difference is that geomipmapped terrain changes its level of detail depending on how far away it is from the camera. geomipmapping is basically the same as texture mipmapping, only applied for terrain. the different levels of detail are not different meshes/models but the same mesh using different index buffers (so actually you switch index buffers, not models), but optically the behaviour is the same.
Well, the heigthmap "grid" system is completly independant from everything (even jME). It has a "manager" class, that I extended to provide some jME specific functions to aid in making TerrainBlocks.
Then there is the node that decides what to load and unload. I think this is what you would be replacing if you want to make geomipmaped terrain. The thing is, the "game" I am writing this has a simple almost top down view. That means it doesn't look in the distance much, and that I can have a not all that large number of blocks loaded, so I don't need quadtrees, op "mipmapping" objects in the distance (since pretty much everything is at the same the distance from the viewport) or quad trees to speed up culling (doesn't do much if you have only a dozen or so blocks).
So you'll probably need your own node to construct the actual terrain. However we really SHOULD share heightmap stuff, and possbily the loading and unloading of heightmaps based on distance and time. I'm also making my terrain editable, if you need that we can share some things there as well.
edit: I'll try and release some code this week. Note that you'll need a patch re-enable multithreading for LWJGL (see http://www.jmonkeyengine.com/jmeforum/index.php?topic=1877.0 ) to actually see it in action.
i understand why you don't need quadtrees now. but depending on how far away you zoom out you might want to use (uniform) level of detail. this is already possible with the stuff i did. sadly the code is such a mess that i don't want to post it yet :// besides that i'm currently stuck with fixing holes that appear in the terrain when patches of different level of detail area near eachother.
and yes, your tile map stuff is what i need
i'll do my best to fix those terrain holes and clean up the code as soon as possible. (yet i have some exams to write and those are more important)
I wonder what you mean "grid like".
TerrainBlock extends from AreaClodMesh which actually is a TIN (triangulated irregular mesh). i think that doesn't work good with the "regular grid" concept geomipmapping needs.
I have a question though, did you solve the "normals" problem yet (I have in my code)?By that I mean setting normals for a "patch" to take into account the patches next to it (I have fixed this in my modified TerrainBlock)
i kind of solved that. there are still some minimal artifacts visible ath the corners of the blocks.
Yes, but I always thought geomipmapped terrain decides to show/hide triangles (by dynamically generating indice buffers I assume now) not based on patches but on the distance of induvidual vertices. That way you don't have the "gap" problem, since the "edge" between higher and lower detail is dynamically generated too. I could be wrong though and even if it does, doesn't mean we have to.
the idea is to choose the right index buffer right before the terrain is rendered. that's why i generate those index buffers when constructing the terrain and not dynamically. geomipmapping only works this way because you have to calculate "popping error" between mipmaps (you see that error when detail pops in or out) and therefore you need all mipmaps.
Thanks for the info all! Been a busy week, finally got caught up and had a chance to remember to get back here.
Anyone have any input on the sprite side of things? What would be the best way to handle 2D sprites on the 3D background (being the ground)?
did anything happen concerning the dynamically loading maps.
Sound interesting for me as i just started to ask myself how i would do that
indeed i actually stopped working on the terrain stuff. my code was just a plain implementation of the geomipmapping algorithm - that means nothing special. when trying to fix the main problem which comes with this algorithm(and after some discussions with llama), i came to the conclusion that llama has chosen the better solution and that it doesn't make sense to write the same thing twice.
so stay tuned for llama's code.
Since I got a PM on this, a little update. I've had some problems with my new computer, and this pesky thing called "work". However I did work some on this the past few days, and I'm putting together some demos now.