Ok, it is a bug.

Confounding, Compounding, Compound issues,

I Beg, I Plea, I do wish you…

could pick up the blend and help with this fix, you?

why would doing the exact same thing 2 times fix it :frowning:

Parent Code


import bge
from mathutils import Vector
from bge import render
scene=bge.logic.getCurrentScene()
def get_centroid_and_mass(objects):
    centroid = Vector()
    mass = 0.0
    for obj in objects:
        if 'Mass' in obj and obj.name!="Parent":
            mass += obj['Mass']
            print(mass,obj)    
    for obj in objects:
         if 'Mass' in obj and obj.name!="Parent":
            influence = obj['Mass'] / mass
            centroid += obj.worldPosition * influence
    return centroid, mass


def join_objects(obj,target):
    
    
    children = obj['target_objects']
    parent = scene.addObject('Parent', target,0)
    centroid, mass = get_centroid_and_mass(children)
    print(centroid, mass)
    parent.worldPosition = centroid
    parent.mass=mass
    
    obj['Root']=parent
    obj['RootName']=parent.name
    target['Root']=parent
    target['RootName']=parent.name
    P2=target['Parent']
    
    target.setParent(parent,1,0)
    for objects in children:
        if objects.name!="Parent" and objects.name!=target:
            objects.removeParent()
            if objects['Parent']!="Empty":
                p=objects['Parent']
                objects.setParent(p,0,0)
                R=objects['Root']
            objects['Root']=parent
            objects['RootName']=parent.name
    for objects in children:
        
        objects['Children']=objects.childrenRecursive
        objects['ChildrenNames']=str(objects['Children'])
    target['Children']=target.childrenRecursive    
    for objects in children:
        objects.removeParent()
       
        objects.setParent(parent,1,0)
    target.removeParent()
    target.setParent(parent,1,0)            
    if obj.name!="Parent":
        obj.setParent(parent, 1, 0)
    else:
        obj.applyMovement((0,0,-100),0) 
        ##obj.endObject()
    parent.worldLinearVelocity=(0,0,0)




def main():


    cont = bge.logic.getCurrentController()
    own = cont.owner
    scene=bge.logic.getCurrentScene()
    Mouse = cont.sensors['Mouse']
    Timer = cont.sensors['Property1']




    ##GetComponent A
    if Mouse.positive and Timer.positive:
        St = Vector ([0,1,0])
        Start = own.worldPosition+(own.worldOrientation * St)
        ##add= scene.addObject("HL",own,10)
        ##add.worldPosition=Start    
        St2 = Vector ([0,7.5,0])
        End = own.worldPosition+(own.worldOrientation * St2)
        ##add2= scene.addObject("HL",own,10)
        ##add2.worldPosition=End
        hitOb, hitPoint, hitNormal, hitPoly = own.rayCast(End, Start, 0, 'Tmesh', 0, 1, 1)
        render.drawLine(Start,End,(255,0,0))   
        if hitOb:
            H=hitOb
            print(H.name)
            if 'Tmesh' in H:
                if 'Component' in H:
                    if H.invalid==False:
                        T=H['Component']
                        if T.invalid==False:
                            target=H['Component']
                            print(target.name)
                            own['PtargetA']=target
                
                
                
        ##GetComponent B
        t = Vector ([0,1.5,0])
        Start2 = target.worldPosition+(target.worldOrientation * St)
        ##add= scene.addObject("HL",own,10)
        ##add.worldPosition=Start    
        St2 = Vector ([0,7.5,0])
        End2 = hitOb.worldPosition+(hitOb.worldOrientation * St2)
        hitOb2, hitPoint2, hitNormal2, hitPoly2 = hitOb.rayCast(End2, Start2, 0, 'Tmesh', 0, 1, 1)
        render.drawLine(Start2,End2,(0,0,255))
        if hitOb2:
            if 'Tmesh' in hitOb2:
                H2=hitOb2
                Component_b=H2['Component']
                own['PTargetB']=Component_b
        
        
        ## Get jack and check if occupied
        if hitPoly2 and hitOb2:
            hitMat = hitPoly2.material_name
            target['hitMat']=hitMat
            own['HitMat']=hitMat
            if 'Jack_' in hitMat:
                print(hitMat)
                if 'hitMat' in Component_b:    
                    if Component_b[hitMat]==False:
                        
                        target['Parent']=Component_b
                        target['ParentName']=Component_b.name
                        print("Jack is empty")
                        Component_b[hitMat]=True
                        hitObPos=Component_b.worldPosition
                        spot=hitObPos+hitNormal2
                        target.alignAxisToVect(-hitNormal2, 1, 1)
                        list=[]
                        target.worldPosition=spot
                        hOffset = Vector([0,-1    ,0])
                        target.worldPosition += target.worldOrientation * hOffset
                        if Component_b['Root']!="Empty":
                            p=Component_b['Root']
                            if p.invalid==False:
                                Component_b=Component_b['Root']
                                list=Component_b.childrenRecursive
                       
                                
                        else:
                            list=[]    
                        list=list+[target]
                        list=list+[Component_b]
                        Component_b['target_objects']=list
                        join_objects(Component_b,target)
                    
