Picking using raycast - manual or collision

Trying to use “right” approach for doing picking in a scene of many objects some of which can be ignored (deep hierarchies).
Constraints:

  • All my objects procedurally generated with a top level encompassing entity and ignorable children.
  • Object is a mesh asset - simple box collision object of this is adequate for picking
  • on collision find the useful top entity node.

So reading through it looks like I want to either:

Doing my own raycasting

Raycast.prototype.initialize = function() {
    this.ray = new pc.Ray();
    // Register the mouse down and touch start event so we know when the user has clicked
    this.app.mouse.on(pc.EVENT_MOUSEDOWN, this.onMouseDown, this);
    // will push resulting collision position in here.
    this.hitPosition = new pc.Vec3();
    // Make the bbox shape of an entity
    this.aabbShape = new pc.BoundingBox(this.boxEntity.getPosition().clone(), this.boxEntity.getLocalScale().clone().scale(0.5));
};

Raycast.prototype.onMouseDown = function(event) {
    if (event.button == pc.MOUSEBUTTON_LEFT) {
        this.doRayCast(event);
    }};

Raycast.prototype.doRayCast = function (screenPosition) {
    // Initialise the ray and work out the direction of the ray from the a screen position
    this.cameraEntity.camera.screenToWorld(screenPosition.x, screenPosition.y, this.cameraEntity.camera.farClip, this.ray.direction); 
    this.ray.origin.copy(this.cameraEntity.getPosition());
    this.ray.direction.sub(this.ray.origin).normalize();
    var results = [];
    var result;
    for (var i=0;i<this.bboxes.length; i++) {
        var hitPosition = new pc.Vec3();
        result = this.bboxes[i][0].intersectsRay(this.ray, hitPosition);
        // result here is just true or false.
        // hitPosition contains the 3space point hit
        if (result)
            results.push(this.bboxes[i][1]); // and maybe hitposition too
    }
    if (results.length > 0) {
        // the hitEntity = results[0]; // might not need a list for this - not sure...
    }
};

Using the collision system:

Raycast.prototype.initialize = function() {
    // Find the first entity in the hierarchy with the name 'Camera'
    this.cameraEntity = this.app.root.findByName('Camera');
    // Add a mousedown event handler
    this.app.mouse.on(pc.EVENT_MOUSEDOWN, this.mouseDown, this);
    // Here we have to have a collision component added to the nodes we care about.
    // haven't coded it ...
};

Raycast.prototype.mouseDown = function (e) {
    this.doRaycast(e);
};

Raycast.prototype.doRaycast = function (screenPosition) {
    // The vec3 to raycast from
    var from = this.cameraEntity.getPosition ();
    // The vec3 to raycast to 
    var to = this.cameraEntity.camera.screenToWorld(screenPosition.x, screenPosition.y, this.cameraEntity.camera.farClip);

    // Raycast between the two points
    var result = this.app.systems.rigidbody.raycastFirst(from, to);
    // here result is a combination of an entity, vector and point
};

Its not clear which is the preferred approach and how much overhead is in the systems.rigidbody approach ?
Is one of them preferred for hover type of detection as user moves mouse over scene ?

##Aside:##
(Also there is another system here: Collision Detection library updated for new scripting system. Not sure of its merits.
How do you find all these addons ? is there a registry ? )

Physics has a big overhead in my experience, especially with a lot of entities in the world. You can use the profiler to see your physics update time. AABB collision is ok if your entities are roughly box shaped, but even then as they rotate they get bent out of shape. You can tell this in the editor by watching the white AABB framing marks as you rotate things. So it kinda depends. Also going through every item in the scene and doing an AABB test is a huge overhead if there are many items. My levels typically could have 500+ items in them.

You linked my Collision library. I wrote that because of these limitations. It uses a grid approach which is the fastest method in a roughly flat world, although it outperformed physics by a wide margin on a sphere based game too.

So I check a grid for entities, raycast the matching ones AABB (and terminate there if Quick And Dirty is set) otherwise I raycast the collider or geometry. I also provide functions for raycasting complex concave meshes. I should point out that raycasts are only half of collision detection, that library of mine also does intersections and collision notifications.

So your choices for picking are:

  • Physics
  • AABB (but try to divide your world up if you have many entities)
  • Render the scene using a collision shader and sample the colour buffer (what the editor does)
  • Use my library
  • Write your own!

:slight_smile:

I don’t know of a registry - it would be a good idea,