BGE proposal - Add a method to detect constraints applied on start.

Proposal = Add object.constraints or? so you can look up and manipulate constraints set on startup

reason = I can’t access Rigid Body Joints not stored at runtime.

(unless I am missing something)

p2 = Expose ‘pinning point’ as a world position for rigid body joint constraint

reason = if object gets outside of it’s joint area -> object.worldPosition = pinning point = fix

right now I tried local position using the rigid body joint target, and storing the position at frame 0

did not work so well…

Wouldn’t it be better to demand a way to get existing constraints from a game object?

e.g.


constraints = bge.constraints.getConstraints(gameObject)

Can you access rigid body joints made in the ui and not in the engine?

Last time I checked the only way to access them was to create them at runtime, though I could be mistaken.

As far as I see you can’t find any constraint with the BGE API.

You can just create one and you get the reference to it at that time. That is all I see.

yeah, it makes it cumbersome,

Why not have a go implementing it yourself? Its been a while since i’ve need to touch blender’s source, but from what i remember exposing things to python isn’t too hard and there’s plenty of examples in the source to copy from.

I got tortoise and cmake, I just need to pull down the source I think,

And so far, every post you made about pulling down and cracking the source has been just talk, as I’ve seen no activity from you on the developer website in terms of code submissions.

Is this another ‘talk’ post or are you going to do something this time?

actually the first time, I got the source code, and was trying to understand, then a factory reset, then I got git, and cmake, and tried again , and then I bought my new pc…

do you have any commits?

Usually you open a proposal, because you have an idea and you want to discuss if there are other (maybe already existing) options. It also shows if others support the idea at all.

Beside of that you might not have the skills to implement it by yourself. This does not mean you are not able to understand the BGE and what the BGE could provide.

A proposal specifies the requirement of the BGE user(s) in a clear way. Other than a “vague feature request” a BGE developer should be able to easily catch what the demand is.

Do you agree that a method to get constraints as a list per object would be good?

founded the list (or better , dictionary)


import bge
import bpy 

cont = bge.logic.getCurrentController()
own = cont.owner
gobname = own.name
target_name = bpy.data.objects[gobname].constraints["Rigid Body Joint"].target.name
constraint_name = bpy.data.objects[gobname].constraints["Rigid Body Joint"].pivot_type


print(target_name, constraint_name)



better than nothing …

I would want to know what constraints an game object has.
So yes that would be good.

It does not really matter that the same constraint belongs to another object too. So you can get it from both objects.

An alternative way would be to get all existing constraints. But that would force you to filter them somehow later. Unfortunatelly the constraint does not provide the involved game objects either. To me it looks like a very very basic Python binding.

The bpy doesn’t work in runtime, but bpy.data.objects.constraints That give some ideas for a proposal like this:

-Delete the functions: createConstraint() and removeConstraint() from bge.constraints module.

-New class type for constraints, maybe KX_Constraint? It will have functions and attributes to change their values, as axes and pivots.

-New CListValue in KX_GameObject named: constraints, it give a Clist of every “KX_Constraint” in the object (It will include the constraints crated in the viewport).

-New function createConstraint() in KX_GameObject.

So, a script would be like this:

objectA = scene.objects["Object A"]
objectB = scene.objects["Object B"]

#Get constraint that already exist
oldConstraint = objectA.constraints["oldConstraint"]

#Create new constraint
newConstraint = objectA.createConstraint(objectB, "newConstraint"...............)

#Modify constraint:
newConstraint.pivotX = float
newConstraint.pivotY = float
newConstraint.pivotZ = float

#Delete constraint
oldConstraint.remove()


What do you think? A little bad thing would be that It will be necessary to put and name to every constraint created.

Anyway, This is just an idea, and that bge’s developers have more important things to do.

I do not think that relying on bpy in any form should be expected. It is the Blender binding rather than the BGE binding.

Adding another “aspect” to the KX_GameObject will add more attributes to the already overloaded object. Nevertheless allowing to see the relationship between KX_GameObject and KX_ConstraintWrapper at both objects is no bad idea.

I think the constraints can be kept separate as they already are, but with a better integration. They do not need a name. I currently do not see what operations would benefit from a name (beside a print statement).

What we need:

  • create constraint (already exist)
  • remove constraint (already exist)
  • find all constraints of an KX_GameObject (missing)
  • find all KX_GameObjects belonging to a constraint (missing).
  • read/write access to the current constraint pivot (missing)
  • read/write access to the current constraint axis (missing)

Did I miss something?

Currently confusing to me:

  • Why do I need to know a constraint id?
  • What can I do with a constraint id?
  • Why is it not encapsulated by the KX_ConstraintWrapper?
  • Why can I get the bge.types.KX_CharacterWrapper by KX_GameObject, but bge.types.KX_VehicleWrapper by constraint id and KX_ConstraintWrapper not at all?
  • Why do I need a second KX_GameObject to create an constraint via Python, but just one when using the GUI?
  • Why do I need to know the constraint id to remove a constraint (not just the KX_ConstraintWrapper)?
  • Why do KX_ConstraintWrapper, KX_VehicleWrapper and KX_ConstraintWrapper do not have a shared super class?

Just some thoughts.

are u trying to work with ragdolls?

Yeah, I already implimented ‘part snap back’ using a object bound to where each ragdoll pieces pivot is, any work in this direction will be to lower the bar to make it easier for people to use constraints.

for parts in own['Parts']:
    if part.getDistanceTo(part['Pin'])>.15:
        part.worldPosition =part['Pin'].worldPosition 

A year ago I have done a patch that actually do this. If I have time I will update it.

Thank you hg1!

Adding another “aspect” to the KX_GameObject will add more attributes to the already overloaded object.

i agree, the methods on the gameobject is not so matter

somemodule.function(own, args)
vs
own.function(args)

the module can do the same work
maybe the methods can be added later, when all work well

They do not need a name. I currently do not see what operations would benefit from a name (beside a print statement).

well, or a dictionary with name as key , or a list with the index as key
since teoretically one gameobject can have many constraints
anyway the list can be iterated and remove the problem of name.

Currently confusing to me:

  • Why do I need to know a constraint id?
  • What can I do with a constraint id?
  • Why is it not encapsulated by the KX_ConstraintWrapper?
  • Why can I get the bge.types.KX_CharacterWrapper by KX_GameObject, but bge.types.KX_VehicleWrapper by constraint id and KX_ConstraintWrapper not at all?
  • Why do I need a second KX_GameObject to create an constraint via Python, but just one when using the GUI?
  • Why do I need to know the constraint id to remove a constraint (not just the KX_ConstraintWrapper)?
  • Why do KX_ConstraintWrapper, KX_VehicleWrapper and KX_ConstraintWrapper do not have a shared super class?

i guess is more over code old

Why do KX_ConstraintWrapper, KX_VehicleWrapper and KX_ConstraintWrapper do not have a shared super class?

this is one thing doable from python ?
i tried to subclassing KX_ConstraintWrapper but nothing …

something like this:


class SuperClass(KX_ConstraintWrapper):
    def __init__(whatarguments?): pass

EDIT: yes probably should be at the inverse :stuck_out_tongue: