更新 ThreeJS 模型在 Animate 中的位置(如何在回调之外访问模型的位置)



我正在尝试创建ISS绕地球的模型。我正在使用三名J来实现这一目标。到目前为止,除了更新进口ISS模型的位置时,我的一切正常。我有一个球体,可以每5秒钟从Ajax调用中绕地球旋转,然后将其转换为地球球模型上的坐标。我本质上想用ISS的模型代替轨道的球体(代码中的孔子(。在模型时遇到麻烦。我目前尝试的是在模型的动画函数中包括参数,然后在回调上将其发送到动画函数,但这会导致整个场景冻结。

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>three.js webgl - OBJLoader + MTLLoader</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: #000;
                color: #fff;
                margin: 0px;
                overflow: hidden;
            }
        </style>
    </head>
    <body>
        <script src="Resources/three.js"></script>
        <script src="Resources/TDSLoader.js"></script>
        <script src="Resources/FBXLoader.js"></script>
        <script src="Resources/GLTFLoader.js"></script>
        <script src="Resources/inflate.min.js"></script>
        <script src="Resources/TrackballControls.js"></script>
<script>
var lat, long, issPosition;
//*********************PRELIM FUNCTIONS BEGIN**********************************
//AJAX request for current position of the ISS
function GetValue() {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
    var requestResponse = xhr.responseText;
    var issInfo = JSON.parse(requestResponse);
    var Lat = issInfo.iss_position.latitude;
    var Long = issInfo.iss_position.longitude;
    callback(Lat, Long); //callback function with lat and long info
                }
            };
            xhr.open("GET", "http://api.open-notify.org/iss-now.json", true);
            xhr.send();
        }
    function callback(Lat, Long) {
        lat = Lat; //set global variables equal to lat and long so animate function has access
        long = Long;
    }
    GetValue(); //function call to get iss location
    setInterval(GetValue, 5000); //interval for iss location, updates every 5 seconds
//convert long & lat to 3D coordinate
function latLongToVector3(lat, lon, radius, heigth) {
    var phi = (lat)*Math.PI/180;
    var theta = (lon-180)*Math.PI/180;
    var x = -(radius+heigth) * Math.cos(phi) * Math.cos(theta);
    var y = (radius+heigth) * Math.sin(phi);
    var z = (radius+heigth) * Math.cos(phi) * Math.sin(theta);
        return new THREE.Vector3(x,y,z);
    }     
//******************PRELIM FUNCTIONS END********************************************
//******************THREE JS ENVIRONMENT BEGIN**************************************   
var width = window.innerWidth;
var height = window.innerHeight;
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, width/height, 0.01, 1000);
camera.position.z = 400;
var 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;
                controls.keys = [ 65, 83, 68 ];
var renderer = new THREE.WebGLRenderer();
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.setSize(width, height);
document.body.appendChild(renderer.domElement);
var direcLight = new THREE.DirectionalLight(0xffffff, 0.3);
direcLight.position.set(-3,3,1.5);
direcLight.castShadow = true;
scene.add(direcLight);
var ambientLight = new THREE.AmbientLight(0xc9c9c9, 1.5);
scene.add(ambientLight);
var geometry1 = new THREE.SphereGeometry(200,32,32);
var geometry2 = new THREE.SphereGeometry(202.5,32,32);
var geometry3 = new THREE.SphereGeometry(3, 32, 32);
var material1 = new THREE.MeshBasicMaterial ({
    color: 0xff0000
});
var material2 = new THREE.MeshPhongMaterial({
    map: new THREE.TextureLoader().load('Resources/Earth3/earthmapoftwo.jpg'),
    bumpMap: new THREE.TextureLoader().load('Resources/Earth3/Bump2.jpg'),
    bumpScale: 1,
    specularMap: new THREE.TextureLoader().load('Resources/Earth3/oceanmaskbytwo.png'),
    specular: new THREE.Color('grey'),
    shininess: 40
});
var material3 = new THREE.MeshPhongMaterial({
    alphaMap: new THREE.TextureLoader().load('Resources/Earth3/Clouds.png'),
    transparent: true,
});
var issModel;
var loaderGLTF = new THREE.GLTFLoader();  
loaderGLTF.load(
    "Resources/Earth3/iss.gltf",
    function(gltf) { //I want to be able to access this gltf outside of this callback function 
        gltf.scene.scale.x = 0.1;
        gltf.scene.scale.y = 0.1;
        gltf.scene.scale.z = 0.1;
        console.log(gltf.scene.position);
        scene.add(gltf.scene);
        animate(gltf); //send gltf to animate function, this does not work
    }
)
var sphere = new THREE.Mesh(geometry1, material2); 
var clouds = new THREE.Mesh(geometry2, material3);
var posSphere = new THREE.Mesh(geometry3, material1);
sphere.receiveShadow = true;
clouds.receiveShadow = true;
posSphere.receiveShadow = true;
scene.add(sphere);
scene.add(clouds);
scene.add(posSphere);
function animate(gltf) {
    clouds.rotation.x += 0.0001;
    clouds.rotation.y += 0.0001;
    clouds.rotation.z += 0.0001; 
    issPosition = latLongToVector3(lat, long, 200, 10);
    posSphere.position.x = issPosition.x; //sphere's location is updated with the issPosition & works 
    posSphere.position.y = issPosition.y;
    posSphere.position.z = issPosition.z;
    gltf.scene.position.x = issPosition.x; //Part I am struggling with here, how to access the gltf's position from within this function. Essentially I want to replace the sphere with the gltf
    gltf.scene.position.y = issPosition.y;
    gltf.scene.position.z = issPosition.z;
    controls.update();
    requestAnimationFrame(animate);
    renderer.render(scene, camera);
            }          
animate();
//**************************THREE JS ENVIRONMENT END*************************************  
</script>
</body>
</html>

您将参数定义到动画函数,但立即以无参数调用。(在代码的最后一行(。这就是为什么您的应用程序"冻结"的原因。(它不是冻结..它可能是一个例外。.您可以在调试器中看到。 ctrl shift j inChrome或更多工具 ->开发人员工具从右上角的...菜单中。例外应在底部以红色显示。(

取出您执行'animate(gltf('的代码行,而是" issmodel = gltf.scene;"

然后在您的动画函数中而不是" gltf.scene.position.x ="等

只是做" issmodel.position.copy(issposition(;"

如果您仍然陷入困境,请尝试在某个地方在线托管它,我们可以更深入地看。

相关内容

  • 没有找到相关文章

最新更新