skinview3d
Advanced tools
Comparing version 1.1.0-alpha.1 to 1.1.0-alpha.2
module.exports = { | ||
"root": true, | ||
"env": { | ||
"browser": true, | ||
"es6": true | ||
@@ -5,0 +5,0 @@ }, |
@@ -0,1 +1,28 @@ | ||
/** | ||
* skinview3d (https://github.com/to2mbn/skinview3d) | ||
* | ||
* MIT License | ||
* | ||
* Copyright (c) 2014-2018 Kent Rasmussen | ||
* Copyright (c) 2017-2018 Haowei Wen, Sean Boult and contributors | ||
* | ||
* Permission is hereby granted, free of charge, to any person obtaining a copy | ||
* of this software and associated documentation files (the "Software"), to deal | ||
* in the Software without restriction, including without limitation the rights | ||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
* copies of the Software, and to permit persons to whom the Software is | ||
* furnished to do so, subject to the following conditions: | ||
* | ||
* The above copyright notice and this permission notice shall be included in all | ||
* copies or substantial portions of the Software. | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
* SOFTWARE. | ||
*/ | ||
(function (global, factory) { | ||
@@ -106,8 +133,10 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('three')) : | ||
function SkinObject(isSlim, layer1Material, layer2Material) { | ||
function SkinObject(slim, layer1Material, layer2Material) { | ||
classCallCheck(this, SkinObject); | ||
// Head | ||
var _this = possibleConstructorReturn(this, (SkinObject.__proto__ || Object.getPrototypeOf(SkinObject)).call(this)); | ||
_this.slim = slim; | ||
// Head | ||
_this.head = new THREE.Group(); | ||
@@ -148,4 +177,4 @@ | ||
var rightArmBox = new THREE.BoxGeometry((isSlim ? 3 : 4) - esp, 12 - esp, 4 - esp, 0, 0, 0); | ||
if (isSlim) { | ||
var rightArmBox = new THREE.BoxGeometry((slim ? 3 : 4) - esp, 12 - esp, 4 - esp, 0, 0, 0); | ||
if (slim) { | ||
addVertices(rightArmBox, toSkinVertices(44, 16, 47, 20), toSkinVertices(47, 16, 50, 20), toSkinVertices(40, 20, 44, 32), toSkinVertices(44, 20, 47, 32), toSkinVertices(47, 20, 51, 32), toSkinVertices(51, 20, 54, 32)); | ||
@@ -158,4 +187,4 @@ } else { | ||
var rightArm2Box = new THREE.BoxGeometry((isSlim ? 3.375 : 4.5) - esp, 13.5 - esp, 4.5 - esp, 0, 0, 0); | ||
if (isSlim) { | ||
var rightArm2Box = new THREE.BoxGeometry((slim ? 3.375 : 4.5) - esp, 13.5 - esp, 4.5 - esp, 0, 0, 0); | ||
if (slim) { | ||
addVertices(rightArm2Box, toSkinVertices(44, 32, 47, 36), toSkinVertices(47, 32, 50, 36), toSkinVertices(40, 36, 44, 48), toSkinVertices(44, 36, 47, 48), toSkinVertices(47, 36, 51, 48), toSkinVertices(51, 36, 54, 48)); | ||
@@ -172,3 +201,3 @@ } else { | ||
_this.rightArm.position.y = -4; | ||
_this.rightArm.position.x = isSlim ? -5.5 : -6; | ||
_this.rightArm.position.x = slim ? -5.5 : -6; | ||
_this.add(_this.rightArm); | ||
@@ -180,4 +209,4 @@ | ||
var leftArmBox = new THREE.BoxGeometry((isSlim ? 3 : 4) - esp, 12 - esp, 4 - esp, 0, 0, 0); | ||
if (isSlim) { | ||
var leftArmBox = new THREE.BoxGeometry((slim ? 3 : 4) - esp, 12 - esp, 4 - esp, 0, 0, 0); | ||
if (slim) { | ||
addVertices(leftArmBox, toSkinVertices(36, 48, 39, 52), toSkinVertices(39, 48, 42, 52), toSkinVertices(32, 52, 36, 64), toSkinVertices(36, 52, 39, 64), toSkinVertices(39, 52, 43, 64), toSkinVertices(43, 52, 46, 64)); | ||
@@ -190,4 +219,4 @@ } else { | ||
var leftArm2Box = new THREE.BoxGeometry((isSlim ? 3.375 : 4.5) - esp, 13.5 - esp, 4.5 - esp, 0, 0, 0); | ||
if (isSlim) { | ||
var leftArm2Box = new THREE.BoxGeometry((slim ? 3.375 : 4.5) - esp, 13.5 - esp, 4.5 - esp, 0, 0, 0); | ||
if (slim) { | ||
addVertices(leftArm2Box, toSkinVertices(52, 48, 55, 52), toSkinVertices(55, 48, 58, 52), toSkinVertices(48, 52, 52, 64), toSkinVertices(52, 52, 55, 64), toSkinVertices(55, 52, 59, 64), toSkinVertices(59, 52, 62, 64)); | ||
@@ -204,3 +233,3 @@ } else { | ||
_this.leftArm.position.y = -4; | ||
_this.leftArm.position.x = isSlim ? 5.5 : 6; | ||
_this.leftArm.position.x = slim ? 5.5 : 6; | ||
_this.add(_this.leftArm); | ||
@@ -285,4 +314,2 @@ | ||
_this3.slim = slim; | ||
_this3.skin = new SkinObject(slim, layer1Material, layer2Material); | ||
@@ -304,2 +331,388 @@ _this3.skin.visible = false; | ||
function invokeAnimation(animation, player, time) { | ||
if (animation instanceof CompositeAnimation) { | ||
animation.play(player, time); | ||
} else if (animation instanceof Function) { | ||
animation(player, time); | ||
} else { | ||
throw "Not an animation: " + animation; | ||
} | ||
} | ||
var AnimationHandle = function () { | ||
function AnimationHandle(animation) { | ||
classCallCheck(this, AnimationHandle); | ||
this.animation = animation; | ||
this.paused = this._paused = false; | ||
this.speed = this._speed = 1.0; | ||
this._lastChange = null; | ||
this._lastChangeX = null; | ||
} | ||
createClass(AnimationHandle, [{ | ||
key: "play", | ||
value: function play(player, time) { | ||
if (this._lastChange === null) { | ||
this._lastChange = time; | ||
this._lastChangeX = 0; | ||
} else if (this.paused !== this._paused || this.speed !== this._speed) { | ||
var dt = time - this._lastChange; | ||
if (this._paused === false) { | ||
this._lastChangeX += dt * this._speed; | ||
} | ||
this._paused = this.paused; | ||
this._speed = this.speed; | ||
this._lastChange = time; | ||
} | ||
if (this.paused === false) { | ||
var _dt = time - this._lastChange; | ||
var x = this._lastChangeX + this.speed * _dt; | ||
invokeAnimation(this.animation, player, x); | ||
} | ||
} | ||
}, { | ||
key: "reset", | ||
value: function reset() { | ||
this._lastChange = null; | ||
} | ||
}]); | ||
return AnimationHandle; | ||
}(); | ||
var CompositeAnimation = function () { | ||
function CompositeAnimation() { | ||
classCallCheck(this, CompositeAnimation); | ||
this.handles = new Set(); | ||
} | ||
createClass(CompositeAnimation, [{ | ||
key: "add", | ||
value: function add(animation) { | ||
var _this = this; | ||
var handle = new AnimationHandle(animation); | ||
handle.remove = function () { | ||
return _this.handles.delete(handle); | ||
}; | ||
this.handles.add(handle); | ||
return handle; | ||
} | ||
}, { | ||
key: "play", | ||
value: function play(player, time) { | ||
this.handles.forEach(function (handle) { | ||
return handle.play(player, time); | ||
}); | ||
} | ||
}]); | ||
return CompositeAnimation; | ||
}(); | ||
var WalkingAnimation = function WalkingAnimation(player, time) { | ||
var skin = player.skin; | ||
// Multiply by animation's natural speed | ||
time *= 8; | ||
// Leg swing | ||
skin.leftLeg.rotation.x = Math.sin(time) * 0.5; | ||
skin.rightLeg.rotation.x = Math.sin(time + Math.PI) * 0.5; | ||
// Arm swing | ||
skin.leftArm.rotation.x = Math.sin(time + Math.PI) * 0.5; | ||
skin.rightArm.rotation.x = Math.sin(time) * 0.5; | ||
var basicArmRotationZ = Math.PI * 0.02; | ||
skin.leftArm.rotation.z = Math.cos(time) * 0.03 + basicArmRotationZ; | ||
skin.rightArm.rotation.z = Math.cos(time + Math.PI) * 0.03 - basicArmRotationZ; | ||
// Head shaking with different frequency & amplitude | ||
skin.head.rotation.y = Math.sin(time / 4) * 0.2; | ||
skin.head.rotation.x = Math.sin(time / 5) * 0.1; | ||
// Always add an angle for cape around the x axis | ||
var basicCapeRotationX = Math.PI * 0.06; | ||
player.cape.rotation.x = Math.sin(time / 1.5) * 0.06 + basicCapeRotationX; | ||
}; | ||
var RunningAnimation = function RunningAnimation(player, time) { | ||
var skin = player.skin; | ||
time *= 15; | ||
// Leg swing with larger amplitude | ||
skin.leftLeg.rotation.x = Math.cos(time + Math.PI) * 1.3; | ||
skin.rightLeg.rotation.x = Math.cos(time) * 1.3; | ||
// Arm swing | ||
skin.leftArm.rotation.x = Math.cos(time) * 1.5; | ||
skin.rightArm.rotation.x = Math.cos(time + Math.PI) * 1.5; | ||
var basicArmRotationZ = Math.PI * 0.1; | ||
skin.leftArm.rotation.z = Math.cos(time) * 0.1 + basicArmRotationZ; | ||
skin.rightArm.rotation.z = Math.cos(time + Math.PI) * 0.1 - basicArmRotationZ; | ||
// Jumping | ||
player.position.y = Math.cos(time * 2); | ||
// Dodging when running | ||
player.position.x = Math.cos(time) * 0.15; | ||
// Slightly tilting when running | ||
player.rotation.z = Math.cos(time + Math.PI) * 0.01; | ||
// Apply higher swing frequency, lower amplitude, | ||
// and greater basic rotation around x axis, | ||
// to cape when running. | ||
var basicCapeRotationX = Math.PI * 0.3; | ||
player.cape.rotation.x = Math.sin(time * 2) * 0.1 + basicCapeRotationX; | ||
// What about head shaking? | ||
// You shouldn't glance right and left when running dude :P | ||
}; | ||
var RotatingAnimation = function RotatingAnimation(player, time) { | ||
player.rotation.y = time; | ||
}; | ||
function copyImage(context, sX, sY, w, h, dX, dY, flipHorizontal) { | ||
var imgData = context.getImageData(sX, sY, w, h); | ||
if (flipHorizontal) { | ||
for (var y = 0; y < h; y++) { | ||
for (var x = 0; x < w / 2; x++) { | ||
var index = (x + y * w) * 4; | ||
var index2 = (w - x - 1 + y * w) * 4; | ||
var pA1 = imgData.data[index]; | ||
var pA2 = imgData.data[index + 1]; | ||
var pA3 = imgData.data[index + 2]; | ||
var pA4 = imgData.data[index + 3]; | ||
var pB1 = imgData.data[index2]; | ||
var pB2 = imgData.data[index2 + 1]; | ||
var pB3 = imgData.data[index2 + 2]; | ||
var pB4 = imgData.data[index2 + 3]; | ||
imgData.data[index] = pB1; | ||
imgData.data[index + 1] = pB2; | ||
imgData.data[index + 2] = pB3; | ||
imgData.data[index + 3] = pB4; | ||
imgData.data[index2] = pA1; | ||
imgData.data[index2 + 1] = pA2; | ||
imgData.data[index2 + 2] = pA3; | ||
imgData.data[index2 + 3] = pA4; | ||
} | ||
} | ||
} | ||
context.putImageData(imgData, dX, dY); | ||
} | ||
function convertSkinTo1_8(context, width) { | ||
var scale = width / 64.0; | ||
var copySkin = function copySkin(context, sX, sY, w, h, dX, dY, flipHorizontal) { | ||
return copyImage(context, sX * scale, sY * scale, w * scale, h * scale, dX * scale, dY * scale, flipHorizontal); | ||
}; | ||
copySkin(context, 4, 16, 4, 4, 20, 48, true); // Top Leg | ||
copySkin(context, 8, 16, 4, 4, 24, 48, true); // Bottom Leg | ||
copySkin(context, 0, 20, 4, 12, 24, 52, true); // Outer Leg | ||
copySkin(context, 4, 20, 4, 12, 20, 52, true); // Front Leg | ||
copySkin(context, 8, 20, 4, 12, 16, 52, true); // Inner Leg | ||
copySkin(context, 12, 20, 4, 12, 28, 52, true); // Back Leg | ||
copySkin(context, 44, 16, 4, 4, 36, 48, true); // Top Arm | ||
copySkin(context, 48, 16, 4, 4, 40, 48, true); // Bottom Arm | ||
copySkin(context, 40, 20, 4, 12, 40, 52, true); // Outer Arm | ||
copySkin(context, 44, 20, 4, 12, 36, 52, true); // Front Arm | ||
copySkin(context, 48, 20, 4, 12, 32, 52, true); // Inner Arm | ||
copySkin(context, 52, 20, 4, 12, 44, 52, true); // Back Arm | ||
} | ||
var SkinViewer = function () { | ||
function SkinViewer(options) { | ||
var _this = this; | ||
classCallCheck(this, SkinViewer); | ||
this.domElement = options.domElement; | ||
this.animation = options.animation || null; | ||
this.animationPaused = false; | ||
this.animationTime = 0; | ||
this.disposed = false; | ||
// texture | ||
this.skinImg = new Image(); | ||
this.skinCanvas = document.createElement("canvas"); | ||
this.skinTexture = new THREE.Texture(this.skinCanvas); | ||
this.skinTexture.magFilter = THREE.NearestFilter; | ||
this.skinTexture.minFilter = THREE.NearestMipMapNearestFilter; | ||
this.capeImg = new Image(); | ||
this.capeCanvas = document.createElement("canvas"); | ||
this.capeTexture = new THREE.Texture(this.capeCanvas); | ||
this.capeTexture.magFilter = THREE.NearestFilter; | ||
this.capeTexture.minFilter = THREE.NearestMipMapNearestFilter; | ||
this.layer1Material = new THREE.MeshBasicMaterial({ map: this.skinTexture, side: THREE.FrontSide }); | ||
this.layer2Material = new THREE.MeshBasicMaterial({ map: this.skinTexture, transparent: true, opacity: 1, side: THREE.DoubleSide }); | ||
this.capeMaterial = new THREE.MeshBasicMaterial({ map: this.capeTexture }); | ||
// scene | ||
this.scene = new THREE.Scene(); | ||
// Use smaller fov to avoid distortion | ||
this.camera = new THREE.PerspectiveCamera(40); | ||
this.camera.position.y = -12; | ||
this.camera.position.z = 60; | ||
this.renderer = new THREE.WebGLRenderer({ angleRot: true, alpha: true, antialias: false }); | ||
this.renderer.setSize(300, 300); // default size | ||
this.renderer.context.getShaderInfoLog = function () { | ||
return ""; | ||
}; // shut firefox up | ||
this.domElement.appendChild(this.renderer.domElement); | ||
this.playerObject = new PlayerObject(options.slim === true, this.layer1Material, this.layer2Material, this.capeMaterial); | ||
this.scene.add(this.playerObject); | ||
// texture loading | ||
this.skinImg.crossOrigin = ""; | ||
this.skinImg.onerror = function () { | ||
return console.error("Failed loading " + _this.skinImg.src); | ||
}; | ||
this.skinImg.onload = function () { | ||
var isOldFormat = false; | ||
if (_this.skinImg.width !== _this.skinImg.height) { | ||
if (_this.skinImg.width === 2 * _this.skinImg.height) { | ||
isOldFormat = true; | ||
} else { | ||
console.error("Bad skin size"); | ||
return; | ||
} | ||
} | ||
var skinContext = _this.skinCanvas.getContext("2d"); | ||
if (isOldFormat) { | ||
var width = _this.skinImg.width; | ||
_this.skinCanvas.width = width; | ||
_this.skinCanvas.height = width; | ||
skinContext.clearRect(0, 0, width, width); | ||
skinContext.drawImage(_this.skinImg, 0, 0, width, width / 2.0); | ||
convertSkinTo1_8(skinContext, width); | ||
} else { | ||
_this.skinCanvas.width = _this.skinImg.width; | ||
_this.skinCanvas.height = _this.skinImg.height; | ||
skinContext.clearRect(0, 0, _this.skinCanvas.width, _this.skinCanvas.height); | ||
skinContext.drawImage(_this.skinImg, 0, 0, _this.skinCanvas.width, _this.skinCanvas.height); | ||
} | ||
_this.skinTexture.needsUpdate = true; | ||
_this.layer1Material.needsUpdate = true; | ||
_this.layer2Material.needsUpdate = true; | ||
_this.playerObject.skin.visible = true; | ||
}; | ||
this.capeImg.crossOrigin = ""; | ||
this.capeImg.onerror = function () { | ||
return console.error("Failed loading " + _this.capeImg.src); | ||
}; | ||
this.capeImg.onload = function () { | ||
var isOldFormat = false; | ||
if (_this.capeImg.width !== 2 * _this.capeImg.height) { | ||
if (_this.capeImg.width * 17 == _this.capeImg.height * 22) { | ||
// width/height = 22/17 | ||
isOldFormat = true; | ||
} else { | ||
console.error("Bad cape size"); | ||
return; | ||
} | ||
} | ||
var capeContext = _this.capeCanvas.getContext("2d"); | ||
if (isOldFormat) { | ||
var width = _this.capeImg.width * 64 / 22; | ||
_this.capeCanvas.width = width; | ||
_this.capeCanvas.height = width / 2; | ||
} else { | ||
_this.capeCanvas.width = _this.capeImg.width; | ||
_this.capeCanvas.height = _this.capeImg.height; | ||
} | ||
capeContext.clearRect(0, 0, _this.capeCanvas.width, _this.capeCanvas.height); | ||
capeContext.drawImage(_this.capeImg, 0, 0, _this.capeImg.width, _this.capeImg.height); | ||
_this.capeTexture.needsUpdate = true; | ||
_this.capeMaterial.needsUpdate = true; | ||
_this.playerObject.cape.visible = true; | ||
}; | ||
if (options.skinUrl) this.skinUrl = options.skinUrl; | ||
if (options.capeUrl) this.capeUrl = options.capeUrl; | ||
if (options.width) this.width = options.width; | ||
if (options.height) this.height = options.height; | ||
var draw = function draw() { | ||
if (_this.disposed) return; | ||
window.requestAnimationFrame(draw); | ||
if (!_this.animationPaused) { | ||
_this.animationTime++; | ||
if (_this.animation) { | ||
invokeAnimation(_this.animation, _this.playerObject, _this.animationTime / 100.0); | ||
} | ||
} | ||
_this.renderer.render(_this.scene, _this.camera); | ||
}; | ||
draw(); | ||
} | ||
createClass(SkinViewer, [{ | ||
key: "setSize", | ||
value: function setSize(width, height) { | ||
this.camera.aspect = width / height; | ||
this.camera.updateProjectionMatrix(); | ||
this.renderer.setSize(width, height); | ||
} | ||
}, { | ||
key: "dispose", | ||
value: function dispose() { | ||
this.disposed = true; | ||
this.domElement.removeChild(this.renderer.domElement); | ||
this.renderer.dispose(); | ||
this.skinTexture.dispose(); | ||
this.capeTexture.dispose(); | ||
} | ||
}, { | ||
key: "skinUrl", | ||
get: function get$$1() { | ||
return this.skinImg.src; | ||
}, | ||
set: function set$$1(url) { | ||
this.skinImg.src = url; | ||
} | ||
}, { | ||
key: "capeUrl", | ||
get: function get$$1() { | ||
return this.capeImg.src; | ||
}, | ||
set: function set$$1(url) { | ||
this.capeImg.src = url; | ||
} | ||
}, { | ||
key: "width", | ||
get: function get$$1() { | ||
return this.renderer.getSize().width; | ||
}, | ||
set: function set$$1(newWidth) { | ||
this.setSize(newWidth, this.height); | ||
} | ||
}, { | ||
key: "height", | ||
get: function get$$1() { | ||
return this.renderer.getSize().height; | ||
}, | ||
set: function set$$1(newHeight) { | ||
this.setSize(this.width, newHeight); | ||
} | ||
}]); | ||
return SkinViewer; | ||
}(); | ||
var OrbitControls = function (_THREE$EventDispatche) { | ||
@@ -867,386 +1280,15 @@ inherits(OrbitControls, _THREE$EventDispatche); | ||
function invokeAnimation(animation, player, time) { | ||
if (animation instanceof CompositeAnimation) { | ||
animation.play(player, time); | ||
} else if (animation instanceof Function) { | ||
animation(player, time); | ||
} else { | ||
throw "Not an animation: " + animation; | ||
} | ||
} | ||
function createOrbitControls(skinViewer) { | ||
var control = new OrbitControls(skinViewer.camera, skinViewer.renderer.domElement); | ||
var AnimationHandle = function () { | ||
function AnimationHandle(animation) { | ||
classCallCheck(this, AnimationHandle); | ||
// default configuration | ||
control.enablePan = false; | ||
control.target = new THREE.Vector3(0, -12, 0); | ||
control.minDistance = 10; | ||
control.maxDistance = 256; | ||
control.update(); | ||
this.animation = animation; | ||
this.paused = this._paused = false; | ||
this.speed = this._speed = 1.0; | ||
this._lastChange = null; | ||
this._lastChangeX = null; | ||
} | ||
createClass(AnimationHandle, [{ | ||
key: "play", | ||
value: function play(player, time) { | ||
if (this._lastChange === null) { | ||
this._lastChange = time; | ||
this._lastChangeX = 0; | ||
} else if (this.paused !== this._paused || this.speed !== this._speed) { | ||
var dt = time - this._lastChange; | ||
if (this._paused === false) { | ||
this._lastChangeX += dt * this._speed; | ||
} | ||
this._paused = this.paused; | ||
this._speed = this.speed; | ||
this._lastChange = time; | ||
} | ||
if (this.paused === false) { | ||
var _dt = time - this._lastChange; | ||
var x = this._lastChangeX + this.speed * _dt; | ||
invokeAnimation(this.animation, player, x); | ||
} | ||
} | ||
}, { | ||
key: "reset", | ||
value: function reset() { | ||
this._lastChange = null; | ||
} | ||
}]); | ||
return AnimationHandle; | ||
}(); | ||
var CompositeAnimation = function () { | ||
function CompositeAnimation() { | ||
classCallCheck(this, CompositeAnimation); | ||
this.handles = new Set(); | ||
} | ||
createClass(CompositeAnimation, [{ | ||
key: "add", | ||
value: function add(animation) { | ||
var _this = this; | ||
var handle = new AnimationHandle(animation); | ||
handle.remove = function () { | ||
return _this.handles.delete(handle); | ||
}; | ||
this.handles.add(handle); | ||
return handle; | ||
} | ||
}, { | ||
key: "play", | ||
value: function play(player, time) { | ||
this.handles.forEach(function (handle) { | ||
return handle.play(player, time); | ||
}); | ||
} | ||
}]); | ||
return CompositeAnimation; | ||
}(); | ||
var WalkAnimation = function WalkAnimation(player, time) { | ||
var skin = player.skin; | ||
var angleRot = time + Math.PI / 2; | ||
// Leg Swing | ||
skin.leftLeg.rotation.x = Math.cos(angleRot); | ||
skin.rightLeg.rotation.x = Math.cos(angleRot + Math.PI); | ||
// Arm Swing | ||
skin.leftArm.rotation.x = Math.cos(angleRot + Math.PI); | ||
skin.rightArm.rotation.x = Math.cos(angleRot); | ||
}; | ||
function copyImage(context, sX, sY, w, h, dX, dY, flipHorizontal) { | ||
var imgData = context.getImageData(sX, sY, w, h); | ||
if (flipHorizontal) { | ||
for (var y = 0; y < h; y++) { | ||
for (var x = 0; x < w / 2; x++) { | ||
var index = (x + y * w) * 4; | ||
var index2 = (w - x - 1 + y * w) * 4; | ||
var pA1 = imgData.data[index]; | ||
var pA2 = imgData.data[index + 1]; | ||
var pA3 = imgData.data[index + 2]; | ||
var pA4 = imgData.data[index + 3]; | ||
var pB1 = imgData.data[index2]; | ||
var pB2 = imgData.data[index2 + 1]; | ||
var pB3 = imgData.data[index2 + 2]; | ||
var pB4 = imgData.data[index2 + 3]; | ||
imgData.data[index] = pB1; | ||
imgData.data[index + 1] = pB2; | ||
imgData.data[index + 2] = pB3; | ||
imgData.data[index + 3] = pB4; | ||
imgData.data[index2] = pA1; | ||
imgData.data[index2 + 1] = pA2; | ||
imgData.data[index2 + 2] = pA3; | ||
imgData.data[index2 + 3] = pA4; | ||
} | ||
} | ||
} | ||
context.putImageData(imgData, dX, dY); | ||
return control; | ||
} | ||
function convertSkinTo1_8(context, width) { | ||
var scale = width / 64.0; | ||
var copySkin = function copySkin(context, sX, sY, w, h, dX, dY, flipHorizontal) { | ||
return copyImage(context, sX * scale, sY * scale, w * scale, h * scale, dX * scale, dY * scale, flipHorizontal); | ||
}; | ||
copySkin(context, 4, 16, 4, 4, 20, 48, true); // Top Leg | ||
copySkin(context, 8, 16, 4, 4, 24, 48, true); // Bottom Leg | ||
copySkin(context, 0, 20, 4, 12, 24, 52, true); // Outer Leg | ||
copySkin(context, 4, 20, 4, 12, 20, 52, true); // Front Leg | ||
copySkin(context, 8, 20, 4, 12, 16, 52, true); // Inner Leg | ||
copySkin(context, 12, 20, 4, 12, 28, 52, true); // Back Leg | ||
copySkin(context, 44, 16, 4, 4, 36, 48, true); // Top Arm | ||
copySkin(context, 48, 16, 4, 4, 40, 48, true); // Bottom Arm | ||
copySkin(context, 40, 20, 4, 12, 40, 52, true); // Outer Arm | ||
copySkin(context, 44, 20, 4, 12, 36, 52, true); // Front Arm | ||
copySkin(context, 48, 20, 4, 12, 32, 52, true); // Inner Arm | ||
copySkin(context, 52, 20, 4, 12, 44, 52, true); // Back Arm | ||
} | ||
var SkinViewer = function () { | ||
function SkinViewer(options) { | ||
var _this = this; | ||
classCallCheck(this, SkinViewer); | ||
this.domElement = options.domElement; | ||
this.animation = options.animation || null; | ||
this.animationPaused = false; | ||
this.animationSpeed = 3; | ||
this.animationTime = 0; | ||
this.disposed = false; | ||
// texture | ||
this.skinImg = new Image(); | ||
this.skinCanvas = document.createElement("canvas"); | ||
this.skinTexture = new THREE.Texture(this.skinCanvas); | ||
this.skinTexture.magFilter = THREE.NearestFilter; | ||
this.skinTexture.minFilter = THREE.NearestMipMapNearestFilter; | ||
this.capeImg = new Image(); | ||
this.capeCanvas = document.createElement("canvas"); | ||
this.capeTexture = new THREE.Texture(this.capeCanvas); | ||
this.capeTexture.magFilter = THREE.NearestFilter; | ||
this.capeTexture.minFilter = THREE.NearestMipMapNearestFilter; | ||
this.layer1Material = new THREE.MeshBasicMaterial({ map: this.skinTexture, side: THREE.FrontSide }); | ||
this.layer2Material = new THREE.MeshBasicMaterial({ map: this.skinTexture, transparent: true, opacity: 1, side: THREE.DoubleSide }); | ||
this.capeMaterial = new THREE.MeshBasicMaterial({ map: this.capeTexture }); | ||
// scene | ||
this.scene = new THREE.Scene(); | ||
this.camera = new THREE.PerspectiveCamera(75); | ||
this.camera.position.y = -12; | ||
this.camera.position.z = 30; | ||
this.renderer = new THREE.WebGLRenderer({ angleRot: true, alpha: true, antialias: false }); | ||
this.renderer.setSize(300, 300); // default size | ||
this.renderer.context.getShaderInfoLog = function () { | ||
return ""; | ||
}; // shut firefox up | ||
this.domElement.appendChild(this.renderer.domElement); | ||
this.playerObject = new PlayerObject(options.slim === true, this.layer1Material, this.layer2Material, this.capeMaterial); | ||
this.scene.add(this.playerObject); | ||
// texture loading | ||
this.skinImg.crossOrigin = ""; | ||
this.skinImg.onerror = function () { | ||
return console.error("Failed loading " + _this.skinImg.src); | ||
}; | ||
this.skinImg.onload = function () { | ||
var isOldFormat = false; | ||
if (_this.skinImg.width !== _this.skinImg.height) { | ||
if (_this.skinImg.width === 2 * _this.skinImg.height) { | ||
isOldFormat = true; | ||
} else { | ||
console.error("Bad skin size"); | ||
return; | ||
} | ||
} | ||
var skinContext = _this.skinCanvas.getContext("2d"); | ||
if (isOldFormat) { | ||
var width = _this.skinImg.width; | ||
_this.skinCanvas.width = width; | ||
_this.skinCanvas.height = width; | ||
skinContext.clearRect(0, 0, width, width); | ||
skinContext.drawImage(_this.skinImg, 0, 0, width, width / 2.0); | ||
convertSkinTo1_8(skinContext, width); | ||
} else { | ||
_this.skinCanvas.width = _this.skinImg.width; | ||
_this.skinCanvas.height = _this.skinImg.height; | ||
skinContext.clearRect(0, 0, _this.skinCanvas.width, _this.skinCanvas.height); | ||
skinContext.drawImage(_this.skinImg, 0, 0, _this.skinCanvas.width, _this.skinCanvas.height); | ||
} | ||
_this.skinTexture.needsUpdate = true; | ||
_this.layer1Material.needsUpdate = true; | ||
_this.layer2Material.needsUpdate = true; | ||
_this.playerObject.skin.visible = true; | ||
}; | ||
this.capeImg.crossOrigin = ""; | ||
this.capeImg.onerror = function () { | ||
return console.error("Failed loading " + _this.capeImg.src); | ||
}; | ||
this.capeImg.onload = function () { | ||
if (_this.capeImg.width !== 2 * _this.capeImg.height) { | ||
console.error("Bad cape size"); | ||
return; | ||
} | ||
_this.capeCanvas.width = _this.capeImg.width; | ||
_this.capeCanvas.height = _this.capeImg.height; | ||
var capeContext = _this.capeCanvas.getContext("2d"); | ||
capeContext.clearRect(0, 0, _this.capeCanvas.width, _this.capeCanvas.height); | ||
capeContext.drawImage(_this.capeImg, 0, 0, _this.capeCanvas.width, _this.capeCanvas.height); | ||
_this.capeTexture.needsUpdate = true; | ||
_this.capeMaterial.needsUpdate = true; | ||
_this.playerObject.cape.visible = true; | ||
}; | ||
if (options.skinUrl) this.skinUrl = options.skinUrl; | ||
if (options.capeUrl) this.capeUrl = options.capeUrl; | ||
if (options.width) this.width = options.width; | ||
if (options.height) this.height = options.height; | ||
var draw = function draw() { | ||
if (_this.disposed) return; | ||
window.requestAnimationFrame(draw); | ||
if (!_this.animationPaused) { | ||
_this.animationTime++; | ||
if (_this.animation) { | ||
invokeAnimation(_this.animation, _this.playerObject, _this.animationTime / 100.0 * _this.animationSpeed); | ||
} | ||
} | ||
_this.renderer.render(_this.scene, _this.camera); | ||
}; | ||
draw(); | ||
} | ||
createClass(SkinViewer, [{ | ||
key: "setSize", | ||
value: function setSize(width, height) { | ||
this.camera.aspect = width / height; | ||
this.camera.updateProjectionMatrix(); | ||
this.renderer.setSize(width, height); | ||
} | ||
}, { | ||
key: "dispose", | ||
value: function dispose() { | ||
this.disposed = true; | ||
this.domElement.removeChild(this.renderer.domElement); | ||
this.renderer.dispose(); | ||
this.skinTexture.dispose(); | ||
this.capeTexture.dispose(); | ||
} | ||
}, { | ||
key: "skinUrl", | ||
get: function get$$1() { | ||
return this.skinImg.src; | ||
}, | ||
set: function set$$1(url) { | ||
this.skinImg.src = url; | ||
} | ||
}, { | ||
key: "capeUrl", | ||
get: function get$$1() { | ||
return this.capeImg.src; | ||
}, | ||
set: function set$$1(url) { | ||
this.capeImg.src = url; | ||
} | ||
}, { | ||
key: "width", | ||
get: function get$$1() { | ||
return this.renderer.getSize().width; | ||
}, | ||
set: function set$$1(newWidth) { | ||
this.setSize(newWidth, this.height); | ||
} | ||
}, { | ||
key: "height", | ||
get: function get$$1() { | ||
return this.renderer.getSize().height; | ||
}, | ||
set: function set$$1(newHeight) { | ||
this.setSize(this.width, newHeight); | ||
} | ||
}]); | ||
return SkinViewer; | ||
}(); | ||
var SkinControl = function () { | ||
function SkinControl(skinViewer) { | ||
var _this2 = this; | ||
classCallCheck(this, SkinControl); | ||
this.enableAnimationControl = true; | ||
this.skinViewer = skinViewer; | ||
this.orbitControls = new OrbitControls(skinViewer.camera, skinViewer.renderer.domElement); | ||
this.orbitControls.enablePan = false; | ||
this.orbitControls.target = new THREE.Vector3(0, -12, 0); | ||
this.orbitControls.minDistance = 10; | ||
this.orbitControls.maxDistance = 256; | ||
this.orbitControls.update(); | ||
this.animationPauseListener = function (e) { | ||
if (_this2.enableAnimationControl) { | ||
e.preventDefault(); | ||
_this2.skinViewer.animationPaused = !_this2.skinViewer.animationPaused; | ||
} | ||
}; | ||
this.skinViewer.domElement.addEventListener("contextmenu", this.animationPauseListener, false); | ||
} | ||
createClass(SkinControl, [{ | ||
key: "dispose", | ||
value: function dispose() { | ||
this.skinViewer.domElement.removeEventListener("contextmenu", this.animationPauseListener, false); | ||
this.orbitControls.dispose(); | ||
} | ||
}]); | ||
return SkinControl; | ||
}(); | ||
/** | ||
* @license | ||
* skinview3d <https://github.com/to2mbn/skinview3d> | ||
* | ||
* Copyright (C) 2017 the original author or authors | ||
* | ||
* This program is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
* | ||
* | ||
* @author yushijinhun <https://github.com/yushijinhun> | ||
* @author Hacksore <https://github.com/Hacksore> | ||
* @author Kent Rasmussen <https://github.com/earthiverse> | ||
*/ | ||
exports.SkinObject = SkinObject; | ||
@@ -1256,5 +1298,9 @@ exports.CapeObject = CapeObject; | ||
exports.SkinViewer = SkinViewer; | ||
exports.SkinControl = SkinControl; | ||
exports.OrbitControls = OrbitControls; | ||
exports.createOrbitControls = createOrbitControls; | ||
exports.invokeAnimation = invokeAnimation; | ||
exports.CompositeAnimation = CompositeAnimation; | ||
exports.WalkAnimation = WalkAnimation; | ||
exports.WalkingAnimation = WalkingAnimation; | ||
exports.RunningAnimation = RunningAnimation; | ||
exports.RotatingAnimation = RotatingAnimation; | ||
@@ -1261,0 +1307,0 @@ Object.defineProperty(exports, '__esModule', { value: true }); |
@@ -1,3 +0,30 @@ | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("three")):"function"==typeof define&&define.amd?define(["exports","three"],t):t(e.skinview3d={},e.THREE)}(this,function(e,t){"use strict";var n=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},a=function(){function e(e,t){for(var n=0;n<t.length;n++){var a=t[n];a.enumerable=a.enumerable||!1,a.configurable=!0,"value"in a&&(a.writable=!0),Object.defineProperty(e,a.key,a)}}return function(t,n,a){return n&&e(t.prototype,n),a&&e(t,a),t}}(),i=function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)},o=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t};function r(e,n,a,i,o,r){return[new t.Vector2(e/o,1-i/r),new t.Vector2(a/o,1-i/r),new t.Vector2(a/o,1-n/r),new t.Vector2(e/o,1-n/r)]}function s(e,t,n,a){return r(e,t,n,a,64,64)}function c(e,t,n,a){return r(e,t,n,a,64,32)}function d(e,t,n,a,i,o,r){e.faceVertexUvs[0]=[],e.faceVertexUvs[0][0]=[o[3],o[0],o[2]],e.faceVertexUvs[0][1]=[o[0],o[1],o[2]],e.faceVertexUvs[0][2]=[a[3],a[0],a[2]],e.faceVertexUvs[0][3]=[a[0],a[1],a[2]],e.faceVertexUvs[0][4]=[t[3],t[0],t[2]],e.faceVertexUvs[0][5]=[t[0],t[1],t[2]],e.faceVertexUvs[0][6]=[n[0],n[3],n[1]],e.faceVertexUvs[0][7]=[n[3],n[2],n[1]],e.faceVertexUvs[0][8]=[i[3],i[0],i[2]],e.faceVertexUvs[0][9]=[i[0],i[1],i[2]],e.faceVertexUvs[0][10]=[r[3],r[0],r[2]],e.faceVertexUvs[0][11]=[r[0],r[1],r[2]]}var h=.002,u=function(e){function a(e,i,r){n(this,a);var c=o(this,(a.__proto__||Object.getPrototypeOf(a)).call(this));c.head=new t.Group;var u=new t.BoxGeometry(8,8,8,0,0,0);d(u,s(8,0,16,8),s(16,0,24,8),s(0,8,8,16),s(8,8,16,16),s(16,8,24,16),s(24,8,32,16));var m=new t.Mesh(u,i);c.head.add(m);var l=new t.BoxGeometry(9,9,9,0,0,0);d(l,s(40,0,48,8),s(48,0,56,8),s(32,8,40,16),s(40,8,48,16),s(48,8,56,16),s(56,8,64,16));var p=new t.Mesh(l,r);p.renderOrder=-1,c.head.add(p),c.add(c.head),c.body=new t.Group;var f=new t.BoxGeometry(8,12,4,0,0,0);d(f,s(20,16,28,20),s(28,16,36,20),s(16,20,20,32),s(20,20,28,32),s(28,20,32,32),s(32,20,40,32));var v=new t.Mesh(f,i);c.body.add(v);var g=new t.BoxGeometry(9,13.5,4.5,0,0,0);d(g,s(20,32,28,36),s(28,32,36,36),s(16,36,20,48),s(20,36,28,48),s(28,36,32,48),s(32,36,40,48));var b=new t.Mesh(g,r);c.body.add(b),c.body.position.y=-10,c.add(c.body),c.rightArm=new t.Group;var w=new t.Group,y=new t.BoxGeometry((e?3:4)-h,12-h,4-h,0,0,0);e?d(y,s(44,16,47,20),s(47,16,50,20),s(40,20,44,32),s(44,20,47,32),s(47,20,51,32),s(51,20,54,32)):d(y,s(44,16,48,20),s(48,16,52,20),s(40,20,44,32),s(44,20,48,32),s(48,20,52,32),s(52,20,56,32));var k=new t.Mesh(y,i);w.add(k);var E=new t.BoxGeometry((e?3.375:4.5)-h,13.5-h,4.5-h,0,0,0);e?d(E,s(44,32,47,36),s(47,32,50,36),s(40,36,44,48),s(44,36,47,48),s(47,36,51,48),s(51,36,54,48)):d(E,s(44,32,48,36),s(48,32,52,36),s(40,36,44,48),s(44,36,48,48),s(48,36,52,48),s(52,36,56,48));var x=new t.Mesh(E,r);x.renderOrder=1,w.add(x),w.position.y=-6,c.rightArm.add(w),c.rightArm.position.y=-4,c.rightArm.position.x=e?-5.5:-6,c.add(c.rightArm),c.leftArm=new t.Group;var O=new t.Group,M=new t.BoxGeometry((e?3:4)-h,12-h,4-h,0,0,0);e?d(M,s(36,48,39,52),s(39,48,42,52),s(32,52,36,64),s(36,52,39,64),s(39,52,43,64),s(43,52,46,64)):d(M,s(36,48,40,52),s(40,48,44,52),s(32,52,36,64),s(36,52,40,64),s(40,52,44,64),s(44,52,48,64));var C=new t.Mesh(M,i);O.add(C);var P=new t.BoxGeometry((e?3.375:4.5)-h,13.5-h,4.5-h,0,0,0);e?d(P,s(52,48,55,52),s(55,48,58,52),s(48,52,52,64),s(52,52,55,64),s(55,52,59,64),s(59,52,62,64)):d(P,s(52,48,56,52),s(56,48,60,52),s(48,52,52,64),s(52,52,56,64),s(56,52,60,64),s(60,52,64,64));var j=new t.Mesh(P,r);j.renderOrder=1,O.add(j),O.position.y=-6,c.leftArm.add(O),c.leftArm.position.y=-4,c.leftArm.position.x=e?5.5:6,c.add(c.leftArm),c.rightLeg=new t.Group;var T=new t.Group,I=new t.BoxGeometry(4-h,12-h,4-h,0,0,0);d(I,s(4,16,8,20),s(8,16,12,20),s(0,20,4,32),s(4,20,8,32),s(8,20,12,32),s(12,20,16,32));var L=new t.Mesh(I,i);T.add(L);var A=new t.BoxGeometry(4.5-h,13.5-h,4.5-h,0,0,0);d(A,s(4,32,8,36),s(8,32,12,36),s(0,36,4,48),s(4,36,8,48),s(8,36,12,48),s(12,36,16,48));var _=new t.Mesh(A,r);_.renderOrder=1,T.add(_),T.position.y=-6,c.rightLeg.add(T),c.rightLeg.position.y=-16,c.rightLeg.position.x=-2,c.add(c.rightLeg),c.leftLeg=new t.Group;var V=new t.Group,N=new t.BoxGeometry(4-h,12-h,4-h,0,0,0);d(N,s(20,48,24,52),s(24,48,28,52),s(16,52,20,64),s(20,52,24,64),s(24,52,28,64),s(28,52,32,64));var S=new t.Mesh(N,i);V.add(S);var U=new t.BoxGeometry(4.5-h,13.5-h,4.5-h,0,0,0);d(U,s(4,48,8,52),s(8,48,12,52),s(0,52,4,64),s(4,52,8,64),s(8,52,12,64),s(12,52,16,64));var z=new t.Mesh(U,r);return z.renderOrder=1,V.add(z),V.position.y=-6,c.leftLeg.add(V),c.leftLeg.position.y=-16,c.leftLeg.position.x=2,c.add(c.leftLeg),c}return i(a,e),a}(t.Group),m=function(e){function a(e){n(this,a);var i=o(this,(a.__proto__||Object.getPrototypeOf(a)).call(this)),r=new t.BoxGeometry(10,16,1,0,0,0);return d(r,c(1,0,11,1),c(11,0,21,1),c(11,1,12,17),c(12,1,22,17),c(0,1,1,17),c(1,1,11,17)),i.cape=new t.Mesh(r,e),i.cape.position.y=-8,i.cape.position.z=-.5,i.add(i.cape),i}return i(a,e),a}(t.Group),l=function(e){function t(e,a,i,r){n(this,t);var s=o(this,(t.__proto__||Object.getPrototypeOf(t)).call(this));return s.slim=e,s.skin=new u(e,a,i),s.skin.visible=!1,s.add(s.skin),s.cape=new m(r),s.cape.position.z=-2,s.cape.position.y=-4,s.cape.rotation.x=25*Math.PI/180,s.cape.visible=!1,s.add(s.cape),s}return i(t,e),t}(t.Group),p=function(e){ | ||
/** | ||
* skinview3d (https://github.com/to2mbn/skinview3d) | ||
* | ||
* MIT License | ||
* | ||
* Copyright (c) 2014-2018 Kent Rasmussen | ||
* Copyright (c) 2017-2018 Haowei Wen, Sean Boult and contributors | ||
* | ||
* Permission is hereby granted, free of charge, to any person obtaining a copy | ||
* of this software and associated documentation files (the "Software"), to deal | ||
* in the Software without restriction, including without limitation the rights | ||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
* copies of the Software, and to permit persons to whom the Software is | ||
* furnished to do so, subject to the following conditions: | ||
* | ||
* The above copyright notice and this permission notice shall be included in all | ||
* copies or substantial portions of the Software. | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
* SOFTWARE. | ||
*/ | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("three")):"function"==typeof define&&define.amd?define(["exports","three"],t):t(e.skinview3d={},e.THREE)}(this,function(e,t){"use strict";var n=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},a=function(){function e(e,t){for(var n=0;n<t.length;n++){var a=t[n];a.enumerable=a.enumerable||!1,a.configurable=!0,"value"in a&&(a.writable=!0),Object.defineProperty(e,a.key,a)}}return function(t,n,a){return n&&e(t.prototype,n),a&&e(t,a),t}}(),i=function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)},o=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t};function r(e,n,a,i,o,r){return[new t.Vector2(e/o,1-i/r),new t.Vector2(a/o,1-i/r),new t.Vector2(a/o,1-n/r),new t.Vector2(e/o,1-n/r)]}function s(e,t,n,a){return r(e,t,n,a,64,64)}function c(e,t,n,a){return r(e,t,n,a,64,32)}function h(e,t,n,a,i,o,r){e.faceVertexUvs[0]=[],e.faceVertexUvs[0][0]=[o[3],o[0],o[2]],e.faceVertexUvs[0][1]=[o[0],o[1],o[2]],e.faceVertexUvs[0][2]=[a[3],a[0],a[2]],e.faceVertexUvs[0][3]=[a[0],a[1],a[2]],e.faceVertexUvs[0][4]=[t[3],t[0],t[2]],e.faceVertexUvs[0][5]=[t[0],t[1],t[2]],e.faceVertexUvs[0][6]=[n[0],n[3],n[1]],e.faceVertexUvs[0][7]=[n[3],n[2],n[1]],e.faceVertexUvs[0][8]=[i[3],i[0],i[2]],e.faceVertexUvs[0][9]=[i[0],i[1],i[2]],e.faceVertexUvs[0][10]=[r[3],r[0],r[2]],e.faceVertexUvs[0][11]=[r[0],r[1],r[2]]}var d=.002,u=function(e){function a(e,i,r){n(this,a);var c=o(this,(a.__proto__||Object.getPrototypeOf(a)).call(this));c.slim=e,c.head=new t.Group;var u=new t.BoxGeometry(8,8,8,0,0,0);h(u,s(8,0,16,8),s(16,0,24,8),s(0,8,8,16),s(8,8,16,16),s(16,8,24,16),s(24,8,32,16));var m=new t.Mesh(u,i);c.head.add(m);var p=new t.BoxGeometry(9,9,9,0,0,0);h(p,s(40,0,48,8),s(48,0,56,8),s(32,8,40,16),s(40,8,48,16),s(48,8,56,16),s(56,8,64,16));var l=new t.Mesh(p,r);l.renderOrder=-1,c.head.add(l),c.add(c.head),c.body=new t.Group;var f=new t.BoxGeometry(8,12,4,0,0,0);h(f,s(20,16,28,20),s(28,16,36,20),s(16,20,20,32),s(20,20,28,32),s(28,20,32,32),s(32,20,40,32));var g=new t.Mesh(f,i);c.body.add(g);var v=new t.BoxGeometry(9,13.5,4.5,0,0,0);h(v,s(20,32,28,36),s(28,32,36,36),s(16,36,20,48),s(20,36,28,48),s(28,36,32,48),s(32,36,40,48));var b=new t.Mesh(v,r);c.body.add(b),c.body.position.y=-10,c.add(c.body),c.rightArm=new t.Group;var w=new t.Group,y=new t.BoxGeometry((e?3:4)-d,12-d,4-d,0,0,0);e?h(y,s(44,16,47,20),s(47,16,50,20),s(40,20,44,32),s(44,20,47,32),s(47,20,51,32),s(51,20,54,32)):h(y,s(44,16,48,20),s(48,16,52,20),s(40,20,44,32),s(44,20,48,32),s(48,20,52,32),s(52,20,56,32));var M=new t.Mesh(y,i);w.add(M);var x=new t.BoxGeometry((e?3.375:4.5)-d,13.5-d,4.5-d,0,0,0);e?h(x,s(44,32,47,36),s(47,32,50,36),s(40,36,44,48),s(44,36,47,48),s(47,36,51,48),s(51,36,54,48)):h(x,s(44,32,48,36),s(48,32,52,36),s(40,36,44,48),s(44,36,48,48),s(48,36,52,48),s(52,36,56,48));var k=new t.Mesh(x,r);k.renderOrder=1,w.add(k),w.position.y=-6,c.rightArm.add(w),c.rightArm.position.y=-4,c.rightArm.position.x=e?-5.5:-6,c.add(c.rightArm),c.leftArm=new t.Group;var E=new t.Group,O=new t.BoxGeometry((e?3:4)-d,12-d,4-d,0,0,0);e?h(O,s(36,48,39,52),s(39,48,42,52),s(32,52,36,64),s(36,52,39,64),s(39,52,43,64),s(43,52,46,64)):h(O,s(36,48,40,52),s(40,48,44,52),s(32,52,36,64),s(36,52,40,64),s(40,52,44,64),s(44,52,48,64));var I=new t.Mesh(O,i);E.add(I);var P=new t.BoxGeometry((e?3.375:4.5)-d,13.5-d,4.5-d,0,0,0);e?h(P,s(52,48,55,52),s(55,48,58,52),s(48,52,52,64),s(52,52,55,64),s(55,52,59,64),s(59,52,62,64)):h(P,s(52,48,56,52),s(56,48,60,52),s(48,52,52,64),s(52,52,56,64),s(56,52,60,64),s(60,52,64,64));var j=new t.Mesh(P,r);j.renderOrder=1,E.add(j),E.position.y=-6,c.leftArm.add(E),c.leftArm.position.y=-4,c.leftArm.position.x=e?5.5:6,c.add(c.leftArm),c.rightLeg=new t.Group;var C=new t.Group,A=new t.BoxGeometry(4-d,12-d,4-d,0,0,0);h(A,s(4,16,8,20),s(8,16,12,20),s(0,20,4,32),s(4,20,8,32),s(8,20,12,32),s(12,20,16,32));var T=new t.Mesh(A,i);C.add(T);var L=new t.BoxGeometry(4.5-d,13.5-d,4.5-d,0,0,0);h(L,s(4,32,8,36),s(8,32,12,36),s(0,36,4,48),s(4,36,8,48),s(8,36,12,48),s(12,36,16,48));var _=new t.Mesh(L,r);_.renderOrder=1,C.add(_),C.position.y=-6,c.rightLeg.add(C),c.rightLeg.position.y=-16,c.rightLeg.position.x=-2,c.add(c.rightLeg),c.leftLeg=new t.Group;var V=new t.Group,N=new t.BoxGeometry(4-d,12-d,4-d,0,0,0);h(N,s(20,48,24,52),s(24,48,28,52),s(16,52,20,64),s(20,52,24,64),s(24,52,28,64),s(28,52,32,64));var U=new t.Mesh(N,i);V.add(U);var S=new t.BoxGeometry(4.5-d,13.5-d,4.5-d,0,0,0);h(S,s(4,48,8,52),s(8,48,12,52),s(0,52,4,64),s(4,52,8,64),s(8,52,12,64),s(12,52,16,64));var z=new t.Mesh(S,r);return z.renderOrder=1,V.add(z),V.position.y=-6,c.leftLeg.add(V),c.leftLeg.position.y=-16,c.leftLeg.position.x=2,c.add(c.leftLeg),c}return i(a,e),a}(t.Group),m=function(e){function a(e){n(this,a);var i=o(this,(a.__proto__||Object.getPrototypeOf(a)).call(this)),r=new t.BoxGeometry(10,16,1,0,0,0);return h(r,c(1,0,11,1),c(11,0,21,1),c(11,1,12,17),c(12,1,22,17),c(0,1,1,17),c(1,1,11,17)),i.cape=new t.Mesh(r,e),i.cape.position.y=-8,i.cape.position.z=-.5,i.add(i.cape),i}return i(a,e),a}(t.Group),p=function(e){function t(e,a,i,r){n(this,t);var s=o(this,(t.__proto__||Object.getPrototypeOf(t)).call(this));return s.skin=new u(e,a,i),s.skin.visible=!1,s.add(s.skin),s.cape=new m(r),s.cape.position.z=-2,s.cape.position.y=-4,s.cape.rotation.x=25*Math.PI/180,s.cape.visible=!1,s.add(s.cape),s}return i(t,e),t}(t.Group);function l(e,t,n){if(e instanceof g)e.play(t,n);else{if(!(e instanceof Function))throw"Not an animation: "+e;e(t,n)}}var f=function(){function e(t){n(this,e),this.animation=t,this.paused=this._paused=!1,this.speed=this._speed=1,this._lastChange=null,this._lastChangeX=null}return a(e,[{key:"play",value:function(e,t){if(null===this._lastChange)this._lastChange=t,this._lastChangeX=0;else if(this.paused!==this._paused||this.speed!==this._speed){var n=t-this._lastChange;!1===this._paused&&(this._lastChangeX+=n*this._speed),this._paused=this.paused,this._speed=this.speed,this._lastChange=t}if(!1===this.paused){var a=t-this._lastChange,i=this._lastChangeX+this.speed*a;l(this.animation,e,i)}}},{key:"reset",value:function(){this._lastChange=null}}]),e}(),g=function(){function e(){n(this,e),this.handles=new Set}return a(e,[{key:"add",value:function(e){var t=this,n=new f(e);return n.remove=function(){return t.handles.delete(n)},this.handles.add(n),n}},{key:"play",value:function(e,t){this.handles.forEach(function(n){return n.play(e,t)})}}]),e}();var v=function(){function e(a){var i=this;n(this,e),this.domElement=a.domElement,this.animation=a.animation||null,this.animationPaused=!1,this.animationTime=0,this.disposed=!1,this.skinImg=new Image,this.skinCanvas=document.createElement("canvas"),this.skinTexture=new t.Texture(this.skinCanvas),this.skinTexture.magFilter=t.NearestFilter,this.skinTexture.minFilter=t.NearestMipMapNearestFilter,this.capeImg=new Image,this.capeCanvas=document.createElement("canvas"),this.capeTexture=new t.Texture(this.capeCanvas),this.capeTexture.magFilter=t.NearestFilter,this.capeTexture.minFilter=t.NearestMipMapNearestFilter,this.layer1Material=new t.MeshBasicMaterial({map:this.skinTexture,side:t.FrontSide}),this.layer2Material=new t.MeshBasicMaterial({map:this.skinTexture,transparent:!0,opacity:1,side:t.DoubleSide}),this.capeMaterial=new t.MeshBasicMaterial({map:this.capeTexture}),this.scene=new t.Scene,this.camera=new t.PerspectiveCamera(40),this.camera.position.y=-12,this.camera.position.z=60,this.renderer=new t.WebGLRenderer({angleRot:!0,alpha:!0,antialias:!1}),this.renderer.setSize(300,300),this.renderer.context.getShaderInfoLog=function(){return""},this.domElement.appendChild(this.renderer.domElement),this.playerObject=new p(!0===a.slim,this.layer1Material,this.layer2Material,this.capeMaterial),this.scene.add(this.playerObject),this.skinImg.crossOrigin="",this.skinImg.onerror=function(){return console.error("Failed loading "+i.skinImg.src)},this.skinImg.onload=function(){var e=!1;if(i.skinImg.width!==i.skinImg.height){if(i.skinImg.width!==2*i.skinImg.height)return void console.error("Bad skin size");e=!0}var t=i.skinCanvas.getContext("2d");if(e){var n=i.skinImg.width;i.skinCanvas.width=n,i.skinCanvas.height=n,t.clearRect(0,0,n,n),t.drawImage(i.skinImg,0,0,n,n/2),function(e,t){var n=t/64,a=function(e,t,a,i,o,r,s,c){return function(e,t,n,a,i,o,r,s){var c=e.getImageData(t,n,a,i);if(s)for(var h=0;h<i;h++)for(var d=0;d<a/2;d++){var u=4*(d+h*a),m=4*(a-d-1+h*a),p=c.data[u],l=c.data[u+1],f=c.data[u+2],g=c.data[u+3],v=c.data[m],b=c.data[m+1],w=c.data[m+2],y=c.data[m+3];c.data[u]=v,c.data[u+1]=b,c.data[u+2]=w,c.data[u+3]=y,c.data[m]=p,c.data[m+1]=l,c.data[m+2]=f,c.data[m+3]=g}e.putImageData(c,o,r)}(e,t*n,a*n,i*n,o*n,r*n,s*n,c)};a(e,4,16,4,4,20,48,!0),a(e,8,16,4,4,24,48,!0),a(e,0,20,4,12,24,52,!0),a(e,4,20,4,12,20,52,!0),a(e,8,20,4,12,16,52,!0),a(e,12,20,4,12,28,52,!0),a(e,44,16,4,4,36,48,!0),a(e,48,16,4,4,40,48,!0),a(e,40,20,4,12,40,52,!0),a(e,44,20,4,12,36,52,!0),a(e,48,20,4,12,32,52,!0),a(e,52,20,4,12,44,52,!0)}(t,n)}else i.skinCanvas.width=i.skinImg.width,i.skinCanvas.height=i.skinImg.height,t.clearRect(0,0,i.skinCanvas.width,i.skinCanvas.height),t.drawImage(i.skinImg,0,0,i.skinCanvas.width,i.skinCanvas.height);i.skinTexture.needsUpdate=!0,i.layer1Material.needsUpdate=!0,i.layer2Material.needsUpdate=!0,i.playerObject.skin.visible=!0},this.capeImg.crossOrigin="",this.capeImg.onerror=function(){return console.error("Failed loading "+i.capeImg.src)},this.capeImg.onload=function(){var e=!1;if(i.capeImg.width!==2*i.capeImg.height){if(17*i.capeImg.width!=22*i.capeImg.height)return void console.error("Bad cape size");e=!0}var t=i.capeCanvas.getContext("2d");if(e){var n=64*i.capeImg.width/22;i.capeCanvas.width=n,i.capeCanvas.height=n/2}else i.capeCanvas.width=i.capeImg.width,i.capeCanvas.height=i.capeImg.height;t.clearRect(0,0,i.capeCanvas.width,i.capeCanvas.height),t.drawImage(i.capeImg,0,0,i.capeImg.width,i.capeImg.height),i.capeTexture.needsUpdate=!0,i.capeMaterial.needsUpdate=!0,i.playerObject.cape.visible=!0},a.skinUrl&&(this.skinUrl=a.skinUrl),a.capeUrl&&(this.capeUrl=a.capeUrl),a.width&&(this.width=a.width),a.height&&(this.height=a.height);!function e(){i.disposed||(window.requestAnimationFrame(e),i.animationPaused||(i.animationTime++,i.animation&&l(i.animation,i.playerObject,i.animationTime/100)),i.renderer.render(i.scene,i.camera))}()}return a(e,[{key:"setSize",value:function(e,t){this.camera.aspect=e/t,this.camera.updateProjectionMatrix(),this.renderer.setSize(e,t)}},{key:"dispose",value:function(){this.disposed=!0,this.domElement.removeChild(this.renderer.domElement),this.renderer.dispose(),this.skinTexture.dispose(),this.capeTexture.dispose()}},{key:"skinUrl",get:function(){return this.skinImg.src},set:function(e){this.skinImg.src=e}},{key:"capeUrl",get:function(){return this.capeImg.src},set:function(e){this.capeImg.src=e}},{key:"width",get:function(){return this.renderer.getSize().width},set:function(e){this.setSize(e,this.height)}},{key:"height",get:function(){return this.renderer.getSize().height},set:function(e){this.setSize(this.width,e)}}]),e}(),b=function(e){ | ||
/** | ||
* @preserve | ||
@@ -35,28 +62,3 @@ * The code was originally from https://github.com/mrdoob/three.js/blob/d45a042cf962e9b1aa9441810ba118647b48aacb/examples/js/controls/OrbitControls.js | ||
*/ | ||
function a(e,i){n(this,a);var r,s,c,d,h,u=o(this,(a.__proto__||Object.getPrototypeOf(a)).call(this));u.object=e,u.domElement=void 0!==i?i:document,u.enabled=!0,u.target=new t.Vector3,u.minDistance=0,u.maxDistance=1/0,u.minZoom=0,u.maxZoom=1/0,u.minPolarAngle=0,u.maxPolarAngle=Math.PI,u.minAzimuthAngle=-1/0,u.maxAzimuthAngle=1/0,u.enableDamping=!1,u.dampingFactor=.25,u.enableZoom=!0,u.zoomSpeed=1,u.enableRotate=!0,u.rotateSpeed=1,u.enablePan=!0,u.keyPanSpeed=7,u.autoRotate=!1,u.autoRotateSpeed=2,u.enableKeys=!0,u.keys={LEFT:37,UP:38,RIGHT:39,BOTTOM:40},u.mouseButtons={ORBIT:t.MOUSE.LEFT,ZOOM:t.MOUSE.MIDDLE,PAN:t.MOUSE.RIGHT},u.target0=u.target.clone(),u.position0=u.object.position.clone(),u.zoom0=u.object.zoom,u.getPolarAngle=function(){return w.phi},u.getAzimuthalAngle=function(){return w.theta},u.saveState=function(){m.target0.copy(m.target),m.position0.copy(m.object.position),m.zoom0=m.object.zoom},u.reset=function(){m.target.copy(m.target0),m.object.position.copy(m.position0),m.object.zoom=m.zoom0,m.object.updateProjectionMatrix(),m.dispatchEvent(l),m.update(),g=v.NONE},u.update=(r=new t.Vector3,s=(new t.Quaternion).setFromUnitVectors(e.up,new t.Vector3(0,1,0)),c=s.clone().inverse(),d=new t.Vector3,h=new t.Quaternion,function(){var e=m.object.position;return r.copy(e).sub(m.target),r.applyQuaternion(s),w.setFromVector3(r),m.autoRotate&&g===v.NONE&&V(2*Math.PI/60/60*m.autoRotateSpeed),w.theta+=y.theta,w.phi+=y.phi,w.theta=Math.max(m.minAzimuthAngle,Math.min(m.maxAzimuthAngle,w.theta)),w.phi=Math.max(m.minPolarAngle,Math.min(m.maxPolarAngle,w.phi)),w.makeSafe(),w.radius*=k,w.radius=Math.max(m.minDistance,Math.min(m.maxDistance,w.radius)),m.target.add(E),r.setFromSpherical(w),r.applyQuaternion(c),e.copy(m.target).add(r),m.object.lookAt(m.target),!0===m.enableDamping?(y.theta*=1-m.dampingFactor,y.phi*=1-m.dampingFactor):y.set(0,0,0),k=1,E.set(0,0,0),!!(x||d.distanceToSquared(m.object.position)>b||8*(1-h.dot(m.object.quaternion))>b)&&(m.dispatchEvent(l),d.copy(m.object.position),h.copy(m.object.quaternion),x=!1,!0)}),u.dispose=function(){m.domElement.removeEventListener("contextmenu",J,!1),m.domElement.removeEventListener("mousedown",Y,!1),m.domElement.removeEventListener("wheel",Z,!1),m.domElement.removeEventListener("touchstart",q,!1),m.domElement.removeEventListener("touchend",K,!1),m.domElement.removeEventListener("touchmove",Q,!1),document.removeEventListener("mousemove",H,!1),document.removeEventListener("mouseup",X,!1),window.removeEventListener("keydown",W,!1)};var m=u,l={type:"change"},p={type:"start"},f={type:"end"},v={NONE:-1,ROTATE:0,DOLLY:1,PAN:2,TOUCH_ROTATE:3,TOUCH_DOLLY:4,TOUCH_PAN:5},g=v.NONE,b=1e-6,w=new t.Spherical,y=new t.Spherical,k=1,E=new t.Vector3,x=!1,O=new t.Vector2,M=new t.Vector2,C=new t.Vector2,P=new t.Vector2,j=new t.Vector2,T=new t.Vector2,I=new t.Vector2,L=new t.Vector2,A=new t.Vector2;function _(){return Math.pow(.95,m.zoomSpeed)}function V(e){y.theta-=e}function N(e){y.phi-=e}var S,U,z,G=(S=new t.Vector3,function(e,t){S.setFromMatrixColumn(t,0),S.multiplyScalar(-e),E.add(S)}),R=(U=new t.Vector3,function(e,t){U.setFromMatrixColumn(t,1),U.multiplyScalar(e),E.add(U)}),B=(z=new t.Vector3,function(e,n){var a=m.domElement===document?m.domElement.body:m.domElement;if(m.object instanceof t.PerspectiveCamera){var i=m.object.position;z.copy(i).sub(m.target);var o=z.length();o*=Math.tan(m.object.fov/2*Math.PI/180),G(2*e*o/a.clientHeight,m.object.matrix),R(2*n*o/a.clientHeight,m.object.matrix)}else m.object instanceof t.OrthographicCamera?(G(e*(m.object.right-m.object.left)/m.object.zoom/a.clientWidth,m.object.matrix),R(n*(m.object.top-m.object.bottom)/m.object.zoom/a.clientHeight,m.object.matrix)):(console.warn("WARNING: OrbitControls.js encountered an unknown camera type - pan disabled."),m.enablePan=!1)});function D(e){m.object instanceof t.PerspectiveCamera?k/=e:m.object instanceof t.OrthographicCamera?(m.object.zoom=Math.max(m.minZoom,Math.min(m.maxZoom,m.object.zoom*e)),m.object.updateProjectionMatrix(),x=!0):(console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."),m.enableZoom=!1)}function F(e){m.object instanceof t.PerspectiveCamera?k*=e:m.object instanceof t.OrthographicCamera?(m.object.zoom=Math.max(m.minZoom,Math.min(m.maxZoom,m.object.zoom/e)),m.object.updateProjectionMatrix(),x=!0):(console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."),m.enableZoom=!1)}function Y(e){if(!1!==m.enabled){switch(e.button){case m.mouseButtons.ORBIT:if(!1===m.enableRotate)return;a=e,O.set(a.clientX,a.clientY),g=v.ROTATE;break;case m.mouseButtons.ZOOM:if(!1===m.enableZoom)return;n=e,I.set(n.clientX,n.clientY),g=v.DOLLY;break;case m.mouseButtons.PAN:if(!1===m.enablePan)return;t=e,P.set(t.clientX,t.clientY),g=v.PAN}var t,n,a;e.preventDefault(),g!==v.NONE&&(document.addEventListener("mousemove",H,!1),document.addEventListener("mouseup",X,!1),m.dispatchEvent(p))}}function H(e){if(!1!==m.enabled){switch(g){case v.ROTATE:if(!1===m.enableRotate)return;!function(e){M.set(e.clientX,e.clientY),C.subVectors(M,O);var t=m.domElement===document?m.domElement.body:m.domElement;V(2*Math.PI*C.x/t.clientWidth*m.rotateSpeed),N(2*Math.PI*C.y/t.clientHeight*m.rotateSpeed),O.copy(M),m.update()}(e);break;case v.DOLLY:if(!1===m.enableZoom)return;n=e,L.set(n.clientX,n.clientY),A.subVectors(L,I),A.y>0?D(_()):A.y<0&&F(_()),I.copy(L),m.update();break;case v.PAN:if(!1===m.enablePan)return;t=e,j.set(t.clientX,t.clientY),T.subVectors(j,P),B(T.x,T.y),P.copy(j),m.update()}var t,n;e.preventDefault()}}function X(e){!1!==m.enabled&&(document.removeEventListener("mousemove",H,!1),document.removeEventListener("mouseup",X,!1),m.dispatchEvent(f),g=v.NONE)}function Z(e){var t;!1===m.enabled||!1===m.enableZoom||g!==v.NONE&&g!==v.ROTATE||(e.preventDefault(),e.stopPropagation(),(t=e).deltaY<0?F(_()):t.deltaY>0&&D(_()),m.update(),m.dispatchEvent(p),m.dispatchEvent(f))}function W(e){!1!==m.enabled&&!1!==m.enableKeys&&!1!==m.enablePan&&function(e){switch(e.keyCode){case m.keys.UP:B(0,m.keyPanSpeed),m.update();break;case m.keys.BOTTOM:B(0,-m.keyPanSpeed),m.update();break;case m.keys.LEFT:B(m.keyPanSpeed,0),m.update();break;case m.keys.RIGHT:B(-m.keyPanSpeed,0),m.update()}}(e)}function q(e){if(!1!==m.enabled){switch(e.touches.length){case 1:if(!1===m.enableRotate)return;r=e,O.set(r.touches[0].pageX,r.touches[0].pageY),g=v.TOUCH_ROTATE;break;case 2:if(!1===m.enableZoom)return;a=(n=e).touches[0].pageX-n.touches[1].pageX,i=n.touches[0].pageY-n.touches[1].pageY,o=Math.sqrt(a*a+i*i),I.set(0,o),g=v.TOUCH_DOLLY;break;case 3:if(!1===m.enablePan)return;t=e,P.set(t.touches[0].pageX,t.touches[0].pageY),g=v.TOUCH_PAN;break;default:g=v.NONE}var t,n,a,i,o,r;g!==v.NONE&&m.dispatchEvent(p)}}function Q(e){if(!1!==m.enabled){switch(e.touches.length){case 1:if(!1===m.enableRotate)return;if(g!==v.TOUCH_ROTATE)return;!function(e){M.set(e.touches[0].pageX,e.touches[0].pageY),C.subVectors(M,O);var t=m.domElement===document?m.domElement.body:m.domElement;V(2*Math.PI*C.x/t.clientWidth*m.rotateSpeed),N(2*Math.PI*C.y/t.clientHeight*m.rotateSpeed),O.copy(M),m.update()}(e);break;case 2:if(!1===m.enableZoom)return;if(g!==v.TOUCH_DOLLY)return;a=(n=e).touches[0].pageX-n.touches[1].pageX,i=n.touches[0].pageY-n.touches[1].pageY,o=Math.sqrt(a*a+i*i),L.set(0,o),A.subVectors(L,I),A.y>0?F(_()):A.y<0&&D(_()),I.copy(L),m.update();break;case 3:if(!1===m.enablePan)return;if(g!==v.TOUCH_PAN)return;t=e,j.set(t.touches[0].pageX,t.touches[0].pageY),T.subVectors(j,P),B(T.x,T.y),P.copy(j),m.update();break;default:g=v.NONE}var t,n,a,i,o;e.preventDefault(),e.stopPropagation()}}function K(e){!1!==m.enabled&&(m.dispatchEvent(f),g=v.NONE)}function J(e){!1!==m.enabled&&!1!==m.enablePan&&e.preventDefault()}return m.domElement.addEventListener("contextmenu",J,!1),m.domElement.addEventListener("mousedown",Y,!1),m.domElement.addEventListener("wheel",Z,!1),m.domElement.addEventListener("touchstart",q,!1),m.domElement.addEventListener("touchend",K,!1),m.domElement.addEventListener("touchmove",Q,!1),window.addEventListener("keydown",W,!1),u.update(),u}return i(a,e),a}(t.EventDispatcher);function f(e,t,n){if(e instanceof g)e.play(t,n);else{if(!(e instanceof Function))throw"Not an animation: "+e;e(t,n)}}var v=function(){function e(t){n(this,e),this.animation=t,this.paused=this._paused=!1,this.speed=this._speed=1,this._lastChange=null,this._lastChangeX=null}return a(e,[{key:"play",value:function(e,t){if(null===this._lastChange)this._lastChange=t,this._lastChangeX=0;else if(this.paused!==this._paused||this.speed!==this._speed){var n=t-this._lastChange;!1===this._paused&&(this._lastChangeX+=n*this._speed),this._paused=this.paused,this._speed=this.speed,this._lastChange=t}if(!1===this.paused){var a=t-this._lastChange,i=this._lastChangeX+this.speed*a;f(this.animation,e,i)}}},{key:"reset",value:function(){this._lastChange=null}}]),e}(),g=function(){function e(){n(this,e),this.handles=new Set}return a(e,[{key:"add",value:function(e){var t=this,n=new v(e);return n.remove=function(){return t.handles.delete(n)},this.handles.add(n),n}},{key:"play",value:function(e,t){this.handles.forEach(function(n){return n.play(e,t)})}}]),e}();var b=function(){function e(a){var i=this;n(this,e),this.domElement=a.domElement,this.animation=a.animation||null,this.animationPaused=!1,this.animationSpeed=3,this.animationTime=0,this.disposed=!1,this.skinImg=new Image,this.skinCanvas=document.createElement("canvas"),this.skinTexture=new t.Texture(this.skinCanvas),this.skinTexture.magFilter=t.NearestFilter,this.skinTexture.minFilter=t.NearestMipMapNearestFilter,this.capeImg=new Image,this.capeCanvas=document.createElement("canvas"),this.capeTexture=new t.Texture(this.capeCanvas),this.capeTexture.magFilter=t.NearestFilter,this.capeTexture.minFilter=t.NearestMipMapNearestFilter,this.layer1Material=new t.MeshBasicMaterial({map:this.skinTexture,side:t.FrontSide}),this.layer2Material=new t.MeshBasicMaterial({map:this.skinTexture,transparent:!0,opacity:1,side:t.DoubleSide}),this.capeMaterial=new t.MeshBasicMaterial({map:this.capeTexture}),this.scene=new t.Scene,this.camera=new t.PerspectiveCamera(75),this.camera.position.y=-12,this.camera.position.z=30,this.renderer=new t.WebGLRenderer({angleRot:!0,alpha:!0,antialias:!1}),this.renderer.setSize(300,300),this.renderer.context.getShaderInfoLog=function(){return""},this.domElement.appendChild(this.renderer.domElement),this.playerObject=new l(!0===a.slim,this.layer1Material,this.layer2Material,this.capeMaterial),this.scene.add(this.playerObject),this.skinImg.crossOrigin="",this.skinImg.onerror=function(){return console.error("Failed loading "+i.skinImg.src)},this.skinImg.onload=function(){var e=!1;if(i.skinImg.width!==i.skinImg.height){if(i.skinImg.width!==2*i.skinImg.height)return void console.error("Bad skin size");e=!0}var t,n,a,o=i.skinCanvas.getContext("2d");if(e){var r=i.skinImg.width;i.skinCanvas.width=r,i.skinCanvas.height=r,o.clearRect(0,0,r,r),o.drawImage(i.skinImg,0,0,r,r/2),n=r/64,(a=function(e,t,a,i,o,r,s,c){return function(e,t,n,a,i,o,r,s){var c=e.getImageData(t,n,a,i);if(s)for(var d=0;d<i;d++)for(var h=0;h<a/2;h++){var u=4*(h+d*a),m=4*(a-h-1+d*a),l=c.data[u],p=c.data[u+1],f=c.data[u+2],v=c.data[u+3],g=c.data[m],b=c.data[m+1],w=c.data[m+2],y=c.data[m+3];c.data[u]=g,c.data[u+1]=b,c.data[u+2]=w,c.data[u+3]=y,c.data[m]=l,c.data[m+1]=p,c.data[m+2]=f,c.data[m+3]=v}e.putImageData(c,o,r)}(e,t*n,a*n,i*n,o*n,r*n,s*n,c)})(t=o,4,16,4,4,20,48,!0),a(t,8,16,4,4,24,48,!0),a(t,0,20,4,12,24,52,!0),a(t,4,20,4,12,20,52,!0),a(t,8,20,4,12,16,52,!0),a(t,12,20,4,12,28,52,!0),a(t,44,16,4,4,36,48,!0),a(t,48,16,4,4,40,48,!0),a(t,40,20,4,12,40,52,!0),a(t,44,20,4,12,36,52,!0),a(t,48,20,4,12,32,52,!0),a(t,52,20,4,12,44,52,!0)}else i.skinCanvas.width=i.skinImg.width,i.skinCanvas.height=i.skinImg.height,o.clearRect(0,0,i.skinCanvas.width,i.skinCanvas.height),o.drawImage(i.skinImg,0,0,i.skinCanvas.width,i.skinCanvas.height);i.skinTexture.needsUpdate=!0,i.layer1Material.needsUpdate=!0,i.layer2Material.needsUpdate=!0,i.playerObject.skin.visible=!0},this.capeImg.crossOrigin="",this.capeImg.onerror=function(){return console.error("Failed loading "+i.capeImg.src)},this.capeImg.onload=function(){if(i.capeImg.width===2*i.capeImg.height){i.capeCanvas.width=i.capeImg.width,i.capeCanvas.height=i.capeImg.height;var e=i.capeCanvas.getContext("2d");e.clearRect(0,0,i.capeCanvas.width,i.capeCanvas.height),e.drawImage(i.capeImg,0,0,i.capeCanvas.width,i.capeCanvas.height),i.capeTexture.needsUpdate=!0,i.capeMaterial.needsUpdate=!0,i.playerObject.cape.visible=!0}else console.error("Bad cape size")},a.skinUrl&&(this.skinUrl=a.skinUrl),a.capeUrl&&(this.capeUrl=a.capeUrl),a.width&&(this.width=a.width),a.height&&(this.height=a.height);!function e(){i.disposed||(window.requestAnimationFrame(e),i.animationPaused||(i.animationTime++,i.animation&&f(i.animation,i.playerObject,i.animationTime/100*i.animationSpeed)),i.renderer.render(i.scene,i.camera))}()}return a(e,[{key:"setSize",value:function(e,t){this.camera.aspect=e/t,this.camera.updateProjectionMatrix(),this.renderer.setSize(e,t)}},{key:"dispose",value:function(){this.disposed=!0,this.domElement.removeChild(this.renderer.domElement),this.renderer.dispose(),this.skinTexture.dispose(),this.capeTexture.dispose()}},{key:"skinUrl",get:function(){return this.skinImg.src},set:function(e){this.skinImg.src=e}},{key:"capeUrl",get:function(){return this.capeImg.src},set:function(e){this.capeImg.src=e}},{key:"width",get:function(){return this.renderer.getSize().width},set:function(e){this.setSize(e,this.height)}},{key:"height",get:function(){return this.renderer.getSize().height},set:function(e){this.setSize(this.width,e)}}]),e}(),w=function(){function e(a){var i=this;n(this,e),this.enableAnimationControl=!0,this.skinViewer=a,this.orbitControls=new p(a.camera,a.renderer.domElement),this.orbitControls.enablePan=!1,this.orbitControls.target=new t.Vector3(0,-12,0),this.orbitControls.minDistance=10,this.orbitControls.maxDistance=256,this.orbitControls.update(),this.animationPauseListener=function(e){i.enableAnimationControl&&(e.preventDefault(),i.skinViewer.animationPaused=!i.skinViewer.animationPaused)},this.skinViewer.domElement.addEventListener("contextmenu",this.animationPauseListener,!1)}return a(e,[{key:"dispose",value:function(){this.skinViewer.domElement.removeEventListener("contextmenu",this.animationPauseListener,!1),this.orbitControls.dispose()}}]),e}(); | ||
/** | ||
* @license | ||
* skinview3d <https://github.com/to2mbn/skinview3d> | ||
* | ||
* Copyright (C) 2017 the original author or authors | ||
* | ||
* This program is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
* | ||
* | ||
* @author yushijinhun <https://github.com/yushijinhun> | ||
* @author Hacksore <https://github.com/Hacksore> | ||
* @author Kent Rasmussen <https://github.com/earthiverse> | ||
*/ | ||
e.SkinObject=u,e.CapeObject=m,e.PlayerObject=l,e.SkinViewer=b,e.SkinControl=w,e.CompositeAnimation=g,e.WalkAnimation=function(e,t){var n=e.skin,a=t+Math.PI/2;n.leftLeg.rotation.x=Math.cos(a),n.rightLeg.rotation.x=Math.cos(a+Math.PI),n.leftArm.rotation.x=Math.cos(a+Math.PI),n.rightArm.rotation.x=Math.cos(a)},Object.defineProperty(e,"__esModule",{value:!0})}); | ||
function a(e,i){n(this,a);var r,s,c,h,d,u=o(this,(a.__proto__||Object.getPrototypeOf(a)).call(this));u.object=e,u.domElement=void 0!==i?i:document,u.enabled=!0,u.target=new t.Vector3,u.minDistance=0,u.maxDistance=1/0,u.minZoom=0,u.maxZoom=1/0,u.minPolarAngle=0,u.maxPolarAngle=Math.PI,u.minAzimuthAngle=-1/0,u.maxAzimuthAngle=1/0,u.enableDamping=!1,u.dampingFactor=.25,u.enableZoom=!0,u.zoomSpeed=1,u.enableRotate=!0,u.rotateSpeed=1,u.enablePan=!0,u.keyPanSpeed=7,u.autoRotate=!1,u.autoRotateSpeed=2,u.enableKeys=!0,u.keys={LEFT:37,UP:38,RIGHT:39,BOTTOM:40},u.mouseButtons={ORBIT:t.MOUSE.LEFT,ZOOM:t.MOUSE.MIDDLE,PAN:t.MOUSE.RIGHT},u.target0=u.target.clone(),u.position0=u.object.position.clone(),u.zoom0=u.object.zoom,u.getPolarAngle=function(){return w.phi},u.getAzimuthalAngle=function(){return w.theta},u.saveState=function(){m.target0.copy(m.target),m.position0.copy(m.object.position),m.zoom0=m.object.zoom},u.reset=function(){m.target.copy(m.target0),m.object.position.copy(m.position0),m.object.zoom=m.zoom0,m.object.updateProjectionMatrix(),m.dispatchEvent(p),m.update(),v=g.NONE},u.update=(r=new t.Vector3,s=(new t.Quaternion).setFromUnitVectors(e.up,new t.Vector3(0,1,0)),c=s.clone().inverse(),h=new t.Vector3,d=new t.Quaternion,function(){var e=m.object.position;return r.copy(e).sub(m.target),r.applyQuaternion(s),w.setFromVector3(r),m.autoRotate&&v===g.NONE&&V(2*Math.PI/60/60*m.autoRotateSpeed),w.theta+=y.theta,w.phi+=y.phi,w.theta=Math.max(m.minAzimuthAngle,Math.min(m.maxAzimuthAngle,w.theta)),w.phi=Math.max(m.minPolarAngle,Math.min(m.maxPolarAngle,w.phi)),w.makeSafe(),w.radius*=M,w.radius=Math.max(m.minDistance,Math.min(m.maxDistance,w.radius)),m.target.add(x),r.setFromSpherical(w),r.applyQuaternion(c),e.copy(m.target).add(r),m.object.lookAt(m.target),!0===m.enableDamping?(y.theta*=1-m.dampingFactor,y.phi*=1-m.dampingFactor):y.set(0,0,0),M=1,x.set(0,0,0),!!(k||h.distanceToSquared(m.object.position)>b||8*(1-d.dot(m.object.quaternion))>b)&&(m.dispatchEvent(p),h.copy(m.object.position),d.copy(m.object.quaternion),k=!1,!0)}),u.dispose=function(){m.domElement.removeEventListener("contextmenu",Q,!1),m.domElement.removeEventListener("mousedown",D,!1),m.domElement.removeEventListener("wheel",H,!1),m.domElement.removeEventListener("touchstart",Z,!1),m.domElement.removeEventListener("touchend",q,!1),m.domElement.removeEventListener("touchmove",W,!1),document.removeEventListener("mousemove",F,!1),document.removeEventListener("mouseup",Y,!1),window.removeEventListener("keydown",X,!1)};var m=u,p={type:"change"},l={type:"start"},f={type:"end"},g={NONE:-1,ROTATE:0,DOLLY:1,PAN:2,TOUCH_ROTATE:3,TOUCH_DOLLY:4,TOUCH_PAN:5},v=g.NONE,b=1e-6,w=new t.Spherical,y=new t.Spherical,M=1,x=new t.Vector3,k=!1,E=new t.Vector2,O=new t.Vector2,I=new t.Vector2,P=new t.Vector2,j=new t.Vector2,C=new t.Vector2,A=new t.Vector2,T=new t.Vector2,L=new t.Vector2;function _(){return Math.pow(.95,m.zoomSpeed)}function V(e){y.theta-=e}function N(e){y.phi-=e}var U,S=(U=new t.Vector3,function(e,t){U.setFromMatrixColumn(t,0),U.multiplyScalar(-e),x.add(U)}),z=function(){var e=new t.Vector3;return function(t,n){e.setFromMatrixColumn(n,1),e.multiplyScalar(t),x.add(e)}}(),G=function(){var e=new t.Vector3;return function(n,a){var i=m.domElement===document?m.domElement.body:m.domElement;if(m.object instanceof t.PerspectiveCamera){var o=m.object.position;e.copy(o).sub(m.target);var r=e.length();r*=Math.tan(m.object.fov/2*Math.PI/180),S(2*n*r/i.clientHeight,m.object.matrix),z(2*a*r/i.clientHeight,m.object.matrix)}else m.object instanceof t.OrthographicCamera?(S(n*(m.object.right-m.object.left)/m.object.zoom/i.clientWidth,m.object.matrix),z(a*(m.object.top-m.object.bottom)/m.object.zoom/i.clientHeight,m.object.matrix)):(console.warn("WARNING: OrbitControls.js encountered an unknown camera type - pan disabled."),m.enablePan=!1)}}();function R(e){m.object instanceof t.PerspectiveCamera?M/=e:m.object instanceof t.OrthographicCamera?(m.object.zoom=Math.max(m.minZoom,Math.min(m.maxZoom,m.object.zoom*e)),m.object.updateProjectionMatrix(),k=!0):(console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."),m.enableZoom=!1)}function B(e){m.object instanceof t.PerspectiveCamera?M*=e:m.object instanceof t.OrthographicCamera?(m.object.zoom=Math.max(m.minZoom,Math.min(m.maxZoom,m.object.zoom/e)),m.object.updateProjectionMatrix(),k=!0):(console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."),m.enableZoom=!1)}function D(e){if(!1!==m.enabled){switch(e.button){case m.mouseButtons.ORBIT:if(!1===m.enableRotate)return;!function(e){E.set(e.clientX,e.clientY)}(e),v=g.ROTATE;break;case m.mouseButtons.ZOOM:if(!1===m.enableZoom)return;!function(e){A.set(e.clientX,e.clientY)}(e),v=g.DOLLY;break;case m.mouseButtons.PAN:if(!1===m.enablePan)return;!function(e){P.set(e.clientX,e.clientY)}(e),v=g.PAN}e.preventDefault(),v!==g.NONE&&(document.addEventListener("mousemove",F,!1),document.addEventListener("mouseup",Y,!1),m.dispatchEvent(l))}}function F(e){if(!1!==m.enabled){switch(v){case g.ROTATE:if(!1===m.enableRotate)return;!function(e){O.set(e.clientX,e.clientY),I.subVectors(O,E);var t=m.domElement===document?m.domElement.body:m.domElement;V(2*Math.PI*I.x/t.clientWidth*m.rotateSpeed),N(2*Math.PI*I.y/t.clientHeight*m.rotateSpeed),E.copy(O),m.update()}(e);break;case g.DOLLY:if(!1===m.enableZoom)return;!function(e){T.set(e.clientX,e.clientY),L.subVectors(T,A),L.y>0?R(_()):L.y<0&&B(_()),A.copy(T),m.update()}(e);break;case g.PAN:if(!1===m.enablePan)return;!function(e){j.set(e.clientX,e.clientY),C.subVectors(j,P),G(C.x,C.y),P.copy(j),m.update()}(e)}e.preventDefault()}}function Y(e){!1!==m.enabled&&(document.removeEventListener("mousemove",F,!1),document.removeEventListener("mouseup",Y,!1),m.dispatchEvent(f),v=g.NONE)}function H(e){!1===m.enabled||!1===m.enableZoom||v!==g.NONE&&v!==g.ROTATE||(e.preventDefault(),e.stopPropagation(),function(e){e.deltaY<0?B(_()):e.deltaY>0&&R(_()),m.update()}(e),m.dispatchEvent(l),m.dispatchEvent(f))}function X(e){!1!==m.enabled&&!1!==m.enableKeys&&!1!==m.enablePan&&function(e){switch(e.keyCode){case m.keys.UP:G(0,m.keyPanSpeed),m.update();break;case m.keys.BOTTOM:G(0,-m.keyPanSpeed),m.update();break;case m.keys.LEFT:G(m.keyPanSpeed,0),m.update();break;case m.keys.RIGHT:G(-m.keyPanSpeed,0),m.update()}}(e)}function Z(e){if(!1!==m.enabled){switch(e.touches.length){case 1:if(!1===m.enableRotate)return;!function(e){E.set(e.touches[0].pageX,e.touches[0].pageY)}(e),v=g.TOUCH_ROTATE;break;case 2:if(!1===m.enableZoom)return;!function(e){var t=e.touches[0].pageX-e.touches[1].pageX,n=e.touches[0].pageY-e.touches[1].pageY,a=Math.sqrt(t*t+n*n);A.set(0,a)}(e),v=g.TOUCH_DOLLY;break;case 3:if(!1===m.enablePan)return;!function(e){P.set(e.touches[0].pageX,e.touches[0].pageY)}(e),v=g.TOUCH_PAN;break;default:v=g.NONE}v!==g.NONE&&m.dispatchEvent(l)}}function W(e){if(!1!==m.enabled){switch(e.touches.length){case 1:if(!1===m.enableRotate)return;if(v!==g.TOUCH_ROTATE)return;!function(e){O.set(e.touches[0].pageX,e.touches[0].pageY),I.subVectors(O,E);var t=m.domElement===document?m.domElement.body:m.domElement;V(2*Math.PI*I.x/t.clientWidth*m.rotateSpeed),N(2*Math.PI*I.y/t.clientHeight*m.rotateSpeed),E.copy(O),m.update()}(e);break;case 2:if(!1===m.enableZoom)return;if(v!==g.TOUCH_DOLLY)return;!function(e){var t=e.touches[0].pageX-e.touches[1].pageX,n=e.touches[0].pageY-e.touches[1].pageY,a=Math.sqrt(t*t+n*n);T.set(0,a),L.subVectors(T,A),L.y>0?B(_()):L.y<0&&R(_()),A.copy(T),m.update()}(e);break;case 3:if(!1===m.enablePan)return;if(v!==g.TOUCH_PAN)return;!function(e){j.set(e.touches[0].pageX,e.touches[0].pageY),C.subVectors(j,P),G(C.x,C.y),P.copy(j),m.update()}(e);break;default:v=g.NONE}e.preventDefault(),e.stopPropagation()}}function q(e){!1!==m.enabled&&(m.dispatchEvent(f),v=g.NONE)}function Q(e){!1!==m.enabled&&!1!==m.enablePan&&e.preventDefault()}return m.domElement.addEventListener("contextmenu",Q,!1),m.domElement.addEventListener("mousedown",D,!1),m.domElement.addEventListener("wheel",H,!1),m.domElement.addEventListener("touchstart",Z,!1),m.domElement.addEventListener("touchend",q,!1),m.domElement.addEventListener("touchmove",W,!1),window.addEventListener("keydown",X,!1),u.update(),u}return i(a,e),a}(t.EventDispatcher);e.SkinObject=u,e.CapeObject=m,e.PlayerObject=p,e.SkinViewer=v,e.OrbitControls=b,e.createOrbitControls=function(e){var n=new b(e.camera,e.renderer.domElement);return n.enablePan=!1,n.target=new t.Vector3(0,-12,0),n.minDistance=10,n.maxDistance=256,n.update(),n},e.invokeAnimation=l,e.CompositeAnimation=g,e.WalkingAnimation=function(e,t){var n=e.skin;t*=8,n.leftLeg.rotation.x=.5*Math.sin(t),n.rightLeg.rotation.x=.5*Math.sin(t+Math.PI),n.leftArm.rotation.x=.5*Math.sin(t+Math.PI),n.rightArm.rotation.x=.5*Math.sin(t);var a=.02*Math.PI;n.leftArm.rotation.z=.03*Math.cos(t)+a,n.rightArm.rotation.z=.03*Math.cos(t+Math.PI)-a,n.head.rotation.y=.2*Math.sin(t/4),n.head.rotation.x=.1*Math.sin(t/5);var i=.06*Math.PI;e.cape.rotation.x=.06*Math.sin(t/1.5)+i},e.RunningAnimation=function(e,t){var n=e.skin;t*=15,n.leftLeg.rotation.x=1.3*Math.cos(t+Math.PI),n.rightLeg.rotation.x=1.3*Math.cos(t),n.leftArm.rotation.x=1.5*Math.cos(t),n.rightArm.rotation.x=1.5*Math.cos(t+Math.PI);var a=.1*Math.PI;n.leftArm.rotation.z=.1*Math.cos(t)+a,n.rightArm.rotation.z=.1*Math.cos(t+Math.PI)-a,e.position.y=Math.cos(2*t),e.position.x=.15*Math.cos(t),e.rotation.z=.01*Math.cos(t+Math.PI);var i=.3*Math.PI;e.cape.rotation.x=.1*Math.sin(2*t)+i},e.RotatingAnimation=function(e,t){e.rotation.y=t},Object.defineProperty(e,"__esModule",{value:!0})}); | ||
//# sourceMappingURL=skinview3d.min.js.map |
@@ -1,3 +0,30 @@ | ||
import { BoxGeometry, DoubleSide, EventDispatcher, FrontSide, Group, MOUSE, Mesh, MeshBasicMaterial, NearestFilter, NearestMipMapNearestFilter, OrthographicCamera, PerspectiveCamera, Quaternion, Scene, Spherical, Texture, Vector2, Vector3, WebGLRenderer } from 'three'; | ||
/** | ||
* skinview3d (https://github.com/to2mbn/skinview3d) | ||
* | ||
* MIT License | ||
* | ||
* Copyright (c) 2014-2018 Kent Rasmussen | ||
* Copyright (c) 2017-2018 Haowei Wen, Sean Boult and contributors | ||
* | ||
* Permission is hereby granted, free of charge, to any person obtaining a copy | ||
* of this software and associated documentation files (the "Software"), to deal | ||
* in the Software without restriction, including without limitation the rights | ||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
* copies of the Software, and to permit persons to whom the Software is | ||
* furnished to do so, subject to the following conditions: | ||
* | ||
* The above copyright notice and this permission notice shall be included in all | ||
* copies or substantial portions of the Software. | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
* SOFTWARE. | ||
*/ | ||
import { Vector2, Group, BoxGeometry, Mesh, Texture, NearestFilter, NearestMipMapNearestFilter, MeshBasicMaterial, FrontSide, DoubleSide, Scene, PerspectiveCamera, WebGLRenderer, Vector3, MOUSE, Quaternion, Spherical, OrthographicCamera, EventDispatcher } from 'three'; | ||
var classCallCheck = function (instance, Constructor) { | ||
@@ -102,8 +129,10 @@ if (!(instance instanceof Constructor)) { | ||
function SkinObject(isSlim, layer1Material, layer2Material) { | ||
function SkinObject(slim, layer1Material, layer2Material) { | ||
classCallCheck(this, SkinObject); | ||
// Head | ||
var _this = possibleConstructorReturn(this, (SkinObject.__proto__ || Object.getPrototypeOf(SkinObject)).call(this)); | ||
_this.slim = slim; | ||
// Head | ||
_this.head = new Group(); | ||
@@ -144,4 +173,4 @@ | ||
var rightArmBox = new BoxGeometry((isSlim ? 3 : 4) - esp, 12 - esp, 4 - esp, 0, 0, 0); | ||
if (isSlim) { | ||
var rightArmBox = new BoxGeometry((slim ? 3 : 4) - esp, 12 - esp, 4 - esp, 0, 0, 0); | ||
if (slim) { | ||
addVertices(rightArmBox, toSkinVertices(44, 16, 47, 20), toSkinVertices(47, 16, 50, 20), toSkinVertices(40, 20, 44, 32), toSkinVertices(44, 20, 47, 32), toSkinVertices(47, 20, 51, 32), toSkinVertices(51, 20, 54, 32)); | ||
@@ -154,4 +183,4 @@ } else { | ||
var rightArm2Box = new BoxGeometry((isSlim ? 3.375 : 4.5) - esp, 13.5 - esp, 4.5 - esp, 0, 0, 0); | ||
if (isSlim) { | ||
var rightArm2Box = new BoxGeometry((slim ? 3.375 : 4.5) - esp, 13.5 - esp, 4.5 - esp, 0, 0, 0); | ||
if (slim) { | ||
addVertices(rightArm2Box, toSkinVertices(44, 32, 47, 36), toSkinVertices(47, 32, 50, 36), toSkinVertices(40, 36, 44, 48), toSkinVertices(44, 36, 47, 48), toSkinVertices(47, 36, 51, 48), toSkinVertices(51, 36, 54, 48)); | ||
@@ -168,3 +197,3 @@ } else { | ||
_this.rightArm.position.y = -4; | ||
_this.rightArm.position.x = isSlim ? -5.5 : -6; | ||
_this.rightArm.position.x = slim ? -5.5 : -6; | ||
_this.add(_this.rightArm); | ||
@@ -176,4 +205,4 @@ | ||
var leftArmBox = new BoxGeometry((isSlim ? 3 : 4) - esp, 12 - esp, 4 - esp, 0, 0, 0); | ||
if (isSlim) { | ||
var leftArmBox = new BoxGeometry((slim ? 3 : 4) - esp, 12 - esp, 4 - esp, 0, 0, 0); | ||
if (slim) { | ||
addVertices(leftArmBox, toSkinVertices(36, 48, 39, 52), toSkinVertices(39, 48, 42, 52), toSkinVertices(32, 52, 36, 64), toSkinVertices(36, 52, 39, 64), toSkinVertices(39, 52, 43, 64), toSkinVertices(43, 52, 46, 64)); | ||
@@ -186,4 +215,4 @@ } else { | ||
var leftArm2Box = new BoxGeometry((isSlim ? 3.375 : 4.5) - esp, 13.5 - esp, 4.5 - esp, 0, 0, 0); | ||
if (isSlim) { | ||
var leftArm2Box = new BoxGeometry((slim ? 3.375 : 4.5) - esp, 13.5 - esp, 4.5 - esp, 0, 0, 0); | ||
if (slim) { | ||
addVertices(leftArm2Box, toSkinVertices(52, 48, 55, 52), toSkinVertices(55, 48, 58, 52), toSkinVertices(48, 52, 52, 64), toSkinVertices(52, 52, 55, 64), toSkinVertices(55, 52, 59, 64), toSkinVertices(59, 52, 62, 64)); | ||
@@ -200,3 +229,3 @@ } else { | ||
_this.leftArm.position.y = -4; | ||
_this.leftArm.position.x = isSlim ? 5.5 : 6; | ||
_this.leftArm.position.x = slim ? 5.5 : 6; | ||
_this.add(_this.leftArm); | ||
@@ -281,4 +310,2 @@ | ||
_this3.slim = slim; | ||
_this3.skin = new SkinObject(slim, layer1Material, layer2Material); | ||
@@ -300,2 +327,388 @@ _this3.skin.visible = false; | ||
function invokeAnimation(animation, player, time) { | ||
if (animation instanceof CompositeAnimation) { | ||
animation.play(player, time); | ||
} else if (animation instanceof Function) { | ||
animation(player, time); | ||
} else { | ||
throw "Not an animation: " + animation; | ||
} | ||
} | ||
var AnimationHandle = function () { | ||
function AnimationHandle(animation) { | ||
classCallCheck(this, AnimationHandle); | ||
this.animation = animation; | ||
this.paused = this._paused = false; | ||
this.speed = this._speed = 1.0; | ||
this._lastChange = null; | ||
this._lastChangeX = null; | ||
} | ||
createClass(AnimationHandle, [{ | ||
key: "play", | ||
value: function play(player, time) { | ||
if (this._lastChange === null) { | ||
this._lastChange = time; | ||
this._lastChangeX = 0; | ||
} else if (this.paused !== this._paused || this.speed !== this._speed) { | ||
var dt = time - this._lastChange; | ||
if (this._paused === false) { | ||
this._lastChangeX += dt * this._speed; | ||
} | ||
this._paused = this.paused; | ||
this._speed = this.speed; | ||
this._lastChange = time; | ||
} | ||
if (this.paused === false) { | ||
var _dt = time - this._lastChange; | ||
var x = this._lastChangeX + this.speed * _dt; | ||
invokeAnimation(this.animation, player, x); | ||
} | ||
} | ||
}, { | ||
key: "reset", | ||
value: function reset() { | ||
this._lastChange = null; | ||
} | ||
}]); | ||
return AnimationHandle; | ||
}(); | ||
var CompositeAnimation = function () { | ||
function CompositeAnimation() { | ||
classCallCheck(this, CompositeAnimation); | ||
this.handles = new Set(); | ||
} | ||
createClass(CompositeAnimation, [{ | ||
key: "add", | ||
value: function add(animation) { | ||
var _this = this; | ||
var handle = new AnimationHandle(animation); | ||
handle.remove = function () { | ||
return _this.handles.delete(handle); | ||
}; | ||
this.handles.add(handle); | ||
return handle; | ||
} | ||
}, { | ||
key: "play", | ||
value: function play(player, time) { | ||
this.handles.forEach(function (handle) { | ||
return handle.play(player, time); | ||
}); | ||
} | ||
}]); | ||
return CompositeAnimation; | ||
}(); | ||
var WalkingAnimation = function WalkingAnimation(player, time) { | ||
var skin = player.skin; | ||
// Multiply by animation's natural speed | ||
time *= 8; | ||
// Leg swing | ||
skin.leftLeg.rotation.x = Math.sin(time) * 0.5; | ||
skin.rightLeg.rotation.x = Math.sin(time + Math.PI) * 0.5; | ||
// Arm swing | ||
skin.leftArm.rotation.x = Math.sin(time + Math.PI) * 0.5; | ||
skin.rightArm.rotation.x = Math.sin(time) * 0.5; | ||
var basicArmRotationZ = Math.PI * 0.02; | ||
skin.leftArm.rotation.z = Math.cos(time) * 0.03 + basicArmRotationZ; | ||
skin.rightArm.rotation.z = Math.cos(time + Math.PI) * 0.03 - basicArmRotationZ; | ||
// Head shaking with different frequency & amplitude | ||
skin.head.rotation.y = Math.sin(time / 4) * 0.2; | ||
skin.head.rotation.x = Math.sin(time / 5) * 0.1; | ||
// Always add an angle for cape around the x axis | ||
var basicCapeRotationX = Math.PI * 0.06; | ||
player.cape.rotation.x = Math.sin(time / 1.5) * 0.06 + basicCapeRotationX; | ||
}; | ||
var RunningAnimation = function RunningAnimation(player, time) { | ||
var skin = player.skin; | ||
time *= 15; | ||
// Leg swing with larger amplitude | ||
skin.leftLeg.rotation.x = Math.cos(time + Math.PI) * 1.3; | ||
skin.rightLeg.rotation.x = Math.cos(time) * 1.3; | ||
// Arm swing | ||
skin.leftArm.rotation.x = Math.cos(time) * 1.5; | ||
skin.rightArm.rotation.x = Math.cos(time + Math.PI) * 1.5; | ||
var basicArmRotationZ = Math.PI * 0.1; | ||
skin.leftArm.rotation.z = Math.cos(time) * 0.1 + basicArmRotationZ; | ||
skin.rightArm.rotation.z = Math.cos(time + Math.PI) * 0.1 - basicArmRotationZ; | ||
// Jumping | ||
player.position.y = Math.cos(time * 2); | ||
// Dodging when running | ||
player.position.x = Math.cos(time) * 0.15; | ||
// Slightly tilting when running | ||
player.rotation.z = Math.cos(time + Math.PI) * 0.01; | ||
// Apply higher swing frequency, lower amplitude, | ||
// and greater basic rotation around x axis, | ||
// to cape when running. | ||
var basicCapeRotationX = Math.PI * 0.3; | ||
player.cape.rotation.x = Math.sin(time * 2) * 0.1 + basicCapeRotationX; | ||
// What about head shaking? | ||
// You shouldn't glance right and left when running dude :P | ||
}; | ||
var RotatingAnimation = function RotatingAnimation(player, time) { | ||
player.rotation.y = time; | ||
}; | ||
function copyImage(context, sX, sY, w, h, dX, dY, flipHorizontal) { | ||
var imgData = context.getImageData(sX, sY, w, h); | ||
if (flipHorizontal) { | ||
for (var y = 0; y < h; y++) { | ||
for (var x = 0; x < w / 2; x++) { | ||
var index = (x + y * w) * 4; | ||
var index2 = (w - x - 1 + y * w) * 4; | ||
var pA1 = imgData.data[index]; | ||
var pA2 = imgData.data[index + 1]; | ||
var pA3 = imgData.data[index + 2]; | ||
var pA4 = imgData.data[index + 3]; | ||
var pB1 = imgData.data[index2]; | ||
var pB2 = imgData.data[index2 + 1]; | ||
var pB3 = imgData.data[index2 + 2]; | ||
var pB4 = imgData.data[index2 + 3]; | ||
imgData.data[index] = pB1; | ||
imgData.data[index + 1] = pB2; | ||
imgData.data[index + 2] = pB3; | ||
imgData.data[index + 3] = pB4; | ||
imgData.data[index2] = pA1; | ||
imgData.data[index2 + 1] = pA2; | ||
imgData.data[index2 + 2] = pA3; | ||
imgData.data[index2 + 3] = pA4; | ||
} | ||
} | ||
} | ||
context.putImageData(imgData, dX, dY); | ||
} | ||
function convertSkinTo1_8(context, width) { | ||
var scale = width / 64.0; | ||
var copySkin = function copySkin(context, sX, sY, w, h, dX, dY, flipHorizontal) { | ||
return copyImage(context, sX * scale, sY * scale, w * scale, h * scale, dX * scale, dY * scale, flipHorizontal); | ||
}; | ||
copySkin(context, 4, 16, 4, 4, 20, 48, true); // Top Leg | ||
copySkin(context, 8, 16, 4, 4, 24, 48, true); // Bottom Leg | ||
copySkin(context, 0, 20, 4, 12, 24, 52, true); // Outer Leg | ||
copySkin(context, 4, 20, 4, 12, 20, 52, true); // Front Leg | ||
copySkin(context, 8, 20, 4, 12, 16, 52, true); // Inner Leg | ||
copySkin(context, 12, 20, 4, 12, 28, 52, true); // Back Leg | ||
copySkin(context, 44, 16, 4, 4, 36, 48, true); // Top Arm | ||
copySkin(context, 48, 16, 4, 4, 40, 48, true); // Bottom Arm | ||
copySkin(context, 40, 20, 4, 12, 40, 52, true); // Outer Arm | ||
copySkin(context, 44, 20, 4, 12, 36, 52, true); // Front Arm | ||
copySkin(context, 48, 20, 4, 12, 32, 52, true); // Inner Arm | ||
copySkin(context, 52, 20, 4, 12, 44, 52, true); // Back Arm | ||
} | ||
var SkinViewer = function () { | ||
function SkinViewer(options) { | ||
var _this = this; | ||
classCallCheck(this, SkinViewer); | ||
this.domElement = options.domElement; | ||
this.animation = options.animation || null; | ||
this.animationPaused = false; | ||
this.animationTime = 0; | ||
this.disposed = false; | ||
// texture | ||
this.skinImg = new Image(); | ||
this.skinCanvas = document.createElement("canvas"); | ||
this.skinTexture = new Texture(this.skinCanvas); | ||
this.skinTexture.magFilter = NearestFilter; | ||
this.skinTexture.minFilter = NearestMipMapNearestFilter; | ||
this.capeImg = new Image(); | ||
this.capeCanvas = document.createElement("canvas"); | ||
this.capeTexture = new Texture(this.capeCanvas); | ||
this.capeTexture.magFilter = NearestFilter; | ||
this.capeTexture.minFilter = NearestMipMapNearestFilter; | ||
this.layer1Material = new MeshBasicMaterial({ map: this.skinTexture, side: FrontSide }); | ||
this.layer2Material = new MeshBasicMaterial({ map: this.skinTexture, transparent: true, opacity: 1, side: DoubleSide }); | ||
this.capeMaterial = new MeshBasicMaterial({ map: this.capeTexture }); | ||
// scene | ||
this.scene = new Scene(); | ||
// Use smaller fov to avoid distortion | ||
this.camera = new PerspectiveCamera(40); | ||
this.camera.position.y = -12; | ||
this.camera.position.z = 60; | ||
this.renderer = new WebGLRenderer({ angleRot: true, alpha: true, antialias: false }); | ||
this.renderer.setSize(300, 300); // default size | ||
this.renderer.context.getShaderInfoLog = function () { | ||
return ""; | ||
}; // shut firefox up | ||
this.domElement.appendChild(this.renderer.domElement); | ||
this.playerObject = new PlayerObject(options.slim === true, this.layer1Material, this.layer2Material, this.capeMaterial); | ||
this.scene.add(this.playerObject); | ||
// texture loading | ||
this.skinImg.crossOrigin = ""; | ||
this.skinImg.onerror = function () { | ||
return console.error("Failed loading " + _this.skinImg.src); | ||
}; | ||
this.skinImg.onload = function () { | ||
var isOldFormat = false; | ||
if (_this.skinImg.width !== _this.skinImg.height) { | ||
if (_this.skinImg.width === 2 * _this.skinImg.height) { | ||
isOldFormat = true; | ||
} else { | ||
console.error("Bad skin size"); | ||
return; | ||
} | ||
} | ||
var skinContext = _this.skinCanvas.getContext("2d"); | ||
if (isOldFormat) { | ||
var width = _this.skinImg.width; | ||
_this.skinCanvas.width = width; | ||
_this.skinCanvas.height = width; | ||
skinContext.clearRect(0, 0, width, width); | ||
skinContext.drawImage(_this.skinImg, 0, 0, width, width / 2.0); | ||
convertSkinTo1_8(skinContext, width); | ||
} else { | ||
_this.skinCanvas.width = _this.skinImg.width; | ||
_this.skinCanvas.height = _this.skinImg.height; | ||
skinContext.clearRect(0, 0, _this.skinCanvas.width, _this.skinCanvas.height); | ||
skinContext.drawImage(_this.skinImg, 0, 0, _this.skinCanvas.width, _this.skinCanvas.height); | ||
} | ||
_this.skinTexture.needsUpdate = true; | ||
_this.layer1Material.needsUpdate = true; | ||
_this.layer2Material.needsUpdate = true; | ||
_this.playerObject.skin.visible = true; | ||
}; | ||
this.capeImg.crossOrigin = ""; | ||
this.capeImg.onerror = function () { | ||
return console.error("Failed loading " + _this.capeImg.src); | ||
}; | ||
this.capeImg.onload = function () { | ||
var isOldFormat = false; | ||
if (_this.capeImg.width !== 2 * _this.capeImg.height) { | ||
if (_this.capeImg.width * 17 == _this.capeImg.height * 22) { | ||
// width/height = 22/17 | ||
isOldFormat = true; | ||
} else { | ||
console.error("Bad cape size"); | ||
return; | ||
} | ||
} | ||
var capeContext = _this.capeCanvas.getContext("2d"); | ||
if (isOldFormat) { | ||
var width = _this.capeImg.width * 64 / 22; | ||
_this.capeCanvas.width = width; | ||
_this.capeCanvas.height = width / 2; | ||
} else { | ||
_this.capeCanvas.width = _this.capeImg.width; | ||
_this.capeCanvas.height = _this.capeImg.height; | ||
} | ||
capeContext.clearRect(0, 0, _this.capeCanvas.width, _this.capeCanvas.height); | ||
capeContext.drawImage(_this.capeImg, 0, 0, _this.capeImg.width, _this.capeImg.height); | ||
_this.capeTexture.needsUpdate = true; | ||
_this.capeMaterial.needsUpdate = true; | ||
_this.playerObject.cape.visible = true; | ||
}; | ||
if (options.skinUrl) this.skinUrl = options.skinUrl; | ||
if (options.capeUrl) this.capeUrl = options.capeUrl; | ||
if (options.width) this.width = options.width; | ||
if (options.height) this.height = options.height; | ||
var draw = function draw() { | ||
if (_this.disposed) return; | ||
window.requestAnimationFrame(draw); | ||
if (!_this.animationPaused) { | ||
_this.animationTime++; | ||
if (_this.animation) { | ||
invokeAnimation(_this.animation, _this.playerObject, _this.animationTime / 100.0); | ||
} | ||
} | ||
_this.renderer.render(_this.scene, _this.camera); | ||
}; | ||
draw(); | ||
} | ||
createClass(SkinViewer, [{ | ||
key: "setSize", | ||
value: function setSize(width, height) { | ||
this.camera.aspect = width / height; | ||
this.camera.updateProjectionMatrix(); | ||
this.renderer.setSize(width, height); | ||
} | ||
}, { | ||
key: "dispose", | ||
value: function dispose() { | ||
this.disposed = true; | ||
this.domElement.removeChild(this.renderer.domElement); | ||
this.renderer.dispose(); | ||
this.skinTexture.dispose(); | ||
this.capeTexture.dispose(); | ||
} | ||
}, { | ||
key: "skinUrl", | ||
get: function get$$1() { | ||
return this.skinImg.src; | ||
}, | ||
set: function set$$1(url) { | ||
this.skinImg.src = url; | ||
} | ||
}, { | ||
key: "capeUrl", | ||
get: function get$$1() { | ||
return this.capeImg.src; | ||
}, | ||
set: function set$$1(url) { | ||
this.capeImg.src = url; | ||
} | ||
}, { | ||
key: "width", | ||
get: function get$$1() { | ||
return this.renderer.getSize().width; | ||
}, | ||
set: function set$$1(newWidth) { | ||
this.setSize(newWidth, this.height); | ||
} | ||
}, { | ||
key: "height", | ||
get: function get$$1() { | ||
return this.renderer.getSize().height; | ||
}, | ||
set: function set$$1(newHeight) { | ||
this.setSize(this.width, newHeight); | ||
} | ||
}]); | ||
return SkinViewer; | ||
}(); | ||
var OrbitControls = function (_THREE$EventDispatche) { | ||
@@ -863,387 +1276,16 @@ inherits(OrbitControls, _THREE$EventDispatche); | ||
function invokeAnimation(animation, player, time) { | ||
if (animation instanceof CompositeAnimation) { | ||
animation.play(player, time); | ||
} else if (animation instanceof Function) { | ||
animation(player, time); | ||
} else { | ||
throw "Not an animation: " + animation; | ||
} | ||
} | ||
function createOrbitControls(skinViewer) { | ||
var control = new OrbitControls(skinViewer.camera, skinViewer.renderer.domElement); | ||
var AnimationHandle = function () { | ||
function AnimationHandle(animation) { | ||
classCallCheck(this, AnimationHandle); | ||
// default configuration | ||
control.enablePan = false; | ||
control.target = new Vector3(0, -12, 0); | ||
control.minDistance = 10; | ||
control.maxDistance = 256; | ||
control.update(); | ||
this.animation = animation; | ||
this.paused = this._paused = false; | ||
this.speed = this._speed = 1.0; | ||
this._lastChange = null; | ||
this._lastChangeX = null; | ||
} | ||
createClass(AnimationHandle, [{ | ||
key: "play", | ||
value: function play(player, time) { | ||
if (this._lastChange === null) { | ||
this._lastChange = time; | ||
this._lastChangeX = 0; | ||
} else if (this.paused !== this._paused || this.speed !== this._speed) { | ||
var dt = time - this._lastChange; | ||
if (this._paused === false) { | ||
this._lastChangeX += dt * this._speed; | ||
} | ||
this._paused = this.paused; | ||
this._speed = this.speed; | ||
this._lastChange = time; | ||
} | ||
if (this.paused === false) { | ||
var _dt = time - this._lastChange; | ||
var x = this._lastChangeX + this.speed * _dt; | ||
invokeAnimation(this.animation, player, x); | ||
} | ||
} | ||
}, { | ||
key: "reset", | ||
value: function reset() { | ||
this._lastChange = null; | ||
} | ||
}]); | ||
return AnimationHandle; | ||
}(); | ||
var CompositeAnimation = function () { | ||
function CompositeAnimation() { | ||
classCallCheck(this, CompositeAnimation); | ||
this.handles = new Set(); | ||
} | ||
createClass(CompositeAnimation, [{ | ||
key: "add", | ||
value: function add(animation) { | ||
var _this = this; | ||
var handle = new AnimationHandle(animation); | ||
handle.remove = function () { | ||
return _this.handles.delete(handle); | ||
}; | ||
this.handles.add(handle); | ||
return handle; | ||
} | ||
}, { | ||
key: "play", | ||
value: function play(player, time) { | ||
this.handles.forEach(function (handle) { | ||
return handle.play(player, time); | ||
}); | ||
} | ||
}]); | ||
return CompositeAnimation; | ||
}(); | ||
var WalkAnimation = function WalkAnimation(player, time) { | ||
var skin = player.skin; | ||
var angleRot = time + Math.PI / 2; | ||
// Leg Swing | ||
skin.leftLeg.rotation.x = Math.cos(angleRot); | ||
skin.rightLeg.rotation.x = Math.cos(angleRot + Math.PI); | ||
// Arm Swing | ||
skin.leftArm.rotation.x = Math.cos(angleRot + Math.PI); | ||
skin.rightArm.rotation.x = Math.cos(angleRot); | ||
}; | ||
function copyImage(context, sX, sY, w, h, dX, dY, flipHorizontal) { | ||
var imgData = context.getImageData(sX, sY, w, h); | ||
if (flipHorizontal) { | ||
for (var y = 0; y < h; y++) { | ||
for (var x = 0; x < w / 2; x++) { | ||
var index = (x + y * w) * 4; | ||
var index2 = (w - x - 1 + y * w) * 4; | ||
var pA1 = imgData.data[index]; | ||
var pA2 = imgData.data[index + 1]; | ||
var pA3 = imgData.data[index + 2]; | ||
var pA4 = imgData.data[index + 3]; | ||
var pB1 = imgData.data[index2]; | ||
var pB2 = imgData.data[index2 + 1]; | ||
var pB3 = imgData.data[index2 + 2]; | ||
var pB4 = imgData.data[index2 + 3]; | ||
imgData.data[index] = pB1; | ||
imgData.data[index + 1] = pB2; | ||
imgData.data[index + 2] = pB3; | ||
imgData.data[index + 3] = pB4; | ||
imgData.data[index2] = pA1; | ||
imgData.data[index2 + 1] = pA2; | ||
imgData.data[index2 + 2] = pA3; | ||
imgData.data[index2 + 3] = pA4; | ||
} | ||
} | ||
} | ||
context.putImageData(imgData, dX, dY); | ||
return control; | ||
} | ||
function convertSkinTo1_8(context, width) { | ||
var scale = width / 64.0; | ||
var copySkin = function copySkin(context, sX, sY, w, h, dX, dY, flipHorizontal) { | ||
return copyImage(context, sX * scale, sY * scale, w * scale, h * scale, dX * scale, dY * scale, flipHorizontal); | ||
}; | ||
copySkin(context, 4, 16, 4, 4, 20, 48, true); // Top Leg | ||
copySkin(context, 8, 16, 4, 4, 24, 48, true); // Bottom Leg | ||
copySkin(context, 0, 20, 4, 12, 24, 52, true); // Outer Leg | ||
copySkin(context, 4, 20, 4, 12, 20, 52, true); // Front Leg | ||
copySkin(context, 8, 20, 4, 12, 16, 52, true); // Inner Leg | ||
copySkin(context, 12, 20, 4, 12, 28, 52, true); // Back Leg | ||
copySkin(context, 44, 16, 4, 4, 36, 48, true); // Top Arm | ||
copySkin(context, 48, 16, 4, 4, 40, 48, true); // Bottom Arm | ||
copySkin(context, 40, 20, 4, 12, 40, 52, true); // Outer Arm | ||
copySkin(context, 44, 20, 4, 12, 36, 52, true); // Front Arm | ||
copySkin(context, 48, 20, 4, 12, 32, 52, true); // Inner Arm | ||
copySkin(context, 52, 20, 4, 12, 44, 52, true); // Back Arm | ||
} | ||
var SkinViewer = function () { | ||
function SkinViewer(options) { | ||
var _this = this; | ||
classCallCheck(this, SkinViewer); | ||
this.domElement = options.domElement; | ||
this.animation = options.animation || null; | ||
this.animationPaused = false; | ||
this.animationSpeed = 3; | ||
this.animationTime = 0; | ||
this.disposed = false; | ||
// texture | ||
this.skinImg = new Image(); | ||
this.skinCanvas = document.createElement("canvas"); | ||
this.skinTexture = new Texture(this.skinCanvas); | ||
this.skinTexture.magFilter = NearestFilter; | ||
this.skinTexture.minFilter = NearestMipMapNearestFilter; | ||
this.capeImg = new Image(); | ||
this.capeCanvas = document.createElement("canvas"); | ||
this.capeTexture = new Texture(this.capeCanvas); | ||
this.capeTexture.magFilter = NearestFilter; | ||
this.capeTexture.minFilter = NearestMipMapNearestFilter; | ||
this.layer1Material = new MeshBasicMaterial({ map: this.skinTexture, side: FrontSide }); | ||
this.layer2Material = new MeshBasicMaterial({ map: this.skinTexture, transparent: true, opacity: 1, side: DoubleSide }); | ||
this.capeMaterial = new MeshBasicMaterial({ map: this.capeTexture }); | ||
// scene | ||
this.scene = new Scene(); | ||
this.camera = new PerspectiveCamera(75); | ||
this.camera.position.y = -12; | ||
this.camera.position.z = 30; | ||
this.renderer = new WebGLRenderer({ angleRot: true, alpha: true, antialias: false }); | ||
this.renderer.setSize(300, 300); // default size | ||
this.renderer.context.getShaderInfoLog = function () { | ||
return ""; | ||
}; // shut firefox up | ||
this.domElement.appendChild(this.renderer.domElement); | ||
this.playerObject = new PlayerObject(options.slim === true, this.layer1Material, this.layer2Material, this.capeMaterial); | ||
this.scene.add(this.playerObject); | ||
// texture loading | ||
this.skinImg.crossOrigin = ""; | ||
this.skinImg.onerror = function () { | ||
return console.error("Failed loading " + _this.skinImg.src); | ||
}; | ||
this.skinImg.onload = function () { | ||
var isOldFormat = false; | ||
if (_this.skinImg.width !== _this.skinImg.height) { | ||
if (_this.skinImg.width === 2 * _this.skinImg.height) { | ||
isOldFormat = true; | ||
} else { | ||
console.error("Bad skin size"); | ||
return; | ||
} | ||
} | ||
var skinContext = _this.skinCanvas.getContext("2d"); | ||
if (isOldFormat) { | ||
var width = _this.skinImg.width; | ||
_this.skinCanvas.width = width; | ||
_this.skinCanvas.height = width; | ||
skinContext.clearRect(0, 0, width, width); | ||
skinContext.drawImage(_this.skinImg, 0, 0, width, width / 2.0); | ||
convertSkinTo1_8(skinContext, width); | ||
} else { | ||
_this.skinCanvas.width = _this.skinImg.width; | ||
_this.skinCanvas.height = _this.skinImg.height; | ||
skinContext.clearRect(0, 0, _this.skinCanvas.width, _this.skinCanvas.height); | ||
skinContext.drawImage(_this.skinImg, 0, 0, _this.skinCanvas.width, _this.skinCanvas.height); | ||
} | ||
_this.skinTexture.needsUpdate = true; | ||
_this.layer1Material.needsUpdate = true; | ||
_this.layer2Material.needsUpdate = true; | ||
_this.playerObject.skin.visible = true; | ||
}; | ||
this.capeImg.crossOrigin = ""; | ||
this.capeImg.onerror = function () { | ||
return console.error("Failed loading " + _this.capeImg.src); | ||
}; | ||
this.capeImg.onload = function () { | ||
if (_this.capeImg.width !== 2 * _this.capeImg.height) { | ||
console.error("Bad cape size"); | ||
return; | ||
} | ||
_this.capeCanvas.width = _this.capeImg.width; | ||
_this.capeCanvas.height = _this.capeImg.height; | ||
var capeContext = _this.capeCanvas.getContext("2d"); | ||
capeContext.clearRect(0, 0, _this.capeCanvas.width, _this.capeCanvas.height); | ||
capeContext.drawImage(_this.capeImg, 0, 0, _this.capeCanvas.width, _this.capeCanvas.height); | ||
_this.capeTexture.needsUpdate = true; | ||
_this.capeMaterial.needsUpdate = true; | ||
_this.playerObject.cape.visible = true; | ||
}; | ||
if (options.skinUrl) this.skinUrl = options.skinUrl; | ||
if (options.capeUrl) this.capeUrl = options.capeUrl; | ||
if (options.width) this.width = options.width; | ||
if (options.height) this.height = options.height; | ||
var draw = function draw() { | ||
if (_this.disposed) return; | ||
window.requestAnimationFrame(draw); | ||
if (!_this.animationPaused) { | ||
_this.animationTime++; | ||
if (_this.animation) { | ||
invokeAnimation(_this.animation, _this.playerObject, _this.animationTime / 100.0 * _this.animationSpeed); | ||
} | ||
} | ||
_this.renderer.render(_this.scene, _this.camera); | ||
}; | ||
draw(); | ||
} | ||
createClass(SkinViewer, [{ | ||
key: "setSize", | ||
value: function setSize(width, height) { | ||
this.camera.aspect = width / height; | ||
this.camera.updateProjectionMatrix(); | ||
this.renderer.setSize(width, height); | ||
} | ||
}, { | ||
key: "dispose", | ||
value: function dispose() { | ||
this.disposed = true; | ||
this.domElement.removeChild(this.renderer.domElement); | ||
this.renderer.dispose(); | ||
this.skinTexture.dispose(); | ||
this.capeTexture.dispose(); | ||
} | ||
}, { | ||
key: "skinUrl", | ||
get: function get$$1() { | ||
return this.skinImg.src; | ||
}, | ||
set: function set$$1(url) { | ||
this.skinImg.src = url; | ||
} | ||
}, { | ||
key: "capeUrl", | ||
get: function get$$1() { | ||
return this.capeImg.src; | ||
}, | ||
set: function set$$1(url) { | ||
this.capeImg.src = url; | ||
} | ||
}, { | ||
key: "width", | ||
get: function get$$1() { | ||
return this.renderer.getSize().width; | ||
}, | ||
set: function set$$1(newWidth) { | ||
this.setSize(newWidth, this.height); | ||
} | ||
}, { | ||
key: "height", | ||
get: function get$$1() { | ||
return this.renderer.getSize().height; | ||
}, | ||
set: function set$$1(newHeight) { | ||
this.setSize(this.width, newHeight); | ||
} | ||
}]); | ||
return SkinViewer; | ||
}(); | ||
var SkinControl = function () { | ||
function SkinControl(skinViewer) { | ||
var _this2 = this; | ||
classCallCheck(this, SkinControl); | ||
this.enableAnimationControl = true; | ||
this.skinViewer = skinViewer; | ||
this.orbitControls = new OrbitControls(skinViewer.camera, skinViewer.renderer.domElement); | ||
this.orbitControls.enablePan = false; | ||
this.orbitControls.target = new Vector3(0, -12, 0); | ||
this.orbitControls.minDistance = 10; | ||
this.orbitControls.maxDistance = 256; | ||
this.orbitControls.update(); | ||
this.animationPauseListener = function (e) { | ||
if (_this2.enableAnimationControl) { | ||
e.preventDefault(); | ||
_this2.skinViewer.animationPaused = !_this2.skinViewer.animationPaused; | ||
} | ||
}; | ||
this.skinViewer.domElement.addEventListener("contextmenu", this.animationPauseListener, false); | ||
} | ||
createClass(SkinControl, [{ | ||
key: "dispose", | ||
value: function dispose() { | ||
this.skinViewer.domElement.removeEventListener("contextmenu", this.animationPauseListener, false); | ||
this.orbitControls.dispose(); | ||
} | ||
}]); | ||
return SkinControl; | ||
}(); | ||
/** | ||
* @license | ||
* skinview3d <https://github.com/to2mbn/skinview3d> | ||
* | ||
* Copyright (C) 2017 the original author or authors | ||
* | ||
* This program is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
* | ||
* | ||
* @author yushijinhun <https://github.com/yushijinhun> | ||
* @author Hacksore <https://github.com/Hacksore> | ||
* @author Kent Rasmussen <https://github.com/earthiverse> | ||
*/ | ||
export { SkinObject, CapeObject, PlayerObject, SkinViewer, SkinControl, CompositeAnimation, WalkAnimation }; | ||
export { SkinObject, CapeObject, PlayerObject, SkinViewer, OrbitControls, createOrbitControls, invokeAnimation, CompositeAnimation, WalkingAnimation, RunningAnimation, RotatingAnimation }; | ||
//# sourceMappingURL=skinview3d.module.js.map |
{ | ||
"name": "skinview3d", | ||
"version": "1.1.0-alpha.1", | ||
"version": "1.1.0-alpha.2", | ||
"description": "Three.js powered Minecraft skin viewer", | ||
"module": "build/skinview3d.module.js", | ||
"main": "build/skinview3d.js", | ||
"typings": "types/skinview3d.d.ts", | ||
"scripts": { | ||
"build": "rollup -c tools/rollup.module.js && rollup -c tools/rollup.browser.js && rollup -c tools/rollup.browser.min.js", | ||
"prepare": "npm test && rm -rf build && npm run build", | ||
"test": "eslint src/** tools/**" | ||
"test": "eslint src/** tools/** && tslint -c tslint.json types/**.ts", | ||
"dev": "npm-run-all --parallel watch serve", | ||
"watch": "rollup -w -c tools/rollup.browser.js", | ||
"serve": "ws" | ||
}, | ||
@@ -16,4 +20,10 @@ "repository": { | ||
}, | ||
"author": "yushijinhun", | ||
"license": "GPL-3.0", | ||
"author": "Haowei Wen <yushijinhun@gmail.com> (https://github.com/yushijinhun)", | ||
"contributors": [ | ||
"Sean Boult <hacksore@mcskinsearch.com> (https://github.com/Hacksore)", | ||
"Pig Fang <g-plane@hotmail.com> (https://github.com/g-plane)", | ||
"printempw <h@prinzeugen.net> (https://github.com/printempw)", | ||
"Kent Rasmussen <hyprkookeez@gmail.com> (https://github.com/earthiverse)" | ||
], | ||
"license": "MIT", | ||
"bugs": { | ||
@@ -27,12 +37,18 @@ "url": "https://github.com/to2mbn/skinview3d/issues" | ||
"devDependencies": { | ||
"@types/three": "^0.89.6", | ||
"babel-cli": "^6.26.0", | ||
"babel-plugin-external-helpers": "^6.22.0", | ||
"babel-preset-env": "^1.6.1", | ||
"eslint": "^4.15.0", | ||
"rollup": "^0.54.0", | ||
"eslint": "^4.17.0", | ||
"local-web-server": "^2.4.0", | ||
"npm-run-all": "^4.1.2", | ||
"rollup": "^0.55.3", | ||
"rollup-plugin-babel": "^3.0.3", | ||
"rollup-plugin-license": "^0.5.0", | ||
"rollup-plugin-node-resolve": "^3.0.2", | ||
"rollup-plugin-uglify": "^2.0.1", | ||
"uglify-es": "^3.3.7" | ||
"rollup-plugin-uglify": "^3.0.0", | ||
"tslint": "^5.9.1", | ||
"typescript": "^2.7.1", | ||
"uglify-es": "^3.3.10" | ||
} | ||
} |
@@ -6,3 +6,4 @@ skinview3d | ||
[![npm](https://img.shields.io/npm/v/skinview3d.svg?style=flat-square)](https://www.npmjs.com/package/skinview3d) | ||
[![license](https://img.shields.io/github/license/to2mbn/skinview3d.svg?style=flat-square)](https://github.com/to2mbn/skinview3d/blob/master/LICENSE) | ||
[![license](https://img.shields.io/badge/license-MIT-yellowgreen.svg?style=flat-square)](https://github.com/to2mbn/skinview3d/blob/master/LICENSE) | ||
[![Gitter chat](https://img.shields.io/gitter/room/TechnologyAdvice/Stardust.svg?style=flat-square)](https://gitter.im/skinview3d/Lobby) | ||
@@ -18,2 +19,3 @@ Three.js powered Minecraft skin viewer. | ||
# Usage | ||
[Examples of using the viewer](https://to2mbn.github.io/skinview3d/) | ||
```html | ||
@@ -31,24 +33,33 @@ <div id="skin_container"></div> | ||
// change the skin and cape | ||
// skinViewer.skinUrl = "img/skin.png"; | ||
// skinViewer.capeUrl = "img/cape.png"; | ||
// Change the textures | ||
skinViewer.skinUrl = "img/skin2.png"; | ||
skinViewer.capeUrl = "img/cape2.png"; | ||
// change the width and height | ||
// skinViewer.width = 300; | ||
// skinViewer.height = 400; | ||
// Resize the skin viewer | ||
skinViewer.width = 300; | ||
skinViewer.height = 400; | ||
// enable the mouse control feature | ||
let control = new skinview3d.SkinControl(skinViewer); | ||
// Control objects with your mouse! | ||
let control = skinview3d.createOrbitControls(skinViewer); | ||
control.enableRotate = true; | ||
control.enableZoom = false; | ||
control.enablePan = false; | ||
// disable the 'right click to play/pause' feature | ||
// control.enableAnimationControl = false; | ||
skinViewer.animation = new skinview3d.CompositeAnimation(); | ||
// add an animation | ||
let walk = skinViewer.animation.add(skinview3d.WalkAnimation); | ||
// Add an animation | ||
let walk = skinViewer.animation.add(skinview3d.WalkingAnimation); | ||
// Add another animation | ||
let rotate = skinViewer.animation.add(skinview3d.RotatingAnimation); | ||
// Remove an animation, stop walking dude | ||
walk.remove(); | ||
// And run for now! | ||
let run = skinViewer.animation.add(skinview3d.RunningAnimation); | ||
// set its speed and some others | ||
walk.speed = 1.5; | ||
// walk.paused = true; | ||
// Set the speed of an animation | ||
run.speed = 3; | ||
// Pause single animation | ||
run.paused = true; | ||
// Pause all animations! | ||
skinViewer.animationPaused = true; | ||
</script> | ||
@@ -55,0 +66,0 @@ ``` |
@@ -58,15 +58,71 @@ function invokeAnimation(animation, player, time) { | ||
let WalkAnimation = (player, time) => { | ||
let WalkingAnimation = (player, time) => { | ||
let skin = player.skin; | ||
let angleRot = time + Math.PI / 2; | ||
// Leg Swing | ||
skin.leftLeg.rotation.x = Math.cos(angleRot); | ||
skin.rightLeg.rotation.x = Math.cos(angleRot + (Math.PI)); | ||
// Multiply by animation's natural speed | ||
time *= 8; | ||
// Arm Swing | ||
skin.leftArm.rotation.x = Math.cos(angleRot + (Math.PI)); | ||
skin.rightArm.rotation.x = Math.cos(angleRot); | ||
// Leg swing | ||
skin.leftLeg.rotation.x = Math.sin(time) * 0.5; | ||
skin.rightLeg.rotation.x = Math.sin(time + Math.PI) * 0.5; | ||
// Arm swing | ||
skin.leftArm.rotation.x = Math.sin(time + Math.PI) * 0.5; | ||
skin.rightArm.rotation.x = Math.sin(time) * 0.5; | ||
let basicArmRotationZ = Math.PI * 0.02; | ||
skin.leftArm.rotation.z = Math.cos(time) * 0.03 + basicArmRotationZ; | ||
skin.rightArm.rotation.z = Math.cos(time + Math.PI) * 0.03 - basicArmRotationZ; | ||
// Head shaking with different frequency & amplitude | ||
skin.head.rotation.y = Math.sin(time / 4) * 0.2; | ||
skin.head.rotation.x = Math.sin(time / 5) * 0.1; | ||
// Always add an angle for cape around the x axis | ||
let basicCapeRotationX = Math.PI * 0.06; | ||
player.cape.rotation.x = Math.sin(time / 1.5) * 0.06 + basicCapeRotationX; | ||
}; | ||
export { CompositeAnimation, WalkAnimation, invokeAnimation }; | ||
let RunningAnimation = (player, time) => { | ||
let skin = player.skin; | ||
time *= 15; | ||
// Leg swing with larger amplitude | ||
skin.leftLeg.rotation.x = Math.cos(time + Math.PI) * 1.3; | ||
skin.rightLeg.rotation.x = Math.cos(time) * 1.3; | ||
// Arm swing | ||
skin.leftArm.rotation.x = Math.cos(time) * 1.5; | ||
skin.rightArm.rotation.x = Math.cos(time + Math.PI) * 1.5; | ||
let basicArmRotationZ = Math.PI * 0.1; | ||
skin.leftArm.rotation.z = Math.cos(time) * 0.1 + basicArmRotationZ; | ||
skin.rightArm.rotation.z = Math.cos(time + Math.PI) * 0.1 - basicArmRotationZ; | ||
// Jumping | ||
player.position.y = Math.cos(time * 2); | ||
// Dodging when running | ||
player.position.x = Math.cos(time) * 0.15; | ||
// Slightly tilting when running | ||
player.rotation.z = Math.cos(time + Math.PI) * 0.01; | ||
// Apply higher swing frequency, lower amplitude, | ||
// and greater basic rotation around x axis, | ||
// to cape when running. | ||
let basicCapeRotationX = Math.PI * 0.3; | ||
player.cape.rotation.x = Math.sin(time * 2) * 0.1 + basicCapeRotationX; | ||
// What about head shaking? | ||
// You shouldn't glance right and left when running dude :P | ||
}; | ||
let RotatingAnimation = (player, time) => { | ||
player.rotation.y = time; | ||
}; | ||
export { | ||
CompositeAnimation, | ||
invokeAnimation, | ||
WalkingAnimation, | ||
RunningAnimation, | ||
RotatingAnimation | ||
}; |
@@ -39,5 +39,7 @@ import * as THREE from "three"; | ||
class SkinObject extends THREE.Group { | ||
constructor(isSlim, layer1Material, layer2Material) { | ||
constructor(slim, layer1Material, layer2Material) { | ||
super(); | ||
this.slim = slim; | ||
// Head | ||
@@ -109,4 +111,4 @@ this.head = new THREE.Group(); | ||
let rightArmBox = new THREE.BoxGeometry((isSlim ? 3 : 4) - esp, 12 - esp, 4 - esp, 0, 0, 0); | ||
if (isSlim) { | ||
let rightArmBox = new THREE.BoxGeometry((slim ? 3 : 4) - esp, 12 - esp, 4 - esp, 0, 0, 0); | ||
if (slim) { | ||
addVertices(rightArmBox, | ||
@@ -133,4 +135,4 @@ toSkinVertices(44, 16, 47, 20), | ||
let rightArm2Box = new THREE.BoxGeometry((isSlim ? 3.375 : 4.5) - esp, 13.5 - esp, 4.5 - esp, 0, 0, 0); | ||
if (isSlim) { | ||
let rightArm2Box = new THREE.BoxGeometry((slim ? 3.375 : 4.5) - esp, 13.5 - esp, 4.5 - esp, 0, 0, 0); | ||
if (slim) { | ||
addVertices(rightArm2Box, | ||
@@ -161,3 +163,3 @@ toSkinVertices(44, 32, 47, 36), | ||
this.rightArm.position.y = -4; | ||
this.rightArm.position.x = isSlim ? -5.5 : -6; | ||
this.rightArm.position.x = slim ? -5.5 : -6; | ||
this.add(this.rightArm); | ||
@@ -170,4 +172,4 @@ | ||
let leftArmBox = new THREE.BoxGeometry((isSlim ? 3 : 4) - esp, 12 - esp, 4 - esp, 0, 0, 0); | ||
if (isSlim) { | ||
let leftArmBox = new THREE.BoxGeometry((slim ? 3 : 4) - esp, 12 - esp, 4 - esp, 0, 0, 0); | ||
if (slim) { | ||
addVertices(leftArmBox, | ||
@@ -194,4 +196,4 @@ toSkinVertices(36, 48, 39, 52), | ||
let leftArm2Box = new THREE.BoxGeometry((isSlim ? 3.375 : 4.5) - esp, 13.5 - esp, 4.5 - esp, 0, 0, 0); | ||
if (isSlim) { | ||
let leftArm2Box = new THREE.BoxGeometry((slim ? 3.375 : 4.5) - esp, 13.5 - esp, 4.5 - esp, 0, 0, 0); | ||
if (slim) { | ||
addVertices(leftArm2Box, | ||
@@ -222,3 +224,3 @@ toSkinVertices(52, 48, 55, 52), | ||
this.leftArm.position.y = -4; | ||
this.leftArm.position.x = isSlim ? 5.5 : 6; | ||
this.leftArm.position.x = slim ? 5.5 : 6; | ||
this.add(this.leftArm); | ||
@@ -325,4 +327,2 @@ | ||
this.slim = slim; | ||
this.skin = new SkinObject(slim, layer1Material, layer2Material); | ||
@@ -329,0 +329,0 @@ this.skin.visible = false; |
@@ -596,2 +596,15 @@ import * as THREE from "three"; | ||
export { OrbitControls }; | ||
function createOrbitControls(skinViewer) { | ||
let control = new OrbitControls(skinViewer.camera, skinViewer.renderer.domElement); | ||
// default configuration | ||
control.enablePan = false; | ||
control.target = new THREE.Vector3(0, -12, 0); | ||
control.minDistance = 10; | ||
control.maxDistance = 256; | ||
control.update(); | ||
return control; | ||
} | ||
export { OrbitControls, createOrbitControls }; |
@@ -1,28 +0,10 @@ | ||
/** | ||
* @license | ||
* skinview3d <https://github.com/to2mbn/skinview3d> | ||
* | ||
* Copyright (C) 2017 the original author or authors | ||
* | ||
* This program is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
* | ||
* | ||
* @author yushijinhun <https://github.com/yushijinhun> | ||
* @author Hacksore <https://github.com/Hacksore> | ||
* @author Kent Rasmussen <https://github.com/earthiverse> | ||
*/ | ||
export { SkinObject, CapeObject, PlayerObject } from "./model"; | ||
export { SkinViewer, SkinControl } from "./viewer"; | ||
export { CompositeAnimation, WalkAnimation } from "./animation"; | ||
export { SkinViewer } from "./viewer"; | ||
export { OrbitControls, createOrbitControls } from "./orbit_controls"; | ||
export { | ||
invokeAnimation, | ||
CompositeAnimation, | ||
WalkingAnimation, | ||
RunningAnimation, | ||
RotatingAnimation | ||
} from "./animation"; |
import * as THREE from "three"; | ||
import { PlayerObject } from "./model"; | ||
import { OrbitControls } from "./orbit_controls"; | ||
import { invokeAnimation } from "./animation"; | ||
@@ -61,3 +60,2 @@ | ||
this.animationPaused = false; | ||
this.animationSpeed = 3; | ||
this.animationTime = 0; | ||
@@ -86,5 +84,6 @@ this.disposed = false; | ||
this.camera = new THREE.PerspectiveCamera(75); | ||
// Use smaller fov to avoid distortion | ||
this.camera = new THREE.PerspectiveCamera(40); | ||
this.camera.position.y = -12; | ||
this.camera.position.z = 30; | ||
this.camera.position.z = 60; | ||
@@ -138,12 +137,24 @@ this.renderer = new THREE.WebGLRenderer({ angleRot: true, alpha: true, antialias: false }); | ||
this.capeImg.onload = () => { | ||
let isOldFormat = false; | ||
if (this.capeImg.width !== 2 * this.capeImg.height) { | ||
console.error("Bad cape size"); | ||
return; | ||
if (this.capeImg.width * 17 == this.capeImg.height * 22) { | ||
// width/height = 22/17 | ||
isOldFormat = true; | ||
} else { | ||
console.error("Bad cape size"); | ||
return; | ||
} | ||
} | ||
this.capeCanvas.width = this.capeImg.width; | ||
this.capeCanvas.height = this.capeImg.height; | ||
let capeContext = this.capeCanvas.getContext("2d"); | ||
if (isOldFormat) { | ||
let width = this.capeImg.width * 64 / 22; | ||
this.capeCanvas.width = width; | ||
this.capeCanvas.height = width / 2; | ||
} else { | ||
this.capeCanvas.width = this.capeImg.width; | ||
this.capeCanvas.height = this.capeImg.height; | ||
} | ||
capeContext.clearRect(0, 0, this.capeCanvas.width, this.capeCanvas.height); | ||
capeContext.drawImage(this.capeImg, 0, 0, this.capeCanvas.width, this.capeCanvas.height); | ||
capeContext.drawImage(this.capeImg, 0, 0, this.capeImg.width, this.capeImg.height); | ||
@@ -167,3 +178,3 @@ this.capeTexture.needsUpdate = true; | ||
if (this.animation) { | ||
invokeAnimation(this.animation, this.playerObject, this.animationTime / 100.0 * this.animationSpeed); | ||
invokeAnimation(this.animation, this.playerObject, this.animationTime / 100.0); | ||
} | ||
@@ -223,29 +234,2 @@ } | ||
class SkinControl { | ||
constructor(skinViewer) { | ||
this.enableAnimationControl = true; | ||
this.skinViewer = skinViewer; | ||
this.orbitControls = new OrbitControls(skinViewer.camera, skinViewer.renderer.domElement); | ||
this.orbitControls.enablePan = false; | ||
this.orbitControls.target = new THREE.Vector3(0, -12, 0); | ||
this.orbitControls.minDistance = 10; | ||
this.orbitControls.maxDistance = 256; | ||
this.orbitControls.update(); | ||
this.animationPauseListener = e => { | ||
if (this.enableAnimationControl) { | ||
e.preventDefault(); | ||
this.skinViewer.animationPaused = !this.skinViewer.animationPaused; | ||
} | ||
}; | ||
this.skinViewer.domElement.addEventListener("contextmenu", this.animationPauseListener, false); | ||
} | ||
dispose() { | ||
this.skinViewer.domElement.removeEventListener("contextmenu", this.animationPauseListener, false); | ||
this.orbitControls.dispose(); | ||
} | ||
} | ||
export { SkinViewer, SkinControl }; | ||
export { SkinViewer }; |
import uglify from "rollup-plugin-uglify"; | ||
import { minify } from "uglify-es"; | ||
import babel from "rollup-plugin-babel"; | ||
import resolve from "rollup-plugin-node-resolve"; | ||
import license from "rollup-plugin-license"; | ||
import fs from "fs"; | ||
@@ -10,3 +11,3 @@ let buildType = config => { | ||
output: [], | ||
external:[ | ||
external: [ | ||
"three" | ||
@@ -60,7 +61,18 @@ ], | ||
} | ||
}, minify) | ||
}) | ||
); | ||
} | ||
options.plugins.push( | ||
license({ | ||
sourcemap: true, | ||
banner: ` | ||
skinview3d (https://github.com/to2mbn/skinview3d) | ||
${fs.readFileSync("LICENSE").toString()} | ||
` | ||
}) | ||
); | ||
return options; | ||
}; | ||
export { buildType }; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Copyleft License
License(Experimental) Copyleft license information was found.
Found 1 instance in 1 package
Mixed license
License(Experimental) Package contains multiple licenses.
Found 1 instance in 1 package
Non-permissive License
License(Experimental) A license not known to be considered permissive was found.
Found 1 instance in 1 package
32
0
100
3903
67
0
431093
15
1