2012-06-16 18 views
31

मुझे तीन.js में रोटेशन के बारे में एक बड़ी समस्या है, मैं अपने 3 डी घन को अपने गेम में घुमाने के लिए चाहता हूं।axis three.js पर 3D ऑब्जेक्ट को घुमाने के लिए कैसे?

//init 
geometry = new THREE.CubeGeometry grid, grid, grid 
material = new THREE.MeshLambertMaterial {color:0xFFFFFF * Math.random(), shading:THREE.FlatShading, overdraw:true, transparent: true, opacity:0.8} 
for i in [[email protected]] 
    othergeo = new THREE.Mesh new THREE.CubeGeometry(grid, grid, grid) 
    othergeo.position.x = grid * @shape[i][0] 
    othergeo.position.y = grid * @shape[i][1] 
    THREE.GeometryUtils.merge geometry, othergeo 
@mesh = new THREE.Mesh geometry, material 

//rotate 
@mesh.rotation.y += y * Math.PI/180 
@mesh.rotation.x += x * Math.PI/180 
@mesh.rotation.z += z * Math.PI/180 

और (एक्स, वाई, जेड) (1, 0, 0)

तो घन बारी बारी से कर सकते हैं हो सकता है, लेकिन समस्या यह है घन है अपनी ही धुरी पर बारी बारी से, इसलिए बाद यह है घुमाया गया, यह उम्मीद के रूप में घूम नहीं सकता है।

मुझे पृष्ठ How to rotate a Three.js Vector3 around an axis? मिल गया है, लेकिन यह सिर्फ विश्व अक्ष के चारों ओर एक वेक्टर 3 बिंदु घुमाने देता है? कि क्या मैं एक गलत तरीका में इसका इस्तेमाल किया या वहाँ अन्य तरीके हैं नहीं

और मैं के रूप में

@mesh.matrixRotationWorld.x += x * Math.PI/180 
@mesh.matrixRotationWorld.y += y * Math.PI/180 
@mesh.matrixRotationWorld.z += z * Math.PI/180 

matrixRotationWorld उपयोग करने के लिए कोशिश की है, लेकिन यह काम नहीं करता, मैं करता हूँ ..

तो, कैसे 3 डी घन दुनिया के धुरी के चारों ओर घूमने दें ???

+2

वह '@' नोटेशन क्या है? कॉफीस्क्रिप्ट में –

+3

'@' का अर्थ है 'यह।' जावास्क्रिप्ट में यह एक शॉर्टेंड है। – AlexJM

उत्तर

45

यहां मेरे द्वारा उपयोग किए जाने वाले दो कार्य हैं। वे मैट्रिक्स रोटेशन पर आधारित हैं। और मनमाना अक्षों के चारों ओर घुमा सकते हैं। दुनिया के अक्षों का उपयोग करके घूमने के लिए आप दूसरे फ़ंक्शन को घुमाने के लिए AroundWorldAxis() का उपयोग करना चाहेंगे।

// Rotate an object around an arbitrary axis in object space 
var rotObjectMatrix; 
function rotateAroundObjectAxis(object, axis, radians) { 
    rotObjectMatrix = new THREE.Matrix4(); 
    rotObjectMatrix.makeRotationAxis(axis.normalize(), radians); 

    // old code for Three.JS pre r54: 
    // object.matrix.multiplySelf(rotObjectMatrix);  // post-multiply 
    // new code for Three.JS r55+: 
    object.matrix.multiply(rotObjectMatrix); 

    // old code for Three.js pre r49: 
    // object.rotation.getRotationFromMatrix(object.matrix, object.scale); 
    // old code for Three.js r50-r58: 
    // object.rotation.setEulerFromRotationMatrix(object.matrix); 
    // new code for Three.js r59+: 
    object.rotation.setFromRotationMatrix(object.matrix); 
} 

var rotWorldMatrix; 
// Rotate an object around an arbitrary axis in world space  
function rotateAroundWorldAxis(object, axis, radians) { 
    rotWorldMatrix = new THREE.Matrix4(); 
    rotWorldMatrix.makeRotationAxis(axis.normalize(), radians); 

    // old code for Three.JS pre r54: 
    // rotWorldMatrix.multiply(object.matrix); 
    // new code for Three.JS r55+: 
    rotWorldMatrix.multiply(object.matrix);    // pre-multiply 

    object.matrix = rotWorldMatrix; 

    // old code for Three.js pre r49: 
    // object.rotation.getRotationFromMatrix(object.matrix, object.scale); 
    // old code for Three.js pre r59: 
    // object.rotation.setEulerFromRotationMatrix(object.matrix); 
    // code for r59+: 
    object.rotation.setFromRotationMatrix(object.matrix); 
} 

तो आप अपने anim समारोह (requestAnimFrame कॉलबैक) के भीतर इन कार्यों बुलाना चाहिए x- अक्ष पर 90 डिग्री के एक रोटेशन में जिसके परिणामस्वरूप:

var xAxis = new THREE.Vector3(1,0,0); 
rotateAroundWorldAxis(mesh, xAxis, Math.PI/180); 
+0

यह काम करता है, धन्यवाद !! –

+0

