Yet One more Minecraft Clone!

Hello All,



First up, I hope I’m posting this in correct location - sorry it not :).



I’m very new to JMonkey and relatively new to Java, but I’ve certainly been having a very enjoyable time playing with it over the last couple of weeks.



Now currently, as a place to start - and as is seems to be bit of fad, I’ve decided to try and work on basic Minecraft clone. I’ve mainly done this, because its a place to start and it covers topics I’m relatively interested in.



So, so far - I’ve manged to make an abstract box manager, that manages a number of boxes in a sector of a defined size. I can then produce a number of sectors to build the world.



Currently, this manger can sort through the data and determine, very crudely which boxes are blocking other boxes, so when they are drawn, only the outer boxes are visible.



At the moment, I’m currently drawing the boxes by preparing and rotating quads for each cube, and then attaching them to a node for a given sector.



So with the background out the way, here are my first few early questions:



Currently, with around 15000 triangles on screen, drawn in wireframe mode, my performance is pritty poor (10fps on averagely good laptop). Should I be expecting to be able to draw more triangles? Would it be faster if each sector was made out of a custom mesh?



Being a Minecraft clone, the mesh would need to be dynamic, what would be the best way to approach this? I feel that regenerating a sector might be too slow?



Last one, should I be attempting LOD the sectors, i.e. collapsing the faces along adjacent lines of blocks, or would this manipulation of the mesh in real time make it even slower?



Any help and advice would be much appreciated.

gandalf said:
Currently, with around 15000 triangles on screen, drawn in wireframe mode, my performance is pritty poor (10fps on averagely good laptop). Should I be expecting to be able to draw more triangles? Would it be faster if each sector was made out of a custom mesh?


Yes, and yes. You will be happiest with a custom mesh that only draws visible faces.

gandalf said:
Being a Minecraft clone, the mesh would need to be dynamic, what would be the best way to approach this? I feel that regenerating a sector might be too slow?


Slow is as slow does. In other words, it's entirely up to the code you write to generate the mesh. It is possible to regenerate the mesh fast enough to be interactive if you are clever about it. That's what Mythruna does.

gandalf said:
Last one, should I be attempting LOD the sectors, i.e. collapsing the faces along adjacent lines of blocks, or would this manipulation of the mesh in real time make it even slower?


It will probably make it slower. I have not come up with a clever way to do this and it comes with some other issues. If every face is a quad then it is easier to use a texture atlas (I don't do this yet but will someday). Repeating textures from a texture atlas is very tricky.

Also note that unless you have a workstation GPU then rendering wireframe models will significantly slow things down.

  1. GeometryBatchFactory.optimize() will fix your problem it will make your 10 fps to 800 fps. Because it converts the model into a custom mesh automatically (removing uneeded things).
  2. please make the following adjustments and report your progress.

    a) why use boxes instead of quads ? as far as i can tell boxes have some faces that arent rendered.

    b) convert boxes into chunks of 32x32 boxes or (64x64) boxes. Use GeometryBatchFactory.optimize() on the 32x32 box sector. You only render the adjacent 32x32 sectors, the others are hidden. Outcome : only 5000 boxes are rendered.

    c) GeometryBatchFactory merges nodes that have the same material. So have some predefined materials. e.g glass, dirt, water.
Repeating textures from a texture atlas is very tricky.


Actually not really , My aproch was for proof of concept, add 4 additional texture coordinates giving the upperleft and downlow point in the atlas, then scale the orginal textues in that field with a mod, works quite good.

I assumed based on the original questions that “hacking shaders” = quite tricky for the poster. :wink:



Maybe I assume incorrectly.

hi gandalf,



soon or later you have to think about a optimal way to store the “volume-information” of each sector/chunk/world/whatever … you are welcome to have a look at our code http://code.google.com/p/bloxel/, i.e.



tessellation-code: http://code.google.com/p/bloxel/source/browse/trunk/bloxel/src/main/java/de/bloxel/world/node/FacesMeshChunkNode.java



volume/chunk-management: http://code.google.com/p/bloxel/source/browse/trunk/bloxel/src/main/java/de/bloxel/world/chunk/

specially http://code.google.com/p/bloxel/source/browse/trunk/bloxel/src/main/java/de/bloxel/world/chunk/ColtChunk.java



