Away3D TypeScriptではじめる3次元表現

第17回 ロゴがパーティクルで弾けるアニメーション

この記事を読むのに必要な時間:およそ 12.5 分

パーティクルとアニメーションを定める関数

関数createParticles()は,つぎの2つの関数を呼び出したあと,以下のようにパーティクルのParticleGeometryオブジェクト(colorGeometry)をつくって返す。呼び出したひとつ目の関数(createColorAnimationSet())は,ParticleAnimationSetオブジェクトを返すので,それが変数(colorAnimationSet)に与えられる。2つ目の関数(setParticlesData())は,読み込んだロゴのBitmapDataオブジェクトからピクセルごとのカラー値と位置座標をそれぞれ変数の配列(colorValuesとcolorPoints)に納める。

  • createColorAnimationSet()
  • setParticlesData()

パーティクルの幾何学情報のGeometryオブジェクト(geometry)PrimitivePrefabBase.geometryプロパティから得た。Geometryオブジェクトの配列(colorGeometrySet)は,ParticleGeometryHelper.generateGeometry()メソッドに渡すと,ParticleGeometryオブジェクトができる(第12回パーティクルのオブジェクトを加える参照)⁠これとMethodMaterialオブジェクト(前述変数colorMaterial)Mesh()コンストラクタに渡せば,パーティクルの平面オブジェクトがつくれる。なお,配列に納めるGeometryオブジェクトの数はロゴのBitmapDataオブジェクトの総ピクセル数(count)だ。

var PARTICLE_SIZE = 2;

var colorValues = [];
var colorPoints = [];

var colorAnimationSet;

function createParticles() {
  colorAnimationSet = createColorAnimationSet(initColorParticle);
  setParticlesData(bitmapData, PARTICLE_SIZE, colorValues, colorPoints);
  var primitive = new PrimitivePlanePrefab(PARTICLE_SIZE, PARTICLE_SIZE, 1, 1, false);
  var geometry = primitive.geometry;
  var colorGeometrySet = [];
  var count = colorPoints.length;
  for (var j = 0; j < count; j++) {
    colorGeometrySet[j] = geometry;
  }
  var colorGeometry = ParticleGeometryHelper.generateGeometry(colorGeometrySet);
  return colorGeometry;
}

関数createColorAnimationSet()は,以下のとおりParticleAnimationSetオブジェクト(colorAnimationSet)をつくって返す。オブジェクトには,AnimationNodeBase(のサブクラス)のオブジェクトをParticleAnimationSet.addAnimation()メソッドで加える(第12回パーティクルにアニメーションを定めるおよび第13回パーティクルのカラーをアニメーションさせる参照)⁠ParticleNodeBaseのサブクラスのコンストラクタを,前回のパーティクルのお題ですでに用いたものも含めて表2にまとめた(なお,ParticleNodeBaseはAnimationNodeBaseのサブクラスだ)⁠関数が引数に受け取った初期化の関数(initParticleFunc)は,ParticleAnimationSet.initParticleFuncプロパティに定めた。

function createColorAnimationSet(initParticleFunc) {
  var LOCAL_STATIC = ParticlePropertiesMode.LOCAL_STATIC;
  var colorAnimationSet = new ParticleAnimationSet();
  colorAnimationSet.addAnimation(new ParticleBillboardNode());
  colorAnimationSet.addAnimation(new ParticleBezierCurveNode(LOCAL_STATIC));
  colorAnimationSet.addAnimation(new ParticlePositionNode(LOCAL_STATIC));
  colorAnimationSet.addAnimation(new ParticleInitialColorNode(LOCAL_STATIC, true, false, new ColorTransform(0, 1, 0, 1)));
  colorAnimationSet.initParticleFunc = initParticleFunc;
  return colorAnimationSet;
}

表2 ParticleNodeBaseのサブクラスのコンストラクタ

ParticleNodeBaseのサブクラスのコンストラクタ機能
ParticleBezierCurveNode(モード, コントロールポイント, 終点)時間に応じた位置をベジエ曲線で定める
ParticleBillboardNode()パーティクルの角度をつねにカメラに向ける。
ParticleColorNode(モード, 乗数データの使用, オフセットデータの使用, usesCycleの使用, usesPhaseの使用, 初めの色, 終わりの色)パーティクルアニメーションの時間に応じた色の変わり方を定める
ParticleInitialColorNode(モード, 乗数データの使用, オフセットデータの使用, 初めの色)パーティクルの初めの色を定める
ParticlePositionNode(モード, 位置ベクトル)パーティクルの初めの位置を定める
ParticleScaleNode(モード, usesCycleの使用, usesPhaseの使用, 最小伸縮率, 最大伸縮率)パーティクルアニメーションが時間に応じてどう伸縮するかを定める
ParticleVelocityNode(モード, 速度ベクトル)パーティクルアニメーションが始まるときの速度を定める

