重力で線路を走る

重力加速度だけでカーブ上を走らせる計算です。

カーブの準備

進行ベクトルを@Nに、車両を傾ける上方向のベクトルを@upに格納しておく。このカーブから傾きを取得して車両の姿勢に反映させる。

重力

加速度はg*sinΘとなる。Θはカーブの進行ベクトルの高さと底辺の長さからアークタンジェントで計算する。

Solver SOP内のWrangleコード

座標計算はカーブの一次元の位置を進めるだけで、三次元の座標はprimuv()でカーブから取得する。

// Run Over: Point
// input1: curve

// 進行ベクトルから角度を求める(高さとXZ平面の長さからアークタンジェントで求める)
float theta = atan2(v@N.y, sqrt(v@N.x * v@N.x + v@N.z * v@N.z));

// 重力加速度(1秒を60フレームで描画するので時間の平方で割る)
float gravity = (9.8 / float(60 * 60)) * -1;

// 速度に加算
f@speed += gravity * sin(theta);

// 摩擦係数(摩擦で減速させたければ0.995等の数字を入れる)
float friction = 1;
f@speed *= friction;

// カーブにおける位置に速度を加算する
f@curvePos += f@speed;

// カーブの長さ
float curveLength = primintrinsic(1, "measuredperimeter", 0);

// パラメトリックUVの座標をつくる(0-1にスケールする)
float ratio = (f@curvePos / curveLength) % 1;
vector2 posuv = set(ratio, 0);

// UVからカーブ上の座標を取得する
@P = primuv(1, "P", 0, posuv);

// 同じようにカーブからNとupベクトルを取得する
@N = primuv(1, "N", 0, posuv);
@up = primuv(1, "up", 0, posuv);

このポイントにCopy to Points SOPで車両メッシュを配置している。

重力だけで走っているので、開始地点より高い位置には行けずに重力に負けて逆走している。

フレームあたりの重力の値

60フレームで動かす場合、重力は1秒の9.8mではなく、9.8/(60*60)mになる。

例えば物を落として5秒後の距離は1/2*g*5^2となるが、5秒=5*60フレームと考えると、1/2*g*(5*60)^2となるので、gを60^2で割るとつじつまが合って同じ距離になる。

タイトルとURLをコピーしました