2013-03-05 33 views
27

Tôi nghĩ rằng bức tranh này tốt nhất giải thích vấn đề của tôi:Làm cách nào để xoay một số mặt trăng quanh hành tinh với THREE.js?

hooray for optical illusions

Trước tiên tôi dịch các hộp dọc theo đường đỏ. Tiếp theo, tôi muốn hiệu ứng xoay là đường màu xanh trong a, nhưng những gì thực sự xảy ra giống với đường màu xanh trong b. Nó cảm thấy như thay đổi xoay luôn luôn liên quan đến không gian đối tượng ban đầu, nhưng bản dịch (mặc dù xảy ra trước) luôn luôn liên quan đến cha mẹ, và không thực sự ảnh hưởng đến các điểm hình học liên quan đến không gian đối tượng. Tôi xin lỗi nếu điều đó khó hiểu; rõ ràng tôi mới ở đây.

Phần quan trọng của mã tạo hiệu ứng này ở bên dưới. Xin lưu ý rằng hướng của hình ảnh khác với mã này tạo ra; hình ảnh chỉ là một ví dụ để hiển thị hiệu ứng rõ ràng.

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); 

Giải pháp duy nhất tôi có thể nghĩ là bọc mỗi hộp trong không gian đối tượng khác và xoay vòng, nhưng có vẻ như công việc quá mức. Phương pháp ưa thích để đạt được kết quả mà tôi đang tìm kiếm là gì?

+0

Tôi không biết Three.js, nhưng cách dịch nó bằng 'Math.cos (xoay) * boxEdge/2, Math.sin (xoay) * boxEdge/2' cũng như xoay vòng cục bộ? – Ryan

+0

Điều đó có nghĩa là làm việc gấp đôi, xoay và dịch từng hộp. Thực sự những gì tôi muốn làm là xoay mỗi bản sao về cùng một điểm, đó là nguồn gốc trước khi dịch. –

Trả lời

29

Có một số cách để làm những gì bạn muốn, nhưng tôi nghĩ đơn giản nhất là như vậy:

// 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); 

Sau đó, trong vòng lặp làm cho bạn:

parent.rotation.z += 0.01; 

EDIT : cập nhật fiddle: http://jsfiddle.net/hbt9c/317/

three.js r.70

+0

Cảm ơn ví dụ. Như tôi đã đề cập trong câu hỏi, đây là những gì tôi đã suy nghĩ. Đây có phải là giải pháp điển hình cho vấn đề không? Tôi có ý định phát triển điều này một thời gian và tôi chỉ muốn chắc chắn rằng tôi không tự bắn mình vào chân. –

+0

Có. Nó là điển hình. Các giải pháp khác là để có mỗi hộp là một đứa trẻ của cảnh, và tính toán mới 'vị trí' và' xoay' vector mỗi khung bằng cách sử dụng toán học. – WestLangley

5

Tạo đối tượng kết hợp có trung tâm sẽ là điểm mà đối tượng bên trong xoay là một câu trả lời rõ ràng và sẽ rất nhanh để viết. Chỉ cần tạo một Object3D và thêm hộp của bạn vào đó.

Cách tiếp cận tương tự được bao phủ bởi this question. Nó dịch chuyển điểm của các đỉnh cho một vật thể, do đó nó có một trung tâm mới.

Ngoài ra, bạn có thể gây rối với các ma trận bằng tay. Hãy thử điều này:

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); 
Các vấn đề liên quan