柱前堂 2024/03/02 21:51

アッパーぶっとびマウスピース

Daz アニメ再び、アッパーでぶっとぶマウスピースをやってみました。

やったこと

1フレームずつ速さと位置を更新してマウスピースに適用しています。
y軸がキャンバスの高さを下回ったら、反発係数0.3でy軸運動量を逆向きにします。

バウンドするごとの最高到達点は、前回の高さ×(反発係数の二乗)になるので、一回のバウンドでおおよそ前回の1割の高さになります。
口から射出された直後はキャンバスから3mくらいの高さまで届いているので、一回目のバウンド後は30cmくらいまで跳ねる計算です。

一回ごとの軌道は放物線なので速さと位置を保持しなくても毎フレームの位置を計算できるのですが、何バウンド目かを保持して軌道を表現する二次関数を切り替えないといけないので、1フレームずつ演算した方が楽かと思います。
後述する今後の課題にも対応しやすそうです。

今後の課題

まず飛ぶ範囲に対してマウスピースが小さいので、カメラ位置が難しいですね。動かすなりカットを入れて動画を分けるなりすればいいのかな……。

y軸方向に小刻みに跳ね続けているのもちょっと不気味です。実際には空気抵抗とか唾液の粘性とか反発係数の変化とかで一定以下の速度になったら跳ねなくなると思うんですが、そういう処理を入れるべきですね。

x, z軸方向も一定速度を保っているのでちょっと元気すぎます。これも空気抵抗を適当に入れるといいのかしら。
何より、マウスピース自体が回転していないんですよね。跳ねるごとにxz軸方向が変わってほしいし、跳んでいる間もくるくる回転していてほしい。回転させるには四元数と和解しないといけませんが……。

スクリプト

// DAZ Studio version 4.22.0.15 filetype DAZ Script

const v_y_first = 400 // [cm/s]
const v_x = -50 // [cm/s]
const v_z = 20 // [cm/s]
const bounding_time = 30 // [frame]
const restitution = 0.3

var mouthpiece = Scene.findNodeByLabel("MouthGuard")
var pos = mouthpiece.getWSPos(0)
const fps = 10
const fps_v = new DzVec3(fps, fps, fps)
const g = new DzVec3(0, 980, 0) // [cm/s^2]
const canvas_y = 100 // [cm]
var v = new DzVec3(v_x, v_y_first, v_z)

for (var frame = 1; frame < bounding_time; frame++){
	pos = pos.add(v.divide(fps_v))
	if (pos.y <= canvas_y){
		v = new DzVec3(v.x, v.y * -1 * restitution, v.z)
		pos = new DzVec3(pos.x, canvas_y, pos.z)
	}else{
		v = v.subtract(g.divide(fps_v))
	}
	mouthpiece.setWSPos(Scene.getTimeStep().valueOf() * frame, pos)
	print("time: " + (frame / fps) + pos)
}

月別アーカイブ

限定特典から探す

記事を検索