RigsOfRods / rigs-of-rods

Main development repository for Rigs of Rods soft-body physics simulator
https://www.rigsofrods.org
GNU General Public License v3.0
990 stars 175 forks source link

AngelScript: FreeForces (with a PartyBaloon demo mod) #3159

Open ohlidalp opened 2 weeks ago

ohlidalp commented 2 weeks ago

FreeForces are global, persistent forces which act upon one node of one actor each. They exist separately from actors and their existing hook/tie/rope interactions. This means they do not interfere with actor N/B or any of the existing linking logic. They're intended for creating special physics effects which aren't supported otherwise, like making party baloons fly. They're intentionally only accessible from scripts to maximize their flexibility and limit maintenance of the codebase.

desperadoBaloonsV2

To manage FreeForces, you use game.pushMessage() with MSG_SIM_ADD_FREEFORCE_REQUESTED, MSG_SIM_MODIFY_FREEFORCE_REQUESTED or MSG_SIM_REMOVE_FREEFORCE_REQUESTED.

Parameters common to ADD/MODIFY requests:

Additional parameters for FREEFORCETYPE_TOWARDS_COORDS:

Additional parameters for FREEFORCETYPE_TOWARDS_NODE:

Note when any of the actors involved in a FreeForce (be it the base one or target one), the freeforce is deleted.

Example from the PartyBaloon demo mod:

    // Create the up-force
    upforce_assigned_id = game.getFreeForceNextId();
    game.pushMessage(MSG_SIM_ADD_FREEFORCE_REQUESTED, {
        {'id', upforce_assigned_id },
        {'type', FREEFORCETYPE_CONSTANT },
        {'base_actor', thisActor.getInstanceId() },  // `BeamClass@ thisActor`is automatic global variable for scripts bound to actors.
        {'base_node', UPFORCE_NODE },
        {'force_const_direction', vector3(0, 1, 0) }, // Y=up
        {'force_magnitude', 0.4f } // Newton/meters
    });

Keep in mind that the physics simulation runs at 2khz (2000 steps per second), while scripts run in sync with FPS. That's why there's no option to add temporary/one-off force impulses from scripts - you are responsible for adding the persistent force, monitoring and adjusting it as needed, and then removing it when no longer necessary. You can create the forces as dummy and then change their type later as needed.

Below is the demo PartyBaloon mod. It weights only 12 grams (0.012 Kg) and under our simulation it moves very slowly, not bypasing a certain threshold, regardless of pull force applied to it. By default, it will just fly off (you can grab it with mouse) but you can use console variables to bind it somewhere: obrazek The script bundled with the baloon will read these variables and create an additional FreeForce towards either the spawn position or given node on given actor. Download PartyBaloon-12grams.zip

Have fun!

Miner34dev commented 3 days ago

Not sure why, but game.getCurrentTruck().getInstanceId() doesn't work (trows an error) and i don't know what actor is the car to attach the baloon to. I don't think it was broken by this PR, it's months the entire angelscript panel (together with any getCurrentTruck() related command) don't work in dev builds.

ohlidalp commented 3 days ago

@Miner34dev That's a quirk of our present reference-counting mechanism, sorry about that, I haven't yet found a way to fix it. You must do either game.getCurrentTruck().getHandle().getInstanceId() or BeamClass@ b = game.getCurrentTruck(); b.getInstanceId() because the return type isn't BeamClass@ but rather BeamClassPtr@ More info is at https://github.com/ohlidalp/RefCountingObject-AngelScript

Miner34dev commented 2 days ago

How does this affect performance? I have to apply a force to over 500 nodes, is it going to make me lag/crash?

Miner34dev commented 2 days ago

How does this affect performance? I have to apply a force to over 500 nodes, is it going to make me lag/crash?

Tested it out, it's completely fine (at least if i add the force at the start and then leave it untouched.)

Miner34dev commented 1 day ago

I'm having a problem with FREEFORCETYPE_TOWARDS_COORDS (i haven't tested with the other ones though), i can't change anything withMSG_SIM_MODIFY_FREEFORCE_REQUESTED, it has no effect. The modification is called from frameStep(). Am i doing something wrong, or is this a bug?