[three] Update bones_browser and webgl_animation_skinning_morph tests (#33888)

* Update tests

* Remove unused interface
This commit is contained in:
Nathan Bierema
2019-03-15 10:25:37 -07:00
committed by Wesley Wigham
parent 8085f1a7bd
commit a3a8f82806
4 changed files with 180 additions and 183 deletions
+21 -6
View File
@@ -42,7 +42,7 @@
initBones();
}
function createGeometry(sizing: any) {
var geometry = new THREE.CylinderGeometry(
var geometry = new THREE.CylinderBufferGeometry(
5, // radiusTop
5, // radiusBottom
sizing.height, // height
@@ -50,14 +50,29 @@
sizing.segmentCount * 3, // heightSegments
true // openEnded
);
for (var i = 0; i < geometry.vertices.length; i++) {
var vertex = geometry.vertices[i];
var position = geometry.attributes.position as THREE.BufferAttribute;
var vertex = new THREE.Vector3();
var skinIndices = [];
var skinWeights = [];
for (var i = 0; i < position.count; i++) {
vertex.fromBufferAttribute(position, i);
var y = (vertex.y + sizing.halfHeight);
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));
skinIndices.push(skinIndex, skinIndex + 1, 0, 0);
skinWeights.push(1 - skinWeight, skinWeight, 0, 0);
}
geometry.addAttribute('skinIndex', new THREE.Uint16BufferAttribute(skinIndices, 4));
geometry.addAttribute('skinWeight', new THREE.Float32BufferAttribute(skinWeights, 4));
return geometry;
}
function createBones(sizing: any) {
@@ -74,7 +89,7 @@
}
return bones;
}
function createMesh(geometry: THREE.Geometry, bones: THREE.Bone[]) {
function createMesh(geometry: THREE.BufferGeometry, bones: THREE.Bone[]) {
var material = new THREE.MeshPhongMaterial({
skinning: true,
color: 0x156289,
+1
View File
@@ -2,3 +2,4 @@
/// <reference types="stats.js" />
/// <reference types="tween.js" />
/// <reference types="dat.gui" />
@@ -1,228 +1,209 @@
// https://github.com/mrdoob/three.js/blob/master/examples/webgl_sprites.html
// https://github.com/mrdoob/three.js/blob/master/examples/webgl_animation_skinning_morph.html
() => {
// ------- variable definitions that does not exist in the original code. These are for typescript.
interface WEBGL {
isWebGLAvailable(): boolean;
isWebGL2Available(): boolean;
getWebGLErrorMessage(): HTMLDivElement;
getWebGL2ErrorMessage(): HTMLDivElement;
getErrorMessage(version: 1 | 2): HTMLDivElement;
}
var WEBGL: WEBGL;
// -------
var SCREEN_WIDTH = window.innerWidth;
var SCREEN_HEIGHT = window.innerHeight;
var FLOOR = -250;
var container: HTMLElement;
if (WEBGL.isWebGLAvailable() === false) {
document.body.appendChild(WEBGL.getWebGLErrorMessage());
}
var container: HTMLElement
var stats: Stats;
var clock: THREE.Clock;
var gui: dat.GUI;
var mixer: THREE.AnimationMixer;
var actions: { [name: string]: THREE.AnimationAction };
var activeAction: THREE.AnimationAction;
var previousAction: THREE.AnimationAction;
var camera: THREE.PerspectiveCamera;
var scene: THREE.Scene;
var renderer: THREE.WebGLRenderer;
var mesh: THREE.Mesh;
var helper: THREE.SkeletonHelper;
var mixer: THREE.AnimationMixer;
var model: THREE.Scene;
var face: THREE.Mesh;
var mouseX = 0, mouseY = 0;
type Emote = 'Jump' | 'Yes' | 'No' | 'Wave' | 'Punch' | 'ThumbsUp';
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
var clock = new THREE.Clock();
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
var api: { [name in Emote]?: () => void; } & { state: string; } = {state: 'Walking'};
init();
animate();
function init() {
container = document.createElement('div');
document.body.appendChild(container);
container = document.getElementById( 'container' );
camera = new THREE.PerspectiveCamera( 30, SCREEN_WIDTH / SCREEN_HEIGHT, 1, 10000 );
camera.position.z = 2200;
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.25, 100);
camera.position.set(-5, 3, 10);
camera.lookAt(new THREE.Vector3(0, 2, 0));
scene = new THREE.Scene();
scene.background = new THREE.Color(0xe0e0e0);
scene.fog = new THREE.Fog(0xe0e0e0, 20, 100);
scene.fog = new THREE.Fog( 0xffffff, 2000, 10000 );
clock = new THREE.Clock();
scene.add( camera );
// lights
var light: THREE.Light = new THREE.HemisphereLight(0xffffff, 0x444444);
light.position.set(0, 20, 0);
scene.add(light);
// GROUND
light = new THREE.DirectionalLight(0xffffff);
light.position.set(0, 20, 10);
scene.add(light);
var geometry = new THREE.PlaneBufferGeometry( 16000, 16000 );
var material = new THREE.MeshPhongMaterial( { emissive: 0x888888 } );
// ground
var mesh = new THREE.Mesh(new THREE.PlaneBufferGeometry(2000, 2000), new THREE.MeshPhongMaterial({
color: 0x999999,
depthWrite: false
}));
mesh.rotation.x = -Math.PI / 2;
scene.add(mesh);
var ground = new THREE.Mesh( geometry, material );
ground.position.set( 0, FLOOR, 0 );
ground.rotation.x = -Math.PI/2;
scene.add( ground );
var grid = new THREE.GridHelper(200, 40, 0x000000, 0x000000);
(grid.material as THREE.LineBasicMaterial).opacity = 0.2;
(grid.material as THREE.LineBasicMaterial).transparent = true;
scene.add(grid);
ground.receiveShadow = true;
// model
var loader = new THREE.GLTFLoader();
loader.load('models/gltf/RobotExpressive/RobotExpressive.glb', function (gltf) {
model = gltf.scene;
scene.add(model);
createGUI(model, gltf.animations);
}, undefined, function (e) {
console.error(e);
});
// LIGHTS
scene.add( new THREE.HemisphereLight( 0x111111, 0x444444 ) );
var light = new THREE.DirectionalLight( 0xebf3ff, 1.5 );
light.position.set( 0, 140, 500 ).multiplyScalar( 1.1 );
scene.add( light );
light.castShadow = true;
light.shadowMapWidth = 1024;
light.shadowMapHeight = 1024;
var d = 390;
light.shadowCameraLeft = -d;
light.shadowCameraRight = d;
light.shadowCameraTop = d * 1.5;
light.shadowCameraBottom = -d;
light.shadowCameraFar = 3500;
//light.shadowCameraVisible = true;
// RENDERER
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setClearColor( scene.fog.color );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
renderer.domElement.style.position = "relative";
container.appendChild( renderer.domElement );
renderer.gammaInput = true;
renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.gammaOutput = true;
renderer.gammaFactor = 2.2;
container.appendChild(renderer.domElement);
renderer.shadowMap.enabled = true;
// STATS
window.addEventListener('resize', onWindowResize, false);
// stats
stats = new Stats();
container.appendChild( stats.dom );
container.appendChild(stats.dom);
}
//
function createGUI(model: THREE.Scene, animations: THREE.AnimationClip[]) {
var states = ['Idle', 'Walking', 'Running', 'Dance', 'Death', 'Sitting', 'Standing'];
var emotes: Emote[] = ['Jump', 'Yes', 'No', 'Wave', 'Punch', 'ThumbsUp'];
var loader = new THREE.JSONLoader();
loader.load( "models/skinned/knight.js", function ( geometry, materials ) {
gui = new dat.GUI();
createScene( geometry, materials as THREE.MeshPhongMaterial[], 0, FLOOR, -300, 60 )
mixer = new THREE.AnimationMixer(model);
} );
actions = {};
// GUI
for (var i = 0; i < animations.length; i++) {
var clip = animations[i];
var action = mixer.clipAction(clip);
actions[clip.name] = action;
initGUI();
if (emotes.indexOf(clip.name as Emote) >= 0 || states.indexOf(clip.name) >= 4) {
action.clampWhenFinished = true;
action.loop = THREE.LoopOnce;
}
}
//
// states
var statesFolder = gui.addFolder('States');
window.addEventListener( 'resize', onWindowResize, false );
var clipCtrl = statesFolder.add(api, 'state').options(states);
clipCtrl.onChange(function () {
fadeToAction(api.state, 0.5);
});
statesFolder.open();
// emotes
var emoteFolder = gui.addFolder('Emote');
function createEmoteCallback(name: Emote) {
api[name] = function () {
fadeToAction(name, 0.2);
mixer.addEventListener('finished', restoreState);
};
emoteFolder.add(api, name);
}
function restoreState() {
mixer.removeEventListener('finished', restoreState);
fadeToAction(api.state, 0.2);
}
for (var i = 0; i < emotes.length; i++) {
createEmoteCallback(emotes[i]);
}
emoteFolder.open();
// expressions
face = model.getObjectByName('Head_2') as THREE.Mesh;
var expressions = Object.keys(face.morphTargetDictionary);
var expressionFolder = gui.addFolder('Expressions');
for (var i = 0; i < expressions.length; i++) {
expressionFolder.add(face.morphTargetInfluences, i.toString(), 0, 1, 0.01).name(expressions[i]);
}
activeAction = actions['Walking'];
activeAction.play();
expressionFolder.open();
}
function fadeToAction(name: string, duration: number) {
previousAction = activeAction;
activeAction = actions[name];
if (previousAction !== activeAction) {
previousAction.fadeOut(duration);
}
activeAction
.reset()
.setEffectiveTimeScale(1)
.setEffectiveWeight(1)
.fadeIn(duration)
.play();
}
function onWindowResize() {
windowHalfX = window.innerWidth / 2;
windowHalfY = window.innerHeight / 2;
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function createScene( geometry: THREE.Geometry, materials: THREE.MeshPhongMaterial[], x: number, y: number, z: number, s: number ) {
//ensureLoop( geometry.animation );
geometry.computeBoundingBox();
var bb = geometry.boundingBox;
var path = "textures/cube/Park2/";
var format = '.jpg';
var urls = [
path + 'posx' + format, path + 'negx' + format,
path + 'posy' + format, path + 'negy' + format,
path + 'posz' + format, path + 'negz' + format
];
for ( var i = 0; i < materials.length; i ++ ) {
var m = materials[ i ];
m.skinning = true;
m.morphTargets = true;
m.specular.setHSL( 0, 0, 0.1 );
m.color.setHSL( 0.6, 0, 0.6 );
//m.map = map;
//m.envMap = envMap;
//m.bumpMap = bumpMap;
//m.bumpScale = 2;
//m.combine = THREE.MixOperation;
//m.reflectivity = 0.75;
}
mesh = new THREE.SkinnedMesh( geometry, new THREE.MeshFaceMaterial( materials ) );
mesh.position.set( x, y - bb.min.y * s, z );
mesh.scale.set( s, s, s );
scene.add( mesh );
mesh.castShadow = true;
mesh.receiveShadow = true;
helper = new THREE.SkeletonHelper( mesh );
//helper.material.linewidth = 3;
helper.visible = false;
scene.add( helper );
var clipMorpher = THREE.AnimationClip.CreateFromMorphTargetSequence( 'facialExpressions', (mesh.geometry as THREE.Geometry).morphTargets, 3, true );
var clipBones = geometry.animations[0];
mixer = new THREE.AnimationMixer( mesh );
}
function initGUI() {
mesh.visible = true;
helper.visible = true;
}
function onDocumentMouseMove( event: MouseEvent ) {
mouseX = ( event.clientX - windowHalfX );
mouseY = ( event.clientY - windowHalfY );
renderer.setSize(window.innerWidth, window.innerHeight);
}
//
function animate() {
requestAnimationFrame( animate );
render();
var dt = clock.getDelta();
if (mixer) mixer.update(dt);
requestAnimationFrame(animate);
renderer.render(scene, camera);
stats.update();
}
function render() {
var delta = 0.75 * clock.getDelta();
camera.position.x += ( mouseX - camera.position.x ) * .05;
camera.position.y = THREE.Math.clamp( camera.position.y + ( - mouseY - camera.position.y ) * .05, 0, 1000 );
camera.lookAt( scene.position );
if( mixer ) {
mixer.update( delta );
helper.update();
}
renderer.render( scene, camera );
}
}
}
+1 -1
View File
@@ -224,7 +224,7 @@ type TypedArray = Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint
// Animation ////////////////////////////////////////////////////////////////////////////////////////
export class AnimationAction {
loop: boolean;
loop: AnimationActionLoopStyles;
time: number;
timeScale: number;
weight: number;