LoD system

Hi,

I need some help with implementing an LoD system. Is there an easy way to do it with python instead of using the add object logic brick? :confused:. I need to know because I am working on a very large city and I want three levels of buildings:

Level 1: Very detailed, Shows windows, street lamps, fire hydrants, phone booths, etc.

Level 2: Medium detail, includes just square buildings with windows(windows are seperate objects btw).

Level 3: Low detail, square buildings.

Could someone point me to a tutorial, show me an example, or make a demo using cubes?

I have a feeling I would be able to do it with logic bricks, since I don’t know python, except I think python would be much cleaner, especially since the amount of buildings I am using is very large.

Thanks in advance,
-Wunderlust

You mean so anyone can choose the amount of detail in a game? I’d just do this. When the games finished duplicate the game scenes 3 times and just remove stuff on the low detail ones.

no,

LoD stants for Level of Detail, basically, objects closer to the player are higher-detailed. The further away they get, the less detail they have. Many games use systems like this. Take Guild Wars for example. They use alpha trees at far distances, when you approach the tree, it gets “replaced” with multi-poly tree.

Now, what I would like to do is implement a very similiar system, except with buildings, If you are really close, the buildings have lots of detail with windows etc. You can see fire hydrants and smaller details. Then as you get further away, the building would be replaced with a Low poly “cube” version of the building with a similiar texture, and the little details get removed. Thus improving performance.

I just need some help setting this system up with python. So, If anyone feels as though they may be able to help, please say something. I would be more than happy to do something in return.

-Wunderlust

Well, I made a rather simple LOD code on the Hero of the Day game for the buildings, the good thing is that it works pretty well, look around the noobs 2.0 thread, adn if posible, look out for the version Gomer did, is an optimisation of my own code :smiley:
The bad thing is that I don’t know where it is on the thread…

I could see If I could whip something up tomorrow. No need for python. Just use ray sensors at various distance and use replace mesh.

Hmmm good luck with that, but im afraid its probubly not something you can ‘whip up’ in a day.

@Wunderlust
Id be sending a PM to haidme, hes just implemented some LOD is his Krum game. Id be interested in seeing how to do it in the GE as well, as ill be needing it soon…

I’m whipping up something now, I’ll post the blend in 5-10 mins.

It would only take like 5 minutes. Literally I’ll post my version in a sec.

Lol ok.
Id be happy to see you both prove me wrong.

Ok, here’s my version of it. It’s very basic, but you get the basic idea.

Attachments

LoD.blend (166 KB)

Hmm,

There are a couple issues with this.

First off, and most importantly, The cube does not change back to a plane when you get a certain distance away from it. I believe this will not work with the “replace mesh” actuator.

Secondly, If you did find a solution, I believe this would be way to many logic bricks. Especially for a city with 50 - 100 buildings in it. I think a script would be better.

Thank you at least for attemtping!

-Wunderlust

I believe I have found what I am looking for from the Noobs 2.0 project thread, as CloudGL directed me. I had to dig though 30 pages to find this:

import GameLogic as G
from math import sqrt
from math import pow
c = G.getCurrentController()
o = c.getOwner()

scene = G.getCurrentScene()
cam = scene.getObjectList()[“OBE”]
#OBE is an object called E (is an empty parented to the camera)
where = cam.getPosition()
ownpos = o.getPosition()
xp = where[0] - ownpos[0]
yp = where[1] - ownpos[1]
zp = where[2] - ownpos[2]
tot = pow(xp,2) + pow(yp,2) + pow(zp,2)
distance = sqrt(tot)
if distance < 10:
o.range = 1
else:
o.range = 0

And the example blend:
http://cloud.gl.googlepages.com/lodTests2.blend

-Wunderlust

Oh you can easily turn it back into it. Ok for a script you would use the same sort of method. just use ray sensors for that stuff like

if ray.isPositive() and lod.isNegative():
changedetail
if ray.isNegative() and lod.isPositive():
changedetail

that sort of method.

Idk though.

This example uses python.

I used 3 objects all representing a sphere and an empty to put the script on.

The main functions I use in the example are “getDistanceTo()” and “setVisible()”.
getDistanceTo() is used to see how fat the player is, I used it like this:

dis = own.getDistanceTo(player)

