12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529 |
- import * as THREE from 'three';
- // import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
- import {unzipSync} from './libs/fflate.module.js';
- import {FontLoader} from './jsm/loaders/FontLoader.js';
- import {CinematicCamera} from './jsm/cameras/CinematicCamera.js';
- import { OrbitControls } from './jsm/controls/OrbitControls.js';
- import { EffectComposer } from './jsm/postprocessing/EffectComposer.js';
- import { RenderPass } from './jsm/postprocessing/RenderPass.js';
- import { ShaderPass } from './jsm/postprocessing/ShaderPass.js';
- import { OutlinePass } from './jsm/postprocessing/OutlinePass.js';
- import { CSS3DRenderer } from './jsm/renderers/CSS3DRenderer.js';
- import { CSS2DRenderer } from './jsm/renderers/CSS2DRenderer.js';
- import { Storage as _Storage } from './libs/Storage.js';
- // --------------------- 折叠 -----------------------
- //region Description
- //endregion
- // iot3d = new IOT3D("iot3d",false); // 创建应用 (div_id,运行模式)
- function IOT3D(iot3d,runmode = 1) {
- window.iot3d = this
- window.runmode = runmode
- 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.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.send();//第三步:发送请求 将请求参数写在URL中
- httpRequest.onreadystatechange = function () {
- if (httpRequest.readyState == 4 && httpRequest.status == 200) {
- var json = JSON.parse(httpRequest.responseText);//获取到json字符串,还需解析
- console.log(json);
- window.parkList = json
- window.parkId = 0
- // 如果需要兼容低版本的浏览器,需要判断一下FileReader对象是否存在。
- if (window.FileReader) {
- blobLoad("00000", window.parkList[window.parkId].T_url)
- } else {
- console.log('你的浏览器不支持读取文件');
- loadProject_Map[ProjectID] = src
- }
- }
- };
- }
- // 解压并更新舞台
- 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;
- 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
- // 开始 加载场景
- if (runmode === 0){
- this.LocalRun()// 本地调试模式
- }else if(runmode === 1){
- this.LoadProject(window.T_ViewID) // 在线
- }else if(runmode === 2){
- this.LoadLocal() // 离线
- }
- }
- export {IOT3D};
|