2021-03-04 04:49:22 +08:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
|
|
|
|
|
var three = require('three');
|
2021-04-30 05:07:04 +08:00
|
|
|
var vue = require('vue');
|
2021-03-04 04:49:22 +08:00
|
|
|
var OrbitControls_js = require('three/examples/jsm/controls/OrbitControls.js');
|
2021-03-08 04:17:46 +08:00
|
|
|
var RectAreaLightUniformsLib_js = require('three/examples/jsm/lights/RectAreaLightUniformsLib.js');
|
|
|
|
var RectAreaLightHelper_js = require('three/examples/jsm/helpers/RectAreaLightHelper.js');
|
2021-03-14 02:34:34 +08:00
|
|
|
var GLTFLoader_js = require('three/examples/jsm/loaders/GLTFLoader.js');
|
|
|
|
var FBXLoader_js = require('three/examples/jsm/loaders/FBXLoader.js');
|
2021-03-04 04:49:22 +08:00
|
|
|
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');
|
2021-04-05 04:02:11 +08:00
|
|
|
var SSAOPass_js = require('three/examples/jsm/postprocessing/SSAOPass.js');
|
2021-03-04 04:49:22 +08:00
|
|
|
var UnrealBloomPass_js = require('three/examples/jsm/postprocessing/UnrealBloomPass.js');
|
|
|
|
|
2021-04-30 05:07:04 +08:00
|
|
|
function setFromProp(o, prop) {
|
|
|
|
if (prop instanceof Object) {
|
|
|
|
Object.entries(prop).forEach(([key, value]) => {
|
|
|
|
o[key] = value;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function bindProps(src, props, dst) {
|
|
|
|
props.forEach((prop) => {
|
|
|
|
bindProp(src, prop, dst, prop);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
function bindProp(src, srcProp, dst, dstProp) {
|
|
|
|
const _dstProp = dstProp || srcProp;
|
|
|
|
const ref = vue.toRef(src, srcProp);
|
|
|
|
if (ref.value instanceof Object) {
|
|
|
|
setFromProp(dst[_dstProp], ref.value);
|
|
|
|
vue.watch(ref, (value) => {
|
|
|
|
setFromProp(dst[_dstProp], value);
|
|
|
|
}, {deep: true});
|
|
|
|
} else {
|
|
|
|
if (ref.value)
|
|
|
|
dst[_dstProp] = src[srcProp];
|
|
|
|
vue.watch(ref, (value) => {
|
|
|
|
dst[_dstProp] = value;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function propsValues(props, exclude = []) {
|
|
|
|
const values = {};
|
|
|
|
Object.entries(props).forEach(([key, value]) => {
|
|
|
|
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 limit(val, min, max) {
|
|
|
|
return val < min ? min : val > max ? max : val;
|
|
|
|
}
|
|
|
|
const MATCAP_ROOT = "https://rawcdn.githack.com/emmelleppi/matcaps/9b36ccaaf0a24881a39062d05566c9e92be4aa0d";
|
|
|
|
const DEFAULT_MATCAP = "0404E8_0404B5_0404CB_3333FC";
|
|
|
|
function getMatcapUrl(hash = DEFAULT_MATCAP, format = 1024) {
|
|
|
|
const 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 "";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
function useRaycaster(options) {
|
|
|
|
const {
|
|
|
|
camera,
|
2021-04-29 00:07:58 +08:00
|
|
|
resetPosition = new three.Vector3(0, 0, 0)
|
2021-04-05 04:02:11 +08:00
|
|
|
} = options;
|
|
|
|
const raycaster = new three.Raycaster();
|
|
|
|
const position = resetPosition.clone();
|
|
|
|
const plane = new three.Plane(new three.Vector3(0, 0, 1), 0);
|
|
|
|
const updatePosition = (coords) => {
|
|
|
|
raycaster.setFromCamera(coords, camera);
|
|
|
|
camera.getWorldDirection(plane.normal);
|
|
|
|
raycaster.ray.intersectPlane(plane, position);
|
|
|
|
};
|
|
|
|
const intersect = (coords, objects) => {
|
|
|
|
raycaster.setFromCamera(coords, camera);
|
|
|
|
return raycaster.intersectObjects(objects);
|
|
|
|
};
|
|
|
|
return {
|
|
|
|
position,
|
|
|
|
updatePosition,
|
2021-04-29 00:07:58 +08:00
|
|
|
intersect
|
2021-04-05 04:02:11 +08:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
function usePointer(options) {
|
|
|
|
const {
|
|
|
|
camera,
|
|
|
|
domElement,
|
|
|
|
intersectObjects,
|
|
|
|
touch = true,
|
|
|
|
resetOnEnd = false,
|
|
|
|
resetPosition = new three.Vector2(0, 0),
|
|
|
|
resetPositionV3 = new three.Vector3(0, 0, 0),
|
2021-04-29 00:07:58 +08:00
|
|
|
onEnter = () => {
|
|
|
|
},
|
|
|
|
onMove = () => {
|
|
|
|
},
|
|
|
|
onLeave = () => {
|
|
|
|
},
|
|
|
|
onClick = () => {
|
|
|
|
},
|
|
|
|
onIntersectEnter = () => {
|
|
|
|
},
|
|
|
|
onIntersectOver = () => {
|
|
|
|
},
|
|
|
|
onIntersectMove = () => {
|
|
|
|
},
|
|
|
|
onIntersectLeave = () => {
|
|
|
|
},
|
|
|
|
onIntersectClick = () => {
|
|
|
|
}
|
2021-04-05 04:02:11 +08:00
|
|
|
} = options;
|
|
|
|
const position = resetPosition.clone();
|
|
|
|
const positionN = new three.Vector2(0, 0);
|
2021-04-29 00:07:58 +08:00
|
|
|
const raycaster = useRaycaster({camera});
|
2021-04-05 04:02:11 +08:00
|
|
|
const positionV3 = raycaster.position;
|
|
|
|
const obj = {
|
|
|
|
position,
|
|
|
|
positionN,
|
|
|
|
positionV3,
|
|
|
|
intersectObjects,
|
|
|
|
listeners: false,
|
|
|
|
addListeners,
|
|
|
|
removeListeners,
|
2021-04-29 00:07:58 +08:00
|
|
|
intersect
|
2021-04-05 04:02:11 +08:00
|
|
|
};
|
|
|
|
return obj;
|
|
|
|
function reset() {
|
|
|
|
position.copy(resetPosition);
|
|
|
|
positionV3.copy(resetPositionV3);
|
|
|
|
}
|
|
|
|
function updatePosition(event) {
|
|
|
|
let x, y;
|
2021-04-30 05:07:04 +08:00
|
|
|
if (event.touches && event.touches.length > 0) {
|
2021-04-05 04:02:11 +08:00
|
|
|
x = event.touches[0].clientX;
|
|
|
|
y = event.touches[0].clientY;
|
|
|
|
} else {
|
|
|
|
x = event.clientX;
|
|
|
|
y = event.clientY;
|
|
|
|
}
|
|
|
|
const rect = domElement.getBoundingClientRect();
|
|
|
|
position.x = x - rect.left;
|
|
|
|
position.y = y - rect.top;
|
2021-04-29 00:07:58 +08:00
|
|
|
positionN.x = position.x / rect.width * 2 - 1;
|
2021-04-05 04:02:11 +08:00
|
|
|
positionN.y = -(position.y / rect.height) * 2 + 1;
|
|
|
|
raycaster.updatePosition(positionN);
|
|
|
|
}
|
|
|
|
function intersect() {
|
|
|
|
if (intersectObjects.length) {
|
|
|
|
const intersects = raycaster.intersect(positionN, intersectObjects);
|
|
|
|
const offObjects = [...intersectObjects];
|
|
|
|
const iMeshes = [];
|
2021-04-29 00:07:58 +08:00
|
|
|
intersects.forEach((intersect2) => {
|
|
|
|
var _a, _b, _c;
|
|
|
|
const {object} = intersect2;
|
|
|
|
const {component} = object.userData;
|
2021-04-05 04:02:11 +08:00
|
|
|
if (object instanceof three.InstancedMesh) {
|
2021-04-29 00:07:58 +08:00
|
|
|
if (iMeshes.indexOf(object) !== -1)
|
|
|
|
return;
|
2021-04-05 04:02:11 +08:00
|
|
|
iMeshes.push(object);
|
|
|
|
}
|
2021-04-29 00:07:58 +08:00
|
|
|
if (!object.userData.over) {
|
|
|
|
object.userData.over = true;
|
|
|
|
const overEvent = {type: "pointerover", over: true, component, intersect: intersect2};
|
|
|
|
const enterEvent = {...overEvent, type: "pointerenter"};
|
2021-04-05 04:02:11 +08:00
|
|
|
onIntersectOver(overEvent);
|
|
|
|
onIntersectEnter(enterEvent);
|
2021-04-29 00:07:58 +08:00
|
|
|
(_a = component.onPointerOver) == null ? void 0 : _a.call(component, overEvent);
|
|
|
|
(_b = component.onPointerEnter) == null ? void 0 : _b.call(component, enterEvent);
|
2021-04-05 04:02:11 +08:00
|
|
|
}
|
2021-04-29 00:07:58 +08:00
|
|
|
const moveEvent = {type: "pointermove", component, intersect: intersect2};
|
2021-04-05 04:02:11 +08:00
|
|
|
onIntersectMove(moveEvent);
|
2021-04-29 00:07:58 +08:00
|
|
|
(_c = component.onPointerMove) == null ? void 0 : _c.call(component, moveEvent);
|
2021-04-05 04:02:11 +08:00
|
|
|
offObjects.splice(offObjects.indexOf(object), 1);
|
|
|
|
});
|
2021-04-29 00:07:58 +08:00
|
|
|
offObjects.forEach((object) => {
|
|
|
|
var _a, _b;
|
|
|
|
const {component} = object.userData;
|
|
|
|
if (object.userData.over) {
|
|
|
|
object.userData.over = false;
|
|
|
|
const overEvent = {type: "pointerover", over: false, component};
|
|
|
|
const leaveEvent = {...overEvent, type: "pointerleave"};
|
2021-04-05 04:02:11 +08:00
|
|
|
onIntersectOver(overEvent);
|
|
|
|
onIntersectLeave(leaveEvent);
|
2021-04-29 00:07:58 +08:00
|
|
|
(_a = component.onPointerOver) == null ? void 0 : _a.call(component, overEvent);
|
|
|
|
(_b = component.onPointerLeave) == null ? void 0 : _b.call(component, leaveEvent);
|
2021-04-05 04:02:11 +08:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function pointerEnter(event) {
|
|
|
|
updatePosition(event);
|
2021-04-29 00:07:58 +08:00
|
|
|
onEnter({type: "pointerenter", position, positionN, positionV3});
|
2021-04-05 04:02:11 +08:00
|
|
|
}
|
|
|
|
function pointerMove(event) {
|
|
|
|
updatePosition(event);
|
2021-04-29 00:07:58 +08:00
|
|
|
onMove({type: "pointermove", position, positionN, positionV3});
|
2021-04-05 04:02:11 +08:00
|
|
|
intersect();
|
|
|
|
}
|
|
|
|
function pointerClick(event) {
|
|
|
|
updatePosition(event);
|
|
|
|
if (intersectObjects.length) {
|
|
|
|
const intersects = raycaster.intersect(positionN, intersectObjects);
|
|
|
|
const iMeshes = [];
|
2021-04-29 00:07:58 +08:00
|
|
|
intersects.forEach((intersect2) => {
|
|
|
|
var _a;
|
|
|
|
const {object} = intersect2;
|
|
|
|
const {component} = object.userData;
|
2021-04-05 04:02:11 +08:00
|
|
|
if (object instanceof three.InstancedMesh) {
|
2021-04-29 00:07:58 +08:00
|
|
|
if (iMeshes.indexOf(object) !== -1)
|
|
|
|
return;
|
2021-04-05 04:02:11 +08:00
|
|
|
iMeshes.push(object);
|
|
|
|
}
|
2021-04-29 00:07:58 +08:00
|
|
|
const event2 = {type: "click", component, intersect: intersect2};
|
|
|
|
onIntersectClick(event2);
|
|
|
|
(_a = component.onClick) == null ? void 0 : _a.call(component, event2);
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
|
|
|
}
|
2021-04-29 00:07:58 +08:00
|
|
|
onClick({type: "click", position, positionN, positionV3});
|
2021-04-05 04:02:11 +08:00
|
|
|
}
|
|
|
|
function pointerLeave() {
|
2021-04-29 00:07:58 +08:00
|
|
|
if (resetOnEnd)
|
|
|
|
reset();
|
|
|
|
onLeave({type: "pointerleave"});
|
2021-04-05 04:02:11 +08:00
|
|
|
}
|
|
|
|
function addListeners() {
|
2021-04-29 00:07:58 +08:00
|
|
|
domElement.addEventListener("mouseenter", pointerEnter);
|
|
|
|
domElement.addEventListener("mousemove", pointerMove);
|
|
|
|
domElement.addEventListener("mouseleave", pointerLeave);
|
|
|
|
domElement.addEventListener("click", pointerClick);
|
2021-04-05 04:02:11 +08:00
|
|
|
if (touch) {
|
2021-04-29 00:07:58 +08:00
|
|
|
domElement.addEventListener("touchstart", pointerEnter);
|
|
|
|
domElement.addEventListener("touchmove", pointerMove);
|
|
|
|
domElement.addEventListener("touchend", pointerLeave);
|
2021-04-05 04:02:11 +08:00
|
|
|
}
|
|
|
|
obj.listeners = true;
|
|
|
|
}
|
|
|
|
function removeListeners() {
|
2021-04-29 00:07:58 +08:00
|
|
|
domElement.removeEventListener("mouseenter", pointerEnter);
|
|
|
|
domElement.removeEventListener("mousemove", pointerMove);
|
|
|
|
domElement.removeEventListener("mouseleave", pointerLeave);
|
|
|
|
domElement.removeEventListener("click", pointerClick);
|
|
|
|
domElement.removeEventListener("touchstart", pointerEnter);
|
|
|
|
domElement.removeEventListener("touchmove", pointerMove);
|
|
|
|
domElement.removeEventListener("touchend", pointerLeave);
|
2021-04-05 04:02:11 +08:00
|
|
|
obj.listeners = false;
|
2021-04-29 00:07:58 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function useThree(params) {
|
|
|
|
const config = {
|
2021-03-04 04:49:22 +08:00
|
|
|
antialias: true,
|
|
|
|
alpha: false,
|
|
|
|
autoClear: true,
|
2021-04-29 00:07:58 +08:00
|
|
|
orbitCtrl: false,
|
2021-04-05 04:02:11 +08:00
|
|
|
pointer: false,
|
|
|
|
resize: false,
|
|
|
|
width: 300,
|
2021-04-29 00:07:58 +08:00
|
|
|
height: 150
|
2021-03-04 04:49:22 +08:00
|
|
|
};
|
2021-04-29 00:07:58 +08:00
|
|
|
if (params) {
|
|
|
|
Object.entries(params).forEach(([key, value]) => {
|
|
|
|
config[key] = value;
|
|
|
|
});
|
|
|
|
}
|
2021-04-05 04:02:11 +08:00
|
|
|
const size = {
|
2021-04-29 00:07:58 +08:00
|
|
|
width: 1,
|
|
|
|
height: 1,
|
|
|
|
wWidth: 1,
|
|
|
|
wHeight: 1,
|
|
|
|
ratio: 1
|
2021-03-04 04:49:22 +08:00
|
|
|
};
|
2021-04-29 00:07:58 +08:00
|
|
|
const beforeRenderCallbacks = [];
|
2021-04-05 04:02:11 +08:00
|
|
|
const intersectObjects = [];
|
2021-04-29 00:07:58 +08:00
|
|
|
const renderer = createRenderer();
|
2021-04-05 04:02:11 +08:00
|
|
|
const obj = {
|
2021-04-29 00:07:58 +08:00
|
|
|
config,
|
|
|
|
renderer,
|
2021-04-05 04:02:11 +08:00
|
|
|
size,
|
|
|
|
init,
|
|
|
|
dispose,
|
|
|
|
render,
|
|
|
|
renderC,
|
|
|
|
setSize,
|
2021-04-29 00:07:58 +08:00
|
|
|
addIntersectObject,
|
|
|
|
removeIntersectObject
|
2021-03-04 04:49:22 +08:00
|
|
|
};
|
2021-04-29 00:07:58 +08:00
|
|
|
return obj;
|
|
|
|
function createRenderer() {
|
|
|
|
const renderer2 = new three.WebGLRenderer({canvas: config.canvas, antialias: config.antialias, alpha: config.alpha});
|
|
|
|
renderer2.autoClear = config.autoClear;
|
|
|
|
return renderer2;
|
|
|
|
}
|
|
|
|
function init() {
|
2021-03-04 04:49:22 +08:00
|
|
|
if (!obj.scene) {
|
2021-04-29 00:07:58 +08:00
|
|
|
console.error("Missing Scene");
|
|
|
|
return false;
|
2021-03-04 04:49:22 +08:00
|
|
|
}
|
|
|
|
if (!obj.camera) {
|
2021-04-29 00:07:58 +08:00
|
|
|
console.error("Missing Camera");
|
|
|
|
return false;
|
2021-03-04 04:49:22 +08:00
|
|
|
}
|
2021-04-29 00:07:58 +08:00
|
|
|
if (config.resize) {
|
2021-04-05 04:02:11 +08:00
|
|
|
onResize();
|
2021-04-29 00:07:58 +08:00
|
|
|
window.addEventListener("resize", onResize);
|
|
|
|
} else if (config.width && config.height) {
|
|
|
|
setSize(config.width, config.height);
|
2021-04-05 04:02:11 +08:00
|
|
|
}
|
|
|
|
initPointer();
|
2021-04-29 00:07:58 +08:00
|
|
|
if (config.orbitCtrl) {
|
|
|
|
const cameraCtrl = new OrbitControls_js.OrbitControls(obj.camera, obj.renderer.domElement);
|
|
|
|
if (config.orbitCtrl instanceof Object) {
|
|
|
|
Object.entries(config.orbitCtrl).forEach(([key, value]) => {
|
|
|
|
cameraCtrl[key] = value;
|
2021-03-04 04:49:22 +08:00
|
|
|
});
|
|
|
|
}
|
2021-04-29 00:07:58 +08:00
|
|
|
onBeforeRender(() => {
|
|
|
|
cameraCtrl.update();
|
|
|
|
});
|
|
|
|
obj.cameraCtrl = cameraCtrl;
|
2021-03-04 04:49:22 +08:00
|
|
|
}
|
2021-04-05 04:02:11 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
function initPointer() {
|
|
|
|
let pointerConf = {
|
|
|
|
camera: obj.camera,
|
|
|
|
domElement: obj.renderer.domElement,
|
2021-04-29 00:07:58 +08:00
|
|
|
intersectObjects
|
2021-04-05 04:02:11 +08:00
|
|
|
};
|
2021-04-29 00:07:58 +08:00
|
|
|
if (config.pointer && config.pointer instanceof Object) {
|
|
|
|
pointerConf = {...pointerConf, ...config.pointer};
|
2021-03-04 04:49:22 +08:00
|
|
|
}
|
2021-04-29 00:07:58 +08:00
|
|
|
const pointer = obj.pointer = usePointer(pointerConf);
|
|
|
|
if (config.pointer || intersectObjects.length) {
|
|
|
|
pointer.addListeners();
|
|
|
|
if (pointerConf.intersectMode === "frame") {
|
|
|
|
onBeforeRender(pointer.intersect);
|
2021-04-05 04:02:11 +08:00
|
|
|
}
|
|
|
|
}
|
2021-03-04 04:49:22 +08:00
|
|
|
}
|
2021-04-29 00:07:58 +08:00
|
|
|
function onBeforeRender(cb) {
|
|
|
|
beforeRenderCallbacks.push(cb);
|
2021-03-04 04:49:22 +08:00
|
|
|
}
|
|
|
|
function render() {
|
2021-04-29 00:07:58 +08:00
|
|
|
beforeRenderCallbacks.forEach((c) => c());
|
2021-03-04 04:49:22 +08:00
|
|
|
obj.renderer.render(obj.scene, obj.camera);
|
|
|
|
}
|
|
|
|
function renderC() {
|
2021-04-29 00:07:58 +08:00
|
|
|
beforeRenderCallbacks.forEach((c) => c());
|
2021-03-04 04:49:22 +08:00
|
|
|
obj.composer.render();
|
|
|
|
}
|
|
|
|
function addIntersectObject(o) {
|
|
|
|
if (intersectObjects.indexOf(o) === -1) {
|
|
|
|
intersectObjects.push(o);
|
|
|
|
}
|
2021-04-05 04:02:11 +08:00
|
|
|
if (obj.pointer && !obj.pointer.listeners) {
|
|
|
|
obj.pointer.addListeners();
|
|
|
|
}
|
2021-03-04 04:49:22 +08:00
|
|
|
}
|
|
|
|
function removeIntersectObject(o) {
|
2021-04-05 04:02:11 +08:00
|
|
|
const i = intersectObjects.indexOf(o);
|
2021-03-04 04:49:22 +08:00
|
|
|
if (i !== -1) {
|
|
|
|
intersectObjects.splice(i, 1);
|
|
|
|
}
|
2021-04-29 00:07:58 +08:00
|
|
|
if (obj.pointer && !config.pointer && intersectObjects.length === 0) {
|
2021-04-05 04:02:11 +08:00
|
|
|
obj.pointer.removeListeners();
|
|
|
|
}
|
2021-03-04 04:49:22 +08:00
|
|
|
}
|
|
|
|
function dispose() {
|
2021-04-29 00:07:58 +08:00
|
|
|
window.removeEventListener("resize", onResize);
|
|
|
|
if (obj.pointer)
|
|
|
|
obj.pointer.removeListeners();
|
|
|
|
if (obj.cameraCtrl)
|
|
|
|
obj.cameraCtrl.dispose();
|
|
|
|
if (obj.renderer)
|
|
|
|
obj.renderer.dispose();
|
2021-03-04 04:49:22 +08:00
|
|
|
}
|
|
|
|
function onResize() {
|
2021-04-29 00:07:58 +08:00
|
|
|
var _a;
|
|
|
|
if (config.resize === "window") {
|
2021-03-04 04:49:22 +08:00
|
|
|
setSize(window.innerWidth, window.innerHeight);
|
|
|
|
} else {
|
2021-04-05 04:02:11 +08:00
|
|
|
const elt = obj.renderer.domElement.parentNode;
|
2021-04-29 00:07:58 +08:00
|
|
|
if (elt)
|
|
|
|
setSize(elt.clientWidth, elt.clientHeight);
|
2021-03-04 04:49:22 +08:00
|
|
|
}
|
2021-04-29 00:07:58 +08:00
|
|
|
(_a = config.onResize) == null ? void 0 : _a.call(config, size);
|
2021-03-04 04:49:22 +08:00
|
|
|
}
|
|
|
|
function setSize(width, height) {
|
|
|
|
size.width = width;
|
|
|
|
size.height = height;
|
|
|
|
size.ratio = width / height;
|
|
|
|
obj.renderer.setSize(width, height, false);
|
2021-04-29 00:07:58 +08:00
|
|
|
const camera = obj.camera;
|
|
|
|
if (camera.type === "PerspectiveCamera") {
|
|
|
|
const pCamera = camera;
|
|
|
|
pCamera.aspect = size.ratio;
|
|
|
|
pCamera.updateProjectionMatrix();
|
2021-03-04 04:49:22 +08:00
|
|
|
}
|
2021-04-29 00:07:58 +08:00
|
|
|
if (camera.type === "OrthographicCamera") {
|
|
|
|
const oCamera = camera;
|
|
|
|
size.wWidth = oCamera.right - oCamera.left;
|
|
|
|
size.wHeight = oCamera.top - oCamera.bottom;
|
2021-03-04 04:49:22 +08:00
|
|
|
} else {
|
2021-04-05 04:02:11 +08:00
|
|
|
const wsize = getCameraSize();
|
2021-04-29 00:07:58 +08:00
|
|
|
size.wWidth = wsize[0];
|
|
|
|
size.wHeight = wsize[1];
|
2021-03-04 04:49:22 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
function getCameraSize() {
|
2021-04-29 00:07:58 +08:00
|
|
|
const camera = obj.camera;
|
|
|
|
const vFOV = camera.fov * Math.PI / 180;
|
|
|
|
const h = 2 * Math.tan(vFOV / 2) * Math.abs(camera.position.z);
|
|
|
|
const w = h * camera.aspect;
|
2021-03-04 04:49:22 +08:00
|
|
|
return [w, h];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-29 00:07:58 +08:00
|
|
|
const RendererInjectionKey = Symbol("Renderer");
|
2021-04-05 04:02:11 +08:00
|
|
|
var Renderer = vue.defineComponent({
|
2021-04-29 00:07:58 +08:00
|
|
|
name: "Renderer",
|
2021-03-04 04:49:22 +08:00
|
|
|
props: {
|
|
|
|
antialias: Boolean,
|
|
|
|
alpha: Boolean,
|
2021-04-29 00:07:58 +08:00
|
|
|
autoClear: {type: Boolean, default: true},
|
|
|
|
orbitCtrl: {type: [Boolean, Object], default: false},
|
|
|
|
pointer: {type: [Boolean, Object], default: false},
|
|
|
|
resize: {type: [Boolean, String], default: false},
|
2021-03-04 04:49:22 +08:00
|
|
|
shadow: Boolean,
|
2021-04-30 05:07:04 +08:00
|
|
|
shadowType: {type: Number, default: three.PCFShadowMap},
|
|
|
|
toneMapping: {type: Number, default: three.NoToneMapping},
|
2021-03-04 04:49:22 +08:00
|
|
|
width: String,
|
|
|
|
height: String,
|
2021-04-05 04:02:11 +08:00
|
|
|
xr: Boolean,
|
2021-04-29 00:07:58 +08:00
|
|
|
onReady: Function,
|
|
|
|
onClick: Function
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
setup(props) {
|
|
|
|
const initCallbacks = [];
|
|
|
|
const mountedCallbacks = [];
|
|
|
|
const beforeRenderCallbacks = [];
|
|
|
|
const afterRenderCallbacks = [];
|
|
|
|
const resizeCallbacks = [];
|
|
|
|
const canvas = document.createElement("canvas");
|
|
|
|
const config = {
|
|
|
|
canvas,
|
|
|
|
antialias: props.antialias,
|
|
|
|
alpha: props.alpha,
|
|
|
|
autoClear: props.autoClear,
|
|
|
|
orbitCtrl: props.orbitCtrl,
|
|
|
|
pointer: props.pointer,
|
|
|
|
resize: props.resize
|
|
|
|
};
|
|
|
|
if (props.width)
|
|
|
|
config.width = parseInt(props.width);
|
|
|
|
if (props.height)
|
|
|
|
config.height = parseInt(props.height);
|
|
|
|
const three = useThree(config);
|
2021-04-30 05:07:04 +08:00
|
|
|
bindProp(props, "toneMapping", three.renderer);
|
2021-04-29 00:07:58 +08:00
|
|
|
const renderFn = () => {
|
|
|
|
};
|
|
|
|
if (props.onClick) {
|
|
|
|
canvas.addEventListener("click", props.onClick);
|
|
|
|
}
|
2021-03-04 04:49:22 +08:00
|
|
|
return {
|
2021-04-29 00:07:58 +08:00
|
|
|
canvas,
|
|
|
|
three,
|
|
|
|
renderer: three.renderer,
|
|
|
|
size: three.size,
|
|
|
|
renderFn,
|
2021-03-04 04:49:22 +08:00
|
|
|
raf: true,
|
2021-04-29 00:07:58 +08:00
|
|
|
initCallbacks,
|
|
|
|
mountedCallbacks,
|
|
|
|
beforeRenderCallbacks,
|
|
|
|
afterRenderCallbacks,
|
|
|
|
resizeCallbacks
|
2021-03-04 04:49:22 +08:00
|
|
|
};
|
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
computed: {
|
|
|
|
camera: {
|
|
|
|
get: function() {
|
|
|
|
return this.three.camera;
|
|
|
|
},
|
|
|
|
set: function(camera) {
|
|
|
|
this.three.camera = camera;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
scene: {
|
|
|
|
get: function() {
|
|
|
|
return this.three.scene;
|
|
|
|
},
|
|
|
|
set: function(scene) {
|
|
|
|
this.three.scene = scene;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
composer: {
|
|
|
|
get: function() {
|
|
|
|
return this.three.composer;
|
|
|
|
},
|
|
|
|
set: function(composer) {
|
|
|
|
this.three.composer = composer;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
provide() {
|
2021-03-04 04:49:22 +08:00
|
|
|
return {
|
2021-04-29 00:07:58 +08:00
|
|
|
[RendererInjectionKey]: this
|
2021-03-04 04:49:22 +08:00
|
|
|
};
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
mounted() {
|
2021-04-29 00:07:58 +08:00
|
|
|
var _a;
|
|
|
|
this.$el.parentNode.insertBefore(this.canvas, this.$el);
|
|
|
|
if (this.three.init()) {
|
|
|
|
this.three.config.onResize = (size) => {
|
|
|
|
this.resizeCallbacks.forEach((e) => e({type: "resize", renderer: this, size}));
|
|
|
|
};
|
2021-04-30 05:07:04 +08:00
|
|
|
if (this.shadow) {
|
|
|
|
this.renderer.shadowMap.enabled = true;
|
|
|
|
this.renderer.shadowMap.type = this.shadowType;
|
|
|
|
}
|
2021-04-29 00:07:58 +08:00
|
|
|
this.renderFn = this.three.composer ? this.three.renderC : this.three.render;
|
|
|
|
this.initCallbacks.forEach((e) => e({type: "init", renderer: this}));
|
|
|
|
(_a = this.onReady) == null ? void 0 : _a.call(this, this);
|
2021-04-05 04:02:11 +08:00
|
|
|
if (this.xr) {
|
|
|
|
this.renderer.xr.enabled = true;
|
2021-04-07 03:46:35 +08:00
|
|
|
this.renderer.setAnimationLoop(this.render);
|
2021-04-05 04:02:11 +08:00
|
|
|
} else {
|
2021-04-07 03:46:35 +08:00
|
|
|
requestAnimationFrame(this.renderLoop);
|
2021-04-05 04:02:11 +08:00
|
|
|
}
|
2021-03-04 04:49:22 +08:00
|
|
|
}
|
2021-04-29 00:07:58 +08:00
|
|
|
this.mountedCallbacks.forEach((e) => e({type: "mounted", renderer: this}));
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
beforeUnmount() {
|
2021-04-29 00:07:58 +08:00
|
|
|
this.canvas.remove();
|
2021-04-07 03:46:35 +08:00
|
|
|
this.beforeRenderCallbacks = [];
|
|
|
|
this.afterRenderCallbacks = [];
|
2021-03-04 04:49:22 +08:00
|
|
|
this.raf = false;
|
|
|
|
this.three.dispose();
|
|
|
|
},
|
|
|
|
methods: {
|
2021-04-29 00:07:58 +08:00
|
|
|
onInit(cb) {
|
|
|
|
this.addListener("init", cb);
|
|
|
|
},
|
2021-04-07 03:46:35 +08:00
|
|
|
onMounted(cb) {
|
2021-04-29 00:07:58 +08:00
|
|
|
this.addListener("mounted", cb);
|
2021-04-07 03:46:35 +08:00
|
|
|
},
|
|
|
|
onBeforeRender(cb) {
|
2021-04-29 00:07:58 +08:00
|
|
|
this.addListener("beforerender", cb);
|
2021-04-07 03:46:35 +08:00
|
|
|
},
|
|
|
|
offBeforeRender(cb) {
|
2021-04-29 00:07:58 +08:00
|
|
|
this.removeListener("beforerender", cb);
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-07 03:46:35 +08:00
|
|
|
onAfterRender(cb) {
|
2021-04-29 00:07:58 +08:00
|
|
|
this.addListener("afterrender", cb);
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-07 03:46:35 +08:00
|
|
|
offAfterRender(cb) {
|
2021-04-29 00:07:58 +08:00
|
|
|
this.removeListener("afterrender", cb);
|
|
|
|
},
|
|
|
|
onResize(cb) {
|
|
|
|
this.addListener("resize", cb);
|
|
|
|
},
|
|
|
|
offResize(cb) {
|
|
|
|
this.removeListener("resize", cb);
|
|
|
|
},
|
|
|
|
addListener(type, cb) {
|
|
|
|
const callbacks = this.getCallbacks(type);
|
|
|
|
callbacks.push(cb);
|
|
|
|
},
|
|
|
|
removeListener(type, cb) {
|
|
|
|
const callbacks = this.getCallbacks(type);
|
|
|
|
const index = callbacks.indexOf(cb);
|
|
|
|
if (index)
|
|
|
|
callbacks.splice(index, 1);
|
|
|
|
},
|
|
|
|
getCallbacks(type) {
|
|
|
|
if (type === "init") {
|
|
|
|
return this.initCallbacks;
|
|
|
|
} else if (type === "mounted") {
|
|
|
|
return this.mountedCallbacks;
|
|
|
|
} else if (type === "beforerender") {
|
|
|
|
return this.beforeRenderCallbacks;
|
|
|
|
} else if (type === "afterrender") {
|
|
|
|
return this.afterRenderCallbacks;
|
|
|
|
} else {
|
|
|
|
return this.resizeCallbacks;
|
|
|
|
}
|
2021-04-07 03:46:35 +08:00
|
|
|
},
|
|
|
|
render(time) {
|
2021-04-29 00:07:58 +08:00
|
|
|
this.beforeRenderCallbacks.forEach((e) => e({type: "beforerender", renderer: this, time}));
|
2021-04-30 05:07:04 +08:00
|
|
|
this.renderFn({renderer: this, time});
|
2021-04-29 00:07:58 +08:00
|
|
|
this.afterRenderCallbacks.forEach((e) => e({type: "afterrender", renderer: this, time}));
|
2021-04-07 03:46:35 +08:00
|
|
|
},
|
|
|
|
renderLoop(time) {
|
2021-04-29 00:07:58 +08:00
|
|
|
if (this.raf)
|
|
|
|
requestAnimationFrame(this.renderLoop);
|
2021-04-07 03:46:35 +08:00
|
|
|
this.render(time);
|
2021-04-29 00:07:58 +08:00
|
|
|
}
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
render() {
|
2021-04-29 00:07:58 +08:00
|
|
|
return this.$slots.default ? this.$slots.default() : [];
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
__hmrId: "Renderer"
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
2021-03-04 04:49:22 +08:00
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
var Camera = vue.defineComponent({
|
|
|
|
render() {
|
|
|
|
return this.$slots.default ? this.$slots.default() : [];
|
2021-04-29 00:07:58 +08:00
|
|
|
}
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
2021-03-14 02:34:34 +08:00
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
var OrthographicCamera = vue.defineComponent({
|
|
|
|
extends: Camera,
|
2021-04-29 00:07:58 +08:00
|
|
|
name: "OrthographicCamera",
|
2021-03-04 04:49:22 +08:00
|
|
|
props: {
|
2021-04-29 00:07:58 +08:00
|
|
|
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: 2e3},
|
|
|
|
zoom: {type: Number, default: 1},
|
|
|
|
position: {type: Object, default: () => ({x: 0, y: 0, z: 0})}
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
setup(props) {
|
|
|
|
const renderer = vue.inject(RendererInjectionKey);
|
|
|
|
if (!renderer) {
|
|
|
|
console.error("Renderer not found");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const camera = new three.OrthographicCamera(props.left, props.right, props.top, props.bottom, props.near, props.far);
|
|
|
|
renderer.camera = camera;
|
|
|
|
bindProp(props, "position", camera);
|
|
|
|
const watchProps = ["left", "right", "top", "bottom", "near", "far", "zoom"];
|
|
|
|
watchProps.forEach((p) => {
|
|
|
|
vue.watch(() => props[p], (value) => {
|
|
|
|
camera[p] = value;
|
|
|
|
camera.updateProjectionMatrix();
|
2021-03-04 04:49:22 +08:00
|
|
|
});
|
|
|
|
});
|
2021-04-29 00:07:58 +08:00
|
|
|
return {renderer, camera};
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
__hmrId: "OrthographicCamera"
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
2021-03-04 04:49:22 +08:00
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
var PerspectiveCamera = vue.defineComponent({
|
|
|
|
extends: Camera,
|
2021-04-29 00:07:58 +08:00
|
|
|
name: "PerspectiveCamera",
|
2021-03-04 04:49:22 +08:00
|
|
|
props: {
|
2021-04-29 00:07:58 +08:00
|
|
|
aspect: {type: Number, default: 1},
|
|
|
|
far: {type: Number, default: 2e3},
|
|
|
|
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}
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
setup(props) {
|
|
|
|
var _a;
|
|
|
|
const renderer = vue.inject(RendererInjectionKey);
|
|
|
|
if (!renderer) {
|
|
|
|
console.error("Renderer not found");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const camera = new three.PerspectiveCamera(props.fov, props.aspect, props.near, props.far);
|
|
|
|
renderer.camera = camera;
|
|
|
|
bindProp(props, "position", camera);
|
|
|
|
if (props.lookAt)
|
|
|
|
camera.lookAt((_a = props.lookAt.x) != null ? _a : 0, props.lookAt.y, props.lookAt.z);
|
|
|
|
vue.watch(() => props.lookAt, (v) => {
|
|
|
|
var _a2;
|
|
|
|
camera.lookAt((_a2 = v.x) != null ? _a2 : 0, v.y, v.z);
|
|
|
|
}, {deep: true});
|
|
|
|
const watchProps = ["aspect", "far", "fov", "near"];
|
|
|
|
watchProps.forEach((p) => {
|
|
|
|
vue.watch(() => props[p], (value) => {
|
|
|
|
camera[p] = value;
|
|
|
|
camera.updateProjectionMatrix();
|
2021-03-04 04:49:22 +08:00
|
|
|
});
|
|
|
|
});
|
2021-04-29 00:07:58 +08:00
|
|
|
return {renderer, camera};
|
|
|
|
},
|
|
|
|
__hmrId: "PerspectiveCamera"
|
|
|
|
});
|
2021-03-04 04:49:22 +08:00
|
|
|
|
2021-04-29 00:07:58 +08:00
|
|
|
const SceneInjectionKey = Symbol("Scene");
|
|
|
|
var Scene = vue.defineComponent({
|
|
|
|
name: "Scene",
|
|
|
|
props: {
|
|
|
|
background: [String, Number, Object]
|
|
|
|
},
|
|
|
|
setup(props) {
|
|
|
|
const renderer = vue.inject(RendererInjectionKey);
|
|
|
|
const scene = new three.Scene();
|
|
|
|
if (!renderer) {
|
|
|
|
console.error("Renderer not found");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
renderer.scene = scene;
|
|
|
|
vue.provide(SceneInjectionKey, scene);
|
|
|
|
const setBackground = (value) => {
|
|
|
|
if (!value)
|
|
|
|
return;
|
|
|
|
if (typeof value === "string" || typeof value === "number") {
|
|
|
|
if (scene.background instanceof three.Color)
|
|
|
|
scene.background.set(value);
|
|
|
|
else
|
|
|
|
scene.background = new three.Color(value);
|
|
|
|
} else if (value instanceof three.Texture) {
|
|
|
|
scene.background = value;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
setBackground(props.background);
|
|
|
|
vue.watch(() => props.background, setBackground);
|
|
|
|
const add = (o) => {
|
|
|
|
scene.add(o);
|
|
|
|
};
|
|
|
|
const remove = (o) => {
|
|
|
|
scene.remove(o);
|
|
|
|
};
|
|
|
|
return {scene, add, remove};
|
|
|
|
},
|
|
|
|
render() {
|
|
|
|
return this.$slots.default ? this.$slots.default() : [];
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
__hmrId: "Scene"
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
2021-03-04 04:49:22 +08:00
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
var Object3D = vue.defineComponent({
|
2021-04-29 00:07:58 +08:00
|
|
|
name: "Object3D",
|
|
|
|
inject: {
|
|
|
|
renderer: RendererInjectionKey,
|
|
|
|
scene: SceneInjectionKey
|
|
|
|
},
|
|
|
|
emits: ["created", "ready"],
|
2021-03-04 04:49:22 +08:00
|
|
|
props: {
|
2021-04-29 00:07:58 +08:00
|
|
|
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, order: "XYZ"})},
|
|
|
|
lookAt: {type: Object, default: null},
|
|
|
|
autoRemove: {type: Boolean, default: true},
|
|
|
|
userData: {type: Object, default: () => ({})}
|
|
|
|
},
|
|
|
|
setup() {
|
|
|
|
return {};
|
|
|
|
},
|
|
|
|
created() {
|
|
|
|
if (!this.renderer) {
|
|
|
|
console.error("Missing parent Renderer");
|
|
|
|
}
|
|
|
|
if (!this.scene) {
|
|
|
|
console.error("Missing parent Scene");
|
|
|
|
}
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
unmounted() {
|
2021-04-29 00:07:58 +08:00
|
|
|
if (this.autoRemove)
|
|
|
|
this.removeFromParent();
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-03-08 04:17:46 +08:00
|
|
|
methods: {
|
2021-04-05 04:02:11 +08:00
|
|
|
initObject3D(o3d) {
|
2021-04-29 00:07:58 +08:00
|
|
|
var _a;
|
2021-03-08 04:17:46 +08:00
|
|
|
this.o3d = o3d;
|
2021-04-29 00:07:58 +08:00
|
|
|
this.$emit("created", o3d);
|
|
|
|
bindProp(this, "position", o3d);
|
|
|
|
bindProp(this, "rotation", o3d);
|
|
|
|
bindProp(this, "scale", o3d);
|
|
|
|
bindProp(this, "userData", o3d.userData);
|
|
|
|
if (this.lookAt)
|
|
|
|
o3d.lookAt((_a = this.lookAt.x) != null ? _a : 0, this.lookAt.y, this.lookAt.z);
|
|
|
|
vue.watch(() => this.lookAt, (v) => {
|
|
|
|
var _a2;
|
|
|
|
o3d.lookAt((_a2 = v.x) != null ? _a2 : 0, v.y, v.z);
|
|
|
|
}, {deep: true});
|
|
|
|
this.parent = this.getParent();
|
|
|
|
if (this.addToParent())
|
|
|
|
this.$emit("ready", this);
|
|
|
|
else
|
|
|
|
console.error("Missing parent (Scene, Group...)");
|
2021-04-05 04:02:11 +08:00
|
|
|
},
|
|
|
|
getParent() {
|
|
|
|
let parent = this.$parent;
|
2021-03-14 02:34:34 +08:00
|
|
|
while (parent) {
|
2021-04-29 00:07:58 +08:00
|
|
|
if (parent.add)
|
|
|
|
return parent;
|
2021-03-14 02:34:34 +08:00
|
|
|
parent = parent.$parent;
|
|
|
|
}
|
2021-04-29 00:07:58 +08:00
|
|
|
return void 0;
|
2021-04-05 04:02:11 +08:00
|
|
|
},
|
|
|
|
addToParent(o) {
|
|
|
|
const o3d = o || this.o3d;
|
2021-04-29 00:07:58 +08:00
|
|
|
if (this.parent) {
|
|
|
|
this.parent.add(o3d);
|
2021-04-05 04:02:11 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
2021-03-08 04:17:46 +08:00
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
removeFromParent(o) {
|
|
|
|
const o3d = o || this.o3d;
|
2021-04-29 00:07:58 +08:00
|
|
|
if (this.parent) {
|
|
|
|
this.parent.remove(o3d);
|
2021-04-05 04:02:11 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
add(o) {
|
|
|
|
var _a;
|
|
|
|
(_a = this.o3d) == null ? void 0 : _a.add(o);
|
|
|
|
},
|
|
|
|
remove(o) {
|
|
|
|
var _a;
|
|
|
|
(_a = this.o3d) == null ? void 0 : _a.remove(o);
|
|
|
|
}
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
render() {
|
2021-03-08 04:17:46 +08:00
|
|
|
return this.$slots.default ? this.$slots.default() : [];
|
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
__hmrId: "Object3D"
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
2021-03-08 04:17:46 +08:00
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
var Group = vue.defineComponent({
|
2021-04-29 00:07:58 +08:00
|
|
|
name: "Group",
|
2021-03-08 04:17:46 +08:00
|
|
|
extends: Object3D,
|
2021-04-29 00:07:58 +08:00
|
|
|
setup() {
|
2021-03-04 04:49:22 +08:00
|
|
|
return {
|
2021-04-29 00:07:58 +08:00
|
|
|
group: new three.Group()
|
2021-03-04 04:49:22 +08:00
|
|
|
};
|
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
created() {
|
|
|
|
this.initObject3D(this.group);
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
__hmrId: "Group"
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
|
|
|
|
2021-04-29 00:07:58 +08:00
|
|
|
const emptyCallBack = () => {
|
|
|
|
};
|
2021-04-05 04:02:11 +08:00
|
|
|
var Raycaster = vue.defineComponent({
|
2021-04-29 00:07:58 +08:00
|
|
|
name: "Raycaster",
|
2021-04-05 04:02:11 +08:00
|
|
|
props: {
|
2021-04-29 00:07:58 +08:00
|
|
|
onPointerEnter: {type: Function, default: emptyCallBack},
|
|
|
|
onPointerOver: {type: Function, default: emptyCallBack},
|
|
|
|
onPointerMove: {type: Function, default: emptyCallBack},
|
|
|
|
onPointerLeave: {type: Function, default: emptyCallBack},
|
|
|
|
onClick: {type: Function, default: emptyCallBack},
|
|
|
|
intersectMode: {type: String, default: "move"}
|
|
|
|
},
|
|
|
|
setup() {
|
|
|
|
const renderer = vue.inject(RendererInjectionKey);
|
|
|
|
return {renderer};
|
2021-04-05 04:02:11 +08:00
|
|
|
},
|
|
|
|
mounted() {
|
2021-04-29 00:07:58 +08:00
|
|
|
if (!this.renderer) {
|
|
|
|
console.error("Renderer not found");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const renderer = this.renderer;
|
|
|
|
this.renderer.onMounted(() => {
|
|
|
|
if (!renderer.camera)
|
|
|
|
return;
|
2021-04-05 04:02:11 +08:00
|
|
|
this.pointer = usePointer({
|
2021-04-29 00:07:58 +08:00
|
|
|
camera: renderer.camera,
|
|
|
|
domElement: renderer.canvas,
|
2021-04-05 04:02:11 +08:00
|
|
|
intersectObjects: this.getIntersectObjects(),
|
|
|
|
onIntersectEnter: this.onPointerEnter,
|
|
|
|
onIntersectOver: this.onPointerOver,
|
|
|
|
onIntersectMove: this.onPointerMove,
|
|
|
|
onIntersectLeave: this.onPointerLeave,
|
2021-04-29 00:07:58 +08:00
|
|
|
onIntersectClick: this.onClick
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
|
|
|
this.pointer.addListeners();
|
2021-04-29 00:07:58 +08:00
|
|
|
if (this.intersectMode === "frame") {
|
|
|
|
renderer.onBeforeRender(this.pointer.intersect);
|
2021-04-05 04:02:11 +08:00
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
|
|
|
unmounted() {
|
2021-04-29 00:07:58 +08:00
|
|
|
var _a;
|
2021-04-05 04:02:11 +08:00
|
|
|
if (this.pointer) {
|
|
|
|
this.pointer.removeListeners();
|
2021-04-29 00:07:58 +08:00
|
|
|
(_a = this.renderer) == null ? void 0 : _a.offBeforeRender(this.pointer.intersect);
|
2021-04-05 04:02:11 +08:00
|
|
|
}
|
|
|
|
},
|
|
|
|
methods: {
|
|
|
|
getIntersectObjects() {
|
2021-04-29 00:07:58 +08:00
|
|
|
if (this.renderer && this.renderer.scene) {
|
|
|
|
const children = this.renderer.scene.children.filter((c) => ["Mesh", "InstancedMesh"].includes(c.type));
|
|
|
|
return children;
|
|
|
|
}
|
|
|
|
return [];
|
|
|
|
}
|
|
|
|
},
|
|
|
|
render() {
|
|
|
|
return [];
|
|
|
|
},
|
|
|
|
__hmrId: "Raycaster"
|
|
|
|
});
|
|
|
|
|
|
|
|
var CubeCamera = vue.defineComponent({
|
|
|
|
extends: Object3D,
|
|
|
|
props: {
|
|
|
|
cubeRTSize: {type: Number, default: 256},
|
|
|
|
cubeCameraNear: {type: Number, default: 0.1},
|
|
|
|
cubeCameraFar: {type: Number, default: 2e3},
|
|
|
|
autoUpdate: Boolean
|
|
|
|
},
|
|
|
|
setup(props) {
|
|
|
|
const rendererC = vue.inject(RendererInjectionKey);
|
|
|
|
if (!rendererC || !rendererC.scene) {
|
|
|
|
console.error("Missing Renderer / Scene");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const renderer = rendererC.renderer, scene = rendererC.scene;
|
|
|
|
const cubeRT = new three.WebGLCubeRenderTarget(props.cubeRTSize, {format: three.RGBFormat, generateMipmaps: true, minFilter: three.LinearMipmapLinearFilter});
|
|
|
|
const cubeCamera = new three.CubeCamera(props.cubeCameraNear, props.cubeCameraFar, cubeRT);
|
|
|
|
const updateRT = () => {
|
|
|
|
cubeCamera.update(renderer, scene);
|
|
|
|
};
|
|
|
|
if (props.autoUpdate) {
|
|
|
|
rendererC.onBeforeRender(updateRT);
|
|
|
|
vue.onUnmounted(() => {
|
|
|
|
rendererC.offBeforeRender(updateRT);
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
rendererC.onMounted(updateRT);
|
|
|
|
}
|
|
|
|
return {cubeRT, cubeCamera};
|
2021-04-05 04:02:11 +08:00
|
|
|
},
|
|
|
|
render() {
|
|
|
|
return [];
|
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
__hmrId: "CubeCamera"
|
|
|
|
});
|
|
|
|
|
|
|
|
const pointerProps = {
|
|
|
|
onPointerEnter: Function,
|
|
|
|
onPointerOver: Function,
|
|
|
|
onPointerMove: Function,
|
|
|
|
onPointerLeave: Function,
|
|
|
|
onPointerDown: Function,
|
|
|
|
onPointerUp: Function,
|
|
|
|
onClick: Function
|
|
|
|
};
|
|
|
|
const MeshInjectionKey = Symbol("Mesh");
|
|
|
|
const Mesh = vue.defineComponent({
|
|
|
|
name: "Mesh",
|
|
|
|
extends: Object3D,
|
|
|
|
props: {
|
|
|
|
castShadow: Boolean,
|
|
|
|
receiveShadow: Boolean,
|
|
|
|
...pointerProps
|
|
|
|
},
|
|
|
|
setup() {
|
|
|
|
return {};
|
|
|
|
},
|
|
|
|
provide() {
|
|
|
|
return {
|
|
|
|
[MeshInjectionKey]: this
|
|
|
|
};
|
|
|
|
},
|
|
|
|
mounted() {
|
|
|
|
if (!this.mesh && !this.loading)
|
|
|
|
this.initMesh();
|
|
|
|
},
|
|
|
|
methods: {
|
|
|
|
initMesh() {
|
|
|
|
const mesh = new three.Mesh(this.geometry, this.material);
|
|
|
|
mesh.userData.component = this;
|
|
|
|
bindProp(this, "castShadow", mesh);
|
|
|
|
bindProp(this, "receiveShadow", mesh);
|
|
|
|
if (this.onPointerEnter || this.onPointerOver || this.onPointerMove || this.onPointerLeave || this.onPointerDown || this.onPointerUp || this.onClick) {
|
|
|
|
if (this.renderer)
|
|
|
|
this.renderer.three.addIntersectObject(mesh);
|
|
|
|
}
|
|
|
|
this.mesh = mesh;
|
|
|
|
this.initObject3D(mesh);
|
|
|
|
},
|
|
|
|
createGeometry() {
|
|
|
|
},
|
|
|
|
addGeometryWatchers(props) {
|
|
|
|
Object.keys(props).forEach((prop) => {
|
|
|
|
vue.watch(() => this[prop], () => {
|
|
|
|
this.refreshGeometry();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
},
|
|
|
|
setGeometry(geometry) {
|
|
|
|
this.geometry = geometry;
|
|
|
|
if (this.mesh)
|
|
|
|
this.mesh.geometry = geometry;
|
|
|
|
},
|
|
|
|
setMaterial(material) {
|
|
|
|
this.material = material;
|
|
|
|
if (this.mesh)
|
|
|
|
this.mesh.material = material;
|
|
|
|
},
|
|
|
|
refreshGeometry() {
|
|
|
|
const oldGeo = this.geometry;
|
|
|
|
this.createGeometry();
|
|
|
|
if (this.mesh && this.geometry)
|
|
|
|
this.mesh.geometry = this.geometry;
|
|
|
|
oldGeo == null ? void 0 : oldGeo.dispose();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
unmounted() {
|
|
|
|
if (this.mesh) {
|
|
|
|
if (this.renderer)
|
|
|
|
this.renderer.three.removeIntersectObject(this.mesh);
|
|
|
|
}
|
|
|
|
if (this.geometry)
|
|
|
|
this.geometry.dispose();
|
|
|
|
if (this.material)
|
|
|
|
this.material.dispose();
|
|
|
|
},
|
|
|
|
__hmrId: "Mesh"
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
2021-04-29 00:07:58 +08:00
|
|
|
function meshComponent(name, props, createGeometry) {
|
|
|
|
return vue.defineComponent({
|
|
|
|
name,
|
|
|
|
extends: Mesh,
|
|
|
|
props,
|
|
|
|
created() {
|
|
|
|
this.createGeometry();
|
|
|
|
this.addGeometryWatchers(props);
|
|
|
|
},
|
|
|
|
methods: {
|
|
|
|
createGeometry() {
|
|
|
|
this.geometry = createGeometry(this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2021-03-04 04:49:22 +08:00
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
const Geometry = vue.defineComponent({
|
2021-03-04 04:49:22 +08:00
|
|
|
props: {
|
|
|
|
rotateX: Number,
|
|
|
|
rotateY: Number,
|
2021-04-30 05:07:04 +08:00
|
|
|
rotateZ: Number,
|
|
|
|
attributes: {type: Array, default: () => []}
|
2021-04-29 00:07:58 +08:00
|
|
|
},
|
|
|
|
inject: {
|
|
|
|
mesh: MeshInjectionKey
|
|
|
|
},
|
|
|
|
setup() {
|
|
|
|
return {};
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
created() {
|
2021-03-04 04:49:22 +08:00
|
|
|
if (!this.mesh) {
|
2021-04-29 00:07:58 +08:00
|
|
|
console.error("Missing parent Mesh");
|
|
|
|
return;
|
2021-03-04 04:49:22 +08:00
|
|
|
}
|
|
|
|
this.createGeometry();
|
|
|
|
this.rotateGeometry();
|
2021-04-29 00:07:58 +08:00
|
|
|
if (this.geometry)
|
|
|
|
this.mesh.setGeometry(this.geometry);
|
|
|
|
Object.keys(this.$props).forEach((prop) => {
|
|
|
|
vue.watch(() => this[prop], this.refreshGeometry);
|
|
|
|
});
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
unmounted() {
|
2021-04-29 00:07:58 +08:00
|
|
|
var _a;
|
|
|
|
(_a = this.geometry) == null ? void 0 : _a.dispose();
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
|
|
|
methods: {
|
2021-04-29 00:07:58 +08:00
|
|
|
createGeometry() {
|
2021-04-30 05:07:04 +08:00
|
|
|
const bufferAttributes = {};
|
|
|
|
const geometry = new three.BufferGeometry();
|
|
|
|
this.attributes.forEach((attribute) => {
|
|
|
|
if (attribute.name && attribute.itemSize && attribute.array) {
|
|
|
|
const bufferAttribute = bufferAttributes[attribute.name] = new three.BufferAttribute(attribute.array, attribute.itemSize, attribute.normalized);
|
|
|
|
geometry.setAttribute(attribute.name, bufferAttribute);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
geometry.computeBoundingBox();
|
|
|
|
this.geometry = geometry;
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
rotateGeometry() {
|
2021-04-29 00:07:58 +08:00
|
|
|
if (!this.geometry)
|
|
|
|
return;
|
|
|
|
if (this.rotateX)
|
|
|
|
this.geometry.rotateX(this.rotateX);
|
|
|
|
if (this.rotateY)
|
|
|
|
this.geometry.rotateY(this.rotateY);
|
|
|
|
if (this.rotateZ)
|
|
|
|
this.geometry.rotateZ(this.rotateZ);
|
2021-03-08 04:17:46 +08:00
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
refreshGeometry() {
|
|
|
|
const oldGeo = this.geometry;
|
2021-03-04 04:49:22 +08:00
|
|
|
this.createGeometry();
|
|
|
|
this.rotateGeometry();
|
2021-04-29 00:07:58 +08:00
|
|
|
if (this.geometry && this.mesh)
|
|
|
|
this.mesh.setGeometry(this.geometry);
|
|
|
|
oldGeo == null ? void 0 : oldGeo.dispose();
|
|
|
|
}
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
render() {
|
|
|
|
return [];
|
|
|
|
}
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
|
|
|
function geometryComponent(name, props, createGeometry) {
|
|
|
|
return vue.defineComponent({
|
|
|
|
name,
|
|
|
|
extends: Geometry,
|
|
|
|
props,
|
|
|
|
methods: {
|
|
|
|
createGeometry() {
|
|
|
|
this.geometry = createGeometry(this);
|
2021-04-29 00:07:58 +08:00
|
|
|
}
|
|
|
|
}
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2021-04-29 00:07:58 +08:00
|
|
|
const props$n = {
|
2021-04-05 04:02:11 +08:00
|
|
|
size: Number,
|
2021-04-29 00:07:58 +08:00
|
|
|
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}
|
2021-03-04 04:49:22 +08:00
|
|
|
};
|
2021-04-05 04:02:11 +08:00
|
|
|
function createGeometry$f(comp) {
|
|
|
|
if (comp.size) {
|
|
|
|
return new three.BoxGeometry(comp.size, comp.size, comp.size, comp.widthSegments, comp.heightSegments, comp.depthSegments);
|
|
|
|
} else {
|
|
|
|
return new three.BoxGeometry(comp.width, comp.height, comp.depth, comp.widthSegments, comp.heightSegments, comp.depthSegments);
|
|
|
|
}
|
|
|
|
}
|
2021-04-29 00:07:58 +08:00
|
|
|
var BoxGeometry = geometryComponent("BoxGeometry", props$n, createGeometry$f);
|
2021-04-05 04:02:11 +08:00
|
|
|
|
2021-04-29 00:07:58 +08:00
|
|
|
const props$m = {
|
|
|
|
radius: {type: Number, default: 1},
|
|
|
|
segments: {type: Number, default: 8},
|
|
|
|
thetaStart: {type: Number, default: 0},
|
|
|
|
thetaLength: {type: Number, default: Math.PI * 2}
|
2021-03-04 04:49:22 +08:00
|
|
|
};
|
2021-04-05 04:02:11 +08:00
|
|
|
function createGeometry$e(comp) {
|
|
|
|
return new three.CircleGeometry(comp.radius, comp.segments, comp.thetaStart, comp.thetaLength);
|
|
|
|
}
|
2021-04-29 00:07:58 +08:00
|
|
|
var CircleGeometry = geometryComponent("CircleGeometry", props$m, createGeometry$e);
|
|
|
|
|
|
|
|
const props$l = {
|
|
|
|
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}
|
2021-03-04 04:49:22 +08:00
|
|
|
};
|
2021-04-05 04:02:11 +08:00
|
|
|
function createGeometry$d(comp) {
|
|
|
|
return new three.ConeGeometry(comp.radius, comp.height, comp.radialSegments, comp.heightSegments, comp.openEnded, comp.thetaStart, comp.thetaLength);
|
|
|
|
}
|
2021-04-29 00:07:58 +08:00
|
|
|
var ConeGeometry = geometryComponent("ConeGeometry", props$l, createGeometry$d);
|
|
|
|
|
|
|
|
const props$k = {
|
|
|
|
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}
|
2021-03-04 04:49:22 +08:00
|
|
|
};
|
2021-04-05 04:02:11 +08:00
|
|
|
function createGeometry$c(comp) {
|
|
|
|
return new three.CylinderGeometry(comp.radiusTop, comp.radiusBottom, comp.height, comp.radialSegments, comp.heightSegments, comp.openEnded, comp.thetaStart, comp.thetaLength);
|
|
|
|
}
|
2021-04-29 00:07:58 +08:00
|
|
|
var CylinderGeometry = geometryComponent("CylinderGeometry", props$k, createGeometry$c);
|
2021-04-05 04:02:11 +08:00
|
|
|
|
2021-04-29 00:07:58 +08:00
|
|
|
const props$j = {
|
|
|
|
radius: {type: Number, default: 1},
|
|
|
|
detail: {type: Number, default: 0}
|
2021-03-04 04:49:22 +08:00
|
|
|
};
|
2021-04-05 04:02:11 +08:00
|
|
|
function createGeometry$b(comp) {
|
|
|
|
return new three.DodecahedronGeometry(comp.radius, comp.detail);
|
|
|
|
}
|
2021-04-29 00:07:58 +08:00
|
|
|
var DodecahedronGeometry = geometryComponent("DodecahedronGeometry", props$j, createGeometry$b);
|
2021-04-05 04:02:11 +08:00
|
|
|
|
2021-04-29 00:07:58 +08:00
|
|
|
const props$i = {
|
|
|
|
radius: {type: Number, default: 1},
|
|
|
|
detail: {type: Number, default: 0}
|
2021-03-04 04:49:22 +08:00
|
|
|
};
|
2021-04-05 04:02:11 +08:00
|
|
|
function createGeometry$a(comp) {
|
|
|
|
return new three.IcosahedronGeometry(comp.radius, comp.detail);
|
|
|
|
}
|
2021-04-29 00:07:58 +08:00
|
|
|
var IcosahedronGeometry = geometryComponent("IcosahedronGeometry", props$i, createGeometry$a);
|
2021-04-05 04:02:11 +08:00
|
|
|
|
2021-04-29 00:07:58 +08:00
|
|
|
const props$h = {
|
2021-04-05 04:02:11 +08:00
|
|
|
points: Array,
|
2021-04-29 00:07:58 +08:00
|
|
|
segments: {type: Number, default: 12},
|
|
|
|
phiStart: {type: Number, default: 0},
|
|
|
|
phiLength: {type: Number, default: Math.PI * 2}
|
2021-03-04 04:49:22 +08:00
|
|
|
};
|
2021-04-05 04:02:11 +08:00
|
|
|
function createGeometry$9(comp) {
|
|
|
|
return new three.LatheGeometry(comp.points, comp.segments, comp.phiStart, comp.phiLength);
|
|
|
|
}
|
2021-04-29 00:07:58 +08:00
|
|
|
var LatheGeometry = geometryComponent("LatheGeometry", props$h, createGeometry$9);
|
2021-04-05 04:02:11 +08:00
|
|
|
|
2021-04-29 00:07:58 +08:00
|
|
|
const props$g = {
|
|
|
|
radius: {type: Number, default: 1},
|
|
|
|
detail: {type: Number, default: 0}
|
2021-03-04 04:49:22 +08:00
|
|
|
};
|
2021-04-05 04:02:11 +08:00
|
|
|
function createGeometry$8(comp) {
|
|
|
|
return new three.OctahedronGeometry(comp.radius, comp.detail);
|
|
|
|
}
|
2021-04-29 00:07:58 +08:00
|
|
|
var OctahedronGeometry = geometryComponent("OctahedronGeometry", props$g, createGeometry$8);
|
2021-04-05 04:02:11 +08:00
|
|
|
|
2021-04-29 00:07:58 +08:00
|
|
|
const props$f = {
|
|
|
|
width: {type: Number, default: 1},
|
|
|
|
height: {type: Number, default: 1},
|
|
|
|
widthSegments: {type: Number, default: 1},
|
|
|
|
heightSegments: {type: Number, default: 1}
|
2021-04-07 03:46:35 +08:00
|
|
|
};
|
|
|
|
function createGeometry$7(comp) {
|
|
|
|
return new three.PlaneGeometry(comp.width, comp.height, comp.widthSegments, comp.heightSegments);
|
|
|
|
}
|
2021-04-29 00:07:58 +08:00
|
|
|
var PlaneGeometry = geometryComponent("PlaneGeometry", props$f, createGeometry$7);
|
2021-04-07 03:46:35 +08:00
|
|
|
|
2021-04-29 00:07:58 +08:00
|
|
|
const props$e = {
|
2021-04-05 04:02:11 +08:00
|
|
|
vertices: Array,
|
|
|
|
indices: Array,
|
2021-04-29 00:07:58 +08:00
|
|
|
radius: {type: Number, default: 1},
|
|
|
|
detail: {type: Number, default: 0}
|
2021-03-04 04:49:22 +08:00
|
|
|
};
|
2021-04-07 03:46:35 +08:00
|
|
|
function createGeometry$6(comp) {
|
2021-04-05 04:02:11 +08:00
|
|
|
return new three.PolyhedronGeometry(comp.vertices, comp.indices, comp.radius, comp.detail);
|
|
|
|
}
|
2021-04-29 00:07:58 +08:00
|
|
|
var PolyhedronGeometry = geometryComponent("PolyhedronGeometry", props$e, createGeometry$6);
|
2021-04-05 04:02:11 +08:00
|
|
|
|
2021-04-29 00:07:58 +08:00
|
|
|
const props$d = {
|
|
|
|
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}
|
2021-03-04 04:49:22 +08:00
|
|
|
};
|
2021-04-07 03:46:35 +08:00
|
|
|
function createGeometry$5(comp) {
|
2021-04-05 04:02:11 +08:00
|
|
|
return new three.RingGeometry(comp.innerRadius, comp.outerRadius, comp.thetaSegments, comp.phiSegments, comp.thetaStart, comp.thetaLength);
|
|
|
|
}
|
2021-04-29 00:07:58 +08:00
|
|
|
var RingGeometry = geometryComponent("RingGeometry", props$d, createGeometry$5);
|
2021-04-05 04:02:11 +08:00
|
|
|
|
2021-04-29 00:07:58 +08:00
|
|
|
const props$c = {
|
|
|
|
radius: {type: Number, default: 1},
|
|
|
|
widthSegments: {type: Number, default: 12},
|
|
|
|
heightSegments: {type: Number, default: 12}
|
2021-03-04 04:49:22 +08:00
|
|
|
};
|
2021-04-07 03:46:35 +08:00
|
|
|
function createGeometry$4(comp) {
|
2021-04-05 04:02:11 +08:00
|
|
|
return new three.SphereGeometry(comp.radius, comp.widthSegments, comp.heightSegments);
|
|
|
|
}
|
2021-04-29 00:07:58 +08:00
|
|
|
var SphereGeometry = geometryComponent("SphereGeometry", props$c, createGeometry$4);
|
2021-04-05 04:02:11 +08:00
|
|
|
|
2021-04-29 00:07:58 +08:00
|
|
|
const props$b = {
|
|
|
|
radius: {type: Number, default: 1},
|
|
|
|
detail: {type: Number, default: 0}
|
2021-03-04 04:49:22 +08:00
|
|
|
};
|
2021-04-07 03:46:35 +08:00
|
|
|
function createGeometry$3(comp) {
|
2021-04-05 04:02:11 +08:00
|
|
|
return new three.TetrahedronGeometry(comp.radius, comp.detail);
|
|
|
|
}
|
2021-04-29 00:07:58 +08:00
|
|
|
var TetrahedronGeometry = geometryComponent("TetrahedronGeometry", props$b, createGeometry$3);
|
2021-04-05 04:02:11 +08:00
|
|
|
|
2021-04-29 00:07:58 +08:00
|
|
|
const props$a = {
|
|
|
|
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}
|
2021-03-04 04:49:22 +08:00
|
|
|
};
|
2021-04-07 03:46:35 +08:00
|
|
|
function createGeometry$2(comp) {
|
2021-04-05 04:02:11 +08:00
|
|
|
return new three.TorusGeometry(comp.radius, comp.tube, comp.radialSegments, comp.tubularSegments, comp.arc);
|
|
|
|
}
|
2021-04-29 00:07:58 +08:00
|
|
|
var TorusGeometry = geometryComponent("TorusGeometry", props$a, createGeometry$2);
|
2021-04-05 04:02:11 +08:00
|
|
|
|
2021-04-29 00:07:58 +08:00
|
|
|
const props$9 = {
|
|
|
|
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}
|
2021-03-04 04:49:22 +08:00
|
|
|
};
|
2021-04-07 03:46:35 +08:00
|
|
|
function createGeometry$1(comp) {
|
2021-04-05 04:02:11 +08:00
|
|
|
return new three.TorusKnotGeometry(comp.radius, comp.tube, comp.tubularSegments, comp.radialSegments, comp.p, comp.q);
|
|
|
|
}
|
2021-04-29 00:07:58 +08:00
|
|
|
var TorusKnotGeometry = geometryComponent("TorusKnotGeometry", props$9, createGeometry$1);
|
2021-04-05 04:02:11 +08:00
|
|
|
|
2021-04-29 00:07:58 +08:00
|
|
|
const props$8 = {
|
2021-04-05 04:02:11 +08:00
|
|
|
points: Array,
|
|
|
|
path: three.Curve,
|
2021-04-29 00:07:58 +08:00
|
|
|
tubularSegments: {type: Number, default: 64},
|
|
|
|
radius: {type: Number, default: 1},
|
|
|
|
radialSegments: {type: Number, default: 8},
|
|
|
|
closed: {type: Boolean, default: false}
|
2021-04-05 04:02:11 +08:00
|
|
|
};
|
2021-04-07 03:46:35 +08:00
|
|
|
function createGeometry(comp) {
|
2021-04-05 04:02:11 +08:00
|
|
|
let curve;
|
|
|
|
if (comp.points) {
|
|
|
|
curve = new three.CatmullRomCurve3(comp.points);
|
|
|
|
} else if (comp.path) {
|
|
|
|
curve = comp.path;
|
|
|
|
} else {
|
2021-04-29 00:07:58 +08:00
|
|
|
console.error("Missing path curve or points.");
|
2021-04-05 04:02:11 +08:00
|
|
|
}
|
|
|
|
return new three.TubeGeometry(curve, comp.tubularSegments, comp.radius, comp.radiusSegments, comp.closed);
|
|
|
|
}
|
|
|
|
var TubeGeometry = vue.defineComponent({
|
2021-03-04 04:49:22 +08:00
|
|
|
extends: Geometry,
|
2021-04-29 00:07:58 +08:00
|
|
|
props: props$8,
|
2021-03-04 04:49:22 +08:00
|
|
|
methods: {
|
2021-04-05 04:02:11 +08:00
|
|
|
createGeometry() {
|
2021-04-07 03:46:35 +08:00
|
|
|
this.geometry = createGeometry(this);
|
2021-04-05 04:02:11 +08:00
|
|
|
},
|
|
|
|
updatePoints(points) {
|
|
|
|
updateTubeGeometryPoints(this.geometry, points);
|
2021-04-29 00:07:58 +08:00
|
|
|
}
|
|
|
|
}
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
|
|
|
function updateTubeGeometryPoints(tube, points) {
|
|
|
|
const curve = new three.CatmullRomCurve3(points);
|
2021-04-29 00:07:58 +08:00
|
|
|
const {radialSegments, radius, tubularSegments, closed} = tube.parameters;
|
2021-04-05 04:02:11 +08:00
|
|
|
const frames = curve.computeFrenetFrames(tubularSegments, closed);
|
|
|
|
tube.tangents = frames.tangents;
|
|
|
|
tube.normals = frames.normals;
|
|
|
|
tube.binormals = frames.binormals;
|
|
|
|
tube.parameters.path = curve;
|
2021-04-29 00:07:58 +08:00
|
|
|
const pAttribute = tube.getAttribute("position");
|
|
|
|
const nAttribute = tube.getAttribute("normal");
|
2021-04-05 04:02:11 +08:00
|
|
|
const normal = new three.Vector3();
|
2021-04-29 00:07:58 +08:00
|
|
|
const P = new three.Vector3();
|
2021-04-05 04:02:11 +08:00
|
|
|
for (let i = 0; i < tubularSegments; i++) {
|
|
|
|
updateSegment(i);
|
|
|
|
}
|
|
|
|
updateSegment(tubularSegments);
|
|
|
|
tube.attributes.position.needsUpdate = true;
|
|
|
|
tube.attributes.normal.needsUpdate = true;
|
|
|
|
function updateSegment(i) {
|
2021-04-29 00:07:58 +08:00
|
|
|
curve.getPointAt(i / tubularSegments, P);
|
2021-04-05 04:02:11 +08:00
|
|
|
const N = frames.normals[i];
|
|
|
|
const B = frames.binormals[i];
|
|
|
|
for (let j = 0; j <= radialSegments; j++) {
|
|
|
|
const v = j / radialSegments * Math.PI * 2;
|
|
|
|
const sin = Math.sin(v);
|
|
|
|
const cos = -Math.cos(v);
|
2021-04-29 00:07:58 +08:00
|
|
|
normal.x = cos * N.x + sin * B.x;
|
|
|
|
normal.y = cos * N.y + sin * B.y;
|
|
|
|
normal.z = cos * N.z + sin * B.z;
|
2021-04-05 04:02:11 +08:00
|
|
|
normal.normalize();
|
2021-04-29 00:07:58 +08:00
|
|
|
const index = i * (radialSegments + 1) + j;
|
|
|
|
nAttribute.setXYZ(index, normal.x, normal.y, normal.z);
|
|
|
|
pAttribute.setXYZ(index, P.x + radius * normal.x, P.y + radius * normal.y, P.z + radius * normal.z);
|
2021-04-05 04:02:11 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var Light = vue.defineComponent({
|
2021-03-08 04:17:46 +08:00
|
|
|
extends: Object3D,
|
2021-04-29 00:07:58 +08:00
|
|
|
name: "Light",
|
2021-03-04 04:49:22 +08:00
|
|
|
props: {
|
2021-04-29 00:07:58 +08:00
|
|
|
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: () => ({})}
|
|
|
|
},
|
|
|
|
setup() {
|
|
|
|
return {};
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
unmounted() {
|
2021-04-29 00:07:58 +08:00
|
|
|
if (this.light instanceof three.SpotLight || this.light instanceof three.DirectionalLight) {
|
|
|
|
this.removeFromParent(this.light.target);
|
|
|
|
}
|
2021-03-04 05:59:51 +08:00
|
|
|
},
|
2021-03-08 04:17:46 +08:00
|
|
|
methods: {
|
2021-04-29 00:07:58 +08:00
|
|
|
initLight(light) {
|
|
|
|
this.light = light;
|
|
|
|
if (light.shadow) {
|
|
|
|
light.castShadow = this.castShadow;
|
|
|
|
setFromProp(light.shadow.mapSize, this.shadowMapSize);
|
|
|
|
setFromProp(light.shadow.camera, this.shadowCamera);
|
2021-03-08 04:17:46 +08:00
|
|
|
}
|
2021-04-29 00:07:58 +08:00
|
|
|
["color", "intensity", "castShadow"].forEach((p) => {
|
|
|
|
vue.watch(() => this[p], (value) => {
|
|
|
|
if (p === "color") {
|
|
|
|
light.color.set(value);
|
2021-03-08 04:17:46 +08:00
|
|
|
} else {
|
2021-04-29 00:07:58 +08:00
|
|
|
light[p] = value;
|
2021-03-08 04:17:46 +08:00
|
|
|
}
|
|
|
|
});
|
2021-03-04 04:49:22 +08:00
|
|
|
});
|
2021-04-29 00:07:58 +08:00
|
|
|
this.initObject3D(light);
|
|
|
|
if (light instanceof three.SpotLight || light instanceof three.DirectionalLight) {
|
|
|
|
bindProp(this, "target", light.target, "position");
|
|
|
|
this.addToParent(light.target);
|
|
|
|
}
|
|
|
|
}
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
__hmrId: "Light"
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
2021-03-04 04:49:22 +08:00
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
var AmbientLight = vue.defineComponent({
|
2021-03-04 04:49:22 +08:00
|
|
|
extends: Light,
|
2021-04-05 04:02:11 +08:00
|
|
|
created() {
|
2021-04-29 00:07:58 +08:00
|
|
|
this.initLight(new three.AmbientLight(this.color, this.intensity));
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
__hmrId: "AmbientLight"
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
2021-03-04 04:49:22 +08:00
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
var DirectionalLight = vue.defineComponent({
|
2021-03-04 04:49:22 +08:00
|
|
|
extends: Light,
|
|
|
|
props: {
|
2021-04-29 00:07:58 +08:00
|
|
|
target: {type: Object, default: () => ({x: 0, y: 0, z: 0})}
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
created() {
|
2021-04-29 00:07:58 +08:00
|
|
|
this.initLight(new three.DirectionalLight(this.color, this.intensity));
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
__hmrId: "DirectionalLight"
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
2021-03-04 04:49:22 +08:00
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
var HemisphereLight = vue.defineComponent({
|
2021-03-08 04:17:46 +08:00
|
|
|
extends: Light,
|
|
|
|
props: {
|
2021-04-29 00:07:58 +08:00
|
|
|
groundColor: {type: String, default: "#444444"}
|
2021-03-08 04:17:46 +08:00
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
created() {
|
2021-04-29 00:07:58 +08:00
|
|
|
const light = new three.HemisphereLight(this.color, this.groundColor, this.intensity);
|
|
|
|
vue.watch(() => this.groundColor, (value) => {
|
|
|
|
light.groundColor.set(value);
|
|
|
|
});
|
|
|
|
this.initLight(light);
|
2021-03-08 04:17:46 +08:00
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
__hmrId: "HemisphereLight"
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
2021-03-08 04:17:46 +08:00
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
var PointLight = vue.defineComponent({
|
2021-03-04 04:49:22 +08:00
|
|
|
extends: Light,
|
|
|
|
props: {
|
2021-04-29 00:07:58 +08:00
|
|
|
distance: {type: Number, default: 0},
|
|
|
|
decay: {type: Number, default: 1}
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
created() {
|
2021-04-29 00:07:58 +08:00
|
|
|
this.initLight(new three.PointLight(this.color, this.intensity, this.distance, this.decay));
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
__hmrId: "PointLight"
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
2021-03-04 04:49:22 +08:00
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
var RectAreaLight = vue.defineComponent({
|
2021-03-08 04:17:46 +08:00
|
|
|
extends: Light,
|
|
|
|
props: {
|
2021-04-29 00:07:58 +08:00
|
|
|
width: {type: Number, default: 10},
|
|
|
|
height: {type: Number, default: 10},
|
|
|
|
helper: Boolean
|
2021-03-08 04:17:46 +08:00
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
created() {
|
2021-03-08 04:17:46 +08:00
|
|
|
RectAreaLightUniformsLib_js.RectAreaLightUniformsLib.init();
|
2021-04-29 00:07:58 +08:00
|
|
|
const light = new three.RectAreaLight(this.color, this.intensity, this.width, this.height);
|
|
|
|
const watchProps = ["width", "height"];
|
|
|
|
watchProps.forEach((p) => {
|
|
|
|
vue.watch(() => this[p], (value) => {
|
|
|
|
light[p] = value;
|
2021-03-08 04:17:46 +08:00
|
|
|
});
|
|
|
|
});
|
|
|
|
if (this.helper) {
|
2021-04-29 00:07:58 +08:00
|
|
|
const lightHelper = new RectAreaLightHelper_js.RectAreaLightHelper(light);
|
|
|
|
light.add(lightHelper);
|
2021-03-08 04:17:46 +08:00
|
|
|
}
|
2021-04-29 00:07:58 +08:00
|
|
|
this.initLight(light);
|
2021-03-08 04:17:46 +08:00
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
__hmrId: "RectAreaLight"
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
2021-03-08 04:17:46 +08:00
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
var SpotLight = vue.defineComponent({
|
2021-03-04 04:49:22 +08:00
|
|
|
extends: Light,
|
|
|
|
props: {
|
2021-04-29 00:07:58 +08:00
|
|
|
angle: {type: Number, default: Math.PI / 3},
|
|
|
|
decay: {type: Number, default: 1},
|
|
|
|
distance: {type: Number, default: 0},
|
|
|
|
penumbra: {type: Number, default: 0},
|
|
|
|
target: Object
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
created() {
|
2021-04-29 00:07:58 +08:00
|
|
|
const light = new three.SpotLight(this.color, this.intensity, this.distance, this.angle, this.penumbra, this.decay);
|
|
|
|
const watchProps = ["angle", "decay", "distance", "penumbra"];
|
|
|
|
watchProps.forEach((p) => {
|
|
|
|
vue.watch(() => this[p], (value) => {
|
|
|
|
light[p] = value;
|
2021-03-04 04:49:22 +08:00
|
|
|
});
|
|
|
|
});
|
2021-04-29 00:07:58 +08:00
|
|
|
this.initLight(light);
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
__hmrId: "SpotLight"
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
2021-03-04 04:49:22 +08:00
|
|
|
|
2021-04-29 00:07:58 +08:00
|
|
|
const MaterialInjectionKey = Symbol("Material");
|
2021-04-05 04:02:11 +08:00
|
|
|
var Material = vue.defineComponent({
|
2021-04-29 00:07:58 +08:00
|
|
|
inject: {
|
|
|
|
mesh: MeshInjectionKey
|
|
|
|
},
|
2021-03-04 04:49:22 +08:00
|
|
|
props: {
|
2021-04-29 00:07:58 +08:00
|
|
|
color: {type: [String, Number], default: "#ffffff"},
|
2021-04-30 05:07:04 +08:00
|
|
|
blending: {type: Number, default: three.NormalBlending},
|
|
|
|
alphaTest: {type: Number, default: 0},
|
2021-04-29 00:07:58 +08:00
|
|
|
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},
|
2021-03-04 04:49:22 +08:00
|
|
|
transparent: Boolean,
|
2021-04-29 00:07:58 +08:00
|
|
|
vertexColors: Boolean
|
|
|
|
},
|
|
|
|
setup() {
|
|
|
|
return {};
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
provide() {
|
2021-03-04 04:49:22 +08:00
|
|
|
return {
|
2021-04-29 00:07:58 +08:00
|
|
|
[MaterialInjectionKey]: this
|
2021-03-04 04:49:22 +08:00
|
|
|
};
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
created() {
|
2021-04-29 00:07:58 +08:00
|
|
|
if (!this.mesh) {
|
|
|
|
console.error("Missing parent Mesh");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (this.createMaterial) {
|
|
|
|
this.material = this.createMaterial();
|
|
|
|
this.mesh.setMaterial(this.material);
|
|
|
|
this.addWatchers();
|
|
|
|
}
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
unmounted() {
|
2021-04-29 00:07:58 +08:00
|
|
|
var _a;
|
|
|
|
(_a = this.material) == null ? void 0 : _a.dispose();
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
|
|
|
methods: {
|
2021-04-05 04:02:11 +08:00
|
|
|
setProp(key, value, needsUpdate = false) {
|
2021-04-29 00:07:58 +08:00
|
|
|
if (this.material) {
|
|
|
|
this.material[key] = value;
|
|
|
|
this.material.needsUpdate = needsUpdate;
|
|
|
|
}
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
setTexture(texture, key = "map") {
|
2021-03-04 04:49:22 +08:00
|
|
|
this.setProp(key, texture, true);
|
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
addWatchers() {
|
2021-04-30 05:07:04 +08:00
|
|
|
["color", "alphaTest", "blending", "depthTest", "depthWrite", "fog", "opacity", "side", "transparent"].forEach((p) => {
|
2021-04-29 00:07:58 +08:00
|
|
|
vue.watch(() => this[p], (value) => {
|
|
|
|
if (p === "color") {
|
|
|
|
this.material.color.set(value);
|
2021-03-04 04:49:22 +08:00
|
|
|
} else {
|
2021-04-29 00:07:58 +08:00
|
|
|
this.material[p] = value;
|
2021-03-04 04:49:22 +08:00
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
2021-04-29 00:07:58 +08:00
|
|
|
}
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
render() {
|
2021-03-08 04:17:46 +08:00
|
|
|
return this.$slots.default ? this.$slots.default() : [];
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
__hmrId: "Material"
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
|
|
|
const wireframeProps = {
|
2021-04-29 00:07:58 +08:00
|
|
|
wireframe: {type: Boolean, default: false},
|
|
|
|
wireframeLinewidth: {type: Number, default: 1}
|
2021-03-14 02:34:34 +08:00
|
|
|
};
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
var BasicMaterial = vue.defineComponent({
|
2021-03-04 04:49:22 +08:00
|
|
|
extends: Material,
|
2021-04-05 04:02:11 +08:00
|
|
|
props: {
|
2021-04-29 00:07:58 +08:00
|
|
|
...wireframeProps
|
2021-04-05 04:02:11 +08:00
|
|
|
},
|
2021-03-04 04:49:22 +08:00
|
|
|
methods: {
|
2021-04-05 04:02:11 +08:00
|
|
|
createMaterial() {
|
2021-04-29 00:07:58 +08:00
|
|
|
const material = new three.MeshBasicMaterial(propsValues(this.$props));
|
|
|
|
bindProps(this, Object.keys(wireframeProps), material);
|
|
|
|
return material;
|
|
|
|
}
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
__hmrId: "BasicMaterial"
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
2021-03-04 04:49:22 +08:00
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
var LambertMaterial = vue.defineComponent({
|
2021-03-04 04:49:22 +08:00
|
|
|
extends: Material,
|
2021-04-05 04:02:11 +08:00
|
|
|
props: {
|
2021-04-29 00:07:58 +08:00
|
|
|
...wireframeProps
|
2021-04-05 04:02:11 +08:00
|
|
|
},
|
2021-03-04 04:49:22 +08:00
|
|
|
methods: {
|
2021-04-05 04:02:11 +08:00
|
|
|
createMaterial() {
|
2021-04-29 00:07:58 +08:00
|
|
|
const material = new three.MeshLambertMaterial(propsValues(this.$props));
|
|
|
|
bindProps(this, Object.keys(wireframeProps), material);
|
|
|
|
return material;
|
|
|
|
}
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
__hmrId: "LambertMaterial"
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
2021-03-04 04:49:22 +08:00
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
var MatcapMaterial = vue.defineComponent({
|
2021-03-04 04:49:22 +08:00
|
|
|
extends: Material,
|
|
|
|
props: {
|
|
|
|
src: String,
|
2021-04-29 00:07:58 +08:00
|
|
|
name: {type: String, default: "0404E8_0404B5_0404CB_3333FC"},
|
|
|
|
flatShading: Boolean
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
|
|
|
methods: {
|
2021-04-05 04:02:11 +08:00
|
|
|
createMaterial() {
|
2021-04-29 00:07:58 +08:00
|
|
|
const src = this.src ? this.src : getMatcapUrl(this.name);
|
|
|
|
const opts = propsValues(this.$props, ["src", "name"]);
|
2021-03-04 04:49:22 +08:00
|
|
|
opts.matcap = new three.TextureLoader().load(src);
|
2021-04-29 00:07:58 +08:00
|
|
|
return new three.MeshMatcapMaterial(opts);
|
|
|
|
}
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
__hmrId: "MatcapMaterial"
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
2021-03-04 04:49:22 +08:00
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
var PhongMaterial = vue.defineComponent({
|
2021-03-04 04:49:22 +08:00
|
|
|
extends: Material,
|
2021-04-05 04:02:11 +08:00
|
|
|
props: {
|
2021-04-29 00:07:58 +08:00
|
|
|
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: 1118481},
|
2021-04-05 04:02:11 +08:00
|
|
|
flatShading: Boolean,
|
2021-04-29 00:07:58 +08:00
|
|
|
...wireframeProps
|
2021-04-05 04:02:11 +08:00
|
|
|
},
|
2021-03-04 04:49:22 +08:00
|
|
|
methods: {
|
2021-04-05 04:02:11 +08:00
|
|
|
createMaterial() {
|
2021-04-29 00:07:58 +08:00
|
|
|
const material = new three.MeshPhongMaterial(propsValues(this.$props));
|
|
|
|
const watchProps = ["emissive", "emissiveIntensity", "reflectivity", "shininess", "specular"];
|
|
|
|
watchProps.forEach((p) => {
|
2021-04-05 04:02:11 +08:00
|
|
|
vue.watch(() => this[p], (value) => {
|
2021-04-29 00:07:58 +08:00
|
|
|
if (p === "emissive" || p === "specular") {
|
|
|
|
material[p].set(value);
|
2021-03-04 04:49:22 +08:00
|
|
|
} else {
|
2021-04-29 00:07:58 +08:00
|
|
|
material[p] = value;
|
2021-03-04 04:49:22 +08:00
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
2021-04-29 00:07:58 +08:00
|
|
|
bindProps(this, Object.keys(wireframeProps), material);
|
|
|
|
return material;
|
|
|
|
}
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
__hmrId: "PhongMaterial"
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
2021-03-04 04:49:22 +08:00
|
|
|
|
2021-04-29 00:07:58 +08:00
|
|
|
const props$7 = {
|
|
|
|
aoMapIntensity: {type: Number, default: 1},
|
|
|
|
bumpScale: {type: Number, default: 1},
|
|
|
|
displacementBias: {type: Number, default: 0},
|
|
|
|
displacementScale: {type: Number, default: 1},
|
|
|
|
emissive: {type: [String, Number], 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
|
2021-03-04 04:49:22 +08:00
|
|
|
};
|
2021-04-05 04:02:11 +08:00
|
|
|
var StandardMaterial = vue.defineComponent({
|
2021-03-04 04:49:22 +08:00
|
|
|
extends: Material,
|
2021-04-05 04:02:11 +08:00
|
|
|
props: {
|
2021-04-29 00:07:58 +08:00
|
|
|
...props$7,
|
|
|
|
...wireframeProps
|
2021-04-05 04:02:11 +08:00
|
|
|
},
|
2021-03-04 04:49:22 +08:00
|
|
|
methods: {
|
2021-04-05 04:02:11 +08:00
|
|
|
createMaterial() {
|
2021-04-29 00:07:58 +08:00
|
|
|
const material = new three.MeshStandardMaterial(propsValues(this.$props, ["normalScale"]));
|
|
|
|
Object.keys(props$7).forEach((p) => {
|
|
|
|
if (p === "normalScale")
|
|
|
|
return;
|
2021-04-05 04:02:11 +08:00
|
|
|
vue.watch(() => this[p], (value) => {
|
2021-04-29 00:07:58 +08:00
|
|
|
if (p === "emissive") {
|
|
|
|
material[p].set(value);
|
2021-03-04 04:49:22 +08:00
|
|
|
} else {
|
2021-04-29 00:07:58 +08:00
|
|
|
material[p] = value;
|
2021-03-04 04:49:22 +08:00
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
2021-04-29 00:07:58 +08:00
|
|
|
bindProp(this, "normalScale", material);
|
|
|
|
bindProps(this, Object.keys(wireframeProps), material);
|
|
|
|
return material;
|
|
|
|
}
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
__hmrId: "StandardMaterial"
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
2021-03-04 04:49:22 +08:00
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
var PhysicalMaterial = vue.defineComponent({
|
2021-03-04 04:49:22 +08:00
|
|
|
extends: StandardMaterial,
|
2021-03-14 02:34:34 +08:00
|
|
|
props: {
|
2021-04-29 00:07:58 +08:00
|
|
|
flatShading: Boolean
|
2021-03-14 02:34:34 +08:00
|
|
|
},
|
2021-03-04 04:49:22 +08:00
|
|
|
methods: {
|
2021-04-05 04:02:11 +08:00
|
|
|
createMaterial() {
|
2021-04-29 00:07:58 +08:00
|
|
|
return new three.MeshPhysicalMaterial(propsValues(this.$props));
|
|
|
|
}
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
__hmrId: "PhysicalMaterial"
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
const defaultVertexShader = `
|
2021-04-29 00:07:58 +08:00
|
|
|
varying vec2 vUv;
|
|
|
|
void main(){
|
|
|
|
vUv = uv;
|
|
|
|
gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0);
|
|
|
|
}
|
|
|
|
`;
|
2021-04-05 04:02:11 +08:00
|
|
|
const defaultFragmentShader = `
|
2021-04-29 00:07:58 +08:00
|
|
|
varying vec2 vUv;
|
|
|
|
void main() {
|
|
|
|
gl_FragColor = vec4(vUv.x, vUv.y, 0., 1.0);
|
|
|
|
}
|
|
|
|
`;
|
2021-04-05 04:02:11 +08:00
|
|
|
var ShaderMaterial = vue.defineComponent({
|
2021-04-29 00:07:58 +08:00
|
|
|
extends: Material,
|
2021-03-14 02:34:34 +08:00
|
|
|
props: {
|
2021-04-29 00:07:58 +08:00
|
|
|
uniforms: {type: Object, default: () => ({})},
|
|
|
|
vertexShader: {type: String, default: defaultVertexShader},
|
|
|
|
fragmentShader: {type: String, default: defaultFragmentShader}
|
2021-03-14 02:34:34 +08:00
|
|
|
},
|
|
|
|
methods: {
|
2021-04-05 04:02:11 +08:00
|
|
|
createMaterial() {
|
2021-04-30 05:07:04 +08:00
|
|
|
const material = new three.ShaderMaterial(propsValues(this.$props, ["color"]));
|
|
|
|
["vertexShader", "fragmentShader"].forEach((p) => {
|
2021-04-29 00:07:58 +08:00
|
|
|
vue.watch(() => this[p], (value) => {
|
2021-04-30 05:07:04 +08:00
|
|
|
material[p] = value;
|
|
|
|
material.needsUpdate = true;
|
2021-04-29 00:07:58 +08:00
|
|
|
});
|
|
|
|
});
|
|
|
|
return material;
|
|
|
|
}
|
2021-03-14 02:34:34 +08:00
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
__hmrId: "ShaderMaterial"
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
2021-03-14 02:34:34 +08:00
|
|
|
|
2021-03-04 04:49:22 +08:00
|
|
|
function replaceAll(string, find, replace) {
|
|
|
|
return string.split(find).join(replace);
|
|
|
|
}
|
2021-04-29 00:07:58 +08:00
|
|
|
const meshphongFragHead = three.ShaderChunk.meshphong_frag.slice(0, three.ShaderChunk.meshphong_frag.indexOf("void main() {"));
|
|
|
|
const meshphongFragBody = three.ShaderChunk.meshphong_frag.slice(three.ShaderChunk.meshphong_frag.indexOf("void main() {"));
|
2021-04-05 04:02:11 +08:00
|
|
|
const SubsurfaceScatteringShader = {
|
2021-03-04 04:49:22 +08:00
|
|
|
uniforms: three.UniformsUtils.merge([
|
|
|
|
three.ShaderLib.phong.uniforms,
|
|
|
|
{
|
2021-04-29 00:07:58 +08:00
|
|
|
thicknessColor: {value: new three.Color(16777215)},
|
|
|
|
thicknessDistortion: {value: 0.1},
|
|
|
|
thicknessAmbient: {value: 0},
|
|
|
|
thicknessAttenuation: {value: 0.1},
|
|
|
|
thicknessPower: {value: 2},
|
|
|
|
thicknessScale: {value: 10}
|
|
|
|
}
|
2021-04-05 04:02:11 +08:00
|
|
|
]),
|
|
|
|
vertexShader: `
|
|
|
|
#define USE_UV
|
|
|
|
${three.ShaderChunk.meshphong_vert}
|
|
|
|
`,
|
|
|
|
fragmentShader: `
|
|
|
|
#define USE_UV
|
|
|
|
#define SUBSURFACE
|
|
|
|
|
|
|
|
${meshphongFragHead}
|
|
|
|
|
|
|
|
uniform float thicknessPower;
|
|
|
|
uniform float thicknessScale;
|
|
|
|
uniform float thicknessDistortion;
|
|
|
|
uniform float thicknessAmbient;
|
|
|
|
uniform float thicknessAttenuation;
|
|
|
|
uniform vec3 thicknessColor;
|
|
|
|
|
|
|
|
void RE_Direct_Scattering(const in IncidentLight directLight, const in vec2 uv, const in GeometricContext geometry, inout ReflectedLight reflectedLight) {
|
|
|
|
#ifdef USE_COLOR
|
|
|
|
vec3 thickness = vColor * thicknessColor;
|
|
|
|
#else
|
|
|
|
vec3 thickness = thicknessColor;
|
|
|
|
#endif
|
|
|
|
vec3 scatteringHalf = normalize(directLight.direction + (geometry.normal * thicknessDistortion));
|
|
|
|
float scatteringDot = pow(saturate(dot(geometry.viewDir, -scatteringHalf)), thicknessPower) * thicknessScale;
|
|
|
|
vec3 scatteringIllu = (scatteringDot + thicknessAmbient) * thickness;
|
|
|
|
reflectedLight.directDiffuse += scatteringIllu * thicknessAttenuation * directLight.color;
|
|
|
|
}
|
2021-04-29 00:07:58 +08:00
|
|
|
` + meshphongFragBody.replace("#include <lights_fragment_begin>", replaceAll(three.ShaderChunk.lights_fragment_begin, "RE_Direct( directLight, geometry, material, reflectedLight );", `
|
2021-04-05 04:02:11 +08:00
|
|
|
RE_Direct( directLight, geometry, material, reflectedLight );
|
|
|
|
#if defined( SUBSURFACE ) && defined( USE_UV )
|
|
|
|
RE_Direct_Scattering(directLight, vUv, geometry, reflectedLight);
|
|
|
|
#endif
|
2021-04-29 00:07:58 +08:00
|
|
|
`))
|
2021-03-04 04:49:22 +08:00
|
|
|
};
|
|
|
|
|
2021-04-29 00:07:58 +08:00
|
|
|
const props$6 = {
|
|
|
|
color: {type: [String, Number], default: "#ffffff"},
|
|
|
|
thicknessColor: {type: [String, Number], 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}
|
|
|
|
};
|
2021-04-05 04:02:11 +08:00
|
|
|
var SubSurfaceMaterial = vue.defineComponent({
|
2021-04-29 00:07:58 +08:00
|
|
|
extends: Material,
|
|
|
|
props: props$6,
|
2021-03-04 04:49:22 +08:00
|
|
|
methods: {
|
2021-04-05 04:02:11 +08:00
|
|
|
createMaterial() {
|
|
|
|
const params = SubsurfaceScatteringShader;
|
|
|
|
const uniforms = three.UniformsUtils.clone(params.uniforms);
|
2021-04-29 00:07:58 +08:00
|
|
|
Object.keys(props$6).forEach((key) => {
|
|
|
|
const value = this[key];
|
2021-04-05 04:02:11 +08:00
|
|
|
let _key = key, _value = value;
|
2021-04-29 00:07:58 +08:00
|
|
|
if (["color", "thicknessColor"].includes(key)) {
|
|
|
|
if (key === "color")
|
|
|
|
_key = "diffuse";
|
2021-03-04 04:49:22 +08:00
|
|
|
_value = new three.Color(value);
|
|
|
|
}
|
2021-04-29 00:07:58 +08:00
|
|
|
uniforms[_key].value = _value;
|
2021-03-04 04:49:22 +08:00
|
|
|
});
|
2021-04-29 00:07:58 +08:00
|
|
|
const material = new three.ShaderMaterial({
|
2021-04-05 04:02:11 +08:00
|
|
|
...params,
|
|
|
|
uniforms,
|
2021-03-04 04:49:22 +08:00
|
|
|
lights: true,
|
|
|
|
transparent: this.transparent,
|
2021-04-29 00:07:58 +08:00
|
|
|
vertexColors: this.vertexColors
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
2021-04-29 00:07:58 +08:00
|
|
|
return material;
|
|
|
|
}
|
2021-03-14 02:34:34 +08:00
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
__hmrId: "SubSurfaceMaterial"
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
2021-03-04 04:49:22 +08:00
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
var ToonMaterial = vue.defineComponent({
|
2021-03-04 04:49:22 +08:00
|
|
|
extends: Material,
|
2021-04-05 04:02:11 +08:00
|
|
|
props: {
|
2021-04-29 00:07:58 +08:00
|
|
|
...wireframeProps
|
2021-04-05 04:02:11 +08:00
|
|
|
},
|
2021-03-04 04:49:22 +08:00
|
|
|
methods: {
|
2021-04-05 04:02:11 +08:00
|
|
|
createMaterial() {
|
2021-04-29 00:07:58 +08:00
|
|
|
const material = new three.MeshToonMaterial(propsValues(this.$props));
|
|
|
|
bindProps(this, Object.keys(wireframeProps), material);
|
|
|
|
return material;
|
|
|
|
}
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
__hmrId: "ToonMaterial"
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
2021-03-04 04:49:22 +08:00
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
var Texture = vue.defineComponent({
|
2021-04-29 00:07:58 +08:00
|
|
|
inject: {
|
|
|
|
material: MaterialInjectionKey
|
|
|
|
},
|
2021-03-04 04:49:22 +08:00
|
|
|
props: {
|
2021-04-29 00:07:58 +08:00
|
|
|
name: {type: String, default: "map"},
|
|
|
|
uniform: String,
|
2021-03-04 04:49:22 +08:00
|
|
|
src: String,
|
|
|
|
onLoad: Function,
|
|
|
|
onProgress: Function,
|
|
|
|
onError: Function,
|
2021-04-30 05:07:04 +08:00
|
|
|
encoding: {type: Number, default: three.LinearEncoding},
|
2021-04-29 00:07:58 +08:00
|
|
|
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})}
|
|
|
|
},
|
|
|
|
setup() {
|
|
|
|
return {};
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
created() {
|
2021-03-04 04:49:22 +08:00
|
|
|
this.refreshTexture();
|
2021-04-05 04:02:11 +08:00
|
|
|
vue.watch(() => this.src, this.refreshTexture);
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
unmounted() {
|
2021-04-29 00:07:58 +08:00
|
|
|
var _a, _b;
|
|
|
|
(_a = this.material) == null ? void 0 : _a.setTexture(null, this.name);
|
|
|
|
(_b = this.texture) == null ? void 0 : _b.dispose();
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
|
|
|
methods: {
|
2021-04-05 04:02:11 +08:00
|
|
|
createTexture() {
|
2021-04-29 00:07:58 +08:00
|
|
|
if (!this.src)
|
|
|
|
return void 0;
|
|
|
|
const texture = new three.TextureLoader().load(this.src, this.onLoaded, this.onProgress, this.onError);
|
2021-04-30 05:07:04 +08:00
|
|
|
const wathProps = ["encoding", "mapping", "wrapS", "wrapT", "magFilter", "minFilter", "repeat", "rotation", "center"];
|
2021-04-29 00:07:58 +08:00
|
|
|
wathProps.forEach((prop) => {
|
|
|
|
bindProp(this, prop, texture);
|
2021-03-08 04:17:46 +08:00
|
|
|
});
|
2021-04-29 00:07:58 +08:00
|
|
|
return texture;
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
refreshTexture() {
|
2021-04-29 00:07:58 +08:00
|
|
|
this.texture = this.createTexture();
|
|
|
|
if (this.texture && this.material) {
|
|
|
|
this.material.setTexture(this.texture, this.name);
|
|
|
|
if (this.material.material instanceof three.ShaderMaterial && this.uniform) {
|
|
|
|
this.material.uniforms[this.uniform] = {value: this.texture};
|
2021-04-05 04:02:11 +08:00
|
|
|
}
|
2021-03-04 04:49:22 +08:00
|
|
|
}
|
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
onLoaded(t) {
|
|
|
|
var _a;
|
|
|
|
(_a = this.onLoad) == null ? void 0 : _a.call(this, t);
|
|
|
|
}
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
render() {
|
2021-03-04 04:49:22 +08:00
|
|
|
return [];
|
2021-04-29 00:07:58 +08:00
|
|
|
}
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
|
|
|
|
2021-04-29 00:07:58 +08:00
|
|
|
var CubeTexture = vue.defineComponent({
|
|
|
|
extends: Texture,
|
|
|
|
props: {
|
|
|
|
path: {type: String, required: true},
|
|
|
|
urls: {
|
|
|
|
type: Array,
|
|
|
|
default: () => ["px.jpg", "nx.jpg", "py.jpg", "ny.jpg", "pz.jpg", "nz.jpg"]
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
mapping: {type: Number, default: three.CubeReflectionMapping}
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
created() {
|
|
|
|
vue.watch(() => this.path, this.refreshTexture);
|
|
|
|
vue.watch(() => this.urls, this.refreshTexture);
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
methods: {
|
|
|
|
createTexture() {
|
|
|
|
return new three.CubeTextureLoader().setPath(this.path).load(this.urls, this.onLoaded, this.onProgress, this.onError);
|
|
|
|
}
|
|
|
|
}
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
2021-03-04 04:49:22 +08:00
|
|
|
|
2021-04-30 05:07:04 +08:00
|
|
|
var PointsMaterial = vue.defineComponent({
|
|
|
|
extends: Material,
|
|
|
|
props: {
|
|
|
|
size: {type: Number, default: 10},
|
|
|
|
sizeAttenuation: {type: Boolean, default: true}
|
|
|
|
},
|
|
|
|
methods: {
|
|
|
|
createMaterial() {
|
|
|
|
const material = new three.PointsMaterial(propsValues(this.$props));
|
|
|
|
return material;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
__hmrId: "PointsMaterial"
|
|
|
|
});
|
|
|
|
|
2021-04-29 00:07:58 +08:00
|
|
|
var Box = meshComponent("Box", props$n, createGeometry$f);
|
2021-03-04 04:49:22 +08:00
|
|
|
|
2021-04-29 00:07:58 +08:00
|
|
|
var Circle = meshComponent("Circle", props$m, createGeometry$e);
|
2021-03-04 04:49:22 +08:00
|
|
|
|
2021-04-29 00:07:58 +08:00
|
|
|
var Cone = meshComponent("Cone", props$l, createGeometry$d);
|
2021-03-04 04:49:22 +08:00
|
|
|
|
2021-04-29 00:07:58 +08:00
|
|
|
var Cylinder = meshComponent("Cylinder", props$k, createGeometry$c);
|
2021-03-04 04:49:22 +08:00
|
|
|
|
2021-04-29 00:07:58 +08:00
|
|
|
var Dodecahedron = meshComponent("Dodecahedron", props$j, createGeometry$b);
|
2021-03-04 04:49:22 +08:00
|
|
|
|
2021-04-29 00:07:58 +08:00
|
|
|
var Icosahedron = meshComponent("Icosahedron", props$i, createGeometry$a);
|
2021-03-04 04:49:22 +08:00
|
|
|
|
2021-04-29 00:07:58 +08:00
|
|
|
var Lathe = meshComponent("Lathe", props$h, createGeometry$9);
|
2021-03-04 04:49:22 +08:00
|
|
|
|
2021-04-29 00:07:58 +08:00
|
|
|
var Octahedron = meshComponent("Octahedron", props$g, createGeometry$8);
|
2021-03-04 04:49:22 +08:00
|
|
|
|
2021-04-29 00:07:58 +08:00
|
|
|
var Plane = meshComponent("Plane", props$f, createGeometry$7);
|
2021-03-04 04:49:22 +08:00
|
|
|
|
2021-04-29 00:07:58 +08:00
|
|
|
var Polyhedron = meshComponent("Polyhedron", props$e, createGeometry$6);
|
2021-03-04 04:49:22 +08:00
|
|
|
|
2021-04-29 00:07:58 +08:00
|
|
|
var Ring = meshComponent("Ring", props$d, createGeometry$5);
|
2021-04-05 04:02:11 +08:00
|
|
|
|
2021-04-29 00:07:58 +08:00
|
|
|
var Sphere = meshComponent("Sphere", props$c, createGeometry$4);
|
2021-04-05 04:02:11 +08:00
|
|
|
|
2021-04-29 00:07:58 +08:00
|
|
|
var Tetrahedron = meshComponent("Tetrahedron", props$b, createGeometry$3);
|
2021-03-04 04:49:22 +08:00
|
|
|
|
2021-04-29 00:07:58 +08:00
|
|
|
const props$5 = {
|
|
|
|
text: {type: String, required: true, default: "Text"},
|
|
|
|
fontSrc: {type: String, required: true},
|
|
|
|
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}
|
2021-03-04 04:49:22 +08:00
|
|
|
};
|
2021-04-05 04:02:11 +08:00
|
|
|
var Text = vue.defineComponent({
|
2021-03-04 04:49:22 +08:00
|
|
|
extends: Mesh,
|
2021-04-29 00:07:58 +08:00
|
|
|
props: props$5,
|
|
|
|
setup() {
|
|
|
|
return {};
|
2021-03-08 04:17:46 +08:00
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
created() {
|
2021-04-29 00:07:58 +08:00
|
|
|
if (!this.fontSrc) {
|
|
|
|
console.error('Missing required prop: "font-src"');
|
|
|
|
return;
|
|
|
|
}
|
2021-04-05 04:02:11 +08:00
|
|
|
const watchProps = [
|
2021-04-29 00:07:58 +08:00
|
|
|
"text",
|
|
|
|
"size",
|
|
|
|
"height",
|
|
|
|
"curveSegments",
|
|
|
|
"bevelEnabled",
|
|
|
|
"bevelThickness",
|
|
|
|
"bevelSize",
|
|
|
|
"bevelOffset",
|
|
|
|
"bevelSegments",
|
|
|
|
"align"
|
2021-04-05 04:02:11 +08:00
|
|
|
];
|
2021-04-29 00:07:58 +08:00
|
|
|
watchProps.forEach((p) => {
|
2021-04-05 04:02:11 +08:00
|
|
|
vue.watch(() => this[p], () => {
|
2021-04-29 00:07:58 +08:00
|
|
|
if (this.font)
|
|
|
|
this.refreshGeometry();
|
2021-03-04 04:49:22 +08:00
|
|
|
});
|
|
|
|
});
|
2021-04-05 04:02:11 +08:00
|
|
|
const loader = new three.FontLoader();
|
2021-04-29 00:07:58 +08:00
|
|
|
this.loading = true;
|
2021-04-05 04:02:11 +08:00
|
|
|
loader.load(this.fontSrc, (font) => {
|
|
|
|
this.loading = false;
|
|
|
|
this.font = font;
|
|
|
|
this.createGeometry();
|
|
|
|
this.initMesh();
|
2021-03-04 04:49:22 +08:00
|
|
|
});
|
|
|
|
},
|
|
|
|
methods: {
|
2021-04-05 04:02:11 +08:00
|
|
|
createGeometry() {
|
|
|
|
this.geometry = new three.TextGeometry(this.text, {
|
2021-03-04 04:49:22 +08:00
|
|
|
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,
|
2021-04-29 00:07:58 +08:00
|
|
|
bevelSegments: this.bevelSegments
|
2021-03-04 04:49:22 +08:00
|
|
|
});
|
2021-04-29 00:07:58 +08:00
|
|
|
if (this.align === "center") {
|
2021-03-04 04:49:22 +08:00
|
|
|
this.geometry.center();
|
|
|
|
}
|
2021-04-29 00:07:58 +08:00
|
|
|
}
|
|
|
|
}
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
2021-03-04 04:49:22 +08:00
|
|
|
|
2021-04-29 00:07:58 +08:00
|
|
|
var Torus = meshComponent("Torus", props$a, createGeometry$2);
|
2021-03-04 04:49:22 +08:00
|
|
|
|
2021-04-29 00:07:58 +08:00
|
|
|
var TorusKnot = meshComponent("TorusKnot", props$9, createGeometry$1);
|
2021-03-04 04:49:22 +08:00
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
var Tube = vue.defineComponent({
|
2021-03-04 04:49:22 +08:00
|
|
|
extends: Mesh,
|
2021-04-29 00:07:58 +08:00
|
|
|
props: props$8,
|
2021-04-05 04:02:11 +08:00
|
|
|
created() {
|
2021-03-04 04:49:22 +08:00
|
|
|
this.createGeometry();
|
2021-04-29 00:07:58 +08:00
|
|
|
this.addGeometryWatchers(props$8);
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
|
|
|
methods: {
|
2021-04-05 04:02:11 +08:00
|
|
|
createGeometry() {
|
2021-04-07 03:46:35 +08:00
|
|
|
this.geometry = createGeometry(this);
|
2021-03-08 04:17:46 +08:00
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
updatePoints(points) {
|
2021-03-10 01:25:02 +08:00
|
|
|
updateTubeGeometryPoints(this.geometry, points);
|
2021-04-29 00:07:58 +08:00
|
|
|
}
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
__hmrId: "Tube"
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
2021-03-08 04:17:46 +08:00
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
var Image = vue.defineComponent({
|
2021-04-29 00:07:58 +08:00
|
|
|
emits: ["loaded"],
|
2021-03-04 04:49:22 +08:00
|
|
|
extends: Mesh,
|
|
|
|
props: {
|
2021-04-29 00:07:58 +08:00
|
|
|
src: {type: String, required: true},
|
2021-03-04 04:49:22 +08:00
|
|
|
width: Number,
|
|
|
|
height: Number,
|
2021-04-29 00:07:58 +08:00
|
|
|
widthSegments: {type: Number, default: 1},
|
|
|
|
heightSegments: {type: Number, default: 1},
|
|
|
|
keepSize: Boolean
|
|
|
|
},
|
|
|
|
setup() {
|
|
|
|
return {};
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
created() {
|
2021-04-29 00:07:58 +08:00
|
|
|
if (!this.renderer)
|
|
|
|
return;
|
|
|
|
this.geometry = new three.PlaneGeometry(1, 1, this.widthSegments, this.heightSegments);
|
|
|
|
this.material = new three.MeshBasicMaterial({side: three.DoubleSide, map: this.loadTexture()});
|
2021-04-05 04:02:11 +08:00
|
|
|
vue.watch(() => this.src, this.refreshTexture);
|
2021-04-29 00:07:58 +08:00
|
|
|
["width", "height"].forEach((p) => {
|
2021-04-05 04:02:11 +08:00
|
|
|
vue.watch(() => this[p], this.resize);
|
2021-03-04 04:49:22 +08:00
|
|
|
});
|
2021-04-29 00:07:58 +08:00
|
|
|
this.resize();
|
|
|
|
if (this.keepSize)
|
|
|
|
this.renderer.onResize(this.resize);
|
|
|
|
},
|
|
|
|
unmounted() {
|
|
|
|
var _a;
|
|
|
|
(_a = this.renderer) == null ? void 0 : _a.offResize(this.resize);
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
|
|
|
methods: {
|
2021-04-05 04:02:11 +08:00
|
|
|
loadTexture() {
|
2021-03-04 04:49:22 +08:00
|
|
|
return new three.TextureLoader().load(this.src, this.onLoaded);
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
refreshTexture() {
|
2021-04-29 00:07:58 +08:00
|
|
|
var _a;
|
|
|
|
(_a = this.texture) == null ? void 0 : _a.dispose();
|
|
|
|
if (this.material) {
|
|
|
|
this.material.map = this.loadTexture();
|
|
|
|
this.material.needsUpdate = true;
|
|
|
|
}
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
onLoaded(texture) {
|
2021-03-04 04:49:22 +08:00
|
|
|
this.texture = texture;
|
|
|
|
this.resize();
|
2021-04-29 00:07:58 +08:00
|
|
|
this.$emit("loaded", texture);
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
resize() {
|
2021-04-29 00:07:58 +08:00
|
|
|
if (!this.renderer || !this.texture)
|
|
|
|
return;
|
|
|
|
const screen = this.renderer.size;
|
2021-04-05 04:02:11 +08:00
|
|
|
const iW = this.texture.image.width;
|
|
|
|
const iH = this.texture.image.height;
|
|
|
|
const iRatio = iW / iH;
|
2021-04-29 00:07:58 +08:00
|
|
|
let w = 1, h = 1;
|
2021-03-04 04:49:22 +08:00
|
|
|
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;
|
2021-04-29 00:07:58 +08:00
|
|
|
} else {
|
|
|
|
if (iRatio > 1)
|
|
|
|
w = h * iRatio;
|
|
|
|
else
|
|
|
|
h = w / iRatio;
|
2021-03-04 04:49:22 +08:00
|
|
|
}
|
2021-04-29 00:07:58 +08:00
|
|
|
if (this.mesh) {
|
|
|
|
this.mesh.scale.x = w;
|
|
|
|
this.mesh.scale.y = h;
|
|
|
|
}
|
|
|
|
}
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
__hmrId: "Image"
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
2021-03-04 04:49:22 +08:00
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
var InstancedMesh = vue.defineComponent({
|
2021-04-29 00:07:58 +08:00
|
|
|
extends: Mesh,
|
2021-03-04 04:49:22 +08:00
|
|
|
props: {
|
2021-04-29 00:07:58 +08:00
|
|
|
count: {type: Number, required: true}
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
|
|
|
methods: {
|
2021-04-05 04:02:11 +08:00
|
|
|
initMesh() {
|
2021-04-29 00:07:58 +08:00
|
|
|
if (!this.renderer)
|
|
|
|
return;
|
|
|
|
if (!this.geometry || !this.material) {
|
|
|
|
console.error("Missing geometry and/or material");
|
|
|
|
return false;
|
|
|
|
}
|
2021-03-04 04:49:22 +08:00
|
|
|
this.mesh = new three.InstancedMesh(this.geometry, this.material, this.count);
|
2021-04-29 00:07:58 +08:00
|
|
|
this.mesh.userData.component = this;
|
|
|
|
bindProp(this, "castShadow", this.mesh);
|
|
|
|
bindProp(this, "receiveShadow", this.mesh);
|
|
|
|
if (this.onPointerEnter || this.onPointerOver || this.onPointerMove || this.onPointerLeave || this.onPointerDown || this.onPointerUp || this.onClick) {
|
|
|
|
this.renderer.three.addIntersectObject(this.mesh);
|
2021-04-05 04:02:11 +08:00
|
|
|
}
|
2021-03-08 04:17:46 +08:00
|
|
|
this.initObject3D(this.mesh);
|
2021-04-05 04:02:11 +08:00
|
|
|
}
|
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
__hmrId: "InstancedMesh"
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
2021-03-04 04:49:22 +08:00
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
var Sprite = vue.defineComponent({
|
2021-03-08 04:17:46 +08:00
|
|
|
extends: Object3D,
|
2021-04-29 00:07:58 +08:00
|
|
|
emits: ["loaded"],
|
2021-03-04 04:49:22 +08:00
|
|
|
props: {
|
2021-04-29 00:07:58 +08:00
|
|
|
src: {type: String, required: true}
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
setup() {
|
|
|
|
return {};
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
created() {
|
2021-03-04 04:49:22 +08:00
|
|
|
this.texture = new three.TextureLoader().load(this.src, this.onLoaded);
|
2021-04-29 00:07:58 +08:00
|
|
|
this.material = new three.SpriteMaterial({map: this.texture});
|
2021-03-04 04:49:22 +08:00
|
|
|
this.sprite = new three.Sprite(this.material);
|
2021-03-08 04:17:46 +08:00
|
|
|
this.initObject3D(this.sprite);
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
unmounted() {
|
2021-04-29 00:07:58 +08:00
|
|
|
var _a, _b;
|
|
|
|
(_a = this.texture) == null ? void 0 : _a.dispose();
|
|
|
|
(_b = this.material) == null ? void 0 : _b.dispose();
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
|
|
|
methods: {
|
2021-04-05 04:02:11 +08:00
|
|
|
onLoaded() {
|
2021-03-04 04:49:22 +08:00
|
|
|
this.updateUV();
|
2021-04-29 00:07:58 +08:00
|
|
|
this.$emit("loaded");
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
updateUV() {
|
2021-04-29 00:07:58 +08:00
|
|
|
if (!this.texture || !this.sprite)
|
|
|
|
return;
|
|
|
|
const iWidth = this.texture.image.width;
|
|
|
|
const iHeight = this.texture.image.height;
|
|
|
|
const iRatio = iWidth / iHeight;
|
2021-04-05 04:02:11 +08:00
|
|
|
let x = 0.5, y = 0.5;
|
2021-04-29 00:07:58 +08:00
|
|
|
if (iRatio > 1) {
|
|
|
|
x = 0.5 * iRatio;
|
2021-03-04 04:49:22 +08:00
|
|
|
} else {
|
2021-04-29 00:07:58 +08:00
|
|
|
y = 0.5 / iRatio;
|
2021-03-04 04:49:22 +08:00
|
|
|
}
|
2021-04-29 00:07:58 +08:00
|
|
|
const positions = this.sprite.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.sprite.geometry.attributes.position.needsUpdate = true;
|
|
|
|
}
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
__hmrId: "Sprite"
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
2021-03-04 04:49:22 +08:00
|
|
|
|
2021-04-30 05:07:04 +08:00
|
|
|
var Points = vue.defineComponent({
|
|
|
|
extends: Object3D,
|
|
|
|
setup() {
|
|
|
|
return {};
|
|
|
|
},
|
|
|
|
provide() {
|
|
|
|
return {
|
|
|
|
[MeshInjectionKey]: this
|
|
|
|
};
|
|
|
|
},
|
|
|
|
mounted() {
|
|
|
|
this.mesh = this.points = new three.Points(this.geometry, this.material);
|
|
|
|
this.initObject3D(this.mesh);
|
|
|
|
},
|
|
|
|
methods: {
|
|
|
|
setGeometry(geometry) {
|
|
|
|
this.geometry = geometry;
|
|
|
|
if (this.mesh)
|
|
|
|
this.mesh.geometry = geometry;
|
|
|
|
},
|
|
|
|
setMaterial(material) {
|
|
|
|
this.material = material;
|
|
|
|
if (this.mesh)
|
|
|
|
this.mesh.material = material;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
var Model = vue.defineComponent({
|
2021-03-14 02:34:34 +08:00
|
|
|
extends: Object3D,
|
2021-04-29 00:07:58 +08:00
|
|
|
emits: ["load", "progress", "error"],
|
|
|
|
props: {
|
|
|
|
src: {type: String, required: true}
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
data() {
|
|
|
|
return {
|
2021-04-29 00:07:58 +08:00
|
|
|
progress: 0
|
2021-04-05 04:02:11 +08:00
|
|
|
};
|
|
|
|
},
|
|
|
|
methods: {
|
|
|
|
onLoad(model) {
|
2021-04-29 00:07:58 +08:00
|
|
|
this.$emit("load", model);
|
2021-04-05 04:02:11 +08:00
|
|
|
this.initObject3D(model);
|
|
|
|
},
|
|
|
|
onProgress(progress) {
|
|
|
|
this.progress = progress.loaded / progress.total;
|
2021-04-29 00:07:58 +08:00
|
|
|
this.$emit("progress", progress);
|
2021-04-05 04:02:11 +08:00
|
|
|
},
|
|
|
|
onError(error) {
|
2021-04-29 00:07:58 +08:00
|
|
|
this.$emit("error", error);
|
|
|
|
}
|
|
|
|
}
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
var GLTF = vue.defineComponent({
|
|
|
|
extends: Model,
|
|
|
|
created() {
|
|
|
|
const loader = new GLTFLoader_js.GLTFLoader();
|
|
|
|
loader.load(this.src, (gltf) => {
|
|
|
|
this.onLoad(gltf.scene);
|
|
|
|
}, this.onProgress, this.onError);
|
2021-04-29 00:07:58 +08:00
|
|
|
}
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
2021-03-14 02:34:34 +08:00
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
var FBX = vue.defineComponent({
|
|
|
|
extends: Model,
|
|
|
|
created() {
|
|
|
|
const loader = new FBXLoader_js.FBXLoader();
|
|
|
|
loader.load(this.src, (fbx) => {
|
|
|
|
this.onLoad(fbx);
|
|
|
|
}, this.onProgress, this.onError);
|
2021-04-29 00:07:58 +08:00
|
|
|
}
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
2021-03-14 02:34:34 +08:00
|
|
|
|
2021-04-29 00:07:58 +08:00
|
|
|
const ComposerInjectionKey = Symbol("Composer");
|
2021-04-05 04:02:11 +08:00
|
|
|
var EffectComposer = vue.defineComponent({
|
|
|
|
setup() {
|
2021-04-29 00:07:58 +08:00
|
|
|
const renderer = vue.inject(RendererInjectionKey);
|
|
|
|
return {renderer};
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
provide() {
|
2021-03-04 04:49:22 +08:00
|
|
|
return {
|
2021-04-29 00:07:58 +08:00
|
|
|
[ComposerInjectionKey]: this
|
2021-03-04 04:49:22 +08:00
|
|
|
};
|
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
created() {
|
|
|
|
if (!this.renderer) {
|
|
|
|
console.error("Renderer not found");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const renderer = this.renderer;
|
|
|
|
const composer = new EffectComposer_js.EffectComposer(this.renderer.renderer);
|
|
|
|
this.composer = composer;
|
|
|
|
this.renderer.composer = composer;
|
|
|
|
renderer.addListener("init", () => {
|
|
|
|
renderer.renderer.autoClear = false;
|
2021-04-05 04:02:11 +08:00
|
|
|
this.resize();
|
2021-04-29 00:07:58 +08:00
|
|
|
renderer.addListener("resize", this.resize);
|
2021-03-04 04:49:22 +08:00
|
|
|
});
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
unmounted() {
|
2021-04-29 00:07:58 +08:00
|
|
|
var _a;
|
|
|
|
(_a = this.renderer) == null ? void 0 : _a.removeListener("resize", this.resize);
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
|
|
|
methods: {
|
2021-04-29 00:07:58 +08:00
|
|
|
addPass(pass) {
|
|
|
|
var _a;
|
|
|
|
(_a = this.composer) == null ? void 0 : _a.addPass(pass);
|
|
|
|
},
|
|
|
|
removePass(pass) {
|
|
|
|
var _a;
|
|
|
|
(_a = this.composer) == null ? void 0 : _a.removePass(pass);
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
resize() {
|
|
|
|
if (this.composer && this.renderer) {
|
|
|
|
this.composer.setSize(this.renderer.size.width, this.renderer.size.height);
|
|
|
|
}
|
|
|
|
}
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
render() {
|
2021-04-29 00:07:58 +08:00
|
|
|
return this.$slots.default ? this.$slots.default() : [];
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
__hmrId: "EffectComposer"
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
2021-03-04 04:49:22 +08:00
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
var EffectPass = vue.defineComponent({
|
2021-04-29 00:07:58 +08:00
|
|
|
inject: {
|
|
|
|
renderer: RendererInjectionKey,
|
|
|
|
composer: ComposerInjectionKey
|
|
|
|
},
|
|
|
|
emits: ["ready"],
|
|
|
|
setup() {
|
|
|
|
return {};
|
|
|
|
},
|
|
|
|
created() {
|
|
|
|
if (!this.composer) {
|
|
|
|
console.error("Missing parent EffectComposer");
|
|
|
|
}
|
|
|
|
if (!this.renderer) {
|
|
|
|
console.error("Missing parent Renderer");
|
2021-03-04 04:49:22 +08:00
|
|
|
}
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
unmounted() {
|
2021-04-29 00:07:58 +08:00
|
|
|
var _a, _b, _c;
|
|
|
|
if (this.pass) {
|
|
|
|
(_a = this.composer) == null ? void 0 : _a.removePass(this.pass);
|
|
|
|
(_c = (_b = this.pass).dispose) == null ? void 0 : _c.call(_b);
|
|
|
|
}
|
2021-04-05 04:02:11 +08:00
|
|
|
},
|
|
|
|
methods: {
|
2021-04-29 00:07:58 +08:00
|
|
|
initEffectPass(pass) {
|
|
|
|
var _a;
|
2021-04-05 04:02:11 +08:00
|
|
|
this.pass = pass;
|
2021-04-29 00:07:58 +08:00
|
|
|
(_a = this.composer) == null ? void 0 : _a.addPass(pass);
|
|
|
|
this.$emit("ready", pass);
|
|
|
|
}
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
render() {
|
2021-03-04 04:49:22 +08:00
|
|
|
return [];
|
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
__hmrId: "EffectPass"
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
2021-03-04 04:49:22 +08:00
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
var RenderPass = vue.defineComponent({
|
2021-03-04 04:49:22 +08:00
|
|
|
extends: EffectPass,
|
2021-04-29 00:07:58 +08:00
|
|
|
created() {
|
|
|
|
if (!this.renderer)
|
|
|
|
return;
|
|
|
|
if (!this.renderer.scene) {
|
|
|
|
console.error("Missing Scene");
|
|
|
|
return;
|
2021-03-04 04:49:22 +08:00
|
|
|
}
|
2021-04-29 00:07:58 +08:00
|
|
|
if (!this.renderer.camera) {
|
|
|
|
console.error("Missing Camera");
|
|
|
|
return;
|
2021-03-04 04:49:22 +08:00
|
|
|
}
|
2021-04-29 00:07:58 +08:00
|
|
|
const pass = new RenderPass_js.RenderPass(this.renderer.scene, this.renderer.camera);
|
|
|
|
this.initEffectPass(pass);
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
__hmrId: "RenderPass"
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
2021-03-04 04:49:22 +08:00
|
|
|
|
2021-04-29 00:07:58 +08:00
|
|
|
const props$4 = {
|
|
|
|
focus: {type: Number, default: 1},
|
|
|
|
aperture: {type: Number, default: 0.025},
|
|
|
|
maxblur: {type: Number, default: 0.01}
|
|
|
|
};
|
2021-04-05 04:02:11 +08:00
|
|
|
var BokehPass = vue.defineComponent({
|
2021-03-04 04:49:22 +08:00
|
|
|
extends: EffectPass,
|
2021-04-29 00:07:58 +08:00
|
|
|
props: props$4,
|
|
|
|
created() {
|
|
|
|
if (!this.renderer)
|
|
|
|
return;
|
|
|
|
if (!this.renderer.scene) {
|
|
|
|
console.error("Missing Scene");
|
|
|
|
return;
|
2021-03-04 04:49:22 +08:00
|
|
|
}
|
2021-04-29 00:07:58 +08:00
|
|
|
if (!this.renderer.camera) {
|
|
|
|
console.error("Missing Camera");
|
|
|
|
return;
|
2021-03-04 04:49:22 +08:00
|
|
|
}
|
2021-04-05 04:02:11 +08:00
|
|
|
const params = {
|
2021-03-04 04:49:22 +08:00
|
|
|
focus: this.focus,
|
|
|
|
aperture: this.aperture,
|
|
|
|
maxblur: this.maxblur,
|
2021-04-29 00:07:58 +08:00
|
|
|
width: this.renderer.size.width,
|
|
|
|
height: this.renderer.size.height
|
2021-03-04 04:49:22 +08:00
|
|
|
};
|
2021-04-29 00:07:58 +08:00
|
|
|
const pass = new BokehPass_js.BokehPass(this.renderer.scene, this.renderer.camera, params);
|
|
|
|
Object.keys(props$4).forEach((p) => {
|
|
|
|
vue.watch(() => this[p], (value) => {
|
|
|
|
pass.uniforms[p].value = value;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
this.initEffectPass(pass);
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
__hmrId: "BokehPass"
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
2021-03-04 04:49:22 +08:00
|
|
|
|
2021-04-29 00:07:58 +08:00
|
|
|
const props$3 = {
|
|
|
|
noiseIntensity: {type: Number, default: 0.5},
|
|
|
|
scanlinesIntensity: {type: Number, default: 0.05},
|
|
|
|
scanlinesCount: {type: Number, default: 4096},
|
|
|
|
grayscale: {type: Number, default: 0}
|
|
|
|
};
|
2021-04-05 04:02:11 +08:00
|
|
|
var FilmPass = vue.defineComponent({
|
2021-03-04 04:49:22 +08:00
|
|
|
extends: EffectPass,
|
2021-04-29 00:07:58 +08:00
|
|
|
props: props$3,
|
|
|
|
created() {
|
2021-04-05 04:02:11 +08:00
|
|
|
const pass = new FilmPass_js.FilmPass(this.noiseIntensity, this.scanlinesIntensity, this.scanlinesCount, this.grayscale);
|
2021-04-29 00:07:58 +08:00
|
|
|
Object.keys(props$3).forEach((p) => {
|
|
|
|
vue.watch(() => this[p], (value) => {
|
|
|
|
pass.uniforms[p].value = value;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
this.initEffectPass(pass);
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
__hmrId: "FilmPass"
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
2021-03-04 04:49:22 +08:00
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
var FXAAPass = vue.defineComponent({
|
2021-03-04 04:49:22 +08:00
|
|
|
extends: EffectPass,
|
2021-04-29 00:07:58 +08:00
|
|
|
created() {
|
|
|
|
var _a;
|
2021-04-05 04:02:11 +08:00
|
|
|
const pass = new ShaderPass_js.ShaderPass(FXAAShader_js.FXAAShader);
|
2021-04-29 00:07:58 +08:00
|
|
|
(_a = this.renderer) == null ? void 0 : _a.addListener("resize", this.resize);
|
|
|
|
this.initEffectPass(pass);
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
unmounted() {
|
2021-04-29 00:07:58 +08:00
|
|
|
var _a;
|
|
|
|
(_a = this.renderer) == null ? void 0 : _a.removeListener("resize", this.resize);
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
|
|
|
methods: {
|
2021-04-29 00:07:58 +08:00
|
|
|
resize({size}) {
|
|
|
|
if (this.pass) {
|
|
|
|
const {resolution} = this.pass.material.uniforms;
|
|
|
|
resolution.value.x = 1 / size.width;
|
|
|
|
resolution.value.y = 1 / size.height;
|
|
|
|
}
|
|
|
|
}
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
__hmrId: "FXAAPass"
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
2021-03-04 04:49:22 +08:00
|
|
|
|
2021-04-29 00:07:58 +08:00
|
|
|
const props$2 = {
|
|
|
|
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}
|
|
|
|
};
|
2021-04-05 04:02:11 +08:00
|
|
|
var HalftonePass = vue.defineComponent({
|
2021-03-04 04:49:22 +08:00
|
|
|
extends: EffectPass,
|
2021-04-29 00:07:58 +08:00
|
|
|
props: props$2,
|
|
|
|
created() {
|
|
|
|
if (!this.renderer)
|
|
|
|
return;
|
|
|
|
const pass = new HalftonePass_js.HalftonePass(this.renderer.size.width, this.renderer.size.height, {});
|
|
|
|
Object.keys(props$2).forEach((p) => {
|
2021-04-05 04:02:11 +08:00
|
|
|
pass.uniforms[p].value = this[p];
|
2021-04-29 00:07:58 +08:00
|
|
|
vue.watch(() => this[p], (value) => {
|
|
|
|
pass.uniforms[p].value = value;
|
2021-03-04 04:49:22 +08:00
|
|
|
});
|
|
|
|
});
|
2021-04-29 00:07:58 +08:00
|
|
|
this.initEffectPass(pass);
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
__hmrId: "HalftonePass"
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
2021-03-04 04:49:22 +08:00
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
var SMAAPass = vue.defineComponent({
|
2021-03-04 04:49:22 +08:00
|
|
|
extends: EffectPass,
|
2021-04-29 00:07:58 +08:00
|
|
|
created() {
|
|
|
|
if (!this.renderer)
|
|
|
|
return;
|
|
|
|
const pass = new SMAAPass_js.SMAAPass(this.renderer.size.width, this.renderer.size.height);
|
|
|
|
this.initEffectPass(pass);
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
__hmrId: "SMAAPass"
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
var SSAOPass = vue.defineComponent({
|
|
|
|
extends: EffectPass,
|
|
|
|
props: {
|
|
|
|
options: {
|
|
|
|
type: Object,
|
2021-04-29 00:07:58 +08:00
|
|
|
default: () => ({})
|
|
|
|
}
|
2021-04-05 04:02:11 +08:00
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
created() {
|
|
|
|
if (!this.renderer)
|
|
|
|
return;
|
|
|
|
if (!this.renderer.scene) {
|
|
|
|
console.error("Missing Scene");
|
|
|
|
return;
|
2021-04-05 04:02:11 +08:00
|
|
|
}
|
2021-04-29 00:07:58 +08:00
|
|
|
if (!this.renderer.camera) {
|
|
|
|
console.error("Missing Camera");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const pass = new SSAOPass_js.SSAOPass(this.renderer.scene, this.renderer.camera, this.renderer.size.width, this.renderer.size.height);
|
|
|
|
Object.keys(this.options).forEach((key) => {
|
|
|
|
pass[key] = this.options[key];
|
|
|
|
});
|
|
|
|
this.initEffectPass(pass);
|
2021-04-05 04:02:11 +08:00
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
__hmrId: "SSAOPass"
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
2021-03-04 04:49:22 +08:00
|
|
|
|
|
|
|
var DefaultShader = {
|
|
|
|
uniforms: {},
|
2021-04-05 04:02:11 +08:00
|
|
|
vertexShader: `
|
|
|
|
varying vec2 vUv;
|
|
|
|
void main() {
|
|
|
|
vUv = uv;
|
|
|
|
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
fragmentShader: `
|
|
|
|
varying vec2 vUv;
|
|
|
|
void main() {
|
|
|
|
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
|
|
|
|
}
|
2021-04-29 00:07:58 +08:00
|
|
|
`
|
2021-03-04 04:49:22 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
var TiltShift = {
|
|
|
|
uniforms: {
|
2021-04-29 00:07:58 +08:00
|
|
|
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()}
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
|
|
|
vertexShader: DefaultShader.vertexShader,
|
2021-04-05 04:02:11 +08:00
|
|
|
fragmentShader: `
|
|
|
|
uniform sampler2D tDiffuse;
|
|
|
|
uniform float blurRadius;
|
|
|
|
uniform float gradientRadius;
|
|
|
|
uniform vec2 start;
|
|
|
|
uniform vec2 end;
|
|
|
|
uniform vec2 delta;
|
|
|
|
uniform vec2 texSize;
|
|
|
|
varying vec2 vUv;
|
|
|
|
|
|
|
|
float random(vec3 scale, float seed) {
|
|
|
|
/* use the fragment position for a different seed per-pixel */
|
|
|
|
return fract(sin(dot(gl_FragCoord.xyz + seed, scale)) * 43758.5453 + seed);
|
|
|
|
}
|
|
|
|
|
|
|
|
void main() {
|
|
|
|
vec4 color = vec4(0.0);
|
|
|
|
float total = 0.0;
|
|
|
|
|
|
|
|
/* randomize the lookup values to hide the fixed number of samples */
|
|
|
|
float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0);
|
|
|
|
|
|
|
|
vec2 normal = normalize(vec2(start.y - end.y, end.x - start.x));
|
|
|
|
float radius = smoothstep(0.0, 1.0, abs(dot(vUv * texSize - start, normal)) / gradientRadius) * blurRadius;
|
|
|
|
for (float t = -30.0; t <= 30.0; t++) {
|
|
|
|
float percent = (t + offset - 0.5) / 30.0;
|
|
|
|
float weight = 1.0 - abs(percent);
|
|
|
|
vec4 texel = texture2D(tDiffuse, vUv + delta / texSize * percent * radius);
|
|
|
|
// vec4 texel2 = texture2D(tDiffuse, vUv + vec2(-delta.y, delta.x) / texSize * percent * radius);
|
|
|
|
|
|
|
|
/* switch to pre-multiplied alpha to correctly blur transparent images */
|
|
|
|
texel.rgb *= texel.a;
|
|
|
|
// texel2.rgb *= texel2.a;
|
|
|
|
|
|
|
|
color += texel * weight;
|
|
|
|
total += 2.0 * weight;
|
|
|
|
}
|
|
|
|
|
|
|
|
gl_FragColor = color / total;
|
|
|
|
|
|
|
|
/* switch back from pre-multiplied alpha */
|
|
|
|
gl_FragColor.rgb /= gl_FragColor.a + 0.00001;
|
|
|
|
}
|
2021-04-29 00:07:58 +08:00
|
|
|
`
|
2021-03-04 04:49:22 +08:00
|
|
|
};
|
|
|
|
|
2021-04-29 00:07:58 +08:00
|
|
|
const props$1 = {
|
|
|
|
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})}
|
|
|
|
};
|
2021-04-05 04:02:11 +08:00
|
|
|
var TiltShiftPass = vue.defineComponent({
|
2021-03-04 04:49:22 +08:00
|
|
|
extends: EffectPass,
|
2021-04-29 00:07:58 +08:00
|
|
|
props: props$1,
|
|
|
|
setup() {
|
|
|
|
return {uniforms1: {}, uniforms2: {}};
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
created() {
|
|
|
|
if (!this.composer)
|
|
|
|
return;
|
2021-03-04 04:49:22 +08:00
|
|
|
this.pass1 = new ShaderPass_js.ShaderPass(TiltShift);
|
2021-04-29 00:07:58 +08:00
|
|
|
this.pass2 = new ShaderPass_js.ShaderPass(TiltShift);
|
2021-04-05 04:02:11 +08:00
|
|
|
const uniforms1 = this.uniforms1 = this.pass1.uniforms;
|
2021-04-29 00:07:58 +08:00
|
|
|
const uniforms2 = this.uniforms2 = this.pass2.uniforms;
|
|
|
|
uniforms2.blurRadius = uniforms1.blurRadius;
|
|
|
|
uniforms2.gradientRadius = uniforms1.gradientRadius;
|
|
|
|
uniforms2.start = uniforms1.start;
|
|
|
|
uniforms2.end = uniforms1.end;
|
|
|
|
uniforms2.texSize = uniforms1.texSize;
|
|
|
|
bindProp(this, "blurRadius", uniforms1.blurRadius, "value");
|
|
|
|
bindProp(this, "gradientRadius", uniforms1.gradientRadius, "value");
|
2021-03-04 04:49:22 +08:00
|
|
|
this.updateFocusLine();
|
2021-04-29 00:07:58 +08:00
|
|
|
["start", "end"].forEach((p) => {
|
|
|
|
vue.watch(() => this[p], this.updateFocusLine, {deep: true});
|
2021-03-04 04:49:22 +08:00
|
|
|
});
|
2021-04-29 00:07:58 +08:00
|
|
|
this.pass1.setSize = (width, height) => {
|
|
|
|
uniforms1.texSize.value.set(width, height);
|
2021-03-04 04:49:22 +08:00
|
|
|
};
|
2021-04-29 00:07:58 +08:00
|
|
|
this.initEffectPass(this.pass1);
|
|
|
|
this.composer.addPass(this.pass2);
|
|
|
|
},
|
|
|
|
unmounted() {
|
|
|
|
if (this.composer && this.pass2)
|
|
|
|
this.composer.removePass(this.pass2);
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
|
|
|
methods: {
|
2021-04-05 04:02:11 +08:00
|
|
|
updateFocusLine() {
|
2021-04-29 00:07:58 +08:00
|
|
|
this.uniforms1.start.value.copy(this.start);
|
|
|
|
this.uniforms1.end.value.copy(this.end);
|
2021-04-05 04:02:11 +08:00
|
|
|
const dv = new three.Vector2().copy(this.end).sub(this.start).normalize();
|
2021-04-29 00:07:58 +08:00
|
|
|
this.uniforms1.delta.value.copy(dv);
|
|
|
|
this.uniforms2.delta.value.set(-dv.y, dv.x);
|
|
|
|
}
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
__hmrId: "TiltShiftPass"
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
2021-03-04 04:49:22 +08:00
|
|
|
|
2021-04-29 00:07:58 +08:00
|
|
|
const props = {
|
|
|
|
strength: {type: Number, default: 1.5},
|
|
|
|
radius: {type: Number, default: 0},
|
|
|
|
threshold: {type: Number, default: 0}
|
|
|
|
};
|
2021-04-05 04:02:11 +08:00
|
|
|
var UnrealBloomPass = vue.defineComponent({
|
2021-03-04 04:49:22 +08:00
|
|
|
extends: EffectPass,
|
2021-04-29 00:07:58 +08:00
|
|
|
props,
|
|
|
|
created() {
|
|
|
|
if (!this.renderer)
|
|
|
|
return;
|
|
|
|
const size = new three.Vector2(this.renderer.size.width, this.renderer.size.height);
|
2021-04-05 04:02:11 +08:00
|
|
|
const pass = new UnrealBloomPass_js.UnrealBloomPass(size, this.strength, this.radius, this.threshold);
|
2021-04-29 00:07:58 +08:00
|
|
|
Object.keys(props).forEach((p) => {
|
|
|
|
vue.watch(() => this[p], (value) => {
|
|
|
|
pass.uniforms[p].value = value;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
this.initEffectPass(pass);
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
__hmrId: "UnrealBloomPass"
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
2021-03-04 04:49:22 +08:00
|
|
|
|
|
|
|
var ZoomBlur = {
|
|
|
|
uniforms: {
|
2021-04-29 00:07:58 +08:00
|
|
|
tDiffuse: {value: null},
|
|
|
|
center: {value: new three.Vector2(0.5, 0.5)},
|
|
|
|
strength: {value: 0}
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
|
|
|
vertexShader: DefaultShader.vertexShader,
|
2021-04-05 04:02:11 +08:00
|
|
|
fragmentShader: `
|
|
|
|
uniform sampler2D tDiffuse;
|
|
|
|
uniform vec2 center;
|
|
|
|
uniform float strength;
|
|
|
|
varying vec2 vUv;
|
|
|
|
|
|
|
|
float random(vec3 scale, float seed) {
|
|
|
|
/* use the fragment position for a different seed per-pixel */
|
|
|
|
return fract(sin(dot(gl_FragCoord.xyz + seed, scale)) * 43758.5453 + seed);
|
|
|
|
}
|
|
|
|
|
|
|
|
void main() {
|
|
|
|
vec4 color = vec4(0.0);
|
|
|
|
float total = 0.0;
|
|
|
|
vec2 toCenter = center - vUv;
|
|
|
|
|
|
|
|
/* randomize the lookup values to hide the fixed number of samples */
|
|
|
|
float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0);
|
|
|
|
|
|
|
|
for (float t = 0.0; t <= 40.0; t++) {
|
|
|
|
float percent = (t + offset) / 40.0;
|
|
|
|
float weight = 4.0 * (percent - percent * percent);
|
|
|
|
vec4 texel = texture2D(tDiffuse, vUv + toCenter * percent * strength);
|
|
|
|
|
|
|
|
/* switch to pre-multiplied alpha to correctly blur transparent images */
|
|
|
|
texel.rgb *= texel.a;
|
|
|
|
|
|
|
|
color += texel * weight;
|
|
|
|
total += weight;
|
|
|
|
}
|
|
|
|
|
|
|
|
gl_FragColor = color / total;
|
|
|
|
|
|
|
|
/* switch back from pre-multiplied alpha */
|
|
|
|
gl_FragColor.rgb /= gl_FragColor.a + 0.00001;
|
|
|
|
}
|
2021-04-29 00:07:58 +08:00
|
|
|
`
|
2021-03-04 04:49:22 +08:00
|
|
|
};
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
var ZoomBlurPass = vue.defineComponent({
|
2021-03-04 04:49:22 +08:00
|
|
|
extends: EffectPass,
|
|
|
|
props: {
|
2021-04-29 00:07:58 +08:00
|
|
|
center: {type: Object, default: () => ({x: 0.5, y: 0.5})},
|
|
|
|
strength: {type: Number, default: 0.5}
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
created() {
|
2021-04-05 04:02:11 +08:00
|
|
|
const pass = new ShaderPass_js.ShaderPass(ZoomBlur);
|
2021-04-29 00:07:58 +08:00
|
|
|
bindProp(this, "center", pass.uniforms.center, "value");
|
|
|
|
bindProp(this, "strength", pass.uniforms.strength, "value");
|
|
|
|
this.initEffectPass(pass);
|
2021-03-04 04:49:22 +08:00
|
|
|
},
|
2021-04-29 00:07:58 +08:00
|
|
|
__hmrId: "ZoomBlurPass"
|
2021-04-05 04:02:11 +08:00
|
|
|
});
|
2021-03-04 04:49:22 +08:00
|
|
|
|
|
|
|
var TROIS = /*#__PURE__*/Object.freeze({
|
|
|
|
__proto__: null,
|
|
|
|
Renderer: Renderer,
|
2021-04-29 00:07:58 +08:00
|
|
|
RendererInjectionKey: RendererInjectionKey,
|
2021-03-04 04:49:22 +08:00
|
|
|
OrthographicCamera: OrthographicCamera,
|
|
|
|
PerspectiveCamera: PerspectiveCamera,
|
|
|
|
Camera: PerspectiveCamera,
|
|
|
|
Group: Group,
|
|
|
|
Scene: Scene,
|
2021-04-29 00:07:58 +08:00
|
|
|
SceneInjectionKey: SceneInjectionKey,
|
2021-04-05 04:02:11 +08:00
|
|
|
Object3D: Object3D,
|
|
|
|
Raycaster: Raycaster,
|
2021-04-29 00:07:58 +08:00
|
|
|
CubeCamera: CubeCamera,
|
2021-04-30 05:07:04 +08:00
|
|
|
BufferGeometry: Geometry,
|
2021-03-04 04:49:22 +08:00
|
|
|
BoxGeometry: BoxGeometry,
|
|
|
|
CircleGeometry: CircleGeometry,
|
|
|
|
ConeGeometry: ConeGeometry,
|
|
|
|
CylinderGeometry: CylinderGeometry,
|
|
|
|
DodecahedronGeometry: DodecahedronGeometry,
|
|
|
|
IcosahedronGeometry: IcosahedronGeometry,
|
|
|
|
LatheGeometry: LatheGeometry,
|
|
|
|
OctahedronGeometry: OctahedronGeometry,
|
2021-04-07 03:46:35 +08:00
|
|
|
PlaneGeometry: PlaneGeometry,
|
2021-03-04 04:49:22 +08:00
|
|
|
PolyhedronGeometry: PolyhedronGeometry,
|
|
|
|
RingGeometry: RingGeometry,
|
|
|
|
SphereGeometry: SphereGeometry,
|
|
|
|
TetrahedronGeometry: TetrahedronGeometry,
|
|
|
|
TorusGeometry: TorusGeometry,
|
|
|
|
TorusKnotGeometry: TorusKnotGeometry,
|
|
|
|
TubeGeometry: TubeGeometry,
|
|
|
|
AmbientLight: AmbientLight,
|
|
|
|
DirectionalLight: DirectionalLight,
|
2021-03-08 04:17:46 +08:00
|
|
|
HemisphereLight: HemisphereLight,
|
2021-03-04 04:49:22 +08:00
|
|
|
PointLight: PointLight,
|
2021-03-08 04:17:46 +08:00
|
|
|
RectAreaLight: RectAreaLight,
|
2021-03-04 04:49:22 +08:00
|
|
|
SpotLight: SpotLight,
|
2021-04-29 00:07:58 +08:00
|
|
|
Material: Material,
|
|
|
|
MaterialInjectionKey: MaterialInjectionKey,
|
2021-03-04 04:49:22 +08:00
|
|
|
BasicMaterial: BasicMaterial,
|
|
|
|
LambertMaterial: LambertMaterial,
|
|
|
|
MatcapMaterial: MatcapMaterial,
|
|
|
|
PhongMaterial: PhongMaterial,
|
|
|
|
PhysicalMaterial: PhysicalMaterial,
|
2021-03-14 02:34:34 +08:00
|
|
|
ShaderMaterial: ShaderMaterial,
|
2021-03-04 04:49:22 +08:00
|
|
|
StandardMaterial: StandardMaterial,
|
|
|
|
SubSurfaceMaterial: SubSurfaceMaterial,
|
|
|
|
ToonMaterial: ToonMaterial,
|
|
|
|
Texture: Texture,
|
|
|
|
CubeTexture: CubeTexture,
|
2021-04-30 05:07:04 +08:00
|
|
|
PointsMaterial: PointsMaterial,
|
2021-03-04 04:49:22 +08:00
|
|
|
Mesh: Mesh,
|
2021-04-29 00:07:58 +08:00
|
|
|
MeshInjectionKey: MeshInjectionKey,
|
2021-03-04 04:49:22 +08:00
|
|
|
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,
|
|
|
|
Image: Image,
|
|
|
|
InstancedMesh: InstancedMesh,
|
|
|
|
Sprite: Sprite,
|
2021-04-30 05:07:04 +08:00
|
|
|
Points: Points,
|
2021-03-14 02:34:34 +08:00
|
|
|
GLTFModel: GLTF,
|
|
|
|
FBXModel: FBX,
|
2021-03-04 04:49:22 +08:00
|
|
|
EffectComposer: EffectComposer,
|
2021-04-29 00:07:58 +08:00
|
|
|
ComposerInjectionKey: ComposerInjectionKey,
|
2021-03-04 04:49:22 +08:00
|
|
|
RenderPass: RenderPass,
|
|
|
|
BokehPass: BokehPass,
|
|
|
|
FilmPass: FilmPass,
|
|
|
|
FXAAPass: FXAAPass,
|
|
|
|
HalftonePass: HalftonePass,
|
|
|
|
SMAAPass: SMAAPass,
|
2021-04-05 04:02:11 +08:00
|
|
|
SSAOPass: SSAOPass,
|
2021-03-04 04:49:22 +08:00
|
|
|
TiltShiftPass: TiltShiftPass,
|
|
|
|
UnrealBloomPass: UnrealBloomPass,
|
|
|
|
ZoomBlurPass: ZoomBlurPass,
|
|
|
|
setFromProp: setFromProp,
|
2021-03-14 02:34:34 +08:00
|
|
|
bindProps: bindProps,
|
2021-03-08 04:17:46 +08:00
|
|
|
bindProp: bindProp,
|
2021-03-04 04:49:22 +08:00
|
|
|
propsValues: propsValues,
|
|
|
|
lerp: lerp,
|
|
|
|
limit: limit,
|
2021-04-05 04:02:11 +08:00
|
|
|
getMatcapUrl: getMatcapUrl
|
2021-03-04 04:49:22 +08:00
|
|
|
});
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
const TroisJSVuePlugin = {
|
2021-04-29 00:07:58 +08:00
|
|
|
install(app) {
|
2021-04-05 04:02:11 +08:00
|
|
|
const comps = [
|
2021-04-29 00:07:58 +08:00
|
|
|
"Camera",
|
|
|
|
"OrthographicCamera",
|
|
|
|
"PerspectiveCamera",
|
|
|
|
"Raycaster",
|
|
|
|
"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",
|
|
|
|
"PlaneGeometry",
|
|
|
|
"Polyhedron",
|
|
|
|
"PolyhedronGeometry",
|
|
|
|
"Ring",
|
|
|
|
"RingGeometry",
|
|
|
|
"Sphere",
|
|
|
|
"SphereGeometry",
|
|
|
|
"Tetrahedron",
|
|
|
|
"TetrahedronGeometry",
|
|
|
|
"Text",
|
|
|
|
"Torus",
|
|
|
|
"TorusGeometry",
|
|
|
|
"TorusKnot",
|
|
|
|
"TorusKnotGeometry",
|
|
|
|
"Tube",
|
|
|
|
"TubeGeometry",
|
|
|
|
"Image",
|
|
|
|
"InstancedMesh",
|
|
|
|
"Sprite",
|
|
|
|
"FBXModel",
|
|
|
|
"GLTFModel",
|
|
|
|
"BokehPass",
|
|
|
|
"EffectComposer",
|
|
|
|
"FilmPass",
|
|
|
|
"FXAAPass",
|
|
|
|
"HalftonePass",
|
|
|
|
"RenderPass",
|
|
|
|
"SAOPass",
|
|
|
|
"SMAAPass",
|
|
|
|
"SSAOPass",
|
|
|
|
"TiltShiftPass",
|
|
|
|
"UnrealBloomPass",
|
|
|
|
"ZoomBlurPass",
|
|
|
|
"GLTFViewer"
|
2021-04-05 04:02:11 +08:00
|
|
|
];
|
2021-04-29 00:07:58 +08:00
|
|
|
comps.forEach((comp) => {
|
2021-03-04 04:49:22 +08:00
|
|
|
app.component(comp, TROIS[comp]);
|
|
|
|
});
|
2021-04-29 00:07:58 +08:00
|
|
|
}
|
2021-03-04 04:49:22 +08:00
|
|
|
};
|
2021-03-08 04:17:46 +08:00
|
|
|
function createApp(params) {
|
|
|
|
return vue.createApp(params).use(TroisJSVuePlugin);
|
|
|
|
}
|
|
|
|
|
2021-04-29 00:07:58 +08:00
|
|
|
function useTextures() {
|
|
|
|
const obj = {
|
|
|
|
loader: new three.TextureLoader(),
|
|
|
|
count: 0,
|
|
|
|
textures: [],
|
|
|
|
loadProgress: 0,
|
|
|
|
loadTextures,
|
|
|
|
dispose
|
|
|
|
};
|
|
|
|
return obj;
|
|
|
|
function loadTextures(images, cb) {
|
|
|
|
obj.count = images.length;
|
|
|
|
obj.textures.splice(0);
|
|
|
|
obj.loadProgress = 0;
|
|
|
|
Promise.all(images.map(loadTexture)).then(cb);
|
|
|
|
}
|
|
|
|
function loadTexture(img, index) {
|
|
|
|
return new Promise((resolve) => {
|
|
|
|
obj.loader.load(img.src, (texture) => {
|
|
|
|
obj.loadProgress += 1 / obj.count;
|
|
|
|
obj.textures[index] = texture;
|
|
|
|
resolve(texture);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
function dispose() {
|
|
|
|
obj.textures.forEach((t) => t.dispose());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-04 04:49:22 +08:00
|
|
|
exports.AmbientLight = AmbientLight;
|
|
|
|
exports.BasicMaterial = BasicMaterial;
|
|
|
|
exports.BokehPass = BokehPass;
|
|
|
|
exports.Box = Box;
|
|
|
|
exports.BoxGeometry = BoxGeometry;
|
2021-04-30 05:07:04 +08:00
|
|
|
exports.BufferGeometry = Geometry;
|
2021-03-04 04:49:22 +08:00
|
|
|
exports.Camera = PerspectiveCamera;
|
|
|
|
exports.Circle = Circle;
|
|
|
|
exports.CircleGeometry = CircleGeometry;
|
2021-04-29 00:07:58 +08:00
|
|
|
exports.ComposerInjectionKey = ComposerInjectionKey;
|
2021-03-04 04:49:22 +08:00
|
|
|
exports.Cone = Cone;
|
|
|
|
exports.ConeGeometry = ConeGeometry;
|
2021-04-29 00:07:58 +08:00
|
|
|
exports.CubeCamera = CubeCamera;
|
2021-03-04 04:49:22 +08:00
|
|
|
exports.CubeTexture = CubeTexture;
|
|
|
|
exports.Cylinder = Cylinder;
|
|
|
|
exports.CylinderGeometry = CylinderGeometry;
|
|
|
|
exports.DirectionalLight = DirectionalLight;
|
|
|
|
exports.Dodecahedron = Dodecahedron;
|
|
|
|
exports.DodecahedronGeometry = DodecahedronGeometry;
|
|
|
|
exports.EffectComposer = EffectComposer;
|
2021-03-14 02:34:34 +08:00
|
|
|
exports.FBXModel = FBX;
|
2021-03-04 04:49:22 +08:00
|
|
|
exports.FXAAPass = FXAAPass;
|
|
|
|
exports.FilmPass = FilmPass;
|
2021-03-14 02:34:34 +08:00
|
|
|
exports.GLTFModel = GLTF;
|
2021-03-04 04:49:22 +08:00
|
|
|
exports.Group = Group;
|
|
|
|
exports.HalftonePass = HalftonePass;
|
2021-03-08 04:17:46 +08:00
|
|
|
exports.HemisphereLight = HemisphereLight;
|
2021-03-04 04:49:22 +08:00
|
|
|
exports.Icosahedron = Icosahedron;
|
|
|
|
exports.IcosahedronGeometry = IcosahedronGeometry;
|
|
|
|
exports.Image = Image;
|
|
|
|
exports.InstancedMesh = InstancedMesh;
|
|
|
|
exports.LambertMaterial = LambertMaterial;
|
|
|
|
exports.Lathe = Lathe;
|
|
|
|
exports.LatheGeometry = LatheGeometry;
|
|
|
|
exports.MatcapMaterial = MatcapMaterial;
|
2021-04-29 00:07:58 +08:00
|
|
|
exports.Material = Material;
|
|
|
|
exports.MaterialInjectionKey = MaterialInjectionKey;
|
2021-03-04 04:49:22 +08:00
|
|
|
exports.Mesh = Mesh;
|
2021-04-29 00:07:58 +08:00
|
|
|
exports.MeshInjectionKey = MeshInjectionKey;
|
2021-04-05 04:02:11 +08:00
|
|
|
exports.Object3D = Object3D;
|
2021-03-04 04:49:22 +08:00
|
|
|
exports.Octahedron = Octahedron;
|
|
|
|
exports.OctahedronGeometry = OctahedronGeometry;
|
|
|
|
exports.OrthographicCamera = OrthographicCamera;
|
|
|
|
exports.PerspectiveCamera = PerspectiveCamera;
|
|
|
|
exports.PhongMaterial = PhongMaterial;
|
|
|
|
exports.PhysicalMaterial = PhysicalMaterial;
|
|
|
|
exports.Plane = Plane;
|
2021-04-07 03:46:35 +08:00
|
|
|
exports.PlaneGeometry = PlaneGeometry;
|
2021-03-04 04:49:22 +08:00
|
|
|
exports.PointLight = PointLight;
|
2021-04-30 05:07:04 +08:00
|
|
|
exports.Points = Points;
|
|
|
|
exports.PointsMaterial = PointsMaterial;
|
2021-03-04 04:49:22 +08:00
|
|
|
exports.Polyhedron = Polyhedron;
|
|
|
|
exports.PolyhedronGeometry = PolyhedronGeometry;
|
2021-04-05 04:02:11 +08:00
|
|
|
exports.Raycaster = Raycaster;
|
2021-03-08 04:17:46 +08:00
|
|
|
exports.RectAreaLight = RectAreaLight;
|
2021-03-04 04:49:22 +08:00
|
|
|
exports.RenderPass = RenderPass;
|
|
|
|
exports.Renderer = Renderer;
|
2021-04-29 00:07:58 +08:00
|
|
|
exports.RendererInjectionKey = RendererInjectionKey;
|
2021-03-04 04:49:22 +08:00
|
|
|
exports.Ring = Ring;
|
|
|
|
exports.RingGeometry = RingGeometry;
|
|
|
|
exports.SMAAPass = SMAAPass;
|
2021-04-05 04:02:11 +08:00
|
|
|
exports.SSAOPass = SSAOPass;
|
2021-03-04 04:49:22 +08:00
|
|
|
exports.Scene = Scene;
|
2021-04-29 00:07:58 +08:00
|
|
|
exports.SceneInjectionKey = SceneInjectionKey;
|
2021-03-14 02:34:34 +08:00
|
|
|
exports.ShaderMaterial = ShaderMaterial;
|
2021-03-04 04:49:22 +08:00
|
|
|
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;
|
2021-03-08 04:17:46 +08:00
|
|
|
exports.bindProp = bindProp;
|
2021-03-14 02:34:34 +08:00
|
|
|
exports.bindProps = bindProps;
|
2021-03-08 04:17:46 +08:00
|
|
|
exports.createApp = createApp;
|
2021-03-04 04:49:22 +08:00
|
|
|
exports.getMatcapUrl = getMatcapUrl;
|
|
|
|
exports.lerp = lerp;
|
|
|
|
exports.limit = limit;
|
|
|
|
exports.propsValues = propsValues;
|
|
|
|
exports.setFromProp = setFromProp;
|
2021-04-29 00:07:58 +08:00
|
|
|
exports.useTextures = useTextures;
|
|
|
|
//# sourceMappingURL=trois.js.map
|