trouble using libnew

am I doing this wrong?


import bge
from mathutils import Vector


def root(gobj):
    while (gobj.parent):
        gobj=gobj.parent
    
    
    return gobj


def main():


    cont = bge.logic.getCurrentController()
    own = cont.owner
    if 'BuiltIt' not in own:
        own['BuiltIt']=bge.logic.getCurrentScene().objects['BuildIt']
    popped =[]
    
    for child in own.childrenRecursive:
        if child['Parent']==own:
            child['Parent']="Empty"
        child.removeParent()
        child.applyForce((0,0,.00001),0)
        if type(child['Parent']) is not str:
            child.setParent(child['Parent'],1,0)
            print('2')
        popped.append(child)
        
    for child in popped:
        print('1')
        child['Root']=root(child)
        names=str(child['Num'])
        print("root of "+names+" is "+str(root(child)))
        
        
    for child in popped:
        num=0    
        if child['Root']==child:
            child['COM']=Vector([0,0,0])
            
            for children in child.childrenRecursive:
                child['COM']+=Vector(children.worldPosition)
                num+=1
            
            child['COM']*=1/num
                    
    for child in popped:    
        if child['Root']==child:
            ##Need Libn
            own['BuiltIt']['AddedRoots']+=1
            
            
            
           
            
            print(str(own['BuiltIt']['AddedRoots']))
            
            OldObject=bge.logic.getCurrentScene().addObject('Root',child,0)
            print("Old mesh is "+OldObject.meshes[0].name)
            NameOfMesh=bge.logic.getCurrentScene().objectsInactive['Root'].meshes[0].name
            print('New mesh name should be '+"Rooot"+str(own['BuiltIt']['AddedRoots']))
           
            New_mesh = bge.logic.LibNew("Rooot"+str(own['BuiltIt']['AddedRoots']),'Mesh', [NameOfMesh])
            print(str(New_mesh)) 
            OldObject.replaceMesh(New_mesh[0],1,1)
            print("New mesh is "+OldObject.meshes[0].name)
            OldObject.worldPosition=child['COM']
            
            for child2 in child.childrenRecursive:
                child2.setParent(OldObject,1,0)
            child.setParent(OldObject,1,0)    
            print('NewRoot is'+OldObject.name)
                
        
    
    
           
    
    
        
    
main()



trying to generate new meshes named Rooot1 and Rooot2,

instead I am getting Plane.002 and Plane.002??

press P, left click on the cube to build it, press space to snap off any of it’s children with new compound roots,

for some reason the new compound roots libNew mesh, is the same 2 times in a row???

Attachments

LibNewTrouble.blend (578 KB)

more over is this code that generate too many bugs:

New_mesh = bge.logic.LibNew(“Rooot”+str(own[‘BuiltIt’][‘AddedRoots’]),‘Mesh’, [NameOfMesh])

:smiley:

im not sure if is what you try to do .
this replace the mesh of children with a mesh duplicated.
the meshes created should be stored in GD[“meshes_copies”]


import bge


def get_global_meshes_copies():
    key = "meshes_copies"
    if not key in bge.logic.globalDict:
        bge.logic.globalDict[key] = {}
    return bge.logic.globalDict[key]


def create_mesh_copy(old_mesh_name):    
    def get_name_unique(name, n=0):
        if name + str(n) in bge.logic.LibList():
            return get_name_unique(name, n+1)
        new_name = name + str(n)
        return new_name
    
    new_mesh_name = get_name_unique(old_mesh_name)
    new_mesh_obj = bge.logic.LibNew(new_mesh_name, 'Mesh', [old_mesh_name])[0]
    
        
    get_global_meshes_copies()[new_mesh_name] = new_mesh_obj


    return new_mesh_obj








def main():
    
    def get_owner():
        cont = bge.logic.getCurrentController()
        own = cont.owner
        return own
    
    own = get_owner()
    if not "init" in own:
        name_old_mesh = bge.logic.getCurrentScene().objectsInactive['Root'].meshes[0].name
        
        for chi in own.children:
            new_mesh = create_mesh_copy(name_old_mesh)
            chi.replaceMesh(new_mesh)
    own["init"] = 1

    
main()



EDIT: correct some bug (due to the motion modules -> sctipt)

PS:
not there something of strange that to check the names of the meshes you have to check in <bge.logic.LibList()> ???

is not the same list that contain the blends charged with LibLoad() ???

what i mean is, should not be bge.logic.LibListMesh() ?

apparently the libNew does not create a new physics mesh anyway?

there is a bug in the tracker,

well the object that get a new mesh must be obj with triangle collision then add -> obj_replaced.reinstancePhysicsMesh()

this work just as should

umh, on children 1 work , on children 2 not…


import bge


def get_global_meshes_copies():
    key = "meshes_copies"
    if not key in bge.logic.globalDict:
        bge.logic.globalDict[key] = {}
    return bge.logic.globalDict[key]


