0

私は現在、テクスチャで回転する立方体を作ろうとしています。また、コントロール (マウスオーバーでキューブを回転させる矢印イメージ) を使用して、キューブを x 軸と y 軸で (前後に) 回転させたいと考えています。X 軸で回転させると、立方体の裏側が逆さまになります。

これは、UV マッピングが機能する方法と関係があることを知っています。そこで、キューブの初期化でそれを修正しようとしましたが、うまくいきました。しかし、立方体を y 軸で回転させようとすると、テクスチャが逆さまになります。そのため、回転要求に従って、その場でテクスチャの向きを変更する必要があることを学びました。

しかし、これは私にはうまくいきません。キューブの初期化後に「faceVertexUvs[0][5]」を変更する方法が見つかりませんでした。初期化時にキューブ ジオメトリに「needsUpdate」を設定しようとしても役に立ちませんでした。

私が自分自身を明確にしたことを願っています。その問題に対するある種の解決策はありますか?

前もってありがとうマイケル

私の問題をよりよく説明するために、ここにソース コードを投稿します。

JsFiddle では、別のドメインのテクスチャ イメージを使用することは許可されていない (そして CORS は機能しなかった) ため、デモを行うことはできません。次のコードをコピーして貼り付け、「test.html」としてローカルに保存します。テクスチャ イメージは、http: //www.mikelmade.de/cors/t.pngで入手できます。「test.html」と同じディレクトリにある必要があります。WebGL 対応のブラウザーで「test.html」を開き、マウスを「上」に移動すると、私の言いたいことがわかるはずです。

<html><head><script src="jquery.js"></script></head><body>
<script src="https://raw.github.com/mrdoob/three.js/master/build/three.min.js"></script>
<script src="https://raw.github.com/mrdoob/three.js/master/examples/js/libs/stats.min.js"> </script>

<script>
        var cubeGeo;
        var materials = [];
        var container, stats;
        var camera, scene, renderer;
        var cube, plane;

        var targetRotation = 0;
        var targetRotationOnMouseDown = 0;

        var mouseX = 0;
        var mouseXOnMouseDown = 0;

        var windowHalfX = window.innerWidth / 2;
        var windowHalfY = window.innerHeight / 2;

        init();
        animate();
        function init() {
            container = document.createElement( 'div' );
            document.body.appendChild( container );

            var info = document.createElement( 'div' );
            info.style.position = 'absolute';
            info.style.top = '10px';
            info.style.width = '100%';
            info.style.textAlign = 'center';
            info.innerHTML = 'Drag to spin the cube';
            container.appendChild( info );

            camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1000 );
            camera.position.y = 150;
            camera.position.z = 500;

            scene = new THREE.Scene();

    // add subtle ambient lighting
    var ambientLight = new THREE.AmbientLight(0x555555);
    scene.add(ambientLight);

    // add directional light source
    var directionalLight = new THREE.DirectionalLight(0xEEEEEE);
    directionalLight.position.set(1, 1, 1).normalize();
    scene.add(directionalLight);

            // Cube
            for ( var i = 0; i < 6; i ++ ) {
                var img = new Image();
                img.src = 't.png';
                var tex = new THREE.Texture(img);
                img.tex = tex;
                img.onload = function() { this.tex.needsUpdate = true; };
                var mat = new THREE.MeshLambertMaterial({map: tex});
                materials.push(mat);
            }

            cubeGeo = new THREE.CubeGeometry(200,200,200,1,1,1);
            cubeGeo.uvsNeedUpdate = true;
            cubeGeo.dynamic = true;

            cube = new THREE.Mesh( cubeGeo, new THREE.MeshFaceMaterial( materials ) );

            cube.position.y = 150;
            scene.add( cube );

            renderer = new THREE.WebGLRenderer({antialias:true});
            renderer.setSize( window.innerWidth, window.innerHeight );

            // enable shadows on the renderer
            renderer.shadowMapEnabled = true;
            container.appendChild( renderer.domElement );

            stats = new Stats();
            stats.domElement.style.position = 'absolute';
            stats.domElement.style.top = '0px';
            container.appendChild( stats.domElement );

            document.addEventListener( 'mousedown', onDocumentMouseDown, false );
            document.addEventListener( 'touchstart', onDocumentTouchStart, false );
            document.addEventListener( 'touchmove', onDocumentTouchMove, false );

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

        }

        function onWindowResize() {
            windowHalfX = window.innerWidth / 2;
            windowHalfY = window.innerHeight / 2;

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

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

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

            document.addEventListener( 'mousemove', onDocumentMouseMove, false );
            document.addEventListener( 'mouseup', onDocumentMouseUp, false );
            document.addEventListener( 'mouseout', onDocumentMouseOut, false );

            mouseXOnMouseDown = event.clientX - windowHalfX;
            targetRotationOnMouseDown = targetRotation;
        }

        function onDocumentMouseMove( event ) {
            mouseX = event.clientX - windowHalfX;
            targetRotation = targetRotationOnMouseDown + ( mouseX - mouseXOnMouseDown ) * 0.02;
        }

        function onDocumentMouseUp( event ) {
            document.removeEventListener( 'mousemove', onDocumentMouseMove, false );
            document.removeEventListener( 'mouseup', onDocumentMouseUp, false );
            document.removeEventListener( 'mouseout', onDocumentMouseOut, false );
        }

        function onDocumentMouseOut( event ) {
            document.removeEventListener( 'mousemove', onDocumentMouseMove, false );
            document.removeEventListener( 'mouseup', onDocumentMouseUp, false );
            document.removeEventListener( 'mouseout', onDocumentMouseOut, false );
        }

        function onDocumentTouchStart( event ) {
            if ( event.touches.length === 1 ) {
                event.preventDefault();
                mouseXOnMouseDown = event.touches[ 0 ].pageX - windowHalfX;
                targetRotationOnMouseDown = targetRotation;
            }
        }

        function onDocumentTouchMove( event ) {
            if ( event.touches.length === 1 ) {
                event.preventDefault();
                mouseX = event.touches[ 0 ].pageX - windowHalfX;
                targetRotation = targetRotationOnMouseDown + ( mouseX - mouseXOnMouseDown ) * 0.05;
            }
        }


        function animatex(dir) {
            cubeGeo.faceVertexUvs[0][5] = [new THREE.UV(1, 0), new THREE.UV(1, 1), new THREE.UV(0, 1), new THREE.UV(0, 0)];
            animate2(dir);
        }

        var anim = 0;
        function animate2(dir) {
                requestAnimationFrame(function() {
                    cubeGeo.faceVertexUvs[0][5] = [new THREE.UV(1, 0), new THREE.UV(1, 1), new THREE.UV(0, 1), new THREE.UV(0, 0)];
                    if(anim == 1) {
                        animate2(dir);
                    }
                });
                render2();
                stats.update();
        }

        function render2() {
            cube.rotation.x = cube.rotation.x+0.06;
            renderer.render( scene, camera );
        }

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

        }

        function render() {
            cube.rotation.y += ( targetRotation - cube.rotation.y ) * 0.05;
            $('#test').html(cube.rotation.y);
            renderer.render( scene, camera );
        }

    </script>
    <div id="up" style="position:absolute;z-index:500000;left:100px;top:20px;" class="nav">up</div>
    <div id="down" style="position:absolute;z-index:500000;left:100px;top:40px;" class="nav">down</div>
    <div id="left" style="position:absolute;z-index:500000;left:100px;top:60px;" class="nav">left</div>
    <div id="right" style="position:absolute;z-index:500000;left:100px;top:80px;" class="nav">right</div>
    <div id="test" style="position:absolute;z-index:500000;left:100px;top:100px;"> </div>
    <script>
        var _interval = 0;
        $(document).ready(function(){
        $('.nav').mouseover(function() {
            switch($(this).prop('id')) {
                case 'up':
                    anim = 1;
                    animatex('up');
                break;
            }
        });

        $('.nav').mouseout(
            function () {
                anim = 0;
            }
        );
        });
        </script>
    </body>
