箱人形の表示
箱人形は、頭、胴体、右腕、左腕、右足、左足の6つの直方体からできています。それぞれの直方体は、立方体を変形して作ります。また、直方体の各面にテクスチャを貼ることで、体の表面をドット絵で覆います。これまでに解説した知識を総動員して、箱人形を作ります。
ポイントとなるのは、各部品をグループに格納し、1つの人形にすることです。また、グループ化をうまく使用して、疑似的に関節も実現します。
3Dオブジェクトを「Object3D」に追加してグループ化した場合、グループを移動したり回転したりした場合は、格納された3Dオブジェクトもまとめて移動したり回転したりします。このときは回転の中心は、グループの中心位置になります。
例えば腕グループを作り、その中に腕直方体を格納して、腕直方体の肩の位置を腕グループの中心位置に移動したとします。その場合、腕グループを回転させると、腕直方体は肩の位置(腕グループの中心位置)で回転します。この仕組みを利用することで、疑似的に関節を持った人形を作成できます。
以下、箱人形を作成して表示する「crocro.bc.viewBoxChar.js」を掲載します。腕や足などの部品をマウスで操作する処理は、最後の「まとめ」で実装します。
//= サンプル:箱人形の表示
//== 箱人形の表示
crocro.bc.viewBoxChar = function() {
// 変数の初期化
var d3 = crocro.bc.d3; // 3D格納用
// 要素の作成と格納
var chr = crocro.bc.mkBoxChar();
d3.scene.add(chr);
crocro.bc.render();
};
//== 箱人形の作成
crocro.bc.mkBoxChar = function() {
// 変数の初期化
var rootGroup = new THREE.Object3D(); // グループ
// パラメータ(頭、胴、右腕、左腕、右足、左足)
var p = [
{sX: 250, sY: 250, sZ: 175, pX: 0, pY: 165}
,{sX: 200, sY: 200, sZ: 120, pX: 0, pY: -60}
,{sX: 70, sY: 250, sZ: 70, pX: -135, pY: -85}
,{sX: 70, sY: 250, sZ: 70, pX: 135, pY: -85}
,{sX: 80, sY: 150, sZ: 80, pX: -50, pY: -100, pY2: -135}
,{sX: 80, sY: 150, sZ: 80, pX: 50, pY: -100, pY2: -135}
];
// ファイル名
var pthBs = "./img/yasumi_yuu/%s_%s.png";
var pth1 = ["head", "body", "arm", "arm", "leg", "leg"];
var pth2 = ["left", "right", "top", "bottom", "front", "back"];
var frmt = function(s1, s2, s3) {
return s1.replace(/%s/, s2).replace(/%s/, s3);
}
// 体の各パーツを作成
for (var i = 0; i <: 6; i ++) {
// マテリアルの作成
var materials = [];
for (var j = 0; j <: 6; j ++) {
var txtr = crocro.bc.getDotTxtr(
frmt(pthBs, pth1[i], pth2[j])
);
var material = new THREE.MeshBasicMaterial({map: txtr});
materials.push(material);
};
// 立方体の作成
var CubeGeo = new THREE.CubeGeometry(
p[i].sX, p[i].sY, p[i].sZ, 4, 4, 4
);
var MeshFaceMat = new THREE.MeshFaceMaterial(materials);
// メッシュの作成
var mesh = new THREE.Mesh(CubeGeo, MeshFaceMat);
// 位置の移動
mesh = crocro.bc.mkBoxChar_mvPos(i, mesh, p);
// グループへの登録
rootGroup.add(mesh);
}
// ルート グループを戻して終了
return rootGroup;
};
//== 位置の移動
crocro.bc.mkBoxChar_mvPos = function(i, mesh, p) {
// 位置の移動
if (i <: 2) {
// 頭と胴の場合
mesh.position.x = p[i].pX;
mesh.position.y = p[i].pY;
} else
if (i <: 4) {
// 腕の場合
mesh.position.y = p[i].pY;
// グループにネストさせる
// 親位置の中心軸で回転が行われるようになる
var group = new THREE.Object3D();
group.add(mesh);
mesh = group;
mesh.position.x = p[i].pX;
} else {
// 足の場合
mesh.position.y = p[i].pY2;
// グループにネストさせる
// 親位置の中心軸で回転が行われるようになる
var group = new THREE.Object3D();
group.add(mesh);
mesh = group;
mesh.position.x = p[i].pX;
mesh.position.y = p[i].pY;
}
// 位置移動したメッシュを戻す
return mesh;
};
//== テクスチャの取得
crocro.bc.getDotTxtr = function(pth) {
// テクスチャを自動読み込み
var texture = THREE.ImageUtils.loadTexture(
pth,
new THREE.UVMapping(),
function() {
// 読み込み後のコールバックでレンダリング
crocro.bc.render();
}
);
// アンチエイリアスなし
texture.magFilter = THREE.NearestFilter;
texture.minFilter = THREE.NearestFilter;
// テクスチャを戻して終了
return texture;
}
