[BGMC17]{Hard-Topic}Rod and hook physics!

Well, I have an idea for rod and reel physics, but I don’t know how to accomplish it. So I have rod and I(will have model, currently just cube) a hook. And I have a line as single plate. Something like rigid body joint withing rood as the object on which the hook is joined sounds good. But if I could set their distance according to a float property called lineLength. So that they have distance between them. Placing line between them would be easier, however - can I somehow make rigid body joints like that with offset?

setParam()

after the joint is made,

you will need many rbj to make the line look good.

and many planes, with the origin on 1 side, with a length of 1.

this way you can use getDistanceTo and object.localScale
to stretch each section of line between the rigid body joints,

Could you, please, make a very simplified .blend so I can see how it works? Otherwise I am a bit confused here as I have never used rigid body joints much.
Thanks for advice!:slight_smile:

look in resources, Create rigid body joint at runtime,

it’s on the first page still I think :smiley:

I don’t see it. Typed it in search and pops nothing that may match…

Yes - it looks like it works in a way I need it to do. However - I don’t understand how setting the distance between theese 2 objects work. Also - the multiple lines between hook and rod should be no collision and run script to get distance between theese 2, I must know their total length(e.g. 10.0) and divide distance by by it(3.0 / 10.0) and get length for each of theese lines and than somehow(no idea how) place them between and hook which must be somehow, IDK how, joined in rigid body joint using offset 100 % equal to the distance property on hook or rod.
Thanks for help, but unfourtunately currently I understand about 50% of all:D Could you help me by explaining most important lines of code?

it’s just all the stuff you need to form a constraint, setup and then plugged in,

it’s a pain kinda for sure.

will the line every get caught on anything ?

if the answer is no, you don’t even need rigid body joints

you need points that float in space, and attempt to match a line to the target, but gravity pulls them down,

I wanna use rigid body on hook and make it “hang” at the rod at certain distance. I will use the method that was used for laser beam at one place for making a line connect 2 objects. However - making hook change distance at which it hangs into rod is my pain. I don’t know how to do it because I have almost 0 experience in theese advanced Blender Game Engine physics…:frowning:

target = hook

Mid = (my.worldPosition+hook.worldPosition)/2

D = my.worldPosition-hook.worldPosition
D = D.magnitude

if hook.worldLinearVelocity.magnidtude < 4 or NoFishOnLine==True:
    Mid.z-=(D*.005)

there is code somewhere out there to draw a arc, you could use the 3 points and draw a arc somehow?

I gotta go, will check later.

http://www.blender.org/api/blender_python_api_2_75_release/mathutils.geometry.html?highlight=mathutils.geo#mathutils.geometry.interpolate_bezier

is a good source for making a curve. It’s not easy though, if you haven’t tried it before you might want to try something a bit simpler, like a rigged mesh line with spline IK.

Yes… Theese all resources are useful, but they are what to use after I solve what I can’t - a hook that hangs at the rod. The line should be visible and shouldn’t have any physics. The hook should have something like distance limit(the furthest distance it is allowed to be located from rod’s tip) and if it is not close enaugh, it should move at rod top direction. Otherwise it should be simple rigid body that falls. And the limit should be controlled by a property. As you see - I know what I need, but I don’t know how to achieve this… I am not sure if constraints will do this…


import bge
from bge import logic


def hook(cont):
    own = cont.owner
    scene = logic.getCurrentScene()
    
    rod = scene.objects["Rod"]
    rodTip = scene.objects["RodTip"]
    
    distance = own.getDistanceTo(rodTip)
    lineLength = rod["lineLength"]

This is what I got now, however - how do I make the hook move to direction of “RodTip”(empty placed at the tip of the rod) when distance > lineLength? Aligning axis to it is not bad idea, but I don’t know how to do it…


import bge
from bge import logic


def hook(cont):
    own = cont.owner
    scene = logic.getCurrentScene()
    
    rod = scene.objects["Rod"]
    rodTip = scene.objects["RodTip"]
    
    distance = own.getDistanceTo(rodTip)
    lineLength = rod["lineLength"]
    
    vel = own.localLinearVelocity
    
    if distance > lineLength:
        cont.activate(cont.actuators["track"])
        own.applyForce([0.0, 0.0, 100.0], True)
    else:
        cont.deactivate(cont.actuators["track"])

Why doesn’t this work? When I do if distance > lineLength, distance is 0.0 all the time and it doesn’t work. But track to is activated and works.

OK! Managed to work:


import bge
from bge import logic


def hook(cont):
    own = cont.owner
    scene = logic.getCurrentScene()
    
    rod = scene.objects["Rod"]
    rodTip = scene.objects["RodTip"]
    
    own["distance"] = own.getDistanceTo(rodTip)
    lineLength = rod["lineLength"]
    
    vel = own.localLinearVelocity
    
    if own["distance"] > lineLength:
        cont.activate(cont.actuators["track"])
        own.applyForce([0.0, 0.0, 15.0], True)
    else:
        cont.deactivate(cont.actuators["track"])

But it gets faster and stronger after time not slowing and easing down and sometimes it moves under terrain. What may be a fix?

OK! setLinearVelocity instead of applyForce:)

yes , i made time ago a thing similar and i also removed applyForce
to make a thing more right, and not more hard…



dist, glob_vec, loc_vec = own.getVectTo(rodTip)
excedence = dist - own["distance"]  # the distance out of limit
if excedence > 0.0: #out of limit
        #adjust the position first, putting the object along the limit
    own.worldPosition += glob_vec * excedence
        
        #bounce realistic
    own.worldLinearVelocity = own.worldLinearVelocity.reflect(glob_vec)
    
    # some velocity is missed in the "impact"..
    own.worldLinearVelocity *= 0.8
    
    
    
    

Hm… Your script sounds interesting. I may want to test yours later as it sounds more accurate than mine one:)


import bge
from bge import logic


def hook(cont):
    own = cont.owner
    scene = logic.getCurrentScene()
    
    rod = scene.objects["Rod"]
    target = scene.objects["throwTarget"]
    rodTip = scene.objects["RodTip"]
    
    own["distance"] = own.getDistanceTo(rodTip)
    lineLength = rod["lineLength"]
    
    vel = own.localLinearVelocity
    
    dist, glob_vec, loc_vec = own.getVectTo(rodTip)
    excedence = dist - own["distance"]  # the distance out of limit
    if excedence > 0.0: #out of limit
        #adjust the position first, putting the object along the limit
        own.worldPosition += glob_vec * excedence
            
        #bounce realistic
        own.worldLinearVelocity = own.worldLinearVelocity.reflect(glob_vec)
        
        # some velocity is missed in the "impact"..
        own.worldLinearVelocity *= 0.8
        
    if rod["fishing"] == False:
        if cont.sensors["space"].positive:
            rod["fishing"] = True
            throwVec = own.getVectTo(target)
            modifier = 5000.0
            rod["lineLength"] += 3.0
            own.applyForce(throwVec[1] * modifier, False)
    else:
        if own["distance"] < 0.5:
            rod["fishing"] = False
            
    if cont.sensors["water"].positive:
        rod["lineLength"] -= 0.05
        own["inWater"] = True
    else:
        own["inWater"] = False

it appears to work fine, but if lineLength is smaller than distance, the float and hook doesn’t move to the tip so that’s why I can’t spin the reel to pull line out of water…