</html>
4

1 に答える 1

0

cubeGeo はメッシュではなくジオメトリだったので、その設定です。

cubeGeo.uvsNeedUpdate = true;

そしてフィドル

http://jsfiddle.net/crossphire/JebXL/2/

改造例はこちら

<html><head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>  
</head><body>
<script src="https://raw.github.com/mrdoob/three.js/master/build/three.min.js"></script>
<script src="https://raw.github.com/mrdoob/three.js/master/examples/js/libs/stats.min.js"> </script>

<script>
        var cubeGeo;
        var materials = [];
        var container, stats;
        var camera, scene, renderer;
        var cube, plane;

        var targetRotation = 0;
        var targetRotationOnMouseDown = 0;

        var mouseX = 0;
        var mouseXOnMouseDown = 0;

        var windowHalfX = window.innerWidth / 2;
        var windowHalfY = window.innerHeight / 2;

        init();
        animate();
        function init() {
            container = document.createElement( 'div' );
            document.body.appendChild( container );

            var info = document.createElement( 'div' );
            info.style.position = 'absolute';
            info.style.top = '10px';
            info.style.width = '100%';
            info.style.textAlign = 'center';
            info.innerHTML = 'Drag to spin the cube';
            container.appendChild( info );

            camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1000 );
            camera.position.y = 150;
            camera.position.z = 500;

            scene = new THREE.Scene();

    // add subtle ambient lighting
    var ambientLight = new THREE.AmbientLight(0x555555);
    scene.add(ambientLight);

    // add directional light source
    var directionalLight = new THREE.DirectionalLight(0xEEEEEE);
    directionalLight.position.set(1, 1, 1).normalize();
    scene.add(directionalLight);

            // Cube
            for ( var i = 0; i < 6; i ++ ) {
                var img = new Image();
                img.src = 'test.png';
                var tex = new THREE.Texture(img);
                img.tex = tex;
                img.onload = function() { this.tex.needsUpdate = true; };
                var mat = new THREE.MeshLambertMaterial({map: tex});
                materials.push(mat);
            }

            cubeGeo = new THREE.CubeGeometry(200,200,200,1,1,1);
            cubeGeo.uvsNeedUpdate = true;
            cubeGeo.dynamic = true;

            cube = new THREE.Mesh( cubeGeo, new THREE.MeshFaceMaterial( materials ) );

            cube.position.y = 150;
            scene.add( cube );

            renderer = new THREE.WebGLRenderer({antialias:true});
            renderer.setSize( window.innerWidth, window.innerHeight );

            // enable shadows on the renderer
            renderer.shadowMapEnabled = true;
            container.appendChild( renderer.domElement );

            stats = new Stats();
            stats.domElement.style.position = 'absolute';
            stats.domElement.style.top = '0px';
            container.appendChild( stats.domElement );

            document.addEventListener( 'mousedown', onDocumentMouseDown, false );
            document.addEventListener( 'touchstart', onDocumentTouchStart, false );
            document.addEventListener( 'touchmove', onDocumentTouchMove, false );

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

        }

        function onWindowResize() {
            windowHalfX = window.innerWidth / 2;
            windowHalfY = window.innerHeight / 2;

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

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

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

            document.addEventListener( 'mousemove', onDocumentMouseMove, false );
            document.addEventListener( 'mouseup', onDocumentMouseUp, false );
            document.addEventListener( 'mouseout', onDocumentMouseOut, false );

            mouseXOnMouseDown = event.clientX - windowHalfX;
            targetRotationOnMouseDown = targetRotation;
        }

        function onDocumentMouseMove( event ) {
            mouseX = event.clientX - windowHalfX;
            targetRotation = targetRotationOnMouseDown + ( mouseX - mouseXOnMouseDown ) * 0.02;
        }

        function onDocumentMouseUp( event ) {
            document.removeEventListener( 'mousemove', onDocumentMouseMove, false );
            document.removeEventListener( 'mouseup', onDocumentMouseUp, false );
            document.removeEventListener( 'mouseout', onDocumentMouseOut, false );
        }

        function onDocumentMouseOut( event ) {
            document.removeEventListener( 'mousemove', onDocumentMouseMove, false );
            document.removeEventListener( 'mouseup', onDocumentMouseUp, false );
            document.removeEventListener( 'mouseout', onDocumentMouseOut, false );
        }

        function onDocumentTouchStart( event ) {
            if ( event.touches.length === 1 ) {
                event.preventDefault();
                mouseXOnMouseDown = event.touches[ 0 ].pageX - windowHalfX;
                targetRotationOnMouseDown = targetRotation;
            }
        }

        function onDocumentTouchMove( event ) {
            if ( event.touches.length === 1 ) {
                event.preventDefault();
                mouseX = event.touches[ 0 ].pageX - windowHalfX;
                targetRotation = targetRotationOnMouseDown + ( mouseX - mouseXOnMouseDown ) * 0.05;
            }
        }


        function animatex(dir) {
            cubeGeo.faceVertexUvs[0][5] = [new THREE.UV(1, 0), new THREE.UV(1, 1), new THREE.UV(0, 1), new THREE.UV(0, 0)];
            cubeGeo.uvsNeedUpdate = true;
            animate2(dir);
        }

        var anim = 0;
        function animate2(dir) {
                requestAnimationFrame(function() {
                    cubeGeo.faceVertexUvs[0][5] = [new THREE.UV(1, 0), new THREE.UV(1, 1), new THREE.UV(0, 1), new THREE.UV(0, 0)];
                    cubeGeo.uvsNeedUpdate = true;
                    if(anim == 1) {
                        animate2(dir);
                    }
                });
                render2();
                stats.update();
        }

        function render2() {
            cube.rotation.x = cube.rotation.x+0.06;
            renderer.render( scene, camera );
        }

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

        }

        function render() {
            cube.rotation.y += ( targetRotation - cube.rotation.y ) * 0.05;
            $('#test').html(cube.rotation.y);
            renderer.render( scene, camera );
        }

    </script>
    <div id="up" style="position:absolute;z-index:500000;left:100px;top:20px;" class="nav">up</div>
    <div id="down" style="position:absolute;z-index:500000;left:100px;top:40px;" class="nav">down</div>
    <div id="left" style="position:absolute;z-index:500000;left:100px;top:60px;" class="nav">left</div>
    <div id="right" style="position:absolute;z-index:500000;left:100px;top:80px;" class="nav">right</div>
    <div id="test" style="position:absolute;z-index:500000;left:100px;top:100px;"> </div>
    <script>
        var _interval = 0;
        $(document).ready(function(){
        $('.nav').mouseover(function() {
            switch($(this).prop('id')) {
                case 'up':
                    anim = 1;
                    animatex('up');
                break;
            }
        });

        $('.nav').mouseout(
            function () {
                anim = 0;
            }
        );
        });
        </script>
    </body>
</html>




mesh.geometry.uvsNeedUpdate = true;

このリンクが役立つ場合があります。 https://github.com/mrdoob/three.js/issues/667

于 2013-02-07T14:34:14.133 に答える