AR.js icon indicating copy to clipboard operation
AR.js copied to clipboard

Raycaster is off center or scaled based on window size

Open maximus123123 opened this issue 4 years ago • 27 comments

Do you want to request a feature or report a bug? Bug

What is the current behavior? OnClick events and the raycaster will give the wrong scaling of the model depending on the size of the screen resulting in missing the target when it should hit or hitting the target when it should miss. If the current behavior is a bug, please provide the steps to reproduce. add a mouse down event in the basic example then click next the torus knot or just above/below it

	function mousedown( event ) {
		var raycaster = new THREE.Raycaster();
		var mouse = new THREE.Vector2();
		mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1
		mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1
		event.stopPropagation(); 
		raycaster.setFromCamera( mouse, camera );
		var intersects =raycaster.intersectObjects([mesh],true);
		console.log(intersects);
		if (intersects.length>0) {
			alert("clicked");
		}
	}
	window.addEventListener( 'mousedown', mousedown, false );

Please mention other relevant information such as the browser version, Operating System and Device Name Chrome on PC and Phone What is the expected behavior? Accurate mousedown events causing the correct If this is a feature request, what is motivation or use case for changing the behavior?

maximus123123 avatar Mar 05 '20 21:03 maximus123123

Hi @maximus123123 , thank you! Does it happens also with the other examples?

kalwalt avatar Mar 06 '20 08:03 kalwalt

Hi @maximus123123 , thank you! Does it happens also with the other examples?

I believe so. Heres another person with the same issue: https://github.com/jeromeetienne/AR.js/issues/584

The issue, I think, It's either the camera: The camera view perhaps is different as you need to change the example's camera from new THREE.Camera to THREE.PerspectiveCamera.

Or the canvas size isn't updating correctly the size correctly for the calculation thus giving the wrong calculation. I have tried using vector3 as well but it didn't help

maximus123123 avatar Mar 06 '20 09:03 maximus123123

Thank you @maximus123123, we also need to know which version of Ar.js are you using, at the moment we have ar.js and ar-nft.js because they use different version of jsartoolkit5: the first the oldest the last the newest version with NFT. Maybe this bug occur the oldest but not the newest version? Please tell me exactly you setup. :slightly_smiling_face:

kalwalt avatar Mar 06 '20 12:03 kalwalt

It occurs in the old and new version. Both "basic" setups make the issue occur and the issue has existed for a while. Resizing the window will make it better then worse again depending on how far you resize.

I am currently using the new basic version: https://github.com/AR-js-org/AR.js/blob/master/three.js/examples/basic.html

maximus123123 avatar Mar 06 '20 12:03 maximus123123

Ok thank you so much! We will see how to fix this, i have not a clear idea how to solve now.

kalwalt avatar Mar 06 '20 13:03 kalwalt

Are you able to reproduce the error?

maximus123123 avatar Mar 06 '20 13:03 maximus123123

Are you able to reproduce the error?

i will try later if i have time. :smile:

kalwalt avatar Mar 06 '20 13:03 kalwalt

@maximus123123 with the basic example i got this error:

three.min.js:869 THREE.Raycaster: Unsupported camera type.
setFromCamera @ three.min.js:869
mousedown @ basic.html:151
basic.html:153 []

i tested only on Desktop (Ubuntu 18.04.03)

kalwalt avatar Mar 06 '20 17:03 kalwalt

I will look deeper into it when i have time, maybe it's not a bug, probably needs the right setup. :smile:

kalwalt avatar Mar 06 '20 17:03 kalwalt

Right, you need to change THREE.Camera to THREE.PerspectiveCamera

maximus123123 avatar Mar 08 '20 14:03 maximus123123

@maximus123123 , try to replace this part:

mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1

with this:

var rect = renderer.domElement.getBoundingClientRect();
mouse.x = ( (event.clientX - rect.left) / rect.width ) * 2 - 1
mouse.y = - ( (event.clientY - rect.top) / rect.height ) * 2 + 1

XiaNi avatar Mar 21 '20 07:03 XiaNi

I am using ar.js with aframe and have similar problem. If I am not using embedded on the a-scene images and videos are distorted and clicks accurate but when I use embedded ratios of elements (images, video) are correct but clicks are off target big time.

Andraz89 avatar Mar 30 '20 06:03 Andraz89

Same issues here. The targets are off, and they're off in different ways depending on if its a mobile sized screen or a regular desktop/laptop.

Here's a link to my codepen with the issue: https://codepen.io/riggitynick/pen/MWaOOeb?editors=1010

There are 3D shapes, and when you click on them, they should vanish, the targets are off a bit(and in really strange ways-weather I open it on my phone or laptop).

riggitynick avatar May 04 '20 23:05 riggitynick

Is this problem solved?

I have been developing similar functions recently and have the same problem as this post and this one

In my test It seems that the ratio of the video element (arjs-video) and canvas does not match, will causes the raycaster coordinates to be distorted

raycaster I usage

cursor="rayOrigin: mouse" 
raycaster="objects: .collidable"

Coordinate formula of rayOrigin (A-frame official built-in, aframe.js)

registerComponent('cursor' ...
    ...
    ......
    left = point.clientX - bounds.left;
    top = point.clientY - bounds.top;
    mouse.x = (left / bounds.width) * 2 - 1;
    mouse.y = -(top / bounds.height) * 2 + 1;

Very similar to @XiaNi provided above

My Test

version

A-frame: 0.9.2
ar.js: 3.1.0

Test Methods

I will generate a object (3D model) on the AR marker, and click on the object with the mouse to stick on a small ball at the click position to display the raycaster coordinates.

Situation.1

<a-scene
     embedded
     arjs="sourceWidth:640; sourceHeight:480; displayWidth: 1920; displayHeight: 1440;">

The ratio of display (1920x1440) is setting to same as the source (640x480), both are 4:3.

  • At 1920x1440 in the browser screen The ratio scale of 3D model and raycaster coordinates are displayed perfectly. The ball is perfectly at the position of the object I clicked. Because 640x480 and 1920x1440 are both 4:3 ratio.

  • At 1920x1080 in the browser screen The ratio scale of the 3D model is displayed perfectly, but the raycaster coordinates will be distorted. The position of the ball has offset. Because 640x480 is 4:3 and 1920x1080 is 16:9 ratio.

In the above cases, due to different screen heights, the offset can be clearly seen as the closer to the upper and lower sides of the screen, the greater the Y-axis offset, and the closer to the center point, the smaller the offset.

BTW, other screen tests can also have perfect results as long as the screen ratio setting same as source. In this case (source=640x480, 4:3) like 1280x960/2560x1920 (4:3) can also work perfectly.

Situation.2

<a-scene
     embedded
     arjs="sourceWidth:640; sourceHeight:360; displayWidth: 1920; displayHeight: 1080;">

The ratio of source (640x360) is setting to same as the display (1920x1080), both are 16:9.

  • At 1920x1080 in the browser screen It looks like I should get the result I want. Unfortunately, the raycaster coordinates are displayed perfectly. And the ball is also perfectly at the position of the object I clicked. BUT the ratio scale of the 3D model is distorted...

So, it seems that I cannot adjust the ratio of source to match the display. It can only adjust the display to match the source ratio. But as long as the display and source ratios are different, the raycaster coordinates will be distorted. Otherwise, rewrite the coordinate formula of rayOrigin?

It is difficult to ensure that the camera (source) and screen resolution (display) supported by each device will be in the same ratio. Like the browser window can also adjust the screen size at will.

Any suggestions? Or this problem already correcting? Thanks!

aoimewo avatar Jun 05 '20 07:06 aoimewo

Hi. I'm also having similar issue while using AFrame and click handling. Did anyone find a solution?

mikeSBIT avatar Jan 14 '21 15:01 mikeSBIT

how to solve this problem?

williamqian avatar Jan 28 '21 10:01 williamqian

hello @kalwalt, do you have any news related to this issue ? thanks !

Bramichou avatar May 17 '21 22:05 Bramichou

Hi anyone have an update on this problem???

dynamic-rick avatar Jul 28 '21 07:07 dynamic-rick

Hey, people. I've fallen in this problem as well. It seems to happen only with embedded component as I've tested on #66. Here's a visual evidence about this issue: output

Markkop avatar Aug 16 '21 19:08 Markkop

Hello there! I've managed to fix this problem by following this Stackoverflow Question and attaching a cursor component after the scene is initialized

const scene = AFRAME.scenes[0];
if (!scene) {
  return;
}
const mouseCursor = document.createElement('a-entity');
mouseCursor.setAttribute('cursor', 'rayOrigin', 'mouse');
scene.appendChild(mouseCursor);

I hope this can help us to fix the problem in its source :v:

Markkop avatar Oct 01 '21 14:10 Markkop

Thank you!! I'll try this soon....


DYNAMIC MANAGEMENT GROUP LTD.

ADDRESS: Room A, 4th Floor Sing Teck Factory Bldg. 44 Wong Chuk Hang Road, Hong Kong Tel: +852-26633524 Cell: +852-90888971

Dynamic Events and Marketing Specialist https://.dynevents.com https://www.dynevents.com

KidsGOLF - the fastest way to learn golf. https://.kidsGOLF.hk https://www.kidsGOLF.hk

On Fri, 1 Oct 2021 at 22:14, Marcelo Kopmann @.***> wrote:

Hello there! I've managed to fix this problem by following this Stackoverflow Question https://stackoverflow.com/questions/67519054/wrong-position-of-a-clickable-object-on-ar-js-scene/67534948#67534948 and attaching a cursor component after the scene is initialized

const scene = AFRAME.scenes[0]; if (!scene) {

return; } const mouseCursor = document.createElement('a-entity'); mouseCursor.setAttribute('cursor', 'rayOrigin', 'mouse'); scene.appendChild(mouseCursor);

I hope this can help us to fix the problem in its source ✌️

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/AR-js-org/AR.js/issues/40#issuecomment-932267095, or unsubscribe https://github.com/notifications/unsubscribe-auth/AOXFELGSBUQQEOCNDVEPG23UEW6ZTANCNFSM4LCTD5XQ .

dynamic-rick avatar Oct 02 '21 03:10 dynamic-rick

Hello there! I've managed to fix this problem by following this Stackoverflow Question and attaching a cursor component after the scene is initialized

const scene = AFRAME.scenes[0];
if (!scene) {
  return;
}
const mouseCursor = document.createElement('a-entity');
mouseCursor.setAttribute('cursor', 'rayOrigin', 'mouse');
scene.appendChild(mouseCursor);

I hope this can help us to fix the problem in its source ✌️

This worked for me! I basically just created a new Component and attached it to the . The component is like this:

AFRAME.registerComponent('custom-cursor', {
    init: function () {
        setTimeout(() => {
            const scene = AFRAME.scenes[0];
            const mouseCursor = document.createElement('a-entity');
            mouseCursor.setAttribute('cursor', 'rayOrigin', 'mouse');
            mouseCursor.setAttribute('raycaster', 'objects', '.clickable');
            scene.appendChild(mouseCursor);
        }, 2000);
    },
});

and then just <a-scene arjs embedded custom-cursor>...</a-scene>

I was literally looking for an answer for days and finally came across the solution.

Yzuriha avatar Mar 06 '22 14:03 Yzuriha

Hello, @Yzuriha thanks for your answer that helped me a lot. However when I tried your example, the target intersection seems to be with the marker rather than the entity which has ".clickable" class. (I'm trying to use it, with an <a-plan> which is taller than my marker)

I tried different things, but none of them work.

This line has no effect, Raycaster only detect intersection inside marker area mouseCursor.setAttribute('raycaster', 'objects', '.clickable');

If you have a solution, I'm a taker !

val14-98 avatar Mar 08 '22 15:03 val14-98

Hey everyone I've created this little example to show how you can make it work with aframe 0.9.2. Unfortunately it doesn't work with more recent versions than that :( https://glitch.com/edit/#!/aframe-ar-js-issue Hope this will help while this isn't fixed. the working example works without the embedded tag too :D

Anulo2 avatar Apr 08 '22 10:04 Anulo2

Same here with Aframe 1.2 :( Does not work, not even with @Yzuriha or @Markkop 's workarounds. Any other ideas?

aaweb avatar Jun 07 '22 09:06 aaweb

Has anyone examined the source code of this demo from 8th Wall? How did they overcome this problem? https://templates.8thwall.app/placeground-aframe/ with mobile tablet or phone

Curacao-lb avatar Nov 08 '23 09:11 Curacao-lb