1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534 |
- import * as THREE from 'three';
- import {FontLoader} from 'three/addons/loaders/FontLoader.js';
- import {CinematicCamera} from 'three/addons/cameras/CinematicCamera.js';
- import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
- import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js';
- import { RenderPass } from 'three/addons/postprocessing/RenderPass.js';
- import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js';
- import { OutlinePass } from 'three/addons/postprocessing/OutlinePass.js';
- import { CSS3DRenderer } from 'three/addons/renderers/CSS3DRenderer.js';
- import { CSS2DRenderer } from 'three/addons/renderers/CSS2DRenderer.js';
- import { Storage as _Storage } from 'three/libs/Storage.js';
- import {unzipSync} from 'three/libs/fflate.module.js';
- console.log('Three.js version:', THREE.REVISION);
- // --------------------- 折叠 -----------------------
- //region Description
- //endregion
- function IOT3D() {
- console.log("-------------- IOT3D --------------")
- window.iot3d = this
- window.THREE = THREE; // Used by APP Scripts.
- window.FontLoader = FontLoader; // Used by APP Scripts.
- // window.VRButton = VRButton; // Used by APP Scripts.
- window.OrbitControls = OrbitControls; // Used by APP Scripts.
- window.CinematicCamera = CinematicCamera; // Used by APP Scripts.
- window.EffectComposer = EffectComposer; // Used by APP Scripts.
- window.RenderPass = RenderPass; // Used by APP Scripts.
- window.ShaderPass = ShaderPass; // Used by APP Scripts.
- window.OutlinePass = OutlinePass; // Used by APP Scripts.
- this.loading_open = function (time){
- //1000为遮罩层显示时长,若不传则一直显示,须调用关闭方法
- $.mask_fullscreen(time);
- }
- this.loading_close = function (){
- //关闭遮罩层
- $.mask_close_all();
- }
- this.loading_text = function (text){
- //关闭遮罩层
- $.mask_text(text);
- }
- this.loading_html = function (html){
- //关闭遮罩层
- $.mask_html(html);
- }
- //
- var self;
- THREE.Cache.enabled = true; //这是一个全局属性,只需要设置一次,供内部使用FileLoader的所有加载器使用。
- // 项目
- // var IOT3D_Url = "https://iot3d.baozhida.cn"
- // var IOT3D_Url = "https://iot3d.baozhida.cn"
- // if(url.indexOf("127.0.0.1") != -1){
- // IOT3D_Url = "http://127.0.0.1:6210"
- // }else {
- // IOT3D_Url = "https://iot3d.baozhida.cn"
- // }
- var clock = new THREE.Clock();
- // 公共
- var dom_width = 500, dom_height = 500;
- var camera, scene, dom, renderer, rendererCss2, rendererCss3,controls;
- var events = {};
- window.parkId = 0; // 园区ID
- var project; // 项目配置
- /// =- 选取
- var raycaster, mouse, INTERSECTED = null;
- // 变量初始化
- self = this;
- dom_width = window.innerWidth;
- dom_height = window.innerHeight;
- self.width = dom_width;
- self.height = dom_width;
- // var vrButton = VRButton.createButton( renderer ); // eslint-disable-line no-undef
- // --------------------- 初始化 -----------------------
- //region Description
- // 舞台
- scene = new THREE.Scene();
- // 相机
- camera = new THREE.PerspectiveCamera(45, dom_width / dom_height, 0.1, 3000);
- camera.position.set(-10, 10, 30);
- camera.lookAt(scene.position);
- window.mixer = new THREE.AnimationMixer( scene ); // 动画
- // HTML dom
- dom = document.getElementById("iot3d");
- //渲染器
- renderer = new THREE.WebGLRenderer({antialias: true});
- renderer.setPixelRatio(window.devicePixelRatio); // TODO: Use setPixelRatio()
- // renderer.outputEncoding = THREE.sRGBEncoding;
- renderer.shadowMap.enabled = true;// 阴影
- renderer.setSize( dom_width, dom_height );
- renderer.setAnimationLoop( animate );
- dom.appendChild(renderer.domElement);
- // rendererCss3
- rendererCss3 = new CSS3DRenderer();
- rendererCss3.setSize( dom.innerWidth, dom.innerHeight );
- rendererCss3.domElement.style.position = 'absolute';
- rendererCss3.domElement.style.top = 0;
- dom.appendChild( rendererCss3.domElement );
- // rendererCss2
- rendererCss2 = new CSS2DRenderer();
- rendererCss2.setSize( dom.innerWidth, dom.innerHeight );
- rendererCss2.domElement.style.position = 'absolute';
- rendererCss2.domElement.style.top = '0px';
- dom.appendChild( rendererCss2.domElement );
- // 加载到 网页
- document.body.appendChild(dom);
- window.addEventListener('resize', function () {
- self.setSize(window.innerWidth, window.innerHeight);
- });
- /// =- 选取
- raycaster = new THREE.Raycaster();
- mouse = new THREE.Vector2();
- var selectedObjects = [],compose,renderPass,outlinePass;
- // 鼠标移动 -轨道控制
- // var AutomaticRotationPerspective = [1,2,20] //自动旋转视角 0 【关闭】 1【360度旋转[1,旋转速度{1~9,2},俯视角度{0~100,20}]】
- var AutomaticRotationPerspectiveInterval = undefined // 定时任务
- var AutomaticRotationPerspectiveTally = 0 // 计数
- // - 鼠标移动视角
- controls = new OrbitControls(camera, renderer.domElement);
- // controls.addEventListener('change', animate); // use if there is no animation loop
- controls.dampingFactor = 0.25;
- controls.minDistance = 5; // 最小距离
- controls.maxDistance = 1000;
- controls.screenSpacePanning = false; // 允许相机平移
- // 设置最大和最小角度
- controls.maxPolarAngle = Math.PI / 2; // 最大角度 (90度) - 可视化平面
- controls.minPolarAngle = 0; // 最小角度 (0度) - 直接向下
- controls.target.set(0, 0, -2.2); // 控件的焦点,.object围绕它运行。它可以随时手动更新以更改控件的焦点。
- // controls.position0.set(200, 200, 500 )
- controls.update();
- // 检查 鼠标是否有操作
- renderer.domElement.addEventListener( 'pointerdown', function () {
- if(AutomaticRotationPerspectiveInterval !== undefined){
- clearInterval(AutomaticRotationPerspectiveInterval); // 停止定时任务的执行
- }
- AutomaticRotationPerspectiveTally = 0
- AutomaticRotationPerspectiveInterval = undefined
- } );
- // 定时 开始触发 自动旋转视角
- setInterval(() => {
- if(project === undefined || project.autoangle === undefined || project.autoangle === "None") return; // 直接跳过
- if(AutomaticRotationPerspectiveInterval === undefined){
- AutomaticRotationPerspectiveTally += 1
- if(AutomaticRotationPerspectiveTally === 3){
- console.log("project.autoangle:",project.autoangle)
- switch (project.autoangle) {
- case "Angle360": // 360度旋转
- self.AroundRotation(scene,project.autoangle_speed,project.autoangle_angle)
- break;
- case "Regainstate": // 回到原始视角
- self.Focus(self.GetScene())
- break;
- }
- }
- }
- }, 1000); // 每秒
- // 数据订阅
- window.pubSub = {
- list: {},
- // 订阅
- subscribe: function(key, fn) {
- if (!this.list[key]) this.list[key] = [];
- this.list[key].push(fn);
- },
- //取消订阅
- unsubscribe: function(key, fn) {
- let fnList = this.list[key];
- if (!fnList) return false;
- if (!fn) { // 不传入指定的方法,清空所用 key 下的订阅
- fnList && (fnList.length = 0);
- } else {
- fnList.forEach((item, index) => {
- item === fn && fnList.splice(index, 1);
- });
- }
- },
- // 发布
- publish: function(key, ...args) {
- if(this.list[key] === undefined) return;
- for (let fn of this.list[key]) fn.call(this, ...args);
- }
- }
- // this.storage.get(fxx)
- //
- // function fxx(xxx) {
- // console.log("fxx-------------------------",xxx)
- // }
- // 测试
- this.Test = function (rotationSpeed = 0.001) {
- console.log("Test-------------------------")
- return
- }
- // 测试
- function cubeDr(a, x, y, z) {
- var cubeGeo = new THREE.BoxGeometry(a, a, a);
- var cubeMat = new THREE.MeshPhongMaterial({
- color: 0xfff000 * Math.random()
- });
- var cube = new THREE.Mesh(cubeGeo, cubeMat);
- cube.position.set(x, y, z);
- cube.castShadow = true;
- scene.add(cube);
- return cube;
- }
- //endregion
- // --------------------- 核心 -----------------------
- //region Description
- // 核心方法
- //region Description
- // 舞台
- this.GetScene = function () {
- return scene
- }
- // 相机
- this.GetCamera = function () {
- return camera
- }
- //渲染器
- this.GetRenderer = function () {
- return renderer
- }
- // 获取 UUID 模型
- this.GetModelByUuid = function (uuid) {
- return scene.getObjectByProperty('uuid', uuid, true);
- }
- // 获取 UUID 模型 内部函数
- this.Model = function (uuid,fun) {
- fun(scene.getObjectByProperty('uuid', uuid, true));
- }
- // 设置显示比例
- this.setPixelRatio = function (pixelRatio) {
- renderer.setPixelRatio(pixelRatio);
- };
- // 设置大小
- this.setSize = function (width, height) {
- dom_width = width;
- dom_height = height;
- if (camera) {
- camera.aspect = dom_width / dom_height;
- camera.updateProjectionMatrix();
- }
- renderer.setSize(width, height);
- if ( rendererCss3 !== null ) {
- rendererCss3.setSize( dom.offsetWidth, dom.offsetHeight );
- }
- if ( rendererCss2 !== null ) {
- rendererCss2.setSize( dom.offsetWidth, dom.offsetHeight );
- }
- self.width = dom_width;
- self.height = dom_width;
- };
- //endregion
- // 鼠标
- //region Description
- //更新视角中心点
- this.orbitControls_target = function (position) {
- console.log("更新视角中心点:", position)
- controls.target.set(position.x, position.y, position.z); // 控件的焦点,.object围绕它运行。它可以随时手动更新以更改控件的焦点。
- controls.update();
- }
- // 计算场景最远距离,并控制参数
- function orbitControls_maxDistance() {
- // 计算场景中的包围盒
- function calculateSceneBoundingBox(scene) {
- const box = new THREE.Box3();
- scene.traverse((object) => {
- if (object.isMesh) {
- // 更新包围盒以包含当前对象的包围盒
- const objectBox = new THREE.Box3().setFromObject(object);
- box.union(objectBox);
- }
- });
- return box;
- }
- // 计算场景的包围盒
- const boundingBox = calculateSceneBoundingBox(scene);
- // 获取包围盒的尺寸
- const size = new THREE.Vector3();
- boundingBox.getSize(size);
- // 获取包围盒的中心
- const center = new THREE.Vector3();
- boundingBox.getCenter(center);
- // 计算最大尺寸距离 (从中心到某个角的距离)
- const maxDistance = center.distanceTo(boundingBox.max);
- // console.log("从中心到最远角的距离:", maxDistance);
- controls.maxDistance = maxDistance * 10;
- }
- // 鼠标选择初始化
- var OutlinePass_selectedObjects_Map = new Map();
- function OutlinePass_inte(){
- // console.log("OutlinePass_inte")
- // 清空所有选项
- selectedObjects = []
- self.Model_Selected_Clear()
- camera.lookAt(scene.position);
- compose = new EffectComposer(renderer);
- renderPass = new RenderPass(scene, camera);
- outlinePass = new OutlinePass(new THREE.Vector2(window.innerWidth,window.innerHeight),scene,camera);
- outlinePass.renderToScreen = true;
- outlinePass.selectedObjects = selectedObjects;
- compose.addPass(renderPass);
- compose.addPass(outlinePass);
- // https://threejs.org/examples/?q=webgl_postprocessing_outline#webgl_postprocessing_outline
- outlinePass.renderToScreen = true;
- outlinePass.edgeStrength = 3 //粗 0.01, 10
- outlinePass.edgeGlow = 1 //发光 0.0, 1
- outlinePass.edgeThickness = 2 //光晕粗 1, 4
- outlinePass.pulsePeriod = 0 //闪烁 0.0, 5
- outlinePass.usePatternTexture = false //是否使用贴图
- let visibleEdgeColor = '#00a1fd'; // 选择颜色
- let hiddenEdgeColor = '#00a1fd'; //遮挡部分颜色
- outlinePass.visibleEdgeColor.set(visibleEdgeColor);
- outlinePass.hiddenEdgeColor.set(hiddenEdgeColor);
- // let light = new THREE.AmbientLight(0x333333);
- // scene.add(light);
- //
- // 这里没有 渲染会报错
- let light = new THREE.SpotLight(0xFFFFFF);
- light.position.set(0, 40, 30);
- light.castShadow = true;
- light.shadow.mapSize.height = 1;
- light.shadow.mapSize.width = 1;
- light.angle = 0;
- scene.add(light);
- // light = new THREE.HemisphereLight(0xffffff, 0x444444, 0.6);
- // light.position.set(0, 200, 0);
- // scene.add(light);
- // const light = new THREE.DirectionalLight( 0xffffff, 0.6 );
- // light.position.set( 1, 1, 1 );
- // light.castShadow = true;
- // light.shadow.mapSize.width = 1024;
- // light.shadow.mapSize.height = 1024;
- //
- // const d = 10;
- //
- // light.shadow.camera.left = - d;
- // light.shadow.camera.right = d;
- // light.shadow.camera.top = d;
- // light.shadow.camera.bottom = - d;
- // light.shadow.camera.far = 1000;
- //
- // scene.add( light );
- }
- // 刷新
- function OutlinePass_selectedObjects_Refresh() {
- if (outlinePass == undefined) return;
- selectedObjects = [];
- OutlinePass_selectedObjects_Map.forEach(function(value, key) {
- // console.log(key, value);
- selectedObjects.push( value );
- })
- if (INTERSECTED != null){
- if(!OutlinePass_selectedObjects_Map.has(INTERSECTED.uuid)){
- selectedObjects.push( INTERSECTED );
- }
- }
- // console.log("selectedObjects:",selectedObjects)
- outlinePass.selectedObjects = selectedObjects;
- // render()
- }
- // 选中配置 选择颜色 ,遮挡部分颜色
- this.Model_Selected_Config = function(visibleEdgeColor="#00ff18",hiddenEdgeColor="#ff0000") {
- outlinePass.visibleEdgeColor.set(visibleEdgeColor);
- outlinePass.hiddenEdgeColor.set(hiddenEdgeColor);
- }
- // 添加
- this.Model_Selected_Add = function(Model) {
- OutlinePass_selectedObjects_Map.set(Model.uuid, Model)
- OutlinePass_selectedObjects_Refresh()
- }
- // 删除
- this.Model_Selected_Del = function(Model) {
- OutlinePass_selectedObjects_Map.delete(Model.uuid)
- OutlinePass_selectedObjects_Refresh()
- }
- // 清空
- this.Model_Selected_Clear = function() {
- OutlinePass_selectedObjects_Map.clear()
- OutlinePass_selectedObjects_Refresh()
- }
- //endregion
- // ------------------------------ 运动 ---------------------------------------------
- // 聚焦物体 -
- var startMove_is = false
- // 聚焦物体 - V1
- // this.startFocus = function (ob,MoveTime=1) {
- //
- // if(startMove_is) {
- // console.log("任务还没结束,不能开始新任务!")
- // return;
- // }
- // startMove_is = true // 开始
- // // if(ob.type != "Group") {
- // // console.log("Group != ")
- // // startMove_is = false
- // // return;
- // // }
- // if(ob.children.length == 0) {
- // console.log("children.length == 0!")
- // startMove_is = false
- // return;
- // }
- // if(ob.children[0].type != "PerspectiveCamera") {
- // console.log("children[0].type != PerspectiveCamera")
- // startMove_is = false
- // return;
- // }
- // let MoveList = []
- // MoveList.push([camera.position.x,camera.position.y,camera.position.z])
- // // MoveList.push([ob.position.x,ob.position.y,ob.position.z])
- // // MoveList.push([ob.children[0].position.x + ob.position.x, ob.children[0].position.y + ob.position.y, ob.children[0].position.z + ob.position.z])
- // MoveList.push([ob.children[0].matrixWorld.elements[12], ob.children[0].matrixWorld.elements[13], ob.children[0].matrixWorld.elements[14]])
- // // MoveList.push([ob.matrixWorld.elements[12], ob.matrixWorld.elements[13], ob.matrixWorld.elements[14]])
- // console.log("MoveList:",MoveList)
- //
- // let MoveListCurve = []
- // for(var item of MoveList) {
- // MoveListCurve.push(new THREE.Vector3(item[0], item[1], item[2]))
- // }
- // let curve = new THREE.CatmullRomCurve3(MoveListCurve)
- //
- // var curveList = curve.getPoints(20 * MoveTime)
- // // console.log("curveList:",curveList)
- //
- // var testIndex = 0
- // var t = setInterval(function () {
- // if(!startMove_is) {
- // curveList = []
- // testIndex = 0
- //
- // clearTimeout(t) //停止 t 定时器
- // return
- // }
- // // 模仿管道的镜头推进
- // if (curveList.length !== 0) {
- // if (testIndex < curveList.length ) {
- //
- // const point = curveList[testIndex] //获取样条曲线指定点坐标,作为相机的位置
- // const pointBox = curveList[testIndex+2] //获取样条曲线指定点坐标
- //
- // camera.position.set(point.x, point.y , point.z)
- // camera.lookAt(ob.matrixWorld.elements[12], ob.matrixWorld.elements[13], ob.matrixWorld.elements[14])
- //
- // controls.target.set(ob.matrixWorld.elements[12], ob.matrixWorld.elements[13], ob.matrixWorld.elements[14]); // 控件的焦点,.object围绕它运行。它可以随时手动更新以更改控件的焦点。
- // controls.update();
- // // camera.lookAt(ob.position.x,ob.position.y,ob.position.z)
- // testIndex += 1
- // } else {
- // curveList = []
- // testIndex = 0
- //
- // clearTimeout(t) //停止 t 定时器
- // startMove_is = false
- //
- //
- // // 更新视角中心点
- // controls.target.set(ob.matrixWorld.elements[12], ob.matrixWorld.elements[13], ob.matrixWorld.elements[14]); // 控件的焦点,.object围绕它运行。它可以随时手动更新以更改控件的焦点。
- // controls.update();
- //
- // }
- // }
- //
- // render()
- // }, 50)
- //
- // return
- // }
- // 围绕旋转 ,围绕对象 , 旋转速度{1~9,2} , 俯视角度{0~100,20}
- this.AroundRotation = function (ob,anglespeed_ = 2,targetHeight = 20) {
- // 自动计算包围盒
- const box = new THREE.Box3().setFromObject(ob);
- const size = box.getSize(new THREE.Vector3());
- const center = box.getCenter(new THREE.Vector3());
- // const targetHeight = 20; // 俯视角度的高度
- const radius = Math.max(size.x, size.z) *1.2; // 基于包围盒计算半径
- let anglespeed = 0.001 * anglespeed_; // 旋转速度
- let angle = Math.atan2(camera.position.z - center.z, camera.position.x - center.x); // 当前相机角度
- // 设置相机位置的函数
- function updateCameraPosition() {
- camera.position.x = radius * Math.cos(angle);
- camera.position.z = radius * Math.sin(angle);
- camera.position.y = targetHeight; // 固定Y坐标高度
- camera.lookAt(center); // 始终朝向场景中心
- }
- // 定时循环
- AutomaticRotationPerspectiveInterval = setInterval(() => {
- angle += anglespeed; // 旋转速度
- updateCameraPosition();
- renderer.render(scene, camera);
- }, 1000 / 60); // 每秒60帧
- }
- // 聚焦物体 - V2
- this.Focus = function (ob) {
- // 计算物体的边界盒
- const box = new THREE.Box3().setFromObject(ob);
- const size = box.getSize(new THREE.Vector3());
- const distance = size.length() * 2.0; // 增加一些距离,以便能看得到
- // 按照目标物体的大小和 20 度俯视角度计算相机位置
- const pitchAngle = THREE.MathUtils.degToRad(20); // 转换为弧度 20
- // const yawAngle = THREE.MathUtils.degToRad(angle); // 旋转 90 度
- const yawAngle = ob.rotation._y
- const targetEnd = box.getCenter(new THREE.Vector3());
- const targetPosition = new THREE.Vector3(
- targetEnd.x + distance * Math.sin(yawAngle),
- targetEnd.y + distance * Math.sin(pitchAngle),
- targetEnd.z + distance * Math.cos(yawAngle)
- );
- let initialPosition = new THREE.Vector3();
- initialPosition.copy(camera.position); // 记录初始位置
- // 在动画开始前,确保相机在正确的初始位置
- // camera.position.copy(targetPosition);
- // controls.target.copy(target);
- // controls.update(); // 更新控件
- const targetStart = new THREE.Vector3(0, 0, 0); // 初始中心点
- // const targetEnd = new THREE.Vector3(1, 1, 1); // 目标中心点
- targetStart.x = controls.target.x
- targetStart.y = controls.target.y
- targetStart.z = controls.target.z
- // console.log("targetStart:",targetStart)
- // console.log("targetEnd:",targetEnd)
- // console.log("initialPosition:",initialPosition)
- // console.log("targetPosition:",targetPosition)
- const distancex = initialPosition.distanceTo(targetPosition);
- // console.log("运动距离:", distancex);
- if(startMove_is) {
- console.log("任务还没结束,不能开始新任务!")
- return;
- }
- startMove_is = true // 开始
- // 动画属性
- const animationDuration = distancex * 2; // 动画持续 2 秒
- let animationDurationTime = 0; // 动画开始时间
- var It = setInterval(function () {
- animationDurationTime += 1;
- const t = Math.min(animationDurationTime / animationDuration, 1); // 归一化
- // console.log("t:",animationDurationTime)
- // 插值计算新的相机位置
- camera.position.x = THREE.MathUtils.lerp(initialPosition.x, targetPosition.x, t);
- camera.position.y = THREE.MathUtils.lerp(initialPosition.y, targetPosition.y, t);
- camera.position.z = THREE.MathUtils.lerp(initialPosition.z, targetPosition.z, t);
- // 插值控制目标位置
- controls.target.x = THREE.MathUtils.lerp(targetStart.x, targetEnd.x, t);
- controls.target.y = THREE.MathUtils.lerp(targetStart.y, targetEnd.y, t);
- controls.target.z = THREE.MathUtils.lerp(targetStart.z, targetEnd.z, t);
- // 更新控件目标
- camera.lookAt(controls.target); // 始终看向目标
- controls.update(); // 更新控件以应用新位置和目标
- // render()
- if(animationDuration <= animationDurationTime || !startMove_is){
- startMove_is = false
- clearTimeout(It) //停止 t 定时器
- }
- }, 10)
- }
- // 聚焦物体运动 -
- // this.startFocusMotion = function (ob,MoveList,MoveTime=1) {
- // if(startMove_is) {
- // console.log("任务还没结束,不能开始新任务!")
- // return;
- // }
- // startMove_is = true // 开始
- //
- // console.log("MoveList:",MoveList)
- //
- // let MoveListCurve = []
- // for(var item of MoveList) {
- // MoveListCurve.push(new THREE.Vector3(item[0], item[1], item[2]))
- // }
- // let curve = new THREE.CatmullRomCurve3(MoveListCurve)
- //
- // var curveList = curve.getPoints(20 * MoveTime)
- // // console.log("curveList:",curveList)
- //
- // var testIndex = 0
- // var t = setInterval(function () {
- // if(!startMove_is) {
- // curveList = []
- // testIndex = 0
- //
- // clearTimeout(t) //停止 t 定时器
- // }
- // // 模仿管道的镜头推进
- // if (curveList.length !== 0) {
- // if (testIndex < curveList.length ) {
- //
- // const point = curveList[testIndex] //获取样条曲线指定点坐标,作为相机的位置
- //
- // camera.position.set(point.x, point.y , point.z)
- //
- // camera.lookAt(ob[0], ob[1], ob[2])
- // controls.target.set(ob[0], ob[1], ob[2]); // 控件的焦点,.object围绕它运行。它可以随时手动更新以更改控件的焦点。
- // controls.update();
- // // camera.lookAt(ob.position.x,ob.position.y,ob.position.z)
- // testIndex += 1
- // } else {
- // curveList = []
- // testIndex = 0
- //
- // clearTimeout(t) //停止 t 定时器
- // startMove_is = false
- //
- //
- // // 更新视角中心点
- // controls.target.set(ob[0], ob[1], ob[2]); // 控件的焦点,.object围绕它运行。它可以随时手动更新以更改控件的焦点。
- // controls.update();
- //
- // }
- // }
- //
- // render()
- // }, 50)
- //
- // return
- // }
- // 路径移动
- this.startMove = function (MoveList,MoveTime=1,orbitControls_target=[]) {
- if(startMove_is) {
- console.log("任务还没结束,不能开始新任务!")
- return;
- }
- startMove_is = true // 开始
- if(MoveList.length == 0) {
- console.log("数据异常!")
- startMove_is = false
- return;
- }
- if(MoveList[0].length != 3) {
- console.log("数据异常!")
- startMove_is = false
- return;
- }
- let MoveListCurve = []
- for(var item of MoveList) {
- MoveListCurve.push(new THREE.Vector3(item[0], item[1], item[2]))
- }
- let curve = new THREE.CatmullRomCurve3(MoveListCurve)
- var curveList = curve.getPoints(20 * MoveTime)
- // console.log("curveList:",curveList)
- var testIndex = 0
- var t = setInterval(function () {
- if(!startMove_is) {
- curveList = []
- testIndex = 0
- clearTimeout(t) //停止 t 定时器
- }
- // 模仿管道的镜头推进
- if (curveList.length !== 0) {
- if (testIndex < curveList.length - 2) {
- const point = curveList[testIndex] //获取样条曲线指定点坐标,作为相机的位置
- const pointBox = curveList[testIndex+2] //获取样条曲线指定点坐标
- camera.position.set(point.x, point.y , point.z)
- camera.lookAt(pointBox.x, pointBox.y , pointBox.z)
- testIndex += 1
- } else {
- curveList = []
- testIndex = 0
- clearTimeout(t) //停止 t 定时器
- startMove_is = false
- // 更新视角中心点
- if(orbitControls_target.length == 3){
- controls.target.set(orbitControls_target[0], orbitControls_target[1], orbitControls_target[2]); // 控件的焦点,.object围绕它运行。它可以随时手动更新以更改控件的焦点。
- controls.update();
- }
- }
- }
- // render()
- }, 50)
- return
- }
- // 停止移动
- this.stopMove = function () {
- startMove_is = false
- }
- // 渲染
- //region Description
- // ---------- 渲染 -----------
- // renderer.setAnimationLoop( render );
- var clock = new THREE.Clock(); // only used for animations
- // function render() {
- // // console.log("render")
- //
- // // 渲染方式
- // if(compose != undefined) {
- // if(selectedObjects.length > 0){
- // compose.render()
- // }else {
- // renderer.render(scene, camera);
- // }
- // }else {
- // renderer.render(scene, camera);
- // }
- //
- // if ( rendererCss2 !== null ) {
- // rendererCss2.render( scene, camera );
- // }
- // if ( rendererCss3 !== null ) {
- // rendererCss3.render( scene, camera );
- // }
- //
- // }
- // this.Render = function () {
- // render()
- // }
- // 渲染
- // let lastRender = performance.now();
- function animate() {
- // let timestamp = timestamp.now();
- // if (timestamp - lastRender < 1000 / 60) return; // 限制为 60fps
- // lastRender = timestamp;
- if(window.ScenePlane !== undefined){
- scene.add( window.ScenePlane );
- }
- // renderer.render(scene, camera);
- if(compose != undefined) {
- if(selectedObjects.length > 0){
- compose.render()
- }else {
- renderer.render(scene, camera);
- }
- }else {
- renderer.render(scene, camera);
- }
- if ( rendererCss2 !== null ) {
- rendererCss2.render( scene, camera );
- }
- if ( rendererCss3 !== null ) {
- rendererCss3.render( scene, camera );
- }
- // 更新控制器
- // controls.update(); // 仅在需要时调用,例如当你使相机移动时
- if(window.ScenePlane !== undefined){
- scene.remove( window.ScenePlane );
- }
- // Animations 动画
- if(window.mixer != null){
- window.mixer.update( clock.getDelta() );
- }
- // requestAnimationFrame(animate);
- }
- //endregion
- //endregion
- // --------------------- 鼠标事件 -----------------------
- //region Description
- var Model_onEvents = {
- mousemove:undefined,
- click:undefined,
- dblclick:undefined,
- mousedown:undefined,
- }
- // 递归寻找上级可触发
- function finde_parent_choice(Ob) {
- if (Ob.choice) {
- return {Ob:Ob,is:true}
- }
- if(Ob.parent.isScene) return null,false
- var Obf = finde_parent_choice(Ob.parent)
- if(Obf.is){
- return Obf
- }
- return {Ob:null,is:false}
- }
- // 移动
- dom.addEventListener('mousemove', onMouseMove, false);
- function onMouseMove(event) {
- // console.log("onMouseMove:",event)
- if (event.isPrimary === false) return;
- // 将鼠标位置归一化为设备坐标。x 和 y 方向的取值范围是 (-1 to +1)
- mouse.x = (event.clientX / dom_width) * 2 - 1;
- mouse.y = -(event.clientY / dom_height) * 2 + 1;
- raycaster.setFromCamera(mouse, camera);
- // 计算物体和射线的焦点
- var intersects = raycaster.intersectObjects(scene.children);
- // console.log("intersects:",intersects)
- if (intersects.length > 0){
- //
- for (let n = 0;intersects.length > n;n++) {
- let objectP = intersects[n].object
- // console.log("objectP:",objectP)
- if(objectP === undefined) break;
- let objectF = finde_parent_choice(objectP)
- // console.log("finde_parent_choice:",objectF)
- if (objectF.is) {
- if(INTERSECTED !== null && INTERSECTED.uuid === objectF.Ob.uuid) break;
- INTERSECTED = objectF.Ob;
- // console.log("移入:",INTERSECTED)
- if (Model_onEvents.mousemove !== undefined) Model_onEvents.mousemove(INTERSECTED)
- if(INTERSECTED.scriptsf !== undefined ){
- INTERSECTED.scriptsf.forEach(scriptf => {
- if(scriptf["onMouseMoveIn"] !== undefined){
- scriptf.onMouseMoveIn()
- }
- })
- }
- break;
- }
- // for (let xn = 0; 10 > xn; xn++) {
- // console.log(xn,"-objectP:",objectP)
- // if(objectP == null) break;
- // // if (objectP.type == "Object3D") {
- // if (INTERSECTED !== objectP) {
- // console.log("intersects[0].object:", intersects[0].object.parent)
- // if (objectP.choice === true) {
- // INTERSECTED = objectP;
- // if (Model_onEvents.mousemove !== undefined) Model_onEvents.mousemove(INTERSECTED)
- // break;
- // }
- // }
- // // }
- // objectP = objectP.parent
- // }
- }
- // console.log("onMouseMove:",INTERSECTED)
- }else {
- // console.log("移出:",INTERSECTED)
- if(INTERSECTED !== null && INTERSECTED.scriptsf !== undefined ){
- INTERSECTED.scriptsf.forEach(scriptf => {
- if(scriptf["onMouseMoveOut"] !== undefined){
- scriptf.onMouseMoveOut()
- }
- })
- }
- INTERSECTED = null;
- }
- OutlinePass_selectedObjects_Refresh()
- // render() // 可优化空间
- }
- this.Model_onMouseMove = function (fun) {
- Model_onEvents.mousemove = fun
- }
- //单击延时触发
- var clickTimeId,clickTimeIs = false;
- // 单击
- dom.addEventListener('click', onClick, false);
- function onClick(event) {
- // console.log("onClick:",INTERSECTED)
- if(INTERSECTED === null){return}
- // 取消上次延时未执行的方法
- clearTimeout(clickTimeId);
- const INTERSECTED_ = INTERSECTED
- //执行延时
- clickTimeId = setTimeout( function () {
- if (INTERSECTED_) {
- if(Model_onEvents.click != undefined) Model_onEvents.click(INTERSECTED)
- }
- // console.log("onClick:",INTERSECTED)
- if(INTERSECTED_.scriptsf !== undefined ){
- INTERSECTED_.scriptsf.forEach(scriptf => {
- if(scriptf["onClick"] !== undefined){
- scriptf.onClick()
- }
- })
- }
- // render()
- }, 250);
- }
- this.Model_onClick = function (fun) {
- Model_onEvents.click = fun
- }
- // 双击
- dom.addEventListener('dblclick', onDblclick, false);
- function onDblclick(event) {
- if(INTERSECTED === null){return}
- clearTimeout(clickTimeId); // 取消上次延时未执行的方法
- if (INTERSECTED) {
- if(Model_onEvents.dblclick != undefined) Model_onEvents.dblclick(INTERSECTED)
- }
- if(INTERSECTED.scriptsf !== undefined ){
- INTERSECTED.scriptsf.forEach(scriptf => {
- if(scriptf["onDblclick"] !== undefined){
- scriptf.onDblclick()
- }
- })
- }
- // render()
- }
- this.Model_onDblclick = function (fun) {
- Model_onEvents.dblclick = fun
- }
- // 右击---
- dom.addEventListener('contextmenu', onMousedown, false);
- function onMousedown(event) {
- if(clickTimeIs) return;
- clickTimeIs = true;
- setTimeout( function () {
- clickTimeIs = false;
- }, 2000); // 防止 反复触发退出
- if(Model_onEvents.mousedown != undefined) Model_onEvents.mousedown(INTERSECTED,event)
- onBackclick()
- // render()
- }
- this.Model_onMousedown = function (fun) {
- Model_onEvents.mousedown = fun
- }
- //
- // this.ondBlclick_Model = function (position) {
- // console.log("更新视角中心点:", position)
- // controls.target.set(position.x, position.y, position.z); // 控件的焦点,.object围绕它运行。它可以随时手动更新以更改控件的焦点。
- // controls.update();
- // }
- //endregion
- // --------------------- 项目 -----------------------
- //region Description
- // 本地调试模式
- this.LocalRun = function ( parkId = 0 ) {
- window.parkId = parkId
- new _Storage(function(result) {
- console.log(result);
- // scene = result.scene
- loadJson(result,"000000"+parkId)
- });
- }
- var loadProject_Map = []; //ProjectID 映射
- var Now_ProjectID = ""; // 当前 ProjectID
- this.load = function (){
- console.log("加载完毕")
- }
- // 加载项目
- this.LoadProject = function (ProjectID) {
- if(Now_ProjectID == ProjectID){ return }
- console.log('[' + /\d\d\:\d\d\:\d\d/.exec(new Date())[0] + ']', "加载 ProjectID:", ProjectID)
- // 是否加载与缓存过
- if (loadProject_Map[ProjectID] == undefined) {
- var httpRequest = new XMLHttpRequest();//第一步:建立所需的对象
- httpRequest.open('GET', './GetProject?T_ViewID=' + ProjectID, true);//第二步:打开连接 将请求参数写在url中 ps:"./Ptest.php?name=test&nameone=testone"
- httpRequest.send();//第三步:发送请求 将请求参数写在URL中
- httpRequest.onreadystatechange = function () {
- if (httpRequest.readyState == 4 && httpRequest.status == 200) {
- var json = JSON.parse(httpRequest.responseText);//获取到json字符串,还需解析
- console.log(json);
- if (json.Code != 200) {
- console.log("ProjectID 错误!", ProjectID)
- return "ProjectID 错误!"
- }
- var json = JSON.parse(json.Data.T_url);//获取到json字符串,还需解析
- console.log(json);
- window.parkList = json
- window.parkId = 0
- // 如果需要兼容低版本的浏览器,需要判断一下FileReader对象是否存在。
- if (window.FileReader) {
- blobLoad(ProjectID, window.parkList[window.parkId].T_url)
- } else {
- console.log('你的浏览器不支持读取文件');
- loadProject_Map[ProjectID] = src
- }
- }
- };
- } else {
- console.log('[' + /\d\d\:\d\d\:\d\d/.exec(new Date())[0] + ']', "缓存加载 ProjectID:", ProjectID)
- f_load(ProjectID)
- }
- }
- this.LoadLocal = function () {
- var httpRequest = new XMLHttpRequest();//第一步:建立所需的对象
- httpRequest.open('GET', './static/LocalProject/main.json', true);//第二步:打开连接 将请求参数写在url中 ps:"./Ptest.php?name=test&nameone=testone"
- httpRequest.responseType = 'json'; // 设置响应类型为 JSON
- httpRequest.onload = function() {
- if (httpRequest.status >= 200 && httpRequest.status < 300) {
- var jsonArray = httpRequest.response; // 直接获取 JSON 数组
- console.log("jsonArray:",jsonArray);
- window.parkList = jsonArray
- window.parkId = 0
- // 如果需要兼容低版本的浏览器,需要判断一下FileReader对象是否存在。
- if (window.FileReader) {
- blobLoad("00000", window.parkList[window.parkId].T_url)
- } else {
- console.log('你的浏览器不支持读取文件');
- loadProject_Map[ProjectID] = src
- }
- }
- };
- httpRequest.send();//第三步:发送请求 将请求参数写在URL中
- }
- // 解压并更新舞台
- function f_load(ProjectID) {
- console.log('[' + /\d\d\:\d\d\:\d\d/.exec(new Date())[0] + ']', "开始加载 file:", loadProject_Map[ProjectID])
- // 解压模型
- // var promise = fetch('../static/16635717199e4e03e8-8850-4152-9c08-9c203c882f7a.zip')
- var promise = fetch(loadProject_Map[ProjectID])
- .then((d) => d.arrayBuffer())
- promise = promise.then(function (data) {
- //响应的内容
- console.log("data:", data);
- const decompressed = unzipSync(new Uint8Array(data), {
- // You may optionally supply a filter for files. By default, all files in a
- // ZIP archive are extracted, but a filter can save resources by telling
- // the library not to decompress certain files
- filter(file) {
- // Don't decompress the massive image or any files larger than 10 MiB
- return file;
- }
- });
- console.log('[' + /\d\d\:\d\d\:\d\d/.exec(new Date())[0] + ']', "file:", decompressed['app.json'])
- var obj = JSON.parse(new TextDecoder().decode(decompressed['app.json']));
- loadJson(obj,ProjectID);// 加载场景
- // self.setSize(dom_width, dom_height);
- // orbitControls() // 鼠标移动 -轨道控制
- Now_ProjectID = ProjectID
- console.log('[' + /\d\d\:\d\d\:\d\d/.exec(new Date())[0] + ']', "JSON obj:", obj)
- }).catch(function (err) {
- console.log(err);
- })
- }
- // 导入 json
- function loadJson(json,ProjectID) {
- let loader = new THREE.ObjectLoader(); // 加载
- console.log("loadJson:", json)
- 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;
- console.log("rendererCss2:", rendererCss2)
- if ( rendererCss2 !== null ) {
- rendererCss2.clean()
- rendererCss3.clean()
- }
- scene = loader.parse(json.scene);
- // camera = loader.parse(json.camera);
- // console.log("json.camera:",json.camera)
- // console.log("camera:",camera)
- camera.position.x = json.camera.object.matrix[12]
- camera.position.y = json.camera.object.matrix[13]
- camera.position.z = json.camera.object.matrix[14]
- // camera.aspect = dom_width / dom_height;
- // camera.updateProjectionMatrix();
- // renderer.setSize(dom_width, dom_height);
- // 中心点
- controls.target.set(0, 0, 0); // 控件的焦点,.object围绕它运行。它可以随时手动更新以更改控件的焦点。
- controls.update();
- //////--------------
- // ScenePlane 场景平面
- if ( project.sceneplane !== undefined ){
- // console.log("sceneplane:",project.sceneplane)
- switch ( project.sceneplane ) {
- case 'None':
- window.ScenePlane = undefined
- break;
- case 'Grass': //草地平面
- const gt = new THREE.TextureLoader().load( './static/js/img/cd.jpg' );
- const gg = new THREE.PlaneGeometry( 300, 300 );
- const gm = new THREE.MeshPhongMaterial( { color: 0xffffff, map: gt } );
- window.ScenePlane = new THREE.Mesh( gg, gm );
- window.ScenePlane.rotation.x = - Math.PI / 2;
- // window.ScenePlane.rotation.y = -0.1
- window.ScenePlane.material.map.repeat.set( 64, 64 );
- window.ScenePlane.material.map.wrapS = THREE.RepeatWrapping;
- window.ScenePlane.material.map.wrapT = THREE.RepeatWrapping;
- window.ScenePlane.material.map.colorSpace = THREE.SRGBColorSpace;
- // note that because the ground does not cast a shadow, .castShadow is left false
- window.ScenePlane.receiveShadow = true;
- break;
- }
- }
- //// ------------
- events = {
- init: [],
- keydown: [],
- keyup: [],
- onMouseMoveIn: [], //鼠标移入
- onMouseMoveOut: [], //鼠标移入
- onClick: [], //鼠标单击
- onDblclick: [], //鼠标双击
- onBackclick: [], //鼠标右击 退后
- renderer: [],
- update: []
- };
- window.Getevents = function () {
- return events
- }
- var scriptWrapParams = 'iot3d,renderer,scene,camera';
- var scriptWrapResultObj = {};
- for (var eventKey in events) {
- scriptWrapParams += ',' + eventKey;
- scriptWrapResultObj[eventKey] = eventKey;
- }
- var scriptWrapResult = JSON.stringify(scriptWrapResultObj).replace(/\"/g, '');
- //执行代码
- // 递归遍历 所有脚本 并添加
- function traverseChildrenScript(object) {
- if ( object.scripts !== undefined && object.scripts.length > 0 ) {
- console.log("addObjectScript:",object.uuid,object.scripts)
- object.scriptsf = []
- var scripts = object.scripts;
- for ( var i = 0; i < scripts.length; i ++ ) {
- // 每个 script 代码
- var script = scripts[i];
- var functions = ( new Function( scriptWrapParams, script.source + '\nreturn ' + scriptWrapResult + ';' ).bind( object ) )( this, renderer, scene, camera );
- // console.log("functions.name",functions)
- object.scriptsf.push(functions)
- for ( var name in functions ) {
- // console.log("functions.name",name)
- if ( functions[ name ] === undefined ) continue;
- if ( events[ name ] === undefined ) {
- console.warn( 'APP.Player: Event type not supported (', name, ')' );
- continue;
- }
- if(name !== "update"){
- events[ name ].push( functions[ name ].bind( object ) );
- }else {
- var subSN = SeekParameterNodes(object)
- // console.log("subSN:",subSN)
- // 订阅
- pubSub.subscribe(subSN, data => {
- // console.log("subSN:",subSN,data);
- functions["update"].bind( object )( data )
- })
- }
- }
- }
- }
- // 遍历当前对象的所有子对象
- object.children.forEach(child => {
- traverseChildrenScript(child); // 递归调用
- });
- }
- traverseChildrenScript(scene)
- // console.log("events:", events)
- dispatch(events.init, arguments);
- console.log("加载完成 ProjectID:",ProjectID)
- // 场景加载后 视角归为
- self.setSize(window.innerWidth, window.innerHeight);
- orbitControls_maxDistance() // 计算场景最远距离,并控制参数
- OutlinePass_inte() // 鼠标选择初始化
- };
- // 文件缓存本地
- function blobLoad(ProjectID, src) {
- self.loading_open() //
- console.log('[' + /\d\d\:\d\d\:\d\d/.exec(new Date())[0] + ']', "文件缓存本地 :", ProjectID)
- // let self = this;
- const req = new XMLHttpRequest();
- req.open("GET", src, true);
- req.responseType = "blob";
- req.onload = function () {
- // Onload is triggered even on 404
- // so we need to check the status code
- if (this.status === 200) {
- const videoBlob = this.response;
- console.log("videoBlob:", videoBlob)
- const blobSrc = URL.createObjectURL(videoBlob); // IE10+
- console.log("blobSrc:", blobSrc)
- loadProject_Map[ProjectID] = blobSrc
- console.log('[' + /\d\d\:\d\d\:\d\d/.exec(new Date())[0] + ']', "文件缓存本地完成 ProjectID:", ProjectID)
- f_load(ProjectID)
- }
- self.loading_close()
- };
- //监听进度事件
- req.addEventListener("progress", function (evt) {
- if (evt.lengthComputable) {
- var percentComplete = evt.loaded / evt.total;
- //进度
- console.log('[' + /\d\d\:\d\d\:\d\d/.exec(new Date())[0] + ']', "ProjectID:", ProjectID, " 进度:", (percentComplete * 100) + "%")
- self.loading_text("模型加载中... "+parseInt(percentComplete * 100) + "%") // 替换内容
- }
- }, false);
- req.onerror = function () {
- // Error
- console.log("blobLoad Error!", src)
- loadProject_Map[ProjectID] = src
- };
- req.send();
- }
- //endregion
- // --------------------- 脚本 -----------------------
- //region Description
- // var time, startTime;
- // startTime = performance.now();
- // // 创建一个每秒执行一次的定时循环
- // setInterval(function() {
- // // 在这里编写需要重复执行的代码
- // time = performance.now();
- // const rendertime = { time: time - startTime }
- // // console.log("renderer:",rendertime)
- // try {
- // dispatch( events.renderer, rendertime);
- // } catch ( e ) {
- // console.error( ( e.message || e ), ( e.stack || '' ) );
- // }
- //
- // }, 1000); // 1000 毫秒 = 1 秒
- function dispatch( array, event ) {
- for ( var i = 0, l = array.length; i < l; i ++ ) {
- array[ i ]( event );
- }
- }
- //
- // function animate() {
- //
- // time = performance.now();
- //
- //
- //
- // prevTime = time;
- //
- // }
- // this.play = function () {
- //
- // if ( renderer.xr.enabled ) dom.append( vrButton );
- //
- // startTime = prevTime = performance.now();
- //
- // document.addEventListener( 'keydown', oneyDown );
- // document.addEventListener( 'keyup', onKeyUp );
- // document.addEventListener( 'pointerup', onPointerUp );
- // document.addEventListener( 'pointermove', onPointerMove );
- //
- // // dispatch( events.start, arguments );
- //
- // renderer.setAnimationLoop( animate );
- //
- // };
- this.render = function ( time ) {
- dispatch( events.update, { time: time * 1000, delta: 0 /* TODO */ } );
- renderer.render( scene, camera );
- };
- 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 onBackclick( event ) {
- dispatch( events.onBackclick, event );
- }
- function upDate( event ) {
- try {
- dispatch( events.update, event );
- } catch ( e ) {
- console.error( ( e.message || e ), ( e.stack || '' ) );
- }
- }
- //endregion
- // --------------------- 功能 -----------------------
- //region Description
- // this.BackgroundScene = function () {
- // var urls = [
- // './static/js/img/posx.jpg',
- // './static/js/img/negx.jpg',
- // './static/js/img/posy.jpg',
- // './static/js/img/negy.jpg',
- // './static/js/img/posz.jpg',
- // './static/js/img/negz.jpg'
- // ];
- //
- // var cubeLoader = new THREE.CubeTextureLoader();
- // scene.background = cubeLoader.load(urls);
- // setTimeout(function(){
- // render()
- // },3000);
- //
- // }
- // 屏幕坐标与世界坐标
- this.scene_3Dto2D = function (position) {
- const worldVector = new THREE.Vector3(
- position.x,
- position.y,
- position.z
- );
- const standardVec = worldVector.project(camera);
- const centerX = dom_width / 2;
- const centerY = dom_height / 2;
- const screenX = Math.round(centerX * standardVec.x + centerX);
- const screenY = Math.round(-centerY * standardVec.y + centerY);
- console.log("screen:", screenX, screenY)
- return screenX, screenY
- }
- //endregion
- console.log("window.runmode:",window.runmode)
- if(window.runmode === undefined) window.runmode = 2
- // 开始 加载场景
- if (window.runmode === 0){
- this.LocalRun()// 本地调试模式
- }else if(window.runmode === 1){
- this.LoadProject(window.T_ViewID) // 在线
- }else if(window.runmode === 2){
- this.LoadLocal() // 离线
- }
- }
- export {IOT3D};
- new IOT3D();
|