1
0
mirror of https://github.com/troisjs/trois.git synced 2024-11-24 04:12:02 +08:00
trois/build/trois.js
Kevin Levron 090e9b78a1 0.1.14
2021-03-13 19:34:34 +01:00

3157 lines
93 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var vue = require('vue');
var three = require('three');
var OrbitControls_js = require('three/examples/jsm/controls/OrbitControls.js');
var RectAreaLightUniformsLib_js = require('three/examples/jsm/lights/RectAreaLightUniformsLib.js');
var RectAreaLightHelper_js = require('three/examples/jsm/helpers/RectAreaLightHelper.js');
var GLTFLoader_js = require('three/examples/jsm/loaders/GLTFLoader.js');
var FBXLoader_js = require('three/examples/jsm/loaders/FBXLoader.js');
var EffectComposer_js = require('three/examples/jsm/postprocessing/EffectComposer.js');
var RenderPass_js = require('three/examples/jsm/postprocessing/RenderPass.js');
var BokehPass_js = require('three/examples/jsm/postprocessing/BokehPass.js');
var FilmPass_js = require('three/examples/jsm/postprocessing/FilmPass.js');
var ShaderPass_js = require('three/examples/jsm/postprocessing/ShaderPass.js');
var FXAAShader_js = require('three/examples/jsm/shaders/FXAAShader.js');
var HalftonePass_js = require('three/examples/jsm/postprocessing/HalftonePass.js');
var SMAAPass_js = require('three/examples/jsm/postprocessing/SMAAPass.js');
var UnrealBloomPass_js = require('three/examples/jsm/postprocessing/UnrealBloomPass.js');
/**
* Three.js helper
*/
function useThree() {
// default conf
var conf = {
canvas: null,
antialias: true,
alpha: false,
autoClear: true,
orbit_ctrl: false,
mouse_move: false,
mouse_raycast: false,
mouse_over: false,
click: false,
resize: true,
width: 0,
height: 0,
};
// size
var size = {
width: 1, height: 1,
wWidth: 1, wHeight: 1,
ratio: 1,
};
// handlers
var afterInitCallbacks = [];
var afterResizeCallbacks = [];
var beforeRenderCallbacks = [];
// mouse tracking
var mouse = new three.Vector2();
var mouseV3 = new three.Vector3();
var mousePlane = new three.Plane(new three.Vector3(0, 0, 1), 0);
var raycaster = new three.Raycaster();
// raycast objects
var intersectObjects = [];
// returned object
var obj = {
conf: conf,
renderer: null,
camera: null,
cameraCtrl: null,
materials: {},
scene: null,
size: size,
mouse: mouse, mouseV3: mouseV3,
init: init,
dispose: dispose,
render: render,
renderC: renderC,
setSize: setSize,
onAfterInit: onAfterInit,
onAfterResize: onAfterResize, offAfterResize: offAfterResize,
onBeforeRender: onBeforeRender, offBeforeRender: offBeforeRender,
addIntersectObject: addIntersectObject, removeIntersectObject: removeIntersectObject,
};
/**
* init three
*/
function init(params) {
if (params) {
Object.entries(params).forEach(function (ref) {
var key = ref[0];
var value = ref[1];
conf[key] = value;
});
}
if (!obj.scene) {
console.error('Missing Scene');
return;
}
if (!obj.camera) {
console.error('Missing Camera');
return;
}
obj.renderer = new three.WebGLRenderer({ canvas: conf.canvas, antialias: conf.antialias, alpha: conf.alpha });
obj.renderer.autoClear = conf.autoClear;
if (conf.orbit_ctrl) {
obj.orbitCtrl = new OrbitControls_js.OrbitControls(obj.camera, obj.renderer.domElement);
if (conf.orbit_ctrl instanceof Object) {
Object.entries(conf.orbit_ctrl).forEach(function (ref) {
var key = ref[0];
var value = ref[1];
obj.orbitCtrl[key] = value;
});
}
}
if (conf.resize) {
onResize();
window.addEventListener('resize', onResize);
} else {
setSize(conf.width | 300, conf.height | 150);
}
conf.mouse_move = conf.mouse_move || conf.mouse_over;
if (conf.mouse_move) {
if (conf.mouse_move === 'body') {
obj.mouse_move_element = document.body;
} else {
obj.mouse_move_element = obj.renderer.domElement;
}
obj.mouse_move_element.addEventListener('mousemove', onMousemove);
obj.mouse_move_element.addEventListener('mouseleave', onMouseleave);
}
if (conf.click) {
obj.renderer.domElement.addEventListener('click', onClick);
}
afterInitCallbacks.forEach(function (c) { return c(); });
return true;
}
/**
* add after init callback
*/
function onAfterInit(callback) {
afterInitCallbacks.push(callback);
}
/**
* add after resize callback
*/
function onAfterResize(callback) {
afterResizeCallbacks.push(callback);
}
/**
* remove after resize callback
*/
function offAfterResize(callback) {
afterResizeCallbacks = afterResizeCallbacks.filter(function (c) { return c !== callback; });
}
/**
* add before render callback
*/
function onBeforeRender(callback) {
beforeRenderCallbacks.push(callback);
}
/**
* remove before render callback
*/
function offBeforeRender(callback) {
beforeRenderCallbacks = beforeRenderCallbacks.filter(function (c) { return c !== callback; });
}
/**
* default render
*/
function render() {
if (obj.orbitCtrl) { obj.orbitCtrl.update(); }
beforeRenderCallbacks.forEach(function (c) { return c(); });
obj.renderer.render(obj.scene, obj.camera);
}
/**
* composer render
*/
function renderC() {
if (obj.orbitCtrl) { obj.orbitCtrl.update(); }
beforeRenderCallbacks.forEach(function (c) { return c(); });
obj.composer.render();
}
/**
* add intersect object
*/
function addIntersectObject(o) {
if (intersectObjects.indexOf(o) === -1) {
intersectObjects.push(o);
}
}
/**
* remove intersect object
*/
function removeIntersectObject(o) {
var i = intersectObjects.indexOf(o);
if (i !== -1) {
intersectObjects.splice(i, 1);
}
}
/**
* remove listeners
*/
function dispose() {
beforeRenderCallbacks = [];
window.removeEventListener('resize', onResize);
if (obj.mouse_move_element) {
obj.mouse_move_element.removeEventListener('mousemove', onMousemove);
obj.mouse_move_element.removeEventListener('mouseleave', onMouseleave);
}
obj.renderer.domElement.removeEventListener('click', onClick);
if (obj.orbitCtrl) { obj.orbitCtrl.dispose(); }
this.renderer.dispose();
}
/**
*/
function updateMouse(e) {
var rect = e.target.getBoundingClientRect();
mouse.x = ((e.clientX - rect.left) / size.width) * 2 - 1;
mouse.y = -((e.clientY - rect.top) / size.height) * 2 + 1;
}
/**
* click listener
*/
function onClick(e) {
updateMouse(e);
raycaster.setFromCamera(mouse, obj.camera);
var objects = raycaster.intersectObjects(intersectObjects);
for (var i = 0; i < objects.length; i++) {
var o = objects[i].object;
if (o.onClick) { o.onClick(e); }
}
}
/**
* mousemove listener
*/
function onMousemove(e) {
updateMouse(e);
onMousechange();
}
/**
* mouseleave listener
*/
function onMouseleave(e) {
// mouse.x = 0;
// mouse.y = 0;
onMousechange();
}
/**
* mouse change
*/
function onMousechange(e) {
if (conf.mouse_over || conf.mouse_raycast) {
raycaster.setFromCamera(mouse, obj.camera);
if (conf.mouse_raycast) {
// get mouse 3d position
obj.camera.getWorldDirection(mousePlane.normal);
mousePlane.normal.normalize();
raycaster.ray.intersectPlane(mousePlane, mouseV3);
}
if (conf.mouse_over) {
var onObjects = raycaster.intersectObjects(intersectObjects);
var offObjects = [].concat( intersectObjects );
for (var i = 0; i < onObjects.length; i++) {
var o = onObjects[i].object;
if (!o.hover && o.onHover) {
o.hover = true;
o.onHover(true);
}
offObjects.splice(offObjects.indexOf(o), 1);
}
for (var i$1 = 0; i$1 < offObjects.length; i$1++) {
var o$1 = offObjects[i$1];
if (o$1.hover && o$1.onHover) {
o$1.hover = false;
o$1.onHover(false);
}
}
}
}
}
/**
* resize listener
*/
function onResize() {
if (conf.resize === 'window') {
setSize(window.innerWidth, window.innerHeight);
} else {
var elt = obj.renderer.domElement.parentNode;
setSize(elt.clientWidth, elt.clientHeight);
}
afterResizeCallbacks.forEach(function (c) { return c(); });
}
/**
* update renderer size and camera
*/
function setSize(width, height) {
size.width = width;
size.height = height;
size.ratio = width / height;
obj.renderer.setSize(width, height, false);
obj.camera.aspect = size.ratio;
obj.camera.updateProjectionMatrix();
if (obj.composer) {
obj.composer.setSize(width, height);
}
if (obj.camera.type === 'OrthographicCamera') {
size.wWidth = obj.camera.right - obj.camera.left;
size.wHeight = obj.camera.top - obj.camera.bottom;
} else {
var wsize = getCameraSize();
size.wWidth = wsize[0]; size.wHeight = wsize[1];
}
}
/**
* calculate camera visible area size
*/
function getCameraSize() {
var vFOV = (obj.camera.fov * Math.PI) / 180;
var h = 2 * Math.tan(vFOV / 2) * Math.abs(obj.camera.position.z);
var w = h * obj.camera.aspect;
return [w, h];
}
return obj;
}
var Renderer = {
name: 'Renderer',
props: {
antialias: Boolean,
alpha: Boolean,
autoClear: { type: Boolean, default: true },
mouseMove: { type: [Boolean, String], default: false },
mouseRaycast: { type: Boolean, default: false },
mouseOver: { type: Boolean, default: false },
click: { type: Boolean, default: false },
orbitCtrl: { type: [Boolean, Object], default: false },
resize: { type: [Boolean, String], default: false },
shadow: Boolean,
width: String,
height: String,
},
setup: function setup() {
return {
three: useThree(),
raf: true,
onMountedCallbacks: [],
};
},
provide: function provide() {
return {
three: this.three,
// renderer: this.three.renderer,
rendererComponent: this,
};
},
mounted: function mounted() {
var params = {
canvas: this.$el,
antialias: this.antialias,
alpha: this.alpha,
autoClear: this.autoClear,
orbit_ctrl: this.orbitCtrl,
mouse_move: this.mouseMove,
mouse_raycast: this.mouseRaycast,
mouse_over: this.mouseOver,
click: this.click,
resize: this.resize,
width: this.width,
height: this.height,
};
if (this.three.init(params)) {
this.renderer = this.three.renderer;
this.renderer.shadowMap.enabled = this.shadow;
if (this.three.composer) { this.animateC(); }
else { this.animate(); }
}
this.onMountedCallbacks.forEach(function (c) { return c(); });
},
beforeUnmount: function beforeUnmount() {
this.raf = false;
this.three.dispose();
},
methods: {
onMounted: function onMounted(callback) {
this.onMountedCallbacks.push(callback);
},
onBeforeRender: function onBeforeRender(callback) {
this.three.onBeforeRender(callback);
},
onAfterResize: function onAfterResize(callback) {
this.three.onAfterResize(callback);
},
animate: function animate() {
if (this.raf) { requestAnimationFrame(this.animate); }
this.three.render();
},
animateC: function animateC() {
if (this.raf) { requestAnimationFrame(this.animateC); }
this.three.renderC();
},
},
render: function render() {
return vue.h('canvas', {}, this.$slots.default());
},
__hmrId: 'Renderer',
};
function setFromProp(o, prop) {
if (prop instanceof Object) {
Object.entries(prop).forEach(function (ref) {
var key = ref[0];
var value = ref[1];
o[key] = value;
});
}
}
function bindProps(src, props, dst) {
props.forEach(function (prop) {
bindProp(src, prop, dst);
});
}
function bindProp(src, srcProp, dst, dstProp) {
if (!dstProp) { dstProp = srcProp; }
var ref = vue.toRef(src, srcProp);
if (ref.value instanceof Object) {
setFromProp(dst[dstProp], ref.value);
vue.watch(ref, function (value) { setFromProp(dst[dstProp], value); }, { deep: true });
} else {
if (ref.value) { dst[dstProp] = src[srcProp]; }
vue.watch(ref, function (value) { dst[dstProp] = value; });
}
}
function propsValues(props, exclude) {
var values = {};
Object.entries(props).forEach(function (ref) {
var key = ref[0];
var value = ref[1];
if (!exclude || (exclude && !exclude.includes(key))) {
values[key] = value;
}
});
return values;
}
function lerp(value1, value2, amount) {
amount = amount < 0 ? 0 : amount;
amount = amount > 1 ? 1 : amount;
return value1 + (value2 - value1) * amount;
}
function lerpv2(v1, v2, amount) {
v1.x = lerp(v1.x, v2.x, amount);
v1.y = lerp(v1.y, v2.y, amount);
}
function lerpv3(v1, v2, amount) {
v1.x = lerp(v1.x, v2.x, amount);
v1.y = lerp(v1.y, v2.y, amount);
v1.z = lerp(v1.z, v2.z, amount);
}
function limit(val, min, max) {
return val < min ? min : (val > max ? max : val);
}
// from https://github.com/pmndrs/drei/blob/master/src/useMatcapTexture.tsx
var MATCAP_ROOT = 'https://rawcdn.githack.com/emmelleppi/matcaps/9b36ccaaf0a24881a39062d05566c9e92be4aa0d';
function getMatcapUrl(hash, format) {
if ( format === void 0 ) format = 1024;
var fileName = "" + hash + (getMatcapFormatString(format)) + ".png";
return (MATCAP_ROOT + "/" + format + "/" + fileName);
}
function getMatcapFormatString(format) {
switch (format) {
case 64:
return '-64px';
case 128:
return '-128px';
case 256:
return '-256px';
case 512:
return '-512px';
default:
return '';
}
}
// shader defaults
var defaultVertexShader = "\nvarying vec2 vUv;\nvoid main(){\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0);\n}";
var defaultFragmentShader = "\nvarying vec2 vUv;\nvoid main() {\n gl_FragColor = vec4(vUv.x, vUv.y, 0., 1.0);\n}";
var OrthographicCamera = {
name: 'OrthographicCamera',
inject: ['three'],
props: {
left: { type: Number, default: -1 },
right: { type: Number, default: 1 },
top: { type: Number, default: 1 },
bottom: { type: Number, default: -1 },
near: { type: Number, default: 0.1 },
far: { type: Number, default: 2000 },
zoom: { type: Number, default: 1 },
position: { type: Object, default: { x: 0, y: 0, z: 0 } },
},
created: function created() {
var this$1 = this;
this.camera = new three.OrthographicCamera(this.left, this.right, this.top, this.bottom, this.near, this.far);
bindProp(this, 'position', this.camera);
['left', 'right', 'top', 'bottom', 'near', 'far', 'zoom'].forEach(function (p) {
vue.watch(function () { return this$1[p]; }, function () {
this$1.camera[p] = this$1[p];
this$1.camera.updateProjectionMatrix();
});
});
this.three.camera = this.camera;
},
render: function render() { return []; },
__hmrId: 'OrthographicCamera',
};
var PerspectiveCamera = {
name: 'PerspectiveCamera',
inject: ['three'],
props: {
aspect: { type: Number, default: 1 },
far: { type: Number, default: 2000 },
fov: { type: Number, default: 50 },
near: { type: Number, default: 0.1 },
position: { type: Object, default: { x: 0, y: 0, z: 0 } },
lookAt: { type: Object, default: null },
},
created: function created() {
var this$1 = this;
this.camera = new three.PerspectiveCamera(this.fov, this.aspect, this.near, this.far);
bindProp(this, 'position', this.camera);
if (this.lookAt) { this.camera.lookAt(this.lookAt.x, this.lookAt.y, this.lookAt.z); }
vue.watch(function () { return this$1.lookAt; }, function (v) { this$1.camera.lookAt(v.x, v.y, v.z); }, { deep: true });
['aspect', 'far', 'fov', 'near'].forEach(function (p) {
vue.watch(function () { return this$1[p]; }, function () {
this$1.camera[p] = this$1[p];
this$1.camera.updateProjectionMatrix();
});
});
this.three.camera = this.camera;
},
render: function render() { return []; },
__hmrId: 'PerspectiveCamera',
};
var Object3D = {
name: 'Object3D',
inject: ['three', 'scene', 'rendererComponent'],
props: {
position: { type: Object, default: { x: 0, y: 0, z: 0 } },
rotation: { type: Object, default: { x: 0, y: 0, z: 0 } },
scale: { type: Object, default: { x: 1, y: 1, z: 1 } },
lookAt: { type: Object, default: null },
},
// can't use setup because it will not be used in sub components
// setup() {},
unmounted: function unmounted() {
if (this._parent) { this._parent.remove(this.o3d); }
},
methods: {
initObject3D: function initObject3D(o3d) {
var this$1 = this;
this.o3d = o3d;
bindProp(this, 'position', this.o3d);
bindProp(this, 'rotation', this.o3d);
bindProp(this, 'scale', this.o3d);
// TODO : fix lookat.x
if (this.lookAt) { this.o3d.lookAt(this.lookAt.x, this.lookAt.y, this.lookAt.z); }
vue.watch(function () { return this$1.lookAt; }, function (v) { this$1.o3d.lookAt(v.x, v.y, v.z); }, { deep: true });
var parent = this.$parent;
while (parent) {
if (parent.add) {
parent.add(this.o3d);
this._parent = parent;
break;
}
parent = parent.$parent;
}
if (!this._parent) { console.error('Missing parent (Scene, Group...)'); }
},
add: function add(o) { this.o3d.add(o); },
remove: function remove(o) { this.o3d.remove(o); },
},
render: function render() {
return this.$slots.default ? this.$slots.default() : [];
},
__hmrId: 'Object3D',
};
var Group = {
name: 'Group',
extends: Object3D,
created: function created() {
this.group = new three.Group();
this.initObject3D(this.group);
},
__hmrId: 'Group',
};
var Scene = {
name: 'Scene',
inject: ['three'],
props: {
id: String,
background: [String, Number],
},
setup: function setup(props) {
var scene = new three.Scene();
if (props.background) { scene.background = new three.Color(props.background); }
vue.watch(function () { return props.background; }, function (value) { scene.background.set(value); });
return { scene: scene };
},
provide: function provide() {
return {
scene: this.scene,
};
},
mounted: function mounted() {
if (!this.three.scene) {
this.three.scene = this.scene;
}
},
methods: {
add: function add(o) { this.scene.add(o); },
remove: function remove(o) { this.scene.remove(o); },
},
render: function render() {
return this.$slots.default ? this.$slots.default() : [];
},
__hmrId: 'Scene',
};
var Geometry = {
inject: ['mesh'],
props: {
rotateX: Number,
rotateY: Number,
rotateZ: Number,
},
created: function created() {
var this$1 = this;
if (!this.mesh) {
console.error('Missing parent Mesh');
}
this.watchProps = [];
Object.entries(this.$props).forEach(function (e) { return this$1.watchProps.push(e[0]); });
this.createGeometry();
this.rotateGeometry();
this.mesh.setGeometry(this.geometry);
this.addWatchers();
},
unmounted: function unmounted() {
this.geometry.dispose();
},
methods: {
addWatchers: function addWatchers() {
var this$1 = this;
this.watchProps.forEach(function (prop) {
vue.watch(function () { return this$1[prop]; }, function () {
this$1.refreshGeometry();
});
});
},
rotateGeometry: function rotateGeometry() {
if (this.rotateX) { this.geometry.rotateX(this.rotateX); }
if (this.rotateY) { this.geometry.rotateY(this.rotateY); }
if (this.rotateZ) { this.geometry.rotateZ(this.rotateZ); }
},
refreshGeometry: function refreshGeometry() {
var oldGeo = this.geometry;
this.createGeometry();
this.rotateGeometry();
this.mesh.setGeometry(this.geometry);
oldGeo.dispose();
},
},
render: function render() { return []; },
};
var BoxGeometry = {
extends: Geometry,
props: {
size: Number,
width: { type: Number, default: 1 },
height: { type: Number, default: 1 },
depth: { type: Number, default: 1 },
widthSegments: { type: Number, default: 1 },
heightSegments: { type: Number, default: 1 },
depthSegments: { type: Number, default: 1 },
},
methods: {
createGeometry: function createGeometry() {
var w = this.width, h = this.height, d = this.depth;
if (this.size) {
w = this.size; h = this.size; d = this.size;
}
this.geometry = new three.BoxGeometry(w, h, d, this.widthSegments, this.heightSegments, this.depthSegments);
},
},
};
var CircleGeometry = {
extends: Geometry,
props: {
radius: { type: Number, default: 1 },
segments: { type: Number, default: 8 },
thetaStart: { type: Number, default: 0 },
thetaLength: { type: Number, default: Math.PI * 2 },
},
methods: {
createGeometry: function createGeometry() {
this.geometry = new three.CircleGeometry(this.radius, this.segments, this.thetaStart, this.thetaLength);
},
},
};
var ConeGeometry = {
extends: Geometry,
props: {
radius: { type: Number, default: 1 },
height: { type: Number, default: 1 },
radialSegments: { type: Number, default: 8 },
heightSegments: { type: Number, default: 1 },
openEnded: { type: Boolean, default: false },
thetaStart: { type: Number, default: 0 },
thetaLength: { type: Number, default: Math.PI * 2 },
},
methods: {
createGeometry: function createGeometry() {
this.geometry = new three.ConeGeometry(this.radius, this.height, this.radialSegments, this.heightSegments, this.openEnded, this.thetaStart, this.thetaLength);
},
},
};
var CylinderGeometry = {
extends: Geometry,
props: {
radiusTop: { type: Number, default: 1 },
radiusBottom: { type: Number, default: 1 },
height: { type: Number, default: 1 },
radialSegments: { type: Number, default: 8 },
heightSegments: { type: Number, default: 1 },
openEnded: { type: Boolean, default: false },
thetaStart: { type: Number, default: 0 },
thetaLength: { type: Number, default: Math.PI * 2 },
},
methods: {
createGeometry: function createGeometry() {
this.geometry = new three.CylinderGeometry(this.radiusTop, this.radiusBottom, this.height, this.radialSegments, this.heightSegments, this.openEnded, this.thetaStart, this.thetaLength);
},
},
};
var DodecahedronGeometry = {
extends: Geometry,
props: {
radius: { type: Number, default: 1 },
detail: { type: Number, default: 0 },
},
methods: {
createGeometry: function createGeometry() {
this.geometry = new three.DodecahedronGeometry(this.radius, this.detail);
},
},
};
var IcosahedronGeometry = {
extends: Geometry,
props: {
radius: { type: Number, default: 1 },
detail: { type: Number, default: 0 },
},
methods: {
createGeometry: function createGeometry() {
this.geometry = new three.IcosahedronGeometry(this.radius, this.detail);
},
},
};
var LatheGeometry = {
extends: Geometry,
props: {
points: Array,
segments: { type: Number, default: 12 },
phiStart: { type: Number, default: 0 },
phiLength: { type: Number, default: Math.PI * 2 },
},
methods: {
createGeometry: function createGeometry() {
this.geometry = new three.LatheGeometry(this.points, this.segments, this.phiStart, this.phiLength);
},
},
};
var OctahedronGeometry = {
extends: Geometry,
props: {
radius: { type: Number, default: 1 },
detail: { type: Number, default: 0 },
},
methods: {
createGeometry: function createGeometry() {
this.geometry = new three.OctahedronGeometry(this.radius, this.detail);
},
},
};
var PolyhedronGeometry = {
extends: Geometry,
props: {
vertices: Array,
indices: Array,
radius: { type: Number, default: 1 },
detail: { type: Number, default: 0 },
},
methods: {
createGeometry: function createGeometry() {
this.geometry = new three.PolyhedronGeometry(this.vertices, this.indices, this.radius, this.detail);
},
},
};
var RingGeometry = {
extends: Geometry,
props: {
innerRadius: { type: Number, default: 0.5 },
outerRadius: { type: Number, default: 1 },
thetaSegments: { type: Number, default: 8 },
phiSegments: { type: Number, default: 1 },
thetaStart: { type: Number, default: 0 },
thetaLength: { type: Number, default: Math.PI * 2 },
},
methods: {
createGeometry: function createGeometry() {
this.geometry = new three.RingGeometry(this.innerRadius, this.outerRadius, this.thetaSegments, this.phiSegments, this.thetaStart, this.thetaLength);
},
},
};
var SphereGeometry = {
extends: Geometry,
props: {
radius: { type: Number, default: 1 },
widthSegments: { type: Number, default: 12 },
heightSegments: { type: Number, default: 12 },
},
methods: {
createGeometry: function createGeometry() {
this.geometry = new three.SphereGeometry(this.radius, this.widthSegments, this.heightSegments);
},
},
};
var TetrahedronGeometry = {
extends: Geometry,
props: {
radius: { type: Number, default: 1 },
detail: { type: Number, default: 0 },
},
methods: {
createGeometry: function createGeometry() {
this.geometry = new three.TetrahedronGeometry(this.radius, this.detail);
},
},
};
var TorusGeometry = {
extends: Geometry,
props: {
radius: { type: Number, default: 1 },
tube: { type: Number, default: 0.4 },
radialSegments: { type: Number, default: 8 },
tubularSegments: { type: Number, default: 6 },
arc: { type: Number, default: Math.PI * 2 },
},
methods: {
createGeometry: function createGeometry() {
this.geometry = new three.TorusGeometry(this.radius, this.tube, this.radialSegments, this.tubularSegments, this.arc);
},
},
};
var TorusKnotGeometry = {
extends: Geometry,
props: {
radius: { type: Number, default: 1 },
tube: { type: Number, default: 0.4 },
tubularSegments: { type: Number, default: 64 },
radialSegments: { type: Number, default: 8 },
p: { type: Number, default: 2 },
q: { type: Number, default: 3 },
},
methods: {
createGeometry: function createGeometry() {
this.geometry = new three.TorusKnotGeometry(this.radius, this.tube, this.tubularSegments, this.radialSegments, this.p, this.q);
},
},
};
var TubeGeometry = {
extends: Geometry,
props: {
path: three.Curve,
tubularSegments: { type: Number, default: 64 },
radius: { type: Number, default: 1 },
radiusSegments: { type: Number, default: 8 },
closed: { type: Boolean, default: false },
},
methods: {
createGeometry: function createGeometry() {
this.geometry = new three.TubeGeometry(this.path, this.tubularSegments, this.radius, this.radiusSegments, this.closed);
},
},
};
var Light = {
extends: Object3D,
name: 'Light',
props: {
color: { type: String, default: '#ffffff' },
intensity: { type: Number, default: 1 },
castShadow: { type: Boolean, default: false },
shadowMapSize: { type: Object, default: { x: 512, y: 512 } },
shadowCamera: { type: Object, default: {} },
},
// can't use setup because it will not be used in sub components
// setup() {},
unmounted: function unmounted() {
if (this.light.target) { this.$parent.remove(this.light.target); }
},
methods: {
initLight: function initLight() {
var this$1 = this;
if (this.light.target) {
bindProp(this, 'target', this.light.target, 'position');
}
if (this.light.shadow) {
this.light.castShadow = this.castShadow;
setFromProp(this.light.shadow.mapSize, this.shadowMapSize);
setFromProp(this.light.shadow.camera, this.shadowCamera);
}
['color', 'intensity', 'castShadow'].forEach(function (p) {
vue.watch(function () { return this$1[p]; }, function () {
if (p === 'color') {
this$1.light.color.set(this$1.color);
} else {
this$1.light[p] = this$1[p];
}
});
});
this.initObject3D(this.light);
if (this.light.target) { this.$parent.add(this.light.target); }
},
},
__hmrId: 'Light',
};
var AmbientLight = {
extends: Light,
created: function created() {
this.light = new three.AmbientLight(this.color, this.intensity);
this.initLight();
},
__hmrId: 'AmbientLight',
};
var DirectionalLight = {
extends: Light,
props: {
target: Object,
},
created: function created() {
this.light = new three.DirectionalLight(this.color, this.intensity);
this.initLight();
},
__hmrId: 'DirectionalLight',
};
var HemisphereLight = {
extends: Light,
props: {
groundColor: { type: String, default: '#444444' },
},
created: function created() {
var this$1 = this;
this.light = new three.HemisphereLight(this.color, this.groundColor, this.intensity);
vue.watch(function () { return this$1.groundColor; }, function (value) { this$1.light.groundColor.set(value); });
this.initLight();
},
__hmrId: 'HemisphereLight',
};
var PointLight = {
extends: Light,
props: {
distance: {
type: Number,
default: 0,
},
decay: {
type: Number,
default: 1,
},
},
created: function created() {
this.light = new three.PointLight(this.color, this.intensity, this.distance, this.decay);
this.initLight();
},
__hmrId: 'PointLight',
};
var RectAreaLight = {
extends: Light,
props: {
width: { type: Number, default: 10 },
height: { type: Number, default: 10 },
helper: Boolean,
},
created: function created() {
var this$1 = this;
RectAreaLightUniformsLib_js.RectAreaLightUniformsLib.init();
this.light = new three.RectAreaLight(this.color, this.intensity, this.width, this.height);
['width', 'height'].forEach(function (p) {
vue.watch(function () { return this$1[p]; }, function () {
this$1.light[p] = this$1[p];
});
});
if (this.helper) {
this.lightHelper = new RectAreaLightHelper_js.RectAreaLightHelper(this.light);
this.$parent.add(this.lightHelper);
}
this.initLight();
},
unmounted: function unmounted() {
if (this.lightHelper) { this.$parent.remove(this.lightHelper); }
},
__hmrId: 'RectAreaLight',
};
var SpotLight = {
extends: Light,
props: {
angle: { type: Number, default: Math.PI / 3 },
decay: { type: Number, default: 1 },
distance: { type: Number, default: 0 },
penumbra: { type: Number, default: 0 },
target: Object,
},
created: function created() {
var this$1 = this;
this.light = new three.SpotLight(this.color, this.intensity, this.distance, this.angle, this.penumbra, this.decay);
['angle', 'decay', 'distance', 'penumbra'].forEach(function (p) {
vue.watch(function () { return this$1[p]; }, function () {
this$1.light[p] = this$1[p];
});
});
this.initLight();
},
__hmrId: 'SpotLight',
};
var Material = {
inject: ['three', 'mesh'],
props: {
color: { type: [String, Number], default: '#ffffff' },
depthTest: { type: Boolean, default: true },
depthWrite: { type: Boolean, default: true },
fog: { type: Boolean, default: true },
opacity: { type: Number, default: 1 },
side: { type: Number, default: three.FrontSide },
transparent: Boolean,
vertexColors: Boolean,
},
provide: function provide() {
return {
material: this,
};
},
created: function created() {
this.createMaterial();
this.mesh.setMaterial(this.material);
this._addWatchers();
if (this.addWatchers) { this.addWatchers(); }
},
unmounted: function unmounted() {
this.material.dispose();
},
methods: {
setProp: function setProp(key, value, needsUpdate) {
if ( needsUpdate === void 0 ) needsUpdate = false;
this.material[key] = value;
this.material.needsUpdate = needsUpdate;
},
setTexture: function setTexture(texture, key) {
if ( key === void 0 ) key = 'map';
this.setProp(key, texture, true);
},
_addWatchers: function _addWatchers() {
var this$1 = this;
['color', 'depthTest', 'depthWrite', 'fog', 'opacity', 'side', 'transparent'].forEach(function (p) {
vue.watch(function () { return this$1[p]; }, function () {
if (p === 'color') {
this$1.material.color.set(this$1.color);
} else {
this$1.material[p] = this$1[p];
}
});
});
},
},
render: function render() {
return this.$slots.default ? this.$slots.default() : [];
},
__hmrId: 'Material',
};
var wireframeProps = {
wireframe: { type: Boolean, default: false },
// not needed for WebGL
// wireframeLinecap: { type: String, default: 'round' },
// wireframeLinejoin: { type: String, default: 'round' },
wireframeLinewidth: { type: Number, default: 1 }, // not really useful
};
var BasicMaterial = {
extends: Material,
props: Object.assign({}, wireframeProps),
methods: {
createMaterial: function createMaterial() {
this.material = new three.MeshBasicMaterial(propsValues(this.$props));
},
addWatchers: function addWatchers() {
bindProps(this, Object.keys(wireframeProps), this.material);
},
},
__hmrId: 'BasicMaterial',
};
var LambertMaterial = {
extends: Material,
props: Object.assign({}, wireframeProps),
methods: {
createMaterial: function createMaterial() {
this.material = new three.MeshLambertMaterial(propsValues(this.$props));
},
addWatchers: function addWatchers() {
bindProps(this, Object.keys(wireframeProps), this.material);
},
},
__hmrId: 'LambertMaterial',
};
var MatcapMaterial = {
extends: Material,
props: {
src: String,
name: String,
flatShading: Boolean,
},
methods: {
createMaterial: function createMaterial() {
var src = this.name ? getMatcapUrl(this.name) : this.src;
var opts = propsValues(this.$props, ['src', 'name']);
opts.matcap = new three.TextureLoader().load(src);
this.material = new three.MeshMatcapMaterial(opts);
},
addWatchers: function addWatchers() {
// TODO
},
},
__hmrId: 'MatcapMaterial',
};
var PhongMaterial = {
extends: Material,
props: Object.assign({}, {emissive: { type: [Number, String], default: 0 },
emissiveIntensity: { type: Number, default: 1 },
reflectivity: { type: Number, default: 1 },
shininess: { type: Number, default: 30 },
specular: { type: [String, Number], default: 0x111111 },
flatShading: Boolean},
wireframeProps),
methods: {
createMaterial: function createMaterial() {
this.material = new three.MeshPhongMaterial(propsValues(this.$props));
},
addWatchers: function addWatchers() {
var this$1 = this;
// TODO : handle flatShading ?
['emissive', 'emissiveIntensity', 'reflectivity', 'shininess', 'specular'].forEach(function (p) {
vue.watch(function () { return this$1[p]; }, function (value) {
if (p === 'emissive' || p === 'specular') {
this$1.material[p].set(value);
} else {
this$1.material[p] = value;
}
});
});
bindProps(this, Object.keys(wireframeProps), this.material);
},
},
__hmrId: 'PhongMaterial',
};
var props = {
aoMapIntensity: { type: Number, default: 1 },
bumpScale: { type: Number, default: 1 },
displacementBias: { type: Number, default: 0 },
displacementScale: { type: Number, default: 1 },
emissive: { type: [Number, String], default: 0 },
emissiveIntensity: { type: Number, default: 1 },
envMapIntensity: { type: Number, default: 1 },
lightMapIntensity: { type: Number, default: 1 },
metalness: { type: Number, default: 0 },
normalScale: { type: Object, default: { x: 1, y: 1 } },
roughness: { type: Number, default: 1 },
refractionRatio: { type: Number, default: 0.98 },
flatShading: Boolean,
};
var StandardMaterial = {
extends: Material,
props: Object.assign({}, props,
wireframeProps),
methods: {
createMaterial: function createMaterial() {
this.material = new three.MeshStandardMaterial(propsValues(this.$props, ['normalScale']));
},
addWatchers: function addWatchers() {
var this$1 = this;
// TODO : use setProp, handle flatShading ?
Object.keys(props).forEach(function (p) {
if (p === 'normalScale') { return; }
vue.watch(function () { return this$1[p]; }, function (value) {
if (p === 'emissive') {
this$1.material[p].set(value);
} else {
this$1.material[p] = value;
}
});
});
bindProp(this, 'normalScale', this.material);
bindProps(this, Object.keys(wireframeProps), this.material);
},
},
__hmrId: 'StandardMaterial',
};
var PhysicalMaterial = {
extends: StandardMaterial,
props: {
flatShading: Boolean,
},
methods: {
createMaterial: function createMaterial() {
this.material = new three.MeshPhysicalMaterial(propsValues(this.$props));
},
addWatchers: function addWatchers() {
// TODO
},
},
__hmrId: 'PhysicalMaterial',
};
var ShaderMaterial = {
inject: ['three', 'mesh'],
props: {
uniforms: { type: Object, default: function () { return {}; } },
vertexShader: { type: String, default: defaultVertexShader },
fragmentShader: { type: String, default: defaultFragmentShader },
},
created: function created() {
var this$1 = this;
this.createMaterial();
['vertexShader', 'fragmentShader'].forEach(function (p) {
vue.watch(function () { return this$1[p]; }, function () {
// recreate material if we change either shader
this$1.material.dispose();
this$1.createMaterial();
});
});
},
unmounted: function unmounted() {
this.material.dispose();
},
methods: {
createMaterial: function createMaterial() {
this.material = new three.ShaderMaterial(propsValues(this.$props));
this.mesh.setMaterial(this.material);
},
},
render: function render() {
return [];
},
__hmrId: 'ShaderMaterial',
};
/**
* ------------------------------------------------------------------------------------------
* Subsurface Scattering shader
* Based on three/examples/jsm/shaders/SubsurfaceScatteringShader.js
* Based on GDC 2011 Approximating Translucency for a Fast, Cheap and Convincing Subsurface Scattering Look
* https://colinbarrebrisebois.com/2011/03/07/gdc-2011-approximating-translucency-for-a-fast-cheap-and-convincing-subsurface-scattering-look/
*------------------------------------------------------------------------------------------
*/
function replaceAll(string, find, replace) {
return string.split(find).join(replace);
}
var meshphongFragHead = three.ShaderChunk.meshphong_frag.slice(0, three.ShaderChunk.meshphong_frag.indexOf('void main() {'));
var meshphongFragBody = three.ShaderChunk.meshphong_frag.slice(three.ShaderChunk.meshphong_frag.indexOf('void main() {'));
var SubsurfaceScatteringShader = {
uniforms: three.UniformsUtils.merge([
three.ShaderLib.phong.uniforms,
{
thicknessColor: { value: new three.Color(0xffffff) },
thicknessDistortion: { value: 0.1 },
thicknessAmbient: { value: 0.0 },
thicknessAttenuation: { value: 0.1 },
thicknessPower: { value: 2.0 },
thicknessScale: { value: 10.0 },
} ]),
vertexShader: ("\n #define USE_UV\n " + (three.ShaderChunk.meshphong_vert) + "\n "),
fragmentShader: "\n #define USE_UV\n #define SUBSURFACE\n\n " + meshphongFragHead + "\n\n uniform float thicknessPower;\n uniform float thicknessScale;\n uniform float thicknessDistortion;\n uniform float thicknessAmbient;\n uniform float thicknessAttenuation;\n uniform vec3 thicknessColor;\n\n void RE_Direct_Scattering(const in IncidentLight directLight, const in vec2 uv, const in GeometricContext geometry, inout ReflectedLight reflectedLight) {\n #ifdef USE_COLOR\n vec3 thickness = vColor * thicknessColor;\n #else\n vec3 thickness = thicknessColor;\n #endif\n vec3 scatteringHalf = normalize(directLight.direction + (geometry.normal * thicknessDistortion));\n float scatteringDot = pow(saturate(dot(geometry.viewDir, -scatteringHalf)), thicknessPower) * thicknessScale;\n vec3 scatteringIllu = (scatteringDot + thicknessAmbient) * thickness;\n reflectedLight.directDiffuse += scatteringIllu * thicknessAttenuation * directLight.color;\n }\n " + meshphongFragBody.replace(
'#include <lights_fragment_begin>',
replaceAll(
three.ShaderChunk.lights_fragment_begin,
'RE_Direct( directLight, geometry, material, reflectedLight );',
"\n RE_Direct( directLight, geometry, material, reflectedLight );\n #if defined( SUBSURFACE ) && defined( USE_UV )\n RE_Direct_Scattering(directLight, vUv, geometry, reflectedLight);\n #endif\n "
)
),
};
var SubSurfaceMaterial = {
inject: ['three', 'mesh'],
props: {
color: { type: String, default: '#ffffff' },
thicknessColor: { type: String, default: '#ffffff' },
thicknessDistortion: { type: Number, default: 0.4 },
thicknessAmbient: { type: Number, default: 0.01 },
thicknessAttenuation: { type: Number, default: 0.7 },
thicknessPower: { type: Number, default: 2 },
thicknessScale: { type: Number, default: 4 },
transparent: { type: Boolean, default: false },
opacity: { type: Number, default: 1 },
vertexColors: { type: Boolean, default: false },
},
created: function created() {
this.createMaterial();
this.mesh.setMaterial(this.material);
},
unmounted: function unmounted() {
this.material.dispose();
},
methods: {
createMaterial: function createMaterial() {
var params = SubsurfaceScatteringShader;
var uniforms = three.UniformsUtils.clone(params.uniforms);
Object.entries(this.$props).forEach(function (ref) {
var key = ref[0];
var value = ref[1];
var _key = key, _value = value;
if (['color', 'thicknessColor'].includes(key)) {
if (key === 'color') { _key = 'diffuse'; }
_value = new three.Color(value);
}
if (!['transparent', 'vertexColors'].includes(key)) {
uniforms[_key].value = _value;
}
});
this.material = new three.ShaderMaterial(Object.assign({}, params,
{uniforms: uniforms,
lights: true,
transparent: this.transparent,
vertexColors: this.vertexColors}));
},
},
render: function render() {
return [];
},
__hmrId: 'SubSurfaceMaterial',
};
var ToonMaterial = {
extends: Material,
props: Object.assign({}, wireframeProps),
methods: {
createMaterial: function createMaterial() {
this.material = new three.MeshToonMaterial(propsValues(this.$props));
},
addWatchers: function addWatchers() {
bindProps(this, Object.keys(wireframeProps), this.material);
},
},
__hmrId: 'ToonMaterial',
};
var Texture = {
inject: ['material'],
emits: ['loaded'],
props: {
id: { type: String, default: 'map' },
src: String,
onLoad: Function,
onProgress: Function,
onError: Function,
mapping: { type: Number, default: three.UVMapping },
wrapS: { type: Number, default: three.ClampToEdgeWrapping },
wrapT: { type: Number, default: three.ClampToEdgeWrapping },
magFilter: { type: Number, default: three.LinearFilter },
minFilter: { type: Number, default: three.LinearMipmapLinearFilter },
repeat: { type: Object, default: { x: 1, y: 1 } },
rotation: { type: Number, default: 0 },
center: { type: Object, default: { x: 0, y: 0 } },
},
created: function created() {
var this$1 = this;
this.refreshTexture();
vue.watch(function () { return this$1.src; }, this.refreshTexture);
},
unmounted: function unmounted() {
this.material.setTexture(null, this.id);
this.texture.dispose();
},
methods: {
createTexture: function createTexture() {
var this$1 = this;
this.texture = new three.TextureLoader().load(this.src, this.onLoaded, this.onProgress, this.onError);
var wathProps = ['mapping', 'wrapS', 'wrapT', 'magFilter', 'minFilter', 'repeat', 'rotation', 'rotation', 'center'];
wathProps.forEach(function (prop) {
bindProp(this$1, prop, this$1.texture);
});
},
refreshTexture: function refreshTexture() {
this.createTexture();
this.material.setTexture(this.texture, this.id);
},
onLoaded: function onLoaded() {
if (this.onLoad) { this.onLoad(); }
this.$emit('loaded');
},
},
render: function render() { return []; },
};
var CubeTexture = {
inject: ['material'],
emits: ['loaded'],
props: {
path: String,
urls: {
type: Array,
default: ['px.jpg', 'nx.jpg', 'py.jpg', 'ny.jpg', 'pz.jpg', 'nz.jpg'],
},
onLoad: Function,
onProgress: Function,
onError: Function,
id: { type: String, default: 'envMap' },
refraction: Boolean,
// todo: remove ?
refractionRatio: { type: Number, default: 0.98 },
},
created: function created() {
var this$1 = this;
this.refreshTexture();
vue.watch(function () { return this$1.path; }, this.refreshTexture);
vue.watch(function () { return this$1.urls; }, this.refreshTexture);
},
unmounted: function unmounted() {
this.material.setTexture(null, this.id);
this.texture.dispose();
},
methods: {
createTexture: function createTexture() {
this.texture = new three.CubeTextureLoader()
.setPath(this.path)
.load(this.urls, this.onLoaded, this.onProgress, this.onError);
},
refreshTexture: function refreshTexture() {
this.createTexture();
this.material.setTexture(this.texture, this.id);
if (this.refraction) {
this.texture.mapping = three.CubeRefractionMapping;
this.material.setProp('refractionRatio', this.refractionRatio);
}
},
onLoaded: function onLoaded() {
if (this.onLoad) { this.onLoad(); }
this.$emit('loaded');
},
},
render: function render() {
return [];
},
};
var Mesh = {
extends: Object3D,
name: 'Mesh',
props: {
castShadow: Boolean,
receiveShadow: Boolean,
onHover: Function,
onClick: Function,
},
// can't use setup because it will not be used in sub components
// setup() {},
provide: function provide() {
return {
mesh: this,
};
},
mounted: function mounted() {
if (!this.mesh && !this.loading) { this.initMesh(); }
},
methods: {
initMesh: function initMesh() {
var this$1 = this;
this.mesh = new three.Mesh(this.geometry, this.material);
['castShadow', 'receiveShadow'].forEach(function (p) {
this$1.mesh[p] = this$1[p];
vue.watch(function () { return this$1[p]; }, function () { this$1.mesh[p] = this$1[p]; });
});
if (this.onHover) {
this.mesh.onHover = function (over) { this$1.onHover({ component: this$1, over: over }); };
this.three.addIntersectObject(this.mesh);
}
if (this.onClick) {
this.mesh.onClick = function (e) { this$1.onClick({ component: this$1, event: e }); };
this.three.addIntersectObject(this.mesh);
}
this.initObject3D(this.mesh);
},
setGeometry: function setGeometry(geometry) {
this.geometry = geometry;
if (this.mesh) { this.mesh.geometry = geometry; }
},
setMaterial: function setMaterial(material) {
this.material = material;
if (this.mesh) { this.mesh.material = material; }
},
refreshGeometry: function refreshGeometry() {
var oldGeo = this.geometry;
this.createGeometry();
this.mesh.geometry = this.geometry;
oldGeo.dispose();
},
},
unmounted: function unmounted() {
if (this.mesh) {
this.three.removeIntersectObject(this.mesh);
}
// for predefined mesh (geometry and material are not unmounted)
if (this.geometry) { this.geometry.dispose(); }
if (this.material) { this.material.dispose(); }
},
__hmrId: 'Mesh',
};
var Box = {
extends: Mesh,
props: {
size: Number,
width: { type: Number, default: 1 },
height: { type: Number, default: 1 },
depth: { type: Number, default: 1 },
widthSegments: { type: Number, default: 1 },
heightSegments: { type: Number, default: 1 },
depthSegments: { type: Number, default: 1 },
},
created: function created() {
var this$1 = this;
this.createGeometry();
['size', 'width', 'height', 'depth', 'widthSegments', 'heightSegments', 'depthSegments'].forEach(function (prop) {
vue.watch(function () { return this$1[prop]; }, function () {
this$1.refreshGeometry();
});
});
},
methods: {
createGeometry: function createGeometry() {
if (this.size) {
this.geometry = new three.BoxBufferGeometry(this.size, this.size, this.size);
} else {
this.geometry = new three.BoxBufferGeometry(this.width, this.height, this.depth);
}
},
},
__hmrId: 'Box',
};
var Circle = {
extends: Mesh,
props: {
radius: { type: Number, default: 1 },
segments: { type: Number, default: 8 },
thetaStart: { type: Number, default: 0 },
thetaLength: { type: Number, default: Math.PI * 2 },
},
created: function created() {
var this$1 = this;
this.createGeometry();
var watchProps = ['radius', 'segments', 'thetaStart', 'thetaLength'];
watchProps.forEach(function (prop) {
vue.watch(function () { return this$1[prop]; }, function () {
this$1.refreshGeometry();
});
});
},
methods: {
createGeometry: function createGeometry() {
this.geometry = new three.CircleBufferGeometry(this.radius, this.segments, this.thetaStart, this.thetaLength);
},
},
__hmrId: 'Circle',
};
var Cone = {
extends: Mesh,
props: {
radius: { type: Number, default: 1 },
height: { type: Number, default: 1 },
radialSegments: { type: Number, default: 8 },
heightSegments: { type: Number, default: 1 },
openEnded: { type: Boolean, default: false },
thetaStart: { type: Number, default: 0 },
thetaLength: { type: Number, default: Math.PI * 2 },
},
created: function created() {
var this$1 = this;
this.createGeometry();
var watchProps = ['radius', 'height', 'radialSegments', 'heightSegments', 'openEnded', 'thetaStart', 'thetaLength'];
watchProps.forEach(function (prop) {
vue.watch(function () { return this$1[prop]; }, function () {
this$1.refreshGeometry();
});
});
},
methods: {
createGeometry: function createGeometry() {
this.geometry = new three.ConeBufferGeometry(this.radius, this.height, this.radialSegments, this.heightSegments, this.openEnded, this.thetaStart, this.thetaLength);
},
},
__hmrId: 'Cone',
};
var Cylinder = {
extends: Mesh,
props: {
radiusTop: { type: Number, default: 1 },
radiusBottom: { type: Number, default: 1 },
height: { type: Number, default: 1 },
radialSegments: { type: Number, default: 8 },
heightSegments: { type: Number, default: 1 },
openEnded: { type: Boolean, default: false },
thetaStart: { type: Number, default: 0 },
thetaLength: { type: Number, default: Math.PI * 2 },
},
created: function created() {
var this$1 = this;
this.createGeometry();
var watchProps = ['radiusTop', 'radiusBottom', 'height', 'radialSegments', 'heightSegments', 'openEnded', 'thetaStart', 'thetaLength'];
watchProps.forEach(function (prop) {
vue.watch(function () { return this$1[prop]; }, function () {
this$1.refreshGeometry();
});
});
},
methods: {
createGeometry: function createGeometry() {
this.geometry = new three.CylinderBufferGeometry(this.radiusTop, this.radiusBottom, this.height, this.radialSegments, this.heightSegments, this.openEnded, this.thetaStart, this.thetaLength);
},
},
__hmrId: 'Cylinder',
};
var Dodecahedron = {
extends: Mesh,
props: {
radius: { type: Number, default: 1 },
detail: { type: Number, default: 0 },
},
created: function created() {
var this$1 = this;
this.createGeometry();
var watchProps = ['radius', 'detail'];
watchProps.forEach(function (prop) {
vue.watch(function () { return this$1[prop]; }, function () {
this$1.refreshGeometry();
});
});
},
methods: {
createGeometry: function createGeometry() {
this.geometry = new three.DodecahedronBufferGeometry(this.radius, this.detail);
},
},
__hmrId: 'Dodecahedron',
};
var Icosahedron = {
extends: Mesh,
props: {
radius: { type: Number, default: 1 },
detail: { type: Number, default: 0 },
},
created: function created() {
var this$1 = this;
this.createGeometry();
var watchProps = ['radius', 'detail'];
watchProps.forEach(function (prop) {
vue.watch(function () { return this$1[prop]; }, function () {
this$1.refreshGeometry();
});
});
},
methods: {
createGeometry: function createGeometry() {
this.geometry = new three.IcosahedronBufferGeometry(this.radius, this.detail);
},
},
__hmrId: 'Icosahedron',
};
var Lathe = {
extends: Mesh,
props: {
points: Array,
segments: { type: Number, default: 12 },
phiStart: { type: Number, default: 0 },
phiLength: { type: Number, default: Math.PI * 2 },
},
created: function created() {
var this$1 = this;
this.createGeometry();
var watchProps = ['points', 'segments', 'phiStart', 'phiLength'];
watchProps.forEach(function (prop) {
vue.watch(function () { return this$1[prop]; }, function () {
this$1.refreshGeometry();
});
});
},
methods: {
createGeometry: function createGeometry() {
this.geometry = new three.LatheBufferGeometry(this.points, this.segments, this.phiStart, this.phiLength);
},
},
__hmrId: 'Lathe',
};
var Octahedron = {
extends: Mesh,
props: {
radius: { type: Number, default: 1 },
detail: { type: Number, default: 0 },
},
created: function created() {
var this$1 = this;
this.createGeometry();
var watchProps = ['radius', 'detail'];
watchProps.forEach(function (prop) {
vue.watch(function () { return this$1[prop]; }, function () {
this$1.refreshGeometry();
});
});
},
methods: {
createGeometry: function createGeometry() {
this.geometry = new three.OctahedronBufferGeometry(this.radius, this.detail);
},
},
__hmrId: 'Octahedron',
};
var Plane = {
extends: Mesh,
props: {
width: { type: Number, default: 1 },
height: { type: Number, default: 1 },
widthSegments: { type: Number, default: 1 },
heightSegments: { type: Number, default: 1 },
},
created: function created() {
var this$1 = this;
this.createGeometry();
var watchProps = ['width', 'height', 'widthSegments', 'heightSegments'];
watchProps.forEach(function (prop) {
vue.watch(function () { return this$1[prop]; }, function () {
this$1.refreshGeometry();
});
});
},
methods: {
createGeometry: function createGeometry() {
this.geometry = new three.PlaneBufferGeometry(this.width, this.height, this.widthSegments, this.heightSegments);
},
},
__hmrId: 'Plane',
};
var Polyhedron = {
extends: Mesh,
props: {
vertices: Array,
indices: Array,
radius: { type: Number, default: 1 },
detail: { type: Number, default: 0 },
},
created: function created() {
var this$1 = this;
this.createGeometry();
var watchProps = ['vertices', 'indices', 'radius', 'detail'];
watchProps.forEach(function (prop) {
vue.watch(function () { return this$1[prop]; }, function () {
this$1.refreshGeometry();
});
});
},
methods: {
createGeometry: function createGeometry() {
this.geometry = new three.PolyhedronBufferGeometry(this.vertices, this.indices, this.radius, this.detail);
},
},
__hmrId: 'Polyhedron',
};
var Ring = {
extends: Mesh,
props: {
innerRadius: { type: Number, default: 0.5 },
outerRadius: { type: Number, default: 1 },
thetaSegments: { type: Number, default: 8 },
phiSegments: { type: Number, default: 1 },
thetaStart: { type: Number, default: 0 },
thetaLength: { type: Number, default: Math.PI * 2 },
},
created: function created() {
var this$1 = this;
this.createGeometry();
var watchProps = ['innerRadius', 'outerRadius', 'thetaSegments', 'phiSegments', 'thetaStart', 'thetaLength'];
watchProps.forEach(function (prop) {
vue.watch(function () { return this$1[prop]; }, function () {
this$1.refreshGeometry();
});
});
},
methods: {
createGeometry: function createGeometry() {
this.geometry = new three.RingBufferGeometry(this.innerRadius, this.outerRadius, this.thetaSegments, this.phiSegments, this.thetaStart, this.thetaLength);
},
},
__hmrId: 'Ring',
};
var Sphere = {
extends: Mesh,
props: {
radius: Number,
widthSegments: { type: Number, default: 12 },
heightSegments: { type: Number, default: 12 },
},
watch: {
radius: function radius() { this.refreshGeometry(); },
widthSegments: function widthSegments() { this.refreshGeometry(); },
heightSegments: function heightSegments() { this.refreshGeometry(); },
},
created: function created() {
this.createGeometry();
},
methods: {
createGeometry: function createGeometry() {
this.geometry = new three.SphereBufferGeometry(this.radius, this.widthSegments, this.heightSegments);
},
},
__hmrId: 'Sphere',
};
var Tetrahedron = {
extends: Mesh,
props: {
radius: { type: Number, default: 1 },
detail: { type: Number, default: 0 },
},
created: function created() {
var this$1 = this;
this.createGeometry();
var watchProps = ['radius', 'detail'];
watchProps.forEach(function (prop) {
vue.watch(function () { return this$1[prop]; }, function () {
this$1.refreshGeometry();
});
});
},
methods: {
createGeometry: function createGeometry() {
this.geometry = new three.TetrahedronBufferGeometry(this.radius, this.detail);
},
},
__hmrId: 'Tetrahedron',
};
var TextProps = {
text: String,
fontSrc: String,
size: { type: Number, default: 80 },
height: { type: Number, default: 5 },
depth: { type: Number, default: 1 },
curveSegments: { type: Number, default: 12 },
bevelEnabled: { type: Boolean, default: false },
bevelThickness: { type: Number, default: 10 },
bevelSize: { type: Number, default: 8 },
bevelOffset: { type: Number, default: 0 },
bevelSegments: { type: Number, default: 5 },
align: { type: [Boolean, String], default: false },
};
var Text = {
extends: Mesh,
props: Object.assign({}, TextProps),
data: function data() {
return {
loading: true,
};
},
created: function created() {
var this$1 = this;
// add watchers
var watchProps = [
'text', 'size', 'height', 'curveSegments',
'bevelEnabled', 'bevelThickness', 'bevelSize', 'bevelOffset', 'bevelSegments',
'align' ];
watchProps.forEach(function (p) {
vue.watch(function () { return this$1[p]; }, function () {
if (this$1.font) { this$1.refreshGeometry(); }
});
});
var loader = new three.FontLoader();
loader.load(this.fontSrc, function (font) {
this$1.loading = false;
this$1.font = font;
this$1.createGeometry();
this$1.initMesh();
});
},
methods: {
createGeometry: function createGeometry() {
this.geometry = new three.TextBufferGeometry(this.text, {
font: this.font,
size: this.size,
height: this.height,
depth: this.depth,
curveSegments: this.curveSegments,
bevelEnabled: this.bevelEnabled,
bevelThickness: this.bevelThickness,
bevelSize: this.bevelSize,
bevelOffset: this.bevelOffset,
bevelSegments: this.bevelSegments,
});
if (this.align === 'center') {
this.geometry.center();
}
},
},
};
var Torus = {
extends: Mesh,
props: {
radius: { type: Number, default: 0.5 },
tube: { type: Number, default: 0.4 },
radialSegments: { type: Number, default: 8 },
tubularSegments: { type: Number, default: 6 },
arc: { type: Number, default: Math.PI * 2 },
},
created: function created() {
var this$1 = this;
this.createGeometry();
var watchProps = ['radius', 'tube', 'radialSegments', 'tubularSegments', 'arc'];
watchProps.forEach(function (prop) {
vue.watch(function () { return this$1[prop]; }, function () {
this$1.refreshGeometry();
});
});
},
methods: {
createGeometry: function createGeometry() {
this.geometry = new three.TorusBufferGeometry(this.radius, this.tube, this.radialSegments, this.tubularSegments, this.arc);
},
},
__hmrId: 'Torus',
};
var TorusKnot = {
extends: Mesh,
props: {
radius: { type: Number, default: 0.5 },
tube: { type: Number, default: 0.4 },
tubularSegments: { type: Number, default: 64 },
radialSegments: { type: Number, default: 8 },
p: { type: Number, default: 2 },
q: { type: Number, default: 3 },
},
created: function created() {
var this$1 = this;
this.createGeometry();
var watchProps = ['radius', 'tube', 'radialSegments', 'tubularSegments', 'p', 'q'];
watchProps.forEach(function (prop) {
vue.watch(function () { return this$1[prop]; }, function () {
this$1.refreshGeometry();
});
});
},
methods: {
createGeometry: function createGeometry() {
this.geometry = new three.TorusKnotBufferGeometry(this.radius, this.tube, this.tubularSegments, this.radialSegments, this.p, this.q);
},
},
__hmrId: 'TorusKnot',
};
var Tube = {
extends: Mesh,
props: {
path: three.Curve,
points: Array,
tubularSegments: { type: Number, default: 64 },
radius: { type: Number, default: 1 },
radialSegments: { type: Number, default: 8 },
closed: { type: Boolean, default: false },
},
created: function created() {
var this$1 = this;
this.createGeometry();
var watchProps = ['tubularSegments', 'radius', 'radialSegments', 'closed'];
watchProps.forEach(function (prop) {
vue.watch(function () { return this$1[prop]; }, function (v) {
this$1.refreshGeometry();
});
});
vue.watch(function () { return this$1.points; }, function () {
updateTubeGeometryPoints(this$1.geometry, this$1.points);
});
},
methods: {
createGeometry: function createGeometry() {
var curve;
if (this.points) {
curve = new three.CatmullRomCurve3(this.points);
} else if (this.path) {
curve = this.path;
} else {
console.error('Missing path curve or points.');
}
this.geometry = new three.TubeGeometry(curve, this.tubularSegments, this.radius, this.radialSegments, this.closed);
},
// update curve points (without using prop, faster)
updateCurve: function updateCurve(points) {
updateTubeGeometryPoints(this.geometry, points);
},
},
__hmrId: 'Tube',
};
function updateTubeGeometryPoints(tube, points) {
var curve = new three.CatmullRomCurve3(points);
var ref = tube.parameters;
var radialSegments = ref.radialSegments;
var radius = ref.radius;
var tubularSegments = ref.tubularSegments;
var closed = ref.closed;
var frames = curve.computeFrenetFrames(tubularSegments, closed);
tube.tangents = frames.tangents;
tube.normals = frames.normals;
tube.binormals = frames.binormals;
tube.parameters.path = curve;
var pArray = tube.attributes.position.array;
var nArray = tube.attributes.normal.array;
var normal = new three.Vector3();
var P;
for (var i = 0; i < tubularSegments; i++) {
updateSegment(i);
}
updateSegment(tubularSegments);
tube.attributes.position.needsUpdate = true;
tube.attributes.normal.needsUpdate = true;
function updateSegment(i) {
P = curve.getPointAt(i / tubularSegments, P);
var N = frames.normals[i];
var B = frames.binormals[i];
for (var j = 0; j <= radialSegments; j++) {
var v = j / radialSegments * Math.PI * 2;
var sin = Math.sin(v);
var cos = -Math.cos(v);
normal.x = (cos * N.x + sin * B.x);
normal.y = (cos * N.y + sin * B.y);
normal.z = (cos * N.z + sin * B.z);
normal.normalize();
var index = (i * (radialSegments + 1) + j) * 3;
nArray[index] = normal.x;
nArray[index + 1] = normal.y;
nArray[index + 2] = normal.z;
pArray[index] = P.x + radius * normal.x;
pArray[index + 1] = P.y + radius * normal.y;
pArray[index + 2] = P.z + radius * normal.z;
}
}
}
var Gem = {
extends: Mesh,
props: {
cubeRTSize: { type: Number, default: 256 },
cubeCameraNear: { type: Number, default: 0.1 },
cubeCameraFar: { type: Number, default: 2000 },
autoUpdate: Boolean,
},
mounted: function mounted() {
this.initGem();
if (this.autoUpdate) { this.three.onBeforeRender(this.updateCubeRT); }
else { this.rendererComponent.onMounted(this.updateCubeRT); }
},
unmounted: function unmounted() {
this.three.offBeforeRender(this.updateCubeRT);
if (this.meshBack) { this.$parent.remove(this.meshBack); }
if (this.materialBack) { this.materialBack.dispose(); }
},
methods: {
initGem: function initGem() {
var cubeRT = new three.WebGLCubeRenderTarget(this.cubeRTSize, { format: three.RGBFormat, generateMipmaps: true, minFilter: three.LinearMipmapLinearFilter });
this.cubeCamera = new three.CubeCamera(this.cubeCameraNear, this.cubeCameraFar, cubeRT);
bindProp(this, 'position', this.cubeCamera);
this.$parent.add(this.cubeCamera);
this.material.side = three.FrontSide;
this.material.envMap = cubeRT.texture;
this.material.envMapIntensity = 10;
this.material.metalness = 0;
this.material.roughness = 0;
this.material.opacity = 0.75;
this.material.transparent = true;
this.material.premultipliedAlpha = true;
this.material.needsUpdate = true;
this.materialBack = this.material.clone();
this.materialBack.side = three.BackSide;
this.materialBack.envMapIntensity = 5;
this.materialBack.metalness = 1;
this.materialBack.roughness = 0;
this.materialBack.opacity = 0.5;
this.meshBack = new three.Mesh(this.geometry, this.materialBack);
bindProp(this, 'position', this.meshBack);
bindProp(this, 'rotation', this.meshBack);
bindProp(this, 'scale', this.meshBack);
this.$parent.add(this.meshBack);
},
updateCubeRT: function updateCubeRT() {
this.mesh.visible = false;
this.meshBack.visible = false;
this.cubeCamera.update(this.three.renderer, this.scene);
this.mesh.visible = true;
this.meshBack.visible = true;
},
},
__hmrId: 'Gem',
};
var Image = {
emits: ['loaded'],
extends: Mesh,
props: {
src: String,
width: Number,
height: Number,
keepSize: Boolean,
},
created: function created() {
var this$1 = this;
this.createGeometry();
this.createMaterial();
this.initMesh();
vue.watch(function () { return this$1.src; }, this.refreshTexture);
['width', 'height'].forEach(function (p) {
vue.watch(function () { return this$1[p]; }, this$1.resize);
});
if (this.keepSize) { this.three.onAfterResize(this.resize); }
},
methods: {
createGeometry: function createGeometry() {
this.geometry = new three.PlaneBufferGeometry(1, 1, 1, 1);
},
createMaterial: function createMaterial() {
this.material = new three.MeshBasicMaterial({ side: three.DoubleSide, map: this.loadTexture() });
},
loadTexture: function loadTexture() {
return new three.TextureLoader().load(this.src, this.onLoaded);
},
refreshTexture: function refreshTexture() {
if (this.texture) { this.texture.dispose(); }
this.material.map = this.loadTexture();
this.material.needsUpdate = true;
},
onLoaded: function onLoaded(texture) {
this.texture = texture;
this.resize();
this.$emit('loaded');
},
resize: function resize() {
if (!this.texture) { return; }
var screen = this.three.size;
var iW = this.texture.image.width;
var iH = this.texture.image.height;
var iRatio = iW / iH;
var w, h;
if (this.width && this.height) {
w = this.width * screen.wWidth / screen.width;
h = this.height * screen.wHeight / screen.height;
} else if (this.width) {
w = this.width * screen.wWidth / screen.width;
h = w / iRatio;
} else if (this.height) {
h = this.height * screen.wHeight / screen.height;
w = h * iRatio;
}
this.mesh.scale.x = w;
this.mesh.scale.y = h;
},
},
__hmrId: 'Image',
};
var InstancedMesh = {
extends: Object3D,
props: {
castShadow: Boolean,
receiveShadow: Boolean,
count: Number,
},
provide: function provide() {
return {
mesh: this,
};
},
beforeMount: function beforeMount() {
if (!this.$slots.default) {
console.error('Missing Geometry');
}
},
created: function created() {
this.initMesh();
},
methods: {
initMesh: function initMesh() {
var this$1 = this;
this.mesh = new three.InstancedMesh(this.geometry, this.material, this.count);
['castShadow', 'receiveShadow'].forEach(function (p) {
this$1.mesh[p] = this$1[p];
vue.watch(function () { return this$1[p]; }, function () { this$1.mesh[p] = this$1[p]; });
});
this.initObject3D(this.mesh);
},
setGeometry: function setGeometry(geometry) {
this.geometry = geometry;
if (this.mesh) { this.mesh.geometry = geometry; }
},
setMaterial: function setMaterial(material) {
this.material = material;
if (this.mesh) { this.mesh.material = material; }
},
},
__hmrId: 'InstancedMesh',
};
var MirrorMesh = {
extends: Mesh,
props: {
cubeRTSize: { type: Number, default: 256 },
cubeCameraNear: { type: Number, default: 0.1 },
cubeCameraFar: { type: Number, default: 2000 },
autoUpdate: Boolean,
},
mounted: function mounted() {
this.initMirrorMesh();
if (this.autoUpdate) { this.three.onBeforeRender(this.updateCubeRT); }
else { this.rendererComponent.onMounted(this.updateCubeRT); }
},
unmounted: function unmounted() {
this.three.offBeforeRender(this.updateCubeRT);
if (this.cubeCamera) { this.$parent.remove(this.cubeCamera); }
},
methods: {
initMirrorMesh: function initMirrorMesh() {
var cubeRT = new three.WebGLCubeRenderTarget(this.cubeRTSize, { format: three.RGBFormat, generateMipmaps: true, minFilter: three.LinearMipmapLinearFilter });
this.cubeCamera = new three.CubeCamera(this.cubeCameraNear, this.cubeCameraFar, cubeRT);
this.$parent.add(this.cubeCamera);
this.material.envMap = cubeRT.texture;
this.material.needsUpdate = true;
},
updateCubeRT: function updateCubeRT() {
this.mesh.visible = false;
this.cubeCamera.update(this.three.renderer, this.scene);
this.mesh.visible = true;
},
},
__hmrId: 'MirrorMesh',
};
var RefractionMesh = {
extends: Mesh,
props: {
cubeRTSize: { type: Number, default: 256 },
cubeCameraNear: { type: Number, default: 0.1 },
cubeCameraFar: { type: Number, default: 2000 },
refractionRatio: { type: Number, default: 0.98 },
autoUpdate: Boolean,
},
mounted: function mounted() {
this.initMirrorMesh();
if (this.autoUpdate) { this.three.onBeforeRender(this.updateCubeRT); }
else { this.rendererComponent.onMounted(this.updateCubeRT); }
},
unmounted: function unmounted() {
this.three.offBeforeRender(this.updateCubeRT);
if (this.cubeCamera) { this.$parent.remove(this.cubeCamera); }
},
methods: {
initMirrorMesh: function initMirrorMesh() {
var cubeRT = new three.WebGLCubeRenderTarget(this.cubeRTSize, { mapping: three.CubeRefractionMapping, format: three.RGBFormat, generateMipmaps: true, minFilter: three.LinearMipmapLinearFilter });
this.cubeCamera = new three.CubeCamera(this.cubeCameraNear, this.cubeCameraFar, cubeRT);
bindProp(this, 'position', this.cubeCamera);
this.$parent.add(this.cubeCamera);
this.material.envMap = cubeRT.texture;
this.material.refractionRatio = this.refractionRatio;
this.material.needsUpdate = true;
},
updateCubeRT: function updateCubeRT() {
this.mesh.visible = false;
this.cubeCamera.update(this.three.renderer, this.scene);
this.mesh.visible = true;
},
},
__hmrId: 'RefractionMesh',
};
var Sprite = {
extends: Object3D,
emits: ['loaded'],
props: {
src: String,
},
data: function data() {
return {
loading: true,
};
},
created: function created() {
this.texture = new three.TextureLoader().load(this.src, this.onLoaded);
this.material = new three.SpriteMaterial({ map: this.texture });
this.sprite = new three.Sprite(this.material);
this.geometry = this.sprite.geometry;
this.initObject3D(this.sprite);
},
unmounted: function unmounted() {
this.texture.dispose();
this.material.dispose();
},
methods: {
onLoaded: function onLoaded() {
this.loading = false;
this.updateUV();
this.$emit('loaded');
},
updateUV: function updateUV() {
this.iWidth = this.texture.image.width;
this.iHeight = this.texture.image.height;
this.iRatio = this.iWidth / this.iHeight;
var x = 0.5, y = 0.5;
if (this.iRatio > 1) {
y = 0.5 / this.iRatio;
} else {
x = 0.5 / this.iRatio;
}
var positions = this.geometry.attributes.position.array;
positions[0] = -x; positions[1] = -y;
positions[5] = x; positions[6] = -y;
positions[10] = x; positions[11] = y;
positions[15] = -x; positions[16] = y;
this.geometry.attributes.position.needsUpdate = true;
},
},
__hmrId: 'Sprite',
};
var GLTF = {
extends: Object3D,
emits: ['loaded'],
props: {
src: String,
},
created: function created() {
var this$1 = this;
var loader = new GLTFLoader_js.GLTFLoader();
loader.load(this.src, function (gltf) {
this$1.$emit('loaded', gltf);
this$1.initObject3D(gltf.scene);
});
},
};
var FBX = {
extends: Object3D,
emits: ['loaded'],
props: {
src: String,
},
created: function created() {
var this$1 = this;
var loader = new FBXLoader_js.FBXLoader();
loader.load(this.src, function (fbx) {
this$1.$emit('loaded', fbx);
this$1.initObject3D(fbx);
});
},
};
var EffectComposer = {
setup: function setup() {
return {
passes: [],
};
},
inject: ['three'],
provide: function provide() {
return {
passes: this.passes,
};
},
mounted: function mounted() {
var this$1 = this;
this.three.onAfterInit(function () {
this$1.composer = new EffectComposer_js.EffectComposer(this$1.three.renderer);
this$1.three.renderer.autoClear = false;
this$1.passes.forEach(function (pass) {
this$1.composer.addPass(pass);
});
this$1.three.composer = this$1.composer;
this$1.resize();
this$1.three.onAfterResize(this$1.resize);
});
},
unmounted: function unmounted() {
this.three.offAfterResize(this.resize);
},
methods: {
resize: function resize() {
this.composer.setSize(this.three.size.width, this.three.size.height);
},
},
render: function render() {
return this.$slots.default();
},
__hmrId: 'EffectComposer',
};
var EffectPass = {
inject: ['three', 'passes'],
beforeMount: function beforeMount() {
if (!this.passes) {
console.error('Missing parent EffectComposer');
}
},
unmounted: function unmounted() {
if (this.pass.dispose) { this.pass.dispose(); }
},
render: function render() {
return [];
},
__hmrId: 'EffectPass',
};
var RenderPass = {
extends: EffectPass,
mounted: function mounted() {
if (!this.three.scene) {
console.error('Missing Scene');
}
if (!this.three.camera) {
console.error('Missing Camera');
}
var pass = new RenderPass_js.RenderPass(this.three.scene, this.three.camera);
this.passes.push(pass);
this.pass = pass;
},
__hmrId: 'RenderPass',
};
var BokehPass = {
extends: EffectPass,
props: {
focus: {
type: Number,
default: 1,
},
aperture: {
type: Number,
default: 0.025,
},
maxblur: {
type: Number,
default: 0.01,
},
},
watch: {
focus: function focus() { this.pass.uniforms.focus.value = this.focus; },
aperture: function aperture() { this.pass.uniforms.aperture.value = this.aperture; },
maxblur: function maxblur() { this.pass.uniforms.maxblur.value = this.maxblur; },
},
mounted: function mounted() {
if (!this.three.scene) {
console.error('Missing Scene');
}
if (!this.three.camera) {
console.error('Missing Camera');
}
var params = {
focus: this.focus,
aperture: this.aperture,
maxblur: this.maxblur,
width: this.three.size.width,
height: this.three.size.height,
};
var pass = new BokehPass_js.BokehPass(this.three.scene, this.three.camera, params);
this.passes.push(pass);
this.pass = pass;
},
__hmrId: 'BokehPass',
};
var FilmPass = {
extends: EffectPass,
props: {
noiseIntensity: {
type: Number,
default: 0.5,
},
scanlinesIntensity: {
type: Number,
default: 0.05,
},
scanlinesCount: {
type: Number,
default: 4096,
},
grayscale: {
type: Number,
default: 0,
},
},
watch: {
noiseIntensity: function noiseIntensity() { this.pass.uniforms.nIntensity.value = this.noiseIntensity; },
scanlinesIntensity: function scanlinesIntensity() { this.pass.uniforms.sIntensity.value = this.scanlinesIntensity; },
scanlinesCount: function scanlinesCount() { this.pass.uniforms.sCount.value = this.scanlinesCount; },
grayscale: function grayscale() { this.pass.uniforms.grayscale.value = this.grayscale; },
},
mounted: function mounted() {
var pass = new FilmPass_js.FilmPass(this.noiseIntensity, this.scanlinesIntensity, this.scanlinesCount, this.grayscale);
this.passes.push(pass);
this.pass = pass;
},
__hmrId: 'FilmPass',
};
var FXAAPass = {
extends: EffectPass,
mounted: function mounted() {
var pass = new ShaderPass_js.ShaderPass(FXAAShader_js.FXAAShader);
this.passes.push(pass);
this.pass = pass;
// resize will be called in three init
this.three.onAfterResize(this.resize);
},
unmounted: function unmounted() {
this.three.offAfterResize(this.resize);
},
methods: {
resize: function resize() {
var ref = this.pass.material.uniforms;
var resolution = ref.resolution;
resolution.value.x = 1 / this.three.size.width;
resolution.value.y = 1 / this.three.size.height;
},
},
__hmrId: 'FXAAPass',
};
var HalftonePass = {
extends: EffectPass,
props: {
shape: { type: Number, default: 1 },
radius: { type: Number, default: 4 },
rotateR: { type: Number, default: Math.PI / 12 * 1 },
rotateG: { type: Number, default: Math.PI / 12 * 2 },
rotateB: { type: Number, default: Math.PI / 12 * 3 },
scatter: { type: Number, default: 0 },
},
mounted: function mounted() {
var this$1 = this;
var pass = new HalftonePass_js.HalftonePass(this.three.size.width, this.three.size.height, {});
['shape', 'radius', 'rotateR', 'rotateG', 'rotateB', 'scatter'].forEach(function (p) {
pass.uniforms[p].value = this$1[p];
vue.watch(function () { return this$1[p]; }, function () {
pass.uniforms[p].value = this$1[p];
});
});
this.passes.push(pass);
this.pass = pass;
},
__hmrId: 'HalftonePass',
};
var SMAAPass = {
extends: EffectPass,
mounted: function mounted() {
// three size is not set yet, but this pass will be resized by effect composer
var pass = new SMAAPass_js.SMAAPass(this.three.size.width, this.three.size.height);
this.passes.push(pass);
this.pass = pass;
},
__hmrId: 'SMAAPass',
};
var DefaultShader = {
uniforms: {},
vertexShader: "\n varying vec2 vUv;\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }\n ",
fragmentShader: "\n varying vec2 vUv;\n void main() {\n gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);\n }\n ",
};
// From https://github.com/evanw/glfx.js
var TiltShift = {
uniforms: {
tDiffuse: { value: null },
blurRadius: { value: 0 },
gradientRadius: { value: 0 },
start: { value: new three.Vector2() },
end: { value: new three.Vector2() },
delta: { value: new three.Vector2() },
texSize: { value: new three.Vector2() },
},
vertexShader: DefaultShader.vertexShader,
fragmentShader: "\n uniform sampler2D tDiffuse;\n uniform float blurRadius;\n uniform float gradientRadius;\n uniform vec2 start;\n uniform vec2 end;\n uniform vec2 delta;\n uniform vec2 texSize;\n varying vec2 vUv;\n\n float random(vec3 scale, float seed) {\n /* use the fragment position for a different seed per-pixel */\n return fract(sin(dot(gl_FragCoord.xyz + seed, scale)) * 43758.5453 + seed);\n }\n\n void main() {\n vec4 color = vec4(0.0);\n float total = 0.0;\n\n /* randomize the lookup values to hide the fixed number of samples */\n float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0);\n\n vec2 normal = normalize(vec2(start.y - end.y, end.x - start.x));\n float radius = smoothstep(0.0, 1.0, abs(dot(vUv * texSize - start, normal)) / gradientRadius) * blurRadius;\n for (float t = -30.0; t <= 30.0; t++) {\n float percent = (t + offset - 0.5) / 30.0;\n float weight = 1.0 - abs(percent);\n vec4 texel = texture2D(tDiffuse, vUv + delta / texSize * percent * radius);\n // vec4 texel2 = texture2D(tDiffuse, vUv + vec2(-delta.y, delta.x) / texSize * percent * radius);\n\n /* switch to pre-multiplied alpha to correctly blur transparent images */\n texel.rgb *= texel.a;\n // texel2.rgb *= texel2.a;\n\n color += texel * weight;\n total += 2.0 * weight;\n }\n\n gl_FragColor = color / total;\n\n /* switch back from pre-multiplied alpha */\n gl_FragColor.rgb /= gl_FragColor.a + 0.00001;\n }\n ",
};
var TiltShiftPass = {
extends: EffectPass,
props: {
blurRadius: { type: Number, default: 10 },
gradientRadius: { type: Number, default: 100 },
start: { type: Object, default: { x: 0, y: 100 } },
end: { type: Object, default: { x: 10, y: 100 } },
},
mounted: function mounted() {
var this$1 = this;
this.pass = new ShaderPass_js.ShaderPass(TiltShift);
this.passes.push(this.pass);
this.pass1 = new ShaderPass_js.ShaderPass(TiltShift);
this.passes.push(this.pass1);
var uniforms = this.uniforms = this.pass.uniforms;
var uniforms1 = this.uniforms1 = this.pass1.uniforms;
uniforms1.blurRadius = uniforms.blurRadius;
uniforms1.gradientRadius = uniforms.gradientRadius;
uniforms1.start = uniforms.start;
uniforms1.end = uniforms.end;
uniforms1.texSize = uniforms.texSize;
bindProp(this, 'blurRadius', uniforms.blurRadius, 'value');
bindProp(this, 'gradientRadius', uniforms.gradientRadius, 'value');
this.updateFocusLine();
['start', 'end'].forEach(function (p) {
vue.watch(function () { return this$1[p]; }, this$1.updateFocusLine, { deep: true });
});
this.pass.setSize = function (width, height) {
uniforms.texSize.value.set(width, height);
};
},
methods: {
updateFocusLine: function updateFocusLine() {
this.uniforms.start.value.copy(this.start);
this.uniforms.end.value.copy(this.end);
var dv = new three.Vector2().copy(this.end).sub(this.start).normalize();
this.uniforms.delta.value.copy(dv);
this.uniforms1.delta.value.set(-dv.y, dv.x);
},
},
__hmrId: 'TiltShiftPass',
};
var UnrealBloomPass = {
extends: EffectPass,
props: {
strength: { type: Number, default: 1.5 },
radius: { type: Number, default: 0 },
threshold: { type: Number, default: 0 },
},
watch: {
strength: function strength() { this.pass.strength = this.strength; },
radius: function radius() { this.pass.radius = this.radius; },
threshold: function threshold() { this.pass.threshold = this.threshold; },
},
mounted: function mounted() {
var size = new three.Vector2(this.three.size.width, this.three.size.height);
var pass = new UnrealBloomPass_js.UnrealBloomPass(size, this.strength, this.radius, this.threshold);
this.passes.push(pass);
this.pass = pass;
},
__hmrId: 'UnrealBloomPass',
};
// From https://github.com/evanw/glfx.js
var ZoomBlur = {
uniforms: {
tDiffuse: { value: null },
center: { value: new three.Vector2(0.5, 0.5) },
strength: { value: 0 },
},
vertexShader: DefaultShader.vertexShader,
fragmentShader: "\n uniform sampler2D tDiffuse;\n uniform vec2 center;\n uniform float strength;\n varying vec2 vUv;\n\n float random(vec3 scale, float seed) {\n /* use the fragment position for a different seed per-pixel */\n return fract(sin(dot(gl_FragCoord.xyz + seed, scale)) * 43758.5453 + seed);\n }\n \n void main() {\n vec4 color = vec4(0.0);\n float total = 0.0;\n vec2 toCenter = center - vUv;\n \n /* randomize the lookup values to hide the fixed number of samples */\n float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0);\n \n for (float t = 0.0; t <= 40.0; t++) {\n float percent = (t + offset) / 40.0;\n float weight = 4.0 * (percent - percent * percent);\n vec4 texel = texture2D(tDiffuse, vUv + toCenter * percent * strength);\n\n /* switch to pre-multiplied alpha to correctly blur transparent images */\n texel.rgb *= texel.a;\n\n color += texel * weight;\n total += weight;\n }\n\n gl_FragColor = color / total;\n\n /* switch back from pre-multiplied alpha */\n gl_FragColor.rgb /= gl_FragColor.a + 0.00001;\n }\n ",
};
var ZoomBlurPass = {
extends: EffectPass,
props: {
center: { type: Object, default: { x: 0.5, y: 0.5 } },
strength: { type: Number, default: 0.5 },
},
mounted: function mounted() {
this.pass = new ShaderPass_js.ShaderPass(ZoomBlur);
this.passes.push(this.pass);
var uniforms = this.uniforms = this.pass.uniforms;
bindProp(this, 'center', uniforms.center, 'value');
bindProp(this, 'strength', uniforms.strength, 'value');
},
__hmrId: 'ZoomBlurPass',
};
var TROIS = /*#__PURE__*/Object.freeze({
__proto__: null,
Renderer: Renderer,
OrthographicCamera: OrthographicCamera,
PerspectiveCamera: PerspectiveCamera,
Camera: PerspectiveCamera,
Group: Group,
Scene: Scene,
BoxGeometry: BoxGeometry,
CircleGeometry: CircleGeometry,
ConeGeometry: ConeGeometry,
CylinderGeometry: CylinderGeometry,
DodecahedronGeometry: DodecahedronGeometry,
IcosahedronGeometry: IcosahedronGeometry,
LatheGeometry: LatheGeometry,
OctahedronGeometry: OctahedronGeometry,
PolyhedronGeometry: PolyhedronGeometry,
RingGeometry: RingGeometry,
SphereGeometry: SphereGeometry,
TetrahedronGeometry: TetrahedronGeometry,
TorusGeometry: TorusGeometry,
TorusKnotGeometry: TorusKnotGeometry,
TubeGeometry: TubeGeometry,
AmbientLight: AmbientLight,
DirectionalLight: DirectionalLight,
HemisphereLight: HemisphereLight,
PointLight: PointLight,
RectAreaLight: RectAreaLight,
SpotLight: SpotLight,
BasicMaterial: BasicMaterial,
LambertMaterial: LambertMaterial,
MatcapMaterial: MatcapMaterial,
PhongMaterial: PhongMaterial,
PhysicalMaterial: PhysicalMaterial,
ShaderMaterial: ShaderMaterial,
StandardMaterial: StandardMaterial,
SubSurfaceMaterial: SubSurfaceMaterial,
ToonMaterial: ToonMaterial,
Texture: Texture,
CubeTexture: CubeTexture,
Mesh: Mesh,
Box: Box,
Circle: Circle,
Cone: Cone,
Cylinder: Cylinder,
Dodecahedron: Dodecahedron,
Icosahedron: Icosahedron,
Lathe: Lathe,
Octahedron: Octahedron,
Plane: Plane,
Polyhedron: Polyhedron,
Ring: Ring,
Sphere: Sphere,
Tetrahedron: Tetrahedron,
Text: Text,
Torus: Torus,
TorusKnot: TorusKnot,
Tube: Tube,
Gem: Gem,
Image: Image,
InstancedMesh: InstancedMesh,
MirrorMesh: MirrorMesh,
RefractionMesh: RefractionMesh,
Sprite: Sprite,
GLTFModel: GLTF,
FBXModel: FBX,
EffectComposer: EffectComposer,
RenderPass: RenderPass,
BokehPass: BokehPass,
FilmPass: FilmPass,
FXAAPass: FXAAPass,
HalftonePass: HalftonePass,
SMAAPass: SMAAPass,
TiltShiftPass: TiltShiftPass,
UnrealBloomPass: UnrealBloomPass,
ZoomBlurPass: ZoomBlurPass,
setFromProp: setFromProp,
bindProps: bindProps,
bindProp: bindProp,
propsValues: propsValues,
lerp: lerp,
lerpv2: lerpv2,
lerpv3: lerpv3,
limit: limit,
getMatcapUrl: getMatcapUrl,
defaultVertexShader: defaultVertexShader,
defaultFragmentShader: defaultFragmentShader
});
var TroisJSVuePlugin = {
install: function (app) {
var comps = [
'Camera',
'OrthographicCamera',
'PerspectiveCamera',
'Renderer',
'Scene',
'Group',
'AmbientLight',
'DirectionalLight',
'HemisphereLight',
'PointLight',
'RectAreaLight',
'SpotLight',
'BasicMaterial',
'LambertMaterial',
'MatcapMaterial',
'PhongMaterial',
'PhysicalMaterial',
'ShaderMaterial',
'StandardMaterial',
'SubSurfaceMaterial',
'ToonMaterial',
'Texture',
'CubeTexture',
'Mesh',
'Box', 'BoxGeometry',
'Circle', 'CircleGeometry',
'Cone', 'ConeGeometry',
'Cylinder', 'CylinderGeometry',
'Dodecahedron', 'DodecahedronGeometry',
'Icosahedron', 'IcosahedronGeometry',
'Lathe', 'LatheGeometry',
'Octahedron', 'OctahedronGeometry',
'Plane',
'Polyhedron', 'PolyhedronGeometry',
'Ring', 'RingGeometry',
'Sphere', 'SphereGeometry',
'Tetrahedron', 'TetrahedronGeometry',
'Text',
'Torus', 'TorusGeometry',
'TorusKnot', 'TorusKnotGeometry',
'Tube', 'TubeGeometry',
'Gem',
'Image',
'InstancedMesh',
'MirrorMesh',
'RefractionMesh',
'Sprite',
'FBXModel',
'GLTFModel',
'BokehPass',
'EffectComposer',
'FilmPass',
'FXAAPass',
'HalftonePass',
'RenderPass',
'SAOPass',
'SMAAPass',
'TiltShiftPass',
'UnrealBloomPass',
'ZoomBlurPass',
'GLTFViewer' ];
comps.forEach(function (comp) {
app.component(comp, TROIS[comp]);
});
},
};
function createApp(params) {
return vue.createApp(params).use(TroisJSVuePlugin);
}
exports.AmbientLight = AmbientLight;
exports.BasicMaterial = BasicMaterial;
exports.BokehPass = BokehPass;
exports.Box = Box;
exports.BoxGeometry = BoxGeometry;
exports.Camera = PerspectiveCamera;
exports.Circle = Circle;
exports.CircleGeometry = CircleGeometry;
exports.Cone = Cone;
exports.ConeGeometry = ConeGeometry;
exports.CubeTexture = CubeTexture;
exports.Cylinder = Cylinder;
exports.CylinderGeometry = CylinderGeometry;
exports.DirectionalLight = DirectionalLight;
exports.Dodecahedron = Dodecahedron;
exports.DodecahedronGeometry = DodecahedronGeometry;
exports.EffectComposer = EffectComposer;
exports.FBXModel = FBX;
exports.FXAAPass = FXAAPass;
exports.FilmPass = FilmPass;
exports.GLTFModel = GLTF;
exports.Gem = Gem;
exports.Group = Group;
exports.HalftonePass = HalftonePass;
exports.HemisphereLight = HemisphereLight;
exports.Icosahedron = Icosahedron;
exports.IcosahedronGeometry = IcosahedronGeometry;
exports.Image = Image;
exports.InstancedMesh = InstancedMesh;
exports.LambertMaterial = LambertMaterial;
exports.Lathe = Lathe;
exports.LatheGeometry = LatheGeometry;
exports.MatcapMaterial = MatcapMaterial;
exports.Mesh = Mesh;
exports.MirrorMesh = MirrorMesh;
exports.Octahedron = Octahedron;
exports.OctahedronGeometry = OctahedronGeometry;
exports.OrthographicCamera = OrthographicCamera;
exports.PerspectiveCamera = PerspectiveCamera;
exports.PhongMaterial = PhongMaterial;
exports.PhysicalMaterial = PhysicalMaterial;
exports.Plane = Plane;
exports.PointLight = PointLight;
exports.Polyhedron = Polyhedron;
exports.PolyhedronGeometry = PolyhedronGeometry;
exports.RectAreaLight = RectAreaLight;
exports.RefractionMesh = RefractionMesh;
exports.RenderPass = RenderPass;
exports.Renderer = Renderer;
exports.Ring = Ring;
exports.RingGeometry = RingGeometry;
exports.SMAAPass = SMAAPass;
exports.Scene = Scene;
exports.ShaderMaterial = ShaderMaterial;
exports.Sphere = Sphere;
exports.SphereGeometry = SphereGeometry;
exports.SpotLight = SpotLight;
exports.Sprite = Sprite;
exports.StandardMaterial = StandardMaterial;
exports.SubSurfaceMaterial = SubSurfaceMaterial;
exports.Tetrahedron = Tetrahedron;
exports.TetrahedronGeometry = TetrahedronGeometry;
exports.Text = Text;
exports.Texture = Texture;
exports.TiltShiftPass = TiltShiftPass;
exports.ToonMaterial = ToonMaterial;
exports.Torus = Torus;
exports.TorusGeometry = TorusGeometry;
exports.TorusKnot = TorusKnot;
exports.TorusKnotGeometry = TorusKnotGeometry;
exports.TroisJSVuePlugin = TroisJSVuePlugin;
exports.Tube = Tube;
exports.TubeGeometry = TubeGeometry;
exports.UnrealBloomPass = UnrealBloomPass;
exports.ZoomBlurPass = ZoomBlurPass;
exports.bindProp = bindProp;
exports.bindProps = bindProps;
exports.createApp = createApp;
exports.defaultFragmentShader = defaultFragmentShader;
exports.defaultVertexShader = defaultVertexShader;
exports.getMatcapUrl = getMatcapUrl;
exports.lerp = lerp;
exports.lerpv2 = lerpv2;
exports.lerpv3 = lerpv3;
exports.limit = limit;
exports.propsValues = propsValues;
exports.setFromProp = setFromProp;