btGeneric6DofSpringConstraint

bullet physicsのbtGeneric6DofSpringConstraint。
最近バネっぽい動きが欲しくてこいつと数日格闘しておりました。
六自由度でバネをもつ拘束ということのようです。

btGeneric6DofConstraintのサブクラスで、メンバ関数がいくつか追加されており、追加のものは主に以下のようなものがあります。

void btGeneric6DofSpringConstraint::enableSpring(int index, bool onOff)
void btGeneric6DofSpringConstraint::setStiffness(int index, btScalar stiffness)
void btGeneric6DofSpringConstraint::setDamping(int index, btScalar damping)

可動域を設定するときはbtVector3でいけるのに、index渡して呼ばないといけないなんて、無駄にforループ書かされてるみたいでがっかりな感じです。他に以下のAPIがあり、これら4つでバネとしての性質を制御するようです。

void btGeneric6DofSpringConstraint::setEquilibriumPoint()

ドキュメントがさっぱりだし、btGeneric6DofConstraintは可動域越えるとなんかの偶然でバネのように動いてくれてまぎらわしかったり、ピクピクしてくれたりと、なかなか思うにいかなかったのですが、ちょっと発見があってバネっぽく動いてくれるようになったので少し解説してみたいと思います。

enableSpringは名前そのまんまでバネの有効無効。
setStiffnessはバネの強さ。パラメータは多分正の数が妥当。強いほどバネが強くなってバネの振動のスピードがあがったり、振幅が狭くなっていったりしてました。
setDampingは減衰の係数みたいで、0.0f〜1.0fの範囲内が妥当。1.0fにしておくと無限に揺れ、それ以下だと徐々に止まっていく、そんな感じでした。
setEquilibriumPointは、これを呼んだときのjointの位置関係がバネの復元基準の位置になるようです。

で、今回のハマリの一番のポイントですが、enableSpringをtrueにしさえすればバネが働くのかと思いきや、どうやら可動範囲をフリーにしないとバネとして機能しないようでした。つまりloweLimit>upperLimitの関係になるようにする。

例えば以下のような雰囲気。

btGeneric6DofSpringConstraint *springJoint = new btGeneric6DofSpringConstraint();
springJoint-> setLinearLowerLimit( btVector3(1.0f,1.0f,1.0f));
springJoint-> setLinearUpperLimit( btVector3(-1.0f,-1.0f,-1.0f));

バネなしジョイントの固さってどこで調整するんだろうなぁ・・・。誰か教えて・・・。