Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Three.js 强制轨道控制围绕移动对象导航(几乎正常工作)_Three.js - Fatal编程技术网

Three.js 强制轨道控制围绕移动对象导航(几乎正常工作)

Three.js 强制轨道控制围绕移动对象导航(几乎正常工作),three.js,Three.js,我正在学习Three.js,我正在玩太阳系的模型来学习它是如何工作的。所以我有一个场景,地球围绕太阳旋转,月亮围绕地球旋转 现在我想把重点放在月球上,并使用控制装置围绕月球旋转(同时让它一直在屏幕中央)。轨道控制似乎是实现这一目标的理想选择,但我无法让它们在移动的月球上工作 以下是我的3次尝试(请忽略地球和月球是立方体) 尝试1-放置摄影机() 首先,我创建了一个场景,其中相机是月亮的孩子(没有轨道控制) var摄影机、控件、场景、渲染器、labelRenderer; 太阳平面,地球,月球;

我正在学习Three.js,我正在玩太阳系的模型来学习它是如何工作的。所以我有一个场景,地球围绕太阳旋转,月亮围绕地球旋转

现在我想把重点放在月球上,并使用控制装置围绕月球旋转(同时让它一直在屏幕中央)。轨道控制似乎是实现这一目标的理想选择,但我无法让它们在移动的月球上工作

以下是我的3次尝试(请忽略地球和月球是立方体)

尝试1-放置摄影机() 首先,我创建了一个场景,其中
相机
是月亮的孩子(没有轨道控制)

