动画行星围绕它 parent 独立于 parent 的旋转状态
Animating planet orbiting it's parent idependent on parent's rotation state
我正在尝试学习 Three.js,对这些技术不熟悉。我实现了一个太阳,行星绕着行星运行,月亮绕着行星运行。我关心的是,做我目前所做的事情我必须做很多 objects 并在渲染循环中执行很多计算。
1。源代码:
WestLangley 以更多 easy-to-understand 的方式为我们提供了 fiddle 的问题:
- this fiddle 呈现的更像是现在的样子 - 行星的 parent 在太阳内部,旋转 parent 将使行星绕轨道运行。但是除了每个 planet/moon 一个额外的 object 之外,还有一个问题是 parent 旋转也会在
updateMatrixWorld
Object3D 方法期间旋转行星。因此它的旋转速度比您通过查看 mesh2.rotateOnAxis( AXIS, 0.01 );
位所假设的要快一些。
- this fiddle 显示了一种 parent-less 方法。案例是,我正在尝试找到一种方法,我可以在系统启动时配置行星 positions/spins-speed/orbit-speed,而不是仅仅为它提供服务器时间,这样会让处于同一位置的玩家之间感觉同步。
3。问题本身
就我浏览手册而言,我发现有可能使用 Three.js 矩阵逻辑来执行此类动画。我愿意尽可能减少 object 中 ::animate()
的使用(可能通过覆盖 updateMatrix
和 updateMatrixWorld
方法)。不幸的是,我的英语和数学都不够好,无法理解这些矩阵是怎么回事。如果有人能帮助我,我将不胜感激。
4。目前工作进度
工作 fiddle 是 here。我能够创造一个星球并且几乎拥有我想要的一切。剩下的一个问题是,a 想以 random-looking 度以上的行星轨道运行。
分叉这一点。我愿意减少我的太阳系中的对象数量,隐藏动画循环中的计算并使其尽可能可配置。
为此,我实现了名为 Planet
:
的自定义 Mesh
var Planet = function ( geometry, material ) {
THREE.Mesh.call( this, geometry, material );
this.type = 'Planet';
};
Planet.prototype = Object.create( THREE.Mesh.prototype );
并覆盖标准 Object3D
矩阵计算函数:
Planet.prototype._matrixUpdate = THREE.Object3D.prototype.updateMatrix;
Planet.prototype._updateMatrixWorld = THREE.Object3D.prototype.updateMatrixWorld;
Planet.prototype.updateMatrix = function() {};
Planet.prototype.updateMatrixWorld = function() {};
多亏了我可以重新计算 planets/moons 在标准方法中创建的 planets/moons 的位置和旋转 运行 每次渲染调用。
为了良好的开端,我在 Planet 构造函数中制作了一些我需要的基本参数的原型:
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
这些应该可以在创建时配置,但现在硬编码没问题。
比进入新的 updateMatrix()
,计算当前行星相对于其父行星的位置:
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
};
最后但并非最不重要的一点 - 通过 updateMatrixWorld
实施向 Object3D.worldMatrix
提供这些更改:
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.
工作代码在 this fiddle 中。通过这种方式,我减少了渲染循环期间的数学时间,减少了嵌套代码,最后:减少了高达 50% 的对象数量。但我对这个答案不是 100% 有信心,因此欢迎任何进一步的优化。
我正在尝试学习 Three.js,对这些技术不熟悉。我实现了一个太阳,行星绕着行星运行,月亮绕着行星运行。我关心的是,做我目前所做的事情我必须做很多 objects 并在渲染循环中执行很多计算。
1。源代码:
WestLangley 以更多 easy-to-understand 的方式为我们提供了 fiddle 的问题:
- this fiddle 呈现的更像是现在的样子 - 行星的 parent 在太阳内部,旋转 parent 将使行星绕轨道运行。但是除了每个 planet/moon 一个额外的 object 之外,还有一个问题是 parent 旋转也会在
updateMatrixWorld
Object3D 方法期间旋转行星。因此它的旋转速度比您通过查看mesh2.rotateOnAxis( AXIS, 0.01 );
位所假设的要快一些。 - this fiddle 显示了一种 parent-less 方法。案例是,我正在尝试找到一种方法,我可以在系统启动时配置行星 positions/spins-speed/orbit-speed,而不是仅仅为它提供服务器时间,这样会让处于同一位置的玩家之间感觉同步。
3。问题本身
就我浏览手册而言,我发现有可能使用 Three.js 矩阵逻辑来执行此类动画。我愿意尽可能减少 object 中 ::animate()
的使用(可能通过覆盖 updateMatrix
和 updateMatrixWorld
方法)。不幸的是,我的英语和数学都不够好,无法理解这些矩阵是怎么回事。如果有人能帮助我,我将不胜感激。
4。目前工作进度
工作 fiddle 是 here。我能够创造一个星球并且几乎拥有我想要的一切。剩下的一个问题是,a 想以 random-looking 度以上的行星轨道运行。
分叉这一点。我愿意减少我的太阳系中的对象数量,隐藏动画循环中的计算并使其尽可能可配置。
为此,我实现了名为 Planet
:
Mesh
var Planet = function ( geometry, material ) {
THREE.Mesh.call( this, geometry, material );
this.type = 'Planet';
};
Planet.prototype = Object.create( THREE.Mesh.prototype );
并覆盖标准 Object3D
矩阵计算函数:
Planet.prototype._matrixUpdate = THREE.Object3D.prototype.updateMatrix;
Planet.prototype._updateMatrixWorld = THREE.Object3D.prototype.updateMatrixWorld;
Planet.prototype.updateMatrix = function() {};
Planet.prototype.updateMatrixWorld = function() {};
多亏了我可以重新计算 planets/moons 在标准方法中创建的 planets/moons 的位置和旋转 运行 每次渲染调用。
为了良好的开端,我在 Planet 构造函数中制作了一些我需要的基本参数的原型:
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
这些应该可以在创建时配置,但现在硬编码没问题。
比进入新的 updateMatrix()
,计算当前行星相对于其父行星的位置:
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
};
最后但并非最不重要的一点 - 通过 updateMatrixWorld
实施向 Object3D.worldMatrix
提供这些更改:
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.
工作代码在 this fiddle 中。通过这种方式,我减少了渲染循环期间的数学时间,减少了嵌套代码,最后:减少了高达 50% 的对象数量。但我对这个答案不是 100% 有信心,因此欢迎任何进一步的优化。