and then setVisible() was used to change the objects visiblilty.

detail1.setVisible(0) - Invisible
detail1.setVisible(1) - Visible

W - Foreward
S - Backwards

If you need more help understanding the script just tell me.

Attachments

lod.blend (147 KB)

This is EXACTLY what I wanted, thank you! Do you think there is any way you could “optimize” this to use more python, less logic bricks? Or does it matter? And would I have to go through and add this stuff to Every object or could I just duplicate them and have it still work?

As for doing multiple buildings it would be best to move the script onto your main object, the player or onto an empty that has all the script running off it.

You would need to name buildings like “building1_detail1”, “building1_detail2” ect and the script would need to be edited like so.

The variable definitions need to change:

building1_detail1 = GameLogic.getCurrentScene().getObjectList()["OBBuilding1_Detail1"]
building1_detail2 = GameLogic.getCurrentScene().getObjectList()["OBBuilding1_Detail2"]
building1_detail3 = GameLogic.getCurrentScene().getObjectList()["OBBuilding1_Detail3"]

building2_detail1 = GameLogic.getCurrentScene().getObjectList()["OBBuilding2_Detail1"]
building2_detail2 = GameLogic.getCurrentScene().getObjectList()["OBBuilding2_Detail2"]
building2_detail3 = GameLogic.getCurrentScene().getObjectList()["OBBuilding2_Detail3"]

You would also need to change the dis variable like this:

building1_dis = building1_detail1.getDistanceTo(player)
building2_dis = building2_detail1.getDistanceTo(player)

And the if commands should look like this:

if (building1_dis &gt;= 15):
    building1_detail3.setVisible(1)
    building1_detail2.setVisible(0)
    building1_detail1.setVisible(0)
elif (building1_dis &lt;= 5):
    building1_detail3.setVisible(0)
    building1_detail2.setVisible(0)
    building1_detail1.setVisible(1)
else:
    building1_detail3.setVisible(0)
    building1_detail2.setVisible(1)
    building1_detail1.setVisible(0)

if (building2_dis &gt;= 15):
     building2_detail3.setVisible(1)
     building2_detail2.setVisible(0)
     building2_detail1.setVisible(0)
 elif (building2_dis &lt;= 5):
     building2_detail3.setVisible(0)
     building2_detail2.setVisible(0)
     building2_detail1.setVisible(1)
 else:
     building2_detail3.setVisible(0)
     building2_detail2.setVisible(1)
     building2_detail1.setVisible(0)

There is no logic bricks execpt for the script controller, sorry for the messy code, I had logic bricks in my first example then I change to all python and forgot to clean up ><

Here is what the code should look like, and you can delete all the visiblity actuators.

#===================================================================
#Import Modules
#===================================================================
import GameLogic

#===================================================================
#Instance Variables
#===================================================================
cont = GameLogic.getCurrentController()
own = GameLogic.getCurrentController().getOwner()

player = GameLogic.getCurrentScene().getObjectList()["OBPlayer"]
detail1 = GameLogic.getCurrentScene().getObjectList()["OBDetail1"]
detail2 = GameLogic.getCurrentScene().getObjectList()["OBDetail2"]
detail3 = GameLogic.getCurrentScene().getObjectList()["OBDetail3"]

dis = own.getDistanceTo(player)

#===================================================================
#Determine Detail
#===================================================================
if (dis &gt;= 15):
    own.LoD = 3
    detail3.setVisible(1)
    detail2.setVisible(0)
    detail1.setVisible(0)
elif (dis &lt;= 5):
    own.LoD = 1
    detail3.setVisible(0)
    detail2.setVisible(0)
    detail1.setVisible(1)
else:
    own.LoD = 2
    detail3.setVisible(0)
    detail2.setVisible(1)
    detail1.setVisible(0)

Doesn’t this have to “check up” on every building though, making it slow? I’m not the best at python/scripting. So I may need some help implementing this, check your private messages.

-Wunderlust

It does have to check up once on every building, its quick though. It only calculates the distance once and does only simple math operations to determine what detail it should be in. You could also add a bit of code that checks if the player is moving and only updates then, because the buildings won’t change if the players not moving.

Nice andrew-101

Ill be studying this also. :cool:

Proven wrong? :eyebrowlift2: