Has anyone noticed that drawLine() is a bit strange?

It says “in the 3D scene” but you can’t tell which one :spin:. This makes it hard when using more than one scene at the same time.

Just to let you know.

Yes, i think it intends to refer to the mapping of 3d to camera space coordinates.

or perhaps it is quite limited (or still under development?)… Anyways, maybe it was designed to have one script of these in each scene where you want to use it…?

Another thing - I wonder if you can make a scene “active” and have the script run afterwards (as another parameter) - maybe it will run in the newly activated scene (or it will “only” work in the one from where the script was run?)

What about KX_Scene.pre_draw.append() and KX_Scene.post_draw.append()?

And I noticed another strange side of drawLine(). I hope somebody can tell me why.
When drawLine() was used to draw a line between 2 moving objects, there’s always a “delay” between the line and objects.
For example if I draw a line between 2 free fall cubes’ center, when the cubes are moving fast, what I got is:

That’s predictable; The BGE is a sequential engine; it processes logic before rendering and physics updates.
This means that you first draw the line between objects at their current positions, then in the next step the Physics updates, and due to gravity both objects are displaced, showing an offset.
Here Monster captures the game loop quite graphically;

The delay usually happens as well, when you try to synchronize two objects via python controller. The “copy target” seems to be one frame behind (which finally is true).

hey there… is this delayed draw somehow managable? It is a bit annoying!

I think it’s only manageable by faking a delay on the game object. So instead of parenting the visual object to the invisible physics object, let it follow by copying the worldPosition every logic tic. It’s a guess, but if the problem is that the drawLine() is just lacking one tic behind, and not drawing incorrectly, then I think it should line up.

You could probably draw the lines from and to the object’s positions plus their linear velocities divided by the logic tic rate to ‘beat’ the lag.

Hey, I suppose that could work! I’m gonna test it.

Edit: It works perfectly! Thanks for that SolarLune. Here’s the code and blend:

from bge import logic, render
from mathutils import Vector

ticRate = logic.getLogicTicRate()
vec = Vector((0, 0, 3))
color = [0, 1, 0]

def main(cont):
    own = cont.owner
    pos = own.worldPosition
    vel = own.worldLinearVelocity
    fromVec = pos + vel/ticRate
    toVec = fromVec + vec
    render.drawLine(fromVec, toVec, color)

Edit2: This fixes also the problem with the lag of objects that follow by copying the worldPosition:

from bge import logic

ticRate = logic.getLogicTicRate()

def main(cont):
    own = cont.owner
    scene = own.scene
    cube = scene.objects['Cube']
    pos = cube.worldPosition
    vel = cube.worldLinearVelocity
    own.worldPosition = pos + vel/ticRate

Edit3: Also tested if it would deviate when the object travels in a circular trajectory but it doesn’t.


DrawLineFix00.blend (82.8 KB)

The reason that this works is simple. The physics updates after the logic, meaning the logic will actually have an old position if it tries to read it. Therefore as physics applies the updates from the specified linear velocity it will always show the correct value.

That’s what I was thinking after testing this with circular motion. If the physics would be updated from the new value then it would deviate. But I didn’t know that until now. So that’s great!

Can a vertex be placed by the physics engine?

Can you initiate the line in logic, and have the physics move the vertex to the correct position ?

what happens if I draw a line, and then output a mesh that is hooked to a armature, and the armatures’ base is 1 connection point, and it’s top is the other, and physics places the “Target” and “Base” using RBJ’s ???

will this be accurate?

Another question, how do I define a face for physics collision or a bounding box for a drawn line? spawn a object instead?