Clod

I’m starting CLOD mesh now. CLOD (continuous level of detail) will be similar to discrete level of detail. Where a collection of models are swapped out as more/less detail is needed. CLOD will take a single geometry as it’s base and dynamically generate a new model with more/less vertices as needed. This will provide the benefit that only a single model is needed for CLOD, rather than multiple like Discrete LOD.



If any questions/requests are to be made, do it here.

we need more models to test this on. Il go find some :slight_smile:

Say, for example, I have a large terrain that I want to be handled by the CLOD system. But, however, I have certain features on that terrain that should never be collapsed or simplified. Will it be possible to specify that certain parts of the model/mesh/whatever not be altered?



This article on random river generation for terrain prompted me to ask. Read the section on level of detail for an explanation. In a nutshell, it’s possible that certain LOD algorithms will accidentally oversimplify the river such that it ceases to exist.



edit: brain-keyboard disconnect!

Thanks Eric, I’ll keep that in mind. At this point, I can’t say one way or the other if that will be a problem. But I will think about it now.

Feel free to grab a model of a destroyer I have posted in MilkshapeASCII at



http://willy.resounding.com/kerry/



it’s called “Acheron_Hull.txt”



I also have a question about this model:



It has 3286 polys, but the render info I see when importing it into jME shows twice this amount, even when backface culling is specified. Perhaps this is necessary owing to engine design, but could there be a flag to disable the creation of non-existent backface polys? I am looking to do a naval sim in jME and would like to be able to have double-sided polygons only where I author them (if this helps reduce the memory required to depict them in Java).



tone

Interesting, thanks for noticing this. I’ll look into it with the model you provided and see if I can find out what’s causing the extra polys to be rendered.



You are using the renderer statistics flag to get your results?

its because the poly count in milkshape counts the number of "rectangle" polygons, while in jME, we use TriMeshes (which are half "regtangles").



That would be my explanation for the high poly count, or are the poly count in jME calculated differently?

Ah, yes. We send triangles to the card, so consider each of those polygons. If Milkshape treats quads as polygons, that’s the discrepancy.

"mojomonk" wrote:

You are using the renderer statistics flag to get your results?

I copied and pasted the code for the GUI printout in TestManyChildren, except my game is a FixedLogicrategame whereas the TMC game was a SimpleGame.

I am not sure I buy the tris vs quads discussion. In my authoring tool, the meshes are triangular only and the count is the lower figure. If you ARE right, it is because (sheer guess here) that my import/export through milkshape is creating double-sided tris. I doubt this, however, as if I ask jME to cull backfaces, I can go "inside" my ship and it disappears (except in places where I created inverse faces such as the bridge and wireless cabins).

Let me take a moment to create a simpler model along the same art path -- a mesh cube. Look for it in a few minutes as cube.txt in that same web directory.

tone

okay … posted a 12 triangle green cube as cube.txt

The GUI in jME in my fixedLogicrateGame indicates that it has 24 faces.

Also interesting to note is that my FPS locks at the logic rate (32 Hz).



I quickly altered my game to be a SimpleGame and it then correctly displays 12 triangles and the frame rate leaps to 100+



Do you perhaps need my code? I wonder if we’d see the same issues if we altered TestMileshapeASCIIModel to be a fixedlogicrategame?



tone

Hmmm that’s quite interesting, looks like that is a FixedLogicrateGame bug. I’ll check into it.

Please don’t bother!



I fixed the issue. I had to clear the render statistics at the TOP of the render() function. It seems the code I copied from a SimpleGame was very dependent on update() and render() being called in alternation.



I now have a very high (but plausible?) frame rate being displayed, and the correct number of vertices/tris.



tone

Looks like I have some documentation to do. :slight_smile: I didn’t even see the problem.

A quick enhancement would be to have the Javadoc indicate what units are returned in Timer’s “long getTime()” method.



Is it a tick count? a millisecond count?



I’ll test myself to see, but if it is tick count I’d have to opine that adding one that explicitly is in seconds (as a float) or milliseconds would ease the application’s most likely desires for elapsed time representation.



For a few dollars more, have you considered altering some method names to explicitly indicate units used, e.g.: “long getElapsedMsecs()”? I find this approach makes the most readable code in the end as it can excuse reviewers of applications drawing upon the API from having to drive down to the API’s Javadoc to understand application-level logic.



Thanks for your time and effort exploring my near-bug.



tone

H’lo.



The getTime() method in Timer returns a value in ticks. The number of ticks per second is dependent on the underlying implementation, and is given by getResolution(). It would be exceedingly simple to return the number of seconds elapsed: a return value of getTime()/getResolution(). Note, however, that the seconds value would only be useful for deltas as we couldn’t guarantee that it starts at 0.0 seconds.



I’ve updated the Javdocs to be a bit clearer regarding time. I’ve also added a getTimeInSeconds() to the Timer class. Thanks for the suggestions!

To redivert this thread back to its original topic… :slight_smile:



A first cut of CLOD is finally done! wheew Check out TestClodMesh.



keys:

+,- Change level of detail

L Toggle lights

T Toggle Wireframe mode

M Toggle Model or Disc



I still need to put together an algo for automatically changing the LOD based on screen area or perhaps distance from the camera (something done manually in the test.)



Known Issue: Our ClodMesh requires that triangles in a given mesh are unique. I’m using the ASE liberty model… I wanted to use our MD2 model, Dr. Freak, but it appears to have a dozen or so triangles that overlap in the first frame, so ClodMesh dumps… I’ll get that cleaned up.



Known Issue: Well, not really an issue, but if you decrease LOD all the way on a 3d object (such as the Model in our test,) it becomes a lump of nothingness… Keep in mind that the idea is you are so far away when such a LOD is shown that it doesn’t matter.



Finally, a big thanks to Graum for helping debug the final stages of CLOD!

One other thought on CLOD. I was playing around with very large Disks (in the order of 30k+tris for a single disk) They are very nice… pretty much perfectly round, but a real dog to render. Running them through CLOD however, I can get that tri count down to 100 triangles… Going from 100 FPS to 2,000 FPS and still maintaining the nice roundness.



Bottomline? It might be benefitial to run some TriMeshes through CLOD, set it to the lower LOD and extract that as a new TriMesh. Especially useful if we ever make a way to serialize a trimesh to disk…

Update: I’ve added code to CLOD that will automatically strip out triangles that are duplicates (ie, they reference the same indices.) Dr. Freak works now. :slight_smile:

Ok, another update here. I’ve extended ClodMesh with a new class called AreaClodMesh. This uses an estimate of the BoundingVolume’s area when projected to the screen to determine how many triangles it should shoot for in the Clod. You can tune that by calling setTrisPerPixel (1 by default, lower numbers make the model decay faster.). You can also set how often it rechecks the clod record level by calling setDistanceTolerance which is how much the distance between you and the clod has to change before it will recalc the record. (also default 1.0f)



Try out TestAutoClodMesh. :slight_smile:



I think CLOD can be safely put to bed (for this version anyhow.)

I guess I should be the first to say this officially (I’ve told you elsewhere). Great job, it works fantastically. It’s this kind of thing that will seperate us from the other engines out there.