Git Product home page Git Product logo

yuka's People

Contributors

caramboleyo avatar dependabot[bot] avatar discordier avatar mugen87 avatar robp94 avatar waelyasmina avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

yuka's Issues

ConvexHull generation from certain input points causing infinite loop

This is a showstopper for me. I'm not sure where the loop goes endless from the YUKA.ConvexHull codebase yet. Example point input below for reference.

It'd be good to have a test unit/case for this.

To trigger endless loop, use the code below:.

var jsonArr = [{"x":-55.53499860610813,"y":73.11029657847513,"z":-63.59099818190188},{"x":-55.7849986005202,"y":73.11029657847513,"z":-69.34100186807655},{"x":-58.53499853905291,"y":73.11029657847513,"z":-68.84100187925242},{"x":-58.03499855022878,"y":73.11029657847513,"z":-63.59099818190188},{"x":-55.53499860610813,"y":73.01029657847513,"z":-63.59099818190188},{"x":-55.7849986005202,"y":73.01029657847513,"z":-69.34100186807655},{"x":-58.53499853905291,"y":73.01029657847513,"z":-68.84100187925242},{"x":-58.03499855022878,"y":73.01029657847513,"z":-63.59099818190188},{"x":-9.78499962870032,"y":74.11029655612339,"z":-64.84100196865938},{"x":-10.034999623112384,"y":74.11029655612339,"z":-64.09100198542319},{"x":-9.034999645464126,"y":73.92279656031434,"z":-63.59099818190188},{"x":-9.78499962870032,"y":74.0102965561234,"z":-64.84100196865938},{"x":-10.034999623112384,"y":74.0102965561234,"z":-64.09100198542319},{"x":-9.034999645464126,"y":73.82279656031434,"z":-63.59099818190188}];
new YUKA.ConvexHull().fromPoints(jsonArr.map((p)=>{return new YUKA.Vector3(p.x, p.y, p.z)}));

Screenshot of the above 14 input points below (shown as small green cubes) floating above the navmesh regions highlighted in red. Looks "innocent" enough. So this seems like a serious bug.

image

expected hull output:

image

Problems running locally on Windows 10

Following your instructions:

npm install
npm start

The output in the console is:

> npm run dev


> [email protected] dev C:\git\yuka
> concurrently "rollup -c "config/rollup/config.js" -w" "http-server -c-1"

[0] rollup v1.12.0
[0] bundles src/yuka.js → build\yuka.js, build\yuka.module.js...
[1] Starting up http-server, serving ./
[1] Available on:
[1]   http://192.168.1.125:8080
[1]   http://127.0.0.1:8080
[1] Hit CTRL-C to stop the server
[0] created build\yuka.js, build\yuka.module.js in 1s

After opening either of the available urls Chrome says:

This page isn’t working 127.0.0.1 sent an invalid response.
ERR_INVALID_REDIRECT

Nothing is rendered at all.

BVHNode intersectRay Method extension

Hello!

How can I use the intersectray method of bvhnode to return the triangle index of the original meshgeometry, because I added some custom attribute attributes to the meshgeometry, and I need to judge the custom data of the corresponding location according to the current intersection index. What can I do if I can?

thank you!

Question: Best Practices

In a given state, one that controls behavior:

Where should changes to the agents steering behavior go?

export class FooState extends YUKA.State {
  constructor() {}
  enter(agent) { 
    // Should this go here?
     agent.steering.behaviors[0].active = false
     agent.steering.behvariors[1].active = true
  }
  
  execute(agent) {
      // OR should this go here?
     agent.steering.behaviors[0].active = false
     agent.steering.behvariors[1].active = true
  }
}

Orientation/up-vector of YUKA-vehicle, ideas for a better solution?

Hi,

I wanted to hear if someone have any ideas for a better solution than the one i’ve come up with.

Background of the problem:

I’m making a 3D-simulator for a company. Basically it’s a water-pool and in the pool there will be robots that can either follow a 2D preprogrammed route/path or the robots can be controlled like an ROV in 3D-space. I’m planning to use THREE.js combined with YUKA.js for the simulator and so far it looks very promising.