var摄影机、控件、场景、渲染器、labelRenderer;
太阳平面,地球,月球;
var角=0;
函数buildScene(){
场景=新的三个。场景();
solarPlane=创建solarPlane();
地球=创造体(“地球”);
月亮=创造体(“月亮”);
场景。添加(solarPlane);
solarPlane.add(地球);
地球。添加(月亮);
添加(相机);
}
init();
制作动画();
函数init(){
renderer=new THREE.WebGLRenderer({
反别名:假
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth、window.innerHeight);
document.body.appendChild(renderer.doElement);
labelRenderer=new THREE.css2drender();
labelRenderer.setSize(window.innerWidth、window.innerHeight);
labelRenderer.DoElement.style.position='absolute';
labelRenderer.domElement.style.top='0';
labelRenderer.DomeElement.style.pointerEvents='none';
document.body.appendChild(labelRenderer.doElement);
摄像头=新的三个透视摄像头(60,window.innerWidth/window.innerHeight,0.11000);
摄像机位置设置(13.670839104116506、10.62941701834559、0.3516419193657562);
摄像机。注视(0,0,0);
buildScene();
}
函数动画(时间){
角度=(角度+0.005)%(2*Math.PI);
旋转体(接地,角度,1);
旋转体(月亮,角度,2);
render();
请求动画帧(动画);
功能旋转体(主体、角度、半径){
body.rotation.x=角度;
body.position.x=半径*数学cos(角度);
主体位置y=半径x数学sin(角度);
body.position.z=半径*Math.sin(角度);
}
}
函数render(){
渲染器。渲染(场景、摄影机);
渲染(场景、摄影机);
}
函数createBody(名称、父级){
var geometry=新的三立方测量法(1,1,1);
const body=new THREE.Mesh(几何体,new THREE.MeshNormalMaterial());
身体位置设置(1,1,1);
body.scale.set(.3、.3、.3);
body.name=名称;
body.add(makeTextLabel(name));
返回体;
}
函数createSolarPlane(){
var solarPlane=新的三个.GridHelper(5,10);
添加(makeTextLabel(“太阳能平面”);
返回太阳能飞机;
}
函数makeTextLabel(标签){
var text=document.createElement('div');
text.style.color='rgb(255,255,255)';
text.textContent=标签;
返回新的三个.CSS2DObject(文本);
}
正文{
保证金:0;
}

我通过引入一个假的相机来实现它,除了
camera.parent

fakeCamera = camera.clone(); // parent becomes null
controls = new THREE.OrbitControls(fakeCamera, renderer.domElement);
这样,
OrbitControls
就有了一个具有自己坐标系的摄像头

然后,在渲染之前,我将
fakeCamera
的值复制回用于渲染的真实摄影机

camera.position.copy(fakeCamera.position);
camera.quaternion.copy(fakeCamera.quaternion);
camera.scale.copy(fakeCamera.scale);

render();
而且效果很好

编辑

我注意到

camera.position.copy(fakeCamera.position);
camera.quaternion.copy(fakeCamera.quaternion);
camera.scale.copy(fakeCamera.scale);
可以替换为

camera.copy(fakeCamera);
(以下代码已相应更新)

var摄影机、伪摄影机、控件、场景、渲染器、labelRenderer;
太阳平面,地球,月球;
var角=0;
函数buildScene(){
场景=新的三个。场景();
solarPlane=创建solarPlane();
地球=创造体(“地球”);
月亮=创造体(“月亮”);
场景。添加(solarPlane);
solarPlane.add(地球);
地球。添加(月亮);
添加(相机);
}
init();
制作动画();
函数init(){
renderer=new THREE.WebGLRenderer({
反别名:假
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth、window.innerHeight);
document.body.appendChild(renderer.doElement);
labelRenderer=new THREE.css2drender();
labelRenderer.setSize(window.innerWidth、window.innerHeight);
labelRenderer.DoElement.style.position='absolute';
labelRenderer.domElement.style.top='0';
labelRenderer.DomeElement.style.pointerEvents='none';
document.body.appendChild(labelRenderer.doElement);
摄像头=新的三个透视摄像头(60,window.innerWidth/window.innerHeight,0.11000);
摄像机位置设置(13.670839104116506、10.62941701834559、0.3516419193657562);
摄像机。注视(0,0,0);
buildScene();
fakeCamera=camera.clone();
控件=新的三个.OrbitControls(fakeCamera、renderer.domElement);
controls.enablePan=false;
controls.enableDamping=false;
}
函数动画(时间){
角度=(角度+0.005)%(2*Math.PI);
旋转体(接地,角度,1);
旋转体(月亮,角度,2);
照相机。复制(伪造照相机);
render();
请求动画帧(动画);
功能旋转体(主体、角度、半径){
body.rotation.x=角度;
body.position.x=半径*数学cos(角度);
主体位置y=半径x数学sin(角度);
body.position.z=半径*Math.sin(角度);
}
}
函数render(){
渲染器。渲染(场景、摄影机);
渲染(场景、摄影机);
}
函数createBody(名称、父级){
var geometry=新的三立方测量法(1,1,1);
const body=new THREE.Mesh(几何体,new THREE.MeshNormalMaterial());
身体位置设置(1,1,1);
body.scale.set(.3、.3、.3);
body.name=名称;
body.add(makeTextLabel(name));
返回体;
}
函数createSolarPlane(){
var solarPlane=新的三个.GridHelper(5,10);
添加(makeTextLabel(“太阳能平面”);
返回太阳能飞机;
}
函数makeTextLabel(标签){
var text=document.createElement('div');
text.style.color='rgb(255,255,255)';
text.textContent=标签;
camera.copy(fakeCamera);
THREE.OrbitControlsLocal = function ( realObject, domElement ) {
    this.realObject = realObject;
    //Camera and Object3D have different forward direction:
    let placeholderObject = realObject.isCamera ? new THREE.PerspectiveCamera() : new THREE.Object3D;
    this.placeholderObject = placeholderObject;

    THREE.OrbitControls.call( this, placeholderObject, domElement );

    let globalUpdate = this.update;
    this.globalUpdate = globalUpdate;
    this.update = function() {

        //This responds to changes made to realObject from outside the controls:
        placeholderObject.position.copy( realObject.position );
        placeholderObject.quaternion.copy( realObject.quaternion);
        placeholderObject.scale.copy( realObject.scale );
        placeholderObject.up.copy( realObject.up );

        var retval = globalUpdate();
        realObject.position.copy( placeholderObject.position );
        realObject.quaternion.copy( placeholderObject.quaternion);
        realObject.scale.copy( placeholderObject.scale );
        return retval ;

    };

    this.update();
};

THREE.OrbitControlsLocal.prototype = Object.create(THREE.OrbitControls.prototype);
THREE.OrbitControlsLocal.prototype.constructor = THREE.OrbitControlsLocal;

Object.defineProperties(THREE.OrbitControlsLocal.prototype, {
    localTarget: {
        get: ()=>this.target,
        set: v=>this.target=v
    }
});