一般获取景区上某个地址的标记,都是通过手动获取的。因为这些标记是无规律可寻的。所以我们就得考虑如何通过手动去获取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 > 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 && 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("div");<br> tagElement.innerHTML = "<span>标记" + (tags.length + 1) + "</span>";<br> tagElement.style.background = "#00ff00";<br> tagElement.style.position = "absolute";<br> tagElement.addEventListener("click", function(evt){<br> alert(tagElement.innerText);<br> });<br> tagMesh.updateTag = function(){<br> if(isOffScreen(tagMesh, camera)){<br> tagElement.style.display = "none";<br> }else{<br> tagElement.style.display = "block";<br> var position = toScreenPosition(tagMesh, camera);<br> tagElement.style.left = position.x + "px";<br> tagElement.style.top = position.y + "px";<br> }<br> }<br> tagMesh.updateTag();<br> document.getElementById("WebGL-output").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服务器故障的排除。
Photoshop|
Dreamweaver|
SVG|
WebGL|
Visual Studio|
PowerDesigner|
Eclipse|
Git|
Apache Ant|
Atom|
Composer|
CodeSmith|
Flex|
Gradle|
Maven|
Sublime Text3|
SVN|
Tableau|
Vim|
Chrome开发者工具|
OpenGL|
Unity|
Direct3D|
用户登录
还没有账号?立即注册
用户注册
投稿取消
文章分类: |
|
还能输入300字
上传中....