def create_mesh_copy(old_mesh_name):    
    def get_name_unique(name, n=0):
        if name + str(n) in bge.logic.LibList():
            return get_name_unique(name, n+1)
        new_name = name + str(n)
        print(new_name)
        return new_name
    
    new_mesh_name = get_name_unique(old_mesh_name)
    new_mesh_obj = bge.logic.LibNew(new_mesh_name, 'Mesh', [old_mesh_name])[0]
    
    key = "meshes_copies"
    if not key in bge.logic.globalDict:
        bge.logic.globalDict[key] = {}
        
    get_global_meshes_copies()[new_mesh_name] = new_mesh_obj


    return new_mesh_obj








def main():
    
    def get_owner():
        cont = bge.logic.getCurrentController()
        own = cont.owner
        return own
    
    own = get_owner()
    if not "init" in own:
        gob_to_copy = bge.logic.getCurrentScene().objectsInactive['Root']
        name_old_mesh = gob_to_copy.meshes[0].name
        
        for chi in own.children:
            new_mesh = create_mesh_copy(name_old_mesh)
            chi.replaceMesh(new_mesh)
            chi.reinstancePhysicsMesh(gob_to_copy, new_mesh)
        own["init"] = 1


    
main()





EDIT: removed some other(custom) bugs , but work only on 1 children -> seem a bug of bge

I suggest to post code that is reduced to the point. All this unnecessary things are just confusing and distracting. I mean creating the new object is just one statement. Lets add some configuration operations … it should not be more than 5 lines.

If my bike is broken I do not bring in my whole house.

yeah, the added object that gets the libloaded mesh, still has the same physics mesh, (I talked to panzertank for a while last night)

if you spawn 1 instance of the mesh, and parent a bunch of stuff to it, compound, when you spawn in another copy, and see its physics bounds, it has the compound physics bound of the original. (even if it gets a libNew mesh)

replacing another children with (apparently) exactly the same setup now work perfectly with any number of children(s).

agree with removing all code useless .

post just this since work :wink: (removed a bit of trash code but added some other for test if robust ;))


import bge,random


def get_global_meshes_copies():
    key = "meshes_copies"
    if not key in bge.logic.globalDict:
        bge.logic.globalDict[key] = {}
    return bge.logic.globalDict[key]


def create_mesh_copy(old_mesh_name):    
    def get_name_unique(name, n=0):
        if name + str(n) in bge.logic.LibList():
            return get_name_unique(name, n+1)
        new_name = name + str(n)
        print(new_name)
        return new_name
    
    new_mesh_name = get_name_unique(old_mesh_name)
    new_mesh_obj = bge.logic.LibNew(new_mesh_name, 'Mesh', [old_mesh_name])[0]
        
    get_global_meshes_copies()[new_mesh_name] = new_mesh_obj


    return new_mesh_obj








def main():
    cont = bge.logic.getCurrentController()
    own = cont.owner


    if not "init" in own:
        gob_to_copy = bge.logic.getCurrentScene().objectsInactive['Root']
        name_old_mesh = gob_to_copy.meshes[0].name
        
        for chi in own.children:
            new_mesh = create_mesh_copy(name_old_mesh)
            chi.replaceMesh(new_mesh)
            fac = random.random()
            def mesh_deform():
                mesh = chi.meshes[0]
                for n in range(mesh.getVertexArrayLength(0)):
                    vert = mesh.getVertex(0,n)
                    vert.XYZ *= 1.0 + fac * 5
            mesh_deform()
            
            chi.reinstancePhysicsMesh(chi, new_mesh)
        own["init"] = 1


    
main()



SO: -> no bugs(about the physic)
still just a bit complex manage these “copies” (even tried to use LibFree())

I used your function :smiley: same bugs

it’s a nice function though :smiley:

Panzertank says that it’s re-instance physics mesh that needs love , as replacemesh calls it to update the physics mesh,
it just does not do what it’s supposed to,

https://developer.blender.org/T40955

Here is a demo that shows that it works. You need to care some requirements:

  • The owner must have collision bounds triangle mesh in the physics tab. Otherwise the physics shape will remain as set in the tab regardless of the meshes shape.
  • Replace mesh must have set usePhysicsMesh=True. Otherwise only the visible shape will change.

reinstancePhysicsMesh is only needed on skin mesh objects (deformed on armatures) - which should match your situation.

The working demo should look like that:

  • watch the cubes fall and
  • press <space> to see the spheres roll

This is the scene:


Attachments

LibNewDemo.blend (486 KB)

triangle mesh does not work with compund assembly,

(bumping a child rotates and pushes on the root in compound assembly)

I can’t help on compounds. I rarely use them.

Edit: how about a rigid body joint constraint?

Panzertank and lordLoki / the developers - said they were already working on this - ReinstancePhysicsMesh(argument, argument,argument)

apparently replace physics mesh did not actually grab the physics of the object unless it was a triangle mesh
(they are changing that)