Proof of physics LOD's utility

Attachments

PhysicsLODKDTree.blend (427 KB)

Is this an LOD for physics? I have been dying for something like this! Although, either way I don’t understand this at all, could you walk me through how I could implement this? Sorry, just starting to learn a lot with the BGE.

step 1
ok- make a GFX object and a Physics object(invisible) for each object

so make the name of the physics item, the name of the GFX item + _Physics

like

Tree and Tree_Physics

add a property to any item that will have physics LOD, PLOD?

step2
use


import bge
import mathutils
from mathutils import Vector
if 'KD' not in own:
    obList = []
    for objects in own.scene.objects:
        if 'PLOD' in objects:
            obList.append(objects)

    size = len(oblist)        
    kd = mathutils.kdtree.KDTree(size)
    index=0
    for object in obList:
        kd.insert(objects.worldPosition,index)
        index+=1
    kd.balance()
    own['KD']=kd
    own['PList']=obList

run this on frame 0 to build a KDTree for items that are static only*

then you can use this each frame to add/remove physics for each item
(like) - (I rewrote it to be even faster)

delay - 1 frame------------------(physicsLOD)


import bge




def main():


    cont = bge.logic.getCurrentController()
    own = cont.owner
    
    if 'Actor' not in own:
        own['Actor']=own.scene.objects['Actor']


        
    kd = own['KD']
    
    close =[]
    
    Pos = own['Actor'].worldPosition


    #Get all objects inside a 25 unit radius, if they need physics add it
    for (co, index, dist) in kd.find_range(Pos, 25):
        close.append(index)
        if 'phys' not in own['PList'][index][1]:
            nStr =own['PList'][index][1].name+"_Physics"
            own['PList'][index][1]['phys']=own.scene.addObject(nStr,own['PList'][index][1],0)
            own['PList'][index][1]['phys'].setParent(own['PList'][index][1],0,0)

    #Get all units inside a 30 unit radius, if they are not in the 25 unit list they need physics removed
    for (co, index, dist) in kd.find_range(Pos, 30):
        if index not in close:
            if 'phys' in own['PList'][index][1]:
                own['PList'][index][1]['phys'].endObject()
                del own['PList'][index][1]['phys']
        
  
                    
main()



Effectively this makes a loading bubble, and a unloading bubble for physics

This is fucking amazing. How are there not more comments on this. Thanks BPR!

As you told by youself - no comment! :wink:
Cool!:slight_smile:

Thanks Guys!

edit:
I noticed a single issue (the kd generator vs the applier had a discrepancy )
own[‘PList’][index][1] needed replaced with own[‘PList’][index]

import bge


def main():


    cont = bge.logic.getCurrentController()
    own = cont.owner
    
    if 'Actor' not in own:
        own['Actor']=own.scene.objects['Actor']


        
    kd = own['KD']
    
    close =[]
    
    Pos = own['Actor'].worldPosition


    #Get all objects inside a 25 unit radius, if they need physics add it
    for (co, index, dist) in kd.find_range(Pos, 25):
        close.append(index)
        if 'phys' not in own['PList'][index]:
            nStr =own['PList'][index].name+"_Physics"
            own['PList'][index]['phys']=own.scene.addObject(nStr,own['PList'][index],0)
            own['PList'][index]['phys'].setParent(own['PList'][index],0,0)

    #Get all units inside a 30 unit radius, if they are not in the 25 unit list they need physics removed
    for (co, index, dist) in kd.find_range(Pos, 30):
        if index not in close:
            if 'phys' in own['PList'][index]:
                own['PList'][index]['phys'].endObject()
                del own['PList'][index]'phys'] 

edit: In upbge they recently added a command to suspendPhysics and restorePhysics,
should in theory be even faster !

I will add a demo here when I get the time :smiley:

You could also limit it to the cone of vision of the actor to make it even more efficient. This proves why BGE is much better then Unity.

In upbge they recently added a command to suspendPhysics and restorePhysics,
should in theory be even faster !

So why don’t you use it in bge :stuck_out_tongue: it was always there

if distance > 150:
                
        #maak ontzichtbaar en stop physics
        obj.visible = False
        obj.suspendDynamics()
            
    else:
                
        #maak zichtbaar en re-activeer physics
        obj.restoreDynamics()
        obj.visible = True

no that only removes dynamics, static meshes physics is still calculated every frame, if you have a large open world, you run into physics adding up quite a bit.

in a 100x100 maze with up to 4 box colliders per maze tile was dropping the framerate below 60 fps witbout any other effects,

with physics lod the same scene used .3 ish ms logic and less then 1 ms physics.(including the cost of deleting and adding the physics mesh instances.)

what upbge is adding, is a offswitch for all physics essentially making a object no collision. and it you can flip it back on.