Edited at
HaxeDay 13

HaxeとThreejsで3Dコンテンツを作る 初級編

More than 3 years have passed since last update.


はじめに

私はFlash/ActionScriptしかほぼわからなかったのですが、Haxeをちょっとやってみたら、ほぼFlashと同じ感覚で、CanvasとかWebGLを使ったゲームのようにインタラクティブなものが作れるようになりました。

今回はそんな便利なHaxeとThreejsを使い、以下のようなBoxを複数配置し、マウスに反応する簡単なサンプルを作ります。初心者向けの内容です。

image


開発環境

開発はWindowsでFlashDevelopを使ってます。インストールが終われば、コマンドラインを使わずに、コンパイルまでできるので便利です。インストールにはこの記事がとても参考になります。

http://dev.classmethod.jp/ria/html5/haxe-createjs-1/

macもいろいろありそうですが、ここではふれません。

(macで FlashDevelopを使う方法があります)

http://qiita.com/_nabe/items/662624c7b093da9195f2


Three.jsをHaxeで使えるようにする

externというインターフェイスが定義されているファイルが必要になります。github上で公開されているもの(https://github.com/tong/three.hx )があるのでそれを使います。以下のようにコマンドラインで書くと、threejsという名でライブラリとしてインストールされ、扱えるようになります。

haxelib git threejs https://github.com/tong/three.hx

これでもいいんですが、パソコンが変わったり、開発環境が変わったりするとなんか面倒なので、私は下記のようにexternディレクトリを作り、そこにexternファイル群を入れ、srcパスを通しています。ご参考までに。

image


サンプルコード

Boxをいっぱいおいて、マウスでカメラが動くという簡単なサンプルコードを書いてみました。Main.hxとMain3d.hxでできています。できあがると、こんなかんじです


Main.hx

package ;

import js.Browser;
import js.Lib;

class Main
{

private static var _main:Main3d;

static function main()
{
Browser.window.onload = untyped _init;
}

static private function _init()
{
_main = new Main3d();
_main.init();
}

}



Main3d.hx

package ;

import js.Browser;
import three.BoxGeometry;
import three.DirectionalLight;
import three.Mesh;
import three.MeshLambertMaterial;
import three.PerspectiveCamera;
import three.PointLight;
import three.Scene;
import three.Vector3;
import three.WebGLRenderer;
/**
* ...
* @author nabe
*/

class Main3d
{

private var _scene :Scene;
private var _camera :PerspectiveCamera;
private var _renderer :WebGLRenderer;
private var _mouseX :Float = 0;
private var _mouseY :Float = 0;
private var _amp :Float = 400;

var _down:Bool=false;

public function new()
{
}

public function init()
{

_scene = new Scene();
_camera = new PerspectiveCamera(60, Browser.window.innerWidth / Browser.window.innerHeight, 10, 50000);

_camera.near = 5;
_camera.far = 40000;

_scene.add(new PointLight(0xffffff, 3));
var d:DirectionalLight = new DirectionalLight(0xffffff);
d.position.set(1000, 1000, 100);
_scene.add(d);

_renderer = new WebGLRenderer();
_renderer.setSize(Browser.window.innerWidth, Browser.window.innerHeight);
Browser.document.body.appendChild(_renderer.domElement);

//マウスの座標とってる
_renderer.domElement.onmousemove = function(e){
_mouseX = e.clientX;
_mouseY = e.clientY;
}

//箱200個おいてる
for(i in 0...200){
var geo:BoxGeometry = new BoxGeometry(10,10,10);
var mat:MeshLambertMaterial = new MeshLambertMaterial( { color:0xffffff * Math.random() } );
var mesh:Mesh = new Mesh(geo, mat);
mesh.position.set(
1000 * (Math.random() - 0.5),
1000 * (Math.random() - 0.5),
1000 * (Math.random() - 0.5)
);
_scene.add( mesh );
}

_run();

}

private function _run():Void
{
//マウスによってカメラ動かしてる
var rad:Float = _mouseX / Browser.window.innerWidth * Math.PI * 2;
_camera.position.x = _amp * Math.cos(rad);
_camera.position.y = 0;
_camera.position.z = _amp * Math.sin(rad);
_camera.lookAt(new Vector3());

_renderer.render(_scene, _camera, null, false);
Three.requestAnimationFrame( untyped _run);
}

}



おわりに

Haxeはクラス作るのも、エディタのコードの補間も、コンパイルエラーだしてくれるのも超便利です。ゲームみたいな複雑なものにとてもむくのではないでしょうか。js/htmlが分からない私でも楽しく開発できて、自然にjs/htmlもちょっとわかるようになりました。

逆にHTMLの開発(ふつうのWebページみたいなの?)とかには向いてないのかもしれないです。