hv

Andreas

Hey Guys, Thanks for all the awesome responses!



@pspeed, thanks, this is what I was suspecting - I just wanted to be sure that there wasn’t something else that I was missing before embarking on custom meshes.



As for hacking shaders, at the moment this is certainly out of my depth :). But for the time being I’m more interested in how the cube data should be organised and then interpreted to be rendered.



@ahoehma, thanks for the links, I will certainly have a poke around. when you say ‘store the “volume-information”’ Do you mean creating a database for whether a given space is occupied by a box? Rather than just simply adding boxes to the scenegraph? Or there something else that I’m missing? I’m crudely asuming that the custom mesh data ‘could’ also be used later down the line for collision detection?



@tralala, thanks for your tips. I am currently using Quads for each face of the cube and I’m not drawing the quads for the cubes which share two adjacent faces. I’ve also grouped them in similar way, currently I have the concept of sector, which can be generated with a defined X,Y and Z number of cubes. Then I can also create three dimensional array of sectors.



My view - when dynamically changing this content, to determine which sector had been changed and then re-process the sector.



Going forward, I was going to use custom meshes, rather than quads, to save on the rotation stage at generation.



For example I was going to generate two custom triangles, storing just an array of verts and indices for the triangles in each cube.



[java]

22–3

| | Counter-clockwise

| |

0–11

[/java]



At the point of generating the mesh, I was thinking of gathering all of the visible (not covered) faces into one bigger vert array and index array - then generating a custom mesh out of the data. Ultimately doing this per material.



Then, I was thinking of calling GeometryBatchFactory.optimize() on the output.



But the question I have, does GeometryBatchFactory.optimize() remove overlapping verts? Using the method described above, would mean that two adjacent squares would contain 4 triangles and 8 verts, where it could be represented with 6 verts.



But the question I have, does GeometryBatchFactory.optimize() remove overlapping verts? Or would I have to write something to do that myself? At the lowest level, does removing these verts actually make a performance increase when drawing the object, or does it just reduce the memory footprint?

Of course the more vertices a model has, the slower the game will be.

GeometryBatchFactory.optimize() combines nodes into 1 mesh, now i dont think it does optimizations. One way to test it is :

a) using box vs b) using quad. And see performance difference after optimize.

Nope it does not combine triangles currently, it only copies all data into one mesh.

Hello All,



Just wanted to post, that I’ve moved it over to custom meshes now and I’ve got a 10 fold increase in performance. Pritty chuffed, I’m sure I will be back with further questions soon.

I don’t mean to hijack this thread, but…

Where would you start for making these quad things? Here’s my current code. https://github.com/simplyianm/SandBlox

At the moment, I have a function that renders the block mesh and a second one that renders the block material. (Check out Block.java and RenderedBlock.java in the geom and block packages) Instead, should I make each block consist of separate quads? Or should I merge the quads?



Also, to determine if a face is visible, would I loop through each block and get the bordering faces and determine if those faces are see-through? Thanks and sorry if this isn’t clear.

@albireox; I don’t mind you hi-jacking the thread but I’m not too sure how much I can help you. :S. Others maybe able to chip in tho!



From glancing at your code, it looks like we are taking two different approaches. From what I understand, you are working directly with the mesh and Spatials to add and remove boxes from the scene. (have to admit i only took a quick glance).



So if I understood your code correctly, when you add or remove a box, your are directly manipulating the scenegraph (hope I’m using the right terminology here).



In my code - I have the ‘concept’ of a grid of boxes. Rather than the geometry, rather than add invidual boxes to scene, I’m adding a mesh which contains ‘all’ my boxes in one go.



I used the custom mesh tutorial, https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:custom_meshes as a how to construct a single face or quad.



I basically recursively add the vertex data to a buffer for each box in my conceptual grid. Once I’ve completed this for all the boxes; I do the final stage of the data preparation and turn it into a mesh.



In my ‘concept’ of grid of boxes, I also store whether the box should be drawn, this is just simply determined if the box has any neighbors, on the grid. If it does I set flag inside the data structure to highlight whether at the rendering stage they should be considered.



My conceptual grid is kept completely separate to final rendered output, that is so I can use it for other purposes.



Hope that explains.



Cheers



Gregs