Announcement

Collapse
No announcement yet.

[Video] Physics Programmers --- Help :(

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

    [Video] Physics Programmers --- Help :(

    I'm having a really strange behaviour occur with my objects' physics. I'm attempting to set the rotational velocity of my object, but only on two of it's local axes, to make it self-right depending on it's rotation relative to a given normal.

    This is much easier to describe with a video, so here it is:


    Notice the odd behaviour, if the craft is facing either the positive-X or negative-X direction, the craft behaves as it should, righting itself to follow the normal of the terrain below it. However, as soon as the craft starts facing more towards Positive-Y or Negative-Y, it starts getting madly out of control, until it starts to face positive/negative-X again and returns to the proper behaviour. For some reason as it starts to line up with the Y-axis, it starts going mental. I've posted the psuedo-logic below and the video does the same thing in Blueprint.

    I've done the same logic for the craft in both C++ and in Blueprints, and experienced the same behaviour with both. I've tried rotating the Normal and the 'Alpha' force around various rotations and still had no luck. I'm convinced it must be something wrong with the way the logic is being conducted, but can't for the life of me figure out what it is, and I'm following the logic of another game that works perfectly with this technique (according to reliable sources). Can anybody highlight where I'm going wrong?

    I have also tried using Physics Forces (AddTorque), but that yields the same problem, and later down the line will be harder to replicate anyway, so ideally I want to set the rotational velocity directly.

    Psuedo-Code
    Code:
    Omega  = Angular Velocity (Local-Space)
    Alpha = Angular Acceleration
    Normal = World-Space Normal of Terrain Beneath Vehicle (From Line Trace)
    Alpha Damp = Damping Value.
    Alpha Track = Speed at which it tries to right itself.
    
    Pitch and roll damping:
    alpha.x = -alphaDamp * omega.x
    alpha.y = -alphaDamp * omega.y
    
    Terrain Normal Tracking:
    trackNormal = Normalize( ( normal.x, normal.y, normal.z + 2) )
    scaledTrack = alphaTrack * heightRatio
    alpha.x -= scaledTrack * DotProduct(trackNormal, ForwardVector)
    alpha.y += scaledTrack * DotProduct(trackNormal, RightVector)
    
    Omega += alpha * deltaSeconds
    
    Convert 'Omega' To World-Space
    
    Mesh->SetPhysicsAngularVelocity(Omega, false)
    Last edited by TheJamsh; 01-05-2015, 06:44 PM.

    #2
    sorry i'm not the one to help but that was so much fun amazing^^ i'm still laughing

    Comment


      #3
      Originally posted by sangloo View Post
      sorry i'm not the one to help but that was so much fun amazing^^ i'm still laughing
      Haha I got excited to see a reply then, when you've been slaving over the problem for weeks it's not funny anymore !

      Comment


        #4
        Hard to say without hands-on experience, but I notice you're not doing any damping on alpha.y - is that intentional, or maybe the source of the problem?

        Comment


          #5
          Originally posted by Xenome View Post
          Hard to say without hands-on experience, but I notice you're not doing any damping on alpha.y - is that intentional, or maybe the source of the problem?
          Sorry, that's a typo, should be Y!

          Comment


            #6
            Ah, that's settled then. Thinking continues...

            Comment


              #7
              Sorry I can't delve into it more deeply at the moment but it seems to me like one of your vectors is either in local where it should be world (or vise versa) or you have a vector somewhere that is rotated strange, like 90 degrees on Y axis or something. Have you tried adding an Arrow component to things to make sure your assumptions match reality? I would also make 100% sure the XYZ axis of the model matches what you think it is, as well as any components of the model you are applying forces to. Make sure there are no weird relative rotations.

              Comment


                #8
                Thanks Sinoth for looking,

                The XYZ of the model is okay, it's the root component of the actor and there aren't any other components inside the version you're seeing in the video (it's just a static mesh), so it doesn't seem to be a model-related issue. When converting Angular Velocity to local space (and then back again at the very end of the function when it's set on the mesh), I've tried both 'RotateVector' (using the meshes world rotation), and the 'Inverse Vector Transform Location / Direction' in code, neither of which seem to fix the problem.

                I think it might be something more to do with the maths of the way it's done. I'm using the Dot-Product of the Surface Normal and the Vehicles Forward/Right vectors to work out the strength of the force, but at some point I think those vectors might flip in relation to something... not sure. I might have to switch to using a series of cross products or something. *Logically* it should work, I think.

                Comment


                  #9
                  Originally posted by TheJamsh View Post
                  Thanks Sinoth for looking,

                  The XYZ of the model is okay, it's the root component of the actor and there aren't any other components inside the version you're seeing in the video (it's just a static mesh), so it doesn't seem to be a model-related issue. When converting Angular Velocity to local space (and then back again at the very end of the function when it's set on the mesh), I've tried both 'RotateVector' (using the meshes world rotation), and the 'Inverse Vector Transform Location / Direction' in code, neither of which seem to fix the problem.

                  I think it might be something more to do with the maths of the way it's done. I'm using the Dot-Product of the Surface Normal and the Vehicles Forward/Right vectors to work out the strength of the force, but at some point I think those vectors might flip in relation to something... not sure. I might have to switch to using a series of cross products or something. *Logically* it should work, I think.
                  Well, the dot product between two normalized vectors is 1 if they're pointing the same exact direction, going to 0 when they're perpendicular, to -1 when they're pointing in exactly opposite directions. Could that be the cause of the problem here?

                  Another thought, have you tried using a "Make Rot from ZX" (that's what it's called in BP) from the terrain normal and vehicle forward vector? That'll give you a rotation (which you can then convert to a vector) perpendicular to the detected terrain normal, pointing where the forward vector of the vehicle *should* go. Would that help at all?
                  Broad Strokes | Jan Kaluza | Marketplace Release: 'Over 9000 Swords' Modular Melee Weapon System
                  Currently not available for freelance work
                  Dev Blog & Tutorials | Twitter

                  Comment


                    #10
                    instead of one trace and calculate how much you should rotate and balance, how about doing 4 trace at each corner and apply force to them so they try to keep away from surface at specific distance?
                    It would be a simpler calculation and more robust for different terrain situations.
                    Unreal Engine 4 Game Framework diagram for relation of all major base object types
                    Unreal Engine 4 Input Event diagram, scroll down to section Input Processing Procedural
                    Resident Evil Classic Camera
                    RPCs official document, Must Read
                    Everything you should know about replication

                    Comment


                      #11
                      Originally posted by PenguinTD View Post
                      instead of one trace and calculate how much you should rotate and balance, how about doing 4 trace at each corner and apply force to them so they try to keep away from surface at specific distance?
                      It would be a simpler calculation and more robust for different terrain situations.
                      Problem is that quadruples the amount of traces I have to do, and also means the craft won't 'Perch' on edges, it'll just fall straight off the front and potentially get stuck. Not only that but it'll be much harder to network reliably this way, and I want to be able to simulate a couple of hundred of these objects over a network fairly reliably too.

                      The single-line trace is based on a force atm similarly to how you said, but using a simple spring-physics calculation.

                      Comment


                        #12
                        No offence!! I think he needs to perform exorcism on Y axis!!

                        Comment


                          #13
                          EDIT: Nope - Still have the Z-Rotation problem :@

                          Some Success! And thus the power and magic of blueprints was praised on that day...

                          Broke down the problem a little more on paper, and basically the problem I have is that the up-vector of the normal alone isn't enough information to get the difference. The way to correctly get the difference in LOCAL space, is to compute the Right and Forward vectors of the normal (using cross-products), and rotate them so that they align with the Z-rotation of the object, in world space.

                          The result is arrows that follow the surface around, and you can then use those as a point of reference to calculate a difference from. In my case, I'm using a Dot product with the Up-Vector of the normal, to calculate just how much different there is between the craft and the up vector. The Dot Product can then be a simple multiplier for my self-righting force.

                          Visualizing it with arrow components definitely helped, and the best part is that I'm still steering clear of rotators, so I avoid any gimbal-lock errors at the same time, and flipping it upside down also causes a self-righting behaviour too. Magic!

                          Test Blueprint (object rotates around it's own Z axis)
                          21825

                          The Math...
                          21826
                          Last edited by TheJamsh; 01-07-2015, 01:45 PM.

                          Comment


                            #14
                            I DID IT. You have no idea how happy I am. I hope this post helps anybody meeting this issue in future!

                            A few problems with my old method, was that I was trying to generate my normal axes from three cross products, but actually i only need two, one for the 'Uprightness', and then another to force the orthogonality (Direction). Using a 'Make Rot From ZY', this enabled me to get the rotation in world-space of the normal impact, and then rotate it locally according to the Vehicles rotation, thusly:

                            Click image for larger version

Name:	NormalRotation.JPG
Views:	1
Size:	32.1 KB
ID:	1064972

                            So using this, I can forcibly set the world-rotation of my object, and add local rotation on the Z-Axis. The object will then align itself correctly to the surface and it can rotate around the arbitrary Z-axis. This would be fine if I was using Rotators directly to 'set' the rotation, but naturally I had to push the boat out and use physics to drive it, by setting angular velocity directly (as opposed to torque).

                            Following the psuedo-code example above, I can work out the required 'strength' AND direction of the force properly, doing this. The key stage is the 'Unrotate Vector', that prevents it from being world-rotation dependant and again allows it to rotate around an arbitrary axis. As a massive bonus, it makes sure that the craft can't ever settle when it's upside-down, and will forcibly stay upright! 'Nrm' is the same surface normal, and 'Rot' is the rotation I generated above!

                            Click image for larger version

Name:	Fixed!.JPG
Views:	1
Size:	99.3 KB
ID:	1064973

                            Now... to C++!

                            Comment


                              #15
                              not sure if you already consider it, but the dot product can not distinguish between eg 170deg to 180deg and 190deg to 170deg. Both give the same dot product. So by default the dot product is only good up to 180deg. At higher angles say 190deg you get a disambiguity.

                              If you pass the 180deg mark with your vehicle, then you have to create a 'if pass 180, then make 360deg minus the dot product result' logic to actually achieve for example 190degs.
                              Last edited by dev100000; 01-08-2015, 04:35 PM.

                              Comment

                              Working...
                              X