简体   繁体   English

在Three.js的中心旋转mergeometry对象

[英]Rotate the mergeometry object at its center in Three.js

I am struggling to find the way to rotate the object at its center. 我正在努力寻找一种方法来旋转对象的中心。 At the moment i am able to rotate the scene, but when i do the rotation, the object goes away from the user. 目前,我可以旋转场景,但是当我旋转时,对象会远离用户。 I look into the some the already asked questions in the same line on the forum, but couldn't able to get it work. 我在论坛的同一行中调查了一些已经问过的问题,但无法使其正常工作。 Below is the part of the html/three.js file i am using /attached you will find the complete working example.Any help is greatly appreciated 以下是我正在使用/ attached的html / three.js文件的一部分,您将找到完整的工作示例。非常感谢您的帮助

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

            <script>

                    var container, stats;
                    var camera, controls, scene, renderer;
                    var pickingData = [], pickingTexture, pickingScene;
                    var objects = [];
                    var highlightBox;
                    var splitCoord;
                    var avStdProp;

                    var mouse = new THREE.Vector2();
                    var offset = new THREE.Vector3( 10, 10, 10 );

                    var geom = new THREE.BoxGeometry(0.005, 0.005, 0.005 );
                            geom.colorsNeedUpdate = true;

                    init();
                    animate();

                    function init() {

                            container = document.getElementById( "container" );

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

                            camera.position.x=250;
                            camera.position.y=300;
                            camera.position.z=400;

                            renderer = new THREE.WebGLRenderer( { antialias: true } );
                            controls = new THREE.TrackballControls(camera);
                            controls.rotateSpeed = 1.0;
                            controls.zoomSpeed = 4;
                            controls.panSpeed = 0.8;
                            controls.noZoom = false;
                            controls.noPan = false;
                            controls.staticMoving = true;
                            controls.dynamicDampingFactor = 0.3;

                            scene = new THREE.Scene();


                            pickingScene = new THREE.Scene();
                            pickingTexture = new THREE.WebGLRenderTarget(800, 800);
                            pickingTexture.minFilter = THREE.LinearFilter;
                            pickingTexture.generateMipmaps = false;

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

                            var light = new THREE.SpotLight( 0xffffff, 1.5 );
                            light.position.set( 0, 500, 2000 );
                            scene.add( light );

                            var geometry = new THREE.Geometry(),
                            pickingGeometry = new THREE.Geometry(),
                            pickingMaterial = new  THREE.MeshBasicMaterial( { vertexColors: THREE.VertexColors } ),
                            defaultMaterial = new THREE.MeshLambertMaterial({ color: 0xffffff, shading: THREE.FlatShading, vertexColors: THREE.VertexColors } );

                            function applyVertexColors( g, c ) {

                                    g.faces.forEach( function( f ) {

                                            var n = ( f instanceof THREE.Face3 ) ? 3 : 4;

                                            for( var j = 0; j < n; j ++ ) {

                                                    f.vertexColors[ j ] = c;

                                            }

                                    } );

                            }

                            var color = new THREE.Color();

                            var matrix = new THREE.Matrix4();
                            var quaternion = new THREE.Quaternion();

                            var coord="219_163_189;130_173_179;161_113_231;92_103_176;169_193_180;161_165_187;262_163_166;198_143_155;161_189_155;125_121_107";
                            splitCoord=coord.split(";");
                            var coordColr="0_255_255;255_255_0;0_0_255;0_255_0;255_255_0;0_255_0;0_0_255;0_255_255;255_255_0;210_210_45";
                            var splitCoordColor=coordColr.split(";");
                            var avgStd="1_0;3_0;0_0;2_0;3_0;2_0;0_0;1_0;3_0;3_0.35";
                            avStdProp=avgStd.split(";");

                            for ( var i = 0; i < splitCoord.length; i++ ) {

                                    var position = new THREE.Vector3();
                                    var xyz=splitCoord[i].split("_");
                                    var col=splitCoordColor[i].split("_");

                                    position.x = xyz[0];
                                    position.y = xyz[1];
                                    position.z = xyz[2];

                                    var rotation = new THREE.Euler();
                                    rotation.x = 0
                                    rotation.y = 0;
                                    rotation.z = 0;

                                    var scale = new THREE.Vector3();
                                    scale.x = 200 + 100;
                                    scale.y = 200 + 100;
                                    scale.z = 200 + 100;

                                    quaternion.setFromEuler( rotation, false );
                                    matrix.compose( position, quaternion, scale );

                                     // give the geom's vertices a random color, to be displayed

                                    col[0]=col[0]/255;
                                    col[1]=col[1]/255;
                                    col[2]=col[2]/255;

                                    applyVertexColors(geom, color.setRGB(col[0], col[1], col[2]));

                                    geometry.merge( geom, matrix );

                                    // give the geom's vertices a color corresponding to the "id"

                                    applyVertexColors( geom, color.setHex( i ) );

                                    pickingGeometry.merge( geom, matrix );

                                    pickingData[ i ] = {

                                            position: position,
                                            rotation: rotation,
                                            scale: scale

                                    };

                            }

                            var drawnObject = new THREE.Mesh( geometry, defaultMaterial );
                            scene.add( drawnObject );

                            pickingScene.add( new THREE.Mesh( pickingGeometry, pickingMaterial ) );

                            highlightBox = new THREE.Mesh(
                                    new THREE.BoxGeometry( 0.009, 0.009, 0.009 ),
                                    new THREE.MeshLambertMaterial( { color: 0xffffff }
                            ) );
                            scene.add( highlightBox );


                            //renderer.setClearColor( 0xffffff );
                            renderer.setPixelRatio( window.devicePixelRatio );
                            renderer.setSize(800,800);
                            renderer.sortObjects = false;

                             container.appendChild( renderer.domElement );
                            renderer.domElement.addEventListener( 'mousemove', onMouseMove );

                    }

                    //

                    function onMouseMove( e ) {

                            mouse.x = e.clientX;
                            mouse.y = e.clientY;

                    }

                    function pick() {
                    //render the picking scene off-screen
                    renderer.render( pickingScene, camera, pickingTexture );

                    //create buffer for reading single pixel
                    var pixelBuffer = new Uint8Array( 4 );

                    //read the pixel under the mouse from the texture
                    renderer.readRenderTargetPixels(pickingTexture, mouse.x+window.pageXOffset, pickingTexture.height - (mouse.y+window.pageYOffset), 1, 1, pixelBuffer);

                    //interpret the pixel as an ID
                    var id = ( pixelBuffer[0] << 16 ) | ( pixelBuffer[1] << 8 ) | ( pixelBuffer[2]);
                    var data = pickingData[ id ];

                    if (data) {

                    //move our highlightBox so that it surrounds the picked object
                    if (data.position && data.rotation && data.scale && controls.enabled){

                     highlightBox.position.copy( data.position );
                     highlightBox.rotation.copy( data.rotation );
                     highlightBox.scale.copy( data.scale ).add( offset );
                     highlightBox.visible = true;
                     }
                     }

                     else {
                                    highlightBox.visible = false;
                            }
                     }

                    function animate() {

                            requestAnimationFrame( animate );
                            render();
                            //stats.update();

                    }

                     function render() {
                            controls.update();
                            pick();
                            renderer.render(scene, camera);
                    }

any help? 有什么帮助吗?

You can set your objects geometry to center, so the center of the mesh will then be at position (0,0,0) and it wont "move away" while rotating. 您可以将对象的几何形状设置为居中,因此网格的中心将位于位置(0,0,0),并且在旋转时不会“移开”。

Do it like this: 像这样做:

geometry.center();
var drawnObject = new THREE.Mesh( geometry, defaultMaterial );
scene.add( drawnObject );

Update 更新

Because you want to use picking in an unusual way by saving your geometrys coordinates into an array, centering the geometry doesnt help you. 因为您想通过将几何坐标保存到数组中来以一种不寻常的方式使用拾取,所以将几何居中对您没有帮助。 Your question was "Rotate the mergeometry object at its center", but it seems like you want to rotate the camera around your geometrys center. 您的问题是“在其中心旋转合并几何对象”,但似乎您想围绕几何中心旋转相机。

Calculate the bounding sphere of your geometry and set the controls target to its position: 计算几何的边界球并将控件目标设置为其位置:

drawnObject.geometry.computeBoundingSphere();
controls.target = drawnObject.geometry.boundingSphere.center;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM