Pārlūkot izejas kodu

Raycaster: Added setFromXRController() (#27801)

* Raycaster: Added setFromXRController().

* Docs: Added setFromXRController() to Raycaster.

* Clean up.
mrdoob 1 gadu atpakaļ
vecāks
revīzija
49d425cb91

+ 45 - 39
docs/api/ar/core/Raycaster.html

@@ -8,55 +8,55 @@
 	</head>
 	</head>
 	<body class="rtl">
 	<body class="rtl">
 		<h1>[name]</h1>
 		<h1>[name]</h1>
-	 
+
 		<p class="desc">
 		<p class="desc">
 			تم تصميم هذه الفئة للمساعدة في
 			تم تصميم هذه الفئة للمساعدة في
 			[link:https://en.wikipedia.org/wiki/Ray_casting raycasting]. يتم استخدام Raycasting
 			[link:https://en.wikipedia.org/wiki/Ray_casting raycasting]. يتم استخدام Raycasting
 			لاختيار الماوس (العمل على معرفة الكائنات في المساحة ثلاثية الأبعاد التي يكون عليها الماوس
 			لاختيار الماوس (العمل على معرفة الكائنات في المساحة ثلاثية الأبعاد التي يكون عليها الماوس
 			فوق) من بين أشياء أخرى.
 			فوق) من بين أشياء أخرى.
 		</p>
 		</p>
-	 
+
 		<h2>مثال الكود</h2>
 		<h2>مثال الكود</h2>
 		<code>
 		<code>
 		const raycaster = new THREE.Raycaster();
 		const raycaster = new THREE.Raycaster();
 		const pointer = new THREE.Vector2();
 		const pointer = new THREE.Vector2();
-	 
+
 		function onPointerMove( event ) {
 		function onPointerMove( event ) {
-	 
+
 		// حساب موضع المؤشر في إحداثيات الجهاز المعتدلة
 		// حساب موضع المؤشر في إحداثيات الجهاز المعتدلة
 		// (-1 إلى +1) لكلا المكونين
 		// (-1 إلى +1) لكلا المكونين
-	 
+
 		pointer.x = ( event.clientX / window.innerWidth ) * 2 - 1;
 		pointer.x = ( event.clientX / window.innerWidth ) * 2 - 1;
 		pointer.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
 		pointer.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
-	 
+
 		}
 		}
-	 
+
 		function render() {
 		function render() {
-	 
+
 		// تحديث شعاع التقاط مع الكاميرا وموضع المؤشر
 		// تحديث شعاع التقاط مع الكاميرا وموضع المؤشر
 		raycaster.setFromCamera( pointer, camera );
 		raycaster.setFromCamera( pointer, camera );
-	 
+
 		// حساب الكائنات المتقاطعة مع شعاع التقاط
 		// حساب الكائنات المتقاطعة مع شعاع التقاط
 		const intersects = raycaster.intersectObjects( scene.children );
 		const intersects = raycaster.intersectObjects( scene.children );
-	 
+
 		for ( let i = 0; i < intersects.length; i ++ ) {
 		for ( let i = 0; i < intersects.length; i ++ ) {
-	 
+
 		intersects[ i ].object.material.color.set( 0xff0000 );
 		intersects[ i ].object.material.color.set( 0xff0000 );
-	 
+
 		}
 		}
-	 
+
 		renderer.render( scene, camera );
 		renderer.render( scene, camera );
-	 
+
 		}
 		}
-	 
+
 		window.addEventListener( 'pointermove', onPointerMove );
 		window.addEventListener( 'pointermove', onPointerMove );
-	 
+
 		window.requestAnimationFrame(render);
 		window.requestAnimationFrame(render);
-	 
+
 		</code>
 		</code>
-	 
+
 		<h2>أمثلة (Examples)</h2>
 		<h2>أمثلة (Examples)</h2>
-	 
+
 		<p>
 		<p>
 			[example:webgl_interactive_cubes Raycasting to a Mesh]<br />
 			[example:webgl_interactive_cubes Raycasting to a Mesh]<br />
 			[example:webgl_interactive_cubes_ortho Raycasting to a Mesh in using an OrthographicCamera]<br />
 			[example:webgl_interactive_cubes_ortho Raycasting to a Mesh in using an OrthographicCamera]<br />
@@ -68,9 +68,9 @@
 			[example:webgl_interactive_voxelpainter Raycasting to paint voxels]<br />
 			[example:webgl_interactive_voxelpainter Raycasting to paint voxels]<br />
 			[example:webgl_raycaster_texture Raycast to a Texture]
 			[example:webgl_raycaster_texture Raycast to a Texture]
 		</p>
 		</p>
-	 
+
 		<h2>المنشئ (Constructor)</h2>
 		<h2>المنشئ (Constructor)</h2>
-	 
+
 		<h3>[name]( [param:Vector3 origin], [param:Vector3 direction], [param:Float near], [param:Float far] )</h3>
 		<h3>[name]( [param:Vector3 origin], [param:Vector3 direction], [param:Float near], [param:Float far] )</h3>
 		<p>
 		<p>
 			[page:Vector3 origin] — متجه المنشأ الذي يلقي منه الشعاع.<br />
 			[page:Vector3 origin] — متجه المنشأ الذي يلقي منه الشعاع.<br />
@@ -82,64 +82,64 @@
 			أقل من قريب. القيمة الافتراضية هي Infinity.
 			أقل من قريب. القيمة الافتراضية هي Infinity.
 		</p>
 		</p>
 		<p>هذا يخلق كائن raycaster جديد.<br /></p>
 		<p>هذا يخلق كائن raycaster جديد.<br /></p>
-		 
+
 		<h2>الخصائص (Properties)</h2>
 		<h2>الخصائص (Properties)</h2>
-		 
+
 		<h3>[property:Float far]</h3>
 		<h3>[property:Float far]</h3>
 		<p>
 		<p>
 			عامل بعيد للraycaster. هذه القيمة تشير إلى الكائنات التي يمكن
 			عامل بعيد للraycaster. هذه القيمة تشير إلى الكائنات التي يمكن
 			تجاهلها بناءً على المسافة. هذه القيمة لا يجب أن تكون سلبية و
 			تجاهلها بناءً على المسافة. هذه القيمة لا يجب أن تكون سلبية و
 			يجب أن تكون أكبر من خاصية قريب.
 			يجب أن تكون أكبر من خاصية قريب.
 		</p>
 		</p>
-		 
+
 		<h3>[property:Float near]</h3>
 		<h3>[property:Float near]</h3>
 		<p>
 		<p>
 			عامل قريب للraycaster. هذه القيمة تشير إلى الكائنات التي يمكن
 			عامل قريب للraycaster. هذه القيمة تشير إلى الكائنات التي يمكن
 			تجاهلها بناءً على المسافة. هذه القيمة لا يجب أن تكون سلبية و
 			تجاهلها بناءً على المسافة. هذه القيمة لا يجب أن تكون سلبية و
 			يجب أن تكون أصغر من خاصية بعيد.
 			يجب أن تكون أصغر من خاصية بعيد.
 		</p>
 		</p>
-		 
+
 		<h3>[property:Camera camera]</h3>
 		<h3>[property:Camera camera]</h3>
 		<p>
 		<p>
 			الكاميرا المستخدمة عند التصوير بالأشعة ضد كائنات تعتمد على المشهد مثل
 			الكاميرا المستخدمة عند التصوير بالأشعة ضد كائنات تعتمد على المشهد مثل
 			كائنات billboarded مثل [page:Sprites]. يمكن تعيين هذا الحقل يدويًا أو
 			كائنات billboarded مثل [page:Sprites]. يمكن تعيين هذا الحقل يدويًا أو
 			يتم تعيينه عند استدعاء "setFromCamera". افتراضات إلى null.
 			يتم تعيينه عند استدعاء "setFromCamera". افتراضات إلى null.
 		</p>
 		</p>
-		 
+
 		<h3>[property:Layers layers]</h3>
 		<h3>[property:Layers layers]</h3>
 		<p>
 		<p>
 			يستخدم من قبل [name] لتجاهل كائنات 3D بشكل اختياري عند إجراء
 			يستخدم من قبل [name] لتجاهل كائنات 3D بشكل اختياري عند إجراء
 			اختبارات التقاطع. يضمن المثال التالي للكود أن كائنات 3D فقط على طبقة `1` ستحظى باحترام من قِبَل المثيل من [name].
 			اختبارات التقاطع. يضمن المثال التالي للكود أن كائنات 3D فقط على طبقة `1` ستحظى باحترام من قِبَل المثيل من [name].
-		 
+
 			<code>
 			<code>
-			raycaster.layers.set( 1 ); 
-			object.layers.enable( 1 ); 
+			raycaster.layers.set( 1 );
+			object.layers.enable( 1 );
 			</code>
 			</code>
 		</p>
 		</p>
-		 
+
 		<h3>[property:Object params]</h3>
 		<h3>[property:Object params]</h3>
 		<p>
 		<p>
 			 كائن به الخصائص التالية:
 			 كائن به الخصائص التالية:
-		 
+
 			<code>
 			<code>
-			{ 
+			{
 			Mesh: {},
 			Mesh: {},
 			Line: { threshold: 1 },
 			Line: { threshold: 1 },
 			LOD: {},
 			LOD: {},
 			Points: { threshold: 1 },
 			Points: { threshold: 1 },
-			Sprite: {} 
+			Sprite: {}
 			}
 			}
 			</code>
 			</code>
-		 
+
 			حيث threshold هو دقة raycaster عند التقاط
 			حيث threshold هو دقة raycaster عند التقاط
 			كائنات، في وحدات العالم.
 			كائنات، في وحدات العالم.
 		</p>
 		</p>
 
 
 		<h3>[property:Ray ray]</h3>
 		<h3>[property:Ray ray]</h3>
 		<p>ال[Page:Ray] المستخدم للتصوير بالأشعة.</p>
 		<p>ال[Page:Ray] المستخدم للتصوير بالأشعة.</p>
-		 
+
 		<h2>الوظائف (Methods)</h2>
 		<h2>الوظائف (Methods)</h2>
-		 
+
 		<h3>[method:undefined set]( [param:Vector3 origin], [param:Vector3 direction])</h3>
 		<h3>[method:undefined set]( [param:Vector3 origin], [param:Vector3 direction])</h3>
 		<p>
 		<p>
 			[page:Vector3 origin] — متجه المنشأ الذي يلقي منه الشعاع.<br />
 			[page:Vector3 origin] — متجه المنشأ الذي يلقي منه الشعاع.<br />
@@ -150,7 +150,7 @@
 			يحدث الشعاع بمنشأ واتجاه جديد. يرجى ملاحظة أن هذا
 			يحدث الشعاع بمنشأ واتجاه جديد. يرجى ملاحظة أن هذا
 			الطريقة تنسخ فقط القيم من الوسائط.
 			الطريقة تنسخ فقط القيم من الوسائط.
 		</p>
 		</p>
-		 
+
 		<h3>[method:undefined setFromCamera]( [param:Vector2 coords], [param:Camera camera] )</h3>
 		<h3>[method:undefined setFromCamera]( [param:Vector2 coords], [param:Camera camera] )</h3>
 		<p>
 		<p>
 			[page:Vector2 coords] — إحداثيات 2D للماوس، في تعديل جهاز
 			[page:Vector2 coords] — إحداثيات 2D للماوس، في تعديل جهاز
@@ -158,7 +158,13 @@
 			[page:Camera camera] — الكاميرا التي يجب أن ينبثق منها الشعاع
 			[page:Camera camera] — الكاميرا التي يجب أن ينبثق منها الشعاع
 		</p>
 		</p>
 		<p>يحدث الشعاع بمنشأ واتجاه جديد.</p>
 		<p>يحدث الشعاع بمنشأ واتجاه جديد.</p>
-		 
+
+		<h3>[method:this setFromXRController]( [param:WebXRController controller] )</h3>
+		<p>
+			[page:WebXRController controller] — The controller to copy the position and direction from.
+		</p>
+		<p>Updates the ray with a new origin and direction.</p>
+
 		<h3>[method:Array intersectObject]( [param:Object3D object], [param:Boolean recursive], [param:Array optionalTarget] )</h3>
 		<h3>[method:Array intersectObject]( [param:Object3D object], [param:Boolean recursive], [param:Array optionalTarget] )</h3>
 		<p>
 		<p>
 			[page:Object3D object] — الكائن للتحقق من التقاطع مع
 			[page:Object3D object] — الكائن للتحقق من التقاطع مع
@@ -203,7 +209,7 @@
 			وجوه كائن، سترغب في تعيين خصائص [page:Mesh.material material]
 			وجوه كائن، سترغب في تعيين خصائص [page:Mesh.material material]
 			[page:Material.side side] إلى `THREE.DoubleSide`.
 			[page:Material.side side] إلى `THREE.DoubleSide`.
 		</p>
 		</p>
-		 
+
 		<h3>[method:Array intersectObjects]( [param:Array objects], [param:Boolean recursive], [param:Array optionalTarget] )</h3>
 		<h3>[method:Array intersectObjects]( [param:Array objects], [param:Boolean recursive], [param:Array optionalTarget] )</h3>
 		<p>
 		<p>
 			[page:Array objects] — الكائنات للتحقق من التقاطع مع
 			[page:Array objects] — الكائنات للتحقق من التقاطع مع

+ 10 - 4
docs/api/en/core/Raycaster.html

@@ -113,8 +113,8 @@
 			objects on layer `1` will be honored by the instance of [name].
 			objects on layer `1` will be honored by the instance of [name].
 
 
 			<code>
 			<code>
-raycaster.layers.set( 1 ); 
-object.layers.enable( 1 ); 
+raycaster.layers.set( 1 );
+object.layers.enable( 1 );
 			</code>
 			</code>
 		</p>
 		</p>
 
 
@@ -123,12 +123,12 @@ object.layers.enable( 1 );
 			An object with the following properties:
 			An object with the following properties:
 
 
 			<code>
 			<code>
-{ 
+{
 	Mesh: {},
 	Mesh: {},
 	Line: { threshold: 1 },
 	Line: { threshold: 1 },
 	LOD: {},
 	LOD: {},
 	Points: { threshold: 1 },
 	Points: { threshold: 1 },
-	Sprite: {} 
+	Sprite: {}
 }
 }
 			</code>
 			</code>
 
 
@@ -160,6 +160,12 @@ object.layers.enable( 1 );
 		</p>
 		</p>
 		<p>Updates the ray with a new origin and direction.</p>
 		<p>Updates the ray with a new origin and direction.</p>
 
 
+		<h3>[method:this setFromXRController]( [param:WebXRController controller] )</h3>
+		<p>
+			[page:WebXRController controller] — The controller to copy the position and direction from.
+		</p>
+		<p>Updates the ray with a new origin and direction.</p>
+
 		<h3>[method:Array intersectObject]( [param:Object3D object], [param:Boolean recursive], [param:Array optionalTarget] )</h3>
 		<h3>[method:Array intersectObject]( [param:Object3D object], [param:Boolean recursive], [param:Array optionalTarget] )</h3>
 		<p>
 		<p>
 			[page:Object3D object] — The object to check for intersection with the
 			[page:Object3D object] — The object to check for intersection with the

+ 13 - 7
docs/api/it/core/Raycaster.html

@@ -97,7 +97,7 @@
 
 
 		<h3>[property:Camera camera]</h3>
 		<h3>[property:Camera camera]</h3>
 		<p>
 		<p>
-      La telecamera da utilizzare durante il raycast contro oggetti dipendenti dalla vista, come oggetti su cartelloni pubblicitari 
+      La telecamera da utilizzare durante il raycast contro oggetti dipendenti dalla vista, come oggetti su cartelloni pubblicitari
       come [page:Sprites]. Questo campo può essere settato manualmente o viene impostato quando si chiama il metodo "setFromCamera".
       come [page:Sprites]. Questo campo può essere settato manualmente o viene impostato quando si chiama il metodo "setFromCamera".
 
 
       L'impostazione predefinita è null.
       L'impostazione predefinita è null.
@@ -156,12 +156,18 @@
 		  Aggiorna il raggio con una nuova origine e direzione.
 		  Aggiorna il raggio con una nuova origine e direzione.
 		</p>
 		</p>
 
 
+		<h3>[method:this setFromXRController]( [param:WebXRController controller] )</h3>
+		<p>
+			[page:WebXRController controller] — The controller to copy the position and direction from.
+		</p>
+		<p>Updates the ray with a new origin and direction.</p>
+
 		<h3>[method:Array intersectObject]( [param:Object3D object], [param:Boolean recursive], [param:Array optionalTarget] )</h3>
 		<h3>[method:Array intersectObject]( [param:Object3D object], [param:Boolean recursive], [param:Array optionalTarget] )</h3>
 		<p>
 		<p>
 		[page:Object3D object] — L'oggetto da verificare per l'intersezione con il raggio.<br />
 		[page:Object3D object] — L'oggetto da verificare per l'intersezione con il raggio.<br />
-		[page:Boolean recursive] — Se true, controlla anche tutti i discendenti. Altrimenti controlla soltanto 
+		[page:Boolean recursive] — Se true, controlla anche tutti i discendenti. Altrimenti controlla soltanto
     l'intersezione con l'oggetto. Il valore predefinito è true.<br />
     l'intersezione con l'oggetto. Il valore predefinito è true.<br />
-		[page:Array optionalTarget] — (opzionale) obiettivo per impostare il risultato. 
+		[page:Array optionalTarget] — (opzionale) obiettivo per impostare il risultato.
     Altrimenti viene istanziato un nuovo [page:Array]. Se impostato, è necessario cancellare questo array prima di ogni chiamata (ad esempio, array.length = 0;).
     Altrimenti viene istanziato un nuovo [page:Array]. Se impostato, è necessario cancellare questo array prima di ogni chiamata (ad esempio, array.length = 0;).
 		</p>
 		</p>
 		<p>
 		<p>
@@ -183,8 +189,8 @@
 			[page:Integer instanceId] – Il numero di indice dell'istanza in cui il raggio interseca la InstancedMesh.
 			[page:Integer instanceId] – Il numero di indice dell'istanza in cui il raggio interseca la InstancedMesh.
 		</p>
 		</p>
 		<p>
 		<p>
-      `Raycaster` delega al metodo [page:Object3D.raycast raycast] dell'oggetto passato, 
-      quando valuta se il raggio interseca l'oggetto o no. Ciò permette alle mesh di rispondere 
+      `Raycaster` delega al metodo [page:Object3D.raycast raycast] dell'oggetto passato,
+      quando valuta se il raggio interseca l'oggetto o no. Ciò permette alle mesh di rispondere
       in modo diverso al raycasting rispetto alle linee e alle nuvole di punti.
       in modo diverso al raycasting rispetto alle linee e alle nuvole di punti.
 		</p>
 		</p>
 		<p>
 		<p>
@@ -197,14 +203,14 @@
 		<h3>[method:Array intersectObjects]( [param:Array objects], [param:Boolean recursive], [param:Array optionalTarget] )</h3>
 		<h3>[method:Array intersectObjects]( [param:Array objects], [param:Boolean recursive], [param:Array optionalTarget] )</h3>
 		<p>
 		<p>
       [page:Array objects] — Gli oggetti da controllare per l'intersezione con il raggio.<br />
       [page:Array objects] — Gli oggetti da controllare per l'intersezione con il raggio.<br />
-      [page:Boolean recursive] — Se true, controlla anche i discendenti degli oggetti. Altrimenti controlla soltanto 
+      [page:Boolean recursive] — Se true, controlla anche i discendenti degli oggetti. Altrimenti controlla soltanto
       l'intersezione con gli oggetti. Il valore predefinito è true.<br />
       l'intersezione con gli oggetti. Il valore predefinito è true.<br />
       [page:Array optionalTarget] — (opzionale) obiettivo per impostare il risultato.
       [page:Array optionalTarget] — (opzionale) obiettivo per impostare il risultato.
       Altrimenti viene istanziato un nuovo [page:Array]. Se impostato, è necessario cancellare questo array prima di ogni chiamata (ad esempio, array.length = 0;).
       Altrimenti viene istanziato un nuovo [page:Array]. Se impostato, è necessario cancellare questo array prima di ogni chiamata (ad esempio, array.length = 0;).
 		</p>
 		</p>
 		<p>
 		<p>
       Controlla tutte le intersezioni tra il raggio e gli oggetti con o senza i discendenti.
       Controlla tutte le intersezioni tra il raggio e gli oggetti con o senza i discendenti.
-      Le intersezioni sono restituite ordinate per distanza, prima le più vicine. Le intersezioni 
+      Le intersezioni sono restituite ordinate per distanza, prima le più vicine. Le intersezioni
       hanno la stessa forma di quelle restituite da [page:.intersectObject].
       hanno la stessa forma di quelle restituite da [page:.intersectObject].
 		</p>
 		</p>
 
 

+ 6 - 0
docs/api/ko/core/Raycaster.html

@@ -155,6 +155,12 @@
 		레이의 새 시점과 방향을 업데이트합니다.
 		레이의 새 시점과 방향을 업데이트합니다.
 		</p>
 		</p>
 
 
+		<h3>[method:this setFromXRController]( [param:WebXRController controller] )</h3>
+		<p>
+			[page:WebXRController controller] — The controller to copy the position and direction from.
+		</p>
+		<p>Updates the ray with a new origin and direction.</p>
+
 		<h3>[method:Array intersectObject]( [param:Object3D object], [param:Boolean recursive], [param:Array optionalTarget] )</h3>
 		<h3>[method:Array intersectObject]( [param:Object3D object], [param:Boolean recursive], [param:Array optionalTarget] )</h3>
 		<p>
 		<p>
 		[page:Object3D object] — 레이와의 교차 체크를 하는 객체입니다.<br />
 		[page:Object3D object] — 레이와의 교차 체크를 하는 객체입니다.<br />

+ 6 - 0
docs/api/zh/core/Raycaster.html

@@ -159,6 +159,12 @@
 			使用一个新的原点和方向来更新射线。
 			使用一个新的原点和方向来更新射线。
 		</p>
 		</p>
 
 
+		<h3>[method:this setFromXRController]( [param:WebXRController controller] )</h3>
+		<p>
+			[page:WebXRController controller] — The controller to copy the position and direction from.
+		</p>
+		<p>Updates the ray with a new origin and direction.</p>
+
 		<h3>[method:Array intersectObject]( [param:Object3D object], [param:Boolean recursive], [param:Array optionalTarget] )</h3>
 		<h3>[method:Array intersectObject]( [param:Object3D object], [param:Boolean recursive], [param:Array optionalTarget] )</h3>
 		<p>
 		<p>
 		[page:Object3D object] —— 检查与射线相交的物体。<br />
 		[page:Object3D object] —— 检查与射线相交的物体。<br />

+ 1 - 6
examples/jsm/interactive/InteractiveGroup.js

@@ -1,6 +1,5 @@
 import {
 import {
 	Group,
 	Group,
-	Matrix4,
 	Raycaster,
 	Raycaster,
 	Vector2
 	Vector2
 } from 'three';
 } from 'three';
@@ -61,7 +60,6 @@ class InteractiveGroup extends Group {
 		const scope = this;
 		const scope = this;
 
 
 		const raycaster = new Raycaster();
 		const raycaster = new Raycaster();
-		const tempMatrix = new Matrix4();
 
 
 		// TODO: Dispatch pointerevents too
 		// TODO: Dispatch pointerevents too
 
 
@@ -76,10 +74,7 @@ class InteractiveGroup extends Group {
 
 
 			const controller = event.target;
 			const controller = event.target;
 
 
-			tempMatrix.identity().extractRotation( controller.matrixWorld );
-
-			raycaster.ray.origin.setFromMatrixPosition( controller.matrixWorld );
-			raycaster.ray.direction.set( 0, 0, - 1 ).applyMatrix4( tempMatrix );
+			raycaster.setFromXRController( controller );
 
 
 			const intersections = raycaster.intersectObjects( scope.children, false );
 			const intersections = raycaster.intersectObjects( scope.children, false );
 
 

+ 1 - 5
examples/webxr_xr_cubes.html

@@ -38,7 +38,6 @@
 
 
 			let controller, controllerGrip;
 			let controller, controllerGrip;
 			let INTERSECTED;
 			let INTERSECTED;
-			const tempMatrix = new THREE.Matrix4();
 
 
 			init();
 			init();
 			animate();
 			animate();
@@ -208,10 +207,7 @@
 
 
 				// find intersections
 				// find intersections
 
 
-				tempMatrix.identity().extractRotation( controller.matrixWorld );
-
-				raycaster.ray.origin.setFromMatrixPosition( controller.matrixWorld );
-				raycaster.ray.direction.set( 0, 0, - 1 ).applyMatrix4( tempMatrix );
+				raycaster.setFromXRController( controller );
 
 
 				const intersects = raycaster.intersectObjects( room.children, false );
 				const intersects = raycaster.intersectObjects( room.children, false );
 
 

+ 1 - 5
examples/webxr_xr_dragging.html

@@ -36,7 +36,6 @@
 			let raycaster;
 			let raycaster;
 
 
 			const intersected = [];
 			const intersected = [];
-			const tempMatrix = new THREE.Matrix4();
 
 
 			let controls, group;
 			let controls, group;
 
 
@@ -219,10 +218,7 @@
 
 
 				controller.updateMatrixWorld();
 				controller.updateMatrixWorld();
 
 
-				tempMatrix.identity().extractRotation( controller.matrixWorld );
-
-				raycaster.ray.origin.setFromMatrixPosition( controller.matrixWorld );
-				raycaster.ray.direction.set( 0, 0, - 1 ).applyMatrix4( tempMatrix );
+				raycaster.setFromXRController( controller );
 
 
 				return raycaster.intersectObjects( group.children, false );
 				return raycaster.intersectObjects( group.children, false );
 
 

+ 1 - 4
manual/examples/webxr-point-to-select-w-move.html

@@ -128,7 +128,6 @@ function main() {
 			this.raycaster = new THREE.Raycaster();
 			this.raycaster = new THREE.Raycaster();
 			this.objectToColorMap = new Map();
 			this.objectToColorMap = new Map();
 			this.controllerToObjectMap = new Map();
 			this.controllerToObjectMap = new Map();
-			this.tempMatrix = new THREE.Matrix4();
 
 
 			const pointerGeometry = new THREE.BufferGeometry().setFromPoints( [
 			const pointerGeometry = new THREE.BufferGeometry().setFromPoints( [
 				new THREE.Vector3( 0, 0, 0 ),
 				new THREE.Vector3( 0, 0, 0 ),
@@ -190,9 +189,7 @@ function main() {
 			for ( const { controller, line } of this.controllers ) {
 			for ( const { controller, line } of this.controllers ) {
 
 
 				// cast a ray through the from the controller
 				// cast a ray through the from the controller
-				this.tempMatrix.identity().extractRotation( controller.matrixWorld );
-				this.raycaster.ray.origin.setFromMatrixPosition( controller.matrixWorld );
-				this.raycaster.ray.direction.set( 0, 0, - 1 ).applyMatrix4( this.tempMatrix );
+				this.raycaster.setFromXRController( controller );
 				// get the list of objects the ray intersected
 				// get the list of objects the ray intersected
 				const intersections = this.raycaster.intersectObjects( pickablesParent.children );
 				const intersections = this.raycaster.intersectObjects( pickablesParent.children );
 				if ( intersections.length ) {
 				if ( intersections.length ) {

+ 1 - 4
manual/examples/webxr-point-to-select.html

@@ -128,7 +128,6 @@ function main() {
 			this.raycaster = new THREE.Raycaster();
 			this.raycaster = new THREE.Raycaster();
 			this.objectToColorMap = new Map();
 			this.objectToColorMap = new Map();
 			this.controllerToObjectMap = new Map();
 			this.controllerToObjectMap = new Map();
-			this.tempMatrix = new THREE.Matrix4();
 
 
 			const pointerGeometry = new THREE.BufferGeometry().setFromPoints( [
 			const pointerGeometry = new THREE.BufferGeometry().setFromPoints( [
 				new THREE.Vector3( 0, 0, 0 ),
 				new THREE.Vector3( 0, 0, 0 ),
@@ -178,9 +177,7 @@ function main() {
 			for ( const { controller, line } of this.controllers ) {
 			for ( const { controller, line } of this.controllers ) {
 
 
 				// cast a ray through the from the controller
 				// cast a ray through the from the controller
-				this.tempMatrix.identity().extractRotation( controller.matrixWorld );
-				this.raycaster.ray.origin.setFromMatrixPosition( controller.matrixWorld );
-				this.raycaster.ray.direction.set( 0, 0, - 1 ).applyMatrix4( this.tempMatrix );
+				this.raycaster.setFromXRController( controller );
 				// get the list of objects the ray intersected
 				// get the list of objects the ray intersected
 				const intersections = this.raycaster.intersectObjects( pickablesParent.children );
 				const intersections = this.raycaster.intersectObjects( pickablesParent.children );
 				if ( intersections.length ) {
 				if ( intersections.length ) {

+ 14 - 0
src/core/Raycaster.js

@@ -1,6 +1,9 @@
+import { Matrix4 } from '../math/Matrix4.js';
 import { Ray } from '../math/Ray.js';
 import { Ray } from '../math/Ray.js';
 import { Layers } from './Layers.js';
 import { Layers } from './Layers.js';
 
 
+const _matrix = /*@__PURE__*/ new Matrix4();
+
 class Raycaster {
 class Raycaster {
 
 
 	constructor( origin, direction, near = 0, far = Infinity ) {
 	constructor( origin, direction, near = 0, far = Infinity ) {
@@ -53,6 +56,17 @@ class Raycaster {
 
 
 	}
 	}
 
 
+	setFromXRController( controller ) {
+
+		_matrix.identity().extractRotation( controller.matrixWorld );
+
+		this.ray.origin.setFromMatrixPosition( controller.matrixWorld );
+		this.ray.direction.set( 0, 0, - 1 ).applyMatrix4( _matrix );
+
+		return this;
+
+	}
+
 	intersectObject( object, recursive = true, intersects = [] ) {
 	intersectObject( object, recursive = true, intersects = [] ) {
 
 
 		intersectObject( object, this, intersects, recursive );
 		intersectObject( object, this, intersects, recursive );