मुझे लगता है कि प्रत्येक कॉल के लिए एक नया तीन। मैट्रिक्स 4 बनाने के लिए महंगा होगा, अगर आप प्रत्येक फ्रेम एनीमेशन के लिए इसका पुन: उपयोग नहीं करेंगे? – Neil

+3

मुझे इन दो कार्यों को मिला जो किसी ने जिथब पर पोस्ट किया था। मुझे उन्हें नए फ़ंक्शन नामों का उपयोग करने और तीनjs के नवीनतम संस्करण dev संस्करण के लिए संपादित करना था। मैंने यह खुद को सोचा है। कचरा कलेक्टर हर बार वस्तुओं से छुटकारा पा जाएगा। मैंने क्रोम में मेमोरी यूज ग्राफ देखा है और यह ऊपर और नीचे जाता है जहां वस्तुओं को बनाया और नष्ट कर दिया जाता है, लेकिन एनीमेशन अब तक जो कुछ भी मैंने उपयोग किया है उसके लिए ठीक दिखता है। –

12

मैं rotateAroundWorldAxis समारोह जरूरत थी लेकिन इसके बाद के संस्करण कोड नवीनतम रिलीज (आर 52) के साथ काम नहीं करता है। ऐसा लगता है कि getRotationFromMatrix() तरह से setEulerFromRotationMatrix()

function rotateAroundWorldAxis(object, axis, radians) { 

    var rotationMatrix = new THREE.Matrix4(); 

    rotationMatrix.makeRotationAxis(axis.normalize(), radians); 
    rotationMatrix.multiplySelf(object.matrix);      // pre-multiply 
    object.matrix = rotationMatrix; 
    object.rotation.setEulerFromRotationMatrix(object.matrix); 
} 
6

शायद ज़रुरत पड़े बदल दिया गया था ... R52 में विधि (object.matrix setEulerFromRotationMatrix R55 के साथ के बजाय getRotationFromMatrix

9

कहा जाता है आप
rotationMatrix.multiplySelf बदलना होगा);
से
rotationMatrix.multiply (object.matrix);

6

Three.js R59 में, object.rotation.setEulerFromRotationMatrix(object.matrix);object.rotation.setFromRotationMatrix(object.matrix);

3js को बदल दिया गया है इतनी तेजी से बदल रहा है: डी

2

Three.js R66 में, यह मैं क्या उपयोग है (CoffeeScript संस्करण):

THREE.Object3D.prototype.rotateAroundWorldAxis = (axis, radians) -> 
    rotWorldMatrix = new THREE.Matrix4() 
    rotWorldMatrix.makeRotationAxis axis.normalize(), radians 
    rotWorldMatrix.multiply this.matrix 
    this.matrix = rotWorldMatrix 
    this.rotation.setFromRotationMatrix this.matrix 
3

कहीं आसपास इस आसान हो जाता है r59 (एक्स चारों ओर घूमने):

bb.GraphicsEngine.prototype.calcRotation = function (obj, rotationX) 
{ 
    var euler = new THREE.Euler(rotationX, 0, 0, 'XYZ'); 
    obj.position.applyEuler(euler); 
} 
44

रिलीज आर 5 9 के बाद, तीन.जेएस उन तीन कार्यों को ऑब्जेक्ट अक्ष के चारों ओर एक ऑब्जेक्ट घुमाने के लिए प्रदान करता है।

मैं ThreeJS के लिए 'ObjectControls' मॉड्यूल है कि आप एक वस्तु (या एक समूह), और नहीं दृश्य बारी बारी से करने की अनुमति देता है बनाया:

object.rotateX(angle); 
object.rotateY(angle); 
object.rotateZ(angle); 
+1

धन्यवाद। यह शीर्ष जवाब होना चाहिए, अन्य उत्तरों की मस्तिष्क या तो बहिष्कृत या अधिक अक्षम है। अच्छा काम! –

+3

यह एनीमेशन के लिए इस्तेमाल नहीं किया जाना चाहिए! [थ्री.जेएस दस्तावेज] से लिया गया (http://threejs.org/docs/index.html#Reference/Core/Geometry): 'यह आम तौर पर एक बार ऑपरेशन के रूप में किया जाता है, और लूप के दौरान ऑब्जेक्ट 3 डी का उपयोग नहीं करता है। ठेठ वास्तविक समय जाल रोटेशन के लिए घूर्णन। –

+0

@ मैथ्यूक्लिट आप सही हैं। क्या आप एनीमेशन के लिए बेहतर या कुशल समाधान दे सकते हैं? – Hetong

1

मैं इस समस्या को इस तरह से हल किया।

<script src="ObjectControls.js"></script>

उपयोग:: https://albertopiras.github.io/threeJS-object-controls/

यहाँ रेपो है: https://github.com/albertopiras/threeJS-object-controls

var controls = new THREE.ObjectControls(camera, renderer.domElement, yourMesh);

आप यहाँ यहाँ एक लाइव डेमो पा सकते हैं

पुस्तकालय को शामिल करें।

+1

लिंक आश्चर्यजनक रूप से तेजी से मर जाते हैं, जो इस उत्तर को कम उपयोगी बना देगा। क्या आप समाधान के प्रासंगिक हिस्सों को उत्तर के शरीर में पाठ या कोड में आसवित कर सकते हैं? – jdv