Подтвердить что ты не робот

Как повернуть некоторые луны вокруг планеты с помощью THREE.js?

Я думаю, что эта картина лучше всего объясняет мою проблему:

hooray for optical illusions

Сначала я перевешу коробку вдоль красной линии. Затем я хочу, чтобы эффект вращения был синей линией в a, но то, что на самом деле происходит, больше похоже на синюю линию в b. Похоже, что изменение вращения всегда относится к исходному пространству объектов, но перевод (несмотря на то, что он происходит первым) всегда относится к родительскому объекту и на самом деле не влияет на точки геометрии по отношению к пространству объектов. Прошу прощения, если это смущает; ясно, что я новичок в этом.

Важная часть кода, который производит этот эффект, ниже. Пожалуйста, имейте в виду, что ориентация изображения отличается от того, что производит этот код; изображение является просто примером, чтобы четко показать эффект.

var objectContainer = new THREE.Object3D();

var tubeRadius = 100;
var tubeGeometry = new THREE.CylinderGeometry(tubeRadius, tubeRadius, tubeRadius * 3, 36, 1, false);
var tube = new THREE.Mesh(tubeGeomtry, material);
scene.add( tube );

var boxes = new THREE.Object3D();
var boxEdge = 50;
var boxGeometry = new THREE.CubeGeometry(boxEdge, boxEdge, boxEdge);
var box1 = new THREE.Mesh( boxGeometry, material );
box1.translateX(tubeRadius + boxEdge / 2 + 5);
box1.translateY(boxEdge / 2);
box1.rotation = new THREE.Vector3(0, 2*Math.PI/3*0, 0);
boxes.add(box1);
var box2 = box1.clone();
box2.rotation = new THREE.Vector3(0, 2*Math.PI/3*1, 0);
boxes.add(box2);
var box3 = box1.clone();
box3.rotation = new THREE.Vector3(0, 2*Math.PI/3*2, 0);
boxes.add(box3);
scene.add( boxes );

Единственное решение, о котором я могу думать, это обернуть каждую коробку в другое пространство объекта и повернуть вокруг нее, но это кажется чрезмерной работой. Каков предпочтительный метод для достижения результата, который я ищу?

4b9b3361

Ответ 1

Существует несколько способов сделать то, что вы хотите, но я думаю, что самый простой способ:

// parent
parent = new THREE.Object3D();
scene.add( parent );

// pivots
var pivot1 = new THREE.Object3D();
var pivot2 = new THREE.Object3D();
var pivot3 = new THREE.Object3D();

pivot1.rotation.z = 0;
pivot2.rotation.z = 2 * Math.PI / 3;
pivot3.rotation.z = 4 * Math.PI / 3;

parent.add( pivot1 );
parent.add( pivot2 );
parent.add( pivot3 );

// mesh
var mesh1 = new THREE.Mesh( geometry, material );
var mesh2 = new THREE.Mesh( geometry, material );
var mesh3 = new THREE.Mesh( geometry, material );

mesh1.position.y = 5;
mesh2.position.y = 5;
mesh3.position.y = 5;

pivot1.add( mesh1 );
pivot2.add( mesh2 );
pivot3.add( mesh3 );

Затем в вашем цикле рендеринга:

parent.rotation.z += 0.01;

EDIT: обновленная скрипта: http://jsfiddle.net/hbt9c/317/

three.js r.70

Ответ 2

Создание составного объекта, центром которого будет точка, вокруг которой вращаются внутренние объекты, является одним очевидным ответом и будет очень быстро писать. Просто создайте Object3D и добавьте в него свой блок.

Аналогичный подход охватывает этот вопрос. Он сдвигает точку вершин для объекта, поэтому он имеет эффективный центр.

Кроме того, вы можете обходиться с помощью матриц вручную. Попробуйте следующее:

var boxGeometry = new THREE.CubeGeometry(boxEdge, boxEdge, boxEdge);
var mr = new THREE.Matrix4();
var mt = new THREE.Matrix4();
mt.setPosition(new THREE.Vector3(0,tubeRadius,0));
var box1 = new THREE.Mesh( boxGeometry, material );
box1.applyMatrix(mt);
var box2 = box1.clone();
mr.makeRotationZ(2 * Math.PI /3);
box2.applyMatrix(mr);
boxes.add(box2);
var box3 = box1.clone();
mr.makeRotationZ(4 * Math.PI /3);
box3.applyMatrix(mr);
boxes.add(box3);
boxes.add(box1);
scene.add( boxes );