ThreeJS中一组3D对象的中心轴
Posted
技术标签:
【中文标题】ThreeJS中一组3D对象的中心轴【英文标题】:Center pivot in a group of 3D objects in ThreeJS 【发布时间】:2015-07-12 19:19:20 【问题描述】:我目前正在开发一个插件原型,可以通过 ThreeJS 自定义 3D 对象。到目前为止我所做的工作可以在这里看到:
http://itemgl.kaleidoscop.net/
您可能已经看到,当您悬停左箭头或右箭头时,对象会旋转,其原点位于左上角。有人知道如何在 ThreeJS 中改变它吗?
代码如下:
var options = $.extend(
id: 'canvas',
width: 1110,
height: 650,
clearColor: 0xEEEEEE,
btnLeft: $('#btnPrevious'),
btnRight: $('#btnNext'),
imagesLeather: ('.imageWood'),
imagesWood: ('.imageWood'),
core: object: [], renderer: null, camera: null, scene: null, light: null, canvas: null, spotLight: null, group: null, interval: null,
items: wood: null, leather: null,
geometry: ground: null, cube: null,
numObj: 7,
objGeometry: [x: 15, y: 1, z: 15, x: 2, y: 16, z: 2, x: 2, y: 16, z: 2, x: 2, y: 32, z: 2, x: 2, y: 32, z: 2,x: 12, y: 3, z: 1,x: 12, y: 3, z: 1],
objPosition: [x: 8, y: 6, z: 3, x: 1, y: -2, z: 10, x: 15, y: -2, z: 10, x: 1, y: 6, z: -5, x: 15, y: 6, z: -5, x: 8, y: 20, z: -5, x: 8, y: 15, z: -5],
objType: ['Leather', 'Wood', 'Wood', 'Wood', 'Wood','Leather','Leather']
, options);
var methods =
init: function(settings)
if(typeof settings === 'object')
$.extend(settings, this.options);
options.core.scene = new THREE.Scene();
options.core.camera = new THREE.PerspectiveCamera(50, options.width/options.height, 0.1, 1000);
options.core.renderer = new THREE.WebGLRenderer();
options.core.renderer.setClearColor(new THREE.Color(0xEEEEEE, 1.0));
options.core.renderer.setSize(options.width, options.height);
options.core.renderer.shadowMapEnabled = true;
options.core.group = new THREE.Object3D();
options.core.group.position.x = 5;
for(var i=0; i<options.numObj; i++)
var cubeGeometry = new THREE.BoxGeometry(options.objGeometry[i].x, options.objGeometry[i].y, options.objGeometry[i].z);
options.core.object[i] = methods.addMaterial(cubeGeometry, 'images/Resources/UVMap.png');
options.core.object[i].receiveShadow = true;
options.core.object[i].position.x = options.objPosition[i].x;
options.core.object[i].position.y = options.objPosition[i].y;
options.core.object[i].position.z = options.objPosition[i].z;
options.core.group.add(options.core.object[i]);
options.core.scene.add(options.core.group);
options.core.camera.position.x = 10;
options.core.camera.position.y = 30;
options.core.camera.position.z = 60;
options.core.camera.lookAt(new THREE.Vector3(10, 0, 0));
options.core.light = new THREE.AmbientLight(0x0c0c0c);
options.core.scene.add(options.core.light);
options.core.spotLight = new THREE.SpotLight(0xffffff);
options.core.spotLight.position.set(-30, 60, 60);
options.core.spotLight.castShadow = true;
options.core.scene.add(options.core.spotLight);
$("#"+options.id).append(options.core.renderer.domElement);
methods.render();
methods.setupButtons();
options.core.renderer.render(options.core.scene, options.core.camera);
,
setupButtons: function()
options.btnLeft.hover(
function()
options.core.interval = window.setInterval(function()
options.core.group.rotation.y += 0.05;
options.core.renderer.render(options.core.scene, options.core.camera);
, 15);
, function()
window.clearInterval(options.core.interval);
);
options.btnRight.hover(
function()
options.core.interval = window.setInterval(function()
options.core.group.rotation.y -= 0.05;
options.core.renderer.render(options.core.scene, options.core.camera);
, 15);
, function()
window.clearInterval(options.core.interval);
);
,
render: function()
requestAnimationFrame(methods.render);
options.core.renderer.render(options.core.scene, options.core.camera);
,
changeItem: function(type, obj)
var texture = THREE.ImageUtils.loadTexture(obj.firstChild.src);
for(var i=0; i<options.numObj; i++)
if(options.objType[i] == type)
options.core.object[i].material.map = texture;
,
addMaterial: function(geom, imageFile)
var texture = THREE.ImageUtils.loadTexture(imageFile)
var mat = new THREE.MeshPhongMaterial();
mat.map = texture;
mat.needsUpdate = true;
var mesh = new THREE.Mesh(geom, mat);
return mesh;
;
$.fn.ItemGL = function(method)
if(typeof method === 'undefined')
method = 'init';
if(methods[method])
return methods[ method ].apply(this, Array.prototype.slice.call(arguments, 1));
else if(typeof method === 'object' || !method)
return methods.init.apply(this, arguments);
else
$.error('Method '+ method+' does not exist on jQuery');
;
【问题讨论】:
***.com/questions/12746011/…, ***.com/questions/18068599/… 谢谢@dekkard!我认为这会有所帮助:D 见***.com/questions/28848863/… 【参考方案1】:group.applyMatrix( new THREE.Matrix4().makeTranslation( x,y,z ) );
您可以在许多其他问题中看到的内容并没有为我完成这项工作。 可能是因为它是一个组而不是单个对象。
我的解决方案(有点长,但对我有用):
找出所有 objPosition 值的中心
var maxTrans = x:0, y:0, z:0;
var minTrans = x:0, y:0, z:0;
var translate2Center = x:0, y:0, z:0;
for(var i=0; i<options.objPosition.length; i++)
var temp = options.objPosition[i];
if (temp.x > maxTrans.x) maxTrans.x = temp.x;
else if (temp.x < minTrans.x) minTrans.x = temp.x;
if (temp.y > maxTrans.y) maxTrans.y = temp.y;
else if (temp.y < minTrans.y) minTrans.y = temp.y;
if (temp.z > maxTrans.z) maxTrans.z = temp.z;
else if (temp.z < minTrans.z) minTrans.z = temp.z;
translate2Center.x = minTrans.x + (maxTrans.x-minTrans.x)/2;
translate2Center.y = minTrans.y + (maxTrans.y-minTrans.y)/2;
translate2Center.z = minTrans.z + (maxTrans.z-minTrans.z)/2;
在添加到组之前翻译每个对象
for(var i=0; i<options.numObj; i++)
options.core.object[i].position.x = options.objPosition[i].x - translate2Center.x;
options.core.object[i].position.y = options.objPosition[i].y - translate2Center.y;
options.core.object[i].position.z = options.objPosition[i].z - translate2Center.z;
options.core.group.add(options.core.object[i]);
将整个组移回
options.core.group.applyMatrix( new THREE.Matrix4().makeTranslation(
translate2Center.x, translate2Center.y, translate2Center.z)
);
【讨论】:
谢谢伙计!你的回答太棒了!我一直在努力解决这个问题@Tobias以上是关于ThreeJS中一组3D对象的中心轴的主要内容,如果未能解决你的问题,请参考以下文章