ボディがポイントAとポイントBの間をスライドできるようにするスライダーコンストレイントをインスタンス化します。コンストレイントをインスタンス化するために、2つのボディをコンストレイントに割り当てます。この場合、1つのダイナミックボディを静的な世界にコンストレイントします。スライディングドアを考えてください。 。3番目と4番目のパラメーターは、変換、参照フレームAおよび参照フレームBです。変換を作成および操作するために、ライブラリはクォータニオン、行列、オイラー角をサポートしています。
デフォルトのスライダー制約は、ボディをx軸に沿ってスライドさせます。私の質問は 、2つの変換を設定して、ボディBがそれ自体の原点と空間内の追加の点によって指定された軸に沿ってスライドするようにするにはどうすればよいですか?
素朴に私は試しました:
frameA.setOrigin(origin_of_point); //since the world itself has origin (0,0,0)
frameA.setRotation(Quaternion(directionToB, 0 rotation));
frameB.setOrigin(0,0,0); //axis goes through origin of object
frameB.setRotation(Quaternion(directionToPoint,0))
ただし、クォータニオンは期待どおりに機能していないようです。それらについての私の数学的知識はよくないので、誰かがこれがうまくいかない理由について私に記入してくれるなら、私は感謝するでしょう。何が起こるかというと、体はその方向に直交する軸に沿ってスライドします。Quaternionコンストラクターで回転部分を変更すると、ボディはそのスライド方向を中心に回転します。
編集: フレームワークは弾丸物理学です。2つの変換は、各ボディのローカル座標系に関して、スライダージョイントが各ボディにどのように取り付けられるかです。
Edit2 直交基底を介して変換の回転部分を設定することもできますが、その場合、単一のベクトルから直交基底を確実に構築する必要があります。クォータニオンがこれを防ぐことを望みました。
Edit3 私は次の手順でいくつかの限られた成功を収めています:
btTransform trafoA, trafoB;
trafoA.setIdentity();
trafoB.setIdentity();
vec3 bodyorigin(entA->getTrafo().col_t);
vec3 thisorigin(trafo.col_t);
vec3 dir=bodyorigin-thisorigin;
dir.Normalize();
mat4x4 dg=dgGrammSchmidt(dir);
mat4x4 dg2=dgGrammSchmidt(-dir);
btMatrix3x3 m(
dg.col_x.x, dg.col_y.x, dg.col_z.x,
dg.col_x.y, dg.col_y.y, dg.col_z.y,
dg.col_x.z, dg.col_y.z, dg.col_z.z);
btMatrix3x3 m2(
dg2.col_x.x, dg2.col_y.x, dg2.col_z.x,
dg2.col_x.y, dg2.col_y.y, dg2.col_z.y,
dg2.col_x.z, dg2.col_y.z, dg2.col_z.z);
trafoA.setBasis(m);
trafoB.setBasis(m2);
trafoA.setOrigin(btVector3(trafo.col_t.x,trafo.col_t.y,trafo.col_t.z));
btSliderConstraint* sc=new btSliderConstraint(*game.worldBody, *entA->getBody(), trafoA, trafoB, true);
ただし、GramSchmidtは常にtrafoBマトリックスの一部の軸を反転し、ドアは上下逆または右から左に表示されます。私はこれを解決するためのよりエレガントな方法を望んでいました。 Edit4 解決策を見つけましたが、上部のベクトルがスライド方向と一致している場合、これによって制約ソルバーに特異点が生じるかどうかはわかりません。
btTransform rbat = rba->getCenterOfMassTransform();
btVector3 up(rbat.getBasis()[0][0], rbat.getBasis()[1][0], rbat.getBasis()[2][0]);
btVector3 direction = (rbb->getWorldTransform().getOrigin() - btVector3(trafo.col_t.x, trafo.col_t.y, trafo.col_t.z)).normalize();
btScalar angle = acos(up.dot(direction));
btVector3 axis = up.cross(direction);
trafoA.setRotation(btQuaternion(axis, angle));
trafoB.setRotation(btQuaternion(axis, angle));
trafoA.setOrigin(btVector3(trafo.col_t.x,trafo.col_t.y,trafo.col_t.z));