Enable/disable physics on a specific body?

edited April 2012 in Help request
Hi again, have been looking here and there but I can't figure out how to achieve this (which I am sure should be trivial):

I have an object with a physics body configured. I want it to not start simulating until it's triggered by an event in my code.

Is there a way to configure it to have its physics disabled from the start, and then enable physics on it later? Or is there a way to attach a physics body programmatically, when I want it to start simulating?

Hope this makes sense - I'm sure I'm missing something obvious...

Comments

  • edited April 2012
    Hi!

    Unfortunately you can't simply enable/disable a body as Box2D doesn't allow me to do that.

    However you can delete/create a body or even simply create/delete body parts at runtime (if you simply want to suppress collisions, for example).

    Or if it's only collision effects you want to suppress, you can call orxBody_SetPartSolid() and turn all your parts non-solid (collision events will still be sent but won't affect the dynamics of your object).

    For finding/removing/adding parts, have a look at orxBody_GetNextPart/_GetPartName/_DeletePart/_AddPartFromConfig.

    Now if you really want to completely remove the body of your object, I'd suggest not creating it in config but still storing its name in a different config key (something like FuturBody = ...).

    Then when you want to add your body, here's the code needed:
    orxConfig_PushSection(orxConfig_GetName(MyObject));
    MyBody = orxBody_CreateFromConfig(orxConfig_GetString("FutureBody"));
    orxObject_LinkStructure(MyObject, orxSTRUCTURE(MyBody));
    orxConfig_PopSection();
    

    But in this case note that, as you've created the body yourself, orx will not be responsible of deleting it: you'll have to delete it yourself.

    For example, if you listen to the event orxOBJECT_EVENT_DELETE, when handling it do:
    if(!orxString_Compare(orxObject_GetName(EventObject), "ObjectWithFutureBody"))
    {
      orxBODY *MyBody = orxOBJECT_GET_STRUCTURE(EventObject, BODY);
    
      if(MyBody)
      {
        orxObject_UnlinkStructure(EventObject, orxSTRUCTURE_ID_BODY);
    
        orxBody_Delete(MyBody);
      }
    }
    

    An alternative option if you don't want to do the creation/deletion of the body yourself would be to replace your object when you need a body: ie. delete it, replace it with a version that has a body, but in that case you need either to know its state or copy its info before re-applying them to the new object (like position, rotation, anim frame, etc).

    You can even do that with some config manipulation at runtime, something like having the FutureBody section as mentioned above when creating the first version of the object, and do that when creating the new version of the object:
    orxConfig_PushSection(orxObject_GetName(MyObject));
    orxConfig_SetString("Body", orxConfig_GetString("FutureBody"));
    orxObject_Delete(MyObject);
    MyObject = orxObject_CreateFromConfig("ObjectWithFutureBody");
    orxConfig_SetString("Body", orxSTRING_EMPTY);
    orxConfig_PopSection();
    
  • edited April 2012
    Thanks very much for that! Was unaware of how the linking/unlinking worked, that looks like it would be very useful (not just for this specific purpose).

    I'll experiment a bit with this and let you know how it goes.
  • edited April 2012
    Yep, it can be done with all the structures "supported" by orxOBJECTs. Though in most cases they can be enabled/disabled instead of completely removed, orxBODY being a special case. :)
  • jimjim
    edited December 2012
    Merry Christmas and Happy New year to all, I hope everybody is enjoying their vacation. Its great that ORXv1.4rc0 is released, I still have exams and class projects, but I have re-started my journey with orx :) I have found in box2d manual that there is a way to disable a body so that it does no take part in collision. its called activation, it can be defined as
    bodyDef.active = true;
    

    There is also mouse joints, group index that I could not find in orx right now. I think as iarwain said in other post, orx is currently using a modified version and an older version of box2d than current box2d release. So updating the physics engine would solve this kind of problems.
  • edited December 2012
    Hey Jim, nice to see you around! :)

    As for per-body deactivation, it's now handled in orx (more details here). :)

    Mouse joint is the only type of joint that is not supported as it's easy to get the same result with a couple lines of code (and Box2D's author acknowledges that this joint is a convenience hack).

    And finally, group indices don't exist in orx either. I can't really think of a situation where they'd be really needed in addition to the traditional flags/masks used by most of the physics engine.

    I also plan to soon add something to make physics flags/masks a tad bit more user friendly: https://bitbucket.org/orx/orx/issue/13/add-support-for-literal-collision-types-as

    I see that you removed bullet and sleep parameters from your post, so I guess you found their equivalent in orx! ;)
  • jimjim
    edited December 2012
    oh... I checked it in orxBody but could not find it there, Its in orxOject, it does make sense. Is there any way to enable or disable an object from config? Also if I want to keep the object on screen just want to disable the physics body ?

    As I also know, group indices is not that helpful as it can be used for only two types of objects.

    Now, that would be very cool to use literal mask type, normally we can define enum of category bits in C, so if thats can be done from config, it will be really helpful.

    Yeah, I have found bullet and sleep parameters as HighSpeed and AllowSleep. And, thanks for the reply.
  • edited December 2012
    You can disable an object in config by adding a track to it.
    [MyObject]
    TrackList = DisableTrack
    
    [DisableTrack]
    0 = Object.Enable ^ false
    

    If you want to keep the visual active but not the physics, I'd recommend separating your object in two sub-objects: a parent with the body and a child with the visual.
    Or, if you don't plan on reactivating the body, you can simply remove it by calling orxObject_UnlinkStructure(orxSTRUCTURE_ID_BODY).

    Along with the collision type literals, there'll be functions that'll translate a literal to a value and reciprocally.
  • jimjim
    edited December 2012
    Thats cool that it can be done using timeline, I think I need to search in the forum to know more about timeline and command. That's really a good practice to separate the graphics and body for that kind of situation. One more ques, Can I trigger a timeline using code, coz I have found that timeline tracks will be played immediately.

    Edit: I have found the post that explains what timelines can do, so forget my last question. All questions answered I think.
  • edited December 2012
    Yes, you can either execute a single command using the orxCommand_* API or add a timeline track to an object with orxObject_AddTimeLineTrack().

    In a timeline track, you can delay commands easily from config.

    For example, consider this track:
    [MyTimeLineTrack]
    2 = Object.Enable ^ false
    5 = Object.Enable ^ true
    

    It'll deactivate the object 2 seconds after the track has been added to it and then will re-activate it 5 seconds after the start.

    You can have looping timeline track or you can even add tracks from a track, easily looping through a hierarchy of objects, for example.

    Lastly, for debugging/tweaking purposes, you can execute commands at runtime by opening the console and typing commands there.
    For example, 'Config.SetValue Render ShowProfiler true' will activate the rendering of the profiler.
  • jimjim
    edited December 2012
    thanks a lot. Timelines are great, I think they are great for events that are not very frequent or performance sensitive, like UI system, music,sound, additional animation or cut-scenes. I just need to trigger the appropriate track from code, for example, in menu systems and I can then customize the tracks from config as I needed. Am I right ?
  • edited December 2012
    Yep, all the ones you mentioned are the typical use cases.
    I'm currently working on an iPad game where all the sounds, FXs, musics and menus are handled almost entirely with timeline tracks.

    It's very flexible as it allows my designer teammate to create all the menus and tweak them all by himself without requiring any code change from me. I like that. ;)

    Basically, I have a single function for handling all the UI: it simply polls which object is under the mouse, and depending on the current input state, I check if that object has one of the following config property: OnEnterTrack, OnLeaveTrack, OnClickTrack and OnReleaseTrack. If so, I simply add the right track at the right moment on that object, and those track will pause the game, create a menu, do all the fades, etc.

    In order to interact with other objects from within the tracks, some special objects register themselves to a given config section I call RunTime.

    For example, when the game scene is created (ie the parent/owner of all the gameplay objects), it runs this track upon creation:
    [SceneTrack]
    0 = Config.SetValue RunTime Scene ^
    

    And whenever another track needs to interact with the scene, it can find it by executing a similar track to this one:
    0 = > Config.GetValue RunTime Scene # Object.SetLifeTime < 0; <= Deletes the whole game scene after a game over, for example
    

    You can customize tracks from the code, but keep in mind that a track that is currently referenced somewhere won't be reloaded from config, instead the loaded instance will be used. Exactly in the same way FXs or sounds work.
  • jimjim
    edited December 2012
    That's a very cool usage of timeline, a small tutorial of menu system or timelines would help newbies understand it better, of course there are posts regarding timelines. And its a cool feature i must say.
  • edited December 2012
    I'm glad you like it.

    Yep, a tutorial for commands, timelines and console would be great. That and some info on the wiki. Though I don't know when I'll find the time to do it myself. :(

    I'd rather focus on the open issues at the moment: https://bitbucket.org/orx/orx/issues?status=new&status=open
  • jimjim
    edited December 2012
    yeah, I am referring to community to help building some more tutorials in this regard, but I assure you when I learn something interesting and out of the box, I will try to put them on the wiki no matter how bad my coding style is ;)
    And those issues look really promising.
Sign In or Register to comment.