3. js Добавление вращения к группе вокруг оси - PullRequest
1 голос
/ 26 мая 2020

Я пытаюсь построить кубик Рубика, используя 3. js. Чтобы повернуть одну сторону, я складываю все маленькие кубики, которые нужно повернуть, в группу, а затем вращаю ее. Чтобы указать точку поворота, я использую эту функцию, которую я нашел:

//Turn Group Around Center function
        THREE.Object3D.prototype.rotateAroundWorldAxis = function () {
            // rotate object around axis in world space (the axis passes through point)
            // axis is assumed to be normalized
            // assumes object does not have a rotated parent
            var q = new THREE.Quaternion();
            return function rotateAroundWorldAxis(point, axis, angle) {
                q.setFromAxisAngle(axis, angle);
                this.applyQuaternion(q);
                this.position.sub(point);
                this.position.applyQuaternion(q);
                this.position.add(point);
                return this;
            }
        }();

Когда я использую ее для поворота группы один раз, все работает, но когда я использую ее дважды:

myGroup.rotateAroundWorldAxis(rotationPoint, zAxis, Math.PI / 2);
myGroup.rotateAroundWorldAxis(rotationPoint, zAxis, Math.PI / 2);

во втором повороте ничего не происходит.

Я думаю, это потому, что функция применяет поворот только к неперевёрнутому объекту, а не добавляет его. (вращение = 90 вместо вращения + = 90)

Мой вопрос: как я могу решить эту проблему и позволить функции запомнить предыдущие повороты?

1 Ответ

1 голос
/ 26 мая 2020

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

Если вам нужен простой пример вместо do c, я закодировал небольшой урок до трех. js (для визуализации всех параметров камеры), где я представлял небольшую солнечную систему, в которой Я вращаю вокруг Солнца разные планеты на разных орбитах.

Вы можете визуализировать это здесь , а код размещен на моем Github . Что я делаю, так это то, что в main.html я использую следующую функцию анимации для своих планет:

function animatePlanets() {
            requestAnimationFrame(animatePlanets);
            var quaternion, rotationSpeed, rotationSpeedMoon, pivotPoint, pivotPointMoon, rotationAxeMoon, subgroup, planetPosition, planet

                for ( var i = 0; i < views.length; ++ i ) {

                    var view = views[ i ];
                    var camera = view.camera;

                    for (let i=1;i<group.children.length;i++){

                        // Rotate the planet around the sun
                        pivotPoint = group.children[i]
                        planetPosition = pivotPoint.children[0].position

                        // Defining the rotation axe and speed
                        rotationAxe = (new THREE.Vector3(-planetPosition.y,planetPosition.x,0)).normalize()
                        rotationSpeed = pivotPoint.speed

                        // Applying the rotation to the planet
                        quaternion = new THREE.Quaternion().setFromAxisAngle(rotationAxe,rotationSpeed)
                        pivotPoint.applyQuaternion(quaternion)

                        // Applying local rotation to the planet if not satellites
                        if (pivotPoint.children[0].children.length == 0){
                            planet = pivotPoint.children[0]
                            quaternion =  new THREE.Quaternion().setFromAxisAngle(rotationAxe,rotationSpeed*10)
                            planet.applyQuaternion(quaternion)
                        }
                // Render the scene, using the camera specifications
                renderer.render(scene, view.camera);
                }
            }

Я надеюсь, что пример достаточно ясен, я на самом деле просто определяю точку вращения и применяю вращение в rotationSpeed каждой из планет в моей группе вокруг этой точки.
Скажите мне, если у вас есть дополнительные вопросы!

...