main()




unparent


import bge
from mathutils import Vector
scene=bge.logic.getCurrentScene()




##get center of mass
def get_centroid_and_mass(objects):
    centroid = Vector()
    mass = 0.0
    for obj in objects:
        if 'Mass' in obj and obj.name!="Parent":
            mass += obj['Mass']
            print(mass,obj)    
    for obj in objects:
         if 'Mass' in obj and obj.name!="Parent":
            influence = obj['Mass'] / mass
            centroid += obj.worldPosition * influence
    return centroid, mass
##Parent objects to "fake center"
def join_objects(obj):
    
    
    children = obj['target_objects']
    ##Add fake root
    parent = scene.addObject('Parent', obj, 0)
    ##get new center of mass and mass
    centroid, mass = get_centroid_and_mass(children)
    
    print(centroid, mass)
    ##Move Fake root to center of mass
    parent.worldPosition = centroid
    
    parent.mass = mass
    ## trying to ditch extra fake centers as ending them crashes blender
    for objects in children:
        if objects.name!="Parent":
            objects.removeParent()
            if objects['Parent']!="Empty":
                p=objects['Parent']
                objects.setParent(p,0,0)
                
            objects['Root']=parent
            objects['RootName']=parent.name
    for objects in children:
        
        objects['Children']=objects.childrenRecursive
        objects['ChildrenNames']=str(objects['Children'])
        objects.removeParent()
       
        objects.setParent(parent,1,0)
    


def main():


    cont = bge.logic.getCurrentController()
    own = cont.owner
    
    Ray = cont.sensors[ 'Ray' ]
    MouseR = cont.sensors[ 'Mouse1']
    
    
    ##selection of target of unparent logic
    if Ray.positive and MouseR.positive and own[ 'Parenttimer' ] == 0:
        target=Ray.hitObject
        ## Tmesh object
        own['RParentTarget'] = target
        ## component assosiated with Tmesh flag
        Comp=target['Component']
        ## root assosiated with component
        print(Comp.name)
        list2=[]  
        list1=[]
        if 'Children' not in target:
            target['Children']=[]
        if 'Children' in Comp:
            list2=Comp['Children']
        
            
        store=Comp    
        if Comp['Root']!="Empty":
            
            Root=Comp['Root']
        else:
            Root=Comp
            
        if Root.children!=[]:          
            for items in Root.children:
                if items!=Comp:
                    if items not in list2:
                        if items.name!="Parent":
                            list1=list1+[items]
            
        if Comp['Parent']!="Empty":
            P1=Comp['Parent']
        
            P1[Comp['hitMat']] = False
        
        
        
        
        print(list1)
        
        for items in Root.childrenRecursive:
            items.removeParent()
        
        if 'COM' in Root:
            Root.endObject()
              
        Comp.removeParent()
        Comp.reinstancePhysicsMesh()
        Comp.applyMovement((0,-1,.5),1)
        for items in list2:
            items.removeParent()
        list2=list2+[Comp]
        
        Comp['target_objects'] = list2
        Comp.removeParent()   
        print(list2)
        store['Parent']="Empty"
        if len(list2)>1:
            store['Root']="Empty"
            join_objects(Comp)
        else:
            Comp['Root']="Empty"    
        if len(list1)>1:
            
            Root['target_objects'] = list1 
            join_objects(Root)
            
        else:
            if 'COM' in Root:
                Root.endObject()
            if 'COM' not in Root:
                Root['Root']="Empty"    
main()

here is a .blend

Attachments

CompoundAssemblyV5 (1a).blend (677 KB)

You need to give some information about what your problem is, because there’s so much code there, and a lot of it is not modular enough to just read it and infer the meaning.

ok,

So we have each component- a rigid body-simple physics bounds[box] , that spawns a triangle mesh “Tmesh” Flag, the flag has materials on each side, that represent jacks on the component,
when a ray is cast at a component, it hits the flag getting a material, then it looks up that materials property , on the component. IE hitting material Jack_01 -> MAJack_01- in component.

if it’s false that means it’s empty so proceed to->

step 1
Parenting-> make list of object1(to be parented) and object2(to be parented to)
store parent in object1(to be parented)-object[‘Parent’]
and store ‘target_objects’ (object 2 and it’s children-recursive) in object 2 or if it has a fake root, root.childrenRecursive

