Awesome to see you here, @isaac-mason!!
That would be an awesome collab with @roland ![]()
Awesome to see you here, @isaac-mason!!
That would be an awesome collab with @roland ![]()
I’ve viewed the examples on navcat.dev, and they’re pretty cool.
Hey @isaac-mason! Great to have you here!
I believe maintaining backward compatibility of the interface is the top priority. More advanced or specialized scenarios can always be addressed by accessing navcat’s functionality directly.
I’m excited to collaborate and hear your thoughts on how we can align babylon.js’s navigation system with navcat in a practical way.
Let’s bring @Cedric into the discussion as well.
@Panuchka I know your project pushes the NavigationPlugin quite a bit, would love to get your input on this discussion as well!
https://navcat.dev/ examples are awesome! It looks very fast as well!
The goal of current Navigation API in Babylon is to be able to get crowds and navmesh in a few calls. I like this approach to get comething moving on screen quickly and then get more depth in the API and use cases. Babylon navigation was made a long time ago when WASM and compilation of native code was a bit more obscure. (same for performance). If navcat.dev is easy to integrate in a JS environment , I guess integration on Babylon would be limited to a few things like debug draw, mesh conversion,… something else?
I believe maintaining backward compatibility of the interface is the top priority. More advanced or specialized scenarios can always be addressed by accessing navcat’s functionality directly.
That is fair enough ![]()
I’m excited to collaborate and hear your thoughts on how we can align babylon.js’s navigation system with navcat in a practical way.
For sure, are you and others on the babylonjs discord or somewhere else @roland? Maybe we can discuss there more easily.
The goal of current Navigation API in Babylon is to be able to get crowds and navmesh in a few calls. I like this approach to get comething moving on screen quickly and then get more depth in the API and use cases.
…
If navcat.dev is easy to integrate in a JS environment , I guess integration on Babylon would be limited to a few things like debug draw, mesh conversion,… something else?
@Cedric I can understand the benefit of that ![]()
And I think your assessment on integrating navcat in a babylonjs project right now, without any navigation plugin work, is right.
I can see a few paths for serving babylon.js users:
Also +1 to the point that these are not mutually exclusive!
My Discord account got terminated a few weeks ago because of long inactivity
If you prefer Discord, I can hop back in anytime! Just not right now, I’m about to dive into the Navcat integration for babylon.js, and my desk’s already packed with work.
Let me talk it over with the team. @Cedric, I’ll dig into Navcat and put together a proposal, we can open the discussion after that. Are you OK with that?
@isaac-mason Thanks a lot!
Discord is probably easiest for me for quick responses or if you’re keen for a back and forth chat. You can DM me, and or find me and a few others following navcat and recast-navigation-js on the webgamedev discord, in the game-ai channel Web Game Dev. Otherwise I’ll keep an eye here and also on github issues.
I’ll wait to hear from you then, don’t hesitate to reach out! ![]()
Small update from my side. I’ve started working on a “navcat/blocks” package entrypoint that will contain higher level abstractions like “crowd”, “path corridor”, “preset generators”, “flow field pathfinding” etc.
Awesome !!!
Thank you for providing this new version of recast.js.![]()
I might have discovered a bug in babylonjs.addons.min.js(v8.33.4),maybe we should add a forced type conversion for TileCacheMeshProcess like this?
//@@@@create TileCacheMeshProcess instance
var h=c?rt(t):u?it(t):tt(t);
if(h.tileCacheMeshProcess)
h.tileCacheMeshProcess=new (Qe().TileCacheMeshProcess)((h.tileCacheMeshProcess));
Ortherwise it will cause a nullpointer error in recast.js.
Meanwhile,should we change the demo code in this page
if (avgY > 1.5) {
polyAreas.set(i,STAIRS_AREA)
polyFlags.set(i,STAIRS_FLAG)
//polyAreas[i] = STAIRS_AREA;//it dosen't work
//polyFlags[i] = STAIRS_FLAG;
} else {
polyAreas.set(i,DEFAULT_AREA)
polyFlags.set(i,WALK_FLAG)
//polyAreas[i] = DEFAULT_AREA;
//polyFlags[i] = WALK_FLAG;
}
@roland Before I found the notes on V2 I was working on integrating NavCat. I rounded it out with your v2 code. It’s frickin’ awesome how nicely Babylon and NavCat have enabled me to get something working.
Also I love the navMesh code already supports thininstances I thought that was gonna be a whole thing ![]()
Some very small notes I can contribute back :
1. ThinInstances that have a fully zero’d out matrix breaks NavCat
They cause navCat’s calculateMeshBounds to return a bounds object with NaNs.
This is likely to bite people as one heavily caveated (see below comments) way of ‘deleting’ a thinInstance is to just zero out it’s buffer data with thinInstanceSetMatrixAt.
To mitigate this I hacked up your getPositionsAndIndices code to include an unrolled loop style isAllZero check
if (mesh.hasThinInstances) {
worldMatrices.push(worldMatrix);
const thinMatrices = (mesh as Mesh).thinInstanceGetWorldMatrices();
for (let instanceIndex = 0; instanceIndex < thinMatrices.length; instanceIndex++) {
const tmpMatrix = new Matrix();
const thinMatrix = thinMatrices[instanceIndex];
thinMatrix.multiplyToRef(worldMatrix, tmpMatrix);
// Don't include fully zero'd matrices because they break NavCat's calculateMeshBounds
const m = tmpMatrix.m;
const isMatrixAllZero =
m[0] === 0 &&
m[1] === 0 &&
m[2] === 0 &&
m[3] === 0 &&
m[4] === 0 &&
m[5] === 0 &&
m[6] === 0 &&
m[7] === 0 &&
m[8] === 0 &&
m[9] === 0 &&
m[10] === 0 &&
m[11] === 0 &&
m[12] === 0 &&
m[13] === 0 &&
m[14] === 0 &&
m[15] === 0;
if (!isMatrixAllZero) {
worldMatrices.push(tmpMatrix);
}
}
} else {
worldMatrices.push(worldMatrix);
}
Ground plane
(top left original scene, right is aggregate mesh before sent to navCat, bottom left is navMesh result)
vs a box with 1 depth causing overlap
I’m not sure where this comes from as a “generally accepted way”.
What is the consequence of zeroing a matrix, is it effectively equivalent to setting the scale to 0?
I would rather decrement thinInstanceCount as listed in the doc, after copying a matrix if you’re not removing the last element. That would avoid executing the vertex shader for your deleted instances.
navcat (and recast from which the navmesh creation algorithm is taken) does not work with “solid” shapes but only treats a list of triangles. So the voxellization process may create holes, depending on your parameters (typically voxel size and walkable radius). Isaac did a great job at illustrating the process in navcat’s docs.
Checked and you’re right, it’s stated as a heavily caveated possibility, not an accepted way
Thankyou for the info, I’m deep in those docs at the moment figuring out why a flat meshified tilemap isn’t classed as walkable (bit offtopic but if anyone has any ideas
)![]()
Your response doesn’t quite answer my question though : I wasn’t sure what if any issues / perf this might cause. My gut and a quick goggle suggests avoiding islands may lead to better performance.
Apart from increased memory usage, you might encounter worse performance with polygon queries (such as findClosestPoint), but no difference with path queries, as the A* algorithm is only traveling through connected polygons. If your world is big, using tiles would already improve the general performance of polygon queries and limit the potential overhead with only a few more polygons per tile.
Also this is definitely offtopic so if you need more help with navcat, you should post on navcat’s github or the web game dev’s discord where Isaac is also present (link above in his message)