はりうすブログ (のすけのメモ)

湘南にある小さな会社 代表 ”のすけ”のブログです

babylon.js ステップ10 メッシュの交差衝突判定 (Intersect Collisions - mesh)

f:id:hollywis:20200620221236p:plain

メッシュ同士が、それぞれ衝突を検出する方法をやります

いきましょう!!

説明

衝突検出の2つの方法を紹介します。

  1. 2つのメッシュが接触しているときに衝突イベントを発生させる方法
  1. メッシュと1点間の接触を検出する方法

2つのメッシュが接触しているときに衝突イベントを発生させる方法


intersectsMesh()を使うことで、対象との交差(衝突)判定を行うことが出来ます

コードは次の通り

// 平面(plan1)とballoon1との交差判定
if (balloon1.intersectsMesh(plan1, false)) {
  balloon1.material.emissiveColor = new BABYLON.Color4(1, 0, 0, 1);
} else {
  balloon1.material.emissiveColor = new BABYLON.Color4(1, 1, 1, 1);
}


バビロンエンジンでは、交差判定を効率よく行うために
オブジェクトの周囲に下図のように境界ボックス(バウンティングボックス)を作成し、

このボックスと衝突するメッシュの間の交差をテストします。

f:id:hollywis:20200620221905p:plain


また、より詳細に接触を検出したい場合には第二引数をtrueにすることで、

バウンティングボックスをメッシュにより近くし、

交差判定を正確にすることが出来ます。

ただ、この操作は計算負荷が高くなるようです。


左が、falseの例、右がtrueの例です。

f:id:hollywis:20200620222143p:plain

このタイプのバウンディングボックスは、メッシュをある角度に回転させる場合に特に役立ちます。

メッシュと1点間の接触を検出する方法

特定の1点との接触判定をする方法が、intersectsPoint()です。


使用方法は次の通り

var pointToIntersect = new BABYLON.Vector3(10, -5, 0);
if (balloon3.intersectsPoint(pointToIntersect)){
  balloon3.material.emissiveColor = new BABYLON.Color4(1, 0, 0, 1);
}

デモはこちらです

ボールと接触すると赤色になります

https://www.babylonjs-playground.com/#KQV9SA

まとめ

babylon.jsでは衝突判定ようの便利な関数があり

オブジェクト間ではintersectsMesh()


オブジェクトと点ではintersectsPoint()を使うことで衝突判定を行う方法を紹介しました。


次回はマウスとの衝突判定です!

babylon.js ステップ9 カメラとメッシュの衝突判定&重力 (Cameras, Mesh Collisions and Gravity)

babylon.js を覚えようステップ9は衝突判定と重力制御です!


いやー、重力とか楽しそうですね。


メッシュだけでなく、カメラにも設定できるようです。


いきましょう!!

説明

f:id:hollywis:20200620210628j:plain

FPSFirst Person Shooter)ゲームをプレイしたことがありますか?

この回では、そのFPS的なカメラの動きをシミュレートします。

カメラは床にあり、地面と衝突しており、シーン内のオブジェクトと衝突している可能性がありますね

では、このFPS的な設定をしていきましょう!

1.重力の設定

シーンにグラビティ(重力)ベクトルをVector3型で設定します。

scene.gravity = new BABYLON.Vector3(0, -9.81, 0);

古典的には、yに重力加速度9.8を下向き(負)に設定すると良いです。

カメラへの適用は、applyGravityプロパティをtrue設定します

camera.applyGravity = true; 

2.楕円体を定義する

次の重要なステップは、カメラの周りに楕円体を定義することらしいです。

この楕円体はプレーヤーの幅(プレイヤーサイズ)を表します。

外部のメッシュがこの楕円体に接触すると衝突イベントが発生し、カメラがこのメッシュに近づきすぎないようにすることで、カメラがメッシュにめり込まないようにします。
f:id:hollywis:20200620211011p:plain

babylon.jsカメラの楕円体プロパティのデフォルトはサイズ(0.5、1、0.5)ですが、

値を変更すると、調整された軸に応じて、背が高く、大きく、小さく、薄くなります。

次の例では、カメラの楕円体をデフォルトの楕円体よりも少し大きくします。

//カメラの周りに楕円を定義 (e.g. your player's size)
camera.ellipsoid = new BABYLON.Vector3(1, 1, 1);

カメラの楕円体はオフセット(Offset)され、常に視点が楕円体の上にあります。

camera.ellipsoidOffsetプロパティを更新することにより、この動作を制御できます。

計算は次のようになります。

finalPosition = position - vec3(0, ellipsoid.y, 0) + ellipsoidOffset

衝突を適用する(Apply collision)

最後のステップとして、シーン内の衝突の検知をすることを宣言します。

// Enable Collisions
scene.collisionsEnabled = true;
camera.checkCollisions = true;

そして、どのメッシュがカメラと衝突するか設定出来ます。

これはとても便利ですね!Three.jsではなかった設定です。

ground.checkCollisions = true;
box.checkCollisions = true;


以上です!!

demoはこちら
https://www.babylonjs-playground.com/#4HUQQ

カメラは地面と衝突するまで落ちます。

また、ボックスに近づくとカメラがボックスに衝突します。

メッシュオブジェクトとメッシュオブジェクトの衝突

mesh.ellipsoidプロパティ

mesh.moveWithCollisions(velocity)関数

を使用して、メッシュでも同じことを行うこともできる。


この関数は、指定された速度でメッシュを移動させ、現在のメッシュとcheckCollisionsがアクティブになっているすべてのメッシュとの間に衝突がないかどうかをチェックします。


mesh.ellipsoidOffsetを使用して、メッシュ上で楕円体の中心を移動することもできます(デフォルトでは、楕円体はメッシュの中心にあります)。

var speedCharacter = 8;
var gravity = 0.15;
var character = ここにメッシュを設定;

character.ellipsoid = new BABYLON.Vector3(0.5, 1.0, 0.5); //楕円を定義
character.ellipsoidOffset = new BABYLON.Vector3(0, 1.0, 0); //楕円オフセットを設定(上にずらす)

var forwards = new BABYLON.Vector3(parseFloat(Math.sin(character.rotation.y)) / speedCharacter, gravity, parseFloat(Math.cos(character.rotation.y)) / speedCharacter);
forwards.negate();

character.moveWithCollisions(forwards); //衝突判定ありの前進

// または

var backwards = new BABYLON.Vector3(parseFloat(Math.sin(character.rotation.y)) / speedCharacter, -gravity, parseFloat(Math.cos(character.rotation.y)) / speedCharacter);

character.moveWithCollisions(backwards); // 衝突判定ありの後進

ArcRotateCameraでの衝突

ArcRotateCameraでも衝突をチェックすることができますが、、、

障害物に沿ってスライドする代わりに、衝突が追加されてもこのカメラは移動しません。


衝突を有効にするには、camera.checkCollisions = trueを呼び出します。


次のコードで衝突半径を定義できます。

camera.collisionRadius = new BABYLON.Vector3(0.5, 0.5, 0.5)

まとめ

重力を設定する方法は、シーンに設定して、カメラのapplyGravityをtrueにするだけという。

ものすごく簡単に重力が設定できることを紹介しました。

Three.jsではもう少し複雑ですよね。


また、衝突判定には楕円を対象物の周りに作ってmoveWithCollisionsで移動させることで衝突判定が出来ます。

お次はメッシュの衝突判定をより詳しくいきます!


hollywis.hatenablog.com

babylon.js ステップ8 アニメーション(Animations)

babylon.js でのステップも8個目!!

今回はアニメーションです!

アニメーションは、メッシュに動きを与えて見栄えがするシーンを作成出来ます。

いきましょう!

アニメーションの2つの方法

アニメーション方法には2つあります。

  1. 予めアニメーションの動きのキーフレームを定義する方法
  1. 実行時にアニメーションを適用されるようにプロパティを随時変更する方法

キーフレームアニメーション

まず環境を作ります

シーン、ライト、カメラを設定してから、箱を一個置いてみます。

function createScene() {
  //Here... your basic scene as before: [scene, light, camera]

  //Create a box
  var box1 = BABYLON.Mesh.CreateBox("Box1", 10.0, scene);
  box1.position.x = -20;

アニメーションオブジェクトを定義します。
(GSAPみたいなトゥイーン的な方法ですね)

// new BABYLON.Animation(名前,変更対象(例:xの大きさ),値の型,動作タイプ);
var animationBox = new BABYLON.Animation("myAnimation", "scaling.x", 30, BABYLON.Animation.ANIMATIONTYPE_FLOAT, BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE);

値の型は次の設定値があります

  • BABYLON.Animation.ANIMATIONTYPE_FLOAT
  • BABYLON.Animation.ANIMATIONTYPE_VECTOR2
  • BABYLON.Animation.ANIMATIONTYPE_VECTOR3
  • BABYLON.Animation.ANIMATIONTYPE_QUATERNION
  • BABYLON.Animation.ANIMATIONTYPE_MATRIX
  • BABYLON.Animation.ANIMATIONTYPE_COLOR3


動作タイプには次の設定があります

  • BABYLON.Animation.ANIMATIONLOOPMODE_RELATIVE・・・以前の値を使いインクリメントしてループ
  • BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE・・・初期値にリセットしてループ
  • BABYLON.Animation.ANIMATIONLOOPMODE_CONSTANT・・・最後の値をキープしてループ


動作モードについてもう少し捕捉すると

次のように アニメーションキーを設定するとして

// 配列にキーフレームを設定(フレームは昇順でpushしないとならない!)
var keys = []; 

//キーフレーム 0で, スケールを1
  keys.push({
    frame: 0,
    value: 1
  });

  //キーフレーム20で, スケールを0.2
  keys.push({
    frame: 20,
    value: 0.2
  });

  //キーフレーム 100で, スケールを1
  keys.push({
    frame: 100,
    value: 1
  });

Vector2、Vector3、Quaternionの場合は、キーにinTangent値とoutTangent値を設定します

var keys = []; 

  keys.push({
    frame: 0,
    value: BABYLON.Vector3.Zero(),
    outTangent: new BABYLON.Vector3(1, 0, 0)
  });

  keys.push({
    frame: 20,
    inTangent: new BABYLON.Vector3(1, 0, 0),
    value: new BABYLON.Vector3(1, 1, 1),
    outTangent: new BABYLON.Vector3(-1, 0, 0)
  });

  keys.push({
    frame: 100,
    inTangent: new BABYLON.Vector3(-1, 0, 0),
    value: BABYLON.Vector3.Zero()
  });

そして、定義したアニメーション配列をアニメオブジェクトに設定します

animationBox.setKeys(keys);

そして、このアニメーションを箱に紐付けます

box1.animations = [];
box1.animations.push(animationBox);

そして、実行コマンド(beginAnimation)でアニメーションが起動します

// 箱をキーフレーム0から100まで実行!
scene.beginAnimation(box1, 0, 100, true);

キーフレームを入れ替えて逆に実行も可能!

scene.beginAnimation(box1, 100, 0, true);


beginAnimationには、そのほかスピード設定などなど、いろいろ設定できるのドキュメントを確認してみてくださいな

アニメーションを止める方法

実行した後に

var newAnimation = scene.beginAnimation(box1, 0, 100, true);

pauseで止められます

newAnimation.pause();

そのほか、restart(),stop(),reset()もあります

終了を待って同期処理をする

promises を使って同期実行が出来ます

var anim = scene.beginAnimation(box1, 0, 100, false);

console.log("before");
await anim.waitAsync();
console.log("after");

例はこちら
https://www.babylonjs-playground.com/#HZBCXR

CreateAndStartAnimation関数

AbstractMeshオブジェクトの場合には、

StartとEndを設定することでアニメーションを定義出来ます。

BABYLON.Animation.CreateAndStartAnimation('boxscale', box1, 'scaling.x', 30, 120, 1.0, 1.5);

アニメーションのブレンド

f:id:hollywis:20200620162648p:plain
歩いている状態から走る状態へのなめらかな遷移など、アニメーションのブレンドが出来ます!

enableBlending = true を設定

例はこちら
https://www.babylonjs-playground.com/#2BLI9T#174

f:id:hollywis:20200620162742p:plain

アニメーションの重みを設定してブレンド

Babylon.js 3.2以降では、ブレンドを特定の重みでアニメーションを開始できます。

重さを用いたアニメーションはscene.beginWeightedAnimationAPIを使用します。

// 停止 重み 1.0
// scene.beginWeightedAnimation(対象,開始フレーム,終了フレーム,重み,ループ(true/false),(スピード),(終了後の処理),(アニメート設定))
var idleAnim = scene.beginWeightedAnimation(skeleton, 0, 89, 1.0, true);
// 歩き 重み 0
var walkAnim = scene.beginWeightedAnimation(skeleton, 90, 124, 0, true);
// 走り 重み 0
var runAnim = scene.beginWeightedAnimation(skeleton, 125, 146, 0, true);


重みは0から1.0の間をとります。-1を設定するとモードがオフになります。

例はこちら
https://www.babylonjs-playground.com/#IQN716#9

イージング機能

アニメーションにイージングを追加出来ます

イージングチートシート
Easing Functions Cheat Sheet

適用できる関数はこちら

  • BABYLON.CircleEase()
  • BABYLON.BackEase(amplitude)
  • BABYLON.BounceEase(bounces, bounciness)
  • BABYLON.CubicEase()
  • BABYLON.ElasticEase(oscillations, springiness)
  • BABYLON.ExponentialEase(exponent)
  • BABYLON.PowerEase(power)
  • BABYLON.QuadraticEase()
  • BABYLON.QuarticEase()
  • BABYLON.QuinticEase()
  • BABYLON.SineEase()
  • BABYLON.BezierCurveEase()


EasingModeプロパティを使用して、イージング関数の動作の変更もできます。
つまり、アニメーションの補間方法を変更できます。EasingModeに指定できる値は3つあります。

  • BABYLON.EasingFunction.EASINGMODE_EASEIN :補間は、イージング関数に関連付けられた数式に従います。
  • BABYLON.EasingFunction.EASINGMODE_EASEOUT :補間は、100%補間からイージング関数に関連付けられた数式の出力を引いたものに従います。
  • BABYLON.EasingFunction.EASINGMODE_EASEINOUT :補間では、アニメーションの前半にEaseInを使用し、後半にEaseOutを使用します。

補完ベジェの自作も出来ます

// 例
var bezierEase = new BABYLON.BezierCurveEase(0.32, -0.73, 0.69, 1.59);

設定例はこちら
https://www.babylonjs-playground.com/#8ZNVGR

複雑なアニメーション

複雑なアニメーションでは、アニメーションの各フレーム(ティック)ごとにすべてを選択できます。

ゲームのような複雑なアニメーションを設定する場合は、こちらを使います。

requestAnimationFrameを使うわけですがbabylon.jsでは便利なregisterBeforeRenderが用意されています

scene.registerBeforeRender(function () {
  //Your code here
});

例はこちら
https://playground.babylonjs.com/#YJVTI6

まとめ

アニメーションには、予め動きを定義できる

「キーフレームアニメーション」

「複雑なアニメーション」

の2つがありました。



「キーフレームアニメーション」には、かなり細かい設定が可能なプロパティが多く用意されており、予定調和可能な映画やCMのような表現で活躍すると思います。

また、ゲームのような動きが予測出来ないような場合には「複雑なアニメーション」をregisterBeforeRender関数を利用して実行します。


お次はコリジョン(衝突)判定

いきましょう

hollywis.hatenablog.com

babylon.js ステップ7 ライティング

f:id:hollywis:20200620154902j:plain


babylon.js ステップ7 ライティングです。

3D表現はライティングが無いと始まりません。

ライディングの無い空間はただの暗黒です。

暗黒の空間に一条の光として、ライトを設置します。

ライトと言っても、太陽のような環境光もあります。

いきましょう!

ライトの種類

4種類のライトあります

  1. ポイントライト(Point Light)
  2. 指向性ライト(Directional Light)
  3. スポットライト(Spot LIghe)
  4. 半球ライト(HemiLight)

ポイントライト/点光源(Point Light)

ポイントライトは、ワールドスペース内の一意のポイント(点)にから発光されるライトです。

光はこのポイントからあらゆる方向に放出されます。

ポイントライトの分かりやすい例は、裸電球です。

ちょっと上(y軸を多め)に置くとメッシュ全体を照らせます。

var light = new BABYLON.PointLight("pointLight", new BABYLON.Vector3(1, 10, 1), scene);


例はこちら
https://www.babylonjs-playground.com/#20OAV9

指向性ライト/平行光源(Directional Light)

指向性ライト/平行光源は、方向によって定義される特殊な光です。

光は、指定された方向のあらゆる場所から放出され、無限の範囲を持ちます。

指向性ライトの例としては、太陽からの十分に遠い惑星があったとして

その惑星に対して、並行な光が降り注ぐと思うのですが、そんな感じです。

下方向に光を当てると、オブジェクトの上部が明るくなります。

var light = new BABYLON.DirectionalLight("DirectionalLight", new BABYLON.Vector3(0, -1, 0), scene);

例はこちら
https://www.babylonjs-playground.com/#20OAV9#1

スポットライト(Spot LIghe)

スポットライトは、単一の点から一方向に円錐状に放出されます。

方向、角度、および指数を設定出来ます。

値は、位置、照らす方向で光の円錐を定義します。

照射角は、ラジアンで、スポットライトの円錐ビームのサイズ(照明のフィールド)を定義し、

指数は、距離(距離)に伴う光の減衰の速度を定義します。

// new BABYLON.SpotLight(名前, 位置, 照らす方向, 照射角, 光の減衰, scene);
var light = new BABYLON.SpotLight("spotLight", new BABYLON.Vector3(0, 30, -10), new BABYLON.Vector3(0, -1, 0), Math.PI / 3, 2, scene);

例はこちら
https://www.babylonjs-playground.com/#20OAV9#3

半球ライト(HemiLight)

半球ライトは、環境光をシミュレートします。

半球の光は、通常は上空に向かう方向によって定義されます。

ただし、次に説明する色の設定をすることで、より完全な効果が得られる。

var light = new BABYLON.HemisphericLight("HemiLight", new BABYLON.Vector3(0, 1, 0), scene);

例はこちら
https://www.babylonjs-playground.com/#20OAV9#5

色の設定

色に影響を与えるライトには、3つのプロパティがあります。

  • 拡散反射光(diffuse )・・・ベースの反射光 4種類のライトすべてに適用
  • 鏡面反射光(specular)・・・ハイライト 4種類のライトすべてに適用
  • 地面光(groundColor)・・・地面からの反射光。半球ライトにのみ適用


地面光(groundColor)の例はこちら

地面からの反射光が緑だと想定して、gtoundColorが適用されています

https://www.babylonjs-playground.com/#20OAV9#6

ライトのオン、オフ、または調光

これでオフ

light.setEnabled(false);

これでオン

light.setEnabled(true);

intensityを設定することで調光できる

light0.intensity = 0.5;
light1.intensity = 2.4;

ポイントライトとスポットライトの場合、rangeプロパティを使用してライトが到達する距離を設定できます

light.range = 100;

ライティングへのテクスチャの適用

テクスチャへ拡散色を定義するとよい(拡散はオブジェクトに基本色を与えます)。

拡散色の例としては、大聖堂内部の光の効果をシミュレートする場合、ステンドグラスを通過する様々な光は色がついて地面に投影されます。

これは、プロジェクターからの光やなどの光の効果にも当てはまります。

これを再現するためには、SpotLightを用いて、projectionTextureプロパティを適用します。

f:id:hollywis:20200620154802p:plain

var spotLight = new BABYLON.SpotLight("spot02", new BABYLON.Vector3(30, 40, 30),
        new BABYLON.Vector3(-1, -2, -1), 1.1, 16, scene);
spotLight.projectionTexture = new BABYLON.Texture("textures/stainedGlass.png", scene);

まとめ

ライトには4つの種類がありました。

ポイントライト(Point Light)、指向性ライト(Directional Light)、スポットライト(Spot LIghe)、半球ライト(HemiLight)

さらには、ライトの反射光に色の設定する方法とテクスチャを適用する方法も説明しました。

次回はアニメーション!!
hollywis.hatenablog.com

babylon.js ステップ6 カメラ

babylon.jsにはよく使われる2つのカメラがあります。

一つは1人称視点のユニバーサルカメラ(the Universal Camera)、

もう一つはアークカメラ(Arc Rotate Camera)です。


まずカメラのコントロールを可能にしましょう

camera.attachControl(canvas, true);

ユニバーサルカメラ Universal Camera

ユニバーサルカメラはキーボード、タッチ、ゲームパッドに対応したカメラです。

これはFreeCamera,Touch Camera, Gamepad Cameraの上位互換です。

ユニバーサルカメラを使うとFPSっぽい一人称視点を得られます。

それぞれの入力方法のデフォルト設定は次の通り

  1. キーボード・・・上下左右キー
  1. マウス・・・視点を回転
  1. タッチ操作・・・上下左右にスワイプ
  1. ゲームパッド・・・デバイス次第

コード

// Parameters : name, position, scene
    var camera = new BABYLON.UniversalCamera("UniversalCamera", new BABYLON.Vector3(0, 0, -10), scene);

// Targets the camera to a particular position. In this case the scene origin
    camera.setTarget(BABYLON.Vector3.Zero());

// Attach the camera to the canvas
    camera.attachControl(canvas, true);

操作例はこちら:
https://www.babylonjs-playground.com/#SRZRWV

アーク回転カメラ(Arc Rotate Camera)

このカメラは常に所定のターゲット位置を指し、ターゲットを回転の中心としてそのターゲットを中心に回転できます
カーソルとマウス、またはタッチイベントで制御できます。

このカメラは、その目標位置を周回するカメラ、またはより想像力で地球を周回するスパイ衛星と考えてください。ターゲット(地球)に対するその位置は、アルファ(ラジアン)縦回転、ベータ(ラジアン)緯度回転、および ターゲット位置からの距離の半径の3つのパラメーターで設定できます。

f:id:hollywis:20200620014150j:plain

コード

// Parameters: alpha, beta, radius, target position, scene
    var camera = new BABYLON.ArcRotateCamera("Camera", 0, 0, 10, new BABYLON.Vector3(0, 0, 0), scene);

// Positions the camera overwriting alpha, beta, radius
    camera.setPosition(new BABYLON.Vector3(0, 0, 20));

// This attaches the camera to the canvas
    camera.attachControl(canvas, true);

操作例:
https://www.babylonjs-playground.com/#SRZRWV#1

フォローカメラ(FollowCamera)

実際に触ってもらった方が早いため例を見てください。

ターゲットとなるメッシュを追随するように設定出来ます

操作例:
https://www.babylonjs-playground.com/#SRZRWV#6

コード

// Parameters: name, position, scene
var camera = new BABYLON.FollowCamera("FollowCam", new BABYLON.Vector3(0, 10, -10), scene);

// The goal distance of camera from target
camera.radius = 30;

// The goal height of camera above local origin (centre) of target
camera.heightOffset = 10;

// The goal rotation of camera around local origin (centre) of target in x y plane
camera.rotationOffset = 0;

// Acceleration of camera in moving from current to goal position
camera.cameraAcceleration = 0.005

// The speed at which acceleration is halted
camera.maxCameraSpeed = 10

// This attaches the camera to the canvas
camera.attachControl(canvas, true);

// NOTE:: SET CAMERA TARGET AFTER THE TARGET'S CREATION AND NOTE CHANGE FROM BABYLONJS V 2.5
// targetMesh created here.
camera.target = targetMesh;   // version 2.4 and earlier
camera.lockedTarget = targetMesh; //version 2.5 onwards

その他のカメラ

バイス回転カメラ(Device Orientation Camera)
・・・デバイスの方向を取得して反映する

例はこちら
https://www.babylonjs-playground.com/#SRZRWV#3



バーチャルジョイスティックカメラ(Virtual Joysticks Camera)

画面上にジョイスティックを表示する

例はこちら
www.youtube.com




WebVR Free Camera

Use the WebVR Camera - Babylon.js Documentation


飛行カメラ(FlyCamera)

WSADキーで動きます

// Parameters: name, position, scene
var camera = new BABYLON.FlyCamera("FlyCamera", new BABYLON.Vector3(0, 5, -10), scene);

// Airplane like rotation, with faster roll correction and banked-turns.
// Default is 100. A higher number means slower correction.
camera.rollCorrect = 10;
// Default is false.
camera.bankedTurn = true;
// Defaults to 90° in radians in how far banking will roll the camera.
camera.bankedTurnLimit = Math.PI / 2;
// How much of the Yawing (turning) will affect the Rolling (banked-turn.)
// Less than 1 will reduce the Rolling, and more than 1 will increase it.
camera.bankedTurnMultiplier = 1;

// This attaches the camera to the canvas
camera.attachControl(canvas, true);

まとめ

様々なコントロール可能なカメラがbabylon.jsにはあり

ユニバーサルカメラとアーク回転カメラが2大カメラです。

さらに、拡張としてバーチャルジョイスティックを画面上に表示させるなど、十分な操作方法が提供されています

次回はライトの設定です

babylon.js ステップ5 マテリアル

マテリアルを使用すると、メッシュを色とテクスチャで覆うことができます。

なお、メッシュを表示するには光が必要です。

拡散マテリアル(Diffuse)と鏡面マテリアル(Specular)では、光源を作成する必要があります。

いきましょう!

f:id:hollywis:20200619152808p:plain

まずは、StandardMaterialでいきます。

var myMaterial = new BABYLON.StandardMaterial("myMaterial", scene);

myMaterial.diffuseColor = new BABYLON.Color3(1, 0, 1);
myMaterial.specularColor = new BABYLON.Color3(0.5, 0.6, 0.87);
myMaterial.emissiveColor = new BABYLON.Color3(1, 1, 1);
myMaterial.ambientColor = new BABYLON.Color3(0.23, 0.98, 0.53);

mesh.material = myMaterial;


BABYLON.Color3はそれぞれ、赤、緑、青を0~1の間で設定します。0がなし、1が一番強い状態です。

  • diffuseColorは拡散色(光に対して反射する基本の色)
  • specularColorは鏡面反射(ハイライト的な反射)
  • emissiveColorは影の色(そのメッシュ自身がその色で反射する)
  • ambientColor 環境光の反射。シーンのアンビエントカラーが設定されている場合にのみ適用される

そして、定義してマテリアルは、mesh.materialでマテリアルを設定していきます

myMaterial.alpha = 0.5;

aplhaで透明度を変えられる

テクスチャ

メッシュに対して、画像を張れる.

f:id:hollywis:20200619152557p:plain

var myMaterial = new BABYLON.StandardMaterial("myMaterial", scene);

myMaterial.diffuseTexture = new BABYLON.Texture("PATH TO IMAGE", scene);
myMaterial.specularTexture = new BABYLON.Texture("PATH TO IMAGE", scene);
myMaterial.emissiveTexture = new BABYLON.Texture("PATH TO IMAGE", scene);
myMaterial.ambientTexture = new BABYLON.Texture("PATH TO IMAGE", scene);

mesh.material = myMaterial;

ワイヤーフレーム

マテリアルに対して、ワイヤーフレーム表示

f:id:hollywis:20200619153209p:plain

myMaterial.wireframe = true;

まとめ

メッシュに対して、設定できるマテリアルについて紹介しました。

色マテリアルの場合は、まず光Lightをシーンに設定した上で

それぞれ、拡散光、鏡面反射、自身の発光、環境光を設定出来ました。

また、画像テクスチャを貼ることも出来ます。

そして、ワイヤフレーム表示もマテリアルで行いました。

次はカメラです。

hollywis.hatenablog.com

babylon.js ステップ4 位置、回転、スケーリング

babylon.js やってみようシリーズのステップ4

位置、回転、スケーリングのお話です

位置の話

babylon.jsには2つの座標系があります

  • ワールド座標系
  • ローカル座標系

ワールド座標系

ワールド座標系の原点は変わりません。

通常、メッシュが作成されると、その中心はワールド軸の原点に配置されます。

移動しても、ワールド座標系はそのワールドの中心(原点)を元に判断されます

ローカル座標系

ローカル軸はメッシュの場所によって動きます。

でもローカル軸の原点は、ワールド座標における位置に関係なく、常にメッシュの作成された中心にあります。

初期状態

ワールド座標とローカル座標は一致しますが

メッシュが動くとズレることになります。

f:id:hollywis:20200619144019j:plain

配置

mesh(メッシュ)に対して positionで位置を設定出来ます

mesh.position = new BABYLON.Vector3(2, 3, 4);

例えばワールド軸にしたがって、2,3,4の位置に配置します

この意味は

obj.position.x  =  2;
obj.position.y  =  3;
obj.position.z  =  4;

です。

f:id:hollywis:20200619144327j:plain

赤がX軸、緑の線がY軸、青がZ軸

回転

meshに対して rotationで回転させることが出来ます

mesh.rotation = new BABYLON.Vector3(alpha, beta, gamma);

回転もVector3型でメッシュに設定します。

alpha、beta、およびgammaはラジアンで設定します。

mesh.rotation.x  =  alpha; //rotation around x axis
mesh.rotation.y  =  beta;  //rotation around y axis
mesh.rotation.z  =  gamma; //rotation around z axis

これも同じ意味になります。


また、addRotationを使ってmesh(メッシュ)を連鎖的に回転させることも出来ます

mesh.addRotation(Math.PI/2, 0, 0).addRotation(0, Math.PI/2, 0).addRotation(0, 0, Math.PI/2);

スケーリング

meshに対して scalingで大きさを設定出来ます

mesh.scaling = new BABYLON.Vector3(scale_x, scale_y, scale_z);

または、個別に

mesh.scaling.y = 5;

とか出来ます。

y軸に対してスケーリングした物を、z軸を中心に回転させたらこんな感じです。

f:id:hollywis:20200619145855j:plain

まとめ

メッシュに対して、position, rotation, scalingを設定することで

それぞれ、位置、回転、大きさを制御できることがわかりました

次回はマテリアルです

hollywis.hatenablog.com