Babylon.js群组导航系统文档中英文对照
第一节
Crowd Navigation System
@@群组导航系统@@
A Navigation Mesh (or navmesh for short) is a surface topology describing the space where an agent can go based on constraints. Based on parameters like agent radius, agent climbing capability, agent height,... the navmesh generation computes a topology from source meshes (the world geometry). Then, this topology can have a debug display (blue mesh on screenshot above) to validate the parameters.
@@导航网格(或者简称为导航网格),是一个用来描述运动物体在约束条件下的移动范围的表面拓扑对象。基于一些参数,比如运动物体的半径、运动物体的爬坡能力、运动物体的高度。。。导航网格生成器根据源网格(场景世界的多边形结构),计算出一个拓扑对象。然后,这个(不可见的)拓扑结构可以具有一个可见的调试显示(上图中的蓝色区域)用来验证参数设置效果。@@
A demo can be found at: Crowd Navigation Demo
@@可以在这里找到一个群组导航的例子:@@
https://playground.babylonjs.com/#HFY257#4
第二节
Creating A Navigation Mesh
@@建立一个导航网格@@
Table Of Contents
@@内容列表@@
How to use the navigation mesh?
@@如何使用导航网格?@@
@@参数@@
@@查询@@
@@烘焙计算结果@@
How to use the navigation mesh?
@@如何使用导航网格?@@
There are many cases to use a navigation mesh: AI and path finding, replace physics for collision detection (only allow player to go where it's possible instead of using collision detection) and many more cases theBabylon.js users will find.
@@导航网格可以用在很多地方:AI与寻路、代替物理引擎进行碰撞检测(只允许玩家前往某些地点,而不是使用碰撞检测)以及Babylon.js的用户将找到的更多地方。@@
First, create the navigation plugin
@@首先,建立一个导航插件对象@@
let navigationPlugin = new BABYLON.RecastJSPlugin();
Prepare some parameters for the agent constraints (described below)
@@为运动物体的约束条件设置一些参数(具体描述在后面)@@
var parameters = {
cs: 0.2,
ch: 0.2,
walkableSlopeAngle: 35,
walkableHeight: 1,
walkableClimb: 1,
walkableRadius: 1,
maxEdgeLen: 12.,
maxSimplificationError: 1.3,
minRegionArea: 8,
mergeRegionArea: 20,
maxVertsPerPoly: 6,
detailSampleDist: 6,
detailSampleMaxError: 1,
};
Call the navigation mesh generation with the parameters and the list of meshes
@@使用这些参数以及网格(世界中的障碍物)列表调用导航网格生成器,@@
navigationPlugin.createNavMesh([groundMesh, wallMesh1, wallMesh2, stair1, stair2], parameters);
And that's it! you can now use the navigation mesh with the crowd system or make queries.
@@然后就欧了!现在你可以通过群组系统使用这个导航网格,或者使用查询功能。@@
Optionaly, you can get a display of the navmesh to ensure it corresponds to your space constraints
@@可选的,你可以选择显示导航网格,以确保它与你的空间约束设置相对应。@@
navmeshdebug = navigationPlugin.createDebugNavMesh(scene);
var matdebug = new BABYLON.StandardMaterial('matdebug', scene);
matdebug.diffuseColor = new BABYLON.Color3(0.1, 0.2, 1);
matdebug.alpha = 0.2;
navmeshdebug.material = matdebug;
Parameters
@@参数@@
cs - The meshes are voxelized in order to compute walkable navmesh. This parameter in world unit define the widthand depth of 1 voxel.
@@网格列表中的网格将被转化为“体素”,好用来计算可到达的导航网格。这个以世界单位表示的参数,定义了1个体素的宽度。@@
ch - Same as cs but for height of the voxel.
@@与cs一样,但定义的是1个体素的高度@@
walkableSlopeAngle - Angle in degree for the maximum walkable slop.
@@可行走斜坡的最大坡度,以角度单位表示@@
walkableHeight - The height in voxel units that is allowd to walk in.
@@运动物体可以到达的最大高度,以体素的个数表示@@
walkableClimb - The delta in voxel units that can be climbed.
@@运动物体可以跨越的最大高度差,以体素的个数表示@@
walkableRadius - the radius in voxel units of the agents.
@@运动物体的半径,以体素的个数表示@@
maxEdgeLen - The maximum allowed length for contour edges along the border of the mesh. Voxel units.
@@导航网格的边缘的每条边的最大长度。以体素尺寸为单位。@@
maxSimplificationError - The maximum distance a simplified contour's border edges should deviate the original raw contour. Voxel units.
@@导航网格是实际场景的简化,导航网格边缘到原始场景轮廓的最大偏离。@@
minRegionArea - The minimum number of cells allowed to form isolated island areas. Voxel units.
@@可以组成孤立岛屿的最少单元格,意思是过于小的区域将被忽略。@@
mergeRegionArea - Any regions with a span count smaller than this value will, if possible, be merged with larger regions. Voxel units.
@@范围小于这个值的区域将在可能的情况下和更大的区域合并在一起,意思是过小的区域将与较大的区域融合,这个值一般比mergeRegionArea 更大。@@
maxVertsPerPoly - The maximum number of vertices allowed for polygons generated during the contour to polygon conversion process. Must be > 3.
@@每个多边形的最大顶点数量-在轮廓转变为多边形的过程中,对于每个多边形允许生成的最大顶点数量。必须大于3.@@
detailSampleDist - Sets the sampling distance to use when generating the detail mesh. World units.
@@细节采样距离-设置生成细节网格时的采样距离。使用世界长度单位@@
detailSampleMaxError - The maximum distance the detail mesh surface should deviate from heightfield data. World Units.
@@细节采样最大误差-细节网格的表面与高度场数据之间的最大偏离。使用世界长度单位@@
(地形-》轮廓(高度场数据)-》导航网格)
Queries
@@查询@@
Basically, query functions help at getting constraint point and vector by the navigation mesh.
@@总的来说,查询方法用来从导航网格获取符合约束条件的点和向量@@
getClosestPoint(position: Vector3): Vector3;
getRandomPointAround(position: Vector3, maxRadius: number): Vector3;
moveAlong(position: Vector3, destination: Vector3): Vector3;
Respectively:
@@依次是:@@
- get a point on the navmesh close to a world position parameter
- @@在导航网格上获取一个靠近某个世界坐标位置的点@@
- get a random world position, on the navmesh, inside a circle of maxRadius.
- @@在最大半径的限制内,在导航网格上取一个随机世界坐标系位置。@@
- constraint a segment by the navmesh and returns the ending world position. Like walking on the navmesh and stopping at the edge.
- @@在导航网格内约束一条线段,并且返回其终点的世界坐标位置。就像在导航网格上走直线,然后在到达导航网格的边缘时停止。@@
When the query can't find a valid solution, the value (0,0,0) is returned.
@@当查询方法无法找到可用的结果时,将返回(0,0,0)@@
Those functions use a bounding box for querying the world. The solution returned is within that bound. To properly set the default box extent to get a finer or broader result, call:
@@这些方法使用边界盒在世界中进行查询。返回的记过也在这个边界以内。可以通过以下方法来调整默认的边界盒,以获得更精确或更粗略的结果。@@
setDefaultQueryExtent(extent: Vector3): void;
If your query returns a point too far from the expected result, use a smaller extent.
@@如果你的查询返回了一个距离期望结果过远的点,使用一个较小的扩展值。(边界盒是由实际的网格扩展一些消除细节后形成的,边界盒越大则与实际网格相差越远)@@
It's possible to get a path built for navigation as a point array. It's up to the user to use this array for drawing prediction path, trigger events,...
@@可以以点数组的方式从导航对象获取一条导航路径。然后用户可以使用这个数组绘制预计路线、触发事件等等@@
var pathPoints = navigationPlugin.computePath(crowd.getAgentPosition(agent), navigationPlugin.getClosestPoint(destinationPoint));
pathLine = BABYLON.MeshBuilder.CreateDashedLines("ribbon", {points: pathPoints, updatable: true, instance: pathLine}, scene);
Baking result
@@烘培计算结果@@
Building a navigation mesh can take a lot of cpu and network resources. In order to lower the download size and cpu needed, it's possible to bake the result of the navigation mesh computation to a byte stream. That byte stream can later be restored to get the navigation mesh back.
@@建立导航网格可能需要消耗很多cpu和网络资源(下载recast库?)。为了降低下载量和cpu消耗,可以把计算出的导航网格烘焙为一个二进制流。这个二进制流之后又可以被恢复为导航网格@@
To retrieve the binary representation of the computed navigation mesh:
@@检索计算出的导航网格的二进制表示:@@
var binaryData = navigationPlugin.getNavmeshData();
binaryData is an Uint8Array that you can save to a file for example. To restore an UInt8Array to a navigation mesh:
@@这里binaryData 对象是一段Uint8Array 型的数据,你可以把这段数据保存为文件。也可以使用以下方法把它恢复为导航网格:@@
navigationPlugin.buildFromNavmeshData(uint8array);
第三节
Crowd Agents
@@群组运动物体@@
Table Of Contents
@@内容列表@@
@@群组与导航运动物体@@
@@如何使用@@
@@运动物体参数@@
传送
Agent orientation and next path target
运动物体的朝向与下一个路径目标
Crowds and navigation agents
@@群组与导航运动物体@@
Now we have a navmesh, we can create autonomous agents and make them navigate within that navmesh constraint. The agents will find the best path to that destination while avoinding other crowd agents. An agent is attach to a Transform. That means that you have to attach a mesh to see them but also that you can attach pretty much anything.
@@现在我们有了一个导航网格,接下来我们可以建立自主的运动物体,然后让它们在导航网格的限制下导航。这些运动物体将找到最佳的到达目的地的路径,并在这一过程中避免和群组中的其他运动物体重叠。运动物体默认被绑定在一个变换节点上。如果你想看到它,则你应该绑定一个网格,当然你还可以绑定其他的东西。@@
A demo can be found at: Crowd and Navigation Agents
@@可以在这里找到一个群组与导航运动物体的例子:@@
https://playground.babylonjs.com/#X5XCVT#240
Click anywhere on the navmesh to make the agents go to that location.
@@点击导航网格上的任意位置,将使运动物体向那个位置运动。@@
How to use it?
@@如何使用?@@
First thing is to create a crowd that all agents will belong to. Parameters are the maximum number of agents in the crowd, the maximum agent radius and the scene.
@@第一件事是建立一个包含所有运动物体的群组对象。参数是群组中的最大运动物体数量、运动物体的最大半径以及场景对象。@@
var crowd = navigationPlugin.createCrowd(10, 0.1, scene);
Then to create an agent and attach it to a transform, call:
然后用以下语句建立一个运动物体,并把它绑定到一个变换节点上:
var agentIndex = crowd.addAgent(position, agentParameters, transform);
And that's it! You will get a non moving agent. We now want to move it.
@@成功了!你将获得一个未运动的运动物体。接下来我们要移动它。@@
crowd.agentGoto(agentIndex, navigationPlugin.getClosestPoint(endPoint));
This code will get the closest position on the navmesh to endPoint. Then it asks the agent to go to that position. Depending on your agent parameters, it will get there faster of slower.
@@这段代码将获取导航网格上最靠近目标点的位置。然后它将让运动物体移动到那个位置。取决于你的运动物体的参数,他将或快或慢地到达那里。@@
Agent Parameters
@@运动物体的参数@@
radius - Radius of the agent. World Unit.
@@半径-运动物体的半径。世界单位@@
height - Heigh in World Unit.
@@高度-以世界单位表示的高度。@@
maxAcceleration - Acceleration max in World Unit per second per second
@@最大加速度-以世界长度单位/(秒*秒)表示的最大加速度@@
maxSpeed - Max speed in World Unit per second.
@@最大速度-以世界单位长度/秒表示的最大速度。@@
collisionQueryRange - The agent collision system will take care of others within that radius in World Unit.
@@碰撞查询范围-以世界单位表示的半径,运动物体的碰撞检测系统将考虑这个半径范围内的物体。@@
pathOptimizationRange - How the path will be optimized and made more straight.
@@路径优化范围-路径将如何被优化,并变得更直@@
separationWeight - How hard the system will try to separate the agent. A Value of 0 means it will not try and agents might collide.
@@分离权重-表示这个系统将用多少努力去尝试保持这个运动物体的独立。如果设为0值,则将不努力保持这个运动物体与其他运动物体的分离并可能导致相撞@@
You can update any of these parameters, per agent, by calling :
@@你可以修改群组中的任何一个运动物体的参数,通过调用以下代码:@@
// change speed and max speed 修改速度和最大速度
crowd.updateAgentParameters(agentIndex, {maxSpeed:10, maxAcceleration:200});
Teleport
@@传送@@
You can teleport an agent to any position using this call:
@@你可以用以下方法把一个运动物体传送到任意位置:@@
crowd.agentTeleport(agentIndex, navigationPlugin.getClosestPoint(destinationPoint));
Please note the navigation state is reseted when teleporting. You'll have to call agentGoto to choose a new destination.
@@请注意传送物体的导航状态将在传送时被重置。你必须调用agentGoto 方法重新设置目的地。@@
Agent orientation and next path target
@@运动物体的朝向以及下一个路径目标@@
Recastjs crowd system does not handle agent orientation. But the velocity is available and it's possible to orient the geometry toward it. To do so, you will need to use Math.atan2 like in the following example. Please take care of the length of the velocity vector. If it's not big enough, you may encounter jittering.
@@Recast.js的群组系统并不处理运动物体的朝向。但是物体的移动速度是可以被获取的,并且可以设置多边形朝向这一速度方向。要做到这一点,你需要像下面的例子这样使用Math.atan2函数。请注意速度向量长度,如果这个长度不够大物体可能不断抖动。@@
let velocity = crowd.getAgentVelocity(agentIndex);
if (velocity.length() > 0.2)//防抖
{
var desiredRotation = Math.atan2(velocity.x, velocity.z);
// interpolate the rotation on Y to get a smoother orientation change 在Y轴的旋转中插值,以获得一个平滑的朝向变化效果。
ag.mesh.rotation.y = ag.mesh.rotation.y + (desiredRotation - ag.mesh.rotation.y) * 0.05;
}
In this PG Agent Orientation and Next Path Targeting
在这个训练场中查看运动物体朝向与下一个路径目标的例子
https://playground.babylonjs.com/#6AE0RP
The agent's cube is oriented by the velocity and a grey little box is placed at the position of the next path corner.
@@代表运动物体的方块根据速度改变朝向,并且一个灰色的小盒子被放置在下一段路径的拐角上。@@
第四节
Adding and removing obstacles
@@添加和移除障碍物@@
Table Of Contents
@@内容列表@@
@@先决条件@@
@@障碍API@@
Prerequisites
@@先决条件@@
Internaly, navigation mesh with support for obstacles differs from 'standard' use case with one static navigation mesh. Obstacles mark tiles as dirty. Those tiles need to be reprocessed to compute a portion of the navigation mesh. To do so, Recast introduces the concept of tiles. Each tile is a square portion of the nav mesh. Tiles a processed each frame. Making huge changes processed of a couple of frames.
@@在内部,导航网格通过对静态的网格的“基础”使用来进行障碍分辨。障碍将把地块标记为“脏的”。这些地块将被加工为导航网格的一部分。为了做到这一点,Recast库引入了地块的概念。每个地块是导航网格一个方块区域。每一帧里都会处理一次地块计算。较多的帧数会产生大量的地块修改计算。@@
In order to build a Tiled nav mesh instead of a single mesh, add the following lines to the nav mesh creation parameters:
@@为了建立一个“地块化”的导航网格,而不是一个单独的导航网格,在导航网格的构造参数里添加以下行@@
var navmeshParameters = {
cs: 0.2,
ch: 0.2,
walkableSlopeAngle: 0,
walkableHeight: 0.0,
walkableClimb: 0,
walkableRadius: 1,
maxEdgeLen: 12.,
maxSimplificationError: 1.3,
minRegionArea: 8,
mergeRegionArea: 20,
maxVertsPerPoly: 6,
detailSampleDist: 6,
detailSampleMaxError: 15,
borderSize: 1,
tileSize:20
};
Note the addition of tileSize. It's the world unit size of each tile. If it's not present or has a value a zero, it falls back to the standard use and obstacles won't work. Also, depending on your use case, this value must be carrefully chosen to trade between too many tiles and too much cpu intensive updates.
@@注意添加的“tileSize”参数。这是以世界单位表示的每个地块的尺寸。如果不提供这个参数或者把它设为0,则导航网格将回退回基础模式,并且障碍物不会生效。另外,取决于你的使用场景,这个值必须被仔细选择,在更多的地块和更高的cpu更新密度间取舍@@
Obstacles API
@@障碍物API@@
Once the navigation mesh is updated to take tiles into account, obstacles are accessible thru 3 simple functions:
@@一旦导航网格被设为考虑地块的,可以使用这三个简单的方法控制障碍物@@
addCylinderObstacle(position: Vector3, radius: number, height: number): IObstacle;
addBoxObstacle(position: Vector3, extent: Vector3, angle: number): IObstacle;
removeObstacle(obstacle: IObstacle): void;
Keep a list of added obstacles in order to remove them later. An obstacle that's not colliding with the navigation mesh will have no influence.
@@将添加的障碍物保存为一个列表,以便后期移除它们。一个与导航网格不接触的障碍物将不会对导航产生影响。@@
Adding a door to a navigation mesh
@@向导航网格中添加一扇门@@
https://playground.babylonjs.com/#WCSDE1