添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

And I can’t find the way to make raycast well to intersect a Mesh. I just try different strategies with camera and rayCast, but I can’t get a good result with it. I use helpers and spheres to debugin.

The way to get any resoult is inverse the rayCast : var vector = new THREE.Vector3( pointer.x, pointer.y, camera.near ).unproject(camera).normalize().negate();

I will appreciate any kind of help, I just starting to learn.

This is my code:

<!DOCTYPE html>
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<!-- three.js library -->
<script src='vendor/three.js/build/three.min.js'></script>
<!-- three.js load GLTF -->
<script src='vendor/three.js/GLTFLoader.js'></script>
<!-- ar.js -->
<script src='../build/ar-threex.js'></script>
<script>THREEx.ArToolkitContext.baseURL = '../'</script>
<body style='position: absolute; top: 0; left: 0; width: 100%; height: 100%; margin : 0px; overflow: hidden;'>
    <style>
        .arjs-loader {
            margin: 0 auto;
            width: 100%;
            height: 100%;
            position: absolute;
            top: 0;
            left: 0;
            display: flex;
            justify-content: center;
            align-items: center;
        .arjs-loader-spinner {
            z-index: 10;
            -webkit-transform: spin 1s linear infinite;
            animation: spin 1s linear infinite;
            border: 3px solid #ddd;
            border-top: 3px solid #42a5f5;
            border-radius: 50%;
            height: 75px;
            width: 75px;
        @-webkit-keyframes spin {
                border-top-color: #42a5f5;
                -webkit-transform: rotate(360deg);
                transform: rotate(360deg);
        @keyframes spin {
                border-top-color: #42a5f5;
                -webkit-transform: rotate(360deg);
                transform: rotate(360deg);
		body{ 
			padding: 0;
			margin: 0; 
    </style>
    <div class="arjs-loader" id="loader-spinner">
        <div class="arjs-loader-spinner"></div>
    <script>
        //////////////////////////////////////////////////////////////////////////////////
        //		Init
        //////////////////////////////////////////////////////////////////////////////////
        var renderer = new THREE.WebGLRenderer({
            antialias: true,
            alpha: true,
            precision: 'mediump',
        var clock = new THREE.Clock();
        var mixers = [];
        renderer.setPixelRatio(window.devicePixelRatio);
        renderer.setClearColor(new THREE.Color('lightgrey'), 0)
        renderer.setSize( window.innerWidth, window.innerHeight );
        renderer.domElement.style.position = 'absolute'
        renderer.domElement.style.top = '0px'
        renderer.domElement.style.left = '0px'
        document.body.appendChild( renderer.domElement );
        // init scene and camera
        var scene = new THREE.Scene();
        //////////////////////////////////////////////////////////////////////////////////
        //		Initialize a basic camera
        //////////////////////////////////////////////////////////////////////////////////
        // Create a camera
		var camera = new THREE.Camera();
        //var camera = new THREE.PerspectiveCamera( 25, window.innerWidth / window.innerHeight, 0.01, 100 );
        scene.add(camera);
        var light = new THREE.AmbientLight(0xffffff);
        scene.add(light);
        ////////////////////////////////////////////////////////////////////////////////
        //          handle arToolkitSource
        ////////////////////////////////////////////////////////////////////////////////
        var arToolkitSource = new THREEx.ArToolkitSource({
            sourceType : 'webcam',
            sourceWidth: 480,
            sourceHeight: 640,
        arToolkitSource.init(function onReady(){
            // use a resize to fullscreen mobile devices
            setTimeout(function() {
                onResize();
            }, 1000);
        // handle resize
        window.addEventListener('resize', function(){
            onResize();
        // listener for end loading of NFT marker
        window.addEventListener('arjs-nft-loaded', function(ev){
          console.log(ev);
		window.addEventListener( 'click', function(){
			// calculate pointer position in normalized device coordinates
			// (-1 to +1) for both components
			var pointer = new THREE.Vector2();
			pointer.x =( event.clientX / window.innerWidth ) * 2 - 1;
			pointer.y =- ( event.clientY / window.innerHeight ) * 2 + 1;
			var vector = new THREE.Vector3( pointer.x, pointer.y, camera.near ).unproject(camera).normalize().negate();
			var raycaster = new THREE.Raycaster( camera.position, vector );//vector.unproject(camera).normalize()
			/*var raycaster = new THREE.Raycaster();
			raycaster.setFromCamera(pointer, camera);*/
			var arrow = new THREE.ArrowHelper( vector, camera.position, 8, 0xff0000 );
            scene.add( arrow );
			// calculate objects intersecting the picking ray
			var intersects = raycaster.intersectObject( model );
			for ( var i = 0; i < intersects.length; i ++ ) {
				var posInt = intersects[0].point;
				var geometry = new THREE.SphereGeometry( 15, 32, 16 ); 
				var material = new THREE.MeshBasicMaterial( { color: 0xffff00 } ); 
				var sphere = new THREE.Mesh( geometry, material );
				sphere.scale.set( 0.001, 0.001, 0.001 );
				sphere.position.set( posInt.x, posInt.y, posInt.z );
				scene.add( sphere );
        function onResize(){
            arToolkitSource.onResizeElement()
            arToolkitSource.copyElementSizeTo(renderer.domElement)
            if( arToolkitContext.arController !== null ){
                arToolkitSource.copyElementSizeTo(arToolkitContext.arController.canvas)
        ////////////////////////////////////////////////////////////////////////////////
        //          initialize arToolkitContext
        ////////////////////////////////////////////////////////////////////////////////
        // create atToolkitContext
        var arToolkitContext = new THREEx.ArToolkitContext({
            detectionMode: 'mono',
            canvasWidth: 480,
            canvasHeight: 640,
            sourceWidth: 480,
            sourceHeight: 640,
        // initialize it
        arToolkitContext.init(function onCompleted(){
            // copy projection matrix to camera
            camera.projectionMatrix.copy( arToolkitContext.getProjectionMatrix() );
        ////////////////////////////////////////////////////////////////////////////////
        //          Create a ArMarkerControls
        ////////////////////////////////////////////////////////////////////////////////
        // init controls for camera
        var markerControls = new THREEx.ArMarkerControls(arToolkitContext, camera, {
            /*type : 'nft',
            descriptorsUrl : 'data/dataNFT/pinball',
            changeMatrixMode: 'cameraTransformMatrix'*/
			type: 'pattern',
			patternUrl: THREEx.ArToolkitContext.baseURL + '../data/data/patt.hiro',
			// patternUrl : THREEx.ArToolkitContext.baseURL + '../data/data/patt.kanji',
			// as we controls the camera, set changeMatrixMode: 'cameraTransformMatrix'
			changeMatrixMode: 'cameraTransformMatrix'
        scene.visible = true;
        var root = new THREE.Object3D();
        scene.add(root);
        //////////////////////////////////////////////////////////////////////////////////
        //		add an object in the scene
        //////////////////////////////////////////////////////////////////////////////////
        var threeGLTFLoader = new THREE.GLTFLoader();
        var model;
        threeGLTFLoader.load("./resources/scene.glb", function (gltf) {
            model = gltf.scene;
			mixer = new THREE.AnimationMixer( model );
			mixers.push(mixer);
			clips = gltf.animations;
			if(clips.length>0){
				clip = THREE.AnimationClip.findByName( clips, 'Walking' );
				action = mixer.clipAction( clips[0] );
				//console.log("Inside gltf " +clipnumber);
				action.play();
            root.matrixAutoUpdate = false;
            root.add(model);
            //model.position.z = -500;
			model.scale.set(0.003,0.003,0.003);
            //model.position.z = 100;
			var geometry = new THREE.SphereGeometry( 15, 32, 16 ); 
			var material = new THREE.MeshBasicMaterial( { color: 0xff0000 } ); 
			var sphere = new THREE.Mesh( geometry, material );
			sphere.scale.set( 0.001, 0.001, 0.001 );
			sphere.position.set( 0, 0, 0 );
			scene.add( sphere );
			/*model.traverse(function (child) {
				if (child.type == 'Mesh') {
					child.material.side = THREE.DoubleSide;
			});*/
            window.addEventListener('arjs-nft-init-data', function(nft) {
              console.log(nft);
              var msg = nft.detail;
              model.position.y = (msg.height / msg.dpi * 2.54 * 10)/2.0; //y axis?
              model.position.x = (msg.width / msg.dpi * 2.54 * 10)/2.0; //x axis?
            //////////////////////////////////////////////////////////////////////////////////
            //		render the whole thing on the page
            //////////////////////////////////////////////////////////////////////////////////
            var animate = function() {
                requestAnimationFrame(animate);
                if (mixers.length > 0) {
                    for (var i = 0; i < mixers.length; i++) {
                        mixers[i].update(clock.getDelta());
                if (!arToolkitSource.ready) {
                    return;
                arToolkitContext.update( arToolkitSource.domElement )
                // update scene.visible if the marker is seen
                //scene.visible = true;//camera.visible;
				var spiner = document.getElementById('loader-spinner');
				if(camera.visible){
					spiner.style.visibility = 'hidden';
					model.traverse(function (child) {
						if (child.type == 'Mesh') {
							child.material.wireframe = false;
				}else{
					spiner.style.visibility = 'visible';
					model.traverse(function (child) {
						if (child.type == 'Mesh') {
							child.material.wireframe = true;
                renderer.render(scene, camera);
            requestAnimationFrame(animate);
    </script>
</body>