Announcement

Collapse
No announcement yet.

The Re-Inventing the Wheel Thread

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    I do get what you are after here for trying to stick with BP, I just don't know if it's that easy to get working. This would make even more sense in the future as BP speed will improve after epic gets their BP to C++ conversion tool done (my guess would be 4.13+).

    The issue we have is not just calling BP from c++, it's also about substepping running on that other thread. I actually forgot about this but I've done BP events that fire from c++ side in the past, I just don't think it would work with substepping. You can read more about this from here: https://wiki.unrealengine.com/Bluepr...ementableEvent
    https://github.com/0lento/UnrealEngine (GameWorks tech merges & upgrades, UE4 physics modifications)

    Comment


      Originally posted by 0lento View Post
      The issue we have is not just calling BP from c++, it's also about substepping running on that other thread. I actually forgot about this but I've done BP events that fire from c++ side in the past, I just don't think it would work with substepping. You can read more about this from here: https://wiki.unrealengine.com/Bluepr...ementableEvent
      Well, the good news is that I actually tried this now and it actually works! You still can't handle anything but physics on your substep event but it's ok for this purpose Bad news is that it only seems to work for actor/pawn/player controller, at least I couldn't make it work for example on actor component but I may have missed something. I'll try few other things and post some code snippets for this later on.
      https://github.com/0lento/UnrealEngine (GameWorks tech merges & upgrades, UE4 physics modifications)

      Comment


        @BoredEngineer:
        I made a simple example project about this: SubstepExample2.zip.

        Unzip it somewhere, right click the .uproject and generate Visual Studio project files. After that, launch from VS and you should see a similar example I gave earlier, except this time it's done almost completely on blueprints. It's bit hacky and it still needs some rigidbody at the root of the Pawn but you get the idea. Pawn is currently only thing implemented on c++ and it's then inherited to BP.

        You probably could do it on actor component if you figure out how to send the physics tick event from there. Pawn doesn't calculate any forces in any way, it just creates the event and passes things like AddSubstepForce and GetSubstepTransform. Do note that you can use regular AddImpulse directly from BP as it executes only once. You need to call those AddSubstepForces manually because you can't pass that false-flag to a regular AddForce on BPs (regular AddForce would send additional AddForces to physx on each substep that would carry on until next tick starts).

        Basically what my example does is that it adds that custom physics delegate to that root rigidbody and when the custom physics gets executed, it triggers Physics Tick event which you can then use from BP side. Here's a screenshot of it:

        Click image for larger version

