Which steps should I take to simulate taking photo

Hi I want to simulate taking photo, not screenshot out of game, but the idea with picking is wrong
I want to capture for example the gem


and try this code obviously not good solution

/*jshint esversion: 6 */

class PickerFramebuffer extends pc.ScriptType {
  initialize() {
    this.app.mouse.on(pc.EVENT_MOUSEDOWN, this.takePhoto, this);
    this.picker = new pc.Picker(this.app, 1024, 1024);
  }
  takePhoto(e) {
    const picker = this.picker;
    picker.prepare(this.entity.camera, this.app.scene);

    const canvas = document.querySelector("#application-canvas");
    const canvasWidth = canvas.clientWidth;
    const canvasHeight = canvas.clientHeight;

    const selection = picker.getSelection({
      x: Math.floor(event.x * (picker.width / canvasWidth)),
      y: picker.height - Math.floor(event.y * (picker.height / canvasHeight)),
    });

    const selectedItem = selection[0];

    if (selection.length > 0 && selectedItem !== undefined) {
      const nodeName = selectedItem.node.name;

      console.log(selection);

      console.log(nodeName);
    }
  }

  update(dt) {}
}

pc.registerScript(PickerFramebuffer, "PickerFramebuffer");

picking works but issue is, is not correct with the game logic as taking photo,
I know its wrong because it must selects the thing but I want to capture instead some area with this thing for example the gem, if the gem is inside this area then console.log its name

Hi @grzesiekmq,

Just to understand, are you trying to take a screenshot (save to file) of only the Gem model, without including anything else in it?

If that’s the case, you can create a new layer and assign it to your gem and screenshot taking camera only. This way no other objects will be including in the screenshot.

no I just want to determine if the camera sees given object I try this but get the wrong predicate message

const screenPoint = new pc.Vec3();

this.entity.camera.worldToScreen(this.item.localPosition, screenPoint);

console.log(screenPoint);

const {x,y,z} = screenPoint;
const inFront = z > 0;
const isSeenByCamera = x > 0 && x < 1 && y > 0 && y < 1 && inFront;

if(isSeenByCamera){
    console.log(this.item.name);
}
else{
    console.log('sth wrong with isSeenByCamera predicate');
}

Ah I see, not sure if that’s the best approach here. A more precise approach is to use the following property for each mesh instance of the model:

https://developer.playcanvas.com/api/pc.MeshInstance.html#visibleThisFrame

But if you are ok with checking the location of the entity only, I think you can do the following:

const isPointVisible = this.entity.camera.frustum.containsPoint(this.item.getPosition());

In both cases make sure that frustum culling is enabled in your main camera.

3 Likes

ok got it but the issue is now I can’t figure out how to determine what camera sees,
I tried with adding script attribute of type entity and works, but I have more items :slight_smile:
I try following getting items with specific tag etc:

        const photoItems = this.items.findByTag('photoItem');
        const item = photoItems[0];

        let photoItem = '';
        let score = 0;

        switch(item.name){
            case 'Red Gem':
            photoItem = 'Red Gem';
            score = 50;
            break;
            case 'Football':
            photoItem = 'Football';
            score = 100;
            break;
        }

        const includesItem = item.name.includes(photoItem);

maybe find index but I doont know which index
so generally in pseudocode I want to find:
taggedItem == current seen item
so I assume sth like photoItems[currentSeenIndex] ?
so then I am close to solution

ok just for each loop

 takePhoto() {
        const photoItems = this.items.findByTag('photoItem');
        photoItems.forEach(item => {

            let photoItem = '';
            let score = 0;

            switch (item.name) {
                case 'Red Gem':
                    photoItem = 'Red Gem';
                    score = 50;
                    break;
                case 'Football':
                    photoItem = 'Football';
                    score = 100;
                    break;
            }

            const includesItem = item.name.includes(photoItem);

            console.log(photoItems);
            console.log(item);

            const isSeenByCamera = this.entity.camera.frustum.containsPoint(item.getPosition());

            if (isSeenByCamera && item.enabled && includesItem) {
                this.score += score;
                console.log(this.score);

                this.scoreUI.element.text = `Score: ${this.score}`;

                item.enabled = false;
            }

        });

    }
1 Like

Are you trying to do a Pokemon Snap style game?

maybe,
I mean as for now:
taking photo, adding score, so similar to endless runner but instead of running into the collectible just take photo,
this is very early concept generally
and little yes because I thought of some photodex or photedex like pokedex (so ‘database’ of photographed items with score maybe some wiki)