28 June 2017

New Mesh generation

After a long time being blocked by professionnal projects and constraints, I come back to my small self-learning game project. I made several modification to my project, mainly on the graphical side, following a brutal change of PC with no save...


Full Mesh generation

First, the map display was previously created by generating a set of face (top and side), and then using a library (JMonkeyEngine) functionnality to batch those individual meshes into one mesh.

I tried a different way, by generating the whole mesh directly. At first I created only the top surface. Since i know the number of hex, I just had to multiply by seven to get the number of vertices; Of course this mean that i do not share vertex between hex, but since they can be at different height, or have different UV, this is not really a point.
We can then work from hex to hex, adding the point, UV, colors, and then indicate wich point form the cell's triangles.

for each column
for each line

   get cell data
   startCellIndex = indexPoint;
   point (indexPoint++) = center
   point (indexPoint++) = peripheral point
   // ... 5 others peripheral points
   

   texture(indexUV++) = center UV
   texture(indexUV++) = peripheral pointUV
   // ... 5 others peripheral points

   // and now add the triangles
   triangle(indexTriangle++) = startCellIndex
   triangle(indexTriangle++) = startCellIndex+1
   triangle(indexTriangle++) = startCellIndex+2
   triangle(indexTriangle++) = startCellIndex
   triangle(indexTriangle++) = startCellIndex+2
   triangle(indexTriangle++) = startCellIndex+3
   //... 4 others triangles



I then added the side mesh in the same way in a second mesh, with the added minor complexity that not all side are to be present (only the one where the neighbours i lower or empty).


Advantages

The selection is a bit faster. Since, when generating a cell, I now know the position of the center, I add it to a HashMap, associated to the cell. When there is a click on the mesh, I get the collision triangle and can check the 3 coordinates against the HashMap. In the old version, I add to perform a ray analysis to get the cell-level intersected mesh and get its Id to know the cell selected.

Also since I know the position of the points / color / uv in the mesh, I can modify those points. For exemple I have developped a set of "cell color extractors" class that take a cell and return a color. One use the terrain to get the color, another us the light, a third us the height... I can use those extractor to recalculate the color of the mesh (and only the color), and re-inject this in the mesh. Presto, we got different views of the map, a bit like the different terrain view in the old "Capitalism" game.


The following image takes four different colorizer for 4 part of the map.


Last I was generating a set of cell and then merging them into batch meshes. This was really time consumming. Currently a 128*128 map takes only a few milliseconds to generate, compared to the full half-minute it took for the previous version.

Disadvantage

Since I'm doing one mesh, i can only have one material. For a very variable look, I'll have to use  a texture atlas. Since I was already doing this, this is not to much of a assle.

Map Look 

Each terrain type is defined in a description file. The terrain id  is associated with 
  • a rule-section to define effect of the terrain with the game (currently only minimal light level on the terrain). 
  • a set of representations. Each representation gives a base color for the hex (color), a position on the texture map for the center of the cell (position), the size of the block on the texture map, and a color for height lines. Some of those can be used or not, depending on the display that is generated.
    <terrain id="dirt">
        <informations></informations>
        <representation>
            <line>rgb(229, 178, 073, 255)</line>
            <color>rgb(229, 178, 073, 255)</color>
 
            <position>0.25 / 0.25</position>           
            <size>0.25</size> 
        </representation>
        <representation>

             <line>rgb(229, 178, 073, 255)</line>            
             <color>rgb(226, 170, 056, 255)</color>            
             <position>0.75 / 0.25</position>            
             <size>0.25</size>
         </representation>
    </terrain>


During the display generation, when creating a cell representation, a random representation of the cell's terrain type is selected.

Development notes

If there is one thing that my projet showed me, this is that, even for a personnal project, a correct developement environment is a must. I lost the first version  this projet because of a bad SSD, and that was my fault. Since then, the project has been linked to a GitHub account.

In the same idea, I now use SonarQube weekly on the project. While this does not mean the code is correct, it help having a project that is maintainable, 

No comments:

Post a Comment