1,介绍

该示例使用的是 r95版本Three.js库。这里利用A*算法实现室内室外寻路、导航功能。

效果图如下:

2,主要说明

1,初始化路网

2,设置路障,我这里是使用鼠标点击设置路障,如下图

3,调用算法传入路网数据实现导航

3,源码

<!DOCTYPE html>
<html><head><title>Threejs中使用A*算法寻路导航,Threejs室内室外地图导航</title><script type="text/javascript" src="libs/three.js"></script><script type="text/javascript" src="libs/OrbitControls.js"></script><script type="text/javascript" charset="UTF-8" src="libs/other/Tween.min.js"></script><script type="text/javascript" charset="UTF-8" src="libs/three/loaders/GLTFLoader.js"></script><script type="text/javascript" src="libs/OBJLoader.js"></script><script type="text/javascript" src="libs/MTLLoader.js"></script><script type="text/javascript" src="libs/util.js"></script><script type="text/javascript" src="libs/util/dat.gui.js"></script><script type="text/javascript" src="libs/astar.js"></script><style>body {margin: 0;overflow: hidden;}</style></head><body><div id="webgl-output"></div><script type="text/javascript">var camera;var renderer;var clock = new THREE.Clock();var mixer = new THREE.AnimationMixer();var clipAction;var animationClip;var length = 36;var ws = 2;var graph = []; // 记录地图var meshArr = new Array(); // 记录障碍物对象数据var meshxy = [{"x": 35,"y": 7},{"x": 35,"y": 7},{"x": 35,"y": 9},{"x": 35,"y": 11},{"x": 29,"y": 11},{"x": 29,"y": 13},{"x": 33,"y": 13},{"x": 33,"y": 11},{"x": 33,"y": 9},{"x": 33,"y": 5},{"x": 33,"y": 7},{"x": 29,"y": 5},{"x": 31,"y": 5},{"x": 31,"y": 11},{"x": 27,"y": 5},{"x": 25,"y": 5},{"x": 25,"y": 7},{"x": 25,"y": 9},{"x": 25,"y": 11},{"x": 25,"y": 13},{"x": 23,"y": 9},{"x": 21,"y": 9},{"x": 19,"y": 9},{"x": 19,"y": 11},{"x": 19,"y": 13},{"x": 15,"y": 9},{"x": 13,"y": 7},{"x": 13,"y": 9},{"x": 13,"y": 11},{"x": 11,"y": 7},{"x": 13,"y": 5},{"x": 11,"y": 5},{"x": 7,"y": 5},{"x": 5,"y": 5},{"x": 5,"y": 7},{"x": 7,"y": 7},{"x": 7,"y": 9},{"x": 7,"y": 11},{"x": 5,"y": 11},{"x": 5,"y": 9},{"x": 7,"y": 15},{"x": 7,"y": 17},{"x": 7,"y": 19},{"x": 11,"y": 23},{"x": 11,"y": 17},{"x": 11,"y": 21},{"x": 11,"y": 19},{"x": 17,"y": 25},{"x": 17,"y": 27},{"x": 17,"y": 29},{"x": 19,"y": 25},{"x": 21,"y": 25},{"x": 17,"y": 21},{"x": 17,"y": 23},{"x": 17,"y": 19},{"x": 15,"y": 19},{"x": 13,"y": 19},{"x": 7,"y": 29},{"x": 7,"y": 31},{"x": 7,"y": 33},{"x": 9,"y": 33},{"x": 13,"y": 33},{"x": 11,"y": 33},{"x": 13,"y": 31},{"x": 13,"y": 29},{"x": 15,"y": 33},{"x": 17,"y": 33},{"x": 19,"y": 33},{"x": 21,"y": 33},{"x": 25,"y": 29},{"x": 25,"y": 31},{"x": 25,"y": 33},{"x": 27,"y": 29},{"x": 29,"y": 29},{"x": 29,"y": 23},{"x": 27,"y": 23},{"x": 25,"y": 23},{"x": 29,"y": 21},{"x": 29,"y": 19},{"x": 33,"y": 19},{"x": 33,"y": 21},{"x": 33,"y": 23},{"x": 33,"y": 25},{"x": 33,"y": 27},{"x": 33,"y": 29},{"x": 33,"y": 31},{"x": 33,"y": 33},{"x": 31,"y": 35},{"x": 29,"y": 35},{"x": 27,"y": 35},{"x": 25,"y": 35},{"x": 7,"y": 23},{"x": 11,"y": 15},{"x": 9,"y": 15},{"x": 35,"y": 9},{"x": 35,"y": 11},{"x": 29,"y": 11},{"x": 29,"y": 13},{"x": 33,"y": 13},{"x": 33,"y": 11},{"x": 33,"y": 9},{"x": 33,"y": 5},{"x": 33,"y": 7},{"x": 29,"y": 5},{"x": 31,"y": 5},{"x": 31,"y": 11},{"x": 27,"y": 5},{"x": 25,"y": 5},{"x": 25,"y": 7},{"x": 25,"y": 9},{"x": 25,"y": 11},{"x": 25,"y": 13},{"x": 23,"y": 9},{"x": 21,"y": 9},{"x": 19,"y": 9},{"x": 19,"y": 11},{"x": 19,"y": 13},{"x": 15,"y": 9},{"x": 13,"y": 7},{"x": 13,"y": 9},{"x": 13,"y": 11},{"x": 11,"y": 7},{"x": 13,"y": 5},{"x": 11,"y": 5},{"x": 7,"y": 5},{"x": 5,"y": 5},{"x": 5,"y": 7},{"x": 7,"y": 7},{"x": 7,"y": 9},{"x": 7,"y": 11},{"x": 5,"y": 11},{"x": 5,"y": 9},{"x": 7,"y": 15},{"x": 7,"y": 17},{"x": 7,"y": 19},{"x": 11,"y": 23},{"x": 11,"y": 17},{"x": 11,"y": 21},{"x": 11,"y": 19},{"x": 17,"y": 25},{"x": 17,"y": 27},{"x": 17,"y": 29},{"x": 19,"y": 25},{"x": 21,"y": 25},{"x": 17,"y": 21},{"x": 17,"y": 23},{"x": 17,"y": 19},{"x": 15,"y": 19},{"x": 13,"y": 19},{"x": 7,"y": 29},{"x": 7,"y": 31},{"x": 7,"y": 33},{"x": 9,"y": 33},{"x": 13,"y": 33},{"x": 11,"y": 33},{"x": 13,"y": 31},{"x": 13,"y": 29},{"x": 15,"y": 33},{"x": 17,"y": 33},{"x": 19,"y": 33},{"x": 21,"y": 33},{"x": 25,"y": 29},{"x": 25,"y": 31},{"x": 25,"y": 33},{"x": 27,"y": 29},{"x": 29,"y": 29},{"x": 29,"y": 23},{"x": 27,"y": 23},{"x": 25,"y": 23},{"x": 29,"y": 21},{"x": 29,"y": 19},{"x": 33,"y": 19},{"x": 33,"y": 21},{"x": 33,"y": 23},{"x": 33,"y": 25},{"x": 33,"y": 27},{"x": 33,"y": 29},{"x": 33,"y": 31},{"x": 33,"y": 33},{"x": 31,"y": 35},{"x": 29,"y": 35},{"x": 27,"y": 35},{"x": 25,"y": 35},{"x": 7,"y": 23},{"x": 11,"y": 15},{"x": 9,"y": 15},{"x": 35,"y": 9},{"x": 35,"y": 11},{"x": 29,"y": 11},{"x": 29,"y": 13},{"x": 33,"y": 13},{"x": 33,"y": 11},{"x": 33,"y": 9},{"x": 33,"y": 5},{"x": 33,"y": 7},{"x": 29,"y": 5},{"x": 31,"y": 5},{"x": 31,"y": 11},{"x": 27,"y": 5},{"x": 25,"y": 5},{"x": 25,"y": 7},{"x": 25,"y": 9},{"x": 25,"y": 11},{"x": 25,"y": 13},{"x": 23,"y": 9},{"x": 21,"y": 9},{"x": 19,"y": 9},{"x": 19,"y": 11},{"x": 19,"y": 13},{"x": 15,"y": 9},{"x": 13,"y": 7},{"x": 13,"y": 9},{"x": 13,"y": 11},{"x": 11,"y": 7},{"x": 13,"y": 5},{"x": 11,"y": 5},{"x": 7,"y": 5},{"x": 5,"y": 5},{"x": 5,"y": 7},{"x": 7,"y": 7},{"x": 7,"y": 9},{"x": 7,"y": 11},{"x": 5,"y": 11},{"x": 5,"y": 9},{"x": 7,"y": 15},{"x": 7,"y": 17},{"x": 7,"y": 19},{"x": 11,"y": 23},{"x": 11,"y": 17},{"x": 11,"y": 21},{"x": 11,"y": 19},{"x": 17,"y": 25},{"x": 17,"y": 27},{"x": 17,"y": 29},{"x": 19,"y": 25},{"x": 21,"y": 25},{"x": 17,"y": 21},{"x": 17,"y": 23},{"x": 17,"y": 19},{"x": 15,"y": 19},{"x": 13,"y": 19},{"x": 7,"y": 29},{"x": 7,"y": 31},{"x": 7,"y": 33},{"x": 9,"y": 33},{"x": 13,"y": 33},{"x": 11,"y": 33},{"x": 13,"y": 31},{"x": 13,"y": 29},{"x": 15,"y": 33},{"x": 17,"y": 33},{"x": 19,"y": 33},{"x": 21,"y": 33},{"x": 25,"y": 29},{"x": 25,"y": 31},{"x": 25,"y": 33},{"x": 27,"y": 29},{"x": 29,"y": 29},{"x": 29,"y": 23},{"x": 27,"y": 23},{"x": 25,"y": 23},{"x": 29,"y": 21},{"x": 29,"y": 19},{"x": 33,"y": 19},{"x": 33,"y": 21},{"x": 33,"y": 23},{"x": 33,"y": 25},{"x": 33,"y": 27},{"x": 33,"y": 29},{"x": 33,"y": 31},{"x": 33,"y": 33},{"x": 31,"y": 35},{"x": 29,"y": 35},{"x": 27,"y": 35},{"x": 25,"y": 35},{"x": 7,"y": 23},{"x": 11,"y": 15},{"x": 9,"y": 15},{"x": 19,"y": 21},{"x": 21,"y": 21},{"x": 21,"y": 19},{"x": 29,"y": 27},{"x": 29,"y": 25}]; // 记录障碍坐标物数据var lineArr = new Array(); // 记录路网数据var meshbool = false; // 显示障碍物var linebool = false; // 显示路网var resultArray = new Array();var isCaculate = false;function init() {// 创建一个场景,它将包含我们所有的元素,如物体,相机和灯光。var scene = new THREE.Scene();var urls = ['assets/textures/cubemap/flowers/posx.jpg','assets/textures/cubemap/flowers/negx.jpg','assets/textures/cubemap/flowers/posy.jpg','assets/textures/cubemap/flowers/negy.jpg','assets/textures/cubemap/flowers/posz.jpg','assets/textures/cubemap/flowers/negz.jpg'];var cubeLoader = new THREE.CubeTextureLoader();scene.background = cubeLoader.load(urls);// 创建一个摄像机,它定义了我们正在看的地方camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 0.1, 1000);// 将摄像机对准场景的中心camera.position.x = 60;camera.position.y = 35;camera.position.z = 60;camera.lookAt({x: 0,y: 5,z: -20});var orbit = new THREE.OrbitControls(camera);orbit.target = camera.position;orbit.update();// 创建一个渲染器并设置大小,WebGLRenderer将会使用电脑显卡来渲染场景// initialize basic rendererrenderer = initRenderer({antialias: true,logarithmicDepthBuffer: true,});// 将平面添加到场景中var plane = createPlaneGeometryBasicMaterial();scene.add(plane);// 在屏幕上显示坐标轴var axes = new THREE.AxesHelper(100);scene.add(axes);scene.add(new THREE.AmbientLight(0x666666));scene.add(new THREE.AmbientLight("#ffffff", 1));initModel();// initPeople();initGround();initGrid();var i = 0;function tweenComplete() {if (i < points.length) {switch (i) {case 0:aaa.rotateY(Math.PI);break;case 1:case 5:case 8:case 9:aaa.rotateY(-0.5 * Math.PI);break;case 2:case 3:case 4:case 6:case 7:aaa.rotateY(0.5 * Math.PI);break;case 10:mixer.stopAllAction();break;}tween = new TWEEN.Tween(points[i]).to(points[i + 1], 3000).easing(TWEEN.Easing.Linear.None).onUpdate(function() {aaa.position.set(this.x, this.y, this.z);}).onComplete(tweenComplete).start();i++;}}// 使用GUI调试库var controls = new function() {this.clickBool = false;this.displayRoadGrid = function() {for (var i = 0; i < lineArr.length; i++) {if (linebool) {// 显示路网scene.add(lineArr[i].obj);} else {// 隐藏路网var obj = scene.getObjectByName(lineArr[i].name);scene.remove(obj);}}linebool = !linebool}this.displayObstacles = function() {for (var i = 0; i < meshArr.length; i++) {if (meshbool) {// 显示障碍物scene.add(meshArr[i].obj);} else {// 隐藏障碍物var obj = scene.getObjectByName(meshArr[i].name);scene.remove(obj);}}meshbool = !meshbool}this.outputObstacles = function() {for (var i = 0; i < meshArr.length; i++) {meshxy.push({x: meshArr[i].x,y: meshArr[i].y})}console.log(meshArr)console.log(lineArr)console.log(meshxy)localStorage.setItem('meshArr', JSON.stringify(meshArr));localStorage.setItem('lineArr', JSON.stringify(lineArr));localStorage.setItem('meshxy', JSON.stringify(meshxy));}}var gui = new dat.GUI();// 隐藏显示障路网gui.add(controls, 'displayRoadGrid');// 隐藏显示障碍物gui.add(controls, 'displayObstacles');// 输出障碍物对象gui.add(controls, 'outputObstacles');gui.add(controls, "clickBool");// 启动动画renderScene();// 添加模型function initModel() {var mtlLoader = new THREE.MTLLoader();mtlLoader.setPath("assets/models/obj_mtl/")mtlLoader.load('city.mtl', function(materials) {materials.preload();var objLoader = new THREE.OBJLoader();objLoader.setMaterials(materials);objLoader.load('assets/models/obj_mtl/city.obj', function(object) {var mesh = object;mesh.scale.set(3, 3, 3);mesh.position.set(18, 0, 18);scene.add(mesh);});});}// 添加人物模型function initPeople() {var loader = new THREE.GLTFLoader();loader.load('assets/models/CesiumMan/CesiumMan.gltf', function(result) {result.scene.scale.set(1, 1, 1);result.scene.translateY(0);aaa = result.scene;scene.add(result.scene);tweenComplete();mixer = new THREE.AnimationMixer(result.scene);animationClip = result.animations[0];clipAction = mixer.clipAction(animationClip).play();animationClip = clipAction.getClip();});}// 创建一个地面并设置草坪材质function createPlaneGeometryBasicMaterial() {var textureLoader = new THREE.TextureLoader();var cubeMaterial = new THREE.MeshStandardMaterial({map: textureLoader.load("assets/textures/stone/cd.jpg"),});cubeMaterial.map.wrapS = THREE.RepeatWrapping;cubeMaterial.map.wrapT = THREE.RepeatWrapping;cubeMaterial.map.repeat.set(18, 18)// 创建地平面并设置大小var planeGeometry = new THREE.PlaneGeometry(500, 500);var plane = new THREE.Mesh(planeGeometry, cubeMaterial);// 设置平面位置并旋转plane.rotation.x = -0.5 * Math.PI;plane.position.x = 0;plane.position.z = 0;return plane;}// 绘制线路function initLine(pArr) {var points = [];var geometry = new THREE.Geometry();for (var i = 0; i < pArr.length; i++) {var randomX = pArr[i].x;var randomY = pArr[i].y;var randomZ = pArr[i].z;var vector = new THREE.Vector3(randomX, randomY, randomZ);geometry.vertices.push(vector);points.push(vector);}var material = new THREE.LineBasicMaterial({color: 0x0000FF});var line = new THREE.Line(geometry, material);scene.add(line);return points;}// 绘制路网function initGround() {var geometry = new THREE.Geometry();geometry.vertices.push(new THREE.Vector3(0, 0, 0));geometry.vertices.push(new THREE.Vector3(length, 0, 0));for (var i = 0; i <= length / ws; i++) {var material = new THREE.LineBasicMaterial({color: 0x808080});var line = new THREE.Line(geometry, material);line.position.z = i * ws;line.name = "line_" + i;lineArr.push({name: "line_" + i,obj: line});scene.add(line);var line = new THREE.Line(geometry, material);line.position.x = i * ws;line.position.z = length;line.rotation.y = 90 * Math.PI / 180;line.name = "line_" + i + 180;lineArr.push({name: "line_" + i + 180,obj: line});scene.add(line);}}// 初始化障碍物随机function initGrid() {for (var i = 0; i < length / ws; i++) {var nodeRow = [];for (var j = 0; j < length / ws; j++) {nodeRow.push(1);}graph.push(nodeRow);}if (meshxy.length > 0) {for (var i = 0; i < meshxy.length; i++) {initObstacles(meshxy[i].x, meshxy[i].y);}} else {for (var i = 0; i < length / ws; i++) {var nodeRow = [];for (var j = 0; j < length / ws; j++) {var salt = Math.random() * 7;if (salt > 2) {nodeRow.push(1);} else {nodeRow.push(0);}if (salt <= 2) {var cube = new THREE.Mesh(new THREE.CubeGeometry(1, 1, 1), new THREE.MeshBasicMaterial({color: 0xC0C0C0}));let x = ws * j + ws / 2;let z = ws * i + ws / 2;cube.position.set(x, 1.2, z);scene.add(cube);}}graph.push(nodeRow);}}}//计算路径function caculatePath(resultArray) {var maps = new Graph(graph); // 地图var startX = parseInt(resultArray[0].position.z / ws);var startY = parseInt(resultArray[0].position.x / ws);var endX = parseInt(resultArray[1].position.z / ws);var endY = parseInt(resultArray[1].position.x / ws);var start = maps.grid[startX][startY];var end = maps.grid[endX][endY];result = astar.search(maps, start, end);if (result.length == 0) {alert("无可到达路径");cleanSphere();return;}var nArr = [{x: resultArray[0].position.x,z: resultArray[0].position.z,y: 1.2}];for (var i = 0; i < result.length; i++) {let d = {x: result[i].y * ws + ws / 2,y: 1.2,z: result[i].x * ws + ws / 2,}nArr.push(d);}initLine(nArr);}//清除小球function cleanSphere() {let child = scene.children; //获取场景中的所有子对象for (var i = 0; i < child.length; i++) {if (child[i].geometry instanceof THREE.SphereGeometry) { //几何对象是球体几何scene.remove(child[i]); //从场景中移除i--;}}isCaculate = false;}//初始球体function initSphere(x, z) {if (isCaculate) {cleanSphere();}var geometry = new THREE.SphereGeometry(ws / 2, 30, 30); //球体几何var material = new THREE.MeshBasicMaterial({color: 0xffff00}); //网格基础材料if (resultArray.length == 0) {var sphere = new THREE.Mesh(geometry, material);sphere.position.x = x;sphere.position.y = 1;sphere.position.z = z;resultArray.push(sphere);scene.add(sphere);} else if (resultArray[0].position.x != x || resultArray[0].position.z != z) {var sphere = new THREE.Mesh(geometry, material);sphere.position.x = x;sphere.position.y = 1;sphere.position.z = z;resultArray.push(sphere);scene.add(sphere);caculatePath(resultArray);isCaculate = true;resultArray = new Array();}}// 绘制障碍物function initObstacles(x, z) {var name = "mesh_" + x + z;var obj = scene.getObjectByName(name);if (obj) {scene.remove(obj);for (var i = 0; i < meshArr.length; i++) {if (meshArr[i].name == name) {meshArr.splice(i, 1);}}graph[parseInt(z / ws)][parseInt(x / ws)] = 1;} else {var geometry = new THREE.BoxGeometry(ws, ws, ws); //球体几何var material = new THREE.MeshBasicMaterial({color: 0xff0000});var sphere = new THREE.Mesh(geometry, material);sphere.position.x = x;sphere.position.y = 1;sphere.position.z = z;sphere.name = name;scene.add(sphere);meshArr.push({name: name,obj: sphere,x: x,y: z,});graph[parseInt(z / ws)][parseInt(x / ws)] = 0;}}// 拾取对象function pickupObjects(event) {// 点击屏幕创建一个向量var raycaster = new THREE.Raycaster();var vector = new THREE.Vector2((event.clientX / window.innerWidth) * 2 - 1, -(event.clientY / window.innerHeight) * 2 + 1);var fxl = new THREE.Vector3(0, 1, 0);var groundplane = new THREE.Plane(fxl, 0);raycaster.setFromCamera(vector, camera);var ray = raycaster.ray;let intersects = ray.intersectPlane(groundplane);let x = intersects.x;let z = intersects.z;if (x < 0 || z < 0 || length < z || length < x) {return;}var k, m;for (var i = 0; i < length; i += ws) {if (x >= i && x < i + ws) {k = i + ws / 2;}}for (var j = 0; j < length; j += ws) {if (z >= j && z < j + ws) {m = j + ws / 2;}}if (controls.clickBool) {initSphere(k, m); //初始化球体} else {initObstacles(k, m);}}document.addEventListener('click', pickupObjects, false); //监听单击拾取对象初始化球体// 动画渲染var step = 5;function renderScene() {TWEEN.update();var delta = clock.getDelta();orbit.update();mixer.update(delta);// 使用requestAnimationFrame函数进行渲染requestAnimationFrame(renderScene);renderer.render(scene, camera);}// 渲染的场景renderer.render(scene, camera);// 创建一个球形几何体function createSphereGeometryLambertMaterial(point) {// 创建一个球体var sphereGeometry = new THREE.SphereGeometry(0.2, 20, 20);var sphereMaterial = new THREE.MeshBasicMaterial({color: 0x7777ff,wireframe: true});var sphereMaterial = new THREE.MeshLambertMaterial({color: 0xff0000});var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);// 设置该物体投射阴影sphere.castShadow = true;// 位置范围sphere.position.x = point.x;sphere.position.y = point.y;sphere.position.z = point.z;return sphere;}}window.onload = init;function onResize() {camera.aspect = window.innerWidth / window.innerHeight;camera.updateProjectionMatrix();renderer.setSize(window.innerWidth, window.innerHeight);}// 监听调整大小事件window.addEventListener('resize', onResize, false);</script></body>
</html>

