2015-04-20 3 views
1

J'essaie d'apprendre Three.js, en étant nouveau à ces technologies. J'ai réalisé un soleil avec la planète en orbite, avec la lune en orbite autour de la planète. Ce qui me préoccupe, c'est de faire ce que j'ai jusqu'ici, je dois faire beaucoup d'objets et effectuer pas mal de calculs pendant le rendu des boucles.Planète animée en orbite autour de son parent indépendant sur l'état de rotation du parent

1.: codes sources

WestLangley nous a fourni tripote présentant problème plus facile à comprendre la manière si:

  • this fiddle présente plus comme il est à la recherche en ce moment - la planète a son parent à l'intérieur soleil, et la rotation de ce parent fera l'orbite de la planète. Mais avec un objet supplémentaire par planète/lune, theres un problème que la rotation parent tourne la planète en place aussi, pendant updateMatrixWorld la méthode Object3D. Donc, il va tourner un peu plus vite que vous pouvez supposer en regardant mesh2.rotateOnAxis(AXIS, 0.01); bit.
  • this fiddle montre une approche sans parent. Le cas est, j'essaie de trouver moyen, où je peux configurer les positions de la planète/tours-vitesse/orbit-vitesse au démarrage du système et de simplement le nourrir avec l'heure du serveur, de sorte qu'il se sent synchronisé entre les joueurs au même endroit .

3. Question se

Pour autant que je voyageais à travers les manuels, je trouve qu'il peut y avoir une possibilité d'effectuer une telle animation en utilisant la logique de la matrice Three.js. Je suis prêt à réduire l'utilisation de ::animate() objets intérieurs autant que possible (peut-être en remplaçant les méthodes updateMatrix et updateMatrixWorld). Malheureusement, mon anglais et mes maths ne sont pas assez bons pour comprendre, ce qui se passe avec ces matrices. Si quelqu'un peut m'aider, j'apprécierais vraiment ceci.

4. Les travaux actuels progrès

violon de travail est here. J'ai été capable de créer une planète et j'ai presque tout ce que je veux. Un problème de gauche est que, aimerait planer en orbite autour de degrés plus aléatoires.

+0

[Ce violon] (http://jsfiddle.net/t83pzoj2/) montre comment trois.js est destiné à être utilisé. Voir [ce post] (http://stackoverflow.com/questions/11966779/learning-webgl-and-three-js/11970687#11970687) pour certaines ressources mathématiques. – WestLangley

+0

@WestLangley cela ressemble exactement à ce que j'ai en ce moment. Le problème est que la rotation du pivot le long de la position changeante du maillage2 change sa rotation locale en conséquence de 'updateWorldMatrix' Je suis disposé à contrôler sa vitesse de rotation séparément et à éviter d'utiliser des éléments Object3D vides comme parents. Est-ce au moins possible? – yergo

+0

Est-ce ce que vous voulez dire - sans pivots? http://jsfiddle.net/t83pzoj2/4/ – WestLangley

Répondre

2

Fourchez ce peu autour. J'étais prêt à réduire le nombre d'objets dans mon système solaire, cacher les calculs de la boucle d'animation et le rendre aussi configurable que possible.

Pour faire cela, je mis en œuvre personnalisée Mesh appelé Planet:

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

et outrepassée fonctions standard de calcul de matrice Object3D:

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

Merci que je peux recalculer les positions et les rotations des planètes/lunes créé sur cette base à l'intérieur des méthodes standard exécutaient chaque appel de rendu.

Pour un bon départ, j'ai prototypé dans le constructeur Planète des arguments de base je besoin:

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 

ceux-ci devraient être configurable à l'heure de création, mais pour l'instant hardcode est ok.

que d'entrer dans une nouvelle updateMatrix(), pour calculer la position de la planète actuelle par rapport avec son 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 
}; 

Et enfin, mais non le moindre - la fourniture de ces changements à Object3D.worldMatrix via updateMatrixWorld mise en œuvre:

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. 

Le code de travail est en this fiddle. De cette façon j'ai réduit le temps mathématique pendant la boucle de rendu, le code imbriqué réduit et enfin: les objets réduits comptent jusqu'à 50%. Mais je ne suis pas sûr à 100% de cette réponse, donc d'autres optimisations sont appréciées.

+0

Merci pour le violon. A beaucoup aidé. –