用户登录
用户注册

分享至

webgl 球体

  • 作者: 生活就是生下来就要干活
  • 来源: 51数据库
  • 2020-10-01
一般获取景区上某个地址的标记,都是通过手动获取的。因为这些标记是无规律可寻的。所以我们就得考虑如何通过手动去获取3D图上的某个地址。人机交互时通过鼠标来操作,但鼠标是2D坐标,需要转换到对应的3D坐标上。Three.js为我们提供了Raycaster对象,我们可以很轻松的获取到一个2D点对应的3D坐标。先声明几个对象:<br>var raycasterCubeMesh;<br>var raycaster = new THREE.Raycaster();<br>var mouseVector = new THREE.Vector3();<br> var tags = [];<br><br>    这里需要在document上注册mousemove事件,实时获取鼠标对应的3D坐标。事件代码如下:<br>function onMouseMove(event){<br>            mouseVector.x = 2 * (event.clientX / window.innerHeight) - 1;<br>            mouseVector.y = - 2 * (event.clientY / window.innerHeight) + 1;<br><br>            raycaster.setFromCamera(mouseVector.clone(), camera);<br>            var intersects = raycaster.intersectObjects([cubeMesh]);<br><br>            if(raycasterCubeMesh){<br>                scene.remove(raycasterCubeMesh);<br>            }<br>            activePoint = null;<br>            if(intersects.length &gt; 0){<br>                var points = [];<br>                points.push(new THREE.Vector3(0, 0, 0));<br>                points.push(intersects[0].point);<br><br>                var mat = new THREE.MeshBasicMaterial({color: 0xff0000, transparent: true, opacity: 0.5});<br>                var sphereGeometry = new THREE.SphereGeometry(100);<br><br>                raycasterCubeMesh = new THREE.Mesh(sphereGeometry, mat);<br>                raycasterCubeMesh.position.copy(intersects[0].point);<br>                scene.add(raycasterCubeMesh);<br>                activePoint = intersects[0].point;<br>            }<br>        }<br><br>    代码中的大部分我已经在“如何实现对象交互”有介绍。这里只介绍和当前功能相关代码。intersects包含了鼠标当前位置下拾取到的3D对象集合。如果长度大于0,表示已经拾取到3D对象了。由于我们给intersectObjects函数只传递了cubeMesh对象(即全景图),所以intersects的长度肯定为1。intersects[0].point表示鼠标投射到cubeMesh对象表面上的坐标。这个坐标正是我们需要的3D标记点。所以我把这个点存储在activePoint。raycasterCubeMesh直接用交互点作为中心画的一个球体,鼠标移动这个球体也就跟着移动。<br>    鼠标移动时,能够获取到3D坐标了。如何确认这个坐标就是我们需要的?这里还得 给docuent注册一个mousedown事件。通过右键点击确认。注册事件如下:<br>function onMouseDown(event){<br>            if(event.buttons === 2 &amp;&amp;  activePoint){<br>                var tagMesh = new THREE.Mesh(new THREE.SphereGeometry(1), new THREE.MeshBasicMaterial({color: 0xffff00}));<br>                tagMesh.position.copy(activePoint);<br>                tagObject.add(tagMesh);<br><br>                var tagElement = document.createElement(&quot;div&quot;);<br>                tagElement.innerHTML = &quot;&lt;span&gt;标记&quot; + (tags.length + 1) + &quot;&lt;/span&gt;&quot;;<br>                tagElement.style.background = &quot;#00ff00&quot;;<br>                tagElement.style.position  = &quot;absolute&quot;;<br>                tagElement.addEventListener(&quot;click&quot;, function(evt){<br>                    alert(tagElement.innerText);<br>                });<br>                tagMesh.updateTag = function(){<br>                    if(isOffScreen(tagMesh, camera)){<br>                        tagElement.style.display = &quot;none&quot;;<br>                    }else{<br>                        tagElement.style.display = &quot;block&quot;;<br>                        var position = toScreenPosition(tagMesh, camera);<br>                        tagElement.style.left = position.x + &quot;px&quot;;<br>                        tagElement.style.top = position.y + &quot;px&quot;;<br>                    }<br>                }<br>                tagMesh.updateTag();<br>                document.getElementById(&quot;WebGL-output&quot;).appendChild(tagElement);<br>                tags.push(tagMesh);<br>            }<br>        }<br><br>    代码第一行有if判断,只有鼠标右键触发,并且activePoint不为空,才执行下面的代码。首先创建一个球体tagMesh并且设置坐标为activePoint,然后把它添加到tagObject对象中。tagObject是一个Object3D对象,用来存放所有的tagMesh,便于统一管理。<br>   接着代码创建了一个tagElement元素,设置样式和内容。并且附加到WebGL容器中。tagMesh自定义了updateTag函数,里边调用了两个特别重要的函数:toScreenPosition和isOffScreen。这里先不忙介绍updateTag函数。接下来通过介绍这两个函数来回答剩下的问题。



  为了保证任何一位上网用户都能顺畅地访问到web服务器中的内容,网络管理员在正式发布web信息之前往往需要设置一下iis服务器,以便确保单位的web网站可以始终如一地稳定运行。本文分析了web服务器故障的排除。
软件
前端设计
程序设计
Java相关