动画行星绕其父母的旋转状态进行轨道运动 [英] Animating planet orbiting it's parent idependent on parent's rotation state

查看:132
本文介绍了动画行星绕其父母的旋转状态进行轨道运动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在努力学习Three.js,对这些技术不熟悉。我实现了一个绕行星绕行的太阳,月亮环绕着行星。我关心的是,到目前为止,我必须做很多对象并在渲染循环中执行大量计算。

I'm trying to learn Three.js, beeing new to those technologies. I achieved a sun with planet orbitting around, with moon orbitting around planet. What am I concerned of, is to do what i have so far i have to make quite a lot of objects and perform quite a lot of calculations during rendering loops.

WestLangley 为我们提供了更多问题的小提示易于理解的方式:

WestLangley provided us with fiddles presenting problem in more easy-to-understand way so:


  • 这个小提琴呈现的更像它现在正在寻找 - 行星的父母在太阳内,旋转那个父母将使行星轨道。但是每个行星/月球还有一个额外的物体,在 updateMatrixWorld Object3D方法期间,父旋转也会将行星旋转到位。因此,通过查看 mesh2.rotateOnAxis(AXIS,0.01); 位,它会比你想象的更快一点。

  • < a href =http://jsfiddle.net/t83pzoj2/4/ =nofollow noreferrer>这个小提琴显示了一个无父母的方法。案例是,我正试图找到方法,我可以在系统启动时配置行星位置/旋转速度/轨道速度,而不仅仅是服务器时间,因此它会让玩家在同一位置感觉同步。

  • this fiddle presents more like it is looking right now - planet has its parent inside sun, and rotating that parent will make planet orbit. But along with one extra object per planet/moon, theres an issue that parent rotation spins planet in place too, during to updateMatrixWorld Object3D method. So it will spin a bit faster than you may assume by looking at mesh2.rotateOnAxis( AXIS, 0.01 ); bit.
  • this fiddle shows one parent-less approach. Case is, I'm trying to find way, where I can configure planet positions/spins-speed/orbit-speed at system start and than just feed it with server time, so it will make it feel synchronised between players being at same location.

据我浏览手册,我发现可能有可能使用Three.js矩阵逻辑执行此类动画。我愿意尽可能减少对象内部 :: animate()的使用(可能通过覆盖 updateMatrix updateMatrixWorld 方法)。不幸的是,我的英语和数学都不够理解,有什么方法可以解决这些矩阵问题。如果有人可以帮助我,我会非常感激。

As far as I travelled through manuals, I found there may be a possibility of performing such animation using Three.js matrix logic. I'm willing to reduce usage of ::animate() inside objects as far as possible (maybe by overriding updateMatrix and updateMatrixWorld methods). Unfortunately my english nor math are not good enough to understand, whats going around with those matrixes. If somebody can help me, I would really appreciate this.

工作小提琴是这里。我能够创造一个星球并且几乎拥有我想要的一切。剩下的一个问题就是,想要以更随机的度数运行行星。

Working fiddle is here. I was able to create a Planet and have almost all I want. One left issue is that, a would like to planet orbit at more random-looking degrees.

推荐答案

将这一点分开。我愿意减少太阳系中的物体数量,隐藏动画循环中的计算,并使其尽可能配置。

Forked this bit around. I was willing to reduce object count in my solar system, hide calculations from animation loop nad make it as configurable as possible.

为此,我实现了自定义 Mesh 名为 Planet

To make this I implemented custom Mesh called Planet:

var Planet =  function ( geometry, material ) {
    THREE.Mesh.call( this, geometry, material );
    this.type = 'Planet';
};
Planet.prototype = Object.create( THREE.Mesh.prototype );

并覆盖标准 Object3D 矩阵计算函数:

and overriden standard Object3D matrix-calculation functions:

Planet.prototype._matrixUpdate = THREE.Object3D.prototype.updateMatrix;
Planet.prototype._updateMatrixWorld = THREE.Object3D.prototype.updateMatrixWorld;
Planet.prototype.updateMatrix = function() {};
Planet.prototype.updateMatrixWorld = function() {};

由于这个原因,我可以重新计算标准方法中在该基础上创建的行星/卫星的位置和旋转每次渲染调用都会运行。

Thanks to that I can recalculate positions and rotations of planets/moons created on that base inside standard methods been running every render call.

为了好的开始,我在Planet构造函数中构建了一些我需要的基本参数原型:

For good start I've prototyped in Planet constructor some basic arguments I will need:

    this.rotationAxis = new THREE.Vector3( 0, 1, 0 ).normalize(); // always rotate on Y
    this.rotationSpeed = Math.PI/2; // length of planet day

    this.orbitAxis = new THREE.Vector3( 0, 0.1, 1 ).normalize(); // y,z for orbit AXIS
    this.orbitSpeed = Math.PI / 8; // length of planet year

这些应该可以在创建时配置,但是现在硬编码还可以。

those should be configurable on creation time, but for now hardcode is ok.

比进入新的 updateMatrix(),计算与其父母相关的当前行星位置:

Than going into new updateMatrix(), to calculate current planet position in relation of it's parent:

Planet.prototype.updateMatrix = function() {

    var dta = delta || 0; // THREE.Clock::getDelta

    // just for now, sun is not orbiting around
    // anything, so checking instance
    if ( this.parent instanceof Planet ) {
        // rotate position in relation to parent, to make planet orbit
        this.position.applyAxisAngle(this.orbitAxis, this.orbitSpeed * dta);
    }

    // rotate planet in place, to make it spin
    this.rotateOnAxis(this.rotationAxis, this.rotationSpeed * dta);

    this._matrixUpdate(); // fabricating Object3D.matrix
};

最后,但并非最不重要 - 将这些更改提供给 Object3D.worldMatrix via updateMatrixWorld implementation:

And last, but not least - providing those changes to Object3D.worldMatrix via updateMatrixWorld implementation:

Planet.prototype.updateMatrixWorld = function() {
    if ( this.matrixAutoUpdate === true ) this.updateMatrix();

    if ( this.matrixWorldNeedsUpdate === true || force === true ) {

        if ( this.parent === undefined ) {
            this.matrixWorld.copy( this.matrix );
        } else {
            // THIS else block is all whats different
            // between Planet and standard Object3Dmethod
            v = new THREE.Vector3(); // empty vector
            v.applyMatrix4(this.parent.matrixWorld); // setup with parent position
            v.add(this.position); // add local position

            // compose instead of multiplication
            this.matrixWorld.compose(v, this.quaternion, this.scale); 

        }
   // ... rest like in THREE's (71) git.

工作代码位于这个小提琴。这样我在渲染循环期间减少了数学时间,减少了嵌套代码,最后:减少了最多50%的对象数量。但我对这个答案并不是100%有信心,所以任何进一步的优化都会受到赞赏。

Working code is in this fiddle. This way I have reduced math-time during render loop, reduced nested code and finally: reduced objects count by up to 50%. But I'm am not 100% confident about that answer, so any further optimisations are appreciated.

这篇关于动画行星绕其父母的旋转状态进行轨道运动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