three.js - Rotation after a Rotation not acting how I Expect -
i have rubiks-cube-like puzzle trying model in webgl using three.js:
each of two-color centers can rotate. when rotate, bring of pieces around them along on rotation. example, if rotate orange-blue center, happens:
when complete rotation, lines up:
however, when try rotate orange-white center, strange behavior 2 pieces inherited orange-blue center after first rotation:
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
Post a Comment