three 基础库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

305 lines
6.6 KiB

2 years ago
// import { CSS2DRenderer, CSS2DObject } from '/examples/jsm/renderers/CSS2DRenderer.js';
import { CSS3DRenderer, CSS3DObject } from '/examples/jsm/renderers/CSS3DRenderer.js';
var APP = {
Player: function () {
var renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(window.devicePixelRatio); // TODO: Use player.setPixelRatio()
renderer.outputEncoding = THREE.sRGBEncoding;
var css2DRenderer = createCSS2DRenderer()
var loader = new THREE.ObjectLoader();
var camera, scene;
var vrButton = VRButton.createButton(renderer); // eslint-disable-line no-undef
var events = {};
var dom = document.createElement('div');
dom.appendChild(renderer.domElement);
dom.appendChild(css2DRenderer.domElement);
this.dom = dom;
var waters=[];
this.width = 500;
this.height = 500;
function createCSS2DRenderer() {
css2DRenderer = new CSS3DRenderer();
css2DRenderer.setSize(window.innerWidth, window.innerHeight);
css2DRenderer.domElement.style.position = 'absolute';
css2DRenderer.domElement.style.top = '0px';//信息弹窗界面高度一半
css2DRenderer.domElement.style.left = '0px';//信息弹窗界面宽度一半
css2DRenderer.domElement.style.pointerEvents = 'none';
return css2DRenderer;
}
function createCSSLabel(text, parent) {
const labelDiv = document.createElement('div');
labelDiv.className = 'label';
labelDiv.name = "csslabeldiv"
labelDiv.textContent = text;
labelDiv.style.pointerEvents = 'none';//避免HTML标签遮挡三维场景的鼠标事件
const moonLabel = new CSS2DObject(labelDiv);
moonLabel.position.set(1, 2, 0);
moonLabel.name = "datalabel"
moonLabel.userData = { name: "datalable", id: "", url: "" }
return moonLabel;
}
this.load = function (json) {
var project = json.project;
if (project.vr !== undefined) renderer.xr.enabled = project.vr;
if (project.shadows !== undefined) renderer.shadowMap.enabled = project.shadows;
if (project.shadowType !== undefined) renderer.shadowMap.type = project.shadowType;
if (project.toneMapping !== undefined) renderer.toneMapping = project.toneMapping;
if (project.toneMappingExposure !== undefined) renderer.toneMappingExposure = project.toneMappingExposure;
if (project.physicallyCorrectLights !== undefined) renderer.physicallyCorrectLights = project.physicallyCorrectLights;
this.setScene(loader.parse(json.scene));
this.setCamera(loader.parse(json.camera));
events = {
init: [],
start: [],
stop: [],
keydown: [],
keyup: [],
pointerdown: [],
pointerup: [],
pointermove: [],
update: []
};
var scriptWrapParams = 'player,renderer,scene,camera';
var scriptWrapResultObj = {};
for (var eventKey in events) {
scriptWrapParams += ',' + eventKey;
scriptWrapResultObj[eventKey] = eventKey;
}
var scriptWrapResult = JSON.stringify(scriptWrapResultObj).replace(/\"/g, '');
for (var uuid in json.scripts) {
var object = scene.getObjectByProperty('uuid', uuid, true);
if (object === undefined) {
console.warn('APP.Player: Script without object.', uuid);
continue;
}
var scripts = json.scripts[uuid];
for (var i = 0; i < scripts.length; i++) {
var script = scripts[i];
var functions = (new Function(scriptWrapParams, script.source + '\nreturn ' + scriptWrapResult + ';').bind(object))(this, renderer, scene, camera);
for (var name in functions) {
if (functions[name] === undefined) continue;
if (events[name] === undefined) {
console.warn('APP.Player: Event type not supported (', name, ')');
continue;
}
events[name].push(functions[name].bind(object));
}
}
}
dispatch(events.init, arguments);
// this.initLable();
};
this.setCamera = function (value) {
camera = value;
camera.aspect = this.width / this.height;
camera.updateProjectionMatrix();
// this.camera = camera;
window.camera = camera;
};
this.setScene = function (value) {
scene = value;
window.scene = scene
};
this.addWater=function(water){
waters.push(water);
}
this.setPixelRatio = function (pixelRatio) {
renderer.setPixelRatio(pixelRatio);
};
this.setSize = function (width, height) {
this.width = width;
this.height = height;
if (camera) {
camera.aspect = this.width / this.height;
camera.updateProjectionMatrix();
}
renderer.setSize(width, height);
};
function dispatch(array, event) {
for (var i = 0, l = array.length; i < l; i++) {
array[i](event);
}
}
var time, startTime, prevTime;
function render(time) {
// dispatch(events.update, { time: time * 1000, delta: 0 /* TODO */ });
renderer.render(scene, camera);
if (css2DRenderer != null) {
css2DRenderer.render(scene, camera);
}
waters.forEach(water => {
// 播放特效
water.material.uniforms['time'].value += 1.0 / 60.0;
});
};
function animate() {
time = performance.now();
try {
dispatch(events.update, { time: time - startTime, delta: time - prevTime });
} catch (e) {
console.error((e.message || e), (e.stack || ''));
}
// renderer.render(scene, camera);
render(time);
prevTime = time;
}
this.play = function () {
if (renderer.xr.enabled) dom.append(vrButton);
startTime = prevTime = performance.now();
document.addEventListener('keydown', onKeyDown);
document.addEventListener('keyup', onKeyUp);
document.addEventListener('pointerdown', onPointerDown);
document.addEventListener('pointerup', onPointerUp);
document.addEventListener('pointermove', onPointerMove);
dispatch(events.start, arguments);
renderer.setAnimationLoop(animate);
};
this.stop = function () {
if (renderer.xr.enabled) vrButton.remove();
document.removeEventListener('keydown', onKeyDown);
document.removeEventListener('keyup', onKeyUp);
document.removeEventListener('pointerdown', onPointerDown);
document.removeEventListener('pointerup', onPointerUp);
document.removeEventListener('pointermove', onPointerMove);
dispatch(events.stop, arguments);
renderer.setAnimationLoop(null);
};
this.dispose = function () {
renderer.dispose();
camera = undefined;
scene = undefined;
};
//
function onKeyDown(event) {
dispatch(events.keydown, event);
}
function onKeyUp(event) {
dispatch(events.keyup, event);
}
function onPointerDown(event) {
dispatch(events.pointerdown, event);
}
function onPointerUp(event) {
dispatch(events.pointerup, event);
}
function onPointerMove(event) {
dispatch(events.pointermove, event);
}
}
};
export { APP };