three.js - Rotation after a Rotation not acting how I Expect -


i have rubiks-cube-like puzzle trying model in webgl using three.js:

enter image description here

each of two-color centers can rotate. when rotate, bring of pieces around them along on rotation. example, if rotate orange-blue center, happens:

rotating around orange-blue center

when complete rotation, lines up:

enter image description here

however, when try rotate orange-white center, strange behavior 2 pieces inherited orange-blue center after first rotation:

enter image description here

i expect them rotate other pieces, instead rotate differently.

i using three.js's object3d.rotateonaxis() function rotations:

function rotate ( center, distance ) {     var axis = center.axis;     center.model.rotateonaxis ( axis, distance );     ( var in center.stickers ) {         center.stickers[i].rotateonaxis ( axis, distance  );     }      ( var in center.children ) {         center.children[i].model.rotateonaxis ( axis, distance );          //note: stickers colored faces         ( var s in center.children[i].stickers ) {             center.children[i].stickers[s].rotateonaxis ( axis, distance );         }     } } 

here key-press code looks like:

function showcube() {     //set stuff up, then...      count = 0;     parent.onkeypress = function(event) {          if ( count < 6 ) {             rotate( blocks.centers [ "bo" ],  math.pi / 6 );              count++;              if ( count == 6 ) {                 moveface ( blocks, "o1", "oy", "bw" );                 moveface ( blocks, "o2", "ow", "by" );                  moveface ( blocks, "b1", "bw", "oy" );                 moveface ( blocks, "b2", "by", "ow" );                  movecorner ( blocks, "bow", "ow", "oy" );                 movecorner ( blocks, "bow", "bw", "by" );                  movecorner ( blocks, "boy", "oy", "ow" );                 movecorner ( blocks, "boy", "by", "bw" );             }          } else {              rotate( blocks.centers [ "ow" ],  math.pi / 6 );         }     } }  function moveface ( blocks, child, oldparent, newparent ) {     var index = blocks.centers [ oldparent ].children.indexof ( blocks.faces [ child ] );     blocks.centers [ oldparent ].children.splice ( index, 1 );     blocks.centers [ newparent ].children.push ( blocks.faces [ child ] ); }  function movecorner ( blocks, child, oldparent, newparent ) {     var index = blocks.centers [ oldparent ].children.indexof ( blocks.corners [ child ] );     blocks.centers [ oldparent ].children.splice ( index, 1 );     blocks.centers [ newparent ].children.push ( blocks.corners [ child ] ); } 

interestingly, blue-orange-yellow corner rotate correctly, need rotation around difference between bo vector , ow vector.

that say:

  • blue-orange axis normalized vector of: (0, 1, 1)
  • orange-white axis normalized vector of: (1, 0, 1)
  • after first rotation complete, if try rotate boy corner around normal of (1, 0, 1), behavior shown in pictures.
  • however, if try rotate around (0, 1, 1) - (1, 0, 1), i.e. (-1, 1, 0), desired behavior.

i don't understand what's happening. can me update rotate function behavior want, without having keep long list of past rotations piece has experienced?

i suspect after first rotation, need tell piece "zero" rotation state without causing motion, i'm not quite sure how that, or if it's right approach.

you can play thing here: http://joshuad.net/clover-cube/so-question/

thanks!

i fixed changing rotate method this:

function rotate ( center, distance ) {     var axis = center.axis;     center.model.rotateonaxis ( axis, distance );     applystatestomatrixdirectly ( center.model );      ( var stickerindex in center.stickers ) {         center.stickers[stickerindex].rotateonaxis ( axis, distance  );         applystatestomatrixdirectly ( center.stickers[stickerindex] );     }      ( var childindex in center.children ) {         center.children[childindex].model.rotateonaxis ( axis, distance );         applystatestomatrixdirectly ( center.children[childindex].model );          ( var childstickerindex in center.children[childindex].stickers ) {             center.children[childindex].stickers[childstickerindex].rotateonaxis ( axis, distance );             applystatestomatrixdirectly ( center.children[childindex].stickers[childstickerindex] );         }     } }  function applystatestomatrixdirectly ( model ) {     model.updatematrix();     model.geometry.applymatrix( model.matrix );     model.position.set( 0, 0, 0 );     model.rotation.set( 0, 0, 0 );     model.scale.set( 1, 1, 1 )     model.updatematrix(); } 

the idea function applystatestomatrixdirectly() applies rotation directly model matrix , reset of rotation data (as else). allows model "forget" has been rotated, allowing new rotateonaxis work.


Comments

Popular posts from this blog

c# - How Configure Devart dotConnect for SQLite Code First? -

c++ - Clear the memory after returning a vector in a function -

erlang - Saving a digraph to mnesia is hindered because of its side-effects -