Model not loading in Three.js webxr hit test

Hi,
I am trying to load my model in hit-test webxr example but its throwing an error and some time scene getting freeze tried to laod model from local folder still its not loading. i have given my code below,
please take a look and help me out to solve this issue.

CODE:

<!DOCTYPE html>
three.js ar - hit test
	<div id="info">
		<a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> ar - hit test<br/>(Chrome Android 81+)
	</div>

	<script type="module">

		import * as THREE from './build/three.module.js';
		import { ARButton } from './jsm/webxr/ARButton.js';
		import {OBJLoader2} from 'https://threejsfundamentals.org/threejs/resources/threejs/r115/examples/jsm/loaders/OBJLoader2.js';
		import {OBJLoader} from 'https://threejsfundamentals.org/threejs/resources/threejs/r115/examples/jsm/loaders/OBJLoader.js';
		
		//import {MTLLoader} from 'https://threejsfundamentals.org/threejs/resources/threejs/r115/examples/jsm/loaders/MTLLoader.js';
		import {MTLLoader} from 'https://threejs.org/examples/js/loaders/MTLLoader.js';
		import {MtlObjBridge} from 'https://threejsfundamentals.org/threejs/resources/threejs/r115/examples/jsm/loaders/obj2/bridge/MtlObjBridge.js';


		var container;
		var camera, scene, renderer;
		var controller;

		var reticle;

		var hitTestSource = null;
		var hitTestSourceRequested = false;

		var mtlLoader;
		var monkeymesh;

		init();
		animate();

		function init() {

			container = document.createElement( 'div' );
			document.body.appendChild( container );

			scene = new THREE.Scene();

			camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.01, 20 );

			var light = new THREE.HemisphereLight( 0xffffff, 0xbbbbff, 1 );
			light.position.set( 0.5, 1, 0.25 );
			scene.add( light );

			//

			renderer = new THREE.WebGLRenderer( { antialias: true, alpha: true } );
			renderer.setPixelRatio( window.devicePixelRatio );
			renderer.setSize( window.innerWidth, window.innerHeight );
			renderer.xr.enabled = true;
			container.appendChild( renderer.domElement );

			document.body.appendChild( ARButton.createButton( renderer, { requiredFeatures: [ 'hit-test' ] } ) );


			var geometry = new THREE.CylinderBufferGeometry( 0.1, 0.1, 0.2, 32 ).translate( 0, 0.1, 0 );
			var boxgeometry = new THREE.BoxBufferGeometry( 0.25, 0.25, 0.25 ).translate(0,0.1,0);

			////////////////////////////////////////////////////////////////////////////////////////////////
			mtlLoader = new THREE.MTLLoader();
					mtlLoader.setPath( "https://threejs.org/examples/models/obj/walt/" );
					mtlLoader.load( 'monkey.mtl', function( materials ) {

					materials.preload();

					var objLoader = new THREE.OBJLoader();
					objLoader.setMaterials( materials );
					objLoader.setPath( "https://threejs.org/examples/models/obj/walt/" );
					objLoader.load( 'monkey.obj', function ( object ) {

						monkeymesh = object;
						monkeymesh.position.setFromMatrixPosition( reticle.matrix );
						scene.add( mesh );

					} );

					} );

			function onSelect() {

				if ( reticle.visible ) {

					var material = new THREE.MeshPhongMaterial( { color: 0xffffff * Math.random() } );
					var mesh = new THREE.Mesh( boxgeometry, material );
					mesh.position.setFromMatrixPosition( reticle.matrix );
					//mesh.scale.y = Math.random() * 2 + 1;
					mesh.scale.set(0.25,0.25,0.25);
					scene.add( mesh );				
					

				}

			}

			controller = renderer.xr.getController( 0 );
			controller.addEventListener( 'select', onSelect );
			scene.add( controller );

			reticle = new THREE.Mesh(
				new THREE.RingBufferGeometry( 0.15, 0.2, 32 ).rotateX( - Math.PI / 2 ),
				new THREE.MeshBasicMaterial()
			);
			reticle.matrixAutoUpdate = false;
			reticle.visible = false;
			scene.add( reticle );

			//

			window.addEventListener( 'resize', onWindowResize, false );

		}
		

		function onWindowResize() {

			camera.aspect = window.innerWidth / window.innerHeight;
			camera.updateProjectionMatrix();

			renderer.setSize( window.innerWidth, window.innerHeight );

		}

		//

		function animate() {

			renderer.setAnimationLoop( render );

		}

		function render( timestamp, frame ) {

			if ( frame ) {

				var referenceSpace = renderer.xr.getReferenceSpace();
				var session = renderer.xr.getSession();

				if ( hitTestSourceRequested === false ) {

					session.requestReferenceSpace( 'viewer' ).then( function ( referenceSpace ) {

						session.requestHitTestSource( { space: referenceSpace } ).then( function ( source ) {

							hitTestSource = source;

						} );

					} );

					session.addEventListener( 'end', function () {

						hitTestSourceRequested = false;
						hitTestSource = null;

					} );

					hitTestSourceRequested = true;

				}

				if ( hitTestSource ) {

					var hitTestResults = frame.getHitTestResults( hitTestSource );

					if ( hitTestResults.length ) {

						var hit = hitTestResults[ 0 ];

						reticle.visible = true;
						reticle.matrix.fromArray( hit.getPose( referenceSpace ).transform.matrix );

					} else {

						reticle.visible = false;

					}

				}

			}

			renderer.render( scene, camera );

		}

	</script>
</body>

https://threejs.org/examples/models/obj/walt/monkey.mtl
https://threejs.org/examples/models/obj/walt/monkey.obj

Both URLs do not exist. So it’s not surprising that no model is displayed.

Sorry,

Here is the link for the model, this is also not working.

https://threejstesting.z13.web.core.windows.net/models/monkey.mtl
https://threejstesting.z13.web.core.windows.net/models/monkey.obj

With this (reduced) code the model is rendered on my system:

import * as THREE from 'https://cdn.jsdelivr.net/npm/three@0.118.3/build/three.module.js';
import { OBJLoader } from 'https://cdn.jsdelivr.net/npm/three@0.118.3/examples/jsm/loaders/OBJLoader.js';
import { MTLLoader } from 'https://cdn.jsdelivr.net/npm/three@0.118.3/examples/jsm/loaders/MTLLoader.js';

var container;
var camera, scene, renderer;
var controller;

var reticle;

var hitTestSource = null;
var hitTestSourceRequested = false;

var mtlLoader;
var monkeymesh;

init();
animate();

function init() {

	container = document.createElement( 'div' );
	document.body.appendChild( container );

	scene = new THREE.Scene();

	camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.01, 20 );
	camera.position.z = 10;

	var light = new THREE.HemisphereLight( 0xffffff, 0xbbbbff, 1 );
	light.position.set( 0.5, 1, 0.25 );
	scene.add( light );

	//

	renderer = new THREE.WebGLRenderer( { antialias: true, alpha: true } );
	renderer.setPixelRatio( window.devicePixelRatio );
	renderer.setSize( window.innerWidth, window.innerHeight );
	renderer.xr.enabled = true;
	container.appendChild( renderer.domElement );


	////////////////////////////////////////////////////////////////////////////////////////////////
	mtlLoader = new MTLLoader();
	mtlLoader.setPath( "./models/obj/monkey/" );
	mtlLoader.load( 'materials.mtl', function ( materials ) {

		materials.preload();

		var objLoader = new OBJLoader();
		objLoader.setMaterials( materials );
		objLoader.setPath( "./models/obj/monkey/" );
		objLoader.load( 'model.obj', function ( object ) {

			monkeymesh = object;
			scene.add( monkeymesh );

		} );

	} );

	var boxgeometry = new THREE.BoxBufferGeometry( 0.25, 0.25, 0.25 ).translate( 0, 0.1, 0 );

	function onSelect() {

		if ( reticle.visible ) {

			var material = new THREE.MeshPhongMaterial( { color: 0xffffff * Math.random() } );
			var mesh = new THREE.Mesh( boxgeometry, material );
			mesh.position.setFromMatrixPosition( reticle.matrix );
			//mesh.scale.y = Math.random() * 2 + 1;
			mesh.scale.set( 0.25, 0.25, 0.25 );
			scene.add( mesh );


		}

	}

	controller = renderer.xr.getController( 0 );
	controller.addEventListener( 'select', onSelect );
	scene.add( controller );

	reticle = new THREE.Mesh(
		new THREE.RingBufferGeometry( 0.15, 0.2, 32 ).rotateX( - Math.PI / 2 ),
		new THREE.MeshBasicMaterial()
	);
	reticle.matrixAutoUpdate = false;
	reticle.visible = false;
	scene.add( reticle );

	//

	window.addEventListener( 'resize', onWindowResize, false );

}


function onWindowResize() {

	camera.aspect = window.innerWidth / window.innerHeight;
	camera.updateProjectionMatrix();

	renderer.setSize( window.innerWidth, window.innerHeight );

}

//

function animate() {

	renderer.setAnimationLoop( render );

}

function render( timestamp, frame ) {

	if ( frame ) {

		var referenceSpace = renderer.xr.getReferenceSpace();
		var session = renderer.xr.getSession();

		if ( hitTestSourceRequested === false ) {

			session.requestReferenceSpace( 'viewer' ).then( function ( referenceSpace ) {

				session.requestHitTestSource( { space: referenceSpace } ).then( function ( source ) {

					hitTestSource = source;

				} );

			} );

			session.addEventListener( 'end', function () {

				hitTestSourceRequested = false;
				hitTestSource = null;

			} );

			hitTestSourceRequested = true;

		}

		if ( hitTestSource ) {

			var hitTestResults = frame.getHitTestResults( hitTestSource );

			if ( hitTestResults.length ) {

				var hit = hitTestResults[ 0 ];

				reticle.visible = true;
				reticle.matrix.fromArray( hit.getPose( referenceSpace ).transform.matrix );

			} else {

				reticle.visible = false;

			}

		}

	}

	renderer.render( scene, camera );

}
  • You have to ensure to import OBJLoader and MTLLoader from the same release and from the same origin.
  • There is no need to use the THREE namespace when creating the loaders.
  • If you export models by yourself from Blender, I highly recommend to export to the more modern glTF instead. It’s the recommended 3D format of three.js.
1 Like

Can you please tell me how to apply the textures on this model?
I have multiple textures for my model i want to apply it, but dont know how to do that, can you please help me out?

Your OBJ file defines no texture coordinates. Hence, it’s not possible to use it with textures.

but i have applied the multiple textures in my obj file and exported.
and what you mean by texture coordinates?
can you please explain that?

Sorry, but I’m not going to start explaining basics in computer graphics. There are many existing resources about texture coordinates that explain this topic much better than I ever could.

I also suggest you read how OBJ represents texture coordinates. You will then quickly understand that these definitions are missing in your file:

http://paulbourke.net/dataformats/obj/

Sure, i will check that.
Thanks.

Super helpful, thank you so much! One question, though: where in the code did you instantiate the “monkeymesh” object at the location of the reticle?