Entity picking using raycasting


#1

I am implementing Raycasting in my project for fetching rigid bodies but there is a weird behaviour as When I click on a wall it returns null but when I click on the white box it returns me the box.

When I disabled the physics layer from the wall it returned the wall.

1.Wall Has a Physics layer in which I have applied group and mask to the wall

2.There is a white box it does not have the physics layer applied on it

Game Link >> https://playcanv.as/p/BdJhF61O/

Scripts
/////////////////////////////////////////////////////////////////////
Raycasting.

var Raycasting = pc.createScript('raycasting');

// initialize code called once per entity
Raycasting.prototype.initialize = function() {
   
  this.app.mouse.on(pc.EVENT_MOUSEDOWN, this.onSelect, this);
};

Raycasting.prototype.doRayCast = function (screenPosition) {
    var cameraDepth = 29.5;
    // The vec3 to raycast from
    var from = this.entity.getPosition ();
    // The vec3 to raycast to 
    var to = this.entity.camera.screenToWorld(screenPosition.x, screenPosition.y,cameraDepth);

    
    // Raycast between the two points
    var result = this.app.systems.rigidbody.raycastFirst(from, to);
     console.log(result);
};


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

///////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////
PhysicsLayer._

var PhysicsLayer = pc.createScript('physicsLayer');

PhysicsLayer.attributes.add('groupA', {type: 'boolean', default: false, title: 'Group A'});
PhysicsLayer.attributes.add('groupB', {type: 'boolean', default: false, title: 'Group B'});
PhysicsLayer.attributes.add('groupC', {type: 'boolean', default: false, title: 'Group C'});
PhysicsLayer.attributes.add('groupD', {type: 'boolean', default: false, title: 'Group D'});
PhysicsLayer.attributes.add('groupE', {type: 'boolean', default: false, title: 'Group E'});
PhysicsLayer.attributes.add('groupF', {type: 'boolean', default: false, title: 'Group F'});
PhysicsLayer.attributes.add('groupG', {type: 'boolean', default: false, title: 'Group G'});
PhysicsLayer.attributes.add('groupH', {type: 'boolean', default: false, title: 'Group H'});

PhysicsLayer.attributes.add('maskAll', {type: 'boolean', default: true, title: 'Mask All'});
PhysicsLayer.attributes.add('maskA', {type: 'boolean', default: false, title: 'Mask A'});
PhysicsLayer.attributes.add('maskB', {type: 'boolean', default: false, title: 'Mask B'});
PhysicsLayer.attributes.add('maskC', {type: 'boolean', default: false, title: 'Mask C'});
PhysicsLayer.attributes.add('maskD', {type: 'boolean', default: false, title: 'Mask D'});
PhysicsLayer.attributes.add('maskE', {type: 'boolean', default: false, title: 'Mask E'});
PhysicsLayer.attributes.add('maskF', {type: 'boolean', default: false, title: 'Mask F'});
PhysicsLayer.attributes.add('maskG', {type: 'boolean', default: false, title: 'Mask G'});
PhysicsLayer.attributes.add('maskH', {type: 'boolean', default: false, title: 'Mask H'});

// initialize code called once per entity
PhysicsLayer.prototype.initialize = function() {
    var body = this.entity.rigidbody;

    // Groups
    if (this.groupA) {
        body.group |= (pc.BODYGROUP_USER_1);
    }

    if (this.groupB) {
        body.group |= (pc.BODYGROUP_USER_2);
    }

    if (this.groupC) {
        body.group |= (pc.BODYGROUP_USER_3);
    }

    if (this.groupD) {
        body.group |= (pc.BODYGROUP_USER_4);
    }

    if (this.groupE) {
        body.group |= (pc.BODYGROUP_USER_5);
    }

    if (this.groupF) {
        body.group |= (pc.BODYGROUP_USER_6);
    }

    if (this.groupG) {
        body.group |= (pc.BODYGROUP_USER_7);
    }

    if (this.groupH) {
        body.group |= (pc.BODYGROUP_USER_8);
    }

    // Masks
    // Reset the mask to 0 so that the engine defaults aren't used
    body.mask = pc.BODYGROUP_TRIGGER;

    if (this.maskAll) {
        body.mask |= (pc.BODYMASK_ALL);
    }

    if (this.maskA) {
        body.mask |= (pc.BODYGROUP_USER_1);
    }

    if (this.maskB) {
        body.mask |= (pc.BODYGROUP_USER_2);
    }

    if (this.maskC) {
        body.mask |= (pc.BODYGROUP_USER_3);
    }

    if (this.maskD) {
        body.mask |= (pc.BODYGROUP_USER_4);
    }

    if (this.maskE) {
        body.mask |= (pc.BODYGROUP_USER_5);
    }

    if (this.maskF) {
        body.mask |= (pc.BODYGROUP_USER_6);
    }

    if (this.maskG) {
        body.mask |= (pc.BODYGROUP_USER_7);
    }

    if (this.maskH) {
        body.mask |= (pc.BODYGROUP_USER_8);
    }
};


PhysicsLayer.prototype.setGroupMask = function(entity,value) {
    // console.log(entity +  value);
    var body1 = entity.rigidbody;
    switch(value)
    {
        case 1 :
            body1.group = (pc.BODYGROUP_USER_1);
            body1.mask = (pc.BODYGROUP_USER_1);
            break;

        case 2 :
            body1.group = (pc.BODYGROUP_USER_2);
            body1.mask = (pc.BODYGROUP_USER_2);
            break;

        case 3 :
            body1.group = (pc.BODYGROUP_USER_3);
            body1.mask = (pc.BODYGROUP_USER_3);
            break;

        case 4 :
            body1.group = (pc.BODYGROUP_USER_4);
            body1.mask = (pc.BODYGROUP_USER_4);
            break;

        case 5 :
            body1.group = (pc.BODYGROUP_USER_5);
            body1.mask = (pc.BODYGROUP_USER_5);
            break;

        case 6 :
            body1.group = (pc.BODYGROUP_USER_6);
            body1.mask = (pc.BODYGROUP_USER_6);
            break;

        case 7 :
            body1.group = (pc.BODYGROUP_USER_7);
            body1.mask = (pc.BODYGROUP_USER_7);
            break;

        case 8 :
            body1.group = (pc.BODYGROUP_USER_8);
            body1.mask = (pc.BODYGROUP_USER_8);
            break;



    }
};

///////////////////////////////////////////////////////////////////

Please help me with this as I have no idea why it is happening. Without Physics Layer script raycasting is working but with it is not

Thanks


#2

Can you reproduce the problem in a separate scene and provide a link to the project?


#3

Thanks @MasalovAndreey for replying, I have provided the scripts of my project and the link of the game. please see results in the console

Thanks


#4

The raycast function in the engine has a filter applied to it if I remember correctly so it doesn’t return results for triggers. setGroupMask sets the group directly rather than merging it with the existing groups that the engine already assigned to rigid bodies.

Either store the original groups and masks that the engine assigns at the start so you can merge with when you want to set the group and mask on the fly.

Or add a raycast method that accepts a filter.


#5

Thanks, @yaustar for replying, Could you please provide me a reference link for the resolution of my problem :slight_smile:

Thanks


#6

Unfortunately, there aren’t any as this is outside the PlayCanvas’ public API. It requires going through the engine source code and understandingthe Ammo physics library as well.


#7

OK, @yaustar Thanks, I will go through ammo.js and will let you know If I get my issue resolved :slight_smile:


#8

Hi, @yaustar I have got my issue resolved I just need to raycast filtering as I used one of your demos for filtered raycasting :slight_smile: Thank you so much for providing such demos.

Thanks