zoukankan      html  css  js  c++  java
  • 基于WebGL(ThingJS)的平面图导航,室内导航,3D聚焦 (二)

    前言

    基于WebGL架构的3D可视化平台—平面图导航(一)中已经完成了iframe面板与我们的3D场景的简单交互,下面我们继续完善并给iframe页加上鼠标悬停事件让iframe页的img标签和我们场景中的obj一起动起来。

    实现

    第一步,还是使用之前的场景接着上次的继续,先编写iframe页。给每一个img标签都加上onmouseover、onmouseout 事件。

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
        <style>
          	.total_image {
            	margin : 20px;
            }
            .total_image img{
                cursor: pointer;
                transition: all 0.6s;
                 50px;
            }
            .total_image img:hover{
                transform: scale(1.5);
                position:relative;
                z-index:100;
            }
        </style>
    </head>
    
    <body>
    <div class="total_image" style=" 500px;height: 280px;background-size: 100% auto">
        <img class="model_imag" src="发电室1.jpg" style="float: left;display: block; 85px;height: 84px" 
    			onclick="onClick('PowerGenerationGroup_01','viewPoint_1')" onmouseover="onMouseOver('PowerGenerationGroup_01','viewPoint_1')" onmouseout="onMouseOut('PowerGenerationGroup_01')">
                  
        <img class="model_imag" src="发电室2.jpg" style="float: left;display: block; 78px;height: 84px" 
    			onclick="onClick('PowerGenerationGroup_02','viewPoint_2')" onmouseover="onMouseOver('PowerGenerationGroup_02','viewPoint_2')" onmouseout="onMouseOut('PowerGenerationGroup_02')">
                  
        <img class="model_imag" src="发电室3.jpg" style="float: left;display: block;170px;height: 84px" 
    			onclick="onClick('PowerGenerationGroup_03','viewPoint_3')" onmouseover="onMouseOver('PowerGenerationGroup_03','viewPoint_3')" onmouseout="onMouseOut('PowerGenerationGroup_03')">
                  
        <img class="model_imag" src="发电室4.jpg" style="float: left;display: block;167px;height: 84px" 
    			onclick="onClick('PowerGenerationGroup_04','viewPoint_4')" onmouseover="onMouseOver('PowerGenerationGroup_04','viewPoint_4')" onmouseout="onMouseOut('PowerGenerationGroup_04')">
                  
        <div style="display: block;float: left; 100px;height: 145px;background-color:white">
            <img class="model_imag" src="办公室1.jpg" style="float: left;display: block;100px;height: 60px" 
    			onclick="onClick('Office','viewPoint_5')" onmouseover="onMouseOver('Office','viewPoint_5')" onmouseout="onMouseOut('Office')">
            <img class="model_imag" src="返回.png" style="float: left;display: block;100px;height: 80px" onclick="initViewPoint()">
        </div>
    
        <img class="model_imag" src="发电室5.jpg" style="float: right;display: block;123px" 
    			onclick="onClick('PowerGenerationGroup_05','viewPoint_8')" onmouseover="onMouseOver('PowerGenerationGroup_05','viewPoint_8')" onmouseout="onMouseOut('PowerGenerationGroup_05')"> 
                  
        <img class="model_imag" src="会议室1.jpg" style="float: left;display: block; 138px;height: 145px"  alt="" 
    			onclick="onClick('BoardRoom_01','viewPoint_6')" onmouseover="onMouseOver('BoardRoom_01','viewPoint_6')" onmouseout="onMouseOut('BoardRoom_01')">
                  
        <img class="model_imag" src="会议室2.jpg" style="float: left;display: block; 138px;height: 145px"  alt="" 
    			onclick="onClick('BoardRoom_02','viewPoint_7')" onmouseover="onMouseOver('BoardRoom_02','viewPoint_7')" onmouseout="onMouseOut('BoardRoom_02')"> 
    </div>
    
    <script>
        function onClick(viewPoint,target){
            window.parent.onClick(viewPoint,target);
        }
    	
    	function onMouseOver(targetObj,viewPoint){
        	window.parent.onMouseOver(targetObj,viewPoint);
        }
      	function onMouseOut(targetObj){
            window.parent.onMouseOut(targetObj);
        }
    	function initViewPoint(){
            window.parent.initViewPoint();
        }
    	
    </script>
    </body>
    </html>
    

      

    第二步,房间里的物体不要要让他“飞起来”,还要给他加一个“底座”。这里叫他SurveillanceCamera类,在自己编写类的时候一定要注意,想要当前类生效一定要继承THING.Thing,并且THING.factory.registerClass(‘ClassName’, ClassName);

    class SurveillanceCamera extends THING.Thing {
        constructor(app) {
            super(app);
            this.app = app;
            this.isFrustum = true;
            this.opacity = 1;
            this.color = 0xff00ff;
            this.vertices = [];
            this.near = 0.1;
            this.camera = null;
            this.node = new THREE.Object3D();
            this._frustum = new THREE.Frustum();
            this._projScreenMatrix = new THREE.Matrix4();
    
        }
    
        setup(param) {
            super.setup(param);
            this.fov = param['fov'];
            this.aspect = param['aspect'];
            this.far = param['far'];
            this.alpha = param['alpha'];
            this.lineAlpha = param['lineAlpha'];
            this.setupComplete(param);
        }
    
        setupComplete(param) {
            super.setupComplete(param);
            this.build();
        }
    
        build() {
            if (this.node.children.length > 0) {
                this.node.children = [];
            }
    
            if (this.camera != null) {
                this.camera = null;
            }
    
            var h = this.far * Math.tan(this.fov * 0.5 * 0.017453293);
            var w = this.aspect * h;
    
            var geometry = new THREE.Geometry();
            this.vertices = [new THREE.Vector3(0, 0, 0), new THREE.Vector3(w, -h, -this.far), new THREE.Vector3(w, h, -this.far), new THREE.Vector3(-w, h, -this.far), new THREE.Vector3(-w, -h, -this.far)];
            var faces = [new THREE.Face3(0, 1, 2), new THREE.Face3(0, 2, 3), new THREE.Face3(0, 3, 4), new THREE.Face3(0, 4, 1), new THREE.Face3(3, 4, 1), new THREE.Face3(3, 1, 2)];
            geometry.vertices = this.vertices;
    
            var line_mat = new THREE.LineBasicMaterial({
                color: "#b4f5f8",
                opacity: this.lineAlpha || 0.5,
            })
    
            var texture = THREE.ImageUtils.loadTexture("images/light2.png");
            texture.wrapS = THREE.RepeatWrapping;
            texture.wrapT = THREE.RepeatWrapping;
            var frustum_mat = new THREE.MeshBasicMaterial({
                color: "#0aa5ff",
                opacity: this.alpha || 0.5,
                transparent: true,
                side: THREE.DoubleSide,
            });
            var line_mesh = new THREE.Line(geometry, line_mat);
    
            var frustum_mesh = new THREE.Mesh(geometry, frustum_mat);
            geometry.faces = faces;
            this.node.add(frustum_mesh, line_mesh);
    
            this.camera = new THREE.PerspectiveCamera(this.fov, this.aspect, this.near, this.far);
            this.camera.position.set(this.position[0], this.position[1], this.position[2]);
            this.camera.rotation.copy(this.node.rotation);
    
            this.camera.updateMatrixWorld(true);
            this._updateFrustum();
        }
    
        setPosition() {
            this.camera.position.set(this.position[0], this.position[1], this.position[2]);
            this.camera.updateMatrixWorld(true);
            this._updateFrustum();
        }
    
        _updateFrustum() {
            if (this.camera) {
                this._projScreenMatrix.multiplyMatrices(this.camera.projectionMatrix, this.camera.matrixWorldInverse);
                this._frustum.setFromMatrix(this._projScreenMatrix);
            }
        }
    
        intersectsObject(object) {
            this._updateFrustum();
            return this._frustum.intersectsObject(object);
        }
    
        intersectsBox(box) {
            this._updateFrustum();
            return this._frustum.intersectsBox(box);
        }
    
        intersectsSphere(sphere) {
            this._updateFrustum();
            return this._frustum.intersectsSphere(sphere);
        }
    
        intersectsSprite(sprite) {
            this._updateFrustum();
            return this._frustum.intersectsSprite(sprite);
        }
    }
    
    THING.factory.registerClass('SurveillanceCamera', SurveillanceCamera);
    

      

    第三步,鼠标悬浮事件和鼠标离开事件,这里我们使用了之前创建的SurveillanceCamera类为obj加上了一个“底座”。

    //鼠标悬浮事件
    function onMouseOver(targetObj,viewPoint) {
        if (currentModule != null)
            return;
        overModule = app.query(targetObj)[0];
        overModule.style.boundingBox = true;
        overModule.moveTo({
            "offset": [0, 6, 0],
            "time": 80,
        });
        sCamera = app.create({
            type: 'SurveillanceCamera',
            name: 'SurveillanceCamera_',
            position:app.query(viewPoint)[0].position,
            fov: 65,
            aspect: 1.3,
            far: 6,
        });
        sCamera.angleX = 90;
        sCamera.style.opacity = 0.1;
    }
    //鼠标离开事件
    function onMouseOut(targetObj) {
        if (currentModule != null)
            return;
        if (sCamera) {
            sCamera.destroy();
            sCamera = null;
        }
        outModule = overModule;
        outModule.style.boundingBox = false;
        outModule.stopMoving();
        outModule.position = [0, 0, 0];
        outModule = null;
    }
    

      

    演示地址:http://www.thingjs.com/guide/sampleindex.html?name=/uploads/wechat/S2Vyd2lu/Demo_平面图导航.js

    总结

    利用iframe与ThingJS进行交互完成了平面图导航功能,通过自制的HTML界面,嵌入ThingJS的面板中,形成一个可自定义的导航界面,通过偏移实现相应的视觉效果。
    制作一个视锥,达到投放影像的效果,这里运用面向对象的方式是为了,能够更快捷的创建视锥,起到复用的作用。
    在制作过程中,将物体悬浮的过程时出现了问题,发现如果快速的操作鼠标,物体不会达到预期的视觉效果,例如,鼠标快速的在两个导航图之间切换时,对应的两个物体会不断的上升,尽管将上升与还原的速度加快,也依然无法解决问题。最后解决的办法是:新添加一个变量,将上一次悬浮的物体记录下来,就是文中的 outModule,通过对 outModule 单独操作来解决影响问题。

  • 相关阅读:
    精通搜索分析
    简析MonoTouch工作原理
    第二次结对编程作业
    第02组 团队Git现场编程实战
    第一次结对编程作业
    团队项目需求分析报告
    第一次个人编程作业
    软工第一次作业
    团队项目选题报告
    Rookey.Frame之数据库及缓存配置
  • 原文地址:https://www.cnblogs.com/thingjs/p/10273368.html
Copyright © 2011-2022 走看看