17 package com.generalrobotix.ui.view.tdview;
21 import java.awt.event.*;
22 import javax.media.j3d.*;
23 import javax.vecmath.*;
28 import com.sun.j3d.utils.picking.*;
30 class InvKinemaHandler
extends OperationHandler {
33 public static final int FROM_MODE = 1;
34 public static final int ROTATION_MODE = 2;
35 public static final int TRANSLATION_MODE = 3;
37 public static final int UNKNOWN = 0;
38 public static final int ROTATION_WITH_X = 1;
39 public static final int ROTATION_WITH_Y = 2;
40 public static final int ROTATION_WITH_Z = 4;
41 public static final int AXIS_FLAGS = 7;
42 public static final int MINUS = 8;
44 public static final int XY_TRANSLATION = 1;
45 public static final int YZ_TRANSLATION = 2;
46 public static final int ZX_TRANSLATION = 4;
48 private static final float ROTATION_FACTOR = (float)Math.PI / 360.0f;
49 private static final float ROTATION_LIMIT = (
float)Math.PI / 360.0f;
50 private static final float TRANSLATION_FACTOR = 0.001f;
51 private static final float TRANSLATION_LIMIT = 0.003f;
55 protected int rotationMode_ = UNKNOWN;
56 protected int translationMode_ = UNKNOWN;
61 protected Vector3f v3fAnotherAxis =
new Vector3f();
62 protected Vector3f v3fAxisRotate =
new Vector3f();
70 protected Vector2f v2fDetermine;
73 protected Vector3f v3fAxisFirst =
new Vector3f();
75 protected Vector3f v3fAxisSecond =
new Vector3f();
80 protected Point3f point000 =
new Point3f(0,0,0);
82 private Vector3f normal_;
83 private Point3f intersect_;
85 private Switch bbSwitchFrom_;
86 private Switch bbSwitchTo_;
90 private TransformGroup tgTarget_;
93 private Point startPoint_ =
new Point();
94 private Point point_ =
new Point();
96 private InvKinemaResolver resolver_;
98 private boolean isPicked_;
102 public void setInvKinemaMode(
int mode) {
106 public void setInvKinemaResolver(InvKinemaResolver resolver) {
107 resolver_ = resolver;
112 public void processPicking(MouseEvent evt, BehaviorInfo
info) {
113 startPoint_.x = evt.getPoint().x;
114 startPoint_.y = evt.getPoint().y;
121 info.pickCanvas.setShapeLocation(startPoint_.x, startPoint_.y);
122 PickResult pickResult[] = info.pickCanvas.pickAllSorted();
123 if (pickResult ==
null) {
126 TransformGroup tg = (TransformGroup)pickResult[0].getNode(PickResult.TRANSFORM_GROUP);
127 Point3d startPoint = info.pickCanvas.getStartPosition();
128 PickIntersection
intersection = pickResult[0].getClosestIntersection(startPoint);
129 GrxModelItem model = SceneGraphModifier.getModelFromTG(tg);
133 if(info.manager_.focusedItem()==model){
134 if( pickResult.length > 1){
135 tg = (TransformGroup)pickResult[1].getNode(PickResult.TRANSFORM_GROUP );
136 intersection = pickResult[1].getClosestIntersection(startPoint);
137 info.manager_.focusedItem(
null);
143 intersect_ =
new Point3f(intersection.getPointCoordinates());
144 normal_ =
new Vector3f(intersection.getPointNormal());
145 if (_setInvKinema(tg, info)) {
156 public void processStartDrag(MouseEvent evt, BehaviorInfo info) {
162 _decideRotationAxis(evt, info);
163 limit_ = ROTATION_LIMIT;
165 case TRANSLATION_MODE:
166 _decideTranslationAxis(evt, info);
167 limit_ = TRANSLATION_LIMIT;
176 public void processDragOperation(MouseEvent evt, BehaviorInfo info) {
182 case TRANSLATION_MODE:
183 point_.x = evt.getPoint().x;
184 point_.y = evt.getPoint().y;
193 public void processReleased(MouseEvent evt, BehaviorInfo info) {
199 public boolean processTimerOperation(BehaviorInfo info) {
206 case TRANSLATION_MODE:
212 ((Grx3DView)info.drawable).showOption();
218 public void disableHandler() {
219 _disableBoundingBox();
222 public void setPickTarget(TransformGroup tg, BehaviorInfo info) {
225 _disableBoundingBox();
226 _enableBoundingBoxFrom(tg);
229 case TRANSLATION_MODE:
230 if (bbSwitchFrom_ ==
null) {
234 if (tgTarget_ != tg) {
235 _enableBoundingBoxTo(tg);
243 private void _disableBoundingBox() {
244 if (bbSwitchFrom_ !=
null) {
245 bbSwitchFrom_.setWhichChild(Switch.CHILD_NONE);
248 if (bbSwitchTo_ !=
null) {
249 bbSwitchTo_.setWhichChild(Switch.CHILD_NONE);
253 bbSwitchFrom_ =
null;
257 private boolean _setInvKinema(TransformGroup tg, BehaviorInfo info) {
260 _disableBoundingBox();
261 if (!_enableBoundingBoxFrom(tg)) {
266 if (bbSwitchFrom_ ==
null) {
270 if (tgTarget_ != tg) {
271 if (!_enableBoundingBoxTo(tg)) {
277 case TRANSLATION_MODE:
278 if (bbSwitchFrom_ ==
null) {
282 if (tgTarget_ != tg) {
283 if (!_enableBoundingBoxTo(tg)) {
287 _setTranslationMode();
295 private boolean _enableBoundingBoxFrom(TransformGroup tg) {
296 GrxModelItem model = SceneGraphModifier.getModelFromTG(tg);
301 GrxLinkItem link = SceneGraphModifier.getLinkFromTG(tg);
306 resolver_.setFromJoint(model, link);
307 bbSwitchFrom_ = link.getBBSwitch();
308 bbSwitchFrom_.setWhichChild(Switch.CHILD_ALL);
312 private boolean _enableBoundingBoxTo(TransformGroup tg) {
313 if (bbSwitchTo_ !=
null) {
314 bbSwitchTo_.setWhichChild(Switch.CHILD_NONE);
316 GrxLinkItem link = SceneGraphModifier.getLinkFromTG(tg);
317 GrxModelItem model = SceneGraphModifier.getModelFromTG(tg);
318 bbSwitchTo_ = link.getBBSwitch();
320 if (bbSwitchFrom_ == bbSwitchTo_) {
324 if (bbSwitchTo_ !=
null && resolver_.setToJoint(model, link)) {
325 bbSwitchTo_.setWhichChild(Switch.CHILD_ALL);
333 private void _setRotationMode() {
334 if (Math.abs(normal_.x) == 1.0f) {
335 rotationMode_ = ROTATION_WITH_X;
336 }
else if(Math.abs(normal_.y) == 1.0f) {
337 rotationMode_ = ROTATION_WITH_Y;
338 }
else if(Math.abs(normal_.z) == 1.0f) {
339 rotationMode_ = ROTATION_WITH_Z;
343 private void _setTranslationMode() {
344 if (Math.abs(normal_.x) == 1.0f) {
345 translationMode_ = YZ_TRANSLATION;
346 }
else if(Math.abs(normal_.y) == 1.0f) {
347 translationMode_ = ZX_TRANSLATION;
348 }
else if (Math.abs(normal_.z) == 1.0f) {
349 translationMode_ = XY_TRANSLATION;
353 private void _decideTranslationAxis(MouseEvent evt, BehaviorInfo info) {
355 switch(translationMode_) {
357 v3fAxisFirst.set(1.0
f,0.0
f,0.0
f);
358 v3fAxisSecond.set(0.0
f,1.0
f,0.0
f);
361 v3fAxisFirst.set(0.0
f,1.0
f,0.0
f);
362 v3fAxisSecond.set(0.0
f,0.0
f,1.0
f);
365 v3fAxisFirst.set(0.0
f,0.0
f,1.0
f);
366 v3fAxisSecond.set(1.0
f,0.0
f,0.0
f);
371 Transform3D t3dLocalToVworld =
new Transform3D();
372 Transform3D t3dCurrent =
new Transform3D();
373 Transform3D t3dWorld =
new Transform3D();
374 Transform3D t3dView =
new Transform3D();
376 tgTarget_.getLocalToVworld(t3dLocalToVworld);
377 tgTarget_.getTransform(t3dCurrent);
382 t3dLocalToVworld.mul(t3dCurrent);
383 t3dWorld.set(t3dLocalToVworld);
385 TransformGroup tgView = info.drawable.getTransformGroupRoot();
386 tgView.getLocalToVworld(t3dLocalToVworld);
387 tgView.getTransform(t3dCurrent);
390 t3dLocalToVworld.mul(t3dCurrent);
391 t3dView.set(t3dLocalToVworld);
394 t3dView.mul(t3dWorld);
395 t3dView.transform(v3fAxisFirst);
396 t3dView.transform(v3fAxisSecond);
398 point000.set(0
f,0
f,0
f);
399 t3dView.transform(point000);
400 if (intersect_ !=
null) {
401 Point3f pointPicked =
new Point3f(intersect_);
402 t3dView.transform(pointPicked);
405 info.setTimerEnabled(
true);
408 private void _decideRotationAxis(MouseEvent evt, BehaviorInfo info) {
411 int dx = evt.getPoint().x - startPoint_.x;
412 int dy = evt.getPoint().y - startPoint_.y;
416 (
float)dx * ROTATION_FACTOR,
417 (
float)dy * ROTATION_FACTOR
419 Vector2f v2fMouse =
new Vector2f(pointMouse);
424 Vector3f v3fAxisFirst =
new Vector3f();
425 Vector3f v3fAxisSecond =
new Vector3f();
428 Transform3D t3dLocalToVworld =
new Transform3D();
429 Transform3D t3dCurrent =
new Transform3D();
430 Transform3D t3dWorld =
new Transform3D();
431 Transform3D t3dView =
new Transform3D();
433 tgTarget_.getLocalToVworld(t3dLocalToVworld);
434 tgTarget_.getTransform(t3dCurrent);
437 t3dLocalToVworld.mul(t3dCurrent);
438 t3dWorld.set(t3dLocalToVworld);
440 TransformGroup tgView = info.drawable.getTransformGroupRoot();
441 tgView.getLocalToVworld(t3dLocalToVworld);
442 tgView.getTransform(t3dCurrent);
443 t3dLocalToVworld.mul(t3dCurrent);
444 t3dView.set(t3dLocalToVworld);
447 t3dView.mul(t3dWorld);
449 switch(rotationMode_ & AXIS_FLAGS) {
450 case ROTATION_WITH_X:
451 v3fAxisFirst.set(0.0
f,1.0
f,0.0
f);
452 v3fAxisSecond.set(0.0
f,0.0
f,1.0
f);
454 case ROTATION_WITH_Y:
455 v3fAxisFirst.set(0.0
f,0.0
f,1.0
f);
456 v3fAxisSecond.set(1.0
f,0.0
f,0.0
f);
458 case ROTATION_WITH_Z:
459 v3fAxisFirst.set(1.0
f,0.0
f,0.0
f);
460 v3fAxisSecond.set(0.0
f,1.0
f,0.0
f);
464 t3dView.transform(v3fAxisFirst);
465 t3dView.transform(v3fAxisSecond);
468 float fDotProductFirst = 0.0f;
469 float fDotProductSecond = 0.0f;
472 Vector2f v2fAxisFirst =
new Vector2f(v3fAxisFirst.x, v3fAxisFirst.y);
473 Vector2f v2fAxisSecond =
new Vector2f(v3fAxisSecond.x, v3fAxisSecond.y);
475 v2fAxisFirst.normalize();
476 v2fAxisSecond.normalize();
478 fDotProductFirst = v2fAxisFirst.dot(v2fMouse);
479 fDotProductSecond = v2fAxisSecond.dot(v2fMouse);
482 switch(rotationMode_ & AXIS_FLAGS) {
483 case ROTATION_WITH_X:
484 if (Math.abs(fDotProductFirst) < Math.abs(fDotProductSecond)) {
485 v3fAnotherAxis = v3fAxisSecond;
486 v3fAxisRotate.set(0.0
f, 1.0
f, 0.0
f);
488 v3fAnotherAxis = v3fAxisFirst;
489 v3fAxisRotate.set(0.0
f, 0.0
f, 1.0
f);
492 case ROTATION_WITH_Y:
493 if (Math.abs(fDotProductFirst) < Math.abs(fDotProductSecond)) {
494 v3fAnotherAxis = v3fAxisSecond;
495 v3fAxisRotate.set(0.0
f, 0.0
f, 1.0
f);
497 v3fAnotherAxis = v3fAxisFirst;
498 v3fAxisRotate.set(1.0
f, 0.0
f, 0.0
f);
501 case ROTATION_WITH_Z:
502 if (Math.abs(fDotProductFirst) < Math.abs(fDotProductSecond)) {
503 v3fAnotherAxis = v3fAxisSecond;
504 v3fAxisRotate.set(1.0
f, 0.0
f, 0.0
f);
506 v3fAnotherAxis = v3fAxisFirst;
507 v3fAxisRotate.set(0.0
f, 1.0
f, 0.0
f);
512 Vector3f v3fTemp =
new Vector3f();
513 v3fTemp.set(v3fAxisRotate);
514 t3dView.transform(v3fAxisRotate);
520 Vector2f v2fAxisRotate =
new Vector2f(v3fAxisRotate.x, v3fAxisRotate.y);
525 v2fDetermine =
new Vector2f(v2fAxisRotate.y, -v2fAxisRotate.x);
527 v3fAxisRotate.set(v3fTemp);
529 v2fMouse.normalize();
532 info.setTimerEnabled(
true);
535 private void _translation(BehaviorInfo info) {
538 int dx = point_.x - startPoint_.x;
539 int dy = point_.y - startPoint_.y;
544 (
float)dx * TRANSLATION_FACTOR,
545 (
float)dy * TRANSLATION_FACTOR
547 Vector2f v2fMouse =
new Vector2f(pointMouse);
551 float fDotProductFirst = 0.0f;
552 float fDotProductSecond = 0.0f;
555 Vector2f v2fAxisFirst =
new Vector2f(v3fAxisFirst.x, v3fAxisFirst.y);
556 Vector2f v2fAxisSecond =
new Vector2f(v3fAxisSecond.x, v3fAxisSecond.y);
559 if (v2fAxisFirst.length() == 0) {
560 if (intersect_ !=
null) {
561 Point3f pointPicked =
new Point3f(intersect_);
562 pointPicked.sub(point000);
563 pointPicked.scale(-1.0
f);
564 v3fAxisFirst.set(pointPicked);
565 v2fAxisFirst.set(v3fAxisFirst.x,v3fAxisFirst.y);
568 v2fAxisFirst.set(0.0
f,1.0
f);
572 if (v2fAxisSecond.length() == 0) {
573 if (intersect_ !=
null) {
574 Point3f pointPicked =
new Point3f(intersect_);
575 pointPicked.sub(point000);
576 pointPicked.scale(-1.0
f);
577 v3fAxisSecond.set(pointPicked);
578 v2fAxisSecond.set(v3fAxisSecond.x,v3fAxisSecond.y);
581 v2fAxisSecond.set(1.0
f,0.0
f);
584 v2fAxisFirst.normalize();
585 v2fAxisSecond.normalize();
587 fDotProductFirst = v2fAxisFirst.dot(v2fMouse);
588 fDotProductSecond = v2fAxisSecond.dot(v2fMouse);
590 if (Float.isNaN(fDotProductFirst)) {
591 fDotProductFirst = 0;
594 if (Float.isNaN(fDotProductSecond)) {
595 fDotProductSecond = 0;
598 Transform3D t3dCur =
new Transform3D();
599 Transform3D t3dTranslate =
new Transform3D();
600 tgTarget_.getTransform(t3dCur);
601 Vector3f v3fTranslate =
new Vector3f();
604 if (Math.abs(fDotProductFirst) > TRANSLATION_LIMIT) {
605 if (fDotProductFirst > TRANSLATION_LIMIT) {
606 fDotProductFirst = TRANSLATION_LIMIT;
608 fDotProductFirst = -TRANSLATION_LIMIT;
611 if (Math.abs(fDotProductSecond) > TRANSLATION_LIMIT) {
612 if (fDotProductSecond > TRANSLATION_LIMIT) {
613 fDotProductSecond = TRANSLATION_LIMIT;
615 fDotProductSecond = -TRANSLATION_LIMIT;
619 switch(translationMode_) {
621 v3fTranslate.x += fDotProductFirst;
622 v3fTranslate.y += fDotProductSecond;
625 v3fTranslate.y += fDotProductFirst;
626 v3fTranslate.z += fDotProductSecond;
629 v3fTranslate.z += fDotProductFirst;
630 v3fTranslate.x += fDotProductSecond;
634 t3dTranslate.set(v3fTranslate);
635 t3dCur.mul(t3dTranslate);
636 tgTarget_.setTransform(t3dCur);
643 private void _rotation(BehaviorInfo info) {
644 int dx = point_.x - startPoint_.x;
645 int dy = point_.y - startPoint_.y;
647 Point2f pointMouse =
new Point2f(
648 (
float)dx * ROTATION_FACTOR,
649 (
float)dy * ROTATION_FACTOR
651 Vector2f v2fMouse =
new Vector2f(pointMouse);
654 float fDotProductRotate = v2fDetermine.dot(v2fMouse);
656 Transform3D t3dCur =
new Transform3D();
657 Transform3D t3dRotate =
new Transform3D();
658 tgTarget_.getTransform(t3dCur);
661 if (Math.abs(fDotProductRotate) > ROTATION_LIMIT) {
662 if (fDotProductRotate > ROTATION_LIMIT) {
663 fDotProductRotate = ROTATION_LIMIT;
666 fDotProductRotate = - ROTATION_LIMIT;
670 new AxisAngle4f(v3fAxisRotate, fDotProductRotate);
672 t3dCur.mul(t3dRotate);
673 tgTarget_.setTransform(t3dCur);
680 private void _resolve() {
681 Transform3D t3dCurrent =
new Transform3D();
682 tgTarget_.getTransform(t3dCurrent);
683 Transform3D t3dLocalToVworld =
new Transform3D();
684 tgTarget_.getLocalToVworld(t3dLocalToVworld);
685 Transform3D t3dCur =
new Transform3D();
686 tgTarget_.getTransform(t3dCur);
690 t3dLocalToVworld.mul(t3dCur);
691 t3dCurrent = t3dLocalToVworld;
693 if (resolver_.resolve(t3dCurrent)) {
696 if (mode_ == ROTATION_MODE) {
697 limit_ += (float)(Math.PI/1440);
703 if (mode_ == ROTATION_MODE) {
704 if (limit_ > (
float)Math.PI/1440) {
705 limit_ -= Math.PI/1440;
708 if (limit_ > 0.0001
f) {
int intersection(const fLineVec &lv1, const fLineVec &lv2, fVec3 &c1, fVec3 &c2, double &d, double eps)
#define null
our own NULL pointer
item corresponds to a robot model