easy-three

create.instances

create.instances(originalMesh : Mesh, count : number, props : Object) : Mesh

originalMesh - 元のメッシュ。
count - インスタンスの数。
props - 設定オブジェクト。
  • position (Array | Number) : 位置 (デフォルト : [0, 0, 0])。
  • rotation (Array | Number) : 回転 (デフォルト : [0, 0, 0])。
  • removeOriginal (Boolean) : 元のメッシュを削除するかどうか (デフォルト : true)。
  • offset (Array) : インスタンスの間隔 (デフォルト : [0, 0, 0])。
  • layout (String) : レイアウトの種類 (デフォルト : "line")。
  • radius (Number) : 円形レイアウトの半径 (デフォルト : 1)。
  • castShadow (Boolean | null) : 影を落とすかどうか (デフォルト : null)。
  • receiveShadow (Boolean | null) : 影を受けるかどうか (デフォルト : null)。
  • autoAdd (Boolean) : 自動でシーンに追加 (デフォルト : true)。

1つのジオメトリを複数のインスタンスとして配置することができます。
インスタンスは、元のメッシュのジオメトリとマテリアルを共有するため、パフォーマンスが向上します。
インスタンスの位置や回転は、offsetやlayoutで指定できます。

// 元となるメッシュ
const cube = create.cube()
// cubeを8個のインスタンスとして配置
const instances = create.instances(cube, 8)

デフォルトでは、元となるメッシュは remove されます。元となるメッシュを残したい場合は、removeOriginal を false に設定してください。

インスタンスの位置は、offset で指定できます。offset は、インスタンスの間隔を指定する配列です。
layout を指定することで、インスタンスの配置方法を変更できます。
layout には、"line"、"grid"、"circle"、"cube" の4種類があります。
  • "line" は、1次元の直線上に配置されます。
  • "grid" は、2次元のグリッド状に配置されます。
  • "circle" は、円上に配置されます。
  • "cube" は、3次元の立方体状に配置されます。
また、grid、circle、cube に "-xy"、"-xz"、"-yx"、"-yz"、"-zx"、"-zy" を付けることで、配置する軸を指定できます。

at メソッドを使用して、インスタンスの特定のインデックスにアクセスできます。
各インデックスの位置や回転、スケール、色などを個別に変更することができます。

const cube = create.cube()
const instances = create.instances(cube, 8)
// インスタンスの2番目の位置を変更
instances.at(2).position.set(0, 2, 0)
// インスタンスの3番目のスケールを変更
instances.at(3).scale.set(3, 1, 0)
// インスタンスの色を変更
instances.at(4).color.set("#ff0000")

コードの例

インスタンスの配置

以下の例では、create.cube() で作成した立方体を8個のインスタンスとして配置しています。
layout を指定しない場合は、デフォルトで "line" となり、1次元の直線上に配置されます。

インスタンスの間隔は、offset で指定できます。上記の例では、offset を [1, 0, -1] としているため、x 軸方向に 1、z 軸方向に -1 の間隔で配置されます。

const { camera, controls, create, animate } = init();
controls.connect();
camera.position.set(0, 4, 4);
create.ambientLight();
create.directionalLight();

// 元となるメッシュ
const cube = create.cube()

// cubeを8個のインスタンスとして配置
const instances = create.instances(cube, 8, {
  // インスタンスの間隔を指定 
  offset: [1, 0, -1],
})

animate();

平面状に配置する

layout を "grid" に指定することで、2次元のグリッド状に配置することができます。
offset でインスタンスの間隔を指定できます。上記の例では、offset を [1.2, 0, 1.2] としているため、x 軸方向に 1.2、z 軸方向に 1.2 の間隔で配置されます。
"grid" は "grid-xz" と同じ意味なので、offset の y 軸方向の値は無視されます。

例えば、layout を "grid-xy" に指定すると、x 軸方向と y 軸方向に配置できます。

const { camera, controls, create, animate } = init();
controls.connect();
camera.position.set(0, 4, 4);
create.ambientLight();
create.directionalLight();

const cube = create.cube();
const instances = create.instances(cube, 8, {
  layout: "grid",
  offset: [1.2, 0, 1.2],
});

animate();

円状に配置する

layout を "circle" に指定することで、円状に配置することができます。
radius で円の半径を指定できます。上記の例では、radius を 2 としているため、半径 2 の円状に配置されます。

layout が "circle" の場合、offset は無視されます。円状に配置する場合は、radius で半径を指定してください。

layout の "circle" は "circle-xz" と同じ意味なので、円の平面は xz 平面になります。
"circle-xy" に指定すると、円の平面は xy 平面になります。

const { camera, controls, create, animate } = init();
controls.connect();
camera.position.set(0, 4, 4);
create.ambientLight();
create.directionalLight();

const cube = create.cube();
const instances = create.instances(cube, 8, {
  layout: "circle",
  radius: 2,
});

animate();

立方体状に配置する

layout を "cube" に指定することで、3次元の立方体状に配置することができます。
offset でインスタンスの間隔を指定できます。上記の例では、offset を [1.2, 1.2, 1.2] としているため、x 軸方向に 1.2、y 軸方向に 1.2、z 軸方向に 1.2 の間隔で配置されます。

layout の "cube" は "cube-xy" のように並べ始める軸を指定することができます。

const { camera, controls, create, animate } = init();
controls.connect();
camera.position.set(0, 4, 4);
create.ambientLight();
create.directionalLight();

const cube = create.cube();
const instances = create.instances(cube, 8, {
  layout: "cube",
  offset: [1.2, 1.2, 1.2],
});

animate();

特定のインデックスの操作

インスタンスの特定のインデックスにアクセスするには、at メソッドを使用します。
各インデックスの位置や回転、スケール、色などを個別に変更することができます。

例えば、instances.at(0) で最初のインスタンスにアクセスできます。

色については元のメッシュの色との乗算になるため、元のメッシュの色を白にしておくと、インスタンスの色を自由に変更できます。

const { camera, controls, create, animate } = init();
controls.connect();
camera.position.set(0, 4, 4);
create.ambientLight();
create.directionalLight();

const cube = create.cube({
  option: {
    color: "#ffffff",
  }
});
const instances = create.instances(cube, 8, {
  layout: "circle",
  radius: 3,
});

// 0番目のインスタンスの位置を (0, 0, 0) に設定する
instances.at(0).position.set(0, 0, 0);

// 1番目のインスタンスの色を赤に設定する
instances.at(1).color.set("#ff0000");

// 2番目のインスタンスを少し回転させる
instances.at(2).rotation.set(Math.PI / 4, Math.PI / 4, 0);

// 3番目のインスタンスを少し大きくする
instances.at(3).scale.set(1.5, 1.5, 1.5);

animate();