@GraphType(Plant3D.URIs.Plant)
public class P3DRootNode extends ParentNode<INode> implements IG3DNode, NodeMapProvider<Resource, vtkProp, INode> {
-
+ // Vertical direction that determines the interpretation of rotation angle origin
+ protected Vector3d upVector = new Vector3d(0.0, 1.0, 0.0);
+
@RelatedElementsAdd(Plant3D.URIs.children)
public void addChild(INode node) {
//public void addChild(IP3DVisualNode node) {
public TurnComponent createTurn() {
return new TurnComponent();
}
+
+ public Vector3d getUpVector() {
+ return upVector;
+ }
}
import org.simantics.g3d.math.MathTools;
import org.simantics.g3d.property.annotations.GetPropertyValue;
import org.simantics.g3d.scenegraph.G3DNode;
+import org.simantics.g3d.scenegraph.base.INode;
import org.simantics.plant3d.scenegraph.IP3DNode;
import org.simantics.plant3d.scenegraph.Nozzle;
import org.simantics.plant3d.scenegraph.P3DRootNode;
if (dir == null || dir.lengthSquared() < MathTools.NEAR_ZERO)
return MathTools.getIdentityQuat();
- Vector3d up = new Vector3d(0.0, 1.0, 0.0);
+ final P3DRootNode root = getRoot();
+ Vector3d up = root != null ? new Vector3d(root.getUpVector()) : new Vector3d(0.0, 1.0, 0.0);
double a = up.angle(getPathLegEndpointVector());
if (a < 0.1 || (Math.PI - a) < 0.1) {
- up.set(1.0, 0.0, 0.0);
+ // Rotate components
+ up.set(up.getY(), up.getZ(), up.getX());
}
return getControlPointOrientationQuat(dir, up, angle);
}
+ public P3DRootNode getRoot() {
+ INode n = getParent();
+ while (n != null && !(n instanceof P3DRootNode))
+ n = n.getParent();
+ return (P3DRootNode) n;
+ }
+
public static Quat4d getControlPointOrientationQuat(Vector3d dir, Vector3d up, double angle) {
if (dir == null || dir.lengthSquared() < MathTools.NEAR_ZERO)
return MathTools.getIdentityQuat();
Vector3d right = new Vector3d();
-
+
+ up = new Vector3d(up);
right.cross(dir, up);
up.cross(right, dir);
right.normalize();