|
@@ -39,25 +39,27 @@
|
|
<script src="../../examples/js/controls/OrbitControls.js"></script>
|
|
<script src="../../examples/js/controls/OrbitControls.js"></script>
|
|
|
|
|
|
<script>
|
|
<script>
|
|
-
|
|
|
|
|
|
+
|
|
var gui, scene, camera, renderer, orbit, ambientLight, lights, mesh, bones, skeletonHelper;
|
|
var gui, scene, camera, renderer, orbit, ambientLight, lights, mesh, bones, skeletonHelper;
|
|
-
|
|
|
|
|
|
+
|
|
var state = {
|
|
var state = {
|
|
|
|
+
|
|
animateBones : false
|
|
animateBones : false
|
|
|
|
+
|
|
};
|
|
};
|
|
-
|
|
|
|
|
|
+
|
|
function initScene () {
|
|
function initScene () {
|
|
-
|
|
|
|
|
|
+
|
|
gui = new dat.GUI();
|
|
gui = new dat.GUI();
|
|
scene = new THREE.Scene();
|
|
scene = new THREE.Scene();
|
|
- camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 200 );
|
|
|
|
|
|
+ camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 200 );
|
|
camera.position.z = 30;
|
|
camera.position.z = 30;
|
|
camera.position.y = 30;
|
|
camera.position.y = 30;
|
|
-
|
|
|
|
- renderer = new THREE.WebGLRenderer({antialias: true});
|
|
|
|
|
|
+
|
|
|
|
+ renderer = new THREE.WebGLRenderer( { antialias: true } );
|
|
renderer.setSize( window.innerWidth, window.innerHeight );
|
|
renderer.setSize( window.innerWidth, window.innerHeight );
|
|
document.body.appendChild( renderer.domElement );
|
|
document.body.appendChild( renderer.domElement );
|
|
-
|
|
|
|
|
|
+
|
|
orbit = new THREE.OrbitControls( camera, renderer.domElement );
|
|
orbit = new THREE.OrbitControls( camera, renderer.domElement );
|
|
orbit.noZoom = true;
|
|
orbit.noZoom = true;
|
|
|
|
|
|
@@ -65,33 +67,34 @@
|
|
scene.add( ambientLight );
|
|
scene.add( ambientLight );
|
|
|
|
|
|
lights = [];
|
|
lights = [];
|
|
- lights[0] = new THREE.PointLight( 0xffffff, 1, 0 );
|
|
|
|
- lights[1] = new THREE.PointLight( 0xffffff, 1, 0 );
|
|
|
|
- lights[2] = new THREE.PointLight( 0xffffff, 1, 0 );
|
|
|
|
-
|
|
|
|
- lights[0].position.set( 0, 200, 0 );
|
|
|
|
- lights[1].position.set( 100, 200, 100 );
|
|
|
|
- lights[2].position.set( -100, -200, -100 );
|
|
|
|
|
|
+ lights[ 0 ] = new THREE.PointLight( 0xffffff, 1, 0 );
|
|
|
|
+ lights[ 1 ] = new THREE.PointLight( 0xffffff, 1, 0 );
|
|
|
|
+ lights[ 2 ] = new THREE.PointLight( 0xffffff, 1, 0 );
|
|
|
|
+
|
|
|
|
+ lights[ 0 ].position.set( 0, 200, 0 );
|
|
|
|
+ lights[ 1 ].position.set( 100, 200, 100 );
|
|
|
|
+ lights[ 2 ].position.set( -100, -200, -100 );
|
|
|
|
+
|
|
|
|
+ scene.add( lights[ 0 ] );
|
|
|
|
+ scene.add( lights[ 1 ] );
|
|
|
|
+ scene.add( lights[ 2 ] );
|
|
|
|
|
|
- scene.add( lights[0] );
|
|
|
|
- scene.add( lights[1] );
|
|
|
|
- scene.add( lights[2] );
|
|
|
|
-
|
|
|
|
window.addEventListener( 'resize', function () {
|
|
window.addEventListener( 'resize', function () {
|
|
-
|
|
|
|
|
|
+
|
|
camera.aspect = window.innerWidth / window.innerHeight;
|
|
camera.aspect = window.innerWidth / window.innerHeight;
|
|
camera.updateProjectionMatrix();
|
|
camera.updateProjectionMatrix();
|
|
|
|
|
|
renderer.setSize( window.innerWidth, window.innerHeight );
|
|
renderer.setSize( window.innerWidth, window.innerHeight );
|
|
-
|
|
|
|
|
|
+
|
|
}, false );
|
|
}, false );
|
|
-
|
|
|
|
|
|
+
|
|
initBones();
|
|
initBones();
|
|
setupDatGui();
|
|
setupDatGui();
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
|
|
function createGeometry ( sizing ) {
|
|
function createGeometry ( sizing ) {
|
|
-
|
|
|
|
|
|
+
|
|
var geometry = new THREE.CylinderGeometry(
|
|
var geometry = new THREE.CylinderGeometry(
|
|
5, // radiusTop
|
|
5, // radiusTop
|
|
5, // radiusBottom
|
|
5, // radiusBottom
|
|
@@ -100,88 +103,90 @@
|
|
sizing.segmentCount * 3, // heightSegments
|
|
sizing.segmentCount * 3, // heightSegments
|
|
true // openEnded
|
|
true // openEnded
|
|
);
|
|
);
|
|
-
|
|
|
|
- for( var i=0; i < geometry.vertices.length; i++ ) {
|
|
|
|
-
|
|
|
|
- var vertex = geometry.vertices[i];
|
|
|
|
- var y = (vertex.y + sizing.halfHeight);
|
|
|
|
-
|
|
|
|
|
|
+
|
|
|
|
+ for ( var i = 0; i < geometry.vertices.length; i ++ ) {
|
|
|
|
+
|
|
|
|
+ var vertex = geometry.vertices[ i ];
|
|
|
|
+ var y = ( vertex.y + sizing.halfHeight );
|
|
|
|
+
|
|
var skinIndex = Math.floor( y / sizing.segmentHeight );
|
|
var skinIndex = Math.floor( y / sizing.segmentHeight );
|
|
- var skinWeight = (y % sizing.segmentHeight) / sizing.segmentHeight;
|
|
|
|
-
|
|
|
|
- geometry.skinIndices.push( new THREE.Vector4( skinIndex, skinIndex+1, 0, 0 ) );
|
|
|
|
- geometry.skinWeights.push( new THREE.Vector4( 1-skinWeight, skinWeight, 0, 0 ) );
|
|
|
|
-
|
|
|
|
|
|
+ var skinWeight = ( y % sizing.segmentHeight ) / sizing.segmentHeight;
|
|
|
|
+
|
|
|
|
+ geometry.skinIndices.push( new THREE.Vector4( skinIndex, skinIndex + 1, 0, 0 ) );
|
|
|
|
+ geometry.skinWeights.push( new THREE.Vector4( 1 - skinWeight, skinWeight, 0, 0 ) );
|
|
|
|
+
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
return geometry;
|
|
return geometry;
|
|
|
|
+
|
|
};
|
|
};
|
|
-
|
|
|
|
|
|
+
|
|
function createBones ( sizing ) {
|
|
function createBones ( sizing ) {
|
|
-
|
|
|
|
|
|
+
|
|
bones = [];
|
|
bones = [];
|
|
-
|
|
|
|
|
|
+
|
|
var prevBone = new THREE.Bone();
|
|
var prevBone = new THREE.Bone();
|
|
bones.push( prevBone );
|
|
bones.push( prevBone );
|
|
prevBone.position.y = -sizing.halfHeight;
|
|
prevBone.position.y = -sizing.halfHeight;
|
|
-
|
|
|
|
- for( var i=0; i < sizing.segmentCount; i++ ) {
|
|
|
|
-
|
|
|
|
|
|
+
|
|
|
|
+ for ( var i = 0; i < sizing.segmentCount; i ++ ) {
|
|
|
|
+
|
|
var bone = new THREE.Bone();
|
|
var bone = new THREE.Bone();
|
|
bone.position.y = sizing.segmentHeight;
|
|
bone.position.y = sizing.segmentHeight;
|
|
bones.push( bone );
|
|
bones.push( bone );
|
|
prevBone.add( bone );
|
|
prevBone.add( bone );
|
|
prevBone = bone;
|
|
prevBone = bone;
|
|
-
|
|
|
|
|
|
+
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
return bones;
|
|
return bones;
|
|
|
|
+
|
|
};
|
|
};
|
|
|
|
|
|
function createMesh ( geometry, bones ) {
|
|
function createMesh ( geometry, bones ) {
|
|
-
|
|
|
|
- var material = new THREE.MeshPhongMaterial({
|
|
|
|
|
|
+
|
|
|
|
+ var material = new THREE.MeshPhongMaterial( {
|
|
skinning : true,
|
|
skinning : true,
|
|
color: 0x156289,
|
|
color: 0x156289,
|
|
emissive: 0x072534,
|
|
emissive: 0x072534,
|
|
side: THREE.DoubleSide,
|
|
side: THREE.DoubleSide,
|
|
shading: THREE.FlatShading
|
|
shading: THREE.FlatShading
|
|
- });
|
|
|
|
-
|
|
|
|
|
|
+ } );
|
|
|
|
+
|
|
var mesh = new THREE.SkinnedMesh( geometry, material );
|
|
var mesh = new THREE.SkinnedMesh( geometry, material );
|
|
var skeleton = new THREE.Skeleton( bones );
|
|
var skeleton = new THREE.Skeleton( bones );
|
|
-
|
|
|
|
- mesh.add( bones[0] );
|
|
|
|
-
|
|
|
|
|
|
+
|
|
|
|
+ mesh.add( bones[ 0 ] );
|
|
|
|
+
|
|
mesh.bind( skeleton );
|
|
mesh.bind( skeleton );
|
|
skeleton.calculateInverses();
|
|
skeleton.calculateInverses();
|
|
-
|
|
|
|
|
|
+
|
|
skeletonHelper = new THREE.SkeletonHelper( mesh );
|
|
skeletonHelper = new THREE.SkeletonHelper( mesh );
|
|
skeletonHelper.material.linewidth = 2;
|
|
skeletonHelper.material.linewidth = 2;
|
|
scene.add( skeletonHelper );
|
|
scene.add( skeletonHelper );
|
|
-
|
|
|
|
|
|
+
|
|
return mesh;
|
|
return mesh;
|
|
-
|
|
|
|
|
|
+
|
|
};
|
|
};
|
|
-
|
|
|
|
|
|
+
|
|
function setupDatGui () {
|
|
function setupDatGui () {
|
|
-
|
|
|
|
|
|
+
|
|
var folder = gui.addFolder( "General Options" );
|
|
var folder = gui.addFolder( "General Options" );
|
|
-
|
|
|
|
|
|
+
|
|
folder.add( state, "animateBones" );
|
|
folder.add( state, "animateBones" );
|
|
- folder.__controllers[0].name("Animate Bones");
|
|
|
|
|
|
+ folder.__controllers[ 0 ].name( "Animate Bones" );
|
|
|
|
|
|
folder.add( mesh, "pose" );
|
|
folder.add( mesh, "pose" );
|
|
- folder.__controllers[1].name(".pose()");
|
|
|
|
-
|
|
|
|
|
|
+ folder.__controllers[ 1 ].name( ".pose()" );
|
|
|
|
+
|
|
var bones = mesh.skeleton.bones;
|
|
var bones = mesh.skeleton.bones;
|
|
-
|
|
|
|
- for( var i=0; i < bones.length; i++ ) {
|
|
|
|
-
|
|
|
|
- var bone = bones[i];
|
|
|
|
-
|
|
|
|
|
|
+
|
|
|
|
+ for ( var i = 0; i < bones.length; i ++ ) {
|
|
|
|
+
|
|
|
|
+ var bone = bones[ i ];
|
|
|
|
+
|
|
folder = gui.addFolder( "Bone " + i );
|
|
folder = gui.addFolder( "Bone " + i );
|
|
-
|
|
|
|
|
|
+
|
|
folder.add( bone.position, 'x', -10 + bone.position.x, 10 + bone.position.x );
|
|
folder.add( bone.position, 'x', -10 + bone.position.x, 10 + bone.position.x );
|
|
folder.add( bone.position, 'y', -10 + bone.position.y, 10 + bone.position.y );
|
|
folder.add( bone.position, 'y', -10 + bone.position.y, 10 + bone.position.y );
|
|
folder.add( bone.position, 'z', -10 + bone.position.z, 10 + bone.position.z );
|
|
folder.add( bone.position, 'z', -10 + bone.position.z, 10 + bone.position.z );
|
|
@@ -189,76 +194,76 @@
|
|
folder.add( bone.rotation, 'x', -Math.PI * 0.5, Math.PI * 0.5 );
|
|
folder.add( bone.rotation, 'x', -Math.PI * 0.5, Math.PI * 0.5 );
|
|
folder.add( bone.rotation, 'y', -Math.PI * 0.5, Math.PI * 0.5 );
|
|
folder.add( bone.rotation, 'y', -Math.PI * 0.5, Math.PI * 0.5 );
|
|
folder.add( bone.rotation, 'z', -Math.PI * 0.5, Math.PI * 0.5 );
|
|
folder.add( bone.rotation, 'z', -Math.PI * 0.5, Math.PI * 0.5 );
|
|
-
|
|
|
|
|
|
+
|
|
folder.add( bone.scale, 'x', 0, 2 );
|
|
folder.add( bone.scale, 'x', 0, 2 );
|
|
folder.add( bone.scale, 'y', 0, 2 );
|
|
folder.add( bone.scale, 'y', 0, 2 );
|
|
folder.add( bone.scale, 'z', 0, 2 );
|
|
folder.add( bone.scale, 'z', 0, 2 );
|
|
|
|
|
|
- folder.__controllers[0].name("position.x");
|
|
|
|
- folder.__controllers[1].name("position.y");
|
|
|
|
- folder.__controllers[2].name("position.z");
|
|
|
|
-
|
|
|
|
- folder.__controllers[3].name("rotation.x");
|
|
|
|
- folder.__controllers[4].name("rotation.y");
|
|
|
|
- folder.__controllers[5].name("rotation.z");
|
|
|
|
-
|
|
|
|
- folder.__controllers[6].name("scale.x");
|
|
|
|
- folder.__controllers[7].name("scale.y");
|
|
|
|
- folder.__controllers[8].name("scale.z");
|
|
|
|
-
|
|
|
|
|
|
+ folder.__controllers[ 0 ].name( "position.x" );
|
|
|
|
+ folder.__controllers[ 1 ].name( "position.y" );
|
|
|
|
+ folder.__controllers[ 2 ].name( "position.z" );
|
|
|
|
+
|
|
|
|
+ folder.__controllers[ 3 ].name( "rotation.x" );
|
|
|
|
+ folder.__controllers[ 4 ].name( "rotation.y" );
|
|
|
|
+ folder.__controllers[ 5 ].name( "rotation.z" );
|
|
|
|
+
|
|
|
|
+ folder.__controllers[ 6 ].name( "scale.x" );
|
|
|
|
+ folder.__controllers[ 7 ].name( "scale.y" );
|
|
|
|
+ folder.__controllers[ 8 ].name( "scale.z" );
|
|
|
|
+
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
|
|
function initBones () {
|
|
function initBones () {
|
|
-
|
|
|
|
|
|
+
|
|
var segmentHeight = 8;
|
|
var segmentHeight = 8;
|
|
var segmentCount = 4;
|
|
var segmentCount = 4;
|
|
var height = segmentHeight * segmentCount;
|
|
var height = segmentHeight * segmentCount;
|
|
var halfHeight = height * 0.5;
|
|
var halfHeight = height * 0.5;
|
|
-
|
|
|
|
|
|
+
|
|
var sizing = {
|
|
var sizing = {
|
|
segmentHeight : segmentHeight,
|
|
segmentHeight : segmentHeight,
|
|
segmentCount : segmentCount,
|
|
segmentCount : segmentCount,
|
|
height : height,
|
|
height : height,
|
|
halfHeight : halfHeight
|
|
halfHeight : halfHeight
|
|
};
|
|
};
|
|
-
|
|
|
|
|
|
+
|
|
var geometry = createGeometry( sizing );
|
|
var geometry = createGeometry( sizing );
|
|
var bones = createBones( sizing );
|
|
var bones = createBones( sizing );
|
|
mesh = createMesh( geometry, bones );
|
|
mesh = createMesh( geometry, bones );
|
|
-
|
|
|
|
|
|
+
|
|
mesh.scale.multiplyScalar( 1 );
|
|
mesh.scale.multiplyScalar( 1 );
|
|
scene.add( mesh );
|
|
scene.add( mesh );
|
|
-
|
|
|
|
|
|
+
|
|
};
|
|
};
|
|
-
|
|
|
|
|
|
+
|
|
function render () {
|
|
function render () {
|
|
-
|
|
|
|
|
|
+
|
|
requestAnimationFrame( render );
|
|
requestAnimationFrame( render );
|
|
|
|
|
|
var time = Date.now() * 0.001;
|
|
var time = Date.now() * 0.001;
|
|
-
|
|
|
|
|
|
+
|
|
var bone = mesh;
|
|
var bone = mesh;
|
|
|
|
|
|
-
|
|
|
|
|
|
+
|
|
//Wiggle the bones
|
|
//Wiggle the bones
|
|
- if( state.animateBones ) {
|
|
|
|
-
|
|
|
|
- for( var i=0; i < mesh.skeleton.bones.length; i++ ) {
|
|
|
|
-
|
|
|
|
- mesh.skeleton.bones[i].rotation.z = Math.sin( time ) * 2 / mesh.skeleton.bones.length;
|
|
|
|
-
|
|
|
|
|
|
+ if ( state.animateBones ) {
|
|
|
|
+
|
|
|
|
+ for ( var i = 0; i < mesh.skeleton.bones.length; i ++ ) {
|
|
|
|
+
|
|
|
|
+ mesh.skeleton.bones[ i ].rotation.z = Math.sin( time ) * 2 / mesh.skeleton.bones.length;
|
|
|
|
+
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
|
|
skeletonHelper.update();
|
|
skeletonHelper.update();
|
|
-
|
|
|
|
|
|
+
|
|
renderer.render( scene, camera );
|
|
renderer.render( scene, camera );
|
|
-
|
|
|
|
|
|
+
|
|
};
|
|
};
|
|
-
|
|
|
|
|
|
+
|
|
initScene();
|
|
initScene();
|
|
render();
|
|
render();
|
|
|
|
|