我刚刚开始探索Three.js
以完成我需要渲染从maya导出的3D对象的任务,我已设法通过将.obj
文件转换为.js
来加载此对象使用提供的脚本。
现在我需要添加交互性,例如放大和围绕对象旋转相机,非常类似于此示例here
因此,通过文档OrbitControls
和TrackballControls
完全符合我的要求,但问题是对象不会停留在修复原点,它会在滚动时旋转,并移动放大和缩小时在飞机周围。
编辑: 屏幕截图
答案 0 :(得分:2)
您可以使用THREE.Box3()
及其.setFromObject()
方法将对象移动到场景的中心(请参阅createScene()
函数):
var SCREEN_WIDTH = window.innerWidth;
var SCREEN_HEIGHT = window.innerHeight;
var container;
var camera, scene, controls;
var canvasRenderer, webglRenderer;
var mesh, zmesh, geometry;
var meshes = [];
var mouse = new THREE.Vector2(),
INTERSECTED;
init();
animate();
function init() {
container = document.createElement('div');
document.body.appendChild(container);
camera = new THREE.PerspectiveCamera(70, SCREEN_WIDTH / SCREEN_HEIGHT, 0.1, 1000);
camera.position.set( 0, 5, 50 );
scene = new THREE.Scene();
// LIGHTS
var ambient = new THREE.AmbientLight(0x666666);
scene.add(ambient);
var directionalLight = new THREE.DirectionalLight(0xffeedd);
directionalLight.position.set(100, 200, -100).normalize();
scene.add(directionalLight);
// RENDERER
webglRenderer = new THREE.WebGLRenderer();
webglRenderer.setPixelRatio(window.devicePixelRatio);
webglRenderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
webglRenderer.domElement.style.position = "relative";
container.appendChild(webglRenderer.domElement);
var loader = new THREE.JSONLoader(),
callbackKey = function(geometry, materials) {
createScene(geometry, materials, 0, 0, 0, 20, "skull.jpg")
};
loader.load("https://raw.githubusercontent.com/FahadSHK/Skull3d/master/assets/skulld.js", callbackKey);
controls = new THREE.OrbitControls(camera, webglRenderer.domElement);
controls.rotateSpeed = 1.0;
controls.zoomSpeed = 1.5;
controls.panSpeed = 0.8;
controls.enableZoom = true;
controls.enablePan = false;
controls.enableDamping = true;
controls.dampingFactor = 0.3;
controls.keys = [65, 83, 68];
window.addEventListener('resize', onWindowResize, false);
}
$(document).on('mouseup', function(e) {
console.log("mouse up called");
isDragging = false;
});
function createScene(geometry, materials, x, y, z, scale, tmap) {
zmesh = new THREE.Mesh(geometry, materials);
zmesh.position.set(x, y, z);
zmesh.scale.setScalar(scale);
zmesh.updateMatrixWorld();
// Move the object to the center of the scene
var box3 = new THREE.Box3().setFromObject(zmesh);
zmesh.position.sub(box3.getCenter());
scene.add(zmesh);
}
function onWindowResize() {
windowHalfX = window.innerWidth / 2;
windowHalfY = window.innerHeight / 2;
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
controls.handleResize();
webglRenderer.setSize(window.innerWidth, window.innerHeight);
}
function animate() {
requestAnimationFrame(animate);
controls.update();
webglRenderer.render(scene, camera);
}
body {
overflow: hidden;
margin: 0;
}
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
供参考:https://discourse.threejs.org/t/problem-with-fbxmodel-position/1617/5
答案 1 :(得分:0)
我带了你的代码并将其修改为在这里的代码片段中运行。 (如你所见,我没有太多修改)。当我运行代码片段时,它的行为完全符合我的预期。我没有看到任何错误的轮换或平移。
我做看到几个控制台警告,建议您使用旧版本的three.js。尝试更新到最新版本,并修复警告。如果您仍然发现问题,请更新您的帖子,并提供您所看到的视频或动画。
<!DOCTYPE html>
<html lang="en">
<head>
<title>Skull 3d</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 {
margin: 0;
}
canvas {
width: 100%;
height: 100%
}
</style>
</head>
<body>
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js">
</script>
<!-- <script src="JSONLoader.js"> </script> -->
<script>
var SCREEN_WIDTH = window.innerWidth;
var SCREEN_HEIGHT = window.innerHeight;
var container;
var camera, scene, controls;
var canvasRenderer, webglRenderer;
var mesh, zmesh, geometry;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
var meshes = [];
var mouse = new THREE.Vector2(),
INTERSECTED;
var raycaster = new THREE.Raycaster();
var isDragging = false;
var previousMousePosition = {
x: 0,
y: 0
};
init();
animate();
// update(0, totalGameTime);
function init() {
container = document.createElement('div');
document.body.appendChild(container);
camera = new THREE.PerspectiveCamera(70, SCREEN_WIDTH / SCREEN_HEIGHT, 0.1, 1000);
camera.position.x = 300;
camera.position.y = 500;
camera.position.z = 500;
// camera.position.set( 100, 200, 100 );
scene = new THREE.Scene();
// LIGHTS
var ambient = new THREE.AmbientLight(0x666666);
scene.add(ambient);
var directionalLight = new THREE.DirectionalLight(0xffeedd);
directionalLight.position.set(100, 200, -100).normalize();
scene.add(directionalLight);
// RENDERER
webglRenderer = new THREE.WebGLRenderer();
webglRenderer.setPixelRatio(window.devicePixelRatio);
webglRenderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
webglRenderer.domElement.style.position = "relative";
container.appendChild(webglRenderer.domElement);
// calculate objects intersecting the picking ray
//var intersects = raycaster.intersectObjects( scene.children );
// TheJim01 - Replacing the loader calls with a BoxGeometry, since we can't access the file.
//var loader = new THREE.JSONLoader(),
//callbackKey = function(geometry,materials) {createScene(geometry,materials, 0, 0, 0, 20, "chameleon.jpg")};
//loader.load("skulld.js", callbackKey);
createScene(new THREE.BoxGeometry(10, 10, 10), new THREE.MeshPhongMaterial({
color: "red"
}), 0, 0, 0, 20, "chameleon.jpg");
controls = new THREE.OrbitControls(camera, webglRenderer.domElement);
controls.rotateSpeed = 1.0;
controls.zoomSpeed = 1.5;
controls.panSpeed = 0.8;
controls.noZoom = false;
controls.noPan = false;
controls.staticMoving = true;
controls.dynamicDampingFactor = 0.3;
controls.keys = [65, 83, 68];
window.addEventListener('resize', onWindowResize, false);
}
$(document).on('mouseup', function(e) {
console.log("mouse up called");
isDragging = false;
});
function createScene(geometry, materials, x, y, z, scale, tmap) {
// TheJim01 - Creating a standard mesh because we don't have the original model
zmesh = new THREE.Mesh(geometry, materials);
//zmesh = new THREE.Mesh(geometry, new THREE.MeshFaceMaterial(materials));
//zmesh = new THREE.Mesh(geometry, new THREE.MeshLambertMaterial({map: THREE.TextureLoader(tmap)}));
zmesh.position.set(x, y, z);
zmesh.scale.set(scale, scale, scale);
meshes.push(zmesh);
scene.add(zmesh);
}
function onWindowResize() {
windowHalfX = window.innerWidth / 2;
windowHalfY = window.innerHeight / 2;
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
controls.handleResize();
webglRenderer.setSize(window.innerWidth, window.innerHeight);
}
function animate() {
requestAnimationFrame(animate);
controls.update();
webglRenderer.render(scene, camera);
}
function toRadians(angle) {
return angle * (Math.PI / 180);
}
function toDegrees(angle) {
return angle * (180 / Math.PI);
}
</script>
</body>
</html>