three.js 鼠标旋转怎么通过移动鼠标改变相机旋转

最近在做的项目中遇到需要保存当前的3d管道视角设置的问题,用户希望在对3d场景内的管道进行了缩放、旋转、移动之后可以将场景当前的视角状态保存在数据库中,并在下次加载时读取。 经过不断的尝试和研究,在同事的帮助下总算完成,下面说一下注意事项并附上实现代码。
首先,经过测试保存视角取决于两个部分,一个是camera这个超大的js对象,另一个就是右键平移执行的操作在controls中(开发中使用的是TrackballControls.js)。
先来说camera这个对象参数非常多,详细参数不再做说明,大家可以直接参考Three.js的 camera定义部分的源码,主要有up(相机的z坐标方向)、position(相机位置)、rotation(相机旋转,里面又包含_quaternion)、scale(比例),除了这些之外还有matrix、matrixWorld、matrixWorldInverse、projectionMatrix这几4&4的矩阵,另外还有far、aspect、near参数。这些因素共同决定了相机的视角。要逐个保存这些数据是一项相当繁琐的工作,因此我们想办法将这些对象合并成一个json字符串并在读取时将它们反转。
首先考虑的自然是 JSON.stringify() ,使用该方法转字符串的时候在谷歌浏览器下提示 循环引用的对象(貌似是谷歌的BUG,FF下应该是正常的未测试),因此无法转换,找了一下相关文章发现该方法可以传递一个自定义函数进来,避免循环对象的引用。如下所示
var tc = camera.clone();var cache = [];
var pdata = JSON.stringify(tc, function(key, value) {
if (typeof value === 'object' && value !== null) {
if (cache.indexOf(value) !== -1) {
// Circular reference found, discard key
// Store value in our collection
cache.push(value);
cache = null; // Enable garbage collection
这样就可以将camera的参数保存为一个json字符串形式从而可以保存到数据库中。
对于平移的保存,查看TrackballControls.js文件即可找到 控制平移的参数为 controls.target 为一个THREE.Vector3的向量类型,那很轻易的就可以将其保存,如下所示我们将上面的camera和controls.target合并为一个JSON字符串并保存到数据库中即可。
var target0 = controls.target.clone();
var ptarget = JSON.stringify(target0);
pdata = '{"cam":'+pdata+',"ctrl":'+ptarget+'}';
上面的方式一般都可以想得到,关键是如何将这个json字符串读取出来并完整的赋值给新的camera对象。
我们使用ajax读取后,并将其反转为JSON对象即 &:
var r = JSON.parse(d.angleView);
//d.angleView为数据库中读取出来的视角字符串参数
//关键在这里,使用jquery的extend方法合并相机参数与反转过来的json对象,其中的camera为全局的camera对象,页面初始化时已经定义,此处clone是新生成一个对象,因为camera的赋值均为引用赋值非直接赋值,类似传址
var tcamera = $.extend(true, {}, camera.clone(), r.cam);
var tctrl = new&THREE.Vector3(r.ctrl.x,r.ctrl.y,r.ctrl.z);
camera = tcamera.clone();
controls = new THREE.TrackballControls(camera, renderer.domElement);
//重新为相机加载控制器
camera.updateProjectionMatrix(); //更新相机
controls.target.copy(tctrl);//更新控制器的中心点 copy方法可以在TrackballControls.js中找到
这样 我们就完整的实现了保存相机视角的功能。
阅读(...) 评论()匿名用户不能发表回复!|
每天回帖即可获得10分可用分!小技巧:
你还可以输入10000个字符
(Ctrl+Enter)
请遵守CSDN,不得违反国家法律法规。
转载文章请注明出自“CSDN(www.csdn.net)”。如是商业用途请联系原作者。Three.js(20)
先看效果:
&!DOCTYPE html&
lang="en"&
charset="UTF-8"&
&手动旋转相机&
type="text/javascript" src="../libs/three.js"&&
type="text/javascript" src="../libs/jquery-1.9.0.js"&&
id="container"&&
type="text/javascript"&
$(function(){
var camera,scene,renderer,
var mouseX = 0,mouseY = 0;
var windowHalfX = window.innerWidth/2;
var windowHalfY = window.innerHeight/2;
animate();
function init(){
scene = new THREE.Scene();
container = document.getElementById('container');
camera = new THREE.PerspectiveCamera(40,window.innerWidth/window.innerHeight,1,1000);
camera.position.z = 180;
camera.lookAt(scene.position);
light = new THREE.DirectionalLight(0xffffff,1);
light.position.set(0,0,10);
scene.add(light);
var cubeGeometry = new THREE.CubeGeometry(30,30,30);
var cubeMaterial = new THREE.MeshLambertMaterial({color:0xff0000 });
mesh = new THREE.Mesh(cubeGeometry,cubeMaterial);
scene.add(mesh);
renderer = new THREE.WebGLRenderer({antialias:true});
renderer.setSize(window.innerWidth,window.innerHeight);
container.appendChild(renderer.domElement);
document.addEventListener('mousemove',onDocumentMouseMove,false);
window.addEventListener( 'resize', onWindowResize, false );
function onWindowResize(){
windowHalfX = window.innerWidth/2;
windowHalfY = window.innerHeight/2;
camera.aspect = window.innerWidth/window.innerH
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth,window.innerHeight);
function onDocumentMouseMove(){
mouseX = (event.clientX-windowHalfX);
mouseY = (event.clientY-windowHalfY);
function animate(){
requestAnimationFrame(animate);
function render(){
camera.position.x += (mouseX - camera.position.x);
camera.position.y += (mouseY - camera.position.y);
camera.lookAt(scene.position);
renderer.render( scene, camera );
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:50888次
积分:1503
积分:1503
排名:千里之外
原创:81篇
转载:66篇
评论:20条
(1)(3)(1)(2)(16)(19)(5)(4)(8)(31)(25)(1)(6)(5)(1)(1)(3)(4)(9)(4)(2)(2)(5)(1)

我要回帖

更多关于 three.js 自动旋转 的文章

 

随机推荐