< prev index next >

modules/graphics/src/main/java/javafx/scene/Node.java

Print this page




 136 import com.sun.javafx.geom.RectBounds;
 137 import com.sun.javafx.geom.Vec3d;
 138 import com.sun.javafx.geom.transform.Affine3D;
 139 import com.sun.javafx.geom.transform.BaseTransform;
 140 import com.sun.javafx.geom.transform.GeneralTransform3D;
 141 import com.sun.javafx.geom.transform.NoninvertibleTransformException;
 142 import com.sun.javafx.jmx.MXNodeAlgorithm;
 143 import com.sun.javafx.jmx.MXNodeAlgorithmContext;
 144 import com.sun.javafx.perf.PerformanceTracker;
 145 import com.sun.javafx.scene.BoundsAccessor;
 146 import com.sun.javafx.scene.CameraHelper;
 147 import com.sun.javafx.scene.CssFlags;
 148 import com.sun.javafx.scene.DirtyBits;
 149 import com.sun.javafx.scene.EventHandlerProperties;
 150 import com.sun.javafx.scene.LayoutFlags;
 151 import com.sun.javafx.scene.NodeEventDispatcher;
 152 import com.sun.javafx.scene.NodeHelper;
 153 import com.sun.javafx.scene.SceneHelper;
 154 import com.sun.javafx.scene.SceneUtils;
 155 import com.sun.javafx.scene.input.PickResultChooser;

 156 import com.sun.javafx.scene.transform.TransformUtils;
 157 import com.sun.javafx.scene.traversal.Direction;
 158 import com.sun.javafx.sg.prism.NGNode;
 159 import com.sun.javafx.tk.Toolkit;
 160 import com.sun.prism.impl.PrismSettings;
 161 import com.sun.scenario.effect.EffectHelper;
 162 
 163 import javafx.scene.shape.Shape3D;
 164 import sun.util.logging.PlatformLogger;
 165 import sun.util.logging.PlatformLogger.Level;
 166 
 167 /**
 168  * Base class for scene graph nodes. A scene graph is a set of tree data structures
 169  * where every item has zero or one parent, and each item is either
 170  * a "leaf" with zero sub-items or a "branch" with zero or more sub-items.
 171  * <p>
 172  * Each item in the scene graph is called a {@code Node}. Branch nodes are
 173  * of type {@link Parent}, whose concrete subclasses are {@link Group},
 174  * {@link javafx.scene.layout.Region}, and {@link javafx.scene.control.Control},
 175  * or subclasses thereof.


1848 
1849     private void doCSSLayoutSyncForSnapshot() {
1850         doCSSPass();
1851         doLayoutPass();
1852         updateBounds();
1853         Scene.impl_setAllowPGAccess(true);
1854         syncAll(this);
1855         Scene.impl_setAllowPGAccess(false);
1856     }
1857 
1858     private WritableImage doSnapshot(SnapshotParameters params, WritableImage img) {
1859         if (getScene() != null) {
1860             getScene().doCSSLayoutSyncForSnapshot(this);
1861         } else {
1862             doCSSLayoutSyncForSnapshot();
1863         }
1864 
1865         BaseTransform transform = BaseTransform.IDENTITY_TRANSFORM;
1866         if (params.getTransform() != null) {
1867             Affine3D tempTx = new Affine3D();
1868             params.getTransform().impl_apply(tempTx);
1869             transform = tempTx;
1870         }
1871         double x;
1872         double y;
1873         double w;
1874         double h;
1875         Rectangle2D viewport = params.getViewport();
1876         if (viewport != null) {
1877             // Use the specified viewport
1878             x = viewport.getMinX();
1879             y = viewport.getMinY();
1880             w = viewport.getWidth();
1881             h = viewport.getHeight();
1882         } else {
1883             // Get the bounds in parent of this node, transformed by the
1884             // specified transform.
1885             BaseBounds tempBounds = TempState.getInstance().bounds;
1886             tempBounds = getTransformedBounds(tempBounds, transform);
1887             x = tempBounds.getMinX();
1888             y = tempBounds.getMinY();


3076                         minZ = tempV3D.z;
3077 
3078                         tempV3D.set(0, 0, bounds.getMaxZ());
3079                         localToScene(tempV3D);
3080                         maxZ = tempV3D.z;
3081                     } else {
3082                         Bounds nodeInSceneBounds = localToScene(bounds);
3083                         minZ = nodeInSceneBounds.getMinZ();
3084                         maxZ = nodeInSceneBounds.getMaxZ();
3085                     }
3086 
3087                     if (minZ > camera.getFarClipInScene()
3088                             || maxZ < camera.getNearClipInScene()) {
3089                         return 0;
3090                     }
3091 
3092                 } else {
3093                     BaseBounds nodeInCameraBounds = new BoxBounds();
3094 
3095                     // We need to set tempTx to identity since it is a recycled transform.
3096                     // This is because impl_apply is a matrix concatenation operation.
3097                     tempTx.setToIdentity();
3098                     localToSceneTx.impl_apply(tempTx);
3099 
3100                     // Convert node from local coordinate to camera coordinate
3101                     tempTx.preConcatenate(camera.getSceneToLocalTransform());
3102                     tempTx.transform(localBounds, nodeInCameraBounds);
3103 
3104                     // Compare in camera coornidate
3105                     if (nodeInCameraBounds.getMinZ() > camera.getFarClip()
3106                             || nodeInCameraBounds.getMaxZ() < camera.getNearClip()) {
3107                         return 0;
3108                     }
3109                 }
3110             }
3111 
3112             GeneralTransform3D projViewTx = TempState.getInstance().projViewTx;
3113             projViewTx.set(camera.getProjViewTransform());
3114 
3115             // We need to set tempTx to identity since it is a recycled transform.
3116             // This is because impl_apply is a matrix concatenation operation.
3117             tempTx.setToIdentity();
3118             localToSceneTx.impl_apply(tempTx);
3119 
3120             // The product of projViewTx * localToSceneTransform
3121             GeneralTransform3D tx = projViewTx.mul(tempTx);
3122 
3123             // Transform localBounds to projected bounds
3124             localBounds = tx.transform(localBounds, localBounds);
3125             double area = localBounds.getWidth() * localBounds.getHeight();
3126 
3127             // Use canonical view volume to check whether object is outside the
3128             // viewing frustrum
3129             if (isPerspective) {
3130                 localBounds.intersectWith(-1, -1, 0, 1, 1, 1);
3131                 area = (localBounds.getWidth() < 0 || localBounds.getHeight() < 0) ? 0 : area;
3132             }
3133             return area * (camera.getViewWidth() / 2 * camera.getViewHeight() / 2);
3134         }
3135         return 0;
3136     }
3137 
3138     /* *************************************************************************


4805                 localToParentTx = localToParentTx.deriveWithTranslation(
4806                         getTranslateX() + getLayoutX() + pivotX,
4807                         getTranslateY() + getLayoutY() + pivotY,
4808                         getTranslateZ() + pivotZ);
4809                 localToParentTx = localToParentTx.deriveWithRotation(
4810                         Math.toRadians(getRotate()), getRotationAxis().getX(),
4811                         getRotationAxis().getY(), getRotationAxis().getZ());
4812                 localToParentTx = localToParentTx.deriveWithScale(
4813                         getScaleX(), getScaleY(), getScaleZ());
4814                 localToParentTx = localToParentTx.deriveWithTranslation(
4815                         -pivotX, -pivotY, -pivotZ);
4816             } else {
4817                 localToParentTx = localToParentTx.deriveWithTranslation(
4818                         getTranslateX() + getLayoutX(),
4819                         getTranslateY() + getLayoutY(),
4820                         getTranslateZ());
4821             }
4822 
4823             if (impl_hasTransforms()) {
4824                 for (Transform t : getTransforms()) {
4825                     localToParentTx = t.impl_derive(localToParentTx);
4826                 }
4827             }
4828 
4829             // Check to see whether the node requires mirroring
4830             if (mirror) {
4831                 localToParentTx = localToParentTx.deriveWithTranslation(
4832                         mirroringCenter, 0);
4833                 localToParentTx = localToParentTx.deriveWithScale(
4834                         -1.0, 1.0, 1.0);
4835                 localToParentTx = localToParentTx.deriveWithTranslation(
4836                         -mirroringCenter, 0);
4837             }
4838 
4839             transformDirty = false;
4840         }
4841     }
4842 
4843     /**
4844      * Transforms in place the specified point from parent coords to local
4845      * coords. Made package private for the sake of testing.


6074                     public Object getBean() {
6075                         return Node.this;
6076                     }
6077 
6078                     @Override
6079                     public String getName() {
6080                         return "rotationAxis";
6081                     }
6082                 };
6083             }
6084             return rotationAxis;
6085         }
6086 
6087         public ObservableList<Transform> getTransforms() {
6088             if (transforms == null) {
6089                 transforms = new TrackableObservableList<Transform>() {
6090                     @Override
6091                     protected void onChanged(Change<Transform> c) {
6092                         while (c.next()) {
6093                             for (Transform t : c.getRemoved()) {
6094                                 t.impl_remove(Node.this);
6095                             }
6096                             for (Transform t : c.getAddedSubList()) {
6097                                 t.impl_add(Node.this);
6098                             }
6099                         }
6100 
6101                         impl_transformsChanged();
6102                     }
6103                 };
6104             }
6105 
6106             return transforms;
6107         }
6108 
6109         public boolean canSetTranslateX() {
6110             return (translateX == null) || !translateX.isBound();
6111         }
6112 
6113         public boolean canSetTranslateY() {
6114             return (translateY == null) || !translateY.isBound();
6115         }
6116 
6117         public boolean canSetTranslateZ() {




 136 import com.sun.javafx.geom.RectBounds;
 137 import com.sun.javafx.geom.Vec3d;
 138 import com.sun.javafx.geom.transform.Affine3D;
 139 import com.sun.javafx.geom.transform.BaseTransform;
 140 import com.sun.javafx.geom.transform.GeneralTransform3D;
 141 import com.sun.javafx.geom.transform.NoninvertibleTransformException;
 142 import com.sun.javafx.jmx.MXNodeAlgorithm;
 143 import com.sun.javafx.jmx.MXNodeAlgorithmContext;
 144 import com.sun.javafx.perf.PerformanceTracker;
 145 import com.sun.javafx.scene.BoundsAccessor;
 146 import com.sun.javafx.scene.CameraHelper;
 147 import com.sun.javafx.scene.CssFlags;
 148 import com.sun.javafx.scene.DirtyBits;
 149 import com.sun.javafx.scene.EventHandlerProperties;
 150 import com.sun.javafx.scene.LayoutFlags;
 151 import com.sun.javafx.scene.NodeEventDispatcher;
 152 import com.sun.javafx.scene.NodeHelper;
 153 import com.sun.javafx.scene.SceneHelper;
 154 import com.sun.javafx.scene.SceneUtils;
 155 import com.sun.javafx.scene.input.PickResultChooser;
 156 import com.sun.javafx.scene.transform.TransformHelper;
 157 import com.sun.javafx.scene.transform.TransformUtils;
 158 import com.sun.javafx.scene.traversal.Direction;
 159 import com.sun.javafx.sg.prism.NGNode;
 160 import com.sun.javafx.tk.Toolkit;
 161 import com.sun.prism.impl.PrismSettings;
 162 import com.sun.scenario.effect.EffectHelper;
 163 
 164 import javafx.scene.shape.Shape3D;
 165 import sun.util.logging.PlatformLogger;
 166 import sun.util.logging.PlatformLogger.Level;
 167 
 168 /**
 169  * Base class for scene graph nodes. A scene graph is a set of tree data structures
 170  * where every item has zero or one parent, and each item is either
 171  * a "leaf" with zero sub-items or a "branch" with zero or more sub-items.
 172  * <p>
 173  * Each item in the scene graph is called a {@code Node}. Branch nodes are
 174  * of type {@link Parent}, whose concrete subclasses are {@link Group},
 175  * {@link javafx.scene.layout.Region}, and {@link javafx.scene.control.Control},
 176  * or subclasses thereof.


1849 
1850     private void doCSSLayoutSyncForSnapshot() {
1851         doCSSPass();
1852         doLayoutPass();
1853         updateBounds();
1854         Scene.impl_setAllowPGAccess(true);
1855         syncAll(this);
1856         Scene.impl_setAllowPGAccess(false);
1857     }
1858 
1859     private WritableImage doSnapshot(SnapshotParameters params, WritableImage img) {
1860         if (getScene() != null) {
1861             getScene().doCSSLayoutSyncForSnapshot(this);
1862         } else {
1863             doCSSLayoutSyncForSnapshot();
1864         }
1865 
1866         BaseTransform transform = BaseTransform.IDENTITY_TRANSFORM;
1867         if (params.getTransform() != null) {
1868             Affine3D tempTx = new Affine3D();
1869             TransformHelper.apply(params.getTransform(), tempTx);
1870             transform = tempTx;
1871         }
1872         double x;
1873         double y;
1874         double w;
1875         double h;
1876         Rectangle2D viewport = params.getViewport();
1877         if (viewport != null) {
1878             // Use the specified viewport
1879             x = viewport.getMinX();
1880             y = viewport.getMinY();
1881             w = viewport.getWidth();
1882             h = viewport.getHeight();
1883         } else {
1884             // Get the bounds in parent of this node, transformed by the
1885             // specified transform.
1886             BaseBounds tempBounds = TempState.getInstance().bounds;
1887             tempBounds = getTransformedBounds(tempBounds, transform);
1888             x = tempBounds.getMinX();
1889             y = tempBounds.getMinY();


3077                         minZ = tempV3D.z;
3078 
3079                         tempV3D.set(0, 0, bounds.getMaxZ());
3080                         localToScene(tempV3D);
3081                         maxZ = tempV3D.z;
3082                     } else {
3083                         Bounds nodeInSceneBounds = localToScene(bounds);
3084                         minZ = nodeInSceneBounds.getMinZ();
3085                         maxZ = nodeInSceneBounds.getMaxZ();
3086                     }
3087 
3088                     if (minZ > camera.getFarClipInScene()
3089                             || maxZ < camera.getNearClipInScene()) {
3090                         return 0;
3091                     }
3092 
3093                 } else {
3094                     BaseBounds nodeInCameraBounds = new BoxBounds();
3095 
3096                     // We need to set tempTx to identity since it is a recycled transform.
3097                     // This is because TransformHelper.apply() is a matrix concatenation operation.
3098                     tempTx.setToIdentity();
3099                     TransformHelper.apply(localToSceneTx, tempTx);
3100 
3101                     // Convert node from local coordinate to camera coordinate
3102                     tempTx.preConcatenate(camera.getSceneToLocalTransform());
3103                     tempTx.transform(localBounds, nodeInCameraBounds);
3104 
3105                     // Compare in camera coornidate
3106                     if (nodeInCameraBounds.getMinZ() > camera.getFarClip()
3107                             || nodeInCameraBounds.getMaxZ() < camera.getNearClip()) {
3108                         return 0;
3109                     }
3110                 }
3111             }
3112 
3113             GeneralTransform3D projViewTx = TempState.getInstance().projViewTx;
3114             projViewTx.set(camera.getProjViewTransform());
3115 
3116             // We need to set tempTx to identity since it is a recycled transform.
3117             // This is because TransformHelper.apply() is a matrix concatenation operation.
3118             tempTx.setToIdentity();
3119             TransformHelper.apply(localToSceneTx, tempTx);
3120 
3121             // The product of projViewTx * localToSceneTransform
3122             GeneralTransform3D tx = projViewTx.mul(tempTx);
3123 
3124             // Transform localBounds to projected bounds
3125             localBounds = tx.transform(localBounds, localBounds);
3126             double area = localBounds.getWidth() * localBounds.getHeight();
3127 
3128             // Use canonical view volume to check whether object is outside the
3129             // viewing frustrum
3130             if (isPerspective) {
3131                 localBounds.intersectWith(-1, -1, 0, 1, 1, 1);
3132                 area = (localBounds.getWidth() < 0 || localBounds.getHeight() < 0) ? 0 : area;
3133             }
3134             return area * (camera.getViewWidth() / 2 * camera.getViewHeight() / 2);
3135         }
3136         return 0;
3137     }
3138 
3139     /* *************************************************************************


4806                 localToParentTx = localToParentTx.deriveWithTranslation(
4807                         getTranslateX() + getLayoutX() + pivotX,
4808                         getTranslateY() + getLayoutY() + pivotY,
4809                         getTranslateZ() + pivotZ);
4810                 localToParentTx = localToParentTx.deriveWithRotation(
4811                         Math.toRadians(getRotate()), getRotationAxis().getX(),
4812                         getRotationAxis().getY(), getRotationAxis().getZ());
4813                 localToParentTx = localToParentTx.deriveWithScale(
4814                         getScaleX(), getScaleY(), getScaleZ());
4815                 localToParentTx = localToParentTx.deriveWithTranslation(
4816                         -pivotX, -pivotY, -pivotZ);
4817             } else {
4818                 localToParentTx = localToParentTx.deriveWithTranslation(
4819                         getTranslateX() + getLayoutX(),
4820                         getTranslateY() + getLayoutY(),
4821                         getTranslateZ());
4822             }
4823 
4824             if (impl_hasTransforms()) {
4825                 for (Transform t : getTransforms()) {
4826                     localToParentTx = TransformHelper.derive(t, localToParentTx);
4827                 }
4828             }
4829 
4830             // Check to see whether the node requires mirroring
4831             if (mirror) {
4832                 localToParentTx = localToParentTx.deriveWithTranslation(
4833                         mirroringCenter, 0);
4834                 localToParentTx = localToParentTx.deriveWithScale(
4835                         -1.0, 1.0, 1.0);
4836                 localToParentTx = localToParentTx.deriveWithTranslation(
4837                         -mirroringCenter, 0);
4838             }
4839 
4840             transformDirty = false;
4841         }
4842     }
4843 
4844     /**
4845      * Transforms in place the specified point from parent coords to local
4846      * coords. Made package private for the sake of testing.


6075                     public Object getBean() {
6076                         return Node.this;
6077                     }
6078 
6079                     @Override
6080                     public String getName() {
6081                         return "rotationAxis";
6082                     }
6083                 };
6084             }
6085             return rotationAxis;
6086         }
6087 
6088         public ObservableList<Transform> getTransforms() {
6089             if (transforms == null) {
6090                 transforms = new TrackableObservableList<Transform>() {
6091                     @Override
6092                     protected void onChanged(Change<Transform> c) {
6093                         while (c.next()) {
6094                             for (Transform t : c.getRemoved()) {
6095                                 TransformHelper.remove(t, Node.this);
6096                             }
6097                             for (Transform t : c.getAddedSubList()) {
6098                                 TransformHelper.add(t, Node.this);
6099                             }
6100                         }
6101 
6102                         impl_transformsChanged();
6103                     }
6104                 };
6105             }
6106 
6107             return transforms;
6108         }
6109 
6110         public boolean canSetTranslateX() {
6111             return (translateX == null) || !translateX.isBound();
6112         }
6113 
6114         public boolean canSetTranslateY() {
6115             return (translateY == null) || !translateY.isBound();
6116         }
6117 
6118         public boolean canSetTranslateZ() {


< prev index next >