Fast 3D raycasting/collision Library / Scripts preview

NOTE: Now in beta.

A basic static environment collision detection library using legacy code implementations from Flash 3D engine Alternativa3D, ported over to JS for use in Playcanvas/(or any other JS engines) via a universal Haxe codebase to support varied collision/raycasting implementations. The purpose is to allow basic collision clipping of Ellipsoid volumes (including raycasting) against 3D environment without the overhead of using a physics engine. Some Playcanvas scripts are used to integrate with the collision engine itself. Also uses Javascript code from BVHTree to support highly performant collision detection/raycasting on collision Mesh geometry. I’ve ran smooth collision movement/physics on 50,000 to 100,1000 tri mesehes with no issues (ie. basic quake like movement). It would also run basic movement/collision simulations on simple things like bouncing balls, grenades, sticky mines, etc. , at high speed performance, though, you need to script those yourself.

Github links:

  • /AlternativaPlatform/Alternativa3D
  • /benraziel/bvh-tree

Currently used in:

What the library basically is?

  • It’s a collision scene graph that acts as a bridge to handle polygonal 3D collision environment detection.
  • Move collision scene graph nodes around (based off your implied/related game entities) and update their transforms/(optional bounding boxes) accordingly to match. You can also re-parent the nodes, remove them, or add new ones, etc. . This allows you to easily shift/stream-in objects if needed for different play setups.
  • EllipsoidCollider class to do collision/movement/destination queries on collision scene graph.
  • Raycaster class to do raycasting queries on collision scene graph.
  • Create your own customised collision-checkers by creating your own IRaycastImpl or ITCollidable implementations to best suit the type of 3D environment you are using. Whether it’s a KDTree, BSPTree, QuadTree, bounding volume hierachy, etc. the possibilities are endless.

What features does the package support when integrating the engine to Playcanvas?

  • collision-scene.js script to help build the collision engine’s scene graph which matches Playcanvas scene and any collision components/scripts/tagged nodes found within Playanva’s scene graph. Bounding boxes are generated over the geometry, and are expanded hierachically for ancestor nodes for optimal broadphase collision query traversal.
  • All collision primitives from Playcanvas. (sphere, capsule, box, cylinder) and collision meshes supported.
  • staticCollisionMesh.js script to help filter out meshInstances from a Model asset that you do not wish to be included in collision detections, (and also optionally for regular Playcanvas’ AmmoJS physics).
  • Low memory footprint and highly scalable. All geometries/collidable implementations of collision primitives and Model assets are cached/re-used throughout the entire collision scene for similar Models/collision primitive types. (In fact, I think Playcanvas did not cache Model assets for AmmoJS triMeshes, i think.) . You can repeat 10 times of the same Castle mesh across different transforms (positions/rotations/scales, etc.), and it will return the same collision geometry/implementation instance (usually a BVHTree) across the gameworld.

For Beta: (all done)

  • Proper attribute options for collision-scene.js script.
  • Object Bounding Volume Hierachy generation option for collision-scene.js script to generate OBject Bounding VOlume hierachy at that location instead of follow the scene graph hierachy of Playcanvas Collision/collisionBoundNode tagged) entities. I’m currently using code from Oimo Physic’s DBVT (dynaimc bounding volume tree) structure to handle the tree generation of objects in the scene. This will later be expanded to support hierchical frustum culling as well and a proper API to easily move objects about in the tree and update it. (from the Playcanvas entity references)

yagni features?:

  • Would clean up and provide some examples for end users: Example QPhysics script component for quick plug and play usage of common collision/movement query behaviours of Quake-style player movement/projectiles.
  • BVHTree Hierachy generation option for collision-scene.js script to generate a single BVHTree polygon soup object from all playcanvas collision entities to test against, instead of a scene graph.

RecastCLI integration workflow:

4 Likes

pretty pretty sweet ^^

i failed in copying each files in my own project “ThirdPersonFlying:: Failed to find collision scene!” @my own project : play editor

but succed with forking ur own project & uploading me land pretty nicely ( play )

something like me own charatere was moving by click, but nevermind, i have what i need for easy import & will handle me character like that for now.

here one :kiss: from here for that Keep It Stupid Simple way for the people like me

1 Like

Currently, the convention requires you to have a collision-scene.js script as the first “root” element to house all other nested collision entities. ( I’d have to later see how this can be configurable…) You also need the haxe.js and bvh-tree.js files from the global s folder and have those files loaded first in Script Loading Order.

There is a 2nd generation method option you can use in collision-scene.js that will generate its own bounding volume hierarchy instead of the default playcanvas scene graph structure. If using the default (first) option , and you wish for certain entity nodes to act as sub-hierarchical bounding volume parent containers in the collision scene, you must explicitly tag such entities as “collisionBoundNode”. See Warehouse QPhysics example on how it works.

For use of altern.Raycaster and altern.EllipsoidCollider within Playcanvas, refer to the orbit-camera script and CharacterDemo scripts.

I don’t have official documentation but this is some legacy doc here:
http://alternativaplatform.github.io/Alternativa3D/asdoc/8.32.SSAOEffect/alternativa/engine3d/collisions/EllipsoidCollider.html

