threejs 加载obj 模型并实现对象拾取

初识threejs,实现了简单的threejs和对象拾取。这里简单记录。

  • obj mtl 模型加载

 这部分只实现了简单的模型加载,隐去html部分,最后贴完整源码

// 拾取变量
        var objects = [];
        var renderer, scene, camera;
        var controls, group;
        var stateView;
        //

        // 控制面板显示
        control = new function (){
            this.rotationSpeed = 0.005;
            this.scale = 1;
        
            this.rotationSpeed2 = 0.05;
            this.sptSelectObj = false;
        }
        addControls(control);

        // 性能显示
        stateView = createStats();

        // 通过原生的方式添加对象
        //第一步创建场景元素
        var scene=new THREE.Scene();
            
        // ground
        var mesh = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2000, 2000 ), new THREE.MeshPhongMaterial( { color: 0x999999, depthWrite: false } ) );
        mesh.rotation.x = - Math.PI / 2;
        scene.add( mesh );
        var grid = new THREE.GridHelper( 200, 40, 0x000000, 0x000000 );
        grid.material.opacity = 0.2;
        grid.material.transparent = true;
        scene.add( grid );
        // objects.push(mesh);

        group = new THREE.Group();
        scene.add(group);

        obj = null;
        var mtlLoader = new THREE.MTLLoader();//mtl材质加载器
        mtlLoader.load( 'demo.mtl', function(materialss){
            var objLoader = new THREE.OBJLoader();//obj模型加载器
            objLoader.setMaterials( materialss );//mtl材质赋值给obj模型
            objLoader.load( 'demo.obj',function(object3D){

                obj = object3D;
                // object3D.scale.set(100,100,100);//放大object3D对象
                scene.add( object3D );//object3D对象插入场景对象

                group.add( object3D );

            } );//加载.obj文件,执行obj函数

        });//加载.mtl文件,执行mtl函数

        /
        // 添加光源2
        // lights
        var light = new THREE.HemisphereLight( 0xffffff, 0x444444 );
        light.position.set( 0, 20, 0 );
        scene.add( light );
        light = new THREE.DirectionalLight( 0xffffff );
        light.position.set( 0, 20, 10 );
        scene.add( light );
                
        /
 
        //添加相机  透视相机
        var camera=new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 1000);
        camera.position.set(15, 15, 15);//相机的位置
        camera.lookAt(scene.position);//相机朝向的位置
 
        //添加渲染器
        var renderer=new THREE.WebGLRenderer();
        renderer.setPixelRatio( window.devicePixelRatio );
        renderer.setSize(window.innerWidth, window.innerHeight);

        //将渲染器加到文档中
        document.body.appendChild(renderer.domElement);
 
        function render() {
            renderer.render(scene,camera);
        }
        render();//刚加载页面的时候就渲染一次  要不刚进入页面背景会是黑色的

        //将相机加入到相机控制
        var controls=new THREE.OrbitControls(camera, renderer.domElement);//不传参数默认是整个文档

        //添加事件监听
        // controls.addEventListener("change",renderer);  //当事件改变 触发render方法 渲染界面
        
        var animate = function () {
            requestAnimationFrame( animate );
            renderer.render( scene, camera );
            stateView.update();
        };
        animate();
  • 简单对象拾取(部分类型对象无法拾取)

对象拾取的思路是,摄像机到鼠标连线与模型求交,有交集的对象就是需要拾取的对象。来贴一下关键实现

// events
        // checkbox.addEventListener( 'click', toggleOctree, false );
        renderer.domElement.addEventListener( 'mousemove', onDocumentMouseMove, false );
        window.addEventListener( 'resize', onWindowResize, false );

        function onWindowResize() {

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

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

        }

        var selectedObject = null;
        function onDocumentMouseMove( event ) {

            event.preventDefault();
            if ( selectedObject ) {
                selectedObject.material.color.set( '#69f' ); 
                selectedObject = null;
            }

            var intersects = getIntersects( event.layerX, event.layerY );
            if ( intersects.length > 0 &&selectedObject!=intersects[0].object) {
                var res = intersects.filter( function ( res ) {
                    return res && res.object;
                } )[ 0 ];
                if ( res && res.object ) {
                    selectedObject = res.object; 
                    selectedObject.material.color.set( '#f00' );
                }
            }
        }

        var raycaster = new THREE.Raycaster();
        var mouseVector = new THREE.Vector3();
        function getIntersects( x, y ) {
            x = ( x / window.innerWidth ) * 2 - 1;
            y = - ( y / window.innerHeight ) * 2 + 1;
            mouseVector.set( x, y, 0.5 );
            raycaster.setFromCamera( mouseVector, camera );
            return raycaster.intersectObject( group, true );
        }


        function onWindowResize() {

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

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

        }

        function addControls(controlObject){
            var gui = new dat.GUI();
            gui.add(controlObject,'rotationSpeed',-0.1,0.1);
            gui.add(controlObject, 'scale', 0.01, 2);
    
            gui.add(controlObject, 'rotationSpeed2', -0.1, 0.1);
        } 

        function createStats() {
            var stats = new Stats();
            stats.setMode(0);
        
            stats.domElement.style.position = 'absolute';
            stats.domElement.style.left = '0px';
            stats.domElement.style.top = '5px';
        
            return stats;
        }

 引用的链接是http://www.cnblogs.com/pursues/p/5226807.html

真正实现拾取参考https://www.cnblogs.com/xuejianxiyang/p/9732632.html

https://blog.csdn.net/ithanmang/article/details/80897888

threejs 控制面板和性能检测集成https://www.cnblogs.com/hsprout/p/7865593.html

一个完整项目,源码有问题,但是项目开发思路可以借鉴http://www.cnblogs.com/pursues/p/5226807.html

本项目集成了一个html的魔板,用来改造界面,参考http://demo.cssmoban.com/cssthemes5/tpmo_518_sentra/index.html

下一步希望对模型内部对象,以及外部对象导入现在模型的实现。

 

 

 

 

  • 1
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老朱自强不息

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值