Illustration of the pool with drawn world space axes and a preprogrammed route/path (on “Floor 1”):
image

Illustration of two of the robots with AxesHelper and ArrowHelper added to them:
image

Explanation of problem:

The robots are YUKA Vehicles and I’m using FollowPathBehaviour and OnPathBehaviour.
When the robot follows a path on the floor (i.e. when the y-axis of the robot and the world y-axis points in the same direction and the robot.up-vector is positive y) there’s no problem; the robot rotates/orients itself as it should:

image

The problem occurs when I want the robot to follow a 2D-path on one of the pool walls. I want the robot y-axis to always be orthogonal to the surface it’s on and to point inwards in the pool. To do that I set the robot.up-vector to x, y or z based on what surface in the pool it is running on.
Here I’ve created a 2D-path on “Outlet 1” and set the up-vector to positive x. As you can see the robot “flips” after the turn to make sure the x-axis always points in positive world y-axis, I want to avoid this flipping.

image

My solution:

The solution I’ve come up with is to check the rotation of the robot in the render-loop and change the up-vector based on that. It works but I wanted to check if someone have any idea for a better solution? Is there any way to “trick” the robot into thinking that the world x-axis or z-axis is up instead of world-y, and then always let the up-vector be positive y locally?

Expection in FollowPathBehavior

All,

I have a blender exported navigation mesh I am running a modified yuka navigation example on. Basically I query for a random region and have the Girl (from Goal) find a path to it. This map has closed doors, so the navigation mesh has multiple 'portals??'. I have hit random regions, in a different portal, that don't have a path from Girl to it. This generates the following exception.

