not good but great

プログラミング、アート、映画・本の感想について書きます。

パーティクルをCloneして、球の中に球を描画する

demo


ParticleはCloneできる

Cloneはベクトルを複製することを指す。

.clone() Vector3
Clones this vector.

THREE.jsのソースはこちら。
https://github.com/mrdoob/three.js/blob/master/src/objects/Particle.js

THREE.Particle.prototype.clone = function ( object ) {

if ( object === undefined ) object = new THREE.Particle( this.material );

THREE.Object3D.prototype.clone.call( this, object );

return object;

};

cloneを使って次のことをする。

1.球面上にパーティクルをプロットする。
2.パーティクルをcloneする。
3.cloneしたパーティクルの長さを半分にする。
4.cloneしたパーティクルの色を変える。

1.球面上にパーティクルをプロットする。

particle = new THREE.Particle(material);
//パーティクルの座標 方向ベクトルの決定
particle.position.x = Math.random() * 2 - 1;
particle.position.y = Math.random() * 2 - 1;
particle.position.z = Math.random() * 2 - 1;
//単位ベクトルにする
particle.position.normalize();
//ベクトルを引数の値でスカラー倍する
var length = 450;
particle.position.multiplyScalar(length);
particle.scale.x = particle.scale.y = 3;

scene.add(particle);

//頂点を設定
geometry.vertices.push(new THREE.Vertex(particle.position));

ここでは、あるパーティクル1個に注目する。球面状にプロットするためには、定数でスカラー倍すればよい。

このあたりの処理は過去のエントリに詳しい。
CanvasRendererを用いたパーティクル描画で数Bの空間ベクトルの知識が役立った話 - not good but great

2.パーティクルをcloneする。

//パーティクルを複製
particle2 = particle.clone();

これでcloneできる。

3.cloneしたパーティクルの長さを半分にする。

particle2.position.multiplyScalar(length / 2);

これで球の中に球が入る。

4.cloneしたパーティクルの色を変える。

particle2.material.color.setHex(0x000000)

最初、cloneしているのでparticle2の色を変えるだけだと思っていた。しかし上のコードではparticle1の色も変わってしまう。それはマテリアルを共有しているからだ

マテリアルを別に定義する。

var material2 = new THREE.ParticleCanvasMaterial({
    color:0xa9a9a9,
    program:function(context){
        context.beginPath();
        context.arc(arcX, arcY, radius, startAngle, endAngle, anticlockwise);
        context.closePath();
        context.fill();
    }
});
//別のマテリアルを設定
particle2.material = material2;

新しいマテリアルを設定するればparticle2のみ色のが変わる。他にやり方があるのかもしれないが、この方法をとった。

・参考デモ
https://threejsdoc.appspot.com/doc/three.js/examples/canvas_lines_sphere.html

・マテリアルの色設定
javascript - Three.js change material - Stack Overflow

タッチイベントの検出

/*-----------------------------------
    新しくスクリーンに指が触れた場合に発生するイベント
-----------------------------------*/
function onDocumentTouchStart(event){

    if(event.touches.length > 1){//触れている指の本数をチェック
        //スクロール停止
        event.preventDefault();

        mouseX = event.touches[0].pageX - windowHalfX;
        mouseY = event.touches[0].pageY - windowHalfY;
    }
}

/*-----------------------------------
    スクリーンに触れている指をスライドさせた場合に発生するイベント
-----------------------------------*/
function onDocumentTouchMove(event){
    if(event.touches.length == 1){//触れている指の本数をチェック
        //スクロール停止
        event.preventDefault();

        mouseX = event.touches[0].pageX - windowHalfX;
        mouseY = event.touches[0].pageY - windowHalfY;
    }
}
イベント名 内容
touchstart 新しくスクリーンに指が触れた場合に発生するイベント
touchend スクリーンから指を離した場合に発生するイベント
touchmove スクリーンに触れている指をスライドさせた場合に発生するイベント
touchcancel システムによってタッチイベントがキャンセルされた場合に発生するイベント

詳しい解説
iPhone向けwebアプリを作ってみる-タッチイベント、ジェスチャーイベントに関するまとめ- | アシアルブログ

・preventDefault()の説明
これは現在実行されるアクションがキャンセルされる命令。これを使うことでタッチ操作でのスクロールを抑止している。
Touch/Gestureイベントの勘所 - Playground of ours