Results 1 to 10 of 18

Thread: Direction between 2 Vectors

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Code:
      
      rV := D3DXVector3(
        arctan2(diff.z, diff.x),
        arcsin(diff.y),
        diff.z //why do you need this?
      );
    
      D3DXVec3Lerp(rotation, rV, rotation, 0.1); // interpolating angles is almost never a good idea, I would bet that whatever trouble you are having is probably caused by this. gimbal lock is a fairly rare phenomenon in 3d graphics and doesn't happen consistently, especially not in your case.
    what I suggest you do if you want to achieve smooth camera tranitions is interpolate direction vectors. or even better - spherically interpolate rotation quaternions.

  2. #2
    That sounds good, but I seem to be having a lot of problems trying to incorporate this into my camera class, could you give some example? I appreciate the help. Thanks

    I have made some changes and changed the lerp call to some linear interpolation which is working very smoothly and looks fantastic, i will post the code tomorrow when i'm able.
    Last edited by Colin; 16-11-2012 at 10:20 PM.
    Download the Ziron Assembler
    Get free hosting for Ziron related fan-sites and Ziron projects, contact me in private message.

  3. #3
    well first of all remove the interpolation and make sure everything is working like this:
    rotation := rV;

  4. #4
    Hello Dan, Yes it does work fine, expect still the limitation on the Y axis,

    However after a bit testing i see the problem is on the xz rotation it takes 2*PI for full rotation, on the Y Axis, it would technically take 4*PI, so instead i will do a basic test for flipping the camera, and changing the right and up vectors so the view will then be upside down.
    Last edited by Colin; 17-11-2012 at 10:36 AM.
    Download the Ziron Assembler
    Get free hosting for Ziron related fan-sites and Ziron projects, contact me in private message.

  5. #5
    OK i have my camera system working exactly how i want it except for 1 problem, I have uploaded test build, press N to spawn a ball, then if you press down and to the left so the ball rolls around the camera will at 1 point spin in the opposite direction back to the ball.

    New code:

    Code:
    //
    // sets the look at target of the camera
    //
    procedure TCameraController.setTarget(const targ: TD3DXMatrix);
    const
      tween = 0.01;
    var
      pos, rV: TD3DXVector3;
      diff: TD3DXVector3;
    begin
      pos := D3DXVector3(targ._41, targ._42+5, targ._43); // + 5 look slightly above the object
    
      D3DXVec3Subtract(diff, pos, position);
      D3DXVec3Normalize(diff, diff);
    
      rV := D3DXVector3(
                arctan2(diff.z, diff.x),
                arcsin(diff.y),
                0
              );
    
    
      rotation.x := (rV.x * tween) + rotation.x * (1 - tween);
      rotation.y := (rV.y * tween) + rotation.y * (1 - tween);
      rotation.z := (rV.z * tween) + rotation.z * (1 - tween);
    end;
    
    //
    // sets the position of the camera somewhere behind the object, either facing or by velocity
    //
    procedure TCameraController.Follow(m: TD3DXMatrix; heading: TD3DXVector3);
    const
      Dist = 20;
      MaxDist = 50;
      DefHeight = 15;
    var
      tweenSpeed: TD3DXVector3;
      absdist: TD3DXVector3;
    
      pos: TD3DXVector3;
      gPoint: TD3DXVector3;
    begin
      pos := D3DXVector3(m._41, m._42, m._43);
    
      if (heading.x > 0.00001) and (heading.z > 0.00001) then begin
        D3DXVec3Normalize(heading, heading);
        gPoint.x := m._41 + -Dist*heading.x;
        gPoint.z := m._43 + -Dist*heading.z;
        gPoint.y := m._42 + DefHeight;
      end else begin
        D3DXVec3Normalize(heading, pos);
        gPoint.x := m._41 + -Dist*heading.x;
        gPoint.z := m._43 + -Dist*heading.z;
        gPoint.y := m._42 + DefHeight;
      end;
    
      absdist := D3DXVector3(abs(pos.x-position.x),
                abs(pos.y-position.y),
                abs(pos.z-position.z)
              );
    
      if absdist.x > MaxDist then
        tweenSpeed.x := 0.005 * (absdist.x - (MaxDist-1))
      else
        tweenSpeed.x := 0.005;
    
      tweenSpeed.y := 0.005;
    
      if absdist.z > MaxDist then
        tweenSpeed.z := 0.005 * (absdist.z - (MaxDist-1))
      else
        tweenSpeed.z := 0.005;
    
      position.x := (gPoint.x * tweenSpeed.x) + position.x * (1 - tweenSpeed.x);
      position.y := (gPoint.y * tweenSpeed.y) + position.y * (1 - tweenSpeed.y);
      position.z := (gPoint.z * tweenSpeed.z) + position.z * (1 - tweenSpeed.z);
    end;
    else everything is nice, camera moves very smoothly for the most part, just this problem that is a pain...

    Any ideas?

    Thanks.
    Last edited by Colin; 17-11-2012 at 03:18 PM.
    Download the Ziron Assembler
    Get free hosting for Ziron related fan-sites and Ziron projects, contact me in private message.

  6. #6
    Code:
      rotation.x := (rV.x * tween) + rotation.x * (1 - tween);
      rotation.y := (rV.y * tween) + rotation.y * (1 - tween);
      rotation.z := (rV.z * tween) + rotation.z * (1 - tween);
    you are again interpolating the angles, only doing it manually this time instead of using a d3dx function.
    ok I suppose I have to explain why that is bad. as (I assume) you know arctan2 gives you an angle between
    -Pi and Pi, and you store these angles in your rotation variable. every time you adjust your camera you get a
    new angle and you interpolate between the old rotation variable and the new rV variable. the values that you
    interpolate are angles (-Pi..Pi). so here's an example of the major issue with angles: what if the old angle is
    -0.9 * Pi and the new angle is 0.9 * Pi? the actual angular difference here is only 0.2 * Pi but if you
    numerically interpolate between these angles by a step size of 0.5 (for example) you will end up exactly at 0!
    while you expect to be at Pi, so your camera will turn exactly in the opposite direction.

    as I have said before, you should instead interpolate the direction vectors of the camera. the easiest way to
    do that is to store the current direction vector and the new direction vector, interpolate between them and
    extract your angles from the result. but since I see that you are trying to only deal with the angles you should
    simply convert the rotation variable angles into a vector, interpolate it with the diff vector then extract the
    angles from the result.

    ok at this point if you need more help I can give you the code that will simply work. but that would be no fun would it

  7. #7
    I understand the issue yes, this is the problem that i have been mainly trying to solve.

    What do you mean by "convert the rotation variable angles into a vector" ? the rotation variable is already a vector ?
    Download the Ziron Assembler
    Get free hosting for Ziron related fan-sites and Ziron projects, contact me in private message.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •