package org.simantics.plant3d.gizmo; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionListener; import java.util.ArrayList; import java.util.Collection; import javax.vecmath.AxisAngle4d; import javax.vecmath.Point3d; import javax.vecmath.Tuple3d; import javax.vecmath.Vector2d; import javax.vecmath.Vector3d; import org.simantics.g3d.math.MathTools; import org.simantics.g3d.math.Ray; import org.simantics.g3d.scenegraph.RenderListener; import org.simantics.g3d.shape.Color4d; import org.simantics.g3d.shape.Cone; import org.simantics.g3d.shape.Cylinder; import org.simantics.g3d.shape.Mesh; import org.simantics.g3d.vtk.common.InteractiveVtkPanel; import org.simantics.g3d.vtk.gizmo.vtkGizmo; import org.simantics.g3d.vtk.shape.MeshActor; import org.simantics.g3d.vtk.utils.vtkUtil; import vtk.vtkProp; public class SplitPointSelectionGizmo extends vtkGizmo { MeshActor actor; InteractiveVtkPanel panel; private RenderListener listener; private MouseMotionListener mouseListener; Point3d start; Point3d end; Vector3d dir; Vector2d mousePos = new Vector2d(); Vector3d pa = new Vector3d(); Vector3d pb = new Vector3d(); Tuple3d splitPoint = null; public SplitPointSelectionGizmo(InteractiveVtkPanel panel) { this.panel = panel; int res = 16; Mesh cone_x = Cone.create(0.1, res); cone_x.rotate(MathTools.getQuat(new AxisAngle4d(0,0,-1,Math.PI*0.5))); cone_x.translate(new Vector3d(0.8,0,0)); Mesh tube_x = Cylinder.create(MathTools.ORIGIN, new Vector3d(0.8,0,0), 0.05, res); tube_x.add(cone_x); Color4d z_col = new Color4d(0,1,0,1); tube_x.setColor(z_col); actor = new MeshActor(); actor.setMesh(tube_x); this.listener = new RenderListener() { @Override public void preRender() { Ray ray = vtkUtil.createMouseRay(getRenderer(), mousePos.x, mousePos.y); //ray.dir.add(ray.pos); //if (MathTools.intersectLineLine(start, end, ray.pos, ray.dir, pa, pb)) { double mu[] = new double[2]; if (MathTools.intersectStraightStraight(start, dir, ray.pos, ray.dir, pa, pb,mu)) { splitPoint = pa; if (mu[0] < 0.0) splitPoint = start; else if (mu[0] > 1.0) splitPoint = end; Vector3d dir = new Vector3d(splitPoint); dir.sub(pb); double length = dir.length(); dir.scale(1.0/length); AxisAngle4d aa = MathTools.createRotation(MathTools.X_AXIS, dir); setRotation(aa); setScale(length); setPosition(pb); actor.SetVisibility(1); } else { splitPoint = null; actor.SetVisibility(0); } } @Override public void postRender() { } }; this.mouseListener = new MouseMotionListener() { @Override public void mouseMoved(MouseEvent e) { mousePos.x = e.getX(); mousePos.y = e.getY(); SplitPointSelectionGizmo.this.panel.repaint(); } @Override public void mouseDragged(MouseEvent e) { mousePos.x = e.getX(); mousePos.y = e.getY(); SplitPointSelectionGizmo.this.panel.repaint(); } }; } public void setSplit(Point3d start, Point3d end) { this.start = start; this.end = end; dir = new Vector3d(end); dir.sub(start); } @Override public void attach(Object renderingPart) { super.attach(renderingPart); panel.addListener(listener); panel.addMouseMotionListener(mouseListener); } @Override public void deattach() { panel.removeListener(listener); panel.removeMouseMotionListener(mouseListener); super.deattach(); } @Override public Collection getGizmo() { Collection coll = new ArrayList(); coll.add(actor); return coll; } public Tuple3d getSplitPoint() { return splitPoint; } }