step 2
figure center of mass of new object, and mass.
Generate hierarchy by actually parenting objects in ghost to there object[‘Parent’]

step 3
then store the hiarchy -object[‘children’]=object.childrenRecursive

step 4
then remove parent all items and parent all to new “fake root” -a compound rigid body

step 5 -ditch any old roots

part 7 unparent

generate two lists,

objects below removal item in hierarchy

objects above

do the same use list to generate center of mass etc- but for two lists.

in file,

left click =parent
right click =unparent
middle click =grab

they have timers that need a better setup. so wait 30 frames between clicks or you just reset the timer :smiley:

Problem,

when assembling, “ghosts” show up in physics (no mesh)

they are not listed in children etc,

They are cleared by removing and re-attaching the piece…

I need help identifying if this is a compound physics issue, or a I am retarded issue.

What is a “Parent Code”?

Gather list of items to be assembled into compound object

Get center of mass, and mass
parent all objects to object[‘Parent’] in ghost mode-then store object[‘Children’]=object.childrenRecursive *(build and store a hierarchy)

Remove all parenting

Add a “Parent” object (compound rigid body)

move to center of mass and set mass

See video?

I can pretty much build any compound shape, the problem seems to be related to unparent code,
or Compound physics system
Parent all objects to it in list compound no ghost

(builds compound object in game)

I could not find a translation that says “main” means “parenting”. Why is it not called “parenting” but “main”?

Why are the steps you explain not mentioned in the code? It seems you are the only one who knows what this code is meant to do. I do not even know where to look for the ghosts and children you mention in post #7.

Don’t bother explaining what your code does; It’s a mess, and not worth the time it would take to fully analyze/bugfix.

Tell us what you’re trying to accomplish. Not the programming steps, but the overall game mechanic you’re trying to produce.

That way, you can avoid the XY problem, and we could at least point you in the right direction.

PS:

You need to develop better writing skills, so that you can express yourself in a concise manner, and so that we could actually understand what you’re trying to say; Without that ability, it won’t matter how many posts/videos you make - No one will be able to help you.

It’s quality over quantity, so don’t just treat this forum as a chatroom -> Put serious thought/effort into each and every post.

Why don’t you put cube’s collision bound wrap cube?Select cube properties panel. Physics > collision bounds > convex hull.

Code purpose,

Assemble and disassemble compound rigid body objects in game with accurate physics.
(mass and center of gravity)(working)

Part 2, only allow assembly where there is a component jack, and it is unoccupied.(working)

Pablo, only simple physics bounds can be assembled,(no triangle mesh, soft body or convex hull)

My code is working I think,

either there is a error in my unparenting/split compound code code, or there is a time frame issue at play I don’t understand, or there is a bug in the compound physics,

see the video?

watch when I break off a piece, and stick it back on,
the physics bound is a single cube, the cube that is re-attached has no children,
so where are the 4 cubes coming from?

download the file? is ~670kb

here is the video

my code may be messy but that is not the bug.
Note that my messiness does not spawn new random compound bounds.

Attachments

CompoundAssemblyV5 (1a) (1).blend (677 KB)

If you can redesign it to work using rays , and have a accurate physics bounds, I will be quite happy, tbis is my 3rd time remaking this system, I learn more each time.

The end goal is like a rigid body minecraft, (not the whole world)
Just a limited amount of components per scene.

Never mind it is a bug for sure,

added objects from another layer don’t have a unique physics bound, they must use name instead of object?

Note that the assembled item had 5 blocks, the next item had the same bound,

I remove the second assembly item, then remove on block from the first, now the second assembly has 4 blocks… Proof my code is working, and the engine is not.

If I understand this right… the issue is the following:

If you add the same object twice from another layer, both of them share the same collision. If you change the collision on the first object, it changes the second one too?

yeah, at some level they are sharing compound physics data,

Yes. The helper object you should use as a compound parent (to recreate the physics bounds and center of gravity) has to be a unique mesh object. So you need LibNew. This all would have become clear if you just had talked with me in the other thread, BPR. You first have to design the system, and then put it into code. Otherwise you will just waste a lot of time digging yourself out of a lot of problems.

To give you a heads up, only LibNew will not make it work, there are other flaws in the design still which have to be addressed. One of those is: what if you want to join one cluster with another cluster? What will you do with the second LibNewed helper?

I have a case for that, I can just use if

if target[‘Children’]=[] or target[‘Children’]==“Empty”:

(I only want the player to be able to assemble single objects)
that will be in ParentCheck

I have been designing the system for almost 6 months.

So libNew will work?

I was under the impression that adding a object from a inactive layer was creating a unique copy of that item.

I showed you a video of me assembling things and said that the center of mass was wrong,
you helped me with the join_objects code, thank you btw.

if this last thing is solved I can move on to making the game.