0

OpenGL のピボット位置を考慮しながら、Quaternion を使用してマトリックス回転を実行する方法がわかりません。現在取得しているのは、空間内のある点を中心としたオブジェクトの回転であり、必要なローカル ピボットではありません。ここにコードがあります[Javaを使用]

クォータニオン回転方法:

  public void rotateTo3(float xr, float yr, float zr) {

    _rotation.x = xr;
    _rotation.y = yr;
    _rotation.z = zr;

    Quaternion xrotQ = Glm.angleAxis((xr), Vec3.X_AXIS);
    Quaternion yrotQ = Glm.angleAxis((yr), Vec3.Y_AXIS);
    Quaternion zrotQ = Glm.angleAxis((zr), Vec3.Z_AXIS);
    xrotQ = Glm.normalize(xrotQ);
    yrotQ = Glm.normalize(yrotQ);
    zrotQ = Glm.normalize(zrotQ);

    Quaternion acumQuat;
    acumQuat = Quaternion.mul(xrotQ, yrotQ);
    acumQuat = Quaternion.mul(acumQuat, zrotQ);



    Mat4 rotMat = Glm.matCast(acumQuat);

    _model = new Mat4(1);

   scaleTo(_scaleX, _scaleY, _scaleZ);

    _model = Glm.translate(_model, new Vec3(_pivot.x, _pivot.y, 0));

    _model =rotMat.mul(_model);//_model.mul(rotMat); //rotMat.mul(_model);

    _model = Glm.translate(_model, new Vec3(-_pivot.x, -_pivot.y, 0));


   translateTo(_x, _y, _z);

    notifyTranformChange();
   }

モデル マトリックス スケール メソッド: public void scaleTo(float x, float y, float z) {

    _model.set(0, x);
    _model.set(5, y);
    _model.set(10, z);

    _scaleX = x;
    _scaleY = y;
    _scaleZ = z;

    notifyTranformChange();
  }

翻訳方法: public void translateTo(float x, float y, float z) {

    _x = x - _pivot.x;
    _y = y - _pivot.y;
    _z = z;
    _position.x = _x;
    _position.y = _y;
    _position.z = _z;

    _model.set(12, _x);
    _model.set(13, _y);
    _model.set(14, _z);

    notifyTranformChange();
   }

しかし、Quaternion を使用しないこの方法は問題なく動作します。

  public void rotate(Vec3 axis, float angleDegr) {
    _rotation.add(axis.scale(angleDegr));
    //  change to GLM:
    Mat4 backTr = new Mat4(1.0f);

    backTr = Glm.translate(backTr, new Vec3(_pivot.x, _pivot.y, 0));

    backTr = Glm.rotate(backTr, angleDegr, axis);


    backTr = Glm.translate(backTr, new Vec3(-_pivot.x, -_pivot.y, 0));

    _model =_model.mul(backTr);///backTr.mul(_model);
    notifyTranformChange();

   }
4

2 に答える 2

1

すでにローテーション前後の前後の移動を考慮しているようです。なぜtranslateToの最後の呼び出しですか?

その上、あなたが回転するとき、純粋な回転は常に原点の周りを意味します。したがって、ピボットポイントを中心に回転させたい場合。ピボットポイントを原点に変換してから回転させてから、ピボットに戻すのが正しい方法だと思います。したがって、コードは次のようになると思います。

_model = Glm.translate(_model, new Vec3(-_pivot.x, -_pivot.y, 0));

_model =rotMat.mul(_model);//_model.mul(rotMat); //rotMat.mul(_model);

_model = Glm.translate(_model, new Vec3(_pivot.x, _pivot.y, 0));

と呼び出しなしtranslateTo(_x, _y, _z);。また、回転部分がすでに想定どおりに動作していることを確認できますか?rotMatと比較することで確認できますGlm.rotate(new Mat4(1.0f), angleDegr, axis)。同じ回転でも同じである必要があります。

于 2012-10-18T08:37:09.973 に答える
1

クォータニオンは回転のみを記述します。その結果、クォータニオンのみを使用して、ピボット ポイントを中心に何かをどのように回転させたいですか?

最低限必要なものは、R3 ベクトルとクォータニオンです。1 レベルの変換だけで、最初にオブジェクトを回転させてからそこに移動します。

マトリックスを作成する場合は、最初に比率マトリックスを作成してから、変換を変更せずに追加します。

glTranslate と glRotate (または glMultMatrix) だけを呼び出したい場合は、最初に glTranslate を呼び出し、次に glRoatate を呼び出します。

編集:

レンダリングしておらず、各頂点がどこにあるかを知りたいだけの場合:

Vector3 newVertex = quat.transform(oldVertex) + translation;
于 2012-10-17T12:55:52.607 に答える