ThreeJs 導入外部三維模型,並實現鼠標滾動放大縮小旋轉效果

let i = 0;
function init() {
    // create a scene, that will hold all our elements such as objects, cameras and lights.
    var scene = new THREE.Scene();
    // create a camera, which defines where we're looking at.
    var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
    var renderer = new THREE.WebGLRenderer();
    var axes = new THREE.AxesHelper(20);
    var controls = new THREE.TrackballControls(camera);     //創建場景旋轉縮放事件

    camera.position.set(-30, 40, 30);
    camera.lookAt(scene.position);

    renderer.setClearColor(new THREE.Color(0xcccccc));  // 設置渲染面板顏色
    renderer.setSize(window.innerWidth, window.innerHeight);    // 設置渲染面板長寬

    // // show axes in the screen
    // 顯示三維座標軸
    scene.add(axes);
    
    controls = new THREE.TrackballControls(camera);     //創建場景旋轉縮放事件
    controls.rotateSpeed = 2.5;
    controls.zoomSpeed = 1.2;
    controls.panSpeed = 0.8;
    controls.noZoom = false;
    controls.noPan = false;
    controls.staticMoving = true;
    controls.dynamicDampingFactor = 0.3;
    // create a render and set the size
    // 設置渲染面板屬性
    
    
    // create the ground plane
    // var planeGeometry = new THREE.PlaneGeometry(60, 20);
    // var planeMaterial = new THREE.MeshBasicMaterial({
    //     color: 0xAAAAAA
    // });
    // var plane = new THREE.Mesh(planeGeometry, planeMaterial);

    // // rotate and position the plane
    // plane.rotation.x = -0.5 * Math.PI;
    // plane.position.set(15, 0, 0);

    // // add the plane to the scene
    // scene.add(plane);

    // create a cube
    

    // position the cube
    // cube.position.set(-4, 3, 0);
    // add the cube to the scene
    

    // create a sphere
    // var sphereGeometry = new THREE.SphereGeometry(4, 20, 20);
    // var sphereMaterial = new THREE.MeshBasicMaterial({
    //     color: 0x7777FF,
    //     wireframe: true
    // });
    // var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);

    // // position the sphere
    // sphere.position.set(20, 4, 2);

    // // add the sphere to the scene
    // scene.add(sphere);

    // position and point the camera to the center of the scene

    // add the output of the renderer to the html element

    // render the scene
    let addT = null;
    let redt = null;
    let timeAdd = null;
    let timeDel = null;
    let step = 1;
    let frequ = 100;
    // 數值增加到制定數字
    function add (dis) {
        clearInterval(timeDel);
        timeAdd = setInterval(() => {
            if (i < dis) {
                i++;
                intCub();
            } else {
                clearInterval(timeAdd);
                // del(0);
            }
            console.log(i);
        }, frequ);
    };
    // 數值減少到制定數字
    function del (dis) {
        clearInterval(timeAdd);
        timeDel = setInterval(() => {
            if (i > dis) {
                i--;
                intCub();
            } else {
                val = dis;
                clearInterval(timeDel);
                add(50)
            }
            console.log(i);
        }, frequ);
    };
    
    function intCub () {
        let random = parseInt(1 + (4 - 1) * (Math.random()));   // 隨機數用於正方體的長寬高
        let randomC = parseInt(1 + (2 - 1) * (Math.random()));  // 隨機數用於球形的半徑
        let colorRandomNum = parseInt(1 + (7 - 1) * (Math.random()));  // 隨機數用於賦值後續的物體的材質顏色
        let randomColor = [0xF7CE18, 0x2550EC, 0x57E10C, 0xEB6F0A, 0xEB0AE9, 0x820745, 0x8D11D8];

        // 配置燈光
        let light = new THREE.AmbientLight(0x820745);
        light.position.set(100, 100, 200);
                
        // 生成正方體
        var cubeGeometry = new THREE.BoxGeometry(random, random, random);   // 長寬高
        // 給正方體網格添加材質
        var cubeMaterial = new THREE.MeshBasicMaterial({
            color: randomColor[colorRandomNum],
            wireframe: false  // 是否顯示網格狀態
        });
        var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);  // 將材質貼到模型上

        // 生成原型
        var sphereGeometry = new THREE.SphereGeometry(randomC, 200, 200);  // 半徑和網格數,網格數表示球體的粗糙程度
        var sphereMaterial = new THREE.MeshBasicMaterial({
            color: randomColor[colorRandomNum],
            wireframe: false   // 是否顯示網格狀態
        });
        var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);  // 將材質貼到模型上

        // position the sphere
        // 設置球體的位置
        sphere.position.set(parseInt(-10 + (25 - 1) * (Math.random())), parseInt(-10 + (25 - 1) * (Math.random())), parseInt(-10 + (25 - 1) * (Math.random())));
        
        // 設置正方體的位置
        cube.position.set(parseInt(-10 + (25 - 1) * (Math.random())), parseInt(-10 + (25 - 1) * (Math.random())), parseInt(-10 + (25 - 1) * (Math.random())));
        // add the sphere to the scene
        // 將貼好材質的模型和燈光添加到場景
        scene.add(sphere);  
        scene.add(cube);
        scene.add(light);
        //聲明raycaster和mouse變量
        var raycaster = new THREE.Raycaster();
        var mouse = new THREE.Vector2();
        // 綁定點擊事件
        function onMouseClick( event ) {
            //通過鼠標點擊的位置計算出raycaster所需要的點的位置,以屏幕中心爲原點,值的範圍爲-1到1.
            mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
            mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;

            // 通過鼠標點的位置和當前相機的矩陣計算出raycaster
            raycaster.setFromCamera( mouse, camera );
            // 獲取raycaster直線和所有模型相交的數組集合
            var intersects = raycaster.intersectObjects(scene.children);
            console.log(intersects);
            //將所有的相交的模型的顏色設置爲紅色,如果只需要將第一個觸發事件,那就數組的第一個模型改變顏色即可
            for ( var i = 0; i < intersects.length; i++ ) {
                intersects[i].object.material.color.set(0x000000);
                let msg = JSON.stringify(intersects[i]);
                document.querySelector('.msg .content').innerHTML = msg;
            }
            // alert('我點擊了對象,對象信息已經在控制檯打印出來');
            renderer.render(scene, camera); // 渲染場景中的模型
        }
        // // window.removeEventListener('click', onMouseClick);
        // document.onmousedown = function(event) {
        //     document.onmousemove = function () {
        //         controls.update();
        //         renderer.render(scene, camera); // 渲染場景中的模型
        //     }
        // }
        // document.onmouseup = function(event) {
        //     document.onmousemove = null
        // }
        document.getElementById("webgl-output").appendChild(renderer.domElement);
        // 定時鼠標點擊移動或者滾輪滾動的時候要觸發渲染事件,畫面是不會跟着放大縮小旋轉
        setInterval(() => {
            controls.update();
            renderer.render(scene, camera); // 渲染場景中的模型
        }, 5);
        // renderer.render(scene, camera); // 渲染場景中的模型

        /**************加載模型************** */
        var loader = new THREE.OBJLoader();//在init函數中,創建loader變量,用於導入模型
        let i = 0.04;
        let step = 0.02;
        let v = 0;
        loader.load(
            // 資源鏈接
            'http://10.1.252.90:8080/src/chapter-01/models/man.obj',
            // 資源加載完成後的回調函數
            function (object) {
                console.log(object);
                object.position.set(0, 0, 0);
                object.rotation.z = 3.1415927;  // 糾正導入
                var ms = new THREE.MeshBasicMaterial({
                    color: 0xcccccc,
                    wireframe: true  // 是否顯示網格狀態
                });
                scene.add(object);
                
                renderer.render(scene, camera); // 渲染場景中的模型
                window.addEventListener('click', onMouseClick, false);
                // // var sphere = new THREE.Mesh(object, ms);  // 將材質貼到模型上
                setInterval(() => {
                    i += step;
                    object.rotation.y = i;
                    scene.add(object);
                    // renderer.render(scene, camera); // 渲染場景中的模型
                }, 10);
            }
        );
        /**************加載模型************** */
    };
    // 運行渲染
    add (10);
    intCub();
    
}
<!DOCTYPE html>

<html>

<head>
    <title>Example 01.02 - First Scene</title>
    <meta charset="UTF-8" />
    <script type="text/javascript" charset="UTF-8" src="../../libs/three/three.js"></script>
    <script type="text/javascript" charset="UTF-8" src="../../libs/three/loaders/OBJLoader.js"></script>
    <script type="text/javascript" charset="UTF-8" src="../../libs/three/controls/TrackballControls.js"></script>
    <script type="text/javascript" charset="UTF-8" src="../../libs/three/controls/DragControls.js"></script>
    
    <link rel="stylesheet" href="../../css/default.css">
    <style>
        #render{
            position: fixed;
            left: 20px;
            top: 30px;
            height: 40px;
            width: 120px;
        }
        .msg{
            position: absolute;
            left: 10px;
            top: 10px;
            height: 600px;
            min-height: 550px;
            overflow:scroll;
            width: 500px;
            background: #fff;
            border: 2px solid #eee;
        }
        h3{
            padding: 0;
            margin: 0;
            text-align: center;
        }
    </style>
</head>

<body>

    <!-- Div which will hold the Output -->
    <div id="webgl-output"></div>
    <div class="msg">
        <h3>鼠標點擊的對象信息</h3>
        <div class="content"></div>
    </div>
    <script type="text/javascript" src="./js/01-02.js"></script>
    <!-- Javascript code that runs our Three.js examples -->
    <script type="text/javascript">
        (function () {
            // your page initialization code here
            // the DOM will be available here
            init();
        })();
    </script>
    
</body>

</html>

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章