Page 2 of 2 FirstFirst 12
Results 11 to 18 of 18

Thread: Direction between 2 Vectors

  1. #11
    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.

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

  3. #13
    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.

  4. #14
    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.

  5. #15
    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

  6. #16
    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.

  7. #17
    Quote Originally Posted by Colin View Post
    the rotation variable is already a vector ?
    no it's not=) you just store the angles it in a vector format that's it. what you need to do is convert these angles into a 3d direction vector.
    ok, here's how you do it:
    Code:
    var 
      Dir: TD3DXVector3;
      sh, ch, sv, cv: Single;
    ...
      SinCos(rotation.x, sh, ch);
      SinCos(rotation.y, sv, cv);
      Dir.x := ch * cv; Dir.y := sv; Dir.z := sh * cv;
    then you find the "diff" vector just as you do now.
    interpolate between the Dir and diff vector (Dir is the old camera direction, diff is the new camera direction).
    so you might want to do something like this:
    Code:
      Dir.x := Dir.x + (diff.x - Dir.x) * tween;
      Dir.y := Dir.y + (diff.y - Dir.y) * tween;
      Dir.z := Dir.z + (diff.z - Dir.z) * tween;
      D3DXVec3Normalize(Dir, Dir);
    and finally convert the Dir vector to rotation angles. I don't know why you are using a 3d vector for rotation
    angles, but here it is:
    Code:
      rotation := D3DXVector3(
        arctan2(Dir.z, Dir.x),
        arcsin(Dir.y),
        0
      );
    overall this approach should work fine. however, there is still a more consistent and reliable way of spherically interpolating quaternions instead of vectors,
    but that is a tale for another time.
    Last edited by Dan; 17-11-2012 at 03:59 PM.

  8. #18
    Hello Dan,

    Thanks for the code, and for the explanation, it has helped me to understand the idea behind the method. I have updated the procedure with your code and now it works exactly as it should.

    Code:
    //
    // sets the look at target of the camera
    //
    procedure TCameraController.setTarget(const targ: TD3DXMatrix);
    const
      tween = 0.01;
    var
      pos, diff, Dir: TD3DXVector3;
      sh, ch, sv, cv: Extended;
    begin
      SinCos(rotation.x, sh, ch);
      SinCos(rotation.y, sv, cv);
      Dir := D3DXVector3(ch * cv, sv, sh * cv);
    
      pos := D3DXVector3(targ._41, targ._42+1, targ._43); // + 1 look slightly above the object
    
      D3DXVec3Subtract(diff, pos, position);
      D3DXVec3Normalize(diff, diff);
    
      Dir := D3DXVector3(
                Dir.x + (diff.x - Dir.x) * tween,
                Dir.y + (diff.y - Dir.y) * tween,
                Dir.z + (diff.z - Dir.z) * tween
              );
      D3DXVec3Normalize(Dir, Dir);
    
      rotation := D3DXVector3(
                    arctan2(Dir.z, Dir.x),
                    arcsin(Dir.y),
                    0
      );
    end;
    Once I finish adding an Actor class, then maybe i will come back to working on the camera class to look into the quaternion alternatives.

    Thanks again
    Download the Ziron Assembler
    Get free hosting for Ziron related fan-sites and Ziron projects, contact me in private message.

Page 2 of 2 FirstFirst 12

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
  •