<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
<title>Object3D 的拾取</title>
<meta name="description" content="使用 getObject3DByContainerPos 方法,对 Object3D 对象进行拾取。">
<link rel="stylesheet" href="https://a.amap.com/jsapi_demos/static/demo-center/css/demo-center.css"/>
<style>
html, body, #container { margin: 0; width: 100%; height: 100%; }
.info span { color: #0288d1; }
</style>
</head>
<body>
<div id="container"></div>
<div class="info" style="min-width: 350px;">
<h4>Object3D 拾取信息</h4>
<p>选中的 Mesh ID:<span id="mesh-id">--</span></p>
<p>选中的 face 所在的索引:<span id="face-index">--</span></p>
<p>交叉点距透视原点的距离:<span id="distance">--</span></p>
<p>与拾取对象的交叉点:
<span id="cross-point">--</span>
</p>
</div>
<script src="//cache.amap.com/lbs/static/es5.min.js"></script>
<script src="//webapi.amap.com/maps?v=1.4.15&key=您申请的key值&plugin=Map3D"></script>
<script>
// 创建 3D 底图
var map = new AMap.Map('container', {
viewMode: '3D', // 开启 3D 模式
pitch: 55,
rotation: 35,
center: [116.39756, 39.910215],
features: ['bg', 'road'],
zoom: 15
});
map.AmbientLight = new AMap.Lights.AmbientLight([1, 1, 1], 0.5);
map.DirectionLight = new AMap.Lights.DirectionLight([1, -1, 2], [1, 1, 1], 0.8);
// 添加 Object3DLayer 图层,用于添加 3DObject 对象
var object3Dlayer = new AMap.Object3DLayer();
map.add(object3Dlayer);
var meshes = [];
// 以不规则棱柱体 Prism 为例,添加至 3DObjectLayer 图层中
var paths = [
[
[116.395951, 39.907129],
[116.399127, 39.907178],
[116.399534, 39.900413],
[116.396316, 39.900331]
],
[
[116.391531, 39.922912],
[116.401938, 39.923241],
[116.402431, 39.913334],
[116.398354, 39.913103],
[116.398311, 39.912659],
[116.396273, 39.912643],
[116.396101, 39.913108],
[116.392067, 39.912959]
]
];
// Object3D.Mesh 的 color 分别是[r, g, b, a],每个分量只支持 [0 - 1] 区间,
var color = [100 / 255, 150 / 255, 230 / 255, 0.9];
var selectColor = [255 / 255, 245 / 255, 47 / 255, 0.9];
function initMesh() {
paths.forEach(function (path) {
var bounds = path.map(function (p) {
return new AMap.LngLat(p[0], p[1]);
});
// 创建 Object3D.Mesh 对象
var mesh = new AMap.Object3D.Mesh();
meshes.push(mesh);
var geometry = mesh.geometry;
var vertices = geometry.vertices;
var vertexColors = geometry.vertexColors;
var faces = geometry.faces;
var vertexLength = bounds.length * 2;
var verArr = [];
// 设置侧面
bounds.forEach(function (lngLat, index) {
var g20 = map.lngLatToGeodeticCoord(lngLat);
verArr.push([g20.x, g20.y]);
// 构建顶点-底面顶点
vertices.push(g20.x, g20.y, 0);
// 构建顶点-顶面顶点
vertices.push(g20.x, g20.y, -1000);
// 设置底面顶点颜色
vertexColors.push.apply(vertexColors, color);
// 设置顶面顶点颜色
vertexColors.push.apply(vertexColors, color);
// 设置三角形面
var bottomIndex = index * 2;
var topIndex = bottomIndex + 1;
var nextBottomIndex = (bottomIndex + 2) % vertexLength;
var nextTopIndex = (bottomIndex + 3) % vertexLength;
//侧面三角形1
faces.push(bottomIndex, topIndex, nextTopIndex);
//侧面三角形2
faces.push(bottomIndex, nextTopIndex, nextBottomIndex);
});
// 设置顶面,根据顶点拆分三角形
var triangles = AMap.GeometryUtil.triangulateShape(verArr);
for (var v = 0; v < triangles.length; v += 3) {
var a = triangles[v];
var b = triangles[v + 2];
var c = triangles[v + 1];
faces.push(a * 2 + 1, b * 2 + 1, c * 2 + 1);
}
// 开启透明度支持
mesh.transparent = true;
// 添加至 3D 图层
object3Dlayer.add(mesh);
});
}
function updateMesh(obj) {
var mesh = meshes.find(function (mesh) {
return mesh == obj;
});
// 重置 Mesh 颜色
meshes.forEach(function (mesh) {
updateMeshColor(mesh, color);
});
// 更新选中 Mesh 的 vertexColors
if (mesh) {
updateMeshColor(mesh, selectColor);
}
}
function updateMeshColor(mesh, color) {
var vertexColors = mesh.geometry.vertexColors;
var len = vertexColors.length;
for (var i = 0; i < len / 4; i++) {
var r = color[0];
var g = color[1];
var b = color[2];
var a = color[3];
// 不能重新赋值,只允许修改内容
vertexColors.splice(i * 4, 4, r, g, b, a);
}
mesh.needUpdate = true;
mesh.reDraw();
}
// prism 拾取
map.on('mousemove', function (ev) {
var pixel = ev.pixel;
var px = new AMap.Pixel(pixel.x, pixel.y);
var obj = map.getObject3DByContainerPos(px, [object3Dlayer], false) || {};
// 选中的 face 所在的索引
var index = obj.index;
// 选中的 object3D 对象,这里为当前 Mesh
var object = obj.object;
// 被拾取到的对象和拾取射线的交叉点的3D坐标
var point = obj.point;
// 交叉点距透视原点的距离
var distance = obj.distance;
updateInfo(obj);
updateMesh(object);
});
function updateInfo(obj) {
var $meshId = document.getElementById('mesh-id');
var $faceIndex = document.getElementById('face-index');
var $crossPoint = document.getElementById('cross-point');
var $distance = document.getElementById('distance');
$meshId.innerHTML = (!isNil(obj.object) && !isNil(obj.object.id)) ? obj.object.id : '--';
$faceIndex.innerHTML = !isNil(obj.index) ? obj.index : '--';
$distance.innerHTML = !isNil(obj.distance) ? obj.distance : '--';
var p = '--';
if (obj.point) {
p = [
'',
'X: ' + obj.point[0],
'Y: ' + obj.point[1],
'Z: ' + obj.point[2]
].join('<br>');
}
$crossPoint.innerHTML = p;
}
function isNil(obj) {
return obj == undefined;
}
initMesh();
// updateMeshColor(meshes[0], selectColor);
</script>
</body>
</html>
订阅评论
0 评论