Some help with a math problem?

Discussion in 'Game Development (Technical)' started by zoombapup, Jan 19, 2013.

  1. zoombapup

    Moderator Original Member

    Joined:
    Nov 25, 2004
    Messages:
    2,890
    Likes Received:
    0
    Hey guys..

    I'm trying to implement snapping one object to another. Sort of garry's mod style. Only I can't seem to get the math reliably correct.

    My issue is kind of hard to explain, but here's how it works.

    Each object has a bunch of "snap points" on them. These are 4x4 matrix transforms in object space, so they basically define where on the surface of the object the other object will snap to.

    But when snapping an object, I don't just want to snap the second object's position to that transform, what I want to do is snap the second objects selected snap point to the first objects snap point and then get the position of the second object and fix it in place.

    Currently I'm using:

    Object A transform * snaptransform of A * snaptransform of B.inverse

    Which theoretically gives me the world-space position of object B.

    Only, it doesn't do it reliably, because I have some snaptransform's that are at different angles (imagine snap points on top and bottom of a box) and I'm trying to understand WHY it isn't reliable and failing :)

    I made a quick picture to try and explain better than this text. Hope someone has some thoughts!!

    https://www.dropbox.com/s/unelku3ddfmw7iz/snaps.jpg
     
    #1 zoombapup, Jan 19, 2013
    Last edited: Jan 19, 2013
  2. bantamcitygames

    Administrator Original Member Indie Author Greenlit

    Joined:
    Jul 27, 2004
    Messages:
    1,739
    Likes Received:
    80
    I used to be a wiz at math, acing calculus I, II, III, etc... but alas it is true what they say... if you don't use it you lose it. Although not math related, whenever I've had problems of unreliability its because I did a copy and paste and forgot to change one of the x's in my calculations to y's or something like that. Those are sometimes the hardest to catch without doing a thorough code review.
     
  3. zoombapup

    Moderator Original Member

    Joined:
    Nov 25, 2004
    Messages:
    2,890
    Likes Received:
    0
    This is probably more like a mental blindspot on my part. I know and understand what I think SHOULD happen, but I get some edge cases where some snap points don't snap as expected. So I suspect that in some cases there is a problem with concatenation or some such.
     
  4. jcottier

    jcottier New Member

    Joined:
    Jul 12, 2006
    Messages:
    1,385
    Likes Received:
    0
    snaptransform of B.inverse doesn't look consistent with snaptransform of A (looks like snapstransform is defined in the object space and not the world space), why don't you have Object B.inverse in your equation too?

    JC
     
  5. zoombapup

    Moderator Original Member

    Joined:
    Nov 25, 2004
    Messages:
    2,890
    Likes Received:
    0
    I do. Heres the actual code:

    snapmat = getParentGob()->getTransform() * GetSnapTransform(snapindex) * snap->GetSnapTransform(othersnapindex).inverted();

    The snapmat is the final world space matrix I am setting object B to. getParentGob() gets the gameobject this component is attached to (in this case, object A), GetSnapTransform() gets the object space transform of the snap point (in this case of object A) and then multiplies that with the inverse of the snap transform of B.

    It works for certain cases of snap orientation. But not all of them. Which is where I'm having problems visualizing the issue. To my mind this should just work and yet it doesn't. I tried setting up a unit test for it and it does indeed have some issues. But I cant for the life of me think what is wrong.

    I need a maths hero :) hahahaha
     
  6. Columbo

    Columbo New Member

    Joined:
    Mar 25, 2009
    Messages:
    34
    Likes Received:
    0
    I'm certainly not a maths hero but your logic looks OK to me.
    I suppose you've tried multiplying your matrices in the opposite order already?
    Have you checked your matrix invert works correctly (I've seen maths libs where invert works only for special cases, like no scaling or uniform scaling)?

    Otherwise, I'd divide and conquer, render something at "getParentGob()->getTransform() * GetSnapTransform(snapindex)" and make sure it sticks correctly as the object rotates. After you're confident of that you can concentrate on the other bit.
     
  7. zoombapup

    Moderator Original Member

    Joined:
    Nov 25, 2004
    Messages:
    2,890
    Likes Received:
    0

    Yeah, I rendered something at the snap point and it works fine. So its really something to do with the way that the transform and inverse is working I guess. But I dont think I've actually drawn a debug position there. So maybe I'll try and see how that works.

    From what I can tell, there is some combination of transforms where one essentially inverts the other.
     
  8. jcottier

    jcottier New Member

    Joined:
    Jul 12, 2006
    Messages:
    1,385
    Likes Received:
    0
    Yeah, you should definitely display graphically each step. Decompose your whole transformation into all the step.
    Think of it this way: how can I move my obj into the final metrics and decompose each step.

    Thinking of it, you don't need the original position of objB, you could assume it is at the origin and apply each transformation.
    Looking at your drawing, I am a bit confused about the snap point for Object B, shouldn't they go inside the cube and not outside. Think of it as you need to align them with the one on ObjA. If you align them in your drawing, both cubes will be at the same pos. hope it make senses.

    JC
     
  9. zoombapup

    Moderator Original Member

    Joined:
    Nov 25, 2004
    Messages:
    2,890
    Likes Received:
    0
    Yeah, you ignore the original position of object B. The task is to compute the position and orientation of it so that it is correctly "snapped". Then apply the rigid joint to the world-space objects so they stick together.

    No, the snaps always go on the outside (they represent the UP vector for the snap position, so like a press-stud kind of arrangement), so you should be always be able to align one snap with the other (the snaps up should always be pointing in the opposite direction).

    I think whats happening is in some configurations the snaps UP vector are being aligned when they should be opposite.

    Phil.
     
  10. jcottier

    jcottier New Member

    Joined:
    Jul 12, 2006
    Messages:
    1,385
    Likes Received:
    0
    Not sure I am completely following you but when you compute the inverse of snapB, it isn't really the inverse of snap B, it should be the inverse of the opposite vector. How do you do that? Are you sure this step is correct?

    JC
     
  11. zoombapup

    Moderator Original Member

    Joined:
    Nov 25, 2004
    Messages:
    2,890
    Likes Received:
    0
    Yeah, it just occurred to me that it might need to be rotated 180 degrees so that the snaps are properly aligned. But then why would it work SOMETIMES?

    Imagine a box with a snap at +1 with 0 rotation and a snap at -1 with a 180 rotation (degress), then snap two of them together.

    So box A pos = 0.0.0 and then you add transform (vec(0,1,0),rot(0)) so then you have the world space position and orientation of the snap, you then snap B onto it from pos(0,1,0)rot(0) onto it. So the inverse gives us a position of pos(0,2,0)rot(0), which is as you would expect (snap one box on top of another).

    Then do the BOTTOM snap of B onto A the same way.

    a = pos(0,0,0)rot(0) + a.snap pos(0,1,0) rot(0) + ??

    and here is the tricky bit.. the inverse snap b pos(0,-1,0) rot(180) = pos(0,1,0) rot (-180) = pos(0,-1,0) so we add that on and we get pos(0,0,0)

    So I think the problem is that the rotation on the negative snap point inverts the translation and therefore you get the wrong position?

    Does that make sense?

    If I applied a rotation to get the opposite direction of the snap, I'd basically get the first B snap point inverted and still have the same problem (just the other way round).
     
  12. jcottier

    jcottier New Member

    Joined:
    Jul 12, 2006
    Messages:
    1,385
    Likes Received:
    0
    > If I applied a rotation to get the opposite direction of the snap, I'd basically get the first B snap point inverted and still have the same problem (just the other way round).

    Not at all. before doing your rotation you have to go back to the origin, then do your rotation and then go back to the real position.

    JC
     
  13. JarkkoL

    JarkkoL New Member

    Joined:
    Feb 4, 2009
    Messages:
    363
    Likes Received:
    0
    If this is the result you get, then it's wrong. If you snap box B to A, where both boxes got the same snap->object transformation (e.g. pos(0,1,0)rot(0)), then B should have the same object->world transformation as A: objB_to_world=objA_to_world*snap1_to_obj*inv(snap0_to_obj)
    i.e. snap1_to_obj*inv(snap0_to_obj) will result identity matrix if those snap matrices are equal, so your both boxes will end up overlapping. This is the result that's correct, but not the result you want. To get the result you want, your other snap->obj transform needs to be rotated so that the surface normal points to the opposite direction, i.e. multiply Z (assuming this is your snap normal vector) and X (or Y) vectors by -1.

    Cheers, Jarkko
     
  14. zoombapup

    Moderator Original Member

    Joined:
    Nov 25, 2004
    Messages:
    2,890
    Likes Received:
    0
    Oh man, do I feel silly right now. As I was looking at this again, I noticed that the debug mesh I had added to the snap points wasnt showing +y as the out direction, which it should have been. Turns out I was specifying the orientations of the snap points wrong (I'd chosen the wrong axis to rotate) and that was what was causing the issue!!! :) way to non-fix a problem I'd un-broken already ;)

    Anyway, thanks for the moral support here guys. Now works. So I can bin it in the knowledge it didn't beat me (I don't like how it was working, so going to do something else).
     

Share This Page

  • About Indie Gamer

    When the original Dexterity Forums closed in 2004, Indie Gamer was born and a diverse community has grown out of a passion for creating great games. Here you will find over 10 years of in-depth discussion on game design, the business of game development, and marketing/sales. Indie Gamer also provides a friendly place to meet up with other Developers, Artists, Composers and Writers.
  • Buy us a beer!

    Indie Gamer is delicately held together by a single poor bastard who thankfully gets help from various community volunteers. If you frequent this site or have found value in something you've learned here, help keep the site running by donating a few dollars (for beer of course)!

    Sure, I'll Buy You a Beer