0
\$\begingroup\$

I'm using a Look At function (idem as nasskov answer on this post) to orient a model:

osg::Quat result = quatLookAt(normalize(velocity));

It works but may let the model to roll. How I can avoid this ?

I'm thinking of decomposing the rotation into two quaternions (Pitch&Yaw) but not succeeded so far.


The solution:

inline osg::Vec3
VectorFront()
{
  return osg::Vec3(0, 1, 0);
}

inline osg::Vec3
VectorUp()
{
  return osg::Vec3(0, 0, 1);
}

inline osg::Quat
quatLookAt(const osg::Vec3& dir, const osg::Vec3& up)
{
  if (dir.length2() == 0.0f) {
    assert(false && "Zero length direction in quatLookAt(const osg::Vec3& "
                         "dir, const osg::Vec3& up)");
    return osg::Quat();
  }

  if (up != dir) {
    const osg::Vec3 v = dir + up * -(up * dir);
    osg::Quat       q;
    q.makeRotate(VectorFront(), v);
    osg::Quat r;
    r.makeRotate(v, dir);
    return q * r;// * q
  }

  osg::Quat q;
  q.makeRotate(VectorFront(), dir);
  return q;
}

// ...

const osg::Quat q = quatLookAt(new_forward, VectorUp());
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

Although I'm not sure about the math behind it, you could replicate a Unity function that does this.

https://docs.unity3d.com/ScriptReference/Quaternion.LookRotation.html

LookRotation has 2 parameters for your forward vector and up vector. If you use, for example, the Y axis as your upward vector, then your model should not roll.

Here is a post about replicating it manually:

https://answers.unity.com/questions/819699/calculate-quaternionlookrotation-manually.html

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .