【问题标题】:Javascript threejs 3D draw solid cubic with borderJavascriptthreejs 3D绘制带边框的实心立方体
【发布时间】:2016-12-14 03:24:12
【问题描述】:

我遵循threejs的例子,webgl_interactive_draggablecubes.html。我的项目是使用 Threejs 做一个容器装载计划。所以我想制作带边框的实心立方体。我们可以看到有/没有边界差异的东西。 /image attachement/,

我稍微修改为/1/的代码

我可以使用多种材质,但是我的拖放功能被破坏了。 create Geometry3 中的代码 sn-p 被注释掉了。

我的问题是如何制作带边框的立体立方体,同时可以拖放?

/1/

 <!DOCTYPE html>
<html lang="en">
    <head>
        <title>three.js webgl - draggable cubes</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
        <style>
            body {
                font-family: Monospace;
                background-color: #f0f0f0;
                margin: 0px;
                overflow: hidden;
            }
        </style>
    </head>
    <body>

        <script src="js/three.js"></script>
        <script src="js/TrackballControls.js"></script>
        <script src="js/stats.min.js"></script>

        <script>

            var container, stats;
            var camera, controls, scene, renderer;
            var cubes = [];
            var plane = new THREE.Plane();
            var raycaster = new THREE.Raycaster();
            var mouse = new THREE.Vector2(),
            offset = new THREE.Vector3(),
            intersection = new THREE.Vector3(),
            INTERSECTED, SELECTED;

            init();
            animate();

            function init() {

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

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

                controls = new THREE.TrackballControls( camera );
                controls.rotateSpeed = 1.0;
                controls.zoomSpeed = 1.2;
                controls.panSpeed = 0.8;
                controls.noZoom = false;
                controls.noPan = false;
                controls.staticMoving = true;
                controls.dynamicDampingFactor = 0.3;

                scene = new THREE.Scene();

                scene.add( new THREE.AmbientLight( 0x505050 ) );


                var geometry = new THREE.BoxGeometry( 2, 5, 7);
                var hex =  0xff0000;
                for ( var i = 0; i < geometry.faces.length; i++ ) {                 
                    geometry.faces[ i ].color.setHex( hex );
                }
                var material = new THREE.MeshBasicMaterial( { vertexColors: THREE.FaceColors, overdraw: 0.5,wireframe:true } );
                var cube = new THREE.Mesh( geometry, material );
                cubes.push( cube );

                var geometry2 = new THREE.BoxGeometry(2,4, 5);              
                var hex2 = 0x009fff;
                for ( var i = 0; i < geometry2.faces.length; i++ ) {                
                    geometry2.faces[ i ].color.setHex( hex2 );
                }                  
                var material2 = new THREE.MeshBasicMaterial( { vertexColors: THREE.FaceColors, overdraw: 0.5,wireframe:true } );
                var cube2 = new THREE.Mesh( geometry2, material2 );             
                cubes.push( cube2 );

                var geometry3 = new THREE.BoxGeometry(1,3,4);
                var hex3 = 0x0f0ff0;
                for ( var i = 0; i < geometry3.faces.length; i++ ) {
                    geometry3.faces[ i ].color.setHex( hex3 );
                }              
    /*          var darkMaterial3= new THREE.MeshBasicMaterial( { color: 0xffffcc } );
                var wireframeMaterial3= new THREE.MeshBasicMaterial( { color: 0x0f0000, wireframe: true, transparent: false } ); 
                var multiMaterial3= [ darkMaterial3, wireframeMaterial3 ];          
                var cube3 = THREE.SceneUtils.createMultiMaterialObject(geometry3,multiMaterial3);*/
                var material3 = new THREE.MeshBasicMaterial( { vertexColors: THREE.FaceColors, overdraw: 0.5,wireframe:true } );
                var cube3 = new THREE.Mesh( geometry3, material3 );   
                cubes.push( cube3 );

                scene.add(cube);
                scene.add(cube2);
                scene.add(cube3);

                renderer = new THREE.WebGLRenderer( { antialias: true } );
                renderer.setClearColor( 0xf0f0f0 );
                renderer.setPixelRatio( window.devicePixelRatio );
                renderer.setSize( window.innerWidth, window.innerHeight );
                renderer.sortObjects = false;

                renderer.shadowMap.enabled = true;
                renderer.shadowMap.type = THREE.PCFShadowMap;
                container.appendChild( renderer.domElement );

                stats = new Stats();
                container.appendChild( stats.dom );

                renderer.domElement.addEventListener( 'mousemove', onDocumentMouseMove, false );
                renderer.domElement.addEventListener( 'mousedown', onDocumentMouseDown, false );
                renderer.domElement.addEventListener( 'mouseup', onDocumentMouseUp, false );

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

            function onWindowResize() {
                camera.aspect = window.innerWidth / window.innerHeight;
                camera.updateProjectionMatrix();
                renderer.setSize( window.innerWidth, window.innerHeight );
            }

            function onDocumentMouseMove( event ) {
                event.preventDefault();

                mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
                mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;

                raycaster.setFromCamera( mouse, camera );

                if ( SELECTED ) {
                    if ( raycaster.ray.intersectPlane( plane, intersection ) ) {
                        SELECTED.position.copy( intersection.sub( offset ) );
                    }
                    return;
                }

                var intersects = raycaster.intersectObjects( cubes );
                if ( intersects.length > 0 ) {
                    if ( INTERSECTED != intersects[ 0 ].object ) {
                        if ( INTERSECTED ) INTERSECTED.material.color.setHex( INTERSECTED.currentHex );
                        INTERSECTED = intersects[ 0 ].object;
                        INTERSECTED.currentHex = INTERSECTED.material.color.getHex();

                        plane.setFromNormalAndCoplanarPoint(
                            camera.getWorldDirection( plane.normal ),
                            INTERSECTED.position );
                    }
                    container.style.cursor = 'pointer';
                } else {
                    if ( INTERSECTED ) INTERSECTED.material.color.setHex( INTERSECTED.currentHex );
                    INTERSECTED = null;
                    container.style.cursor = 'auto';
                }
            }

            function onDocumentMouseDown( event ) {
                event.preventDefault();
                raycaster.setFromCamera( mouse, camera );
                var intersects = raycaster.intersectObjects( cubes );

                if ( intersects.length > 0 ) {
                    controls.enabled = false;
                    SELECTED = intersects[ 0 ].object;
                    if ( raycaster.ray.intersectPlane( plane, intersection ) ) {
                        offset.copy( intersection ).sub( SELECTED.position );
                    }
                    container.style.cursor = 'move';
                }
            }

            function onDocumentMouseUp( event ) {
                event.preventDefault();
                controls.enabled = true;
                if ( INTERSECTED ) {
                    SELECTED = null;
                }
                container.style.cursor = 'auto';
            }

            function animate() {
                requestAnimationFrame( animate );
                render();
                stats.update();
            }

            function render() {
                controls.update();
                renderer.render( scene, camera );
            }
        </script>
    </body>
</html> 

【问题讨论】:

    标签: three.js


    【解决方案1】:

    添加WireframeGeometryEdgesGeometry 作为每个可拖动对象的子对象。

    scene.add( object );
    
    objects.push( object );
    
    // wireframe
    var geo = new THREE.EdgesGeometry( object.geometry );
    var mat = new THREE.LineBasicMaterial( { color: 0x000000, linewidth: 4 } );
    var wireframe = new THREE.LineSegments( geo, mat );
    wireframe.renderOrder = 1; // make sure wireframes are rendered 2nd
    object.add( wireframe );
    

    提示:webgl_interactive_draggablecubes.html 示例已被简化。检查 r.83dev 分支。

    three.js r.82

    【讨论】:

    • 太棒了!!快速而正确的答案。如何使线条粗体?当我增加线宽时,它似乎具有最大值。
    • 老天,这是唯一能帮助我解决问题的方法。我用线段渲染了立方体,它们看起来很棒,直到我使用 Orbitcontrols 移动相机,立方体会保留但线条消失了。设置渲染顺序修复它!谢谢!
    【解决方案2】:

    我建议使用 EdgesHelper

          this.scene.add(image3D);
    
          edges                             =   new THREE.EdgesHelper(image3D, 0x808080);
          edges.material.linewidth          =   3;
    
          this.scene.add(edges);
    

    例子:

    【讨论】:

    • EdgesHelper 在 three.js r.81 中已从库中删除。
    • 我用的是r82,找我的case比较好。对于集装箱装载 3D,这是更好的解决方案。是不是贬值了?无论如何,我使用的是 r82,它可以工作。
    • @user84592 阅读您的控制台警告消息:“THREE.EdgesHelper 已被删除。请改用 THREE.EdgesGeometry。”
    • @WestLangley 你说得对,这个 API 已经过时了。但我们的商务人士喜欢这种类型的优势。
    • @user84592 您需要将事件添加到画布容器。 this.canva_container.addEventListener('mousemove', this.onWindowMouseMoveHandler, false);
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-10
    • 2021-12-25
    • 1970-01-01
    • 1970-01-01
    • 2021-03-06
    相关资源
    最近更新 更多