X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;ds=sidebyside;f=org.simantics.plant3d%2Fsrc%2Forg%2Fsimantics%2Fplant3d%2Fscenegraph%2Fcontrolpoint%2FPipeControlPoint.java;h=493f3b894702d8f86606c08e744f75afdffedf9c;hb=5c3aac4fe749c3a12b66823116dc43472bab869d;hp=eec074a68b88693812f7c8f686a08036ea72a548;hpb=61ce1ae33f46cf6d73a8d0ec151dcf1cd27db49f;p=simantics%2F3d.git diff --git a/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/controlpoint/PipeControlPoint.java b/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/controlpoint/PipeControlPoint.java index eec074a6..493f3b89 100644 --- a/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/controlpoint/PipeControlPoint.java +++ b/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/controlpoint/PipeControlPoint.java @@ -518,14 +518,10 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { if (turnAxis == null) { Vector3d dir = getPathLegDirection(Direction.NEXT); - if (dir.lengthSquared() > MathTools.NEAR_ZERO) - dir.normalize(); return getControlPointOrientationQuat(dir, angle); } else { Vector3d dir = getPathLegDirection(Direction.PREVIOUS); - dir.negate(); - if (dir.lengthSquared() > MathTools.NEAR_ZERO) - dir.normalize(); + if (dir != null) dir.negate(); return getControlPointOrientationQuat(dir, turnAxis, angle); } } @@ -563,7 +559,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { public static Quat4d getControlPointOrientationQuat(Vector3d dir, double angle) { - if (dir.lengthSquared() < MathTools.NEAR_ZERO) + if (dir == null || dir.lengthSquared() < MathTools.NEAR_ZERO) return MathTools.getIdentityQuat(); @@ -578,7 +574,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { } public static Quat4d getControlPointOrientationQuat(Vector3d dir, Vector3d up, double angle) { - if (dir.lengthSquared() < MathTools.NEAR_ZERO) + if (dir == null || dir.lengthSquared() < MathTools.NEAR_ZERO) return MathTools.getIdentityQuat(); final Vector3d front = new Vector3d(1.0,0.0,0.0); @@ -925,9 +921,8 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { PipeControlPoint sub = isAxial() ? this : getDualSub(); Vector3d pos = getWorldPosition(), pos2 = sub == this ? pos : sub.getWorldPosition(); - Vector3d dir = sub.getPathLegDirection(Direction.NEXT); + Vector3d dir = sub.getInlineDir(); - dir.normalize(); dir.scale(length * 0.5); p1.set(pos); p2.set(pos2); @@ -939,12 +934,16 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { PipeControlPoint sub = isAxial() || isDirected() || isTurn() ? this : getChildPoints().get(0); Vector3d pos = getWorldPosition(), pos2 = sub == this ? pos : sub.getWorldPosition(); - Vector3d dir1 = getPathLegDirection(Direction.PREVIOUS); - Vector3d dir2 = sub.getPathLegDirection(Direction.NEXT); + Vector3d dir1; + Vector3d dir2; if (isInline()) { - dir1.scale(length * 0.5); + dir2 = getInlineDir(); dir2.scale(length * 0.5); + dir1 = new Vector3d(dir2); + dir1.negate(); } else { + dir1 = getPathLegDirection(Direction.PREVIOUS); + dir2 = sub.getPathLegDirection(Direction.NEXT); dir1.scale(length); dir2.scale(length); } @@ -954,20 +953,34 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { p2.add(dir2); } + /** + * Get both path leg directions, with (0,0,0) if no connection exists. The returned vectors are not normalized. + * + * @param v1 Set to the direction towards the previous control point on output + * @param v2 Set to the direction towards the next control point on output + */ public void getEndDirections(Tuple3d v1, Tuple3d v2) { PipeControlPoint sub = isAxial() ? this : getDualSub(); Vector3d dir1 = getPathLegDirection(Direction.PREVIOUS); Vector3d dir2 = sub.getPathLegDirection(Direction.NEXT); - v1.set(dir1); - v2.set(dir2); + + if (dir1 != null) + v1.set(dir1); + else + v1.set(0,0,0); + + if (dir2 != null) + v2.set(dir2); + else + v2.set(0,0,0); } public void getInlineControlPointEnds(Tuple3d p1, Tuple3d p2, Vector3d dir) { assert (isInline()); Vector3d pos = getWorldPosition(); - dir.set(getPathLegDirection(Direction.NEXT)); + dir.set(getInlineDir()); dir.normalize(); dir.scale(length * 0.5); p1.set(pos); @@ -981,7 +994,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { Vector3d pos = getWorldPosition(); center.set(pos); - dir.set(getPathLegDirection(Direction.NEXT)); + dir.set(getInlineDir()); dir.normalize(); dir.scale(length * 0.5); p1.set(pos); @@ -990,6 +1003,22 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { p2.add(dir); } + public Vector3d getInlineDir() { + Vector3d dir = getPathLegDirection(Direction.NEXT); + if (dir == null) { + dir = getPathLegDirection(Direction.PREVIOUS); + if (dir != null) { + // Use reverse direction + dir.scale(-1.0); + } else { + // Control point is not connected at all, use current orientation + dir = new Vector3d(1,0,0); + MathTools.rotate(getWorldOrientation(), dir, dir); + } + } + return dir; + } + public double getInlineLength() { if (type == PointType.TURN) return length; @@ -998,22 +1027,27 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { return 0; } + /** + * Return the position indicated by the argument. If the indicated direction is not connected, the + * control point's wolrd position is returned instead. + * + * @param type A selector for the position to be returned + * @return The selected position + */ public Vector3d getRealPosition(PositionType type) { Vector3d pos = getWorldPosition(); switch (type) { case NEXT: { - Vector3d dir = getPathLegDirection(Direction.NEXT); + Vector3d dir = getInlineDir(); double length = getInlineLength(); - dir.normalize(); dir.scale(length); pos.add(dir); break; } case PREVIOUS: { - Vector3d dir = getPathLegDirection(Direction.PREVIOUS); + Vector3d dir = getInlineDir(); double length = getInlineLength(); - dir.normalize(); - dir.scale(length); + dir.scale(-length); pos.add(dir); break; }