Name:	substep_example.png
Views:	1
Size:	137.4 KB
ID:	1098588

        Just remember to do all debug draws and actual mesh movements on regular tick, only deal with physics on physics tick. Even line trace debug setting will make Unreal Editor crash!

        edit-> cleaned up the project a little, updated project link.
        Last edited by 0lento; 01-14-2016, 07:46 PM.
        https://github.com/0lento/UnrealEngine (GameWorks tech merges & upgrades, UE4 physics modifications)

        Comment


          As an additional note, breakpoints on sub-stepped part of the BP graph seemed to freeze my Unreal Editor, so that's probably out of the question as well.
          https://github.com/0lento/UnrealEngine (GameWorks tech merges & upgrades, UE4 physics modifications)

          Comment


            Cleaned up the example project a little and updated link, see the original post.
            https://github.com/0lento/UnrealEngine (GameWorks tech merges & upgrades, UE4 physics modifications)

            Comment


              Sounds really cool! I'll check it as soon as I get home
              Youtube Channel

              Comment


                Looking through the code. If I understand correctly, the only reason you need to bind delegate inside of the pawn is to know when sub-step physics update starts using it's root body and from that point you can call AddForce() and etc. on any component of your pawn. The only limitation of this setup I'm aware of is that components which you can build in BP can't receive events, but this is easy to overcome by receiving event in Pawn and then just calling something like MyComponent->UpdatePhysics() function in a loop for all components.
                This is really cool! So there is no need in any sort of "physics controller" component, all what is needed is a custom pawn class and being careful to call sub-step specific AddForce() and GetTransform() in components logic. I'm going to try it when I get home!
                Youtube Channel

                Comment


                  Sounds about right. That example calls custom physics delegate when actual sub-stepping occurs for the Primitive Component (any mesh or shape will do) which you have on the Pawn's root. Code is bit messy because I added additional calls for adding forces / reading transforms from other attached components than the one in root, so there's lots of duplicates. You can clean those away if you don't need that kind of functionality, I just put everything I could think would be useful there. The functions that are used for the root component are bit more efficient as they cache the main BodyInstance and Transform which get used often (saves reusing getters all over again on same physics tick).

                  BP on that extended example is also a bit of a mess as I just kept building it from scratch to suit this kind of workflow better. Basically I tried to build it so, that there's a BP struct array which contains all the live data you need / can access from each suspension element. That way you can read the ray traced position, on ground bool, hit normal etc on regular tick from there and for each wheel. That extended example also contains some changes to functions on c++ side, I cleaned it up little more to follow the way epic has done the same things so I recommend to take a look at that instead of the first example.

                  I usually don't comment the code that much, but I guess some explanations could help if things are not obvious. There's usually a separate c++ function for calling the same thing for Root/Pawn vs component like AddSubstepPawnForce vs AddSubstepForce (I don't like the naming convention I made in the middle of the night so you could want to rethink those). Anyway brief explanation for each:

                  These three work only on physics tick as they carry on the force only until next sub-stepping occurs:

                  AddSubstepForce - Adds Force.
                  AddSubstepForceAtLocation - Adds force at Location which is presented in world space.
                  AddSubstepTorque - Adds Torque.

                  These two can be used everywhere:

                  GetSubstepTransfrom - Get transform straight from BodyIntance so it's up-to-date even on sub-steps.
                  GetSubstepLocationWithOffset - Get offsetted location in world space using BodyInstance. Offset is in local space so you can use components Relative Location for it. Useful for getting components location in world space without any math on BP side as you can't use components own function calls for this (as they are updated only once per Tick).

                  BodyInstance getter is only for internal c++ use as you can't expose BodyInstance to the blueprints as is.
                  https://github.com/0lento/UnrealEngine (GameWorks tech merges & upgrades, UE4 physics modifications)

                  Comment


                    This is awesome! It makes it so much easier than what I was trying to do, thank you a lot!
                    Youtube Channel

                    Comment


                      Originally posted by Mhousse1247
                      If substepping is enabled why you setted bAllowSubstepping to false ?
                      I'll just quote myself few posts back:
                      Originally posted by 0lento View Post
                      if you run it using custom physics delegate (to run it on each substep), set bAllowSubstepping to false (optional parameter on AddForce and AddForceAtLocation). Ori also mentioned this briefly here: https://forums.unrealengine.com/show...l=1#post224762
                      That setting is only meant to be used if you use substepping and apply AddForce from regular Ticks (that boolean also defaults to true). As AddForce only carries the force until next physics step, it needs to handle it bit differently in case where you call it only on regular Tick but still have more physics steps. Without substepping your physics step is same a regular tick on most cases.

                      When calling the AddForce from substepping itself, you don't want to spread the force along all the substeps before next tick but only apply it until the next substep occurs and that's what that boolean does. Basically setting that bool to false just calls the physx addforce equivalent instead of figuring how to spread the force between substeps:
                      https://github.com/EpicGames/UnrealE...Scene.cpp#L407

                      I know it sounds the opposite, but it's been in the engine before we could do custom physics delegates on each substep. This whole approach is bit of a hack in my opinion as physics engine interface on UE4 hasn't been designed for this kind of a use. That's also the reason why we have variables like this that don't make much sense at first.
                      https://github.com/0lento/UnrealEngine (GameWorks tech merges & upgrades, UE4 physics modifications)

                      Comment


                        Ah I see now . I'm working on a Kit for the marketplace and applying forces each tick + sub-stepping enabled is doing the trick without any performance drop (40 AI-driven vehicles 60fps).
                        https://twitter.com/HoussineMehnik/s...86655902887936
                        https://twitter.com/HoussineMehnik/s...57030645567488
                        Website [ LINK ]
                        Twitter [ LINK ]
                        Support ! [ LINK ]

                        Comment


                          Originally posted by Mhousse1247 View Post
                          Ah I see now . I'm working on a Kit for the marketplace and applying forces each tick + sub-stepping enabled is doing the trick without any performance drop (40 AI-driven vehicles 60fps).
                          https://twitter.com/HoussineMehnik/s...86655902887936
                          https://twitter.com/HoussineMehnik/s...57030645567488
                          From my experience it helps only with collision and physics constraints, anything you calculate yourself in Tick() gets very little benefit from sub-stepping. The whole point is to do calculations of your forces INSIDE of each sub-step.
                          To see if your setup benefits from sub-stepping lower your fps artificially and see if it still behaves normally. Something like dampener in suspension calculation, can heavily dependent on delta time and when you tweak it to work nicely at 60 fps don't be surprised if you get completely different behavior at 30 fps. By doing calculation inside of the sub-step you guarantee that your physics update has more or less the same frequency, regardless of how many FPS you get from rendering.
                          Last edited by BoredEngineer; 01-15-2016, 01:11 PM.
                          Youtube Channel

                          Comment


                            Im using an old pc for that , and all is working great at 25 fps.
                            One other tip , instead of using tick , you can use a looping timer with 0.008 interval.
                            Website [ LINK ]
                            Twitter [ LINK ]
                            Support ! [ LINK ]

                            Comment


                              Originally posted by Mhousse1247 View Post
                              Im using an old pc for that , and all is working great at 25 fps.
                              If you plan to sell that kit, you need to make sure it actually works well for all kinds of hardware or you'll have lots of disappointed customers.

                              edit-> seems like I misunderstood your comment, sorry about that. Apparently you do actually test this using two different computers. I'd still check it would work even at 10fps, just in case.

                              One other tip , instead of using tick , you can use a looping timer with 0.008 interval.
                              Issue is not being able to do enough calculations, you can loop through as many calculation rounds as you want even on regular tick or timer or whatever is your way of doing it. Issue is that you don't get real-time data back from physics engine unless you get access to those physics steps directly. Unreal by default updates physics scene to regular objects only once per Tick, so even if you do ask for component locations from BP faster than regular Tick occurs, you can only read the value that was synced to that component on previous Tick.
                              Last edited by 0lento; 01-15-2016, 01:24 PM.
                              https://github.com/0lento/UnrealEngine (GameWorks tech merges & upgrades, UE4 physics modifications)

                              Comment


                                Originally posted by Mhousse1247 View Post
                                Im using an old pc for that , and all is working great at 25 fps.
                                One other tip , instead of using tick , you can use a looping timer with 0.008 interval.
                                You can do it from console using "t.maxfps 20.0".
                                I've tried timer for tanks, it doesn't really work because AddForce() is not executed immediately. Actors/pawns tick before physics, all calls to changing physics state of the components is processed after the tick.
                                Youtube Channel

                                Comment

                                Working...
                                X