gpt4 book ai didi

three.js - 使用 mapbox 更新 3d 模型位置

转载 作者:行者123 更新时间:2023-12-05 06:14:24 57 4
gpt4 key购买 nike

我使用带有 javascript 的 mapbox(使用 this tutorial )将 3D 模型放置在 map 中,我试图在单击按钮时更改对象的位置。不过,物体没有移动,我真的不知道如何修复它。

这是我为更改位置而编写的函数(当我点击按钮时我可以看到所有这些控制台日志,所以我知道不起作用的部分是实际位置更新本身):

function updateObjectLocation(id,newTransform) {
let objectLayer = map.getLayer(id);
if (typeof objectLayer === 'undefined') {
console.log('layer ' + id + ' does not exist');
} else {
console.log(objectLayer);
console.log(newTransform);
objectLayer.render = function(gl, matrix) {
var rotationX = new THREE.Matrix4().makeRotationAxis(
new THREE.Vector3(1,0,0),
newTransform.rotateX
);
var rotationY = new THREE.Matrix4().makeRotationAxis(
new THREE.Vector3(0,1,0),
newTransform.rotateY
);
var rotationZ = new THREE.Matrix4().makeRotationAxis(
new THREE.Vector3(0,0,1),
newTransform.rotateZ
);

var m = new THREE.Matrix4().fromArray(matrix);
var l = new THREE.Matrix4()
.makeTranslation(
newTransform.translateX,
newTransform.translateY,
newTransform.translateZ
)
.scale(
new THREE.Vector3(
newTransform.scale,
- newTransform.scale,
newTransform.scale
)
)
.multiply(rotationX)
.multiply(rotationY)
.multiply(rotationZ);

this.camera.projectionMatrix = m.multiply(l);
this.renderer.state.reset();
this.renderer.render(this.scene, this.camera);
this.map.triggerRepaint();
};
}
}

最佳答案

欢迎使用 Stackoverflow。解决方法就简单多了,只需要修改transformation,不需要重写render方法。在这里你有一个解决方案 how to move a 3D model

完整代码在这里

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Add a 3D model</title>
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
<script src="https://api.mapbox.com/mapbox-gl-js/v1.11.1/mapbox-gl.js"></script>
<link href="https://api.mapbox.com/mapbox-gl-js/v1.11.1/mapbox-gl.css" rel="stylesheet" />
<style>
body {
margin: 0;
padding: 0;
}

#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
#move {
display: block;
position: relative;
margin: 0px auto;
width: 50%;
height: 40px;
padding: 10px;
border: none;
border-radius: 3px;
font-size: 12px;
text-align: center;
color: #fff;
background: #ee8a65;
}
</style>
</head>
<body>
<script src="https://unpkg.com/three@0.106.2/build/three.min.js"></script>
<script src="https://unpkg.com/three@0.106.2/examples/js/loaders/GLTFLoader.js">
</script>
<div id="map"></div>

<button id="move">Move</button>
<script>
mapboxgl.accessToken = 'pk.eyJ1IjoianNjYXN0cm8iLCJhIjoiY2s2YzB6Z25kMDVhejNrbXNpcmtjNGtpbiJ9.28ynPf1Y5Q8EyB_moOHylw';
var map = (window.map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/light-v10',
zoom: 18,
center: [148.9819, -35.3981],
pitch: 60,
antialias: true // create the gl context with MSAA antialiasing, so custom layers are antialiased
}));

// parameters to ensure the model is georeferenced correctly on the map
var modelOrigin = [148.9819, -35.39847];
var modelOrigin2 = [148.9816, -35.39851];
var modelAltitude = 0;
var modelRotate = [Math.PI / 2, 0, 0];

var modelAsMercatorCoordinate = mapboxgl.MercatorCoordinate.fromLngLat(
modelOrigin,
modelAltitude
);

// transformation parameters to position, rotate and scale the 3D model onto the map
var modelTransform = {
translateX: modelAsMercatorCoordinate.x,
translateY: modelAsMercatorCoordinate.y,
translateZ: modelAsMercatorCoordinate.z,
rotateX: modelRotate[0],
rotateY: modelRotate[1],
rotateZ: modelRotate[2],
/* Since our 3D model is in real world meters, a scale transform needs to be
* applied since the CustomLayerInterface expects units in MercatorCoordinates.
*/
scale: modelAsMercatorCoordinate.meterInMercatorCoordinateUnits()
};

var THREE = window.THREE;

// configuration of the custom layer for a 3D model per the CustomLayerInterface
var customLayer = {
id: '3d-model',
type: 'custom',
renderingMode: '3d',
onAdd: function (map, gl) {
this.camera = new THREE.Camera();
this.scene = new THREE.Scene();

// create two three.js lights to illuminate the model
var directionalLight = new THREE.DirectionalLight(0xffffff);
directionalLight.position.set(0, -70, 100).normalize();
this.scene.add(directionalLight);

var directionalLight2 = new THREE.DirectionalLight(0xffffff);
directionalLight2.position.set(0, 70, 100).normalize();
this.scene.add(directionalLight2);

// use the three.js GLTF loader to add the 3D model to the three.js scene
var loader = new THREE.GLTFLoader();
loader.load(
'https://docs.mapbox.com/mapbox-gl-js/assets/34M_17/34M_17.gltf',
function (gltf) {
this.scene.add(gltf.scene);
}.bind(this)
);
this.map = map;

// use the Mapbox GL JS map canvas for three.js
this.renderer = new THREE.WebGLRenderer({
canvas: map.getCanvas(),
context: gl,
antialias: true
});

this.renderer.autoClear = false;
},
render: function (gl, matrix) {
var rotationX = new THREE.Matrix4().makeRotationAxis(
new THREE.Vector3(1, 0, 0),
modelTransform.rotateX
);
var rotationY = new THREE.Matrix4().makeRotationAxis(
new THREE.Vector3(0, 1, 0),
modelTransform.rotateY
);
var rotationZ = new THREE.Matrix4().makeRotationAxis(
new THREE.Vector3(0, 0, 1),
modelTransform.rotateZ
);

var m = new THREE.Matrix4().fromArray(matrix);
var l = new THREE.Matrix4()
.makeTranslation(
modelTransform.translateX,
modelTransform.translateY,
modelTransform.translateZ
)
.scale(
new THREE.Vector3(
modelTransform.scale,
-modelTransform.scale,
modelTransform.scale
)
)
.multiply(rotationX)
.multiply(rotationY)
.multiply(rotationZ);

this.camera.projectionMatrix = m.multiply(l);
this.renderer.state.reset();
this.renderer.render(this.scene, this.camera);
this.map.triggerRepaint();
}
};

map.on('style.load', function () {
map.addLayer(customLayer, 'waterway-label');
});

document.getElementById('move').addEventListener('click', function () {
// creating an event listener to modify the position to modelOrigin2
modelAsMercatorCoordinate = mapboxgl.MercatorCoordinate.fromLngLat(
modelOrigin2,
modelAltitude
);

// transformation parameters to position, rotate and scale the 3D model onto the map
modelTransform = {
translateX: modelAsMercatorCoordinate.x,
translateY: modelAsMercatorCoordinate.y,
translateZ: modelAsMercatorCoordinate.z,
rotateX: modelRotate[0],
rotateY: modelRotate[1],
rotateZ: modelRotate[2],
/* Since our 3D model is in real world meters, a scale transform needs to be
* applied since the CustomLayerInterface expects units in MercatorCoordinates.
*/
scale: modelAsMercatorCoordinate.meterInMercatorCoordinateUnits()
};

});
</script>

</body>
</html>

顺便说一句,如果你想在 Mapbox 和 Three.js 之间创建更具交互性的体验,但我建议你查看最新版本的 threebox。因为它使您能够根据需要添加任意数量的模型和 3D 图层,而且只需几行代码就可以完成下面的这些操作

        map.on('style.load', function () {
map.addLayer({
id: 'custom_layer',
type: 'custom',
renderingMode: '3d',
onAdd: function (map, mbxContext) {

window.tb = new Threebox(
map,
mbxContext,
{ defaultLights: true }
);

var options = {
obj: '/3D/soldier/soldier.glb',
type: 'gltf',
scale: 1,
units: 'meters',
rotation: { x: 90, y: 0, z: 0 } //default rotation
}

tb.loadObj(options, function (model) {
soldier = model.setCoords(origin);
tb.add(soldier);
})

},
render: function (gl, matrix) {
tb.update();
}
});
})

- 3D 模型内置和自定义动画

3D models built-in and custom animations

- 完全光线转换支持 MouseOver/Mouseout、选定、拖放、拖放和旋转、线框

MouseOver/Mouseout, Selected, Drag&Drop, Drag&Rotate, Wireframe

- 考虑高度的 CSS2D 工具提示和标签

CSS2D Tooltips and Labels that consider altitude

**- Three.js 和 Mapbox 相机与深度调整同步 **

Three.js and Mapbox cameras sync with depth adjustment

- 包括纪念碑的地理定位模型

Eiffel tower gif

关于three.js - 使用 mapbox 更新 3d 模型位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62904902/

57 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com