2021-04-05 04:02:11 +08:00
|
|
|
|
import { defineComponent, h, toRef, watch, createApp as createApp$1 } from 'vue';
|
|
|
|
|
import { VRButton } from 'three/examples/jsm/webxr/VRButton.js';
|
|
|
|
|
import { Vector3, Raycaster as Raycaster$1, Plane as Plane$1, Vector2, InstancedMesh as InstancedMesh$1, WebGLRenderer, OrthographicCamera as OrthographicCamera$1, PerspectiveCamera as PerspectiveCamera$1, Group as Group$1, Scene as Scene$1, Color, BoxGeometry as BoxGeometry$1, CircleGeometry as CircleGeometry$1, ConeGeometry as ConeGeometry$1, CylinderGeometry as CylinderGeometry$1, DodecahedronGeometry as DodecahedronGeometry$1, IcosahedronGeometry as IcosahedronGeometry$1, LatheGeometry as LatheGeometry$1, OctahedronGeometry as OctahedronGeometry$1, PolyhedronGeometry as PolyhedronGeometry$1, RingGeometry as RingGeometry$1, SphereGeometry as SphereGeometry$1, TetrahedronGeometry as TetrahedronGeometry$1, TorusGeometry as TorusGeometry$1, TorusKnotGeometry as TorusKnotGeometry$1, TubeGeometry as TubeGeometry$1, Curve, CatmullRomCurve3, AmbientLight as AmbientLight$1, DirectionalLight as DirectionalLight$1, HemisphereLight as HemisphereLight$1, PointLight as PointLight$1, RectAreaLight as RectAreaLight$1, SpotLight as SpotLight$1, FrontSide, MeshBasicMaterial, MeshLambertMaterial, TextureLoader, MeshMatcapMaterial, MeshPhongMaterial, MeshStandardMaterial, MeshPhysicalMaterial, ShaderMaterial as ShaderMaterial$1, ShaderChunk, UniformsUtils, ShaderLib, MeshToonMaterial, UVMapping, ClampToEdgeWrapping, LinearFilter, LinearMipmapLinearFilter, CubeTextureLoader, CubeRefractionMapping, Mesh as Mesh$1, PlaneGeometry, FontLoader, TextGeometry, WebGLCubeRenderTarget, RGBFormat, CubeCamera, BackSide, DoubleSide, SpriteMaterial, Sprite as Sprite$1 } from 'three';
|
2020-09-17 05:54:14 +08:00
|
|
|
|
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
|
2021-03-08 04:17:46 +08:00
|
|
|
|
import { RectAreaLightUniformsLib } from 'three/examples/jsm/lights/RectAreaLightUniformsLib.js';
|
|
|
|
|
import { RectAreaLightHelper } from 'three/examples/jsm/helpers/RectAreaLightHelper.js';
|
2021-03-14 02:34:34 +08:00
|
|
|
|
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
|
|
|
|
|
import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader.js';
|
2020-09-17 05:54:14 +08:00
|
|
|
|
import { EffectComposer as EffectComposer$1 } from 'three/examples/jsm/postprocessing/EffectComposer.js';
|
|
|
|
|
import { RenderPass as RenderPass$1 } from 'three/examples/jsm/postprocessing/RenderPass.js';
|
|
|
|
|
import { BokehPass as BokehPass$1 } from 'three/examples/jsm/postprocessing/BokehPass.js';
|
2020-10-04 06:49:05 +08:00
|
|
|
|
import { FilmPass as FilmPass$1 } from 'three/examples/jsm/postprocessing/FilmPass.js';
|
2021-02-26 05:55:44 +08:00
|
|
|
|
import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js';
|
|
|
|
|
import { FXAAShader } from 'three/examples/jsm/shaders/FXAAShader.js';
|
2020-10-04 06:49:05 +08:00
|
|
|
|
import { HalftonePass as HalftonePass$1 } from 'three/examples/jsm/postprocessing/HalftonePass.js';
|
2021-02-26 05:55:44 +08:00
|
|
|
|
import { SMAAPass as SMAAPass$1 } from 'three/examples/jsm/postprocessing/SMAAPass.js';
|
2021-04-05 04:02:11 +08:00
|
|
|
|
import { SSAOPass as SSAOPass$1 } from 'three/examples/jsm/postprocessing/SSAOPass.js';
|
2020-09-17 05:54:14 +08:00
|
|
|
|
import { UnrealBloomPass as UnrealBloomPass$1 } from 'three/examples/jsm/postprocessing/UnrealBloomPass.js';
|
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
function useRaycaster(options) {
|
|
|
|
|
const {
|
|
|
|
|
camera,
|
|
|
|
|
resetPosition = new Vector3(0, 0, 0),
|
|
|
|
|
} = options;
|
|
|
|
|
|
|
|
|
|
const raycaster = new Raycaster$1();
|
|
|
|
|
const position = resetPosition.clone();
|
|
|
|
|
const plane = new Plane$1(new 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,
|
|
|
|
|
intersect,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function usePointer(options) {
|
|
|
|
|
const {
|
|
|
|
|
camera,
|
|
|
|
|
domElement,
|
|
|
|
|
intersectObjects,
|
|
|
|
|
touch = true,
|
|
|
|
|
resetOnEnd = false,
|
|
|
|
|
resetPosition = new Vector2(0, 0),
|
|
|
|
|
resetPositionV3 = new Vector3(0, 0, 0),
|
|
|
|
|
onEnter = () => {},
|
|
|
|
|
onMove = () => {},
|
|
|
|
|
onLeave = () => {},
|
|
|
|
|
onIntersectEnter = () => {},
|
|
|
|
|
onIntersectOver = () => {},
|
|
|
|
|
onIntersectMove = () => {},
|
|
|
|
|
onIntersectLeave = () => {},
|
|
|
|
|
onIntersectClick = () => {},
|
|
|
|
|
} = options;
|
|
|
|
|
|
|
|
|
|
const position = resetPosition.clone();
|
|
|
|
|
const positionN = new Vector2(0, 0);
|
|
|
|
|
|
|
|
|
|
const raycaster = useRaycaster({ camera });
|
|
|
|
|
const positionV3 = raycaster.position;
|
|
|
|
|
|
|
|
|
|
const obj = {
|
|
|
|
|
position,
|
|
|
|
|
positionN,
|
|
|
|
|
positionV3,
|
|
|
|
|
intersectObjects,
|
|
|
|
|
listeners: false,
|
|
|
|
|
addListeners,
|
|
|
|
|
removeListeners,
|
|
|
|
|
intersect,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return obj;
|
|
|
|
|
|
|
|
|
|
function reset() {
|
|
|
|
|
position.copy(resetPosition);
|
|
|
|
|
positionV3.copy(resetPositionV3);
|
|
|
|
|
}
|
|
|
|
|
function updatePosition(event) {
|
|
|
|
|
let x, y;
|
|
|
|
|
if (event.touches && event.touches.length > 0) {
|
|
|
|
|
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;
|
|
|
|
|
positionN.x = (position.x / rect.width) * 2 - 1;
|
|
|
|
|
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 = [];
|
|
|
|
|
|
|
|
|
|
intersects.forEach(intersect => {
|
|
|
|
|
const { object } = intersect;
|
|
|
|
|
const { component } = object;
|
|
|
|
|
|
|
|
|
|
// only once for InstancedMesh
|
|
|
|
|
if (object instanceof InstancedMesh$1) {
|
|
|
|
|
if (iMeshes.indexOf(object) !== -1) return;
|
|
|
|
|
iMeshes.push(object);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!object.over) {
|
|
|
|
|
object.over = true;
|
|
|
|
|
const overEvent = { type: 'pointerover', over: true, component, intersect };
|
|
|
|
|
const enterEvent = { ...overEvent, type: 'pointerenter' };
|
|
|
|
|
onIntersectOver(overEvent);
|
|
|
|
|
onIntersectEnter(enterEvent);
|
|
|
|
|
component.onPointerOver?.(overEvent);
|
|
|
|
|
component.onPointerEnter?.(enterEvent);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const moveEvent = { type: 'pointermove', component, intersect };
|
|
|
|
|
onIntersectMove(moveEvent);
|
|
|
|
|
component.onPointerMove?.(moveEvent);
|
|
|
|
|
|
|
|
|
|
offObjects.splice(offObjects.indexOf(object), 1);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
offObjects.forEach(object => {
|
|
|
|
|
const { component } = object;
|
|
|
|
|
if (object.over) {
|
|
|
|
|
object.over = false;
|
|
|
|
|
const overEvent = { type: 'pointerover', over: false, component };
|
|
|
|
|
const leaveEvent = { ...overEvent, type: 'pointerleave' };
|
|
|
|
|
onIntersectOver(overEvent);
|
|
|
|
|
onIntersectLeave(leaveEvent);
|
|
|
|
|
component.onPointerOver?.(overEvent);
|
|
|
|
|
component.onPointerLeave?.(leaveEvent);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
function pointerEnter(event) {
|
|
|
|
|
updatePosition(event);
|
|
|
|
|
onEnter({ type: 'pointerenter', position, positionN, positionV3 });
|
|
|
|
|
}
|
|
|
|
|
function pointerMove(event) {
|
|
|
|
|
updatePosition(event);
|
|
|
|
|
onMove({ type: 'pointermove', position, positionN, positionV3 });
|
|
|
|
|
intersect();
|
|
|
|
|
}
|
|
|
|
|
function pointerClick(event) {
|
|
|
|
|
updatePosition(event);
|
|
|
|
|
if (intersectObjects.length) {
|
|
|
|
|
const intersects = raycaster.intersect(positionN, intersectObjects);
|
|
|
|
|
const iMeshes = [];
|
|
|
|
|
intersects.forEach(intersect => {
|
|
|
|
|
const { object } = intersect;
|
|
|
|
|
const { component } = object;
|
|
|
|
|
|
|
|
|
|
// only once for InstancedMesh
|
|
|
|
|
if (object instanceof InstancedMesh$1) {
|
|
|
|
|
if (iMeshes.indexOf(object) !== -1) return;
|
|
|
|
|
iMeshes.push(object);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const event = { type: 'click', component, intersect };
|
|
|
|
|
onIntersectClick(event);
|
|
|
|
|
component.onClick?.(event);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
function pointerLeave() {
|
|
|
|
|
if (resetOnEnd) reset();
|
|
|
|
|
onLeave({ type: 'pointerleave' });
|
|
|
|
|
}
|
|
|
|
|
function addListeners() {
|
|
|
|
|
domElement.addEventListener('mouseenter', pointerEnter);
|
|
|
|
|
domElement.addEventListener('mousemove', pointerMove);
|
|
|
|
|
domElement.addEventListener('mouseleave', pointerLeave);
|
|
|
|
|
domElement.addEventListener('click', pointerClick);
|
|
|
|
|
if (touch) {
|
|
|
|
|
domElement.addEventListener('touchstart', pointerEnter);
|
|
|
|
|
domElement.addEventListener('touchmove', pointerMove);
|
|
|
|
|
domElement.addEventListener('touchend', pointerLeave);
|
|
|
|
|
}
|
|
|
|
|
obj.listeners = true;
|
|
|
|
|
}
|
|
|
|
|
function removeListeners() {
|
|
|
|
|
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);
|
|
|
|
|
obj.listeners = false;
|
|
|
|
|
}}
|
|
|
|
|
|
2020-09-17 05:54:14 +08:00
|
|
|
|
/**
|
|
|
|
|
* Three.js helper
|
|
|
|
|
*/
|
|
|
|
|
function useThree() {
|
|
|
|
|
// default conf
|
2021-04-05 04:02:11 +08:00
|
|
|
|
const conf = {
|
2020-09-17 05:54:14 +08:00
|
|
|
|
canvas: null,
|
|
|
|
|
antialias: true,
|
|
|
|
|
alpha: false,
|
2020-10-04 06:49:05 +08:00
|
|
|
|
autoClear: true,
|
2020-09-17 05:54:14 +08:00
|
|
|
|
orbit_ctrl: false,
|
2021-04-05 04:02:11 +08:00
|
|
|
|
pointer: false,
|
|
|
|
|
resize: false,
|
|
|
|
|
width: 300,
|
|
|
|
|
height: 150,
|
2020-09-17 05:54:14 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// size
|
2021-04-05 04:02:11 +08:00
|
|
|
|
const size = {
|
2021-02-26 05:55:44 +08:00
|
|
|
|
width: 1, height: 1,
|
|
|
|
|
wWidth: 1, wHeight: 1,
|
|
|
|
|
ratio: 1,
|
2020-09-17 05:54:14 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// handlers
|
2021-04-05 04:02:11 +08:00
|
|
|
|
const afterInitCallbacks = [];
|
|
|
|
|
let afterResizeCallbacks = [];
|
|
|
|
|
let beforeRenderCallbacks = [];
|
2020-09-17 05:54:14 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
const intersectObjects = [];
|
2021-02-26 05:55:44 +08:00
|
|
|
|
|
2020-09-17 05:54:14 +08:00
|
|
|
|
// returned object
|
2021-04-05 04:02:11 +08:00
|
|
|
|
const obj = {
|
|
|
|
|
conf,
|
2020-09-17 05:54:14 +08:00
|
|
|
|
renderer: null,
|
|
|
|
|
camera: null,
|
|
|
|
|
cameraCtrl: null,
|
|
|
|
|
scene: null,
|
2021-04-05 04:02:11 +08:00
|
|
|
|
pointer: null,
|
|
|
|
|
size,
|
|
|
|
|
init,
|
|
|
|
|
dispose,
|
|
|
|
|
render,
|
|
|
|
|
renderC,
|
|
|
|
|
setSize,
|
|
|
|
|
onAfterInit,
|
|
|
|
|
onAfterResize, offAfterResize,
|
|
|
|
|
onBeforeRender, offBeforeRender,
|
|
|
|
|
addIntersectObject, removeIntersectObject,
|
2020-09-17 05:54:14 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* init three
|
|
|
|
|
*/
|
|
|
|
|
function init(params) {
|
|
|
|
|
if (params) {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
Object.entries(params).forEach(([key, value]) => {
|
2020-09-17 05:54:14 +08:00
|
|
|
|
conf[key] = value;
|
2020-10-04 06:49:05 +08:00
|
|
|
|
});
|
2020-09-17 05:54:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!obj.scene) {
|
|
|
|
|
console.error('Missing Scene');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!obj.camera) {
|
|
|
|
|
console.error('Missing Camera');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
obj.renderer = new WebGLRenderer({ canvas: conf.canvas, antialias: conf.antialias, alpha: conf.alpha });
|
2020-10-04 06:49:05 +08:00
|
|
|
|
obj.renderer.autoClear = conf.autoClear;
|
2020-09-17 05:54:14 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
if (conf.resize) {
|
|
|
|
|
onResize();
|
|
|
|
|
window.addEventListener('resize', onResize);
|
|
|
|
|
} else {
|
|
|
|
|
setSize(conf.width, conf.height);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
initPointer();
|
|
|
|
|
|
2020-09-17 05:54:14 +08:00
|
|
|
|
if (conf.orbit_ctrl) {
|
|
|
|
|
obj.orbitCtrl = new OrbitControls(obj.camera, obj.renderer.domElement);
|
|
|
|
|
if (conf.orbit_ctrl instanceof Object) {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
Object.entries(conf.orbit_ctrl).forEach(([key, value]) => {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
obj.orbitCtrl[key] = value;
|
|
|
|
|
});
|
2020-09-17 05:54:14 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
afterInitCallbacks.forEach(c => c());
|
2020-09-17 05:54:14 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
function initPointer() {
|
|
|
|
|
let pointerConf = {
|
|
|
|
|
camera: obj.camera,
|
|
|
|
|
domElement: obj.renderer.domElement,
|
|
|
|
|
intersectObjects,
|
|
|
|
|
};
|
2020-09-17 05:54:14 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
if (conf.pointer && conf.pointer instanceof Object) {
|
|
|
|
|
pointerConf = { ...pointerConf, ...conf.pointer };
|
2021-02-26 05:55:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
obj.pointer = usePointer(pointerConf);
|
|
|
|
|
if (conf.pointer || intersectObjects.length) {
|
|
|
|
|
obj.pointer.addListeners();
|
|
|
|
|
if (conf.pointer.intersectMode === 'frame') {
|
|
|
|
|
onBeforeRender(() => {
|
|
|
|
|
obj.pointer.intersect();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-09-17 05:54:14 +08:00
|
|
|
|
}
|
2021-04-05 04:02:11 +08:00
|
|
|
|
|
2020-09-17 05:54:14 +08:00
|
|
|
|
/**
|
2020-10-04 06:49:05 +08:00
|
|
|
|
* add after init callback
|
2020-09-17 05:54:14 +08:00
|
|
|
|
*/
|
|
|
|
|
function onAfterInit(callback) {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
afterInitCallbacks.push(callback);
|
2020-09-17 05:54:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2020-10-04 06:49:05 +08:00
|
|
|
|
* add after resize callback
|
2020-09-17 05:54:14 +08:00
|
|
|
|
*/
|
|
|
|
|
function onAfterResize(callback) {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
afterResizeCallbacks.push(callback);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* remove after resize callback
|
|
|
|
|
*/
|
|
|
|
|
function offAfterResize(callback) {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
afterResizeCallbacks = afterResizeCallbacks.filter(c => c !== callback);
|
2020-09-17 05:54:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2020-10-04 06:49:05 +08:00
|
|
|
|
* add before render callback
|
2020-09-17 05:54:14 +08:00
|
|
|
|
*/
|
|
|
|
|
function onBeforeRender(callback) {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
beforeRenderCallbacks.push(callback);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* remove before render callback
|
|
|
|
|
*/
|
|
|
|
|
function offBeforeRender(callback) {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
beforeRenderCallbacks = beforeRenderCallbacks.filter(c => c !== callback);
|
2020-09-17 05:54:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* default render
|
|
|
|
|
*/
|
|
|
|
|
function render() {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
if (obj.orbitCtrl) obj.orbitCtrl.update();
|
|
|
|
|
beforeRenderCallbacks.forEach(c => c());
|
2020-09-17 05:54:14 +08:00
|
|
|
|
obj.renderer.render(obj.scene, obj.camera);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* composer render
|
|
|
|
|
*/
|
|
|
|
|
function renderC() {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
if (obj.orbitCtrl) obj.orbitCtrl.update();
|
|
|
|
|
beforeRenderCallbacks.forEach(c => c());
|
2020-09-17 05:54:14 +08:00
|
|
|
|
obj.composer.render();
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-26 05:55:44 +08:00
|
|
|
|
/**
|
|
|
|
|
* add intersect object
|
|
|
|
|
*/
|
|
|
|
|
function addIntersectObject(o) {
|
|
|
|
|
if (intersectObjects.indexOf(o) === -1) {
|
|
|
|
|
intersectObjects.push(o);
|
|
|
|
|
}
|
2021-04-05 04:02:11 +08:00
|
|
|
|
// add listeners if needed
|
|
|
|
|
if (obj.pointer && !obj.pointer.listeners) {
|
|
|
|
|
obj.pointer.addListeners();
|
|
|
|
|
}
|
2021-02-26 05:55:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* remove intersect object
|
|
|
|
|
*/
|
|
|
|
|
function removeIntersectObject(o) {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
const i = intersectObjects.indexOf(o);
|
2021-02-26 05:55:44 +08:00
|
|
|
|
if (i !== -1) {
|
|
|
|
|
intersectObjects.splice(i, 1);
|
|
|
|
|
}
|
2021-04-05 04:02:11 +08:00
|
|
|
|
// remove listeners if needed
|
|
|
|
|
if (obj.pointer && !conf.pointer && intersectObjects.length === 0) {
|
|
|
|
|
obj.pointer.removeListeners();
|
|
|
|
|
}
|
2021-02-26 05:55:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
2020-09-17 05:54:14 +08:00
|
|
|
|
/**
|
2021-04-05 04:02:11 +08:00
|
|
|
|
* remove listeners and dispose
|
2020-09-17 05:54:14 +08:00
|
|
|
|
*/
|
|
|
|
|
function dispose() {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
beforeRenderCallbacks = [];
|
2020-09-17 05:54:14 +08:00
|
|
|
|
window.removeEventListener('resize', onResize);
|
2021-04-05 04:02:11 +08:00
|
|
|
|
if (obj.pointer) obj.pointer.removeListeners();
|
|
|
|
|
if (obj.orbitCtrl) obj.orbitCtrl.dispose();
|
|
|
|
|
obj.renderer.dispose();
|
2020-09-17 05:54:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* resize listener
|
|
|
|
|
*/
|
|
|
|
|
function onResize() {
|
|
|
|
|
if (conf.resize === 'window') {
|
|
|
|
|
setSize(window.innerWidth, window.innerHeight);
|
|
|
|
|
} else {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
const elt = obj.renderer.domElement.parentNode;
|
2021-02-26 05:55:44 +08:00
|
|
|
|
setSize(elt.clientWidth, elt.clientHeight);
|
2020-09-17 05:54:14 +08:00
|
|
|
|
}
|
2021-04-05 04:02:11 +08:00
|
|
|
|
afterResizeCallbacks.forEach(c => c());
|
2020-09-17 05:54:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* update renderer size and camera
|
|
|
|
|
*/
|
|
|
|
|
function setSize(width, height) {
|
|
|
|
|
size.width = width;
|
|
|
|
|
size.height = height;
|
|
|
|
|
size.ratio = width / height;
|
|
|
|
|
|
|
|
|
|
obj.renderer.setSize(width, height, false);
|
|
|
|
|
obj.camera.aspect = size.ratio;
|
|
|
|
|
obj.camera.updateProjectionMatrix();
|
|
|
|
|
|
|
|
|
|
if (obj.composer) {
|
|
|
|
|
obj.composer.setSize(width, height);
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-26 05:55:44 +08:00
|
|
|
|
if (obj.camera.type === 'OrthographicCamera') {
|
|
|
|
|
size.wWidth = obj.camera.right - obj.camera.left;
|
|
|
|
|
size.wHeight = obj.camera.top - obj.camera.bottom;
|
|
|
|
|
} else {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
const wsize = getCameraSize();
|
2021-02-26 05:55:44 +08:00
|
|
|
|
size.wWidth = wsize[0]; size.wHeight = wsize[1];
|
|
|
|
|
}
|
2020-09-17 05:54:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* calculate camera visible area size
|
|
|
|
|
*/
|
|
|
|
|
function getCameraSize() {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
const vFOV = (obj.camera.fov * Math.PI) / 180;
|
|
|
|
|
const h = 2 * Math.tan(vFOV / 2) * Math.abs(obj.camera.position.z);
|
|
|
|
|
const w = h * obj.camera.aspect;
|
2020-09-17 05:54:14 +08:00
|
|
|
|
return [w, h];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return obj;
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var Renderer = defineComponent({
|
2021-03-08 04:17:46 +08:00
|
|
|
|
name: 'Renderer',
|
2020-09-17 05:54:14 +08:00
|
|
|
|
props: {
|
2021-02-26 05:55:44 +08:00
|
|
|
|
antialias: Boolean,
|
|
|
|
|
alpha: Boolean,
|
|
|
|
|
autoClear: { type: Boolean, default: true },
|
|
|
|
|
orbitCtrl: { type: [Boolean, Object], default: false },
|
2021-04-05 04:02:11 +08:00
|
|
|
|
pointer: { type: [Boolean, Object], default: false },
|
2021-03-05 16:17:16 +08:00
|
|
|
|
resize: { type: [Boolean, String], default: false },
|
2021-02-26 05:55:44 +08:00
|
|
|
|
shadow: Boolean,
|
2020-09-17 05:54:14 +08:00
|
|
|
|
width: String,
|
|
|
|
|
height: String,
|
2021-04-05 04:02:11 +08:00
|
|
|
|
xr: Boolean,
|
2020-09-17 05:54:14 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
setup() {
|
2020-09-17 05:54:14 +08:00
|
|
|
|
return {
|
|
|
|
|
three: useThree(),
|
|
|
|
|
raf: true,
|
2020-10-04 06:49:05 +08:00
|
|
|
|
onMountedCallbacks: [],
|
2020-09-17 05:54:14 +08:00
|
|
|
|
};
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
provide() {
|
2020-09-17 05:54:14 +08:00
|
|
|
|
return {
|
|
|
|
|
three: this.three,
|
2020-10-04 06:49:05 +08:00
|
|
|
|
// renderer: this.three.renderer,
|
|
|
|
|
rendererComponent: this,
|
2020-09-17 05:54:14 +08:00
|
|
|
|
};
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
mounted() {
|
|
|
|
|
const params = {
|
2021-02-26 05:55:44 +08:00
|
|
|
|
canvas: this.$el,
|
2020-09-17 05:54:14 +08:00
|
|
|
|
antialias: this.antialias,
|
|
|
|
|
alpha: this.alpha,
|
2020-10-04 06:49:05 +08:00
|
|
|
|
autoClear: this.autoClear,
|
2020-09-17 05:54:14 +08:00
|
|
|
|
orbit_ctrl: this.orbitCtrl,
|
2021-04-05 04:02:11 +08:00
|
|
|
|
pointer: this.pointer,
|
2020-09-17 05:54:14 +08:00
|
|
|
|
resize: this.resize,
|
|
|
|
|
width: this.width,
|
|
|
|
|
height: this.height,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (this.three.init(params)) {
|
2021-03-08 04:17:46 +08:00
|
|
|
|
this.renderer = this.three.renderer;
|
|
|
|
|
this.renderer.shadowMap.enabled = this.shadow;
|
2021-04-05 04:02:11 +08:00
|
|
|
|
|
|
|
|
|
if (this.xr) {
|
|
|
|
|
this.vrButton = VRButton.createButton(this.renderer);
|
|
|
|
|
this.renderer.domElement.parentNode.appendChild(this.vrButton);
|
|
|
|
|
this.renderer.xr.enabled = true;
|
|
|
|
|
if (this.three.composer) this.renderer.setAnimationLoop(this.animateXRC);
|
|
|
|
|
else this.renderer.setAnimationLoop(this.animateXR);
|
|
|
|
|
} else {
|
|
|
|
|
if (this.three.composer) this.animateC();
|
|
|
|
|
else this.animate();
|
|
|
|
|
}
|
2020-10-04 06:49:05 +08:00
|
|
|
|
}
|
2021-04-05 04:02:11 +08:00
|
|
|
|
this.onMountedCallbacks.forEach(c => c());
|
2020-10-04 06:49:05 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
beforeUnmount() {
|
2020-09-17 05:54:14 +08:00
|
|
|
|
this.raf = false;
|
|
|
|
|
this.three.dispose();
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
onMounted(callback) {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
this.onMountedCallbacks.push(callback);
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
onBeforeRender(callback) {
|
2020-09-17 05:54:14 +08:00
|
|
|
|
this.three.onBeforeRender(callback);
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
onAfterResize(callback) {
|
2020-09-17 05:54:14 +08:00
|
|
|
|
this.three.onAfterResize(callback);
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
animate() {
|
|
|
|
|
if (this.raf) requestAnimationFrame(this.animate);
|
2020-09-17 05:54:14 +08:00
|
|
|
|
this.three.render();
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
animateC() {
|
|
|
|
|
if (this.raf) requestAnimationFrame(this.animateC);
|
2020-09-17 05:54:14 +08:00
|
|
|
|
this.three.renderC();
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
animateXR() { this.three.render(); },
|
|
|
|
|
animateXRC() { this.three.renderC(); },
|
2020-09-17 05:54:14 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
render() {
|
2021-02-26 05:55:44 +08:00
|
|
|
|
return h('canvas', {}, this.$slots.default());
|
2020-09-17 05:54:14 +08:00
|
|
|
|
},
|
2021-03-08 04:17:46 +08:00
|
|
|
|
__hmrId: 'Renderer',
|
2021-04-05 04:02:11 +08:00
|
|
|
|
});
|
2020-09-17 05:54:14 +08:00
|
|
|
|
|
|
|
|
|
function setFromProp(o, prop) {
|
|
|
|
|
if (prop instanceof Object) {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
Object.entries(prop).forEach(([key, value]) => {
|
2020-09-17 05:54:14 +08:00
|
|
|
|
o[key] = value;
|
2020-10-04 06:49:05 +08:00
|
|
|
|
});
|
2020-09-17 05:54:14 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2021-03-14 02:34:34 +08:00
|
|
|
|
function bindProps(src, props, dst) {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
props.forEach(prop => {
|
2021-03-14 02:34:34 +08:00
|
|
|
|
bindProp(src, prop, dst);
|
|
|
|
|
});
|
|
|
|
|
}
|
2021-03-08 04:17:46 +08:00
|
|
|
|
function bindProp(src, srcProp, dst, dstProp) {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
if (!dstProp) dstProp = srcProp;
|
|
|
|
|
const ref = toRef(src, srcProp);
|
2021-03-08 04:17:46 +08:00
|
|
|
|
if (ref.value instanceof Object) {
|
|
|
|
|
setFromProp(dst[dstProp], ref.value);
|
2021-04-05 04:02:11 +08:00
|
|
|
|
watch(ref, (value) => { setFromProp(dst[dstProp], value); }, { deep: true });
|
2021-03-08 04:17:46 +08:00
|
|
|
|
} else {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
if (ref.value) dst[dstProp] = src[srcProp];
|
|
|
|
|
watch(ref, (value) => { dst[dstProp] = value; });
|
2021-03-08 04:17:46 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2020-10-04 06:49:05 +08:00
|
|
|
|
function propsValues(props, exclude) {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
const values = {};
|
|
|
|
|
Object.entries(props).forEach(([key, value]) => {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
if (!exclude || (exclude && !exclude.includes(key))) {
|
|
|
|
|
values[key] = value;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
return values;
|
|
|
|
|
}
|
2020-09-17 05:54:14 +08:00
|
|
|
|
function lerp(value1, value2, amount) {
|
|
|
|
|
amount = amount < 0 ? 0 : amount;
|
|
|
|
|
amount = amount > 1 ? 1 : amount;
|
|
|
|
|
return value1 + (value2 - value1) * amount;
|
|
|
|
|
}
|
2021-02-26 05:55:44 +08:00
|
|
|
|
function lerpv2(v1, v2, amount) {
|
|
|
|
|
v1.x = lerp(v1.x, v2.x, amount);
|
|
|
|
|
v1.y = lerp(v1.y, v2.y, amount);
|
|
|
|
|
}
|
2020-09-17 05:54:14 +08:00
|
|
|
|
function lerpv3(v1, v2, amount) {
|
|
|
|
|
v1.x = lerp(v1.x, v2.x, amount);
|
|
|
|
|
v1.y = lerp(v1.y, v2.y, amount);
|
|
|
|
|
v1.z = lerp(v1.z, v2.z, amount);
|
|
|
|
|
}
|
2020-10-04 06:49:05 +08:00
|
|
|
|
function limit(val, min, max) {
|
|
|
|
|
return val < min ? min : (val > max ? max : val);
|
|
|
|
|
}
|
2021-02-26 05:55:44 +08:00
|
|
|
|
// from https://github.com/pmndrs/drei/blob/master/src/useMatcapTexture.tsx
|
2021-04-05 04:02:11 +08:00
|
|
|
|
const MATCAP_ROOT = 'https://rawcdn.githack.com/emmelleppi/matcaps/9b36ccaaf0a24881a39062d05566c9e92be4aa0d';
|
2021-02-26 05:55:44 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
function getMatcapUrl(hash, format = 1024) {
|
|
|
|
|
const fileName = `${hash}${getMatcapFormatString(format)}.png`;
|
|
|
|
|
return `${MATCAP_ROOT}/${format}/${fileName}`;
|
2021-02-26 05:55:44 +08:00
|
|
|
|
}
|
|
|
|
|
function getMatcapFormatString(format) {
|
|
|
|
|
switch (format) {
|
|
|
|
|
case 64:
|
|
|
|
|
return '-64px';
|
|
|
|
|
case 128:
|
|
|
|
|
return '-128px';
|
|
|
|
|
case 256:
|
|
|
|
|
return '-256px';
|
|
|
|
|
case 512:
|
|
|
|
|
return '-512px';
|
|
|
|
|
default:
|
|
|
|
|
return '';
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-10-04 06:49:05 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
// import Object3D from '../core/Object3D.js';
|
2021-03-14 02:34:34 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var Camera = defineComponent({
|
|
|
|
|
// TODO: eventually extend Object3D, for now: error 'injection "scene" not found'
|
|
|
|
|
// because camera is a sibling of scene in Trois
|
|
|
|
|
// extends: Object3D,
|
|
|
|
|
inject: ['three'],
|
|
|
|
|
render() {
|
|
|
|
|
return this.$slots.default ? this.$slots.default() : [];
|
|
|
|
|
},
|
|
|
|
|
});
|
2021-03-14 02:34:34 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var OrthographicCamera = defineComponent({
|
|
|
|
|
extends: Camera,
|
2021-03-08 04:17:46 +08:00
|
|
|
|
name: 'OrthographicCamera',
|
2021-02-26 05:55:44 +08:00
|
|
|
|
inject: ['three'],
|
|
|
|
|
props: {
|
|
|
|
|
left: { type: Number, default: -1 },
|
|
|
|
|
right: { type: Number, default: 1 },
|
|
|
|
|
top: { type: Number, default: 1 },
|
|
|
|
|
bottom: { type: Number, default: -1 },
|
|
|
|
|
near: { type: Number, default: 0.1 },
|
|
|
|
|
far: { type: Number, default: 2000 },
|
|
|
|
|
zoom: { type: Number, default: 1 },
|
2021-03-08 04:17:46 +08:00
|
|
|
|
position: { type: Object, default: { x: 0, y: 0, z: 0 } },
|
2021-02-26 05:55:44 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
created() {
|
2021-02-26 05:55:44 +08:00
|
|
|
|
this.camera = new OrthographicCamera$1(this.left, this.right, this.top, this.bottom, this.near, this.far);
|
2021-03-08 04:17:46 +08:00
|
|
|
|
bindProp(this, 'position', this.camera);
|
2021-02-26 05:55:44 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
['left', 'right', 'top', 'bottom', 'near', 'far', 'zoom'].forEach(p => {
|
|
|
|
|
watch(() => this[p], () => {
|
|
|
|
|
this.camera[p] = this[p];
|
|
|
|
|
this.camera.updateProjectionMatrix();
|
2021-02-26 05:55:44 +08:00
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
this.three.camera = this.camera;
|
|
|
|
|
},
|
|
|
|
|
__hmrId: 'OrthographicCamera',
|
2021-04-05 04:02:11 +08:00
|
|
|
|
});
|
2021-02-26 05:55:44 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var PerspectiveCamera = defineComponent({
|
|
|
|
|
extends: Camera,
|
2021-03-08 04:17:46 +08:00
|
|
|
|
name: 'PerspectiveCamera',
|
2020-09-17 05:54:14 +08:00
|
|
|
|
inject: ['three'],
|
|
|
|
|
props: {
|
2021-02-26 05:55:44 +08:00
|
|
|
|
aspect: { type: Number, default: 1 },
|
|
|
|
|
far: { type: Number, default: 2000 },
|
|
|
|
|
fov: { type: Number, default: 50 },
|
|
|
|
|
near: { type: Number, default: 0.1 },
|
2021-03-08 04:17:46 +08:00
|
|
|
|
position: { type: Object, default: { x: 0, y: 0, z: 0 } },
|
|
|
|
|
lookAt: { type: Object, default: null },
|
2020-09-17 05:54:14 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
created() {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
this.camera = new PerspectiveCamera$1(this.fov, this.aspect, this.near, this.far);
|
2021-03-08 04:17:46 +08:00
|
|
|
|
bindProp(this, 'position', this.camera);
|
2020-10-04 06:49:05 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
if (this.lookAt) this.camera.lookAt(this.lookAt.x, this.lookAt.y, this.lookAt.z);
|
|
|
|
|
watch(() => this.lookAt, (v) => { this.camera.lookAt(v.x, v.y, v.z); }, { deep: true });
|
2021-03-05 16:17:16 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
['aspect', 'far', 'fov', 'near'].forEach(p => {
|
|
|
|
|
watch(() => this[p], () => {
|
|
|
|
|
this.camera[p] = this[p];
|
|
|
|
|
this.camera.updateProjectionMatrix();
|
2020-10-04 06:49:05 +08:00
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
this.three.camera = this.camera;
|
2020-09-17 05:54:14 +08:00
|
|
|
|
},
|
2020-10-04 06:49:05 +08:00
|
|
|
|
__hmrId: 'PerspectiveCamera',
|
2021-04-05 04:02:11 +08:00
|
|
|
|
});
|
2020-09-17 05:54:14 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var Object3D = defineComponent({
|
2021-03-08 04:17:46 +08:00
|
|
|
|
name: 'Object3D',
|
|
|
|
|
inject: ['three', 'scene', 'rendererComponent'],
|
2021-04-05 04:02:11 +08:00
|
|
|
|
emits: ['created', 'ready'],
|
2021-02-26 05:55:44 +08:00
|
|
|
|
props: {
|
2021-03-08 04:17:46 +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 } },
|
|
|
|
|
lookAt: { type: Object, default: null },
|
2021-04-05 04:02:11 +08:00
|
|
|
|
autoRemove: { type: Boolean, default: true },
|
2021-02-26 05:55:44 +08:00
|
|
|
|
},
|
2021-03-08 04:17:46 +08:00
|
|
|
|
// can't use setup because it will not be used in sub components
|
|
|
|
|
// setup() {},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
unmounted() {
|
|
|
|
|
if (this.autoRemove) this.removeFromParent();
|
2021-02-26 05:55:44 +08:00
|
|
|
|
},
|
2021-03-08 04:17:46 +08:00
|
|
|
|
methods: {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
initObject3D(o3d) {
|
2021-03-08 04:17:46 +08:00
|
|
|
|
this.o3d = o3d;
|
2021-04-05 04:02:11 +08:00
|
|
|
|
this.$emit('created', this.o3d);
|
2021-03-04 06:23:57 +08:00
|
|
|
|
|
2021-03-08 04:17:46 +08:00
|
|
|
|
bindProp(this, 'position', this.o3d);
|
|
|
|
|
bindProp(this, 'rotation', this.o3d);
|
|
|
|
|
bindProp(this, 'scale', this.o3d);
|
|
|
|
|
|
2021-03-14 02:34:34 +08:00
|
|
|
|
// TODO : fix lookat.x
|
2021-04-05 04:02:11 +08:00
|
|
|
|
if (this.lookAt) this.o3d.lookAt(this.lookAt.x, this.lookAt.y, this.lookAt.z);
|
|
|
|
|
watch(() => this.lookAt, (v) => { this.o3d.lookAt(v.x, v.y, v.z); }, { deep: true });
|
2021-03-08 04:17:46 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
this._parent = this.getParent();
|
|
|
|
|
if (this.addToParent()) this.$emit('ready', this);
|
|
|
|
|
else console.error('Missing parent (Scene, Group...)');
|
|
|
|
|
},
|
|
|
|
|
getParent() {
|
|
|
|
|
let parent = this.$parent;
|
2021-03-14 02:34:34 +08:00
|
|
|
|
while (parent) {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
if (parent.add) return parent;
|
2021-03-14 02:34:34 +08:00
|
|
|
|
parent = parent.$parent;
|
|
|
|
|
}
|
2021-04-05 04:02:11 +08:00
|
|
|
|
return false;
|
|
|
|
|
},
|
|
|
|
|
addToParent(o) {
|
|
|
|
|
const o3d = o || this.o3d;
|
|
|
|
|
if (this._parent) {
|
|
|
|
|
this._parent.add(o3d);
|
|
|
|
|
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;
|
|
|
|
|
if (this._parent) {
|
|
|
|
|
this._parent.remove(o3d);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
},
|
|
|
|
|
add(o) { this.o3d.add(o); },
|
|
|
|
|
remove(o) { this.o3d.remove(o); },
|
2021-02-26 05:55:44 +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() : [];
|
|
|
|
|
},
|
|
|
|
|
__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 = defineComponent({
|
2021-03-08 04:17:46 +08:00
|
|
|
|
name: 'Group',
|
|
|
|
|
extends: Object3D,
|
2021-04-05 04:02:11 +08:00
|
|
|
|
created() {
|
2021-03-08 04:17:46 +08:00
|
|
|
|
this.group = new Group$1();
|
|
|
|
|
this.initObject3D(this.group);
|
2021-02-26 05:55:44 +08:00
|
|
|
|
},
|
|
|
|
|
__hmrId: 'Group',
|
2021-04-05 04:02:11 +08:00
|
|
|
|
});
|
2021-02-26 05:55:44 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var Scene = defineComponent({
|
2021-03-08 04:17:46 +08:00
|
|
|
|
name: 'Scene',
|
2020-09-17 05:54:14 +08:00
|
|
|
|
inject: ['three'],
|
|
|
|
|
props: {
|
|
|
|
|
id: String,
|
|
|
|
|
background: [String, Number],
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
setup(props) {
|
|
|
|
|
const scene = new Scene$1();
|
|
|
|
|
if (props.background) scene.background = new Color(props.background);
|
|
|
|
|
watch(() => props.background, (value) => { scene.background.set(value); });
|
|
|
|
|
return { scene };
|
2020-09-17 05:54:14 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
provide() {
|
2020-09-17 05:54:14 +08:00
|
|
|
|
return {
|
|
|
|
|
scene: this.scene,
|
|
|
|
|
};
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
mounted() {
|
2020-09-17 05:54:14 +08:00
|
|
|
|
if (!this.three.scene) {
|
|
|
|
|
this.three.scene = this.scene;
|
|
|
|
|
}
|
|
|
|
|
},
|
2020-10-04 06:49:05 +08:00
|
|
|
|
methods: {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
add(o) { this.scene.add(o); },
|
|
|
|
|
remove(o) { this.scene.remove(o); },
|
2020-10-04 06:49:05 +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() : [];
|
2020-09-17 05:54:14 +08:00
|
|
|
|
},
|
2021-03-08 04:17:46 +08:00
|
|
|
|
__hmrId: 'Scene',
|
2021-04-05 04:02:11 +08:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
var Raycaster = defineComponent({
|
|
|
|
|
name: 'Raycaster',
|
|
|
|
|
inject: ['three', 'rendererComponent'],
|
|
|
|
|
props: {
|
|
|
|
|
onPointerEnter: { type: Function, default: () => {} },
|
|
|
|
|
onPointerOver: { type: Function, default: () => {} },
|
|
|
|
|
onPointerMove: { type: Function, default: () => {} },
|
|
|
|
|
onPointerLeave: { type: Function, default: () => {} },
|
|
|
|
|
onClick: { type: Function, default: () => {} },
|
|
|
|
|
intersectMode: { type: String, default: 'move' },
|
|
|
|
|
},
|
|
|
|
|
mounted() {
|
|
|
|
|
this.rendererComponent.onMounted(() => {
|
|
|
|
|
this.pointer = usePointer({
|
|
|
|
|
camera: this.three.camera,
|
|
|
|
|
domElement: this.three.renderer.domElement,
|
|
|
|
|
intersectObjects: this.getIntersectObjects(),
|
|
|
|
|
onIntersectEnter: this.onPointerEnter,
|
|
|
|
|
onIntersectOver: this.onPointerOver,
|
|
|
|
|
onIntersectMove: this.onPointerMove,
|
|
|
|
|
onIntersectLeave: this.onPointerLeave,
|
|
|
|
|
onIntersectClick: this.onClick,
|
|
|
|
|
});
|
|
|
|
|
this.pointer.addListeners();
|
|
|
|
|
|
|
|
|
|
if (this.intersectMode === 'frame') {
|
|
|
|
|
this.three.onBeforeRender(this.pointer.intersect);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
unmounted() {
|
|
|
|
|
if (this.pointer) {
|
|
|
|
|
this.pointer.removeListeners();
|
|
|
|
|
this.three.offBeforeRender(this.pointer.intersect);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
|
|
|
|
getIntersectObjects() {
|
|
|
|
|
return this.three.scene.children.filter(e => e.type === 'Mesh');
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
render() {
|
|
|
|
|
return [];
|
|
|
|
|
},
|
|
|
|
|
__hmrId: 'Raycaster',
|
|
|
|
|
});
|
2020-09-17 05:54:14 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
const Geometry = defineComponent({
|
2020-10-04 06:49:05 +08:00
|
|
|
|
inject: ['mesh'],
|
|
|
|
|
props: {
|
|
|
|
|
rotateX: Number,
|
|
|
|
|
rotateY: Number,
|
|
|
|
|
rotateZ: Number,
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
created() {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
if (!this.mesh) {
|
2020-09-17 05:54:14 +08:00
|
|
|
|
console.error('Missing parent Mesh');
|
|
|
|
|
}
|
2021-03-08 04:17:46 +08:00
|
|
|
|
|
2020-10-04 06:49:05 +08:00
|
|
|
|
this.watchProps = [];
|
2021-04-05 04:02:11 +08:00
|
|
|
|
Object.entries(this.$props).forEach(e => this.watchProps.push(e[0]));
|
2021-03-08 04:17:46 +08:00
|
|
|
|
|
2020-10-04 06:49:05 +08:00
|
|
|
|
this.createGeometry();
|
|
|
|
|
this.rotateGeometry();
|
|
|
|
|
this.mesh.setGeometry(this.geometry);
|
2021-03-08 04:17:46 +08:00
|
|
|
|
|
2020-10-04 06:49:05 +08:00
|
|
|
|
this.addWatchers();
|
2020-09-17 05:54:14 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
unmounted() {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
this.geometry.dispose();
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
addWatchers() {
|
|
|
|
|
this.watchProps.forEach(prop => {
|
|
|
|
|
watch(() => this[prop], () => {
|
|
|
|
|
this.refreshGeometry();
|
2020-10-04 06:49:05 +08:00
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
rotateGeometry() {
|
|
|
|
|
if (this.rotateX) this.geometry.rotateX(this.rotateX);
|
|
|
|
|
if (this.rotateY) this.geometry.rotateY(this.rotateY);
|
|
|
|
|
if (this.rotateZ) this.geometry.rotateZ(this.rotateZ);
|
2021-03-08 04:17:46 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
refreshGeometry() {
|
|
|
|
|
const oldGeo = this.geometry;
|
2020-10-04 06:49:05 +08:00
|
|
|
|
this.createGeometry();
|
|
|
|
|
this.rotateGeometry();
|
|
|
|
|
this.mesh.setGeometry(this.geometry);
|
|
|
|
|
oldGeo.dispose();
|
|
|
|
|
},
|
2020-09-17 05:54:14 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
render() { return []; },
|
|
|
|
|
});
|
2020-09-17 05:54:14 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
function geometryComponent(name, props, createGeometry) {
|
|
|
|
|
return defineComponent({
|
|
|
|
|
name,
|
|
|
|
|
extends: Geometry,
|
|
|
|
|
props,
|
|
|
|
|
methods: {
|
|
|
|
|
createGeometry() {
|
|
|
|
|
this.geometry = createGeometry(this);
|
|
|
|
|
},
|
2020-09-17 05:54:14 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const props$h = {
|
|
|
|
|
size: Number,
|
|
|
|
|
width: { type: Number, default: 1 },
|
|
|
|
|
height: { type: Number, default: 1 },
|
|
|
|
|
depth: { type: Number, default: 1 },
|
|
|
|
|
widthSegments: { type: Number, default: 1 },
|
|
|
|
|
heightSegments: { type: Number, default: 1 },
|
|
|
|
|
depthSegments: { type: Number, default: 1 },
|
2020-10-04 06:49:05 +08:00
|
|
|
|
};
|
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
function createGeometry$f(comp) {
|
|
|
|
|
if (comp.size) {
|
|
|
|
|
return new BoxGeometry$1(comp.size, comp.size, comp.size, comp.widthSegments, comp.heightSegments, comp.depthSegments);
|
|
|
|
|
} else {
|
|
|
|
|
return new BoxGeometry$1(comp.width, comp.height, comp.depth, comp.widthSegments, comp.heightSegments, comp.depthSegments);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
var BoxGeometry = geometryComponent('BoxGeometry', props$h, createGeometry$f);
|
|
|
|
|
|
|
|
|
|
const props$g = {
|
|
|
|
|
radius: { type: Number, default: 1 },
|
|
|
|
|
segments: { type: Number, default: 8 },
|
|
|
|
|
thetaStart: { type: Number, default: 0 },
|
|
|
|
|
thetaLength: { type: Number, default: Math.PI * 2 },
|
2020-10-04 06:49:05 +08:00
|
|
|
|
};
|
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
function createGeometry$e(comp) {
|
|
|
|
|
return new CircleGeometry$1(comp.radius, comp.segments, comp.thetaStart, comp.thetaLength);
|
|
|
|
|
}
|
|
|
|
|
var CircleGeometry = geometryComponent('CircleGeometry', props$g, createGeometry$e);
|
|
|
|
|
|
|
|
|
|
const props$f = {
|
|
|
|
|
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 },
|
2020-10-04 06:49:05 +08:00
|
|
|
|
};
|
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
function createGeometry$d(comp) {
|
|
|
|
|
return new ConeGeometry$1(comp.radius, comp.height, comp.radialSegments, comp.heightSegments, comp.openEnded, comp.thetaStart, comp.thetaLength);
|
|
|
|
|
}
|
|
|
|
|
var ConeGeometry = geometryComponent('ConeGeometry', props$f, createGeometry$d);
|
|
|
|
|
|
|
|
|
|
const props$e = {
|
|
|
|
|
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 },
|
2020-10-04 06:49:05 +08:00
|
|
|
|
};
|
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
function createGeometry$c(comp) {
|
|
|
|
|
return new CylinderGeometry$1(comp.radiusTop, comp.radiusBottom, comp.height, comp.radialSegments, comp.heightSegments, comp.openEnded, comp.thetaStart, comp.thetaLength);
|
|
|
|
|
}
|
|
|
|
|
var CylinderGeometry = geometryComponent('CylinderGeometry', props$e, createGeometry$c);
|
|
|
|
|
|
|
|
|
|
const props$d = {
|
|
|
|
|
radius: { type: Number, default: 1 },
|
|
|
|
|
detail: { type: Number, default: 0 },
|
2020-10-04 06:49:05 +08:00
|
|
|
|
};
|
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
function createGeometry$b(comp) {
|
|
|
|
|
return new DodecahedronGeometry$1(comp.radius, comp.detail);
|
|
|
|
|
}
|
|
|
|
|
var DodecahedronGeometry = geometryComponent('DodecahedronGeometry', props$d, createGeometry$b);
|
|
|
|
|
|
|
|
|
|
const props$c = {
|
|
|
|
|
radius: { type: Number, default: 1 },
|
|
|
|
|
detail: { type: Number, default: 0 },
|
2020-10-04 06:49:05 +08:00
|
|
|
|
};
|
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
function createGeometry$a(comp) {
|
|
|
|
|
return new IcosahedronGeometry$1(comp.radius, comp.detail);
|
|
|
|
|
}
|
|
|
|
|
var IcosahedronGeometry = geometryComponent('IcosahedronGeometry', props$c, createGeometry$a);
|
|
|
|
|
|
|
|
|
|
const props$b = {
|
|
|
|
|
points: Array,
|
|
|
|
|
segments: { type: Number, default: 12 },
|
|
|
|
|
phiStart: { type: Number, default: 0 },
|
|
|
|
|
phiLength: { type: Number, default: Math.PI * 2 },
|
2020-10-04 06:49:05 +08:00
|
|
|
|
};
|
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
function createGeometry$9(comp) {
|
|
|
|
|
return new LatheGeometry$1(comp.points, comp.segments, comp.phiStart, comp.phiLength);
|
|
|
|
|
}
|
|
|
|
|
var LatheGeometry = geometryComponent('LatheGeometry', props$b, createGeometry$9);
|
|
|
|
|
|
|
|
|
|
const props$a = {
|
|
|
|
|
radius: { type: Number, default: 1 },
|
|
|
|
|
detail: { type: Number, default: 0 },
|
2020-10-04 06:49:05 +08:00
|
|
|
|
};
|
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
function createGeometry$8(comp) {
|
|
|
|
|
return new OctahedronGeometry$1(comp.radius, comp.detail);
|
|
|
|
|
}
|
|
|
|
|
var OctahedronGeometry = geometryComponent('OctahedronGeometry', props$a, createGeometry$8);
|
|
|
|
|
|
|
|
|
|
const props$9 = {
|
|
|
|
|
vertices: Array,
|
|
|
|
|
indices: Array,
|
|
|
|
|
radius: { type: Number, default: 1 },
|
|
|
|
|
detail: { type: Number, default: 0 },
|
2020-10-04 06:49:05 +08:00
|
|
|
|
};
|
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
function createGeometry$7(comp) {
|
|
|
|
|
return new PolyhedronGeometry$1(comp.vertices, comp.indices, comp.radius, comp.detail);
|
|
|
|
|
}
|
|
|
|
|
var PolyhedronGeometry = geometryComponent('PolyhedronGeometry', props$9, createGeometry$7);
|
|
|
|
|
|
|
|
|
|
const props$8 = {
|
|
|
|
|
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 },
|
2020-09-17 05:54:14 +08:00
|
|
|
|
};
|
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
function createGeometry$6(comp) {
|
|
|
|
|
return new RingGeometry$1(comp.innerRadius, comp.outerRadius, comp.thetaSegments, comp.phiSegments, comp.thetaStart, comp.thetaLength);
|
|
|
|
|
}
|
|
|
|
|
var RingGeometry = geometryComponent('RingGeometry', props$8, createGeometry$6);
|
|
|
|
|
|
|
|
|
|
const props$7 = {
|
|
|
|
|
radius: { type: Number, default: 1 },
|
|
|
|
|
widthSegments: { type: Number, default: 12 },
|
|
|
|
|
heightSegments: { type: Number, default: 12 },
|
2020-10-04 06:49:05 +08:00
|
|
|
|
};
|
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
function createGeometry$5(comp) {
|
|
|
|
|
return new SphereGeometry$1(comp.radius, comp.widthSegments, comp.heightSegments);
|
|
|
|
|
}
|
|
|
|
|
var SphereGeometry = geometryComponent('SphereGeometry', props$7, createGeometry$5);
|
|
|
|
|
|
|
|
|
|
const props$6 = {
|
|
|
|
|
radius: { type: Number, default: 1 },
|
|
|
|
|
detail: { type: Number, default: 0 },
|
2020-10-04 06:49:05 +08:00
|
|
|
|
};
|
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
function createGeometry$4(comp) {
|
|
|
|
|
return new TetrahedronGeometry$1(comp.radius, comp.detail);
|
|
|
|
|
}
|
|
|
|
|
var TetrahedronGeometry = geometryComponent('TetrahedronGeometry', props$6, createGeometry$4);
|
|
|
|
|
|
|
|
|
|
const props$5 = {
|
|
|
|
|
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 },
|
2020-10-04 06:49:05 +08:00
|
|
|
|
};
|
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
function createGeometry$3(comp) {
|
|
|
|
|
return new TorusGeometry$1(comp.radius, comp.tube, comp.radialSegments, comp.tubularSegments, comp.arc);
|
|
|
|
|
}
|
|
|
|
|
var TorusGeometry = geometryComponent('TorusGeometry', props$5, createGeometry$3);
|
|
|
|
|
|
|
|
|
|
const props$4 = {
|
|
|
|
|
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 },
|
2020-10-04 06:49:05 +08:00
|
|
|
|
};
|
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
function createGeometry$2(comp) {
|
|
|
|
|
return new TorusKnotGeometry$1(comp.radius, comp.tube, comp.tubularSegments, comp.radialSegments, comp.p, comp.q);
|
|
|
|
|
}
|
|
|
|
|
var TorusKnotGeometry = geometryComponent('TorusKnotGeometry', props$4, createGeometry$2);
|
|
|
|
|
|
|
|
|
|
const props$3 = {
|
|
|
|
|
points: Array,
|
|
|
|
|
path: Curve,
|
|
|
|
|
tubularSegments: { type: Number, default: 64 },
|
|
|
|
|
radius: { type: Number, default: 1 },
|
|
|
|
|
radialSegments: { type: Number, default: 8 },
|
|
|
|
|
closed: { type: Boolean, default: false },
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
function createGeometry$1(comp) {
|
|
|
|
|
let curve;
|
|
|
|
|
if (comp.points) {
|
|
|
|
|
curve = new CatmullRomCurve3(comp.points);
|
|
|
|
|
} else if (comp.path) {
|
|
|
|
|
curve = comp.path;
|
|
|
|
|
} else {
|
|
|
|
|
console.error('Missing path curve or points.');
|
|
|
|
|
}
|
|
|
|
|
return new TubeGeometry$1(curve, comp.tubularSegments, comp.radius, comp.radiusSegments, comp.closed);
|
|
|
|
|
}
|
|
|
|
|
var TubeGeometry = defineComponent({
|
2020-10-04 06:49:05 +08:00
|
|
|
|
extends: Geometry,
|
2021-04-05 04:02:11 +08:00
|
|
|
|
props: props$3,
|
2020-10-04 06:49:05 +08:00
|
|
|
|
methods: {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
createGeometry() {
|
|
|
|
|
this.geometry = createGeometry$1(this);
|
|
|
|
|
},
|
|
|
|
|
// update points (without using prop, faster)
|
|
|
|
|
updatePoints(points) {
|
|
|
|
|
updateTubeGeometryPoints(this.geometry, points);
|
2020-10-04 06:49:05 +08:00
|
|
|
|
},
|
2020-09-17 05:54:14 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
});
|
2020-09-17 05:54:14 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
function updateTubeGeometryPoints(tube, points) {
|
|
|
|
|
const curve = new CatmullRomCurve3(points);
|
|
|
|
|
const { radialSegments, radius, tubularSegments, closed } = tube.parameters;
|
|
|
|
|
const frames = curve.computeFrenetFrames(tubularSegments, closed);
|
|
|
|
|
tube.tangents = frames.tangents;
|
|
|
|
|
tube.normals = frames.normals;
|
|
|
|
|
tube.binormals = frames.binormals;
|
|
|
|
|
tube.parameters.path = curve;
|
|
|
|
|
|
|
|
|
|
const pArray = tube.attributes.position.array;
|
|
|
|
|
const nArray = tube.attributes.normal.array;
|
|
|
|
|
const normal = new Vector3();
|
|
|
|
|
let P;
|
|
|
|
|
|
|
|
|
|
for (let i = 0; i < tubularSegments; i++) {
|
|
|
|
|
updateSegment(i);
|
|
|
|
|
}
|
|
|
|
|
updateSegment(tubularSegments);
|
|
|
|
|
|
|
|
|
|
tube.attributes.position.needsUpdate = true;
|
|
|
|
|
tube.attributes.normal.needsUpdate = true;
|
|
|
|
|
|
|
|
|
|
function updateSegment(i) {
|
|
|
|
|
P = curve.getPointAt(i / tubularSegments, P);
|
|
|
|
|
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);
|
|
|
|
|
normal.x = (cos * N.x + sin * B.x);
|
|
|
|
|
normal.y = (cos * N.y + sin * B.y);
|
|
|
|
|
normal.z = (cos * N.z + sin * B.z);
|
|
|
|
|
normal.normalize();
|
|
|
|
|
const index = (i * (radialSegments + 1) + j) * 3;
|
|
|
|
|
nArray[index] = normal.x;
|
|
|
|
|
nArray[index + 1] = normal.y;
|
|
|
|
|
nArray[index + 2] = normal.z;
|
|
|
|
|
pArray[index] = P.x + radius * normal.x;
|
|
|
|
|
pArray[index + 1] = P.y + radius * normal.y;
|
|
|
|
|
pArray[index + 2] = P.z + radius * normal.z;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var Light = defineComponent({
|
2021-03-08 04:17:46 +08:00
|
|
|
|
extends: Object3D,
|
|
|
|
|
name: 'Light',
|
2020-09-17 05:54:14 +08:00
|
|
|
|
props: {
|
2021-03-08 04:17:46 +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 } },
|
2021-03-14 02:34:34 +08:00
|
|
|
|
shadowCamera: { type: Object, default: {} },
|
2020-09-17 05:54:14 +08:00
|
|
|
|
},
|
2021-02-26 05:55:44 +08:00
|
|
|
|
// can't use setup because it will not be used in sub components
|
|
|
|
|
// setup() {},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
unmounted() {
|
|
|
|
|
if (this.light.target) this.removeFromParent(this.light.target);
|
2021-03-04 05:59:51 +08:00
|
|
|
|
},
|
2021-03-08 04:17:46 +08:00
|
|
|
|
methods: {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
initLight() {
|
2021-03-08 04:17:46 +08:00
|
|
|
|
if (this.light.target) {
|
|
|
|
|
bindProp(this, 'target', this.light.target, 'position');
|
|
|
|
|
}
|
2020-09-17 05:54:14 +08:00
|
|
|
|
|
2021-03-08 04:17:46 +08:00
|
|
|
|
if (this.light.shadow) {
|
|
|
|
|
this.light.castShadow = this.castShadow;
|
|
|
|
|
setFromProp(this.light.shadow.mapSize, this.shadowMapSize);
|
2021-03-14 02:34:34 +08:00
|
|
|
|
setFromProp(this.light.shadow.camera, this.shadowCamera);
|
2021-03-08 04:17:46 +08:00
|
|
|
|
}
|
2020-09-17 05:54:14 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
['color', 'intensity', 'castShadow'].forEach(p => {
|
|
|
|
|
watch(() => this[p], () => {
|
2021-03-08 04:17:46 +08:00
|
|
|
|
if (p === 'color') {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
this.light.color.set(this.color);
|
2021-03-08 04:17:46 +08:00
|
|
|
|
} else {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
this.light[p] = this[p];
|
2021-03-08 04:17:46 +08:00
|
|
|
|
}
|
|
|
|
|
});
|
2020-10-04 06:49:05 +08:00
|
|
|
|
});
|
|
|
|
|
|
2021-03-08 04:17:46 +08:00
|
|
|
|
this.initObject3D(this.light);
|
2021-04-05 04:02:11 +08:00
|
|
|
|
if (this.light.target) this.addToParent(this.light.target);
|
2021-03-08 04:17:46 +08:00
|
|
|
|
},
|
2020-09-17 05:54:14 +08:00
|
|
|
|
},
|
2020-10-04 06:49:05 +08:00
|
|
|
|
__hmrId: 'Light',
|
2021-04-05 04:02:11 +08:00
|
|
|
|
});
|
2020-09-17 05:54:14 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var AmbientLight = defineComponent({
|
2020-09-17 05:54:14 +08:00
|
|
|
|
extends: Light,
|
2021-04-05 04:02:11 +08:00
|
|
|
|
created() {
|
2020-09-17 05:54:14 +08:00
|
|
|
|
this.light = new AmbientLight$1(this.color, this.intensity);
|
2021-03-08 04:17:46 +08:00
|
|
|
|
this.initLight();
|
2020-09-17 05:54:14 +08:00
|
|
|
|
},
|
2020-10-04 06:49:05 +08:00
|
|
|
|
__hmrId: 'AmbientLight',
|
2021-04-05 04:02:11 +08:00
|
|
|
|
});
|
2020-10-04 06:49:05 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var DirectionalLight = defineComponent({
|
2020-10-04 06:49:05 +08:00
|
|
|
|
extends: Light,
|
|
|
|
|
props: {
|
|
|
|
|
target: Object,
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
created() {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
this.light = new DirectionalLight$1(this.color, this.intensity);
|
2021-03-08 04:17:46 +08:00
|
|
|
|
this.initLight();
|
2020-10-04 06:49:05 +08:00
|
|
|
|
},
|
|
|
|
|
__hmrId: 'DirectionalLight',
|
2021-04-05 04:02:11 +08:00
|
|
|
|
});
|
2020-09-17 05:54:14 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var HemisphereLight = defineComponent({
|
2021-03-08 04:17:46 +08:00
|
|
|
|
extends: Light,
|
|
|
|
|
props: {
|
2021-03-14 02:34:34 +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-03-08 04:17:46 +08:00
|
|
|
|
this.light = new HemisphereLight$1(this.color, this.groundColor, this.intensity);
|
2021-04-05 04:02:11 +08:00
|
|
|
|
watch(() => this.groundColor, (value) => { this.light.groundColor.set(value); });
|
2021-03-08 04:17:46 +08:00
|
|
|
|
this.initLight();
|
|
|
|
|
},
|
|
|
|
|
__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 = defineComponent({
|
2020-09-17 05:54:14 +08:00
|
|
|
|
extends: Light,
|
|
|
|
|
props: {
|
|
|
|
|
distance: {
|
|
|
|
|
type: Number,
|
|
|
|
|
default: 0,
|
|
|
|
|
},
|
|
|
|
|
decay: {
|
|
|
|
|
type: Number,
|
|
|
|
|
default: 1,
|
|
|
|
|
},
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
created() {
|
2020-09-17 05:54:14 +08:00
|
|
|
|
this.light = new PointLight$1(this.color, this.intensity, this.distance, this.decay);
|
2021-03-08 04:17:46 +08:00
|
|
|
|
this.initLight();
|
2020-09-17 05:54:14 +08:00
|
|
|
|
},
|
2020-10-04 06:49:05 +08:00
|
|
|
|
__hmrId: 'PointLight',
|
2021-04-05 04:02:11 +08:00
|
|
|
|
});
|
2020-09-17 05:54:14 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var RectAreaLight = defineComponent({
|
2021-03-08 04:17:46 +08:00
|
|
|
|
extends: Light,
|
|
|
|
|
props: {
|
|
|
|
|
width: { type: Number, default: 10 },
|
|
|
|
|
height: { type: Number, default: 10 },
|
|
|
|
|
helper: Boolean,
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
created() {
|
2021-03-08 04:17:46 +08:00
|
|
|
|
RectAreaLightUniformsLib.init();
|
|
|
|
|
this.light = new RectAreaLight$1(this.color, this.intensity, this.width, this.height);
|
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
['width', 'height'].forEach(p => {
|
|
|
|
|
watch(() => this[p], () => {
|
|
|
|
|
this.light[p] = this[p];
|
2021-03-08 04:17:46 +08:00
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (this.helper) {
|
|
|
|
|
this.lightHelper = new RectAreaLightHelper(this.light);
|
2021-04-05 04:02:11 +08:00
|
|
|
|
this.light.add(this.lightHelper);
|
2021-03-08 04:17:46 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.initLight();
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
unmounted() {
|
|
|
|
|
if (this.lightHelper) this.removeFromParent(this.lightHelper);
|
2021-03-08 04:17:46 +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 = defineComponent({
|
2020-09-17 05:54:14 +08:00
|
|
|
|
extends: Light,
|
|
|
|
|
props: {
|
2021-03-08 04:17:46 +08:00
|
|
|
|
angle: { type: Number, default: Math.PI / 3 },
|
|
|
|
|
decay: { type: Number, default: 1 },
|
|
|
|
|
distance: { type: Number, default: 0 },
|
|
|
|
|
penumbra: { type: Number, default: 0 },
|
2020-10-04 06:49:05 +08:00
|
|
|
|
target: Object,
|
2020-09-17 05:54:14 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
created() {
|
2020-09-17 05:54:14 +08:00
|
|
|
|
this.light = new SpotLight$1(this.color, this.intensity, this.distance, this.angle, this.penumbra, this.decay);
|
2021-04-05 04:02:11 +08:00
|
|
|
|
['angle', 'decay', 'distance', 'penumbra'].forEach(p => {
|
|
|
|
|
watch(() => this[p], () => {
|
|
|
|
|
this.light[p] = this[p];
|
2020-10-04 06:49:05 +08:00
|
|
|
|
});
|
|
|
|
|
});
|
2021-03-08 04:17:46 +08:00
|
|
|
|
this.initLight();
|
2020-09-17 05:54:14 +08:00
|
|
|
|
},
|
2020-10-04 06:49:05 +08:00
|
|
|
|
__hmrId: 'SpotLight',
|
2021-04-05 04:02:11 +08:00
|
|
|
|
});
|
2020-09-17 05:54:14 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var Material = defineComponent({
|
2020-10-04 06:49:05 +08:00
|
|
|
|
inject: ['three', 'mesh'],
|
2020-09-17 05:54:14 +08:00
|
|
|
|
props: {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
color: { type: [String, Number], default: '#ffffff' },
|
|
|
|
|
depthTest: { type: Boolean, default: true },
|
|
|
|
|
depthWrite: { type: Boolean, default: true },
|
|
|
|
|
fog: { type: Boolean, default: true },
|
|
|
|
|
opacity: { type: Number, default: 1 },
|
|
|
|
|
side: { type: Number, default: FrontSide },
|
|
|
|
|
transparent: Boolean,
|
|
|
|
|
vertexColors: Boolean,
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
provide() {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
return {
|
|
|
|
|
material: this,
|
|
|
|
|
};
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
created() {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
this.createMaterial();
|
|
|
|
|
this.mesh.setMaterial(this.material);
|
2021-03-08 04:17:46 +08:00
|
|
|
|
|
2020-10-04 06:49:05 +08:00
|
|
|
|
this._addWatchers();
|
2021-04-05 04:02:11 +08:00
|
|
|
|
if (this.addWatchers) this.addWatchers();
|
2020-09-17 05:54:14 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
unmounted() {
|
2020-09-17 05:54:14 +08:00
|
|
|
|
this.material.dispose();
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
setProp(key, value, needsUpdate = false) {
|
2021-02-26 05:55:44 +08:00
|
|
|
|
this.material[key] = value;
|
|
|
|
|
this.material.needsUpdate = needsUpdate;
|
2020-10-04 06:49:05 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
setTexture(texture, key = 'map') {
|
2021-02-26 05:55:44 +08:00
|
|
|
|
this.setProp(key, texture, true);
|
2020-10-04 06:49:05 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
_addWatchers() {
|
|
|
|
|
['color', 'depthTest', 'depthWrite', 'fog', 'opacity', 'side', 'transparent'].forEach(p => {
|
|
|
|
|
watch(() => this[p], () => {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
if (p === 'color') {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
this.material.color.set(this.color);
|
2020-10-04 06:49:05 +08:00
|
|
|
|
} else {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
this.material[p] = this[p];
|
2020-10-04 06:49:05 +08:00
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
});
|
2020-09-17 05:54:14 +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() : [];
|
2020-09-17 05:54:14 +08:00
|
|
|
|
},
|
2020-10-04 06:49:05 +08:00
|
|
|
|
__hmrId: 'Material',
|
2021-04-05 04:02:11 +08:00
|
|
|
|
});
|
2020-09-17 05:54:14 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
const wireframeProps = {
|
2021-03-14 02:34:34 +08:00
|
|
|
|
wireframe: { type: Boolean, default: false },
|
|
|
|
|
// not needed for WebGL
|
|
|
|
|
// wireframeLinecap: { type: String, default: 'round' },
|
|
|
|
|
// wireframeLinejoin: { type: String, default: 'round' },
|
|
|
|
|
wireframeLinewidth: { type: Number, default: 1 }, // not really useful
|
|
|
|
|
};
|
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var BasicMaterial = defineComponent({
|
2020-09-17 05:54:14 +08:00
|
|
|
|
extends: Material,
|
2021-04-05 04:02:11 +08:00
|
|
|
|
props: {
|
|
|
|
|
...wireframeProps,
|
|
|
|
|
},
|
2020-10-04 06:49:05 +08:00
|
|
|
|
methods: {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
createMaterial() {
|
2021-03-08 04:17:46 +08:00
|
|
|
|
this.material = new MeshBasicMaterial(propsValues(this.$props));
|
2020-10-04 06:49:05 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
addWatchers() {
|
2021-03-14 02:34:34 +08:00
|
|
|
|
bindProps(this, Object.keys(wireframeProps), this.material);
|
|
|
|
|
},
|
2020-09-17 05:54:14 +08:00
|
|
|
|
},
|
2020-10-04 06:49:05 +08:00
|
|
|
|
__hmrId: 'BasicMaterial',
|
2021-04-05 04:02:11 +08:00
|
|
|
|
});
|
2020-09-17 05:54:14 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var LambertMaterial = defineComponent({
|
2020-09-17 05:54:14 +08:00
|
|
|
|
extends: Material,
|
2021-04-05 04:02:11 +08:00
|
|
|
|
props: {
|
|
|
|
|
...wireframeProps,
|
|
|
|
|
},
|
2020-10-04 06:49:05 +08:00
|
|
|
|
methods: {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
createMaterial() {
|
2021-03-08 04:17:46 +08:00
|
|
|
|
this.material = new MeshLambertMaterial(propsValues(this.$props));
|
2020-10-04 06:49:05 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
addWatchers() {
|
2021-03-14 02:34:34 +08:00
|
|
|
|
bindProps(this, Object.keys(wireframeProps), this.material);
|
|
|
|
|
},
|
2020-09-17 05:54:14 +08:00
|
|
|
|
},
|
2020-10-04 06:49:05 +08:00
|
|
|
|
__hmrId: 'LambertMaterial',
|
2021-04-05 04:02:11 +08:00
|
|
|
|
});
|
2020-09-17 05:54:14 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var MatcapMaterial = defineComponent({
|
2020-09-17 05:54:14 +08:00
|
|
|
|
extends: Material,
|
2021-02-26 05:55:44 +08:00
|
|
|
|
props: {
|
|
|
|
|
src: String,
|
|
|
|
|
name: String,
|
2021-03-14 02:34:34 +08:00
|
|
|
|
flatShading: Boolean,
|
2021-02-26 05:55:44 +08:00
|
|
|
|
},
|
2020-10-04 06:49:05 +08:00
|
|
|
|
methods: {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
createMaterial() {
|
|
|
|
|
const src = this.name ? getMatcapUrl(this.name) : this.src;
|
|
|
|
|
const opts = propsValues(this.$props, ['src', 'name']);
|
2021-02-26 05:55:44 +08:00
|
|
|
|
opts.matcap = new TextureLoader().load(src);
|
|
|
|
|
this.material = new MeshMatcapMaterial(opts);
|
2020-10-04 06:49:05 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
addWatchers() {
|
2021-03-14 02:34:34 +08:00
|
|
|
|
// TODO
|
|
|
|
|
},
|
2020-09-17 05:54:14 +08:00
|
|
|
|
},
|
2021-02-26 05:55:44 +08:00
|
|
|
|
__hmrId: 'MatcapMaterial',
|
2021-04-05 04:02:11 +08:00
|
|
|
|
});
|
2020-09-17 05:54:14 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var PhongMaterial = defineComponent({
|
2020-09-17 05:54:14 +08:00
|
|
|
|
extends: Material,
|
2021-04-05 04:02:11 +08:00
|
|
|
|
props: {
|
|
|
|
|
emissive: { type: [Number, String], default: 0 },
|
2020-10-04 06:49:05 +08:00
|
|
|
|
emissiveIntensity: { type: Number, default: 1 },
|
2021-02-26 05:55:44 +08:00
|
|
|
|
reflectivity: { type: Number, default: 1 },
|
|
|
|
|
shininess: { type: Number, default: 30 },
|
|
|
|
|
specular: { type: [String, Number], default: 0x111111 },
|
2021-04-05 04:02:11 +08:00
|
|
|
|
flatShading: Boolean,
|
|
|
|
|
...wireframeProps,
|
|
|
|
|
},
|
2021-02-26 05:55:44 +08:00
|
|
|
|
methods: {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
createMaterial() {
|
2021-03-08 04:17:46 +08:00
|
|
|
|
this.material = new MeshPhongMaterial(propsValues(this.$props));
|
2021-02-26 05:55:44 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
addWatchers() {
|
2021-03-14 02:34:34 +08:00
|
|
|
|
// TODO : handle flatShading ?
|
2021-04-05 04:02:11 +08:00
|
|
|
|
['emissive', 'emissiveIntensity', 'reflectivity', 'shininess', 'specular'].forEach(p => {
|
|
|
|
|
watch(() => this[p], (value) => {
|
2021-02-26 05:55:44 +08:00
|
|
|
|
if (p === 'emissive' || p === 'specular') {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
this.material[p].set(value);
|
2021-02-26 05:55:44 +08:00
|
|
|
|
} else {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
this.material[p] = value;
|
2021-02-26 05:55:44 +08:00
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
});
|
2021-03-14 02:34:34 +08:00
|
|
|
|
bindProps(this, Object.keys(wireframeProps), this.material);
|
2021-02-26 05:55:44 +08:00
|
|
|
|
},
|
2020-10-04 06:49:05 +08:00
|
|
|
|
},
|
2021-02-26 05:55:44 +08:00
|
|
|
|
__hmrId: 'PhongMaterial',
|
2021-04-05 04:02:11 +08:00
|
|
|
|
});
|
2021-02-26 05:55:44 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
const props$2 = {
|
2021-02-26 05:55:44 +08:00
|
|
|
|
aoMapIntensity: { type: Number, default: 1 },
|
|
|
|
|
bumpScale: { type: Number, default: 1 },
|
|
|
|
|
displacementBias: { type: Number, default: 0 },
|
|
|
|
|
displacementScale: { type: Number, default: 1 },
|
|
|
|
|
emissive: { type: [Number, String], default: 0 },
|
|
|
|
|
emissiveIntensity: { type: Number, default: 1 },
|
|
|
|
|
envMapIntensity: { type: Number, default: 1 },
|
|
|
|
|
lightMapIntensity: { type: Number, default: 1 },
|
|
|
|
|
metalness: { type: Number, default: 0 },
|
2021-03-08 04:17:46 +08:00
|
|
|
|
normalScale: { type: Object, default: { x: 1, y: 1 } },
|
2021-02-26 05:55:44 +08:00
|
|
|
|
roughness: { type: Number, default: 1 },
|
|
|
|
|
refractionRatio: { type: Number, default: 0.98 },
|
2021-03-14 02:34:34 +08:00
|
|
|
|
flatShading: Boolean,
|
2021-02-26 05:55:44 +08:00
|
|
|
|
};
|
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var StandardMaterial = defineComponent({
|
2021-02-26 05:55:44 +08:00
|
|
|
|
extends: Material,
|
2021-04-05 04:02:11 +08:00
|
|
|
|
props: {
|
|
|
|
|
...props$2,
|
|
|
|
|
...wireframeProps,
|
|
|
|
|
},
|
2020-10-04 06:49:05 +08:00
|
|
|
|
methods: {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
createMaterial() {
|
2021-03-08 04:17:46 +08:00
|
|
|
|
this.material = new MeshStandardMaterial(propsValues(this.$props, ['normalScale']));
|
2020-09-17 05:54:14 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
addWatchers() {
|
2021-03-14 02:34:34 +08:00
|
|
|
|
// TODO : use setProp, handle flatShading ?
|
2021-04-05 04:02:11 +08:00
|
|
|
|
Object.keys(props$2).forEach(p => {
|
|
|
|
|
if (p === 'normalScale') return;
|
|
|
|
|
watch(() => this[p], (value) => {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
if (p === 'emissive') {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
this.material[p].set(value);
|
2020-10-04 06:49:05 +08:00
|
|
|
|
} else {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
this.material[p] = value;
|
2020-10-04 06:49:05 +08:00
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
});
|
2021-03-08 04:17:46 +08:00
|
|
|
|
bindProp(this, 'normalScale', this.material);
|
2021-03-14 02:34:34 +08:00
|
|
|
|
bindProps(this, Object.keys(wireframeProps), this.material);
|
2020-09-17 05:54:14 +08:00
|
|
|
|
},
|
|
|
|
|
},
|
2020-10-04 06:49:05 +08:00
|
|
|
|
__hmrId: 'StandardMaterial',
|
2021-04-05 04:02:11 +08:00
|
|
|
|
});
|
2020-10-04 06:49:05 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var PhysicalMaterial = defineComponent({
|
2020-10-04 06:49:05 +08:00
|
|
|
|
extends: StandardMaterial,
|
2021-03-14 02:34:34 +08:00
|
|
|
|
props: {
|
|
|
|
|
flatShading: Boolean,
|
|
|
|
|
},
|
2020-10-04 06:49:05 +08:00
|
|
|
|
methods: {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
createMaterial() {
|
2021-03-08 04:17:46 +08:00
|
|
|
|
this.material = new MeshPhysicalMaterial(propsValues(this.$props));
|
2020-10-04 06:49:05 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
addWatchers() {
|
2021-03-14 02:34:34 +08:00
|
|
|
|
// TODO
|
|
|
|
|
},
|
2020-09-17 05:54:14 +08:00
|
|
|
|
},
|
2020-10-04 06:49:05 +08:00
|
|
|
|
__hmrId: 'PhysicalMaterial',
|
2021-04-05 04:02:11 +08:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const defaultVertexShader = `
|
|
|
|
|
varying vec2 vUv;
|
|
|
|
|
void main(){
|
|
|
|
|
vUv = uv;
|
|
|
|
|
gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0);
|
|
|
|
|
}`;
|
|
|
|
|
|
|
|
|
|
const defaultFragmentShader = `
|
|
|
|
|
varying vec2 vUv;
|
|
|
|
|
void main() {
|
|
|
|
|
gl_FragColor = vec4(vUv.x, vUv.y, 0., 1.0);
|
|
|
|
|
}`;
|
2020-09-17 05:54:14 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var ShaderMaterial = defineComponent({
|
2021-03-14 02:34:34 +08:00
|
|
|
|
inject: ['three', 'mesh'],
|
|
|
|
|
props: {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
uniforms: { type: Object, default: () => { return {}; } },
|
2021-03-14 02:34:34 +08:00
|
|
|
|
vertexShader: { type: String, default: defaultVertexShader },
|
|
|
|
|
fragmentShader: { type: String, default: defaultFragmentShader },
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
provide() {
|
|
|
|
|
return {
|
|
|
|
|
material: this,
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
created() {
|
2021-03-14 02:34:34 +08:00
|
|
|
|
this.createMaterial();
|
2021-04-05 04:02:11 +08:00
|
|
|
|
['vertexShader', 'fragmentShader'].forEach(p => {
|
|
|
|
|
watch(() => this[p], () => {
|
2021-03-14 02:34:34 +08:00
|
|
|
|
// recreate material if we change either shader
|
2021-04-05 04:02:11 +08:00
|
|
|
|
this.material.dispose();
|
|
|
|
|
this.createMaterial();
|
2021-03-14 02:34:34 +08:00
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
unmounted() {
|
2021-03-14 02:34:34 +08:00
|
|
|
|
this.material.dispose();
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
createMaterial() {
|
2021-03-14 02:34:34 +08:00
|
|
|
|
this.material = new ShaderMaterial$1(propsValues(this.$props));
|
|
|
|
|
this.mesh.setMaterial(this.material);
|
|
|
|
|
},
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
render() {
|
|
|
|
|
return this.$slots.default ? this.$slots.default() : [];
|
2021-03-14 02:34:34 +08:00
|
|
|
|
},
|
|
|
|
|
__hmrId: 'ShaderMaterial',
|
2021-04-05 04:02:11 +08:00
|
|
|
|
});
|
2021-03-14 02:34:34 +08:00
|
|
|
|
|
2020-10-04 06:49:05 +08:00
|
|
|
|
/**
|
|
|
|
|
* ------------------------------------------------------------------------------------------
|
|
|
|
|
* Subsurface Scattering shader
|
|
|
|
|
* Based on three/examples/jsm/shaders/SubsurfaceScatteringShader.js
|
|
|
|
|
* Based on GDC 2011 – Approximating Translucency for a Fast, Cheap and Convincing Subsurface Scattering Look
|
|
|
|
|
* https://colinbarrebrisebois.com/2011/03/07/gdc-2011-approximating-translucency-for-a-fast-cheap-and-convincing-subsurface-scattering-look/
|
|
|
|
|
*------------------------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
function replaceAll(string, find, replace) {
|
|
|
|
|
return string.split(find).join(replace);
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
const meshphongFragHead = ShaderChunk.meshphong_frag.slice(0, ShaderChunk.meshphong_frag.indexOf('void main() {'));
|
|
|
|
|
const meshphongFragBody = ShaderChunk.meshphong_frag.slice(ShaderChunk.meshphong_frag.indexOf('void main() {'));
|
2020-10-04 06:49:05 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
const SubsurfaceScatteringShader = {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
|
|
|
|
|
uniforms: UniformsUtils.merge([
|
|
|
|
|
ShaderLib.phong.uniforms,
|
|
|
|
|
{
|
2021-03-14 02:34:34 +08:00
|
|
|
|
thicknessColor: { value: new Color(0xffffff) },
|
2020-10-04 06:49:05 +08:00
|
|
|
|
thicknessDistortion: { value: 0.1 },
|
|
|
|
|
thicknessAmbient: { value: 0.0 },
|
|
|
|
|
thicknessAttenuation: { value: 0.1 },
|
|
|
|
|
thicknessPower: { value: 2.0 },
|
|
|
|
|
thicknessScale: { value: 10.0 },
|
2021-04-05 04:02:11 +08:00
|
|
|
|
},
|
|
|
|
|
]),
|
|
|
|
|
|
|
|
|
|
vertexShader: `
|
|
|
|
|
#define USE_UV
|
|
|
|
|
${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;
|
|
|
|
|
}
|
|
|
|
|
` + meshphongFragBody.replace(
|
2020-10-04 06:49:05 +08:00
|
|
|
|
'#include <lights_fragment_begin>',
|
|
|
|
|
replaceAll(
|
|
|
|
|
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
|
|
|
|
|
`
|
2020-10-04 06:49:05 +08:00
|
|
|
|
)
|
|
|
|
|
),
|
|
|
|
|
};
|
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var SubSurfaceMaterial = defineComponent({
|
2021-03-14 02:34:34 +08:00
|
|
|
|
inject: ['three', 'mesh'],
|
2020-09-17 05:54:14 +08:00
|
|
|
|
props: {
|
2021-03-04 04:49:22 +08:00
|
|
|
|
color: { type: String, default: '#ffffff' },
|
2020-10-04 06:49:05 +08:00
|
|
|
|
thicknessColor: { type: String, default: '#ffffff' },
|
|
|
|
|
thicknessDistortion: { type: Number, default: 0.4 },
|
|
|
|
|
thicknessAmbient: { type: Number, default: 0.01 },
|
|
|
|
|
thicknessAttenuation: { type: Number, default: 0.7 },
|
|
|
|
|
thicknessPower: { type: Number, default: 2 },
|
|
|
|
|
thicknessScale: { type: Number, default: 4 },
|
|
|
|
|
transparent: { type: Boolean, default: false },
|
|
|
|
|
opacity: { type: Number, default: 1 },
|
|
|
|
|
vertexColors: { type: Boolean, default: false },
|
2020-09-17 05:54:14 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
created() {
|
2021-03-14 02:34:34 +08:00
|
|
|
|
this.createMaterial();
|
|
|
|
|
this.mesh.setMaterial(this.material);
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
unmounted() {
|
2021-03-14 02:34:34 +08:00
|
|
|
|
this.material.dispose();
|
|
|
|
|
},
|
2020-10-04 06:49:05 +08:00
|
|
|
|
methods: {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
createMaterial() {
|
|
|
|
|
const params = SubsurfaceScatteringShader;
|
|
|
|
|
const uniforms = UniformsUtils.clone(params.uniforms);
|
2020-10-04 06:49:05 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
Object.entries(this.$props).forEach(([key, value]) => {
|
|
|
|
|
let _key = key, _value = value;
|
2021-03-04 04:49:22 +08:00
|
|
|
|
if (['color', 'thicknessColor'].includes(key)) {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
if (key === 'color') _key = 'diffuse';
|
2021-03-04 04:49:22 +08:00
|
|
|
|
_value = new Color(value);
|
2020-10-04 06:49:05 +08:00
|
|
|
|
}
|
2021-03-08 04:17:46 +08:00
|
|
|
|
if (!['transparent', 'vertexColors'].includes(key)) {
|
2021-03-04 04:49:22 +08:00
|
|
|
|
uniforms[_key].value = _value;
|
2020-10-04 06:49:05 +08:00
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
this.material = new ShaderMaterial$1({
|
|
|
|
|
...params,
|
|
|
|
|
uniforms,
|
2020-10-04 06:49:05 +08:00
|
|
|
|
lights: true,
|
|
|
|
|
transparent: this.transparent,
|
2021-04-05 04:02:11 +08:00
|
|
|
|
vertexColors: this.vertexColors,
|
|
|
|
|
});
|
2020-10-04 06:49:05 +08:00
|
|
|
|
},
|
2020-09-17 05:54:14 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
render() {
|
2021-03-14 02:34:34 +08:00
|
|
|
|
return [];
|
|
|
|
|
},
|
2020-10-04 06:49:05 +08:00
|
|
|
|
__hmrId: 'SubSurfaceMaterial',
|
2021-04-05 04:02:11 +08:00
|
|
|
|
});
|
2020-09-17 05:54:14 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var ToonMaterial = defineComponent({
|
2020-10-04 06:49:05 +08:00
|
|
|
|
extends: Material,
|
2021-04-05 04:02:11 +08:00
|
|
|
|
props: {
|
|
|
|
|
...wireframeProps,
|
|
|
|
|
},
|
2020-10-04 06:49:05 +08:00
|
|
|
|
methods: {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
createMaterial() {
|
2021-03-08 04:17:46 +08:00
|
|
|
|
this.material = new MeshToonMaterial(propsValues(this.$props));
|
2020-09-17 05:54:14 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
addWatchers() {
|
2021-03-14 02:34:34 +08:00
|
|
|
|
bindProps(this, Object.keys(wireframeProps), this.material);
|
|
|
|
|
},
|
2020-09-17 05:54:14 +08:00
|
|
|
|
},
|
2020-10-04 06:49:05 +08:00
|
|
|
|
__hmrId: 'ToonMaterial',
|
2021-04-05 04:02:11 +08:00
|
|
|
|
});
|
2020-09-17 05:54:14 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var Texture = defineComponent({
|
2020-10-04 06:49:05 +08:00
|
|
|
|
inject: ['material'],
|
2021-02-26 05:55:44 +08:00
|
|
|
|
emits: ['loaded'],
|
|
|
|
|
props: {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
name: { type: String, default: 'map' },
|
|
|
|
|
uniform: { type: String, default: null },
|
2021-02-26 05:55:44 +08:00
|
|
|
|
src: String,
|
|
|
|
|
onLoad: Function,
|
|
|
|
|
onProgress: Function,
|
|
|
|
|
onError: Function,
|
2021-03-08 04:17:46 +08:00
|
|
|
|
mapping: { type: Number, default: UVMapping },
|
|
|
|
|
wrapS: { type: Number, default: ClampToEdgeWrapping },
|
|
|
|
|
wrapT: { type: Number, default: ClampToEdgeWrapping },
|
|
|
|
|
magFilter: { type: Number, default: LinearFilter },
|
|
|
|
|
minFilter: { type: Number, default: LinearMipmapLinearFilter },
|
|
|
|
|
repeat: { type: Object, default: { x: 1, y: 1 } },
|
|
|
|
|
rotation: { type: Number, default: 0 },
|
|
|
|
|
center: { type: Object, default: { x: 0, y: 0 } },
|
2021-02-26 05:55:44 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
created() {
|
2021-02-26 05:55:44 +08:00
|
|
|
|
this.refreshTexture();
|
2021-04-05 04:02:11 +08:00
|
|
|
|
watch(() => this.src, this.refreshTexture);
|
2020-10-04 06:49:05 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
unmounted() {
|
|
|
|
|
if (this.material && this.material.setTexture) this.material.setTexture(null, this.name);
|
2021-02-26 05:55:44 +08:00
|
|
|
|
this.texture.dispose();
|
2020-10-04 06:49:05 +08:00
|
|
|
|
},
|
|
|
|
|
methods: {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
createTexture() {
|
2021-02-26 05:55:44 +08:00
|
|
|
|
this.texture = new TextureLoader().load(this.src, this.onLoaded, this.onProgress, this.onError);
|
2021-04-05 04:02:11 +08:00
|
|
|
|
const wathProps = ['mapping', 'wrapS', 'wrapT', 'magFilter', 'minFilter', 'repeat', 'rotation', 'rotation', 'center'];
|
|
|
|
|
wathProps.forEach(prop => {
|
|
|
|
|
bindProp(this, prop, this.texture);
|
2021-03-08 04:17:46 +08:00
|
|
|
|
});
|
2021-02-26 05:55:44 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
refreshTexture() {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
this.createTexture();
|
2021-04-05 04:02:11 +08:00
|
|
|
|
// handle standard material
|
|
|
|
|
if (this.material && this.material.setTexture) { this.material.setTexture(this.texture, this.name); }
|
|
|
|
|
// handle shader material
|
|
|
|
|
else if (this.material && this.material.material.type === "ShaderMaterial") {
|
|
|
|
|
// require a `uniform` prop so we know what to call the uniform
|
|
|
|
|
if (!this.uniform) {
|
|
|
|
|
console.warn('"uniform" prop required to use texture in a shader.');
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
this.material.uniforms[this.uniform] = { value: this.texture };
|
|
|
|
|
}
|
2020-09-17 05:54:14 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
onLoaded() {
|
|
|
|
|
if (this.onLoad) this.onLoad();
|
2021-02-26 05:55:44 +08:00
|
|
|
|
this.$emit('loaded');
|
|
|
|
|
},
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
render() { return []; },
|
|
|
|
|
});
|
2020-10-04 06:49:05 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var CubeTexture = defineComponent({
|
2020-10-04 06:49:05 +08:00
|
|
|
|
inject: ['material'],
|
2021-02-26 05:55:44 +08:00
|
|
|
|
emits: ['loaded'],
|
|
|
|
|
props: {
|
|
|
|
|
path: String,
|
|
|
|
|
urls: {
|
|
|
|
|
type: Array,
|
|
|
|
|
default: ['px.jpg', 'nx.jpg', 'py.jpg', 'ny.jpg', 'pz.jpg', 'nz.jpg'],
|
|
|
|
|
},
|
|
|
|
|
onLoad: Function,
|
|
|
|
|
onProgress: Function,
|
|
|
|
|
onError: Function,
|
2021-04-05 04:02:11 +08:00
|
|
|
|
name: { type: String, default: 'envMap' },
|
2021-02-26 05:55:44 +08:00
|
|
|
|
refraction: Boolean,
|
|
|
|
|
// todo: remove ?
|
|
|
|
|
refractionRatio: { type: Number, default: 0.98 },
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
created() {
|
2021-02-26 05:55:44 +08:00
|
|
|
|
this.refreshTexture();
|
2021-04-05 04:02:11 +08:00
|
|
|
|
watch(() => this.path, this.refreshTexture);
|
|
|
|
|
watch(() => this.urls, this.refreshTexture);
|
2020-10-04 06:49:05 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
unmounted() {
|
|
|
|
|
this.material.setTexture(null, this.name);
|
2021-02-26 05:55:44 +08:00
|
|
|
|
this.texture.dispose();
|
2020-10-04 06:49:05 +08:00
|
|
|
|
},
|
|
|
|
|
methods: {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
createTexture() {
|
2021-02-26 05:55:44 +08:00
|
|
|
|
this.texture = new CubeTextureLoader()
|
|
|
|
|
.setPath(this.path)
|
|
|
|
|
.load(this.urls, this.onLoaded, this.onProgress, this.onError);
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
refreshTexture() {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
this.createTexture();
|
2021-04-05 04:02:11 +08:00
|
|
|
|
this.material.setTexture(this.texture, this.name);
|
2021-02-26 05:55:44 +08:00
|
|
|
|
if (this.refraction) {
|
|
|
|
|
this.texture.mapping = CubeRefractionMapping;
|
|
|
|
|
this.material.setProp('refractionRatio', this.refractionRatio);
|
|
|
|
|
}
|
2020-10-04 06:49:05 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
onLoaded() {
|
|
|
|
|
if (this.onLoad) this.onLoad();
|
2021-02-26 05:55:44 +08:00
|
|
|
|
this.$emit('loaded');
|
|
|
|
|
},
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
render() {
|
2021-02-26 05:55:44 +08:00
|
|
|
|
return [];
|
2020-09-17 05:54:14 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const pointerProps = {
|
|
|
|
|
onPointerEnter: Function,
|
|
|
|
|
onPointerOver: Function,
|
|
|
|
|
onPointerMove: Function,
|
|
|
|
|
onPointerLeave: Function,
|
|
|
|
|
onPointerDown: Function,
|
|
|
|
|
onPointerUp: Function,
|
|
|
|
|
onClick: Function,
|
2020-09-17 05:54:14 +08:00
|
|
|
|
};
|
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
const Mesh = defineComponent({
|
2021-03-08 04:17:46 +08:00
|
|
|
|
name: 'Mesh',
|
2021-04-05 04:02:11 +08:00
|
|
|
|
extends: Object3D,
|
2020-09-17 05:54:14 +08:00
|
|
|
|
props: {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
castShadow: Boolean,
|
|
|
|
|
receiveShadow: Boolean,
|
2021-04-05 04:02:11 +08:00
|
|
|
|
...pointerProps,
|
2021-02-26 05:55:44 +08:00
|
|
|
|
},
|
|
|
|
|
// can't use setup because it will not be used in sub components
|
|
|
|
|
// setup() {},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
provide() {
|
2020-09-17 05:54:14 +08:00
|
|
|
|
return {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
mesh: this,
|
2020-09-17 05:54:14 +08:00
|
|
|
|
};
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
mounted() {
|
|
|
|
|
if (!this.mesh && !this.loading) this.initMesh();
|
2020-10-04 06:49:05 +08:00
|
|
|
|
},
|
|
|
|
|
methods: {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
initMesh() {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
this.mesh = new Mesh$1(this.geometry, this.material);
|
2021-04-05 04:02:11 +08:00
|
|
|
|
this.mesh.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) {
|
2021-02-26 05:55:44 +08:00
|
|
|
|
this.three.addIntersectObject(this.mesh);
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-08 04:17:46 +08:00
|
|
|
|
this.initObject3D(this.mesh);
|
2020-10-04 06:49:05 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
addGeometryWatchers(props) {
|
|
|
|
|
Object.keys(props).forEach(prop => {
|
|
|
|
|
watch(() => this[prop], () => {
|
|
|
|
|
this.refreshGeometry();
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
setGeometry(geometry) {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
this.geometry = geometry;
|
2021-04-05 04:02:11 +08:00
|
|
|
|
if (this.mesh) this.mesh.geometry = geometry;
|
2020-10-04 06:49:05 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
setMaterial(material) {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
this.material = material;
|
2021-04-05 04:02:11 +08:00
|
|
|
|
if (this.mesh) this.mesh.material = material;
|
2020-10-04 06:49:05 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
refreshGeometry() {
|
|
|
|
|
const oldGeo = this.geometry;
|
2020-10-04 06:49:05 +08:00
|
|
|
|
this.createGeometry();
|
|
|
|
|
this.mesh.geometry = this.geometry;
|
|
|
|
|
oldGeo.dispose();
|
|
|
|
|
},
|
2020-09-17 05:54:14 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
unmounted() {
|
2021-03-08 04:17:46 +08:00
|
|
|
|
if (this.mesh) {
|
|
|
|
|
this.three.removeIntersectObject(this.mesh);
|
2021-04-05 04:02:11 +08:00
|
|
|
|
}
|
|
|
|
|
// for predefined mesh (geometry is not unmounted)
|
|
|
|
|
if (this.geometry) this.geometry.dispose();
|
2020-10-04 06:49:05 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
__hmrId: 'Mesh',
|
|
|
|
|
});
|
2020-10-04 06:49:05 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
function meshComponent(name, props, createGeometry) {
|
|
|
|
|
return defineComponent({
|
|
|
|
|
name,
|
|
|
|
|
extends: Mesh,
|
|
|
|
|
props,
|
|
|
|
|
created() {
|
|
|
|
|
this.createGeometry();
|
|
|
|
|
this.addGeometryWatchers(props);
|
2020-10-04 06:49:05 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
methods: {
|
|
|
|
|
createGeometry() {
|
|
|
|
|
this.geometry = createGeometry(this);
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
__hmrId: name,
|
|
|
|
|
});
|
|
|
|
|
}
|
2020-10-04 06:49:05 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var Box = meshComponent('Box', props$h, createGeometry$f);
|
2020-10-04 06:49:05 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var Circle = meshComponent('Circle', props$g, createGeometry$e);
|
2020-10-04 06:49:05 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var Cone = meshComponent('Cone', props$f, createGeometry$d);
|
2020-10-04 06:49:05 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var Cylinder = meshComponent('Cylinder', props$e, createGeometry$c);
|
2020-10-04 06:49:05 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var Dodecahedron = meshComponent('Dodecahedron', props$d, createGeometry$b);
|
2020-10-04 06:49:05 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var Icosahedron = meshComponent('Icosahedron', props$c, createGeometry$a);
|
2020-10-04 06:49:05 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var Lathe = meshComponent('Lathe', props$b, createGeometry$9);
|
2020-10-04 06:49:05 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var Octahedron = meshComponent('Octahedron', props$a, createGeometry$8);
|
2020-10-04 06:49:05 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
const props$1 = {
|
|
|
|
|
width: { type: Number, default: 1 },
|
|
|
|
|
height: { type: Number, default: 1 },
|
|
|
|
|
widthSegments: { type: Number, default: 1 },
|
|
|
|
|
heightSegments: { type: Number, default: 1 },
|
2020-10-04 06:49:05 +08:00
|
|
|
|
};
|
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
function createGeometry(comp) {
|
|
|
|
|
return new PlaneGeometry(comp.width, comp.height, comp.widthSegments, comp.heightSegments);
|
|
|
|
|
}
|
|
|
|
|
geometryComponent('PlaneGeometry', props$1, createGeometry);
|
2020-10-04 06:49:05 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var Plane = meshComponent('Plane', props$1, createGeometry);
|
2020-10-04 06:49:05 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var Polyhedron = meshComponent('Polyhedron', props$9, createGeometry$7);
|
2020-10-04 06:49:05 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var Ring = meshComponent('Ring', props$8, createGeometry$6);
|
|
|
|
|
|
|
|
|
|
var Sphere = meshComponent('Sphere', props$7, createGeometry$5);
|
|
|
|
|
|
|
|
|
|
var Tetrahedron = meshComponent('Tetrahedron', props$6, createGeometry$4);
|
2020-10-04 06:49:05 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
const props = {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
text: String,
|
|
|
|
|
fontSrc: String,
|
|
|
|
|
size: { type: Number, default: 80 },
|
|
|
|
|
height: { type: Number, default: 5 },
|
|
|
|
|
depth: { type: Number, default: 1 },
|
|
|
|
|
curveSegments: { type: Number, default: 12 },
|
|
|
|
|
bevelEnabled: { type: Boolean, default: false },
|
|
|
|
|
bevelThickness: { type: Number, default: 10 },
|
|
|
|
|
bevelSize: { type: Number, default: 8 },
|
|
|
|
|
bevelOffset: { type: Number, default: 0 },
|
|
|
|
|
bevelSegments: { type: Number, default: 5 },
|
|
|
|
|
align: { type: [Boolean, String], default: false },
|
|
|
|
|
};
|
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var Text = defineComponent({
|
2020-10-04 06:49:05 +08:00
|
|
|
|
extends: Mesh,
|
2021-04-05 04:02:11 +08:00
|
|
|
|
props,
|
|
|
|
|
data() {
|
2021-03-08 04:17:46 +08:00
|
|
|
|
return {
|
|
|
|
|
loading: true,
|
|
|
|
|
};
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
created() {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
// add watchers
|
2021-04-05 04:02:11 +08:00
|
|
|
|
const watchProps = [
|
2020-10-04 06:49:05 +08:00
|
|
|
|
'text', 'size', 'height', 'curveSegments',
|
|
|
|
|
'bevelEnabled', 'bevelThickness', 'bevelSize', 'bevelOffset', 'bevelSegments',
|
2021-04-05 04:02:11 +08:00
|
|
|
|
'align',
|
|
|
|
|
];
|
|
|
|
|
watchProps.forEach(p => {
|
|
|
|
|
watch(() => this[p], () => {
|
|
|
|
|
if (this.font) this.refreshGeometry();
|
2020-10-04 06:49:05 +08:00
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
const loader = new FontLoader();
|
|
|
|
|
loader.load(this.fontSrc, (font) => {
|
|
|
|
|
this.loading = false;
|
|
|
|
|
this.font = font;
|
|
|
|
|
this.createGeometry();
|
|
|
|
|
this.initMesh();
|
2020-10-04 06:49:05 +08:00
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
createGeometry() {
|
|
|
|
|
this.geometry = new TextGeometry(this.text, {
|
2020-10-04 06:49:05 +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,
|
|
|
|
|
bevelSegments: this.bevelSegments,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (this.align === 'center') {
|
|
|
|
|
this.geometry.center();
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
});
|
2020-10-04 06:49:05 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var Torus = meshComponent('Torus', props$5, createGeometry$3);
|
2020-10-04 06:49:05 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var TorusKnot = meshComponent('TorusKnot', props$4, createGeometry$2);
|
2020-10-04 06:49:05 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var Tube = defineComponent({
|
2020-10-04 06:49:05 +08:00
|
|
|
|
extends: Mesh,
|
2021-04-05 04:02:11 +08:00
|
|
|
|
props: props$3,
|
|
|
|
|
created() {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
this.createGeometry();
|
2021-04-05 04:02:11 +08:00
|
|
|
|
this.addGeometryWatchers(props$3);
|
2020-10-04 06:49:05 +08:00
|
|
|
|
},
|
|
|
|
|
methods: {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
createGeometry() {
|
|
|
|
|
this.geometry = createGeometry$1(this);
|
2021-03-08 04:17:46 +08:00
|
|
|
|
},
|
2021-03-10 01:25:02 +08:00
|
|
|
|
// update curve points (without using prop, faster)
|
2021-04-05 04:02:11 +08:00
|
|
|
|
updatePoints(points) {
|
2021-03-10 01:25:02 +08:00
|
|
|
|
updateTubeGeometryPoints(this.geometry, points);
|
2020-10-04 06:49:05 +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 Gem = defineComponent({
|
2020-10-04 06:49:05 +08:00
|
|
|
|
extends: Mesh,
|
|
|
|
|
props: {
|
2021-02-26 05:55:44 +08:00
|
|
|
|
cubeRTSize: { type: Number, default: 256 },
|
2020-10-04 06:49:05 +08:00
|
|
|
|
cubeCameraNear: { type: Number, default: 0.1 },
|
|
|
|
|
cubeCameraFar: { type: Number, default: 2000 },
|
|
|
|
|
autoUpdate: Boolean,
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
mounted() {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
this.initGem();
|
2021-04-05 04:02:11 +08:00
|
|
|
|
if (this.autoUpdate) this.three.onBeforeRender(this.updateCubeRT);
|
|
|
|
|
else this.rendererComponent.onMounted(this.updateCubeRT);
|
2020-10-04 06:49:05 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
unmounted() {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
this.three.offBeforeRender(this.updateCubeRT);
|
2021-04-05 04:02:11 +08:00
|
|
|
|
if (this.cubeCamera) this.removeFromParent(this.cubeCamera);
|
|
|
|
|
if (this.meshBack) this.removeFromParent(this.meshBack);
|
|
|
|
|
if (this.materialBack) this.materialBack.dispose();
|
2020-10-04 06:49:05 +08:00
|
|
|
|
},
|
|
|
|
|
methods: {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
initGem() {
|
|
|
|
|
const cubeRT = new WebGLCubeRenderTarget(this.cubeRTSize, { format: RGBFormat, generateMipmaps: true, minFilter: LinearMipmapLinearFilter });
|
2020-10-04 06:49:05 +08:00
|
|
|
|
this.cubeCamera = new CubeCamera(this.cubeCameraNear, this.cubeCameraFar, cubeRT);
|
2021-03-08 04:17:46 +08:00
|
|
|
|
bindProp(this, 'position', this.cubeCamera);
|
2021-04-05 04:02:11 +08:00
|
|
|
|
this.addToParent(this.cubeCamera);
|
2020-10-04 06:49:05 +08:00
|
|
|
|
|
|
|
|
|
this.material.side = FrontSide;
|
|
|
|
|
this.material.envMap = cubeRT.texture;
|
|
|
|
|
this.material.envMapIntensity = 10;
|
|
|
|
|
this.material.metalness = 0;
|
|
|
|
|
this.material.roughness = 0;
|
|
|
|
|
this.material.opacity = 0.75;
|
|
|
|
|
this.material.transparent = true;
|
|
|
|
|
this.material.premultipliedAlpha = true;
|
|
|
|
|
this.material.needsUpdate = true;
|
|
|
|
|
|
|
|
|
|
this.materialBack = this.material.clone();
|
|
|
|
|
this.materialBack.side = BackSide;
|
|
|
|
|
this.materialBack.envMapIntensity = 5;
|
|
|
|
|
this.materialBack.metalness = 1;
|
|
|
|
|
this.materialBack.roughness = 0;
|
|
|
|
|
this.materialBack.opacity = 0.5;
|
|
|
|
|
|
|
|
|
|
this.meshBack = new Mesh$1(this.geometry, this.materialBack);
|
|
|
|
|
|
2021-03-08 04:17:46 +08:00
|
|
|
|
bindProp(this, 'position', this.meshBack);
|
|
|
|
|
bindProp(this, 'rotation', this.meshBack);
|
|
|
|
|
bindProp(this, 'scale', this.meshBack);
|
2021-04-05 04:02:11 +08:00
|
|
|
|
this.addToParent(this.meshBack);
|
2020-10-04 06:49:05 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
updateCubeRT() {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
this.mesh.visible = false;
|
|
|
|
|
this.meshBack.visible = false;
|
|
|
|
|
this.cubeCamera.update(this.three.renderer, this.scene);
|
|
|
|
|
this.mesh.visible = true;
|
|
|
|
|
this.meshBack.visible = true;
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
__hmrId: 'Gem',
|
2021-04-05 04:02:11 +08:00
|
|
|
|
});
|
2020-10-04 06:49:05 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var Image = defineComponent({
|
2020-10-04 06:49:05 +08:00
|
|
|
|
emits: ['loaded'],
|
|
|
|
|
extends: Mesh,
|
|
|
|
|
props: {
|
|
|
|
|
src: String,
|
|
|
|
|
width: Number,
|
|
|
|
|
height: Number,
|
|
|
|
|
keepSize: Boolean,
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
created() {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
this.createGeometry();
|
|
|
|
|
this.createMaterial();
|
|
|
|
|
this.initMesh();
|
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
watch(() => this.src, this.refreshTexture);
|
2020-10-04 06:49:05 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
['width', 'height'].forEach(p => {
|
|
|
|
|
watch(() => this[p], this.resize);
|
2020-10-04 06:49:05 +08:00
|
|
|
|
});
|
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
if (this.keepSize) this.three.onAfterResize(this.resize);
|
2020-10-04 06:49:05 +08:00
|
|
|
|
},
|
|
|
|
|
methods: {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
createGeometry() {
|
|
|
|
|
this.geometry = new PlaneGeometry(1, 1, 1, 1);
|
2020-10-04 06:49:05 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
createMaterial() {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
this.material = new MeshBasicMaterial({ side: DoubleSide, map: this.loadTexture() });
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
loadTexture() {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
return new TextureLoader().load(this.src, this.onLoaded);
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
refreshTexture() {
|
|
|
|
|
if (this.texture) this.texture.dispose();
|
2020-10-04 06:49:05 +08:00
|
|
|
|
this.material.map = this.loadTexture();
|
|
|
|
|
this.material.needsUpdate = true;
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
onLoaded(texture) {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
this.texture = texture;
|
|
|
|
|
this.resize();
|
|
|
|
|
this.$emit('loaded');
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
resize() {
|
|
|
|
|
if (!this.texture) return;
|
|
|
|
|
const screen = this.three.size;
|
|
|
|
|
const iW = this.texture.image.width;
|
|
|
|
|
const iH = this.texture.image.height;
|
|
|
|
|
const iRatio = iW / iH;
|
|
|
|
|
let w, h;
|
2020-10-04 06:49:05 +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;
|
|
|
|
|
}
|
|
|
|
|
this.mesh.scale.x = w;
|
|
|
|
|
this.mesh.scale.y = h;
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
__hmrId: 'Image',
|
2021-04-05 04:02:11 +08:00
|
|
|
|
});
|
2020-10-04 06:49:05 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var InstancedMesh = defineComponent({
|
2021-03-08 04:17:46 +08:00
|
|
|
|
extends: Object3D,
|
2020-10-04 06:49:05 +08:00
|
|
|
|
props: {
|
|
|
|
|
castShadow: Boolean,
|
|
|
|
|
receiveShadow: Boolean,
|
2021-03-08 04:17:46 +08:00
|
|
|
|
count: Number,
|
2021-04-05 04:02:11 +08:00
|
|
|
|
...pointerProps,
|
2020-10-04 06:49:05 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
provide() {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
return {
|
|
|
|
|
mesh: this,
|
|
|
|
|
};
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
beforeMount() {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
if (!this.$slots.default) {
|
|
|
|
|
console.error('Missing Geometry');
|
|
|
|
|
}
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
mounted() {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
this.initMesh();
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
initMesh() {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
this.mesh = new InstancedMesh$1(this.geometry, this.material, this.count);
|
2021-04-05 04:02:11 +08:00
|
|
|
|
this.mesh.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.three.addIntersectObject(this.mesh);
|
|
|
|
|
}
|
2020-10-04 06:49:05 +08:00
|
|
|
|
|
2021-03-08 04:17:46 +08:00
|
|
|
|
this.initObject3D(this.mesh);
|
2020-10-04 06:49:05 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
setGeometry(geometry) {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
this.geometry = geometry;
|
2021-04-05 04:02:11 +08:00
|
|
|
|
if (this.mesh) this.mesh.geometry = geometry;
|
2020-10-04 06:49:05 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
setMaterial(material) {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
this.material = material;
|
2021-04-05 04:02:11 +08:00
|
|
|
|
this.material.instancingColor = true;
|
|
|
|
|
if (this.mesh) this.mesh.material = material;
|
2020-10-04 06:49:05 +08:00
|
|
|
|
},
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
unmounted() {
|
|
|
|
|
if (this.mesh) {
|
|
|
|
|
this.three.removeIntersectObject(this.mesh);
|
|
|
|
|
}
|
|
|
|
|
},
|
2020-10-04 06:49:05 +08:00
|
|
|
|
__hmrId: 'InstancedMesh',
|
2021-04-05 04:02:11 +08:00
|
|
|
|
});
|
2020-10-04 06:49:05 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var MirrorMesh = defineComponent({
|
2020-10-04 06:49:05 +08:00
|
|
|
|
extends: Mesh,
|
|
|
|
|
props: {
|
2021-02-26 05:55:44 +08:00
|
|
|
|
cubeRTSize: { type: Number, default: 256 },
|
2020-10-04 06:49:05 +08:00
|
|
|
|
cubeCameraNear: { type: Number, default: 0.1 },
|
|
|
|
|
cubeCameraFar: { type: Number, default: 2000 },
|
|
|
|
|
autoUpdate: Boolean,
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
mounted() {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
this.initMirrorMesh();
|
2021-04-05 04:02:11 +08:00
|
|
|
|
if (this.autoUpdate) this.three.onBeforeRender(this.updateCubeRT);
|
|
|
|
|
else this.rendererComponent.onMounted(this.updateCubeRT);
|
2020-10-04 06:49:05 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
unmounted() {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
this.three.offBeforeRender(this.updateCubeRT);
|
2021-04-05 04:02:11 +08:00
|
|
|
|
if (this.cubeCamera) this.removeFromParent(this.cubeCamera);
|
2020-10-04 06:49:05 +08:00
|
|
|
|
},
|
|
|
|
|
methods: {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
initMirrorMesh() {
|
|
|
|
|
const cubeRT = new WebGLCubeRenderTarget(this.cubeRTSize, { format: RGBFormat, generateMipmaps: true, minFilter: LinearMipmapLinearFilter });
|
2020-10-04 06:49:05 +08:00
|
|
|
|
this.cubeCamera = new CubeCamera(this.cubeCameraNear, this.cubeCameraFar, cubeRT);
|
2021-04-05 04:02:11 +08:00
|
|
|
|
this.addToParent(this.cubeCamera);
|
2020-10-04 06:49:05 +08:00
|
|
|
|
|
|
|
|
|
this.material.envMap = cubeRT.texture;
|
|
|
|
|
this.material.needsUpdate = true;
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
updateCubeRT() {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
this.mesh.visible = false;
|
|
|
|
|
this.cubeCamera.update(this.three.renderer, this.scene);
|
|
|
|
|
this.mesh.visible = true;
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
__hmrId: 'MirrorMesh',
|
2021-04-05 04:02:11 +08:00
|
|
|
|
});
|
2020-10-04 06:49:05 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var RefractionMesh = defineComponent({
|
2020-10-04 06:49:05 +08:00
|
|
|
|
extends: Mesh,
|
|
|
|
|
props: {
|
2021-02-26 05:55:44 +08:00
|
|
|
|
cubeRTSize: { type: Number, default: 256 },
|
2020-10-04 06:49:05 +08:00
|
|
|
|
cubeCameraNear: { type: Number, default: 0.1 },
|
|
|
|
|
cubeCameraFar: { type: Number, default: 2000 },
|
2021-02-26 05:55:44 +08:00
|
|
|
|
refractionRatio: { type: Number, default: 0.98 },
|
2020-10-04 06:49:05 +08:00
|
|
|
|
autoUpdate: Boolean,
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
mounted() {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
this.initMirrorMesh();
|
2021-04-05 04:02:11 +08:00
|
|
|
|
if (this.autoUpdate) this.three.onBeforeRender(this.updateCubeRT);
|
|
|
|
|
else this.rendererComponent.onMounted(this.updateCubeRT);
|
2020-10-04 06:49:05 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
unmounted() {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
this.three.offBeforeRender(this.updateCubeRT);
|
2021-04-05 04:02:11 +08:00
|
|
|
|
if (this.cubeCamera) this.removeFromParent(this.cubeCamera);
|
2020-10-04 06:49:05 +08:00
|
|
|
|
},
|
|
|
|
|
methods: {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
initMirrorMesh() {
|
|
|
|
|
const cubeRT = new WebGLCubeRenderTarget(this.cubeRTSize, { mapping: CubeRefractionMapping, format: RGBFormat, generateMipmaps: true, minFilter: LinearMipmapLinearFilter });
|
2020-10-04 06:49:05 +08:00
|
|
|
|
this.cubeCamera = new CubeCamera(this.cubeCameraNear, this.cubeCameraFar, cubeRT);
|
2021-03-08 04:17:46 +08:00
|
|
|
|
bindProp(this, 'position', this.cubeCamera);
|
2021-04-05 04:02:11 +08:00
|
|
|
|
this.addToParent(this.cubeCamera);
|
2020-10-04 06:49:05 +08:00
|
|
|
|
|
|
|
|
|
this.material.envMap = cubeRT.texture;
|
2021-02-26 05:55:44 +08:00
|
|
|
|
this.material.refractionRatio = this.refractionRatio;
|
2020-10-04 06:49:05 +08:00
|
|
|
|
this.material.needsUpdate = true;
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
updateCubeRT() {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
this.mesh.visible = false;
|
|
|
|
|
this.cubeCamera.update(this.three.renderer, this.scene);
|
|
|
|
|
this.mesh.visible = true;
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
__hmrId: 'RefractionMesh',
|
2021-04-05 04:02:11 +08:00
|
|
|
|
});
|
2020-10-04 06:49:05 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var Sprite = defineComponent({
|
2021-03-08 04:17:46 +08:00
|
|
|
|
extends: Object3D,
|
|
|
|
|
emits: ['loaded'],
|
2020-10-04 06:49:05 +08:00
|
|
|
|
props: {
|
|
|
|
|
src: String,
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
data() {
|
2021-03-08 04:17:46 +08:00
|
|
|
|
return {
|
|
|
|
|
loading: true,
|
|
|
|
|
};
|
2021-02-26 05:55:44 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
created() {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
this.texture = new TextureLoader().load(this.src, this.onLoaded);
|
|
|
|
|
this.material = new SpriteMaterial({ map: this.texture });
|
|
|
|
|
this.sprite = new Sprite$1(this.material);
|
|
|
|
|
this.geometry = this.sprite.geometry;
|
2021-03-08 04:17:46 +08:00
|
|
|
|
this.initObject3D(this.sprite);
|
2020-10-04 06:49:05 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
unmounted() {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
this.texture.dispose();
|
|
|
|
|
this.material.dispose();
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
onLoaded() {
|
2021-03-08 04:17:46 +08:00
|
|
|
|
this.loading = false;
|
2020-10-04 06:49:05 +08:00
|
|
|
|
this.updateUV();
|
|
|
|
|
this.$emit('loaded');
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
updateUV() {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
this.iWidth = this.texture.image.width;
|
|
|
|
|
this.iHeight = this.texture.image.height;
|
|
|
|
|
this.iRatio = this.iWidth / this.iHeight;
|
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
let x = 0.5, y = 0.5;
|
2020-10-04 06:49:05 +08:00
|
|
|
|
if (this.iRatio > 1) {
|
|
|
|
|
y = 0.5 / this.iRatio;
|
|
|
|
|
} else {
|
|
|
|
|
x = 0.5 / this.iRatio;
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
const positions = this.geometry.attributes.position.array;
|
2020-10-04 06:49:05 +08:00
|
|
|
|
positions[0] = -x; positions[1] = -y;
|
|
|
|
|
positions[5] = x; positions[6] = -y;
|
|
|
|
|
positions[10] = x; positions[11] = y;
|
|
|
|
|
positions[15] = -x; positions[16] = y;
|
|
|
|
|
this.geometry.attributes.position.needsUpdate = true;
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
__hmrId: 'Sprite',
|
2021-04-05 04:02:11 +08:00
|
|
|
|
});
|
2020-10-04 06:49:05 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var Model = defineComponent({
|
2021-03-14 02:34:34 +08:00
|
|
|
|
extends: Object3D,
|
2021-04-05 04:02:11 +08:00
|
|
|
|
emits: ['load', 'progress', 'error'],
|
|
|
|
|
data() {
|
|
|
|
|
return {
|
|
|
|
|
progress: 0,
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
|
|
|
|
onLoad(model) {
|
|
|
|
|
this.$emit('load', model);
|
|
|
|
|
this.initObject3D(model);
|
|
|
|
|
},
|
|
|
|
|
onProgress(progress) {
|
|
|
|
|
this.progress = progress.loaded / progress.total;
|
|
|
|
|
this.$emit('progress', progress);
|
|
|
|
|
},
|
|
|
|
|
onError(error) {
|
|
|
|
|
this.$emit('error', error);
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
var GLTF = defineComponent({
|
|
|
|
|
extends: Model,
|
2021-03-14 02:34:34 +08:00
|
|
|
|
props: {
|
|
|
|
|
src: String,
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
created() {
|
|
|
|
|
const loader = new GLTFLoader();
|
|
|
|
|
loader.load(this.src, (gltf) => {
|
|
|
|
|
this.onLoad(gltf.scene);
|
|
|
|
|
}, this.onProgress, this.onError);
|
2021-03-14 02:34:34 +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 = defineComponent({
|
|
|
|
|
extends: Model,
|
2021-03-14 02:34:34 +08:00
|
|
|
|
props: {
|
|
|
|
|
src: String,
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
created() {
|
|
|
|
|
const loader = new FBXLoader();
|
|
|
|
|
loader.load(this.src, (fbx) => {
|
|
|
|
|
this.onLoad(fbx);
|
|
|
|
|
}, this.onProgress, this.onError);
|
2021-03-14 02:34:34 +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 EffectComposer = defineComponent({
|
|
|
|
|
setup() {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
return {
|
|
|
|
|
passes: [],
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
inject: ['three'],
|
2021-04-05 04:02:11 +08:00
|
|
|
|
provide() {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
return {
|
|
|
|
|
passes: this.passes,
|
|
|
|
|
};
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
mounted() {
|
|
|
|
|
this.three.onAfterInit(() => {
|
|
|
|
|
this.composer = new EffectComposer$1(this.three.renderer);
|
|
|
|
|
this.three.renderer.autoClear = false;
|
|
|
|
|
this.passes.forEach(pass => {
|
|
|
|
|
this.composer.addPass(pass);
|
2020-10-04 06:49:05 +08:00
|
|
|
|
});
|
2021-04-05 04:02:11 +08:00
|
|
|
|
this.three.composer = this.composer;
|
2021-02-26 05:55:44 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
this.resize();
|
|
|
|
|
this.three.onAfterResize(this.resize);
|
2020-10-04 06:49:05 +08:00
|
|
|
|
});
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
unmounted() {
|
2021-02-26 05:55:44 +08:00
|
|
|
|
this.three.offAfterResize(this.resize);
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
resize() {
|
2021-02-26 05:55:44 +08:00
|
|
|
|
this.composer.setSize(this.three.size.width, this.three.size.height);
|
|
|
|
|
},
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
render() {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
return this.$slots.default();
|
|
|
|
|
},
|
|
|
|
|
__hmrId: 'EffectComposer',
|
2021-04-05 04:02:11 +08:00
|
|
|
|
});
|
2020-10-04 06:49:05 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var EffectPass = defineComponent({
|
2020-10-04 06:49:05 +08:00
|
|
|
|
inject: ['three', 'passes'],
|
2021-04-05 04:02:11 +08:00
|
|
|
|
emits: ['ready'],
|
|
|
|
|
beforeMount() {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
if (!this.passes) {
|
|
|
|
|
console.error('Missing parent EffectComposer');
|
|
|
|
|
}
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
unmounted() {
|
|
|
|
|
if (this.pass.dispose) this.pass.dispose();
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
|
|
|
|
completePass(pass) {
|
|
|
|
|
this.passes.push(pass);
|
|
|
|
|
this.pass = pass;
|
|
|
|
|
this.$emit('ready', pass);
|
|
|
|
|
},
|
2020-10-04 06:49:05 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
render() {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
return [];
|
|
|
|
|
},
|
|
|
|
|
__hmrId: 'EffectPass',
|
2021-04-05 04:02:11 +08:00
|
|
|
|
});
|
2020-10-04 06:49:05 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var RenderPass = defineComponent({
|
2020-10-04 06:49:05 +08:00
|
|
|
|
extends: EffectPass,
|
2021-04-05 04:02:11 +08:00
|
|
|
|
mounted() {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
if (!this.three.scene) {
|
|
|
|
|
console.error('Missing Scene');
|
|
|
|
|
}
|
|
|
|
|
if (!this.three.camera) {
|
|
|
|
|
console.error('Missing Camera');
|
|
|
|
|
}
|
2021-04-05 04:02:11 +08:00
|
|
|
|
const pass = new RenderPass$1(this.three.scene, this.three.camera);
|
|
|
|
|
this.completePass(pass);
|
2020-10-04 06:49:05 +08:00
|
|
|
|
},
|
|
|
|
|
__hmrId: 'RenderPass',
|
2021-04-05 04:02:11 +08:00
|
|
|
|
});
|
2020-10-04 06:49:05 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var BokehPass = defineComponent({
|
2020-09-17 05:54:14 +08:00
|
|
|
|
extends: EffectPass,
|
2020-10-04 06:49:05 +08:00
|
|
|
|
props: {
|
|
|
|
|
focus: {
|
|
|
|
|
type: Number,
|
|
|
|
|
default: 1,
|
|
|
|
|
},
|
|
|
|
|
aperture: {
|
|
|
|
|
type: Number,
|
|
|
|
|
default: 0.025,
|
|
|
|
|
},
|
|
|
|
|
maxblur: {
|
|
|
|
|
type: Number,
|
|
|
|
|
default: 0.01,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
watch: {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
focus() { this.pass.uniforms.focus.value = this.focus; },
|
|
|
|
|
aperture() { this.pass.uniforms.aperture.value = this.aperture; },
|
|
|
|
|
maxblur() { this.pass.uniforms.maxblur.value = this.maxblur; },
|
2020-10-04 06:49:05 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
mounted() {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
if (!this.three.scene) {
|
|
|
|
|
console.error('Missing Scene');
|
|
|
|
|
}
|
|
|
|
|
if (!this.three.camera) {
|
|
|
|
|
console.error('Missing Camera');
|
|
|
|
|
}
|
2021-04-05 04:02:11 +08:00
|
|
|
|
const params = {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
focus: this.focus,
|
|
|
|
|
aperture: this.aperture,
|
|
|
|
|
maxblur: this.maxblur,
|
|
|
|
|
width: this.three.size.width,
|
|
|
|
|
height: this.three.size.height,
|
|
|
|
|
};
|
2021-04-05 04:02:11 +08:00
|
|
|
|
const pass = new BokehPass$1(this.three.scene, this.three.camera, params);
|
|
|
|
|
this.completePass(pass);
|
2020-10-04 06:49:05 +08:00
|
|
|
|
},
|
|
|
|
|
__hmrId: 'BokehPass',
|
2021-04-05 04:02:11 +08:00
|
|
|
|
});
|
2020-10-04 06:49:05 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var FilmPass = defineComponent({
|
2020-10-04 06:49:05 +08:00
|
|
|
|
extends: EffectPass,
|
|
|
|
|
props: {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
noiseIntensity: { type: Number, default: 0.5 },
|
|
|
|
|
scanlinesIntensity: { type: Number, default: 0.05 },
|
|
|
|
|
scanlinesCount: { type: Number, default: 4096 },
|
|
|
|
|
grayscale: { type: Number, default: 0 },
|
2020-10-04 06:49:05 +08:00
|
|
|
|
},
|
|
|
|
|
watch: {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
noiseIntensity() { this.pass.uniforms.nIntensity.value = this.noiseIntensity; },
|
|
|
|
|
scanlinesIntensity() { this.pass.uniforms.sIntensity.value = this.scanlinesIntensity; },
|
|
|
|
|
scanlinesCount() { this.pass.uniforms.sCount.value = this.scanlinesCount; },
|
|
|
|
|
grayscale() { this.pass.uniforms.grayscale.value = this.grayscale; },
|
2020-10-04 06:49:05 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
mounted() {
|
|
|
|
|
const pass = new FilmPass$1(this.noiseIntensity, this.scanlinesIntensity, this.scanlinesCount, this.grayscale);
|
|
|
|
|
this.completePass(pass);
|
2020-10-04 06:49:05 +08:00
|
|
|
|
},
|
|
|
|
|
__hmrId: 'FilmPass',
|
2021-04-05 04:02:11 +08:00
|
|
|
|
});
|
2020-10-04 06:49:05 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var FXAAPass = defineComponent({
|
2021-02-26 05:55:44 +08:00
|
|
|
|
extends: EffectPass,
|
2021-04-05 04:02:11 +08:00
|
|
|
|
mounted() {
|
|
|
|
|
const pass = new ShaderPass(FXAAShader);
|
|
|
|
|
this.completePass(pass);
|
2021-02-26 05:55:44 +08:00
|
|
|
|
|
|
|
|
|
// resize will be called in three init
|
|
|
|
|
this.three.onAfterResize(this.resize);
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
unmounted() {
|
2021-02-26 05:55:44 +08:00
|
|
|
|
this.three.offAfterResize(this.resize);
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
resize() {
|
|
|
|
|
const { resolution } = this.pass.material.uniforms;
|
2021-02-26 05:55:44 +08:00
|
|
|
|
resolution.value.x = 1 / this.three.size.width;
|
|
|
|
|
resolution.value.y = 1 / this.three.size.height;
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
__hmrId: 'FXAAPass',
|
2021-04-05 04:02:11 +08:00
|
|
|
|
});
|
2021-02-26 05:55:44 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var HalftonePass = defineComponent({
|
2020-10-04 06:49:05 +08:00
|
|
|
|
extends: EffectPass,
|
|
|
|
|
props: {
|
|
|
|
|
shape: { type: Number, default: 1 },
|
|
|
|
|
radius: { type: Number, default: 4 },
|
|
|
|
|
rotateR: { type: Number, default: Math.PI / 12 * 1 },
|
|
|
|
|
rotateG: { type: Number, default: Math.PI / 12 * 2 },
|
|
|
|
|
rotateB: { type: Number, default: Math.PI / 12 * 3 },
|
|
|
|
|
scatter: { type: Number, default: 0 },
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
mounted() {
|
|
|
|
|
const pass = new HalftonePass$1(this.three.size.width, this.three.size.height, {});
|
2020-10-04 06:49:05 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
['shape', 'radius', 'rotateR', 'rotateG', 'rotateB', 'scatter'].forEach(p => {
|
|
|
|
|
pass.uniforms[p].value = this[p];
|
|
|
|
|
watch(() => this[p], () => {
|
|
|
|
|
pass.uniforms[p].value = this[p];
|
2020-10-04 06:49:05 +08:00
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
this.completePass(pass);
|
2020-09-17 05:54:14 +08:00
|
|
|
|
},
|
2020-10-04 06:49:05 +08:00
|
|
|
|
__hmrId: 'HalftonePass',
|
2021-04-05 04:02:11 +08:00
|
|
|
|
});
|
2020-09-17 05:54:14 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var SMAAPass = defineComponent({
|
2021-02-26 05:55:44 +08:00
|
|
|
|
extends: EffectPass,
|
2021-04-05 04:02:11 +08:00
|
|
|
|
mounted() {
|
2021-02-26 05:55:44 +08:00
|
|
|
|
// three size is not set yet, but this pass will be resized by effect composer
|
2021-04-05 04:02:11 +08:00
|
|
|
|
const pass = new SMAAPass$1(this.three.size.width, this.three.size.height);
|
|
|
|
|
this.completePass(pass);
|
2021-02-26 05:55:44 +08:00
|
|
|
|
},
|
|
|
|
|
__hmrId: 'SMAAPass',
|
2021-04-05 04:02:11 +08:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
var SSAOPass = defineComponent({
|
|
|
|
|
extends: EffectPass,
|
|
|
|
|
props: {
|
|
|
|
|
scene: null,
|
|
|
|
|
camera: null,
|
|
|
|
|
options: {
|
|
|
|
|
type: Object,
|
|
|
|
|
default: () => ({}),
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
mounted() {
|
|
|
|
|
const pass = new SSAOPass$1(
|
|
|
|
|
this.scene || this.three.scene,
|
|
|
|
|
this.camera || this.three.camera,
|
|
|
|
|
this.three.size.width,
|
|
|
|
|
this.three.size.height
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
for (const key of Object.keys(this.options)) {
|
|
|
|
|
pass[key] = this.options[key];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.completePass(pass);
|
|
|
|
|
},
|
|
|
|
|
__hmrId: 'SSAOPass',
|
|
|
|
|
});
|
2021-02-26 05:55:44 +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-02-26 05:55:44 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// From https://github.com/evanw/glfx.js
|
|
|
|
|
|
|
|
|
|
var TiltShift = {
|
|
|
|
|
uniforms: {
|
|
|
|
|
tDiffuse: { value: null },
|
|
|
|
|
blurRadius: { value: 0 },
|
|
|
|
|
gradientRadius: { value: 0 },
|
|
|
|
|
start: { value: new Vector2() },
|
|
|
|
|
end: { value: new Vector2() },
|
|
|
|
|
delta: { value: new Vector2() },
|
|
|
|
|
texSize: { value: new Vector2() },
|
|
|
|
|
},
|
|
|
|
|
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-02-26 05:55:44 +08:00
|
|
|
|
};
|
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var TiltShiftPass = defineComponent({
|
2020-09-17 05:54:14 +08:00
|
|
|
|
extends: EffectPass,
|
|
|
|
|
props: {
|
2021-02-26 05:55:44 +08:00
|
|
|
|
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 } },
|
2020-09-17 05:54:14 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
mounted() {
|
2021-02-26 05:55:44 +08:00
|
|
|
|
this.pass = new ShaderPass(TiltShift);
|
|
|
|
|
this.passes.push(this.pass);
|
|
|
|
|
|
|
|
|
|
this.pass1 = new ShaderPass(TiltShift);
|
|
|
|
|
this.passes.push(this.pass1);
|
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
const uniforms = this.uniforms = this.pass.uniforms;
|
|
|
|
|
const uniforms1 = this.uniforms1 = this.pass1.uniforms;
|
2021-02-26 05:55:44 +08:00
|
|
|
|
uniforms1.blurRadius = uniforms.blurRadius;
|
|
|
|
|
uniforms1.gradientRadius = uniforms.gradientRadius;
|
|
|
|
|
uniforms1.start = uniforms.start;
|
|
|
|
|
uniforms1.end = uniforms.end;
|
|
|
|
|
uniforms1.texSize = uniforms.texSize;
|
|
|
|
|
|
2021-03-08 04:17:46 +08:00
|
|
|
|
bindProp(this, 'blurRadius', uniforms.blurRadius, 'value');
|
|
|
|
|
bindProp(this, 'gradientRadius', uniforms.gradientRadius, 'value');
|
2021-02-26 05:55:44 +08:00
|
|
|
|
|
|
|
|
|
this.updateFocusLine();
|
2021-04-05 04:02:11 +08:00
|
|
|
|
['start', 'end'].forEach(p => {
|
|
|
|
|
watch(() => this[p], this.updateFocusLine, { deep: true });
|
2021-02-26 05:55:44 +08:00
|
|
|
|
});
|
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
this.pass.setSize = (width, height) => {
|
2021-02-26 05:55:44 +08:00
|
|
|
|
uniforms.texSize.value.set(width, height);
|
|
|
|
|
};
|
2021-04-05 04:02:11 +08:00
|
|
|
|
|
|
|
|
|
// emit ready event with two passes - do so manually in this file instead
|
|
|
|
|
// of calling `completePass` like in other effect types
|
|
|
|
|
this.$emit('ready', [this.pass, this.pass1]);
|
2021-02-26 05:55:44 +08:00
|
|
|
|
},
|
|
|
|
|
methods: {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
updateFocusLine() {
|
2021-02-26 05:55:44 +08:00
|
|
|
|
this.uniforms.start.value.copy(this.start);
|
|
|
|
|
this.uniforms.end.value.copy(this.end);
|
2021-04-05 04:02:11 +08:00
|
|
|
|
const dv = new Vector2().copy(this.end).sub(this.start).normalize();
|
2021-02-26 05:55:44 +08:00
|
|
|
|
this.uniforms.delta.value.copy(dv);
|
|
|
|
|
this.uniforms1.delta.value.set(-dv.y, dv.x);
|
|
|
|
|
},
|
2020-09-17 05:54:14 +08:00
|
|
|
|
},
|
2021-02-26 05:55:44 +08:00
|
|
|
|
__hmrId: 'TiltShiftPass',
|
2021-04-05 04:02:11 +08:00
|
|
|
|
});
|
2020-09-17 05:54:14 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var UnrealBloomPass = defineComponent({
|
2020-09-17 05:54:14 +08:00
|
|
|
|
extends: EffectPass,
|
|
|
|
|
props: {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
strength: { type: Number, default: 1.5 },
|
|
|
|
|
radius: { type: Number, default: 0 },
|
|
|
|
|
threshold: { type: Number, default: 0 },
|
|
|
|
|
},
|
|
|
|
|
watch: {
|
2021-04-05 04:02:11 +08:00
|
|
|
|
strength() { this.pass.strength = this.strength; },
|
|
|
|
|
radius() { this.pass.radius = this.radius; },
|
|
|
|
|
threshold() { this.pass.threshold = this.threshold; },
|
2020-09-17 05:54:14 +08:00
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
mounted() {
|
|
|
|
|
const size = new Vector2(this.three.size.width, this.three.size.height);
|
|
|
|
|
const pass = new UnrealBloomPass$1(size, this.strength, this.radius, this.threshold);
|
|
|
|
|
this.completePass(pass);
|
2020-09-17 05:54:14 +08:00
|
|
|
|
},
|
2020-10-04 06:49:05 +08:00
|
|
|
|
__hmrId: 'UnrealBloomPass',
|
2021-04-05 04:02:11 +08:00
|
|
|
|
});
|
2020-10-04 06:49:05 +08:00
|
|
|
|
|
2021-02-26 05:55:44 +08:00
|
|
|
|
// From https://github.com/evanw/glfx.js
|
|
|
|
|
|
|
|
|
|
var ZoomBlur = {
|
|
|
|
|
uniforms: {
|
|
|
|
|
tDiffuse: { value: null },
|
|
|
|
|
center: { value: new Vector2(0.5, 0.5) },
|
|
|
|
|
strength: { value: 0 },
|
|
|
|
|
},
|
|
|
|
|
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-02-26 05:55:44 +08:00
|
|
|
|
};
|
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
var ZoomBlurPass = defineComponent({
|
2021-02-26 05:55:44 +08:00
|
|
|
|
extends: EffectPass,
|
|
|
|
|
props: {
|
|
|
|
|
center: { type: Object, default: { x: 0.5, y: 0.5 } },
|
|
|
|
|
strength: { type: Number, default: 0.5 },
|
|
|
|
|
},
|
2021-04-05 04:02:11 +08:00
|
|
|
|
mounted() {
|
|
|
|
|
const pass = new ShaderPass(ZoomBlur);
|
2021-02-26 05:55:44 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
const uniforms = this.uniforms = pass.uniforms;
|
2021-03-08 04:17:46 +08:00
|
|
|
|
bindProp(this, 'center', uniforms.center, 'value');
|
|
|
|
|
bindProp(this, 'strength', uniforms.strength, 'value');
|
2021-04-05 04:02:11 +08:00
|
|
|
|
|
|
|
|
|
this.completePass(pass);
|
2021-02-26 05:55:44 +08:00
|
|
|
|
},
|
|
|
|
|
__hmrId: 'ZoomBlurPass',
|
2021-04-05 04:02:11 +08:00
|
|
|
|
});
|
2021-02-26 05:55:44 +08:00
|
|
|
|
|
2020-10-04 06:49:05 +08:00
|
|
|
|
var TROIS = /*#__PURE__*/Object.freeze({
|
|
|
|
|
__proto__: null,
|
|
|
|
|
Renderer: Renderer,
|
2021-02-26 05:55:44 +08:00
|
|
|
|
OrthographicCamera: OrthographicCamera,
|
2020-10-04 06:49:05 +08:00
|
|
|
|
PerspectiveCamera: PerspectiveCamera,
|
|
|
|
|
Camera: PerspectiveCamera,
|
2021-02-26 05:55:44 +08:00
|
|
|
|
Group: Group,
|
2020-10-04 06:49:05 +08:00
|
|
|
|
Scene: Scene,
|
2021-04-05 04:02:11 +08:00
|
|
|
|
Object3D: Object3D,
|
|
|
|
|
Raycaster: Raycaster,
|
2020-10-04 06:49:05 +08:00
|
|
|
|
BoxGeometry: BoxGeometry,
|
|
|
|
|
CircleGeometry: CircleGeometry,
|
|
|
|
|
ConeGeometry: ConeGeometry,
|
|
|
|
|
CylinderGeometry: CylinderGeometry,
|
|
|
|
|
DodecahedronGeometry: DodecahedronGeometry,
|
|
|
|
|
IcosahedronGeometry: IcosahedronGeometry,
|
|
|
|
|
LatheGeometry: LatheGeometry,
|
|
|
|
|
OctahedronGeometry: OctahedronGeometry,
|
|
|
|
|
PolyhedronGeometry: PolyhedronGeometry,
|
|
|
|
|
RingGeometry: RingGeometry,
|
|
|
|
|
SphereGeometry: SphereGeometry,
|
|
|
|
|
TetrahedronGeometry: TetrahedronGeometry,
|
|
|
|
|
TorusGeometry: TorusGeometry,
|
|
|
|
|
TorusKnotGeometry: TorusKnotGeometry,
|
|
|
|
|
TubeGeometry: TubeGeometry,
|
|
|
|
|
AmbientLight: AmbientLight,
|
|
|
|
|
DirectionalLight: DirectionalLight,
|
2021-03-08 04:17:46 +08:00
|
|
|
|
HemisphereLight: HemisphereLight,
|
2020-10-04 06:49:05 +08:00
|
|
|
|
PointLight: PointLight,
|
2021-03-08 04:17:46 +08:00
|
|
|
|
RectAreaLight: RectAreaLight,
|
2020-10-04 06:49:05 +08:00
|
|
|
|
SpotLight: SpotLight,
|
|
|
|
|
BasicMaterial: BasicMaterial,
|
|
|
|
|
LambertMaterial: LambertMaterial,
|
2021-02-26 05:55:44 +08:00
|
|
|
|
MatcapMaterial: MatcapMaterial,
|
2020-10-04 06:49:05 +08:00
|
|
|
|
PhongMaterial: PhongMaterial,
|
|
|
|
|
PhysicalMaterial: PhysicalMaterial,
|
2021-03-14 02:34:34 +08:00
|
|
|
|
ShaderMaterial: ShaderMaterial,
|
2020-10-04 06:49:05 +08:00
|
|
|
|
StandardMaterial: StandardMaterial,
|
|
|
|
|
SubSurfaceMaterial: SubSurfaceMaterial,
|
|
|
|
|
ToonMaterial: ToonMaterial,
|
2021-02-26 05:55:44 +08:00
|
|
|
|
Texture: Texture,
|
|
|
|
|
CubeTexture: CubeTexture,
|
2020-10-04 06:49:05 +08:00
|
|
|
|
Mesh: Mesh,
|
|
|
|
|
Box: Box,
|
|
|
|
|
Circle: Circle,
|
|
|
|
|
Cone: Cone,
|
|
|
|
|
Cylinder: Cylinder,
|
|
|
|
|
Dodecahedron: Dodecahedron,
|
|
|
|
|
Icosahedron: Icosahedron,
|
|
|
|
|
Lathe: Lathe,
|
|
|
|
|
Octahedron: Octahedron,
|
|
|
|
|
Plane: Plane,
|
|
|
|
|
Polyhedron: Polyhedron,
|
|
|
|
|
Ring: Ring,
|
|
|
|
|
Sphere: Sphere,
|
|
|
|
|
Tetrahedron: Tetrahedron,
|
|
|
|
|
Text: Text,
|
|
|
|
|
Torus: Torus,
|
|
|
|
|
TorusKnot: TorusKnot,
|
|
|
|
|
Tube: Tube,
|
|
|
|
|
Gem: Gem,
|
|
|
|
|
Image: Image,
|
|
|
|
|
InstancedMesh: InstancedMesh,
|
|
|
|
|
MirrorMesh: MirrorMesh,
|
|
|
|
|
RefractionMesh: RefractionMesh,
|
|
|
|
|
Sprite: Sprite,
|
2021-03-14 02:34:34 +08:00
|
|
|
|
GLTFModel: GLTF,
|
|
|
|
|
FBXModel: FBX,
|
2020-10-04 06:49:05 +08:00
|
|
|
|
EffectComposer: EffectComposer,
|
|
|
|
|
RenderPass: RenderPass,
|
|
|
|
|
BokehPass: BokehPass,
|
|
|
|
|
FilmPass: FilmPass,
|
2021-02-26 05:55:44 +08:00
|
|
|
|
FXAAPass: FXAAPass,
|
2020-10-04 06:49:05 +08:00
|
|
|
|
HalftonePass: HalftonePass,
|
2021-02-26 05:55:44 +08:00
|
|
|
|
SMAAPass: SMAAPass,
|
2021-04-05 04:02:11 +08:00
|
|
|
|
SSAOPass: SSAOPass,
|
2021-02-26 05:55:44 +08:00
|
|
|
|
TiltShiftPass: TiltShiftPass,
|
2020-10-04 06:49:05 +08:00
|
|
|
|
UnrealBloomPass: UnrealBloomPass,
|
2021-02-26 05:55:44 +08:00
|
|
|
|
ZoomBlurPass: ZoomBlurPass,
|
2020-10-04 06:49:05 +08:00
|
|
|
|
setFromProp: setFromProp,
|
2021-03-14 02:34:34 +08:00
|
|
|
|
bindProps: bindProps,
|
2021-03-08 04:17:46 +08:00
|
|
|
|
bindProp: bindProp,
|
2020-10-04 06:49:05 +08:00
|
|
|
|
propsValues: propsValues,
|
|
|
|
|
lerp: lerp,
|
2021-02-26 05:55:44 +08:00
|
|
|
|
lerpv2: lerpv2,
|
2020-10-04 06:49:05 +08:00
|
|
|
|
lerpv3: lerpv3,
|
2021-02-26 05:55:44 +08:00
|
|
|
|
limit: limit,
|
2021-04-05 04:02:11 +08:00
|
|
|
|
getMatcapUrl: getMatcapUrl
|
2020-10-04 06:49:05 +08:00
|
|
|
|
});
|
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
const TroisJSVuePlugin = {
|
|
|
|
|
install: (app) => {
|
|
|
|
|
const comps = [
|
2020-10-04 06:49:05 +08:00
|
|
|
|
'Camera',
|
2021-02-26 05:55:44 +08:00
|
|
|
|
'OrthographicCamera',
|
2020-10-04 06:49:05 +08:00
|
|
|
|
'PerspectiveCamera',
|
2021-04-05 04:02:11 +08:00
|
|
|
|
'Raycaster',
|
2020-10-04 06:49:05 +08:00
|
|
|
|
'Renderer',
|
|
|
|
|
'Scene',
|
2021-02-26 05:55:44 +08:00
|
|
|
|
'Group',
|
2020-10-04 06:49:05 +08:00
|
|
|
|
|
|
|
|
|
'AmbientLight',
|
|
|
|
|
'DirectionalLight',
|
2021-03-08 04:17:46 +08:00
|
|
|
|
'HemisphereLight',
|
2020-10-04 06:49:05 +08:00
|
|
|
|
'PointLight',
|
2021-03-08 04:17:46 +08:00
|
|
|
|
'RectAreaLight',
|
2020-10-04 06:49:05 +08:00
|
|
|
|
'SpotLight',
|
|
|
|
|
|
|
|
|
|
'BasicMaterial',
|
|
|
|
|
'LambertMaterial',
|
2021-02-26 05:55:44 +08:00
|
|
|
|
'MatcapMaterial',
|
2020-10-04 06:49:05 +08:00
|
|
|
|
'PhongMaterial',
|
|
|
|
|
'PhysicalMaterial',
|
|
|
|
|
'ShaderMaterial',
|
|
|
|
|
'StandardMaterial',
|
|
|
|
|
'SubSurfaceMaterial',
|
|
|
|
|
'ToonMaterial',
|
|
|
|
|
|
2021-02-26 05:55:44 +08:00
|
|
|
|
'Texture',
|
|
|
|
|
'CubeTexture',
|
2020-10-04 06:49:05 +08:00
|
|
|
|
|
|
|
|
|
'Mesh',
|
2021-03-14 02:34:34 +08:00
|
|
|
|
|
|
|
|
|
'Box', 'BoxGeometry',
|
|
|
|
|
'Circle', 'CircleGeometry',
|
|
|
|
|
'Cone', 'ConeGeometry',
|
|
|
|
|
'Cylinder', 'CylinderGeometry',
|
|
|
|
|
'Dodecahedron', 'DodecahedronGeometry',
|
|
|
|
|
'Icosahedron', 'IcosahedronGeometry',
|
|
|
|
|
'Lathe', 'LatheGeometry',
|
|
|
|
|
'Octahedron', 'OctahedronGeometry',
|
2020-10-04 06:49:05 +08:00
|
|
|
|
'Plane',
|
2021-03-14 02:34:34 +08:00
|
|
|
|
'Polyhedron', 'PolyhedronGeometry',
|
|
|
|
|
'Ring', 'RingGeometry',
|
|
|
|
|
'Sphere', 'SphereGeometry',
|
|
|
|
|
'Tetrahedron', 'TetrahedronGeometry',
|
2020-10-04 06:49:05 +08:00
|
|
|
|
'Text',
|
2021-03-14 02:34:34 +08:00
|
|
|
|
'Torus', 'TorusGeometry',
|
|
|
|
|
'TorusKnot', 'TorusKnotGeometry',
|
|
|
|
|
'Tube', 'TubeGeometry',
|
2020-10-04 06:49:05 +08:00
|
|
|
|
|
|
|
|
|
'Gem',
|
|
|
|
|
'Image',
|
|
|
|
|
'InstancedMesh',
|
|
|
|
|
'MirrorMesh',
|
|
|
|
|
'RefractionMesh',
|
|
|
|
|
'Sprite',
|
|
|
|
|
|
2021-03-14 02:34:34 +08:00
|
|
|
|
'FBXModel',
|
|
|
|
|
'GLTFModel',
|
|
|
|
|
|
2020-10-04 06:49:05 +08:00
|
|
|
|
'BokehPass',
|
|
|
|
|
'EffectComposer',
|
|
|
|
|
'FilmPass',
|
2021-02-26 05:55:44 +08:00
|
|
|
|
'FXAAPass',
|
2020-10-04 06:49:05 +08:00
|
|
|
|
'HalftonePass',
|
|
|
|
|
'RenderPass',
|
|
|
|
|
'SAOPass',
|
2021-02-26 05:55:44 +08:00
|
|
|
|
'SMAAPass',
|
2021-04-05 04:02:11 +08:00
|
|
|
|
'SSAOPass',
|
2021-02-26 05:55:44 +08:00
|
|
|
|
'TiltShiftPass',
|
2020-10-04 06:49:05 +08:00
|
|
|
|
'UnrealBloomPass',
|
2021-02-26 05:55:44 +08:00
|
|
|
|
'ZoomBlurPass',
|
2020-10-04 06:49:05 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
'GLTFViewer',
|
|
|
|
|
];
|
2020-10-04 06:49:05 +08:00
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
comps.forEach(comp => {
|
2020-10-04 06:49:05 +08:00
|
|
|
|
app.component(comp, TROIS[comp]);
|
|
|
|
|
});
|
|
|
|
|
},
|
2020-09-17 05:54:14 +08:00
|
|
|
|
};
|
|
|
|
|
|
2021-03-08 04:17:46 +08:00
|
|
|
|
function createApp(params) {
|
|
|
|
|
return createApp$1(params).use(TroisJSVuePlugin);
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-05 04:02:11 +08:00
|
|
|
|
export { AmbientLight, BasicMaterial, BokehPass, Box, BoxGeometry, PerspectiveCamera as Camera, Circle, CircleGeometry, Cone, ConeGeometry, CubeTexture, Cylinder, CylinderGeometry, DirectionalLight, Dodecahedron, DodecahedronGeometry, EffectComposer, FBX as FBXModel, FXAAPass, FilmPass, GLTF as GLTFModel, Gem, Group, HalftonePass, HemisphereLight, Icosahedron, IcosahedronGeometry, Image, InstancedMesh, LambertMaterial, Lathe, LatheGeometry, MatcapMaterial, Mesh, MirrorMesh, Object3D, Octahedron, OctahedronGeometry, OrthographicCamera, PerspectiveCamera, PhongMaterial, PhysicalMaterial, Plane, PointLight, Polyhedron, PolyhedronGeometry, Raycaster, RectAreaLight, RefractionMesh, RenderPass, Renderer, Ring, RingGeometry, SMAAPass, SSAOPass, Scene, ShaderMaterial, Sphere, SphereGeometry, SpotLight, Sprite, StandardMaterial, SubSurfaceMaterial, Tetrahedron, TetrahedronGeometry, Text, Texture, TiltShiftPass, ToonMaterial, Torus, TorusGeometry, TorusKnot, TorusKnotGeometry, TroisJSVuePlugin, Tube, TubeGeometry, UnrealBloomPass, ZoomBlurPass, bindProp, bindProps, createApp, getMatcapUrl, lerp, lerpv2, lerpv3, limit, propsValues, setFromProp };
|
2020-09-17 05:54:14 +08:00
|
|
|
|
//# sourceMappingURL=trois.module.js.map
|