Exception has occurred: TypeError: Cannot read property 'squaredDistanceTo' of undefined at FollowPathBehavior.calculate (http://localhost:8000/yuka/examples/navigation/navmesh/build/yuka.module.js:4525:36) at SteeringManager._calculateByOrder (http://localhost:8000/yuka/examples/navigation/navmesh/build/yuka.module.js:6833:14) at SteeringManager.calculate (http://localhost:8000/yuka/examples/navigation/navmesh/build/yuka.module.js:6772:8) at Girl.update (http://localhost:8000/yuka/examples/navigation/navmesh/build/yuka.module.js:7218:17) at Girl.update (http://localhost:8000/yuka/examples/navigation/navmesh//Girl.js:65:9) at EntityManager.updateEntity (http://localhost:8000/yuka/examples/navigation/navmesh//build/yuka.module.js:7909:11) at EntityManager.update (http://localhost:8000/yuka/examples/navigation/navmesh//build/yuka.module.js:7859:9) at animate (http://localhost:8000/yuka/examples/navigation/navmesh//index.html:350:18)

Request: Pathfinding 3D

Possibility of creating a 3D Pathfinding,
the idea is to be able to create agents(NPC) with the ability to move in 3D space.
For example a bird/helicopters flying between buildings, spacecraft between asteroids.

2D pathfinding is usually done using a navigation mesh or even a 2D grid map.

So far I've seen many examples of Pathfinding 3D using a 3D grid strategy.

Presentation: Pathfinding in 3D Space - CHIA-MAN HUNG & RUOQI HE
https://ascane.github.io/assets/portfolio/pathfinding3d-slides-en.pdf

Sample images from internet:

Attach NavMesh from an object that has been loaded

Instead of using NavMeshLoader, is it possible to take my navMesh from my blender scene that I already loaded using GFTL loader?

Also can a NavMesh be updated by adding removing polygons after it has been applied?

Error when using NavMesh

I am trying to use code from the first person example, I have successfully loaded my model and then loaded my NavMesh. I set this successfully on the entity. I see my model fine and can see the NavMesh on the floor thanks to the NavMeshHelper.

The issue is that when I update the controls in the animate function I get this error:

Uncaught Error: YUKA.NavMesh.clampMovement(): No current region available.

If I comment this line, then I see the scene again, I can rotate but cannot move around with the arrow keys. The example is on my github if you manage any time to look at the problem.

https://github.com/Coder2012/3d-game-vue

"Force required" is ill-defined

// The steering force returned by this method is the force required,

The calculation gives a difference of velocities. Given the assumption in SteeringBehavior.js that mass=1, it is still only the force needed to move from one velocity to the other in one time unit. This simple calculation biases it to a position past the target, with the bias depending on the magnitude of the force.

SteeringManager considers the maximal force of the vehicle and applies the behaviors by priority, but note that if the Seek behavior were really prioritized, it should know the maximal vehicle force before its calculation, and adjust the calculation accordingly. The simple calculation could be used as is, but scaling the magnitude to the max force.

Alternatively, the max force could be used even better, to minimize the bias, as I did in a school project once. This is for 2D, but can perhaps inspire a similar 3D solution:

function seekAcc(pa,va, pg, aMax) {
	let d = delta(pa,pg);
	let r = length(d);
	//Important check to avoid division by zero:
	if (r === 0) {
		return [0,0];
	}	
	let dir = scale(d, 1/r);
	
	//RT coordinates will be useful:
	let vr = dot(va,dir);
	let vt = dot(va, rotate(dir, 0.5*Math.PI));
	let theta = angle(dir);
	
	//Trusting to find a fixed point by iteration
	//(this decision must be verified mathematically):
	let ar = aMax, at=0;
	let dat = Infinity;
	while (ar !==0 && Math.abs(dat) > 0.0001*aMax) {
		let srt = (vr**2+2*r*ar)**0.5;
		let t1 = (-vr-srt)/ar;
		let t2 = (-vr+srt)/ar;
		let t = t1 > 0 ? t1 : t2;
		let atn = Math.max(-aMax,Math.min(aMax,-2*vt/t));
		dat = atn-at;
		at = atn;
		ar = (aMax**2 -(at**2))**0.5;
	}
	
	return rotate([ar,at], theta);
}

Rough derivation:

	First, estimate time to impact from vr and aMax only:
	r-vr*t-0.5*aMax*t**2 = 0
	t = (-vr +-sqrt(vr**2+2*r*aMax))/aMax
	
	Using this t, find the offset caused by the tangential velocity:
	offset = vt*t
	
	Try to compensate for the offset, by applying an acceleration opposing vt:
	offset = vt*t + 0.5*at*t**2 = 0
	Assuming t is the same:
	at = -2*vt/t
	
	But then
	ar = sqrt(aMax**2-(2*vt/t)**2) < aMax
	and
	t = (-vr +-sqrt(vr**2+2*r*ar))/ar

You can see it in action here, in comparison to a naïve seek:
https://eliashasle.github.io/swarm2d-experiments/Behavior_Seek_comparison.html
(Just refresh the page to get different random scenarios)

May I contribute to this project?

Hey @Mugen87 , how do you feel about my contributing to Yuka? I'm trying to use it for my game but I think it could use some added functionality. How would you feel about me sending you small PR's from time to time?

Additional examples with PixiJS?

Hey, really like the project! I'm trying to use this with a Pixi.js game. Having trouble understanding how to use sprites from pixi for the steering behaviors (specifically seek) and your examples are generally using three.js.

Could you provide a basic demo with pixi?

Building navmesh

After bunch of tests I figured out that NavMeshLoader() considers a tris (triangles) of the mesh as a separate regions only if the mesh (and all the tris of it) is twisted - e.g. tris have different y-coord and are not belonging to one plane.
Otherwise it either builds a large regions from many tris on plane or just hangs the browser (if there are > than say 100 of tris).

E.g. I add a plane in Blender => Triangulate faces (quad becomes separated in two tris) => Subdivide it 4-times and when doing that have to set a tiny amount of "Fractal" (in order the surface of the plane would bend-twist a little bit). This way NavMeshLoader() loads the mesh and considers each tri as a separate region.
When the the "Fractal" option in "Subdivide" window is set to 0, the surface stays flat. This way NavMeshLoader() either could not load the mesh (when subdivided in 10) or builds large regions.

The question is - is it a correct behavior or I miss here smthg?

navmeshBlender

Question: NavMesh

I have some vehicles that are controlled by steering behaviors, I'm not sure how to combine this with mesh navigation such that the vehicles steering behavior is bounded to the surface of the heightmap mesh I'm using. Is this possible and is it a supported behavior/usecase?

For example, the steering behavior pursuit follow and wander create a force that drives each vehicle, but does that produce a target that I can use the the on path steering behavior with?

From the looks of it, there is a target that I can use to combine with the on path steering?
image

Constrain an Entity to the centre of navmesh regions

When using navmesh.findPath(from, to), the resulting path will hit the edges of poligons so that it is the shortest path possible.

When using this with a clampMovement, the Entity can collide with the wall and slow down while it slides along.

How could we ensure the Entity stays away from the walls (maybe in the centre of each region) so that it doesn't collide?

Steering handling in `Vehicle.update()` ignores `GameEntity.maxTurnRate`

I am currently experimenting in combining goals and steering.
I just stumbled over the fact that steering behavior application in Vehicle completely ignores the maxTurnRate defined in GameEntity.

I wonder if we should make steering in Vehicle aware of the maxTurnRate, as technically a vehicle is a derived class from GameEntity and therefore should adhere to the same constraints?

I feel however that implementing it will break existing functionality, as one can disable MovingEntity.updateOrientation.

So we have currently the following feature matrix (ordered by class inheritance):

Method maxTurnRate supported updateOrientation supported steering supported
GameEntity.update() true false false
MovingEntity.update() false (problem) true false
Vehicle.update() false (problem) true true
  • What do you think? How shall we improve the situation?
  • What are the long term goals in yuka regarding the classes?
  • Shall the various pieces be combinable (change to composition pattern for the entity classes) or, as it currently is, remain inheritance pattern?

This is amazing!

How do you generate navmeshes? Is there a way to do it dynamically at runtime?

Cool project!! I've been waiting for something like this for a while!

WanderBehavior within Navmesh

Hi Guys!,

Is it possible to apply a e.g. WanderBehavior within a NavMesh? - I mean a vehicle would wander aimlessly within bounds of a NavMesh?
Or one can use only pathes in Navmesh?

Flyweight pattern of Behaviours lost when reloading JSON

Typically, entities of similar types often share similar behavior instances within their own steering managers to save on memory usage, duplication of data or simply managing certain shared contexts. A caveat with reloading back a scene of entities via JSON is the lack of referencing to track potentially shared behaviors. Perhaps, behaviours could be factored out to a different location in the JSON outside of entity scope, with a Map<Instance, ID> lookup for json references.

Non-terminating while loop

In an attempt to get around the large mesh issue I was talking about here I watered down the detail of the 3d geometry of the mesh and then split it into six parts resulting in this gltf file. That seems to have helped as I now get stuck further down the pipeline of loading the navmesh, here:

	/**
	* Returns true if the polygon is convex.
	*
	* @param {Boolean} ccw - Whether the winding order is CCW or not.
	* @return {Boolean} Whether this polygon is convex or not.
	*/
	convex( ccw = true ) {

		let edge = this.edge;

		do {

			const v1 = edge.tail();
			const v2 = edge.head();
			const v3 = edge.next.head();

			if ( ccw ) {

				if ( leftOn( v1, v2, v3 ) === false )	return false;

			} else {

				if ( leftOn( v3, v2, v1 ) === false ) return false;

			}

			edge = edge.next;

		} while ( edge !== this.edge );

		return true;

	}

I put a deactivated debugger stopping point inside the do-while block, and let it run until it hit an endless loop cycle, then I was able to pause execution inside this code. From there I ran this snippet:

let arr = []
while (edge && edge.vis2 === undefined) {
    arr.push(edge)
    edge.vis2 = true
    arr.push(edge)
    edge = edge.next
}
console.log(arr.length)
console.log(arr.indexOf(this.edge))

The length of the array was 16, and arr.indexOf(this.edge) returns -1, so that proves that the while loop will never terminate.

Is there any way to add obstacles dynamically on a 2D grid?

Hi !

I'm currently working on a small video game where players have to barricade their characters inside a house by putting furnitures along some "open walls" to block the path to prevent ennemies from getting to them.

The main problem is the dynamic nature of the game, we move blocking objects thus we change the valid paths present in the grid.

I have created a 2D grid using GraphUtils.createGridLayout and tried two different ways to "update" the graph dynamically.

First, I tried removing nodes in the graph where there are blocking objects but alas, it did not work well, the paths I then got were incorrect and sometimes not even continuous.

Then, I tried to simply update manually the cost of certain nodes' edges so that they would be less likely to be consider better suited for the path. It works but I wonder if there is a better approach?

Could you recommand anything? Is there a special value we can use to make certain nodes "unwalkable"?

Thanks in advance!

Agent avoids Meshes

Hi and thanx a lot for a great library!
Is it possible for agents (e.g. PursuitBehavior) to avoid meshes (boxes) by pursuing - like ObstAvoidanceBehavior, - but without marking the obstacles as GameEntities? E.g. a lot of trees/boxes.
How would you implement it?

NavMesh.clampMovement: may get stuck at corners

From the code implementation it's pretty obvious that this may happen, since it only considers 1 single edge ("the closest one") from start position, instead of a set of multiple border edges along the contour. Also, wouldn't there be a case where the "closest edge" from start position may not necessarily be the edge you are colliding against? With only one "closest edge" being tested, what about potentially other edges that might be collided against further along the swept movement's volume? For fast moving objects, this can be an issue. Also, by "closest edge", the back-facing edges in relation to the movement's direction might be picked, and thus deal no effect?

image

As above, looking down onto navmesh in first person view. Red arrow indicates direction of movement... Since slided position lies outside of T bounds of clamping "closest" edge (indicated in blue), attempt to check if still within navmesh resgion is done. Because it no longer lies within navmesh region, a force reset to start position is done in the current implementation. Rather than force-reset, consider using the T value along edge to get the respective connecting incident portal edge by getting the T vertex (for T > 1 and T < 0 respectively), and repeat process with new closest border edge on neighboring polygon (find: border edge of neighboring polygon's T complement vertex === T vertex on clamping edge) to test along the actual contour. (by complement vertex meaning match: a.prev.vertex matches with b.vertex or a.vertex matches with b.prev.vertex respectively.).

In the event new border edge along contour is back-facing in relation sliding movement direction (thus, that border-edge isn't actually the true exiting border edge), find the closest front-facing border edge to sliding movement direction on neighboring polygon instead. If there are no such exiting border edges for such a neighboring polygon, then use the closest portal edge front-facing to sliding direction to check for the next neighboring polygon in order to find the exiting border-edge.

NavMesh.getClosestRegion a better approach?

The getClosestRegion is rather moot since it uses a naive distance to centroid which isn't very accruate. It should calculate it based on whether the point lies within the region bounds (in 2D), and if so, maybe use a distance to plane as a metric (or maybe downward ray distance to plane?). If it doesn't lie within region bounds, then check distance to closest edge on polygon.

It could also consider (maybe given an allowance setting?), the CellSpacePartioninig (if available), to speed up the query and zero in on cells that lie within the allowance setting from the point. Currently, this is only supported for getRegionForPoint(pt) method. For the case of querying multiple cells, visited polygons ma be marked as "dirty" for the given timestamp ID query. eg.

// for each query
timestamp++;
// .....
if (polygon.__myNavTimeStamp !== timestamp) {
   polygon.__myNavTimeStamp  = timestamp;
    // process polygon
 }

to avoid visiting polygon twice. (or maybe a Set to check for visited polygons).

Why not use something like getClosestRegion( point , allowance?, resultPt?) ....which can optionally get the resultPt that is clamped closest to the navmesh region. Also, during findPath(), in the event the start point lies OUTSIDE the navmesh, a dummy prior starting straight line route leading from current position to the clamped start position (closest to start) can be done.

I'd probably do up this feature later if/when I need it though.

CellSpacePartioning may also work quite well with a raycast, (probably an optional seperate utility), using a step-based DDA routine to only capture cells along the ray path, prefably with a max distance limit.

As of now, I must ensure that the input points given to the function always lie within the navmesh for optimal results.

how to judge arriveBehave over

sorry for my pool english . i was wrtting a program to show a vehicle movement. i want a vehicle move to my target , so i use arriveBehave class. everytime the vehicle arrive the target ,the program will generate next target position. my problem is i don't know how to judge a arriveBehave is over , i try to use arriveBehaveObj.active to judge , but failed,and the vehicle move past the target and then return

Clamp Quaternion (Rotation)

How would you clamp a quaternion (rotation rate on ZorX-axis)?

We have a plane - XZ-axis, an agent (PursuingBehavior) and an evader. Due to collisions between an agent and an evader (Cannon.js fits very well to Yuka) an evader jump up on Y-axis and an agent tries to follow it - moving on the Y-axis too.
An agent rotates its forward up to position of an evader (direction to target) and then (when the evader falls down on a plane) rotates-dives down (direction to target again).

I've managed to clamp Y-position of an Agent - so it would not go after an evader up - it just waits for it on the plane-Y (0.). I did by simple: IF(agent.position.y >2){agent.position = 2}.
But in meantime an agent rotates around XZ-axis up to lookup to target (evader) and then rotates down when the evader falls.

I've tried to clamp a quaternion of an agent (like Y-position), but erfloglos - no success.
How would you clamp a rotation of an agent betweeen say PI/4 (up) and zero angle of a planeXZ?

wolfyQuaternion2
wolfyQuaternion

How to correctly export a NavMesh from Blender 2.8

I am interested in how the NavMesh example works. I decided to import the mesh into Blender 2.8 (I’m a very proficient Blender user), and after adding a couple of extra triangles to form another poligon I exported this using .gltf + .bin combined.

When loading this back into the demo, I get the following error:

YUKA.NavMeshLoader: Unable to load navigation mesh. Error: YUKA.NavMeshLoader: Invalid geometry format. Please ensure to represent your geometry as triangles.

Can anyone share their export settings as there’s quite a few, maybe my export settings are incorrect.

Missed out re-sort case for PriorityQueue, potentially duplicate enqueing during Graph search?

Unforutnately, I am unable to replicate a test case whereby the shortest path tree already has something registered ... ie. if this._shortestPathTree.has(edge.to).

Compare:
https://github.com/Mugen87/yuka/blob/master/src/graph/search/Dijkstra.js#L113
https://github.com/Mugen87/yuka/blob/master/src/graph/search/AStar.js#L130

versus:

https://github.com/Glidias/Asharena/blob/master/src/arena/pathfinding/GKDijkstra.hx#L116-L131
https://github.com/Glidias/Asharena/blob/master/src/arena/pathfinding/GKAstar.hx#L52-L63

I noticed your implementation does not check if the candidate destination node being considered already exists in priority queue for typical re-sort. (Rather than push new entry to priority queue). Is this deliberate? I was wondering if BinaryHeap structure is an exception to this when it comes to priority queues.., but other implementations like what i see here https://github.com/Habrador/Self-driving-vehicle/blob/master/Self-driving%20vehicle%20Unity/Assets/Scripts/Pathfinding/Hybrid%20A%20star/HybridAStar.cs#L275 also does explicitly check for already existing re-sorts rather than direct push.

BVH: Optimize preparation of geometry data.

There are some minor side issues like the constructor parameters documentation ordering for BVH.js doesn't match the ordering of the function parameters.

Also, from fromMeshGeometry() method could consider additional approaches (in the event of already referencing non-indexed geometry for the parameter, to avoid cloning the Meshgeometry via the toPolygonSoup() call). I understand that cloning does provide stability in case the original mesh geometry may had been altered via some other apps, but I guess seperating out fromMeshGeometry() into two seperate functions (.. ie. another function that avoids calling toPolygonSoup() cloning/conversion process, may be considered to allow bypassing additional cloning for certain application cases.

Yuka and Babylon.js

This is actually not an issue, just a question.
Are there any examples of Yuka implementation with Babylon.js?

Efficient way to find an intersection

Hi guys,

what would be a most efficient way to find an intersection between given entities?
Say, we have static entities and a vehicle. Naive approach would be to iterate all entities each worldstep and compare their boundig spheres with a BS of vehicle. But if we have 100 entities it would have an impact on game perfomance.
Is there any variant in Yuka that makes intersection's search more efficient?
I guess may be a Cell division (cell-space partitioning) has smthg to do with it, but not sure...

jsdoc contradiction to code in GameEntity

I just created typescript definitions for all types in yuka (I wonder if I should submit them as PR here) and found that we have a contradiction in return types in GameEntity.js

yuka/src/core/GameEntity.js

Lines 202 to 216 in 6314fd6

/**
* Executed when this game entity is updated for the first time by its {@link EntityManager}.
*
* @return {GameEntity} A reference to this game entity.
*/
start() {}
/**
* Updates the internal state of this game entity. Normally called by {@link EntityManager#update}
* in each simulation step.
*
* @param {Number} delta - The time delta.
* @return {GameEntity} A reference to this game entity.
*/
update( /* delta */ ) {}

See, we define that we are returning this, while we are in fact a void method.

I wonder what the real intention is here, as I personally do not see any benefit in chaining either method (To be honest, most methods in GameEntity won't be chained in real life applications).

Shall we now add the missing return this or update the jsdoc to reflect @return void?

How to generate NavMesh automatically?

I'm just start to learn game AI. Is there any methods in the lib to create NavMesh from a glb automatically? or Is there other tools I should use to create these navmesh?

SteerBehavior - Vehicle facing the wrong direction

Hi! I'm quite new to threejs and 3d stuff in general and I've been experimenting the SteeringBehavior.

I recently purchased a model from sketchfab and basically my goal is to have the model follow the cursor around in a 2d plane. The model seems to be following the target (point of the cursor) just fine, but the model is facing the wrong way.

Loading the gltf file:

let dog;
    const gltfLoader = new GLTFLoader();
    
    gltfLoader.load('./premium_wolf/source/model.gltf', (gltcScene) => {
      dog = gltcScene;
      dog.scene.matrixAutoUpdate = false; 
      vehicle.setRenderComponent(dog.scene, sync);
      scene.add(dog.scene);
    });

Applying seek behavior to vehicle/my model:

    const seekBehavior = new YUKA.ArriveBehavior(target.position, 2, 1); 
    vehicle.steering.add(seekBehavior);

Output:
Peek 2022-09-22 03-09

Expected Behavior:

  • Head should be facing towards the target (and not the butt :p)

Is there a way to rotate the model while the steering behavior is active?

Polygon.getPortalEdge left/right confusion

Regarding getPortalEdgeTo(), i noticed the left/right assignments appear to be .prev.vertex and .vertex respesctively. Does htis mean that the left/right refers to the dirction relative to being outside the polygon instead of being inside? I'm kind of onfused by the convention with regards to what is "left"/"right" for portal edge data structure as it appears to be flipped in the other way if you consider "left" as "left from inside the polygon". Since polygon edges are winded counter-clockwise, it doesn't appear to make sense if "left" is {left:this.prev.vertex} when "right" should alawys refer to previous vertex since counter-clockwise motion goes from right to left...., (and if using right hand convention along flow direction, it's asssumed the polygon normals should point inwards?)

Perhaps, you should document about the portal data structure and what is "right"/"left" exactly according to certain conventions and make it consistent.

Additionally, maybe getPortalEdgeTo is not very useful generally, and maybe it should just be something more generic like getEdgeTo():HalfEdge, since it appears getPortalEdgeTo is only used by Navmesh and may be better off being used within NavMesh class only instead.

I suspect, assuming you are refering to the old post code from dijesting duck, maybe he had it as if the polygons were wounded clockwise so you deliberately flipped it on purpose to get it to work?

Integrate with collision/physics engine?

Anyway of integrating flocking and various entity behaviours with any given collision/physics engine/solver? Also, what about integrating with NAvmesh ClampMovement + among agent radius itself. Would probably require after entityManager.update() to set to this.velocity to some physics force (maybe even save prevPosition before entityManager.update(), then update entity positions again based off physics engine's entities instead? (to cancel away default this.position.copy( target );)

how to set initial mesh

sorry for my pool english. 1. i want to load a .fbx model as a vehicle mesh,and use arriveBehave class to simulate a scraper move. model load is success, but model is too large and position is not good, i have to scale the model and set the inital position. but when i set mesh.matrixAutoUpdate too false, all my initial set is not work. i am a noob to three js, thans for your reply。2. i want the model don't turn the direction when arrive the target and move to the next target , is there a paremeter to control behave ?
`loader.load('model/pingcangji.fbx', function (object) {
object.traverse(function (child) {
if (child.isMesh) {
child.castShadow = true;
child.receiveShadow = true;
child.scale.x = child.scale.y = child.scale.z = 0.5;

        //yukavehicle.setRenderComponent(child, sync);
        child.rotation.x = Math.PI;
        child.rotation.y = 0;
        child.matrixAutoUpdate = false;
    }
});
object.position.x = 9 * positionWidth;
object.position.y = 10 * positionWidth;
object.position.z = 90;
object.visible = true;
scene.add(object);

});`

Can I run this in a server?

I want to add AI controlled enemies to my multiplayer three.js game. How would I go about running this on a server?

Question/Discussion - Vehicle movement: PathBehaviours

Vehicles steered by a combination of onPathBehaviour/followPathBehaviour do not stop a their last waypoint, but overshoot and turn around afterwards. This can be "fixed" by either increasing the tolerance (makes to vehicle stop ahead to the last point) or changing their related weights. A weight ratio 1/100 seems to stop the character early, but this makes it skip edges of the navMesh (though the path is calculated appropriately). I tried to set .radius to make it follow the path more conscientiously, but no effect.
This occurs in a variety of examples (either 3rd party & yuka published). 1
Since documentation tells my to use followPath together with the onPath behaviour to realize accurate path following, but examples do not show this, I like to ask for an opinion on how to address/fix this. 2

I am confused by _arrive and _seek properties wihtin a followPathBehaviour. Are these used to move the character to the last waypoint of the path and manage deceleration distance and brake force? Since both receive a single target (no path) to go to, solely navigating with these in conjunction with a navMesh seems unwanted. Why are these present / named with a leading underscore?

The box-farming lady approaches her missing boxes just fine, but she does not use navMeshes and is controlled by with a single arriveBehaviour (Girl.js: 37ff, Goals.js: 217ff). 3 Ideally, I'd like to have her movement on an accurate (pre-calculated) path within the navMesh.

MathUtils.area() misleading

I think you left out *0.5 to the result. For the purpose of Coridoor/Convexity calculations where you just need to check the sign, understandably this is left out, but as a standalone function, .area() is expected to return some form of "area"? Then again, the function name itself is misleading because it doesn't clarify whether the "area" is a 2D area vs 3D area . (Based on the method, it's actualy area2DDoubled...)

Is there a certain trick to making a NavMesh

I'm trying to create a NavMesh from my game map. In Blender, I copied all of the faces I want to be navigable by the Vehicle. Then I export it as a GLTF. Does it matter that the faces are double sided?

Navmesh appears smaller than it really is

I created a simple plane in Blender, removed a couple of faces from it, added triangulate modifier and exported as GLB (tried also with GLTF + bin) but when i load it with NavMeshLoader it appears smaller on screen, without any reason.

Is there any custom property i need to add when i export it?

Here is how it appears:
Seven 16-5-2020 17-53-16

Here are my export settings in Blender:
Annotazione 2020-05-16 175556

Navmesh.clampMovement with Vehicle flocking behaviours

I have trouble Navmesh.clampMovement to play nicely with a various Vehicle flocking/[path behavious among multiple agents this to work (or maybe it's due to other things). Based on your experience, is this possible? Would be nice to have an example of it.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.