The doc is actually not entirely correct for constructor. For altern.EllipsoidCollider constructor, 4th parameter is “threshold” and is for the minimal highest precision significant world sized unit for simulating movement that courts as “movement”. 5th parameter boolean is whether you wish to enable collision events or not. ( defaulted to false but for the case of the player controller working in conjunction with other codes to apply gravity and such, I had to use collisionEvents to check for normals of collision surfaces touched during calculateDestination() … to determine if character is on ground or not, prior to disposing/recycling them off back to pool with dispose function.

Raycaster usage doc comments can be found in source code at https://github.com/Glidias/Asharena/blob/master/src/altern/ray/Raycaster.hx
The export out compile class to altern namespace for use in Javascript can be found in src/MainJS.hx

:white_check_mark: working on me own project, was missing the collision-scene.js script as the first “root” element :sun_with_face:

have to patch again orbit-camera for my needs but that’s nothing

Hi, this is a very interesting approach to embed raycasting directly into PlayCanvas hierarchy. I could really make use of this, I ported the ioquake3/idtech3 engine to WebAssembly and I still use the BSP tracing for player movement. However, that is quite undynamic, when one “brush model” is changed, the complete map needs a recompile to .bsp and a reload.

I would like to test this, but I’m unsure about the license. MIT or BSD license e.g. would be very nice. Could you apply some license to this?

The license would mainly be Mozilla Public License, v. 2.0 . But i added more to the main git haxe repository based off the used libraries BVH-Tree and OimoPhysics Dynamic Bounding Volume Tree. (For an old legacy 2D demo of how OimoPhysics’ Dynamic Bounding Volume Tree broadphase works , here’s one in Flash: http://fl.corge.net/c/jA37 .)

Playcanvas hierachy with tagged nodes may/may not be used. There are 2 options in collision-scene.js generation methods.

  1. Playcanvas Hierachy Tagged Nodes (uses current playcanvas scene graph of entities with collision-related scripts/components, or tagged with collisionBoundNode)
  2. Dynamic Bounding Volume Tree (if the Playcanvas scene hierachy distribution of entities is not ideal for hierachical collision detection, uses this instead to let the script create a suitable hierachy for you)

BSP/KD/Quad/Oc trees has it’s advantages in raycasting performance because you can actually raycast the shortest distance node first ( due to split planes) and early exit out unlike bounding volume trees. But often, most modern games nowadays find this slight advantage unnecessary and bounding volume tree setups are more common/flexible (especially anyway if you do need to raycast across all intersections and not just the closest). Bsps also have bad reputation of unwanted/unavoidable geometry splits, requiring hint brushes and such for optimisation but may store/process more tris due to splits.

1 Like

hi Glenn & every body on earth ^^

Things going on here , have what i want with thrid-person-movement.js on main char & other entity following by his own with follow2.js & collision-scene.js.

Now last things am looking for, is collision for camera, as when climbing down the hill the camera can drive under the ground, or whenever u lower pitchAngleMin.

shall i work in thrid-person-movement.js script here :

if (gotMove && this.entityCamera  ) {
            var yaw  = this.entityCamera.script.orbitCamera._yaw;
            dummy.setLocalEulerAngles(0, yaw, 0);
            this.transformedVec.x = x;
            this.transformedVec.z = z;
            var newTranslate = dummy.getLocalTransform().transformVector( this.transformedVec, this.transformedVec );
            x = newTranslate.x;
            z = newTranslate.z;
        }

or patch in orbit-camera.js itself plz ?

am just figuring about, reading srcs, but feel uneasy as i want the camera collision with the ground, but could make some troubles with trees or “overgrounded” structures.

Under orbit-camera, did you turn on the raycastDistance checkbox? It should work automatically with the default collision scene if that’s the case.

If you need to “filter out” certain objects and not have them raycasted, you can tag those entities with noRaycast and it’ll not block the ray.

Likewise, entities can be tagged with noCollide to disable collision against ellipsoid.

But it looks like you have your trees baked in together with your Model entity… so it’s hard to seperate difference cases for that. Unless you resort to 2 duplicate entities (with different tags, one with noCollide and one with noRaycast) containing their own staticBodyModel script references to filter out the necessary meshInstance elements (via regex meshInstance names) for raycasting vs colliding respectively. staticBodyModel script reference can be found on Warehouse model in: https://playcanvas.com/editor/scene/635389

Take note that the tags only apply at initialization time. Applying/removing them during runtime has no effect whatsoever.

Your scene would actually benefit more with a Recast/Detour/Generic navmesh sort of system though…especially with the penguin follower since he’ll get lost/trapped without pathfinding. No such system exists in Playcanvas though and you have to create/find one for yourself.
https://github.com/vincent/recast.js - Very powerful…platform agnostic…and full featured with ability to build navmesh from OBJ file typically as well. Used in Unreal engine. Got crowd agent movement as well, cylindrical dynamic obstacle placements, etc… But this is an emscriptem port which is a hefty 4MB++ javascript file to download.
Below: the not so well-featured (no crowd/dynamic-obstacles/navmesh-generation), but worth porting to Playcanvas engine if possible… (actually, it should be ported over to altern Haxe code and simply use some generic altern.Geometry (or generic interface with .vertices/.indices getters) as a cross-platform vertices+indices geometry base that isn’t tied to any engine/platform. Sigh…)
https://github.com/donmccurdy/three-pathfinding
https://github.com/wanadev/babylon-navigation-mesh

Also, with navmesh, it’s possible to forego collision detection and just run movement script to constraint movement within navmesh as well.

got it ^^, thx, good for me.

i will work on that fbx to get only the meshes i want as ground, & will put house & vegetation as new entity, so am allmost good now with movements.

Need to take a look to UI & want to cast some fireballs asap u know ^^ (forked project so links will still available)

thx for library & links (more studies :scream:)