我正在尝试创建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(;"
如果您仍然陷入困境,请尝试在某个地方在线托管它,我们可以更深入地看。