需要完整代码请留言或者联系我微信:1171053128

Threejs中使用A*算法寻路导航,Threejs室内室外地图导航相关推荐

  1. android启动百度地图应用并开始导航,android打开外部地图导航(百度、高德、腾讯)...

    外部打开百度地图进行导航: /*** 打开百度地图*@paramslat开始地点 维度*@paramslon开始地点 经度*@paramsname开始地点 名字*@paramdlat终点地点 维度*@ ...

  2. 微信小程序地图导航源码、地图导航小程序源码

    最近研究了微信小程序地图功能,编写了地图导航功能的Demo(文章尾部附有下载地址). 1.用户定位功能:用户同意小程序获取位置权限,并定位用户当前位置: 2.选择目的地,并开始自动导航功能 2.选择交 ...

  3. 地图导航APP开发作用

    地图导航APP开发,地图导航APP开发作用. 近些年大家生活的节奏持续加速,很多人针对出游造成了比较大要求,但要想在日常生活中进行有关活动需搞好很多的准备工作,终究用户去到生疏地区都要提早了解好行为路 ...

  4. 如何低成本实现酒店地图导航室内导航

    如何低成本实现 酒店地图导航室内导航,帮助顾客快速找到酒店设施,提高酒店服务水平,提升酒店信息化建设.维小帮提供两种低成本的酒店导航实现方式,供大家参考. 一.模拟导航 在预算有限的情况下,用户可以选 ...

  5. Windows Phone 7编程实践—必应地图导航

    作品目标:Windows Phone 7 开发的实用手册 必应地图导航概述 本文参考和引用Windows Phone官方教程和开发培训包,以及MSDN Windows Phone开发文档,诠释必应地图 ...

  6. 地图导航APP开发功能

    地图导航APP开发,地图导航APP开发功能 1.服务平台追踪定位:一部分用户方位感较弱,用户只需打开手机定位服务,APP便会即时表明用户部位信息. 2.路线规划信息:用户应用地图导航APP,则是期望能 ...

  7. Threejs中使用astar(A*)算法寻路导航,Threejs寻路定位导航

    1,介绍 该示例使用的是 r95版本Three.js库.利用A*算法实现寻路.导航功能.添加坐标轴. 效果图如下: 2,主要说明 引入A*算法astar.js <script type=&quo ...

  8. threejs添加立方体_前端图形学(三十)——从源码去看threejs中的光照模型

    欢迎来到[畅哥聊技术]前端图形学相关技术文章,更多精彩内容持续更新中,敬请关注. 上章节回顾 熟悉了threejs中内置的几何图形的渲染原理就是通过顶点渲染 传入自定义顶点渲染自定义的几何图形 本章目 ...

  9. ThreeJS 中体渲染,利用噪声模拟烟,云

    ThreeJS 中体渲染,利用噪声模拟烟,云 体渲染的东西也看了一段时间了,这里结合Three.js中体积云的例子,实现shdertoy中的一个效果,先放效果图. Fire2 (shadertoy.c ...

  10. threejs中坐标系转换和实现物体跟随鼠标移动

    坐标系转换 下面函数可以将鼠标所在点的屏幕坐标转化成一个Threejs三维坐标: convertTo3DCoordinate(clientX,clientY){var mv = new THREE.V ...

最新文章

  1. 全球首辆飞行摩托开卖!飞行高度可达4572米,243万元一辆,你敢开吗?
  2. Python 中 zip() 函数的用法
  3. 使用MASM03 - Win32汇编语言011
  4. HTML特殊字符编码对照表
  5. 充电网完成数千万元Pre-B轮融资,将会聚焦新能源乘用车市场
  6. Mysql清空表(truncate)与删除表中数据(delete)的区别
  7. Linux 设备驱动开发 —— 设备树在platform设备驱动中的使用
  8. python自然语言处理库_Python 自然语言处理(NLP)工具库汇总
  9. python (元祖\列表\集合\字典)基础用法
  10. iOS——常用的手势总结
  11. android一键改机之真改机build.prop
  12. ArcCatalog导出数据库中shapefile
  13. word打开文档很久很慢_Office软件打开速度慢怎么处理?Word打开很慢如何解决?...
  14. 切换无线网卡失败服务器提示,无线网卡切换为AP模式时提示ICS启动失败的解决方法...
  15. 正在等待暴雪服务器响应,炉石传说无法通过暴雪战网服务进行登录,炉石传说,“游戏无法将你登陆至战网。请等待几分钟并再次尝试”...
  16. 进程系列(一)-进程基本概念
  17. 北科大matlab期末考试,MATLAB 第一次实验课课堂作业
  18. 用sort对vector排序(转载)
  19. 图解 Panda3D引擎开发入门
  20. 新东方老罗(罗永浩)语录全集

热门文章

  1. WPS怎么设置显示文章目录
  2. 聊一聊数据分析师这个职业
  3. 彩虹表MD5破解分析
  4. 【组合数学】指数型母函数(多重集排列问题)
  5. 指针概念、指针大小和内存详解
  6. 1-4 正弦和余弦
  7. win10中查看工作组计算机,win10查看工作组计算机,w10怎样查看工作组
  8. keil编译出现多重定义的问题
  9. minimum在java中的意思_Java Calendar getMinimum()方法与示例
  10. 发现谷歌学术搜索真好用啊