関数setParticlesData()には,つぎのように4つの引数を渡す。第1引数のBitmapDataオブジェクトと第2引数のパーティクルの大きさにもとづいて,第3引数と第4引数の配列にそれぞれピクセルごとのカラー値と位置座標を納める。2つの配列は空のまま受け取る前提だ。

setParticlesData(BitmapDataオブジェクト, パーティクルの大きさ, カラー値の配列, 位置の配列)

BitmapDataオブジェクトのピクセルごとのカラー値(color)は,水平と垂直のふたつのインデックスを引数にしてBitmapData.getPixel32()メソッドで調べられる。座標(point)は,BitmapDataオブジェクト(bitmapData)の中心を原点(0, 0)として関数の第2引数の大きさ(size)に比例させ,Vector3Dオブジェクト(point)で定めた(z座標はデフォルト値0)⁠

関数getRgbComponents()は,カラー値の整数からRGB成分値を取り出し(⁠2進数・16進数とビット演算」05カラー値とビット演算参照)⁠Vector3Dオブジェクトのxyzプロパティに納めて返す。なお,関数setParticlesData()では,受け取ったオブジェクトにVector3D.scaleBy()メソッドを用いて,256階調の値を0~1の比率に変えた。これは,後でパーティクルを初期化するとき(initColorParticle()関数)⁠カラーをColorTransformオブジェクトで定めるためだ(第13回パーティクルのカラーをアニメーションさせる参照)⁠こうして得られたピクセルごとのカラーと座標は,それぞれ配列の変数(colorValuesとcolorPoints)に納めている。

function setParticlesData(bitmapData, size, colorValues, colorPoints) {
  var bitmapWidth = bitmapData.width;
  var bitmapHeight = bitmapData.height;
  for (var i = 0; i < bitmapWidth; i++) {
    for (var j = 0; j < bitmapHeight; j++) {
      var point = new Vector3D(size * (i - bitmapWidth / 2), size * ( -j + bitmapHeight / 2));
      var color = bitmapData.getPixel32(i, j);
      var rgbColor = getRgbComponents(color);
      rgbColor.scaleBy(1 / 255);
      colorValues.push(rgbColor);
      colorPoints.push(point);
    }
  }
}
function getRgbComponents(rgbColor) {
  var rgbVector = new Vector3D();
  rgbVector.x = (rgbColor & 0xff0000) >> 16;
  rgbVector.y = (rgbColor & 0xff00) >> 8;
  rgbVector.z = rgbColor & 0xff;
  return rgbVector;
}

関数startParticleAnimation()は,パーティクルのアニメーションを初期設定する。引数に受け取ったParticleGeometryオブジェクト(colorGeometry)とMethodMaterialオブジェクト(colorMaterial)をMesh()コンストラクタに渡して,パーティクルのオブジェクト(colorParticleMesh)がつくられる。そのMesh.animatorプロパティにParticleAnimatorオブジェクト(animator)を定めたうえで,SceneオブジェクトにScene.addChild()メソッドで加えた。

function startParticleAnimation(colorGeometry) {
  var scene = view.scene;
  var colorParticleMesh = new Mesh(colorGeometry, colorMaterial);
  var animator = new ParticleAnimator(colorAnimationSet);
  colorAnimator = animator;
  colorParticleMesh.animator = animator;
  scene.addChild(colorParticleMesh);
}

著者プロフィール

野中文雄(のなかふみお)

ソフトウェアトレーナー,テクニカルライター,オーサリングエンジニア。上智大学法学部卒,慶応義塾大学大学院経営管理研究科修士課程修了(MBA)。独立系パソコン販売会社で,総務・人事,企画,外資系企業担当営業などに携わる。その後,マルチメディアコンテンツ制作会社に転職。ソフトウェアトレーニング,コンテンツ制作などの業務を担当する。2001年11月に独立。Web制作者に向けた情報発信プロジェクトF-siteにも参加する。株式会社ロクナナ取締役(非常勤)。

URLhttp://www.FumioNonaka.com/

著書

コメント

コメントの記入