JavaScript
3D
Web3D
Mithril.js
Solufa

Solufaで任意軸回転をする

More than 1 year has passed since last update.


導入

今回はQuaternionで回転させていきます。

Solufaを使って簡単にWebで3Dをアニメーションさせる[回転編]

この記事ではrotateの値を直接変更していましたが、このままだとジンバルロックが発生します。

参考記事

今回はジンバルロックが起こらないQuaternionを使って回転させていきます。

基本的に回転はこちらを使ってください。


前回より

入門編からソースコードを持ってきます。

S(function(m) {

var App = {
controller: function() {
return {
geo: {
type: "Box",
value: [ 1, 1, 1 ]
},
mtl: {
type: "MeshPhong",
value: {
color: "#00f",
specular: "#999"
}
}
};
},
view: function( ctrl ) {
return <scene>
<obj>
<mesh geo={ ctrl.geo } mtl={ ctrl.mtl } style={{ rotate: [ 30*Math.PI/180, 45*Math.PI/180, 0 ] }}/>
</obj>
<cam id="cam" style={{ posZ: 10 }}/>
<light init={{ type: "Dir" }} style={{ pos: [ 0, 2, 0 ] }}/>
<light init={{ type: "Amb" }}/>
</scene>;
}
};
m.mount( S.document.body, App );
m.render( S.document.head, <rdr init={{ frame: "#solufa", antialias: true, preserveDrawingBuffer: true }}>
<OrbitVp cam="#cam"/>
</rdr> );
});


実装

今回新たに出てくる要素は

rotateAxis: [ 0, 0, 1 ]elem.style.rotateAngleのみです。


アニメーション

rotate: function( elem, isInit ) {

if ( isInit ) return;
S.update( function( delta, elapsed ){
elem.style.rotateAngle += delta * 1;
});
}


View

view: function( ctrl ) {

return <scene>
<obj config={ctrl.rotate} style={{rotateAxis: [ 0, 0, 1 ]}}>
<mesh geo={ ctrl.geo } mtl={ ctrl.mtl } style={{ rotate: [ 30*Math.PI/180, 45*Math.PI/180, 0 ]}}/>
</obj>
<cam id="cam" style={{ posZ: 10 }}/>
<light init={{ type: "Dir" }} style={{ pos: [ 0, 2, 0 ] }}/>
<light init={{ type: "Amb" }}/>
</scene>;
}


ソースの解説

アニメーションはelem.style.rotateAngleを使用します。

rotateAngleの軸はView側のstyleで指定します。

今回

 <obj config={ctrl.rotate} style={{rotateAxis: [ 0, 0, 1 ]}}>

<mesh geo={ ctrl.geo } mtl={ ctrl.mtl } style={{ rotate: [ 30*Math.PI/180, 45*Math.PI/180, 0 ]}}/>
</obj>

と書きました。

meshを任意の軸 rotateAxis:[x,y,z]で回します。

今回はz軸で回転させています。

そしてViewのupdate内で

elem.style.rotateAngle += delta * 1;

と書きます。

こうすることでz軸に1ラジアンずつ回転させることができます。


最後に

今回はジンバルロックを起こさないQuaternionでの回転方法を説明しました。

ジンバルロックよくわかんねぇ、、、って方がいると思うので時間があったらSolufaを使って説明を書こうかなと思います。