three.js canvas - particles - random
http://threejs.org/examples/#canvas_particles_random
日本語訳
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js canvas - particles - random</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
background-color: #000000;
margin: 0px;
overflow: hidden;
<!-- 入りきらない部分は、隠す方向性で -->
}
a {
color:#0078ff;
}
</style>
</head>
<body>
<script src="../build/three.min.js"></script>
<script src="js/renderers/Projector.js"></script>
<script src="js/renderers/CanvasRenderer.js"></script>
<script src="js/libs/stats.min.js"></script>
<script>
<!-- 定義づけ -->
var container, stats;
var camera, scene, renderer, group, particle;
var mouseX = 0, mouseY = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
init();
animate();
function init() {
container = document.createElement( 'div' );
<!-- containerに、div要素をくっつける。 -->
document.body.appendChild( container );
<!-- body要素に、containerの子要素を入れ込む -->
camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 3000 );
<!-- cameraの設定を行う。 大きさ、高さについての設定 -->
camera.position.z = 1000;
<!-- cameraの位置の設定を行う。z軸方向に、1000上げていく -->
scene = new THREE.Scene();
<!-- シーンの追加 -->
var PI2 = Math.PI * 2;
<!-- PI2の定義を行う -->
var program = function ( context ) {
<!-- proguram関数の設定 contxetが実行されると、施工 -->
context.beginPath();
<!-- 現在のパスのリセットを行う -->
context.arc( 0, 0, 0.5, 0, PI2, true );
<!-- context.arcで、円を描く。最後がtrueなので、反時計周り -->
context.fill();
<!-- 現在の塗りつぶしスタイルで、サブパスを塗りつぶす -->
};
group = new THREE.Group();
<!-- groupを追加 -->
scene.add( group );
<!-- sceanにgroupを追加 -->
for ( var i = 0; i < 1000; i++ ) {
<!-- i=0から、iが1000になるまで繰り返すよ。 -->
var material = new THREE.SpriteCanvasMaterial( {
<!-- materialを作成 -->
color: Math.random() * 0x808008 + 0x808080,
<!-- 色はいろんな色を持つ -->
program: program
} );
particle = new THREE.Sprite( material );
<!-- particleの設計を行う -->
particle.position.x = Math.random() * 2000 - 1000;
<!-- 粒子のx座標の設定 -->
particle.position.y = Math.random() * 2000 - 1000;
<!-- 粒子のy座標の設定 -->
particle.position.z = Math.random() * 2000 - 1000;
<!-- 粒子のz座標の設定 -->
particle.scale.x = particle.scale.y = Math.random() * 20 + 10;
<!-- 粒子の大きさは、一定ん値。 -->
group.add( particle );
<!-- groupにparticleを追加 -->
}
renderer = new THREE.CanvasRenderer();
<!-- rendererを追加 -->
renderer.setPixelRatio( window.devicePixelRatio );
<!-- pixelの率を設定 -->
renderer.setSize( window.innerWidth, window.innerHeight );
<!-- rendererのサイズの設定 -->
container.appendChild( renderer.domElement );
<!-- containerに、rendererの子要素の追加を行う。 -->
stats = new Stats();
<!-- stats関数の設定 -->
stats.domElement.style.position = 'absolute';
<!-- statsの位置付けを絶対値で表す -->
stats.domElement.style.top = '0px';
container.appendChild( stats.domElement );
<!-- containerに、stats.domElement要素の追加 -->
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
<!-- mousemoceが行われた時、onDocumentMouseMoveは行われない -->
document.addEventListener( 'touchstart', onDocumentTouchStart, false );
<!-- touchstartが行われた時、onDocumentTouchStart, falseは実行されない。 -->
document.addEventListener( 'touchmove', onDocumentTouchMove, false );
<!-- touchmoveが、実行された時、 onDocumentTouchMove, falseは実行されない -->
//
window.addEventListener( 'resize', onWindowResize, false );
<!-- resizeされた時、windowのresizeは、行われない、 -->
}
function onWindowResize() {
windowresize関数の設定。
windowHalfX = window.innerWidth / 2;
windowHalfY = window.innerHeight / 2;
camera.aspect = window.innerWidth / window.innerHeight;
<!-- cameraのアス比 -->
camera.updateProjectionMatrix();
<!-- カメラの行列をアップデートする。 -->
renderer.setSize( window.innerWidth, window.innerHeight );
<!-- rendererのサイズの設定 -->
}
//
function onDocumentMouseMove( event ) {
<!-- onDocumentMouseMove関数の設定 イベントを実行すると、実際に起動される。 -->
mouseX = event.clientX - windowHalfX;
mouseY = event.clientY - windowHalfY;
<!-- マウスの位置操作が行われる。 -->
}
function onDocumentTouchStart( event ) {
<!--onDocumentTouchStart関数の設定 eventの設定 -->
if ( event.touches.length === 1 ) {
<!-- もしイベントのタッチの長さが、1ならば。 -->
event.preventDefault();
<!-- イベントを、実行する前にキャンセル可能 -->
mouseX = event.touches[ 0 ].pageX - windowHalfX;
<!-- 最初にタッチした情報のxからwindwHalfXを引いた値が、mouseXの定義。 -->
mouseY = event.touches[ 0 ].pageY - windowHalfY;
<!-- mouseYも同じく -->
}
}
function onDocumentTouchMove( event ) {
<!-- onDocumentTouchMoveの関数の定義、イベントを実行すると、起動する。 -->
if ( event.touches.length === 1 ) {
<!--もし、イベントのタッチの長さが、1ならば -->
event.preventDefault();
<!-- イベントのキャンセルが可能。 -->
mouseX = event.touches[ 0 ].pageX - windowHalfX;
<!-- mouseXの定義。始めにタッチした箇所からの長さを測る。 -->
mouseY = event.touches[ 0 ].pageY - windowHalfY;
<!-- mouseYの定義 -->
}
}
//
function animate() {
<!-- animationの実行 -->
requestAnimationFrame( animate );
<!-- animationframeの実装 -->
render();
<!-- render()を実行 -->
stats.update();
<!-- updateしていく -->
}
function render() {
<!-- rendererの実行 -->
camera.position.x += ( mouseX - camera.position.x ) * 0.05;
<!-- cameraのpositionをどんどん変更していく。 -->
camera.position.y += ( - mouseY - camera.position.y ) * 0.05;
<!-- cameraのpositionをどんどん変更していく。 -->
camera.lookAt( scene.position );
<!-- cameraの視野の中心座標を変換していく。 -->
group.rotation.x += 0.01;
<!-- groupを回転させる -->
group.rotation.y += 0.02;
<!-- groupを回転させる。 -->
renderer.render( scene, camera );
<!-- sceanと、cameraを連携づける。 -->
}
</script>
</body>
</html>
canvas_geometry_cube.html
http://threejs.org/examples/#canvas_geometry_cube
日本語解説
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js canvas - geometry - cube</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
font-family: Monospace;
background-color: #f0f0f0;
margin: 0px;
overflow: hidden;
<!-- overflowボックスからはみ出たときにする処理 今回は隠す方向性 -->
}
</style>
</head>
<body>
<script src="../build/three.min.js"></script>
<script src="js/renderers/Projector.js"></script>
<script src="js/renderers/CanvasRenderer.js"></script>
<script src="js/libs/stats.min.js"></script>
<script>
<!-- 定義付け -->
var container, stats;
var camera, scene, renderer;
var cube, plane;
var targetRotation = 0;
var targetRotationOnMouseDown = 0;
var mouseX = 0;
var mouseXOnMouseDown = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
init();
animate();
function init() {
<!-- containerに、divのidで指定されたものを入れ込む -->
container = document.createElement( 'div' );
<!-- documentの -->
document.body.appendChild( container );
<!-- documentに、containerの子要素追加 -->
var info = document.createElement( 'div' );
<!-- infoに、divのidで指定されたものを追加する -->
info.style.position = 'absolute';
<!-- infoの位置を接待値で決定 -->
info.style.top = '10px';
info.style.width = '100%';
info.style.textAlign = 'center';
info.innerHTML = 'Drag to spin the cube';
<!-- html要素として、Drag to spin the cubeを書き込む -->
container.appendChild( info );
<!-- containerに、infoの子要素を追加 -->
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1000 );
<!-- cameraは、perspectiveカメラで設定 -->
camera.position.y = 150;
camera.position.z = 500;
<!-- カメラの位置設定 -->
scene = new THREE.Scene();
<!-- シーン要素の作成 -->
// Cube
var geometry = new THREE.BoxGeometry( 200, 200, 200 );
<!-- 物体の作成 今回は、boxなので、上記のように -->
for ( var i = 0; i < geometry.faces.length; i += 2 ) {
var hex = Math.random() * 0xffffff;
<!-- 色は、ランダムですよーということ -->
geometry.faces[ i ].color.setHex( hex );
<!-- i番目の面は、hex色 -->
geometry.faces[ i + 1 ].color.setHex( hex );
<!-- i+1番目はhex色 -->
}
var material = new THREE.MeshBasicMaterial( { vertexColors: THREE.FaceColors, overdraw: 0.5 } );
<!-- 物体の特徴の設定 vertexColors は、頂点の色の指定を行う -->
<!-- overdrawは、アンチエイリアスとかそっち系の、境界線をどんくらいにするかとか -->
cube = new THREE.Mesh( geometry, material );
<!-- cubeを作成 特徴は、geometryと、materialですよ。 -->
cube.position.y = 150;
<!-- cubeのy座標的位置の決定 -->
scene.add( cube );
<!-- sceanに追加 -->
// Plane
var geometry = new THREE.PlaneBufferGeometry( 200, 200 );
<!-- 平面の作成を行う。 -->
geometry.rotateX( - Math.PI / 2 );
<!-- geometoryの、x軸回転を90度回転しておこなう。 -->
var material = new THREE.MeshBasicMaterial( { color: 0xe0e0e0, overdraw: 0.5 } );
<!-- materialの特徴について記す -->
plane = new THREE.Mesh( geometry, material );
<!-- planeっていうものは、geometoryと、materialの特徴を持ってる -->
scene.add( plane );
<!-- planeをsceanに追加 -->
renderer = new THREE.CanvasRenderer();
<!-- rendererの作成 -->
renderer.setClearColor( 0xf0f0f0 );
<!-- クリアカラーを決定する -->
renderer.setPixelRatio( window.devicePixelRatio );
<!-- ピクセルの比を、windowのデバイスのピクセル比に変更する。 -->
renderer.setSize( window.innerWidth, window.innerHeight );
<!-- renderereのサイズを設定 -->
container.appendChild( renderer.domElement );
<!-- containerに、renderer.domElementを追加 -->
stats = new Stats();
<!-- stats関数を追加 -->
stats.domElement.style.position = 'absolute';
<!-- statsの位置を絶対値として近づける。 -->
stats.domElement.style.top = '0px';
<!-- statsのdomElementのトップを0pxで保存 -->
container.appendChild( stats.domElement );
<!-- containerに、 -->
document.addEventListener( 'mousedown', onDocumentMouseDown, false );
<!-- documentに、mousedownが実行されるとonDocumentMouseDownが、false -->
document.addEventListener( 'touchstart', onDocumentTouchStart, false );
<!-- touchstartを起動すると、onDocumentTouchstart:falseが実行される -->
document.addEventListener( 'touchmove', onDocumentTouchMove, false );
<!-- touchmoveが実行されると、onDocumentTouchMoveがfalseになる。 -->
//
window.addEventListener( 'resize', onWindowResize, false );
<!--resizeが実行されると、onWindowResizeがfalseになる。 -->
}
function onWindowResize() {
<!-- onDocumentResizeの関数の設定 -->
windowHalfX = window.innerWidth / 2;
<!-- windowHalfXを、windowの幅の1/2へ -->
windowHalfY = window.innerHeight / 2;
<!-- windowhalfYを、windowの高さの1/2へ -->
camera.aspect = window.innerWidth / window.innerHeight;
<!-- cameraのアス比をinnerwidthと、innerの高さの比で設定する。 -->
camera.updateProjectionMatrix();
<!-- cameraの行列をアップデートする -->
renderer.setSize( window.innerWidth, window.innerHeight );
<!-- rendererのサイズを、windowのサイズと、高さで表す。 -->
}
//
function onDocumentMouseDown( event ) {
<!-- ondocumentMouseDownをイベント実行時に実行 -->
event.preventDefault();
<!-- イベントが、キャンセル可能である場合に、イベント実行前に、機能をとめる -->
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
<!-- mousemoveが、実行されたら、onDocumentMouseMoveを実行しない -->
document.addEventListener( 'mouseup', onDocumentMouseUp, false );
<!-- mouseupが実行されたら onDocumentMouseUpを実行しない -->
document.addEventListener( 'mouseout', onDocumentMouseOut, false );
<!-- mouseoutを実行したら、 onDocumentMouseOutを実行しない-->
mouseXOnMouseDown = event.clientX - windowHalfX;
<!-- mouseXOnMouseDownの定義 -->
targetRotationOnMouseDown = targetRotation;
<!--targetRotationOnMouseDownに、targetRotationを入れ込む -->
}
function onDocumentMouseMove( event ) {
<!-- onDocumentMouseMoveの関数は、event実行により、実際に動かされる。 -->
mouseX = event.clientX - windowHalfX;
<!-- mouseXの定義を^行う -->
targetRotation = targetRotationOnMouseDown + ( mouseX - mouseXOnMouseDown ) * 0.02;
<!-- targetRotationの定義を行う -->
}
function onDocumentMouseUp( event ) {
<!-- onDocumentMeetUpは、eventを実行すると、動かされる。 -->
document.removeEventListener( 'mousemove', onDocumentMouseMove, false );
<!-- documentのイベントじ実行するとonDocumentMouseMoveが失敗に終わる -->
document.removeEventListener( 'mouseup', onDocumentMouseUp, false );
<!-- mouseupを実行すると、onDocumentMouseUpが実行されない -->
document.removeEventListener( 'mouseout', onDocumentMouseOut, false );
<!-- mouseoutを、実行すると、onDocumentMouseOutが実行されない。 -->
}
function onDocumentMouseOut( event ) {
<!-- onDocumentMouseOutの関数は、eventが押された時に実行される。 -->
document.removeEventListener( 'mousemove', onDocumentMouseMove, false );
<!-- mousemoveが実行されると、onDocumentMouseMoveが実行されない -->
document.removeEventListener( 'mouseup', onDocumentMouseUp, false );
<!-- mouseupが実行されると、onDocumentMouseUpは、できない。 -->
document.removeEventListener( 'mouseout', onDocumentMouseOut, false );
<!-- mouseoutを実行すると、onDocumentMouseOutが実行されない -->
}
function onDocumentTouchStart( event ) {
<!-- onDocumentTouchStartの関数は、eventが実行された時に実行される。 -->
if ( event.touches.length === 1 ) {
<!-- eventのタッチの長さが、1なら、 -->
event.preventDefault();
<!-- イベントがキャンセル可能である場合、キャンセルする。 -->
mouseXOnMouseDown = event.touches[ 0 ].pageX - windowHalfX;
<!-- mouseXOnMouseDownの定義 -->
targetRotationOnMouseDown = targetRotation;
<!-- targetRotationOnMouseDownにtargetRotationを入れ込む -->
}
}
function onDocumentTouchMove( event ) {
<!--onDocumentTouchMoveは、eventが実行されると、動く -->
if ( event.touches.length === 1 ) {
<!-- もし、タッチの長さが1ならば -->
event.preventDefault();
<!-- イベントのキャンセルが可能。 -->
mouseX = event.touches[ 0 ].pageX - windowHalfX;
<!-- mouseXの定義 -->
targetRotation = targetRotationOnMouseDown + ( mouseX - mouseXOnMouseDown ) * 0.05;
<!-- targetRotationの定義 -->
}
}
//
function animate() {
<!-- animateを実行 -->
requestAnimationFrame( animate );
<!-- 次のコンマがはじまる時に、animateを実行していく関数 -->
render();
<!-- renderを実行 -->
stats.update();
<!-- statsをupdateする。 -->
}
function render() {
<!-- rendere関数について -->
plane.rotation.y = cube.rotation.y += ( targetRotation - cube.rotation.y ) * 0.05;
<!-- plane.rotation.yの定義 -->
renderer.render( scene, camera );
<!-- sceanと、cameraを同期 -->
}
</script>
</body>
</html>
Cameras-PerspectiveCamera-
遠近法を使ったカメラについて説明していきます。
例
animation / skinning / blending
animation / skinning / blending
var camera = new THREE.PerspectiveCamera( 45, width / height, 1, 1000 ); scene.add( camera );
Constructor
PerspectiveCamera( fov, aspect, near, far )
fov--カメラの視覚の垂直場
aspect--カメラ面の比
near--カメラから見える一番近い距離
far--カメラから見える一番遠い距離
Properties
.zoom
カメラのズームの設定
.fov
カメラの角度的な、一番下から、一番上の視覚的垂直場
カメラのアス比windowの高さによって割り当てられたwindowの幅
.near
カメラから見える一番近い距離
.far
カメラから見える一番遠い距離
Methods
.setLens ( focalLength, frameSize )
focalLength --焦点の長さ
frameSize--フレームのサイズ
見積もるために、焦点距離を使用する。そして、FOV 35mm カメラ(全てのフレーム)は、もしサイズが細分化されなければ使用される。
この公式は、
http://www.bobatkins.com/photography/technical/field_of_view.html
で使用される。
.setViewOffset ( fullWidth, fullHeight, x, y, width, height )
fullWidth ― 様々な視覚の全ての広さをsetupする。
fullHeight ― 様々な視覚の全ての高さをsetupする。
x ― サブカメラの水平方向
y ― サブカメラの垂直方向
width ― サブカメラの幅
height ― サブカメラの高さ
より高い円錐でのoffsetをセットする。
これは、マルチウィンドウか、マルチモニタと、マルチメカニックのセットアップ。
例えば、
もし、3×2モニターと、それぞれのモニターは、1950×1080、そしてモニターは、下のようなグリッドになってます。
+---+---+---+
| A | B | C |
+---+---+---+
| D | E | F |
+---+---+—+-+
呼び出したいモニターは、下のようになります。
var w = 1920;
var h = 1080;
var fullWidth = w * 3;
var fullHeight = h * 2;
// A
camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 0, w, h );
// B
camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 0, w, h );
// C
camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 0, w, h );
// D
camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 1, w, h );
// E
camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 1, w, h );
// F
camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 1, w, h );
モニターは、gridと同じサイズでなければいけないのに理由はないということを覚えておいてください。
.updateProjectionMatrix ()
カメラの投射行列をアップデートします。
パラメーターを変えた時に、必ず呼びださなければいけません。
.clone ()
PerspectiveCameraのクローンを返す。
.toJSON ()
JSON フォーマットでカメラのデータを返す。
Source
Cameras-OrthgraphicCamera-
正当な投影でのカメラ
例
var camera = new THREE.OrthographicCamera( width / - 2, width / 2, height / 2, height / - 2, 1, 1000 );
scene.add( camera );
Constructor
OrthographicCamera( left, right, top, bottom, near, far )
left-カメラの左端
right-カメラの右端
top--カメラの上端
bottom--カメラの下端
near --カメラの一番手前の位置
far--カメラが見える一番遠い距離
Properties
.zoom
カメラのズームをセット
.left
カメラの左側
.right
カメラの右側
.top
カメラの上端
.bottom
カメラの下端
.near
カメラから一番近く見える位置
.far
カメラから一番遠い位置
Methods
.updateProjectionMatrix ()
カメラの投射行列のアップデートを行う
パラメーターの変更をした後必ず呼び出す必要あり!
.clone ()
OrthographicCameraのクローンを作り上げる
.toJSON ()
JSONフォーマットでカメラのデータを返すよ。
Source
Cameras-CubeCamera-
webGLRenderTargetCubeに与える6つのカメラを作成します。
example
materials / cubemap / dynamic2
//Create cube camera
var cubeCamera = new THREE.CubeCamera( 1, 100000, 128 );
scene.add( cubeCamera ); //Create car
var chromeMaterial = new THREE.MeshLambertMaterial( { color: 0xffffff, envMap: cubeCamera.renderTarget } );
var car = new Mesh( carGeometry, chromeMaterial );
scene.add( car ); //Update the render target cube
car.setVisible( false ); cubeCamera.position.copy( car.position ); cubeCamera.updateCubeMap( renderer, scene ); //Render the scene
car.setVisible( true ); renderer.render( scene, camera );
Constructor
CubeCamera(near,far,cubeResolution)
near--近いクリッピングの距離を表します。
far--遠距離のクリッピングの距離を表します。
cubeResolution―cubeの幅の大きさをセットします。
webGLRenderTargetCubeに渡すような6つのPerspectiveCameraを含むようなCubeCameraを構成します。
Properties
.renderTarget
生成されるようなcubeのテクスチャ
Methods
.updateCubeMap (renderer, scene)
renderer ― 現在のwebGLレンダラー
scean ― 現在のシーン
ターゲットをアップデートしたい時に、この要素よ呼び出します。
Source
Cameras-camera-
カメラのベースとなるクラスについて書いていきます。
このクラスは、新しいカメラを作る際に、常に維持され続ける必要があります。
Constructor
Camera()
このconstructorは、正しいタイプ(matrixWorldInverseと、projectionMatrix)に対する以下の特性を持っています。
properties
.matrixWorldInverse
これは、matrixworldの正反対のものです。
matrixWorldは、カメラの全体的な変換を持つ行列を持っています。
.projectionMatrix
これは、projectionを含む行列です。
Methods
.getWorldDirection (vector)
vector-(optional)
指定されている空間において、カメラが見ている方向を表してくれるベクトルを返してくれる要素です。
.lookAt(vector)
vector-point to look at
これは、このカメラの親要素が、シーンか、position(0,0,0)であるのと同じように全体的
な空間において、ベクトルでのpositionが見えるような カメラを作り出します。
.clone(camera)
camera-camera to clone
カメラのクローンを返します。
Source
イントロダクション-次元変換-
Three.jsは、3D変換を、コード化するために、行列を使用します。
変換位置、回転、そして、機能拡張していく。
全てのObject3Dのインスタンスは、物体の位置や、回転そして、規模を保持している行列を持っている。
このページは、どのようにオブジェクトの変換をアップデートしていくのかについて描写していく。
便利な特性と、matrixAutoUpdate
物体の変換のアップデートのためには、二つの方法がある。
物体の位置、4元数、そして規模の特性を、修正し、それらの特性から、物体の行列をthree.jsに再計算
させます。
object.position.copy(start_position);
object.quaternion.copy(quaternion);
規定では、matrixAutoUpdateの特性は trueにセットされていて、
行列は、自動的に再計算されます。
もし、物体が静的なら、再計算が起こった時、主導でコントロールしたいのなら、
よりよいパフォーマンスは、特性をfalseにしたら得られる。
object.matrixAutoUpdate = false;
そして、多くの特性を変えた後、 行列は、アップデートされます。
object.updateMatrix();
物体の行列を直接修正する。Matrix4クラスは、行列を修正するための様々なメソッドを
持っています。
object.matrix.setRotationFromQuaternion(quaternion); object.matrix.setPosition(start_position); object.matrixAutoUpdate = false;
matrixAutoUpdateは、このケースでは、falseにセットされていて、必ずしもmatrixAutoUpdateを呼び出す必要はないってことに、注意してください。
updateMatrixを呼び出すことが、行列や、位置からの再計算、規模やその他へ作られる変化
手動での変化をなくします。
物体と、WorldMatrix
物体の行列は、物体のparentとの関係性への物体の変化を蓄えています。
世界の同等での物体の変化を得るために、物体のObject3D.matrixWorld.にアクセスする
必要があります。
parentかchild objectの転換が変わる時、childオブジェクトのupdateMatrixWorld()を呼んだことによってアップデートされたmatrixworldを呼ぶ事ができます。
Rotationと、Quaternion
Three.js は、3D回転を再表現することの2つの方法を提供してくれます。
二つの間で、転換するための方法と同等の オイラー角と、Quaternions。オイラー角と、gimbal lockと呼ばれる。そこでは、ある配置では、自由の度合いを失います。
(物体が一つの軸でしか回転しなくなることを防ぐ)
この理由によって、物体の回転は、常に4元数に保存されます。