< prev index next >

modules/graphics/src/main/java/javafx/scene/shape/Sphere.java

Print this page




  48  * The {@code Sphere} class defines a 3 dimensional sphere with the specified size.
  49  * A {@code Sphere} is a 3D geometry primitive created with a given radius.
  50  * It is centered at the origin.
  51  *
  52  * @since JavaFX 8.0
  53  */
  54 public class Sphere extends Shape3D {
  55     static {
  56          // This is used by classes in different packages to get access to
  57          // private and package private methods.
  58         SphereHelper.setSphereAccessor(new SphereHelper.SphereAccessor() {
  59             @Override
  60             public NGNode doCreatePeer(Node node) {
  61                 return ((Sphere) node).doCreatePeer();
  62             }
  63 
  64             @Override
  65             public void doUpdatePeer(Node node) {
  66                 ((Sphere) node).doUpdatePeer();
  67             }

















  68         });
  69     }
  70 
  71     static final int DEFAULT_DIVISIONS = 64;
  72     static final double DEFAULT_RADIUS = 1;
  73     private int divisions = DEFAULT_DIVISIONS;
  74     private TriangleMesh mesh;
  75 
  76     /**
  77      * Creates a new instance of {@code Sphere} of radius of 1.0.
  78      * The resolution defaults to MID_RESOLUTION divisions along sphere's axes.
  79      */
  80     public Sphere() {
  81         this(DEFAULT_RADIUS, DEFAULT_DIVISIONS);
  82     }
  83 
  84     /**
  85      * Creates a new instance of {@code Sphere} of a given radius.
  86      * The resolution defaults to MID_RESOLUTION divisions along sphere's axes.
  87      *


 115      * @defaultValue 1.0
 116      */
 117     private DoubleProperty radius;
 118 
 119     public final void setRadius(double value) {
 120         radiusProperty().set(value);
 121     }
 122 
 123     public final double getRadius() {
 124         return radius == null ? 1 : radius.get();
 125     }
 126 
 127     public final DoubleProperty radiusProperty() {
 128         if (radius == null) {
 129             radius = new SimpleDoubleProperty(Sphere.this, "radius", DEFAULT_RADIUS) {
 130                 @Override
 131                 public void invalidated() {
 132                     NodeHelper.markDirty(Sphere.this, DirtyBits.MESH_GEOM);
 133                     manager.invalidateSphereMesh(key);
 134                     key = 0;
 135                     impl_geomChanged();
 136                 }
 137             };
 138         }
 139         return radius;
 140     }
 141 
 142     /**
 143      * Retrieves the divisions attribute use to generate this sphere.
 144      *
 145      * @return the divisions attribute.
 146      */
 147     public int getDivisions() {
 148         return divisions;
 149     }
 150 
 151     /*
 152      * Note: This method MUST only be called via its accessor method.
 153      */
 154     private NGNode doCreatePeer() {
 155         return new NGSphere();


 158     /*
 159      * Note: This method MUST only be called via its accessor method.
 160      */
 161     private void doUpdatePeer() {
 162         if (NodeHelper.isDirty(this, DirtyBits.MESH_GEOM)) {
 163             final NGSphere pgSphere = NodeHelper.getPeer(this);
 164             final float r = (float) getRadius();
 165             if (r < 0) {
 166                 pgSphere.updateMesh(null);
 167             } else {
 168                 if (key == 0) {
 169                     key = generateKey(r, divisions);
 170                 }
 171                 mesh = manager.getSphereMesh(r, divisions, key);
 172                 mesh.updatePG();
 173                 pgSphere.updateMesh(mesh.getPGTriangleMesh());
 174             }
 175         }
 176     }
 177 
 178     /**
 179      * @treatAsPrivate implementation detail
 180      * @deprecated This is an internal API that is not intended for use and will be removed in the next version
 181      */
 182     @Deprecated
 183     @Override
 184     public BaseBounds impl_computeGeomBounds(BaseBounds bounds, BaseTransform tx) {
 185         final float r = (float) getRadius();
 186 
 187         if (r < 0) {
 188             return bounds.makeEmpty();
 189         }
 190 
 191         bounds = bounds.deriveWithNewBounds(-r, -r, -r, r, r ,r);
 192         bounds = tx.transform(bounds, bounds);
 193         return bounds;
 194     }
 195 
 196     /**
 197      * @treatAsPrivate implementation detail
 198      * @deprecated This is an internal API that is not intended for use and will be removed in the next version
 199      */
 200     @Deprecated
 201     @Override
 202     protected boolean impl_computeContains(double localX, double localY) {
 203         double r = getRadius();
 204         double n2 = localX * localX + localY * localY;
 205         return n2 <= r * r;
 206     }
 207 
 208     /**
 209      * @treatAsPrivate implementation detail
 210      * @deprecated This is an internal API that is not intended for use and will be removed in the next version
 211      */
 212     @Deprecated
 213     @Override
 214     protected boolean impl_computeIntersects(PickRay pickRay, PickResultChooser pickResult) {
 215 
 216         final boolean exactPicking = divisions < DEFAULT_DIVISIONS && mesh != null;
 217 
 218         final double r = getRadius();
 219         final Vec3d dir = pickRay.getDirectionNoClone();
 220         final double dirX = dir.x;
 221         final double dirY = dir.y;
 222         final double dirZ = dir.z;
 223         final Vec3d origin = pickRay.getOriginNoClone();
 224         final double originX = origin.x;
 225         final double originY = origin.y;
 226         final double originZ = origin.z;
 227 
 228         // Coeficients of a quadratic equation desribing intersection with sphere
 229         final double a = dirX * dirX + dirY * dirY + dirZ * dirZ;
 230         final double b = 2 * (dirX * originX + dirY * originY + dirZ * originZ);
 231         final double c = originX * originX + originY * originY + originZ * originZ - r * r;
 232 
 233         final double discriminant = b * b - 4 * a * c;
 234         if (discriminant < 0) {




  48  * The {@code Sphere} class defines a 3 dimensional sphere with the specified size.
  49  * A {@code Sphere} is a 3D geometry primitive created with a given radius.
  50  * It is centered at the origin.
  51  *
  52  * @since JavaFX 8.0
  53  */
  54 public class Sphere extends Shape3D {
  55     static {
  56          // This is used by classes in different packages to get access to
  57          // private and package private methods.
  58         SphereHelper.setSphereAccessor(new SphereHelper.SphereAccessor() {
  59             @Override
  60             public NGNode doCreatePeer(Node node) {
  61                 return ((Sphere) node).doCreatePeer();
  62             }
  63 
  64             @Override
  65             public void doUpdatePeer(Node node) {
  66                 ((Sphere) node).doUpdatePeer();
  67             }
  68 
  69             @Override
  70             public BaseBounds doComputeGeomBounds(Node node,
  71             BaseBounds bounds, BaseTransform tx) {
  72                 return ((Sphere) node).doComputeGeomBounds(bounds, tx);
  73             }
  74 
  75             @Override
  76             public boolean doComputeContains(Node node, double localX, double localY) {
  77                 return ((Sphere) node).doComputeContains(localX, localY);
  78             }
  79 
  80             @Override
  81             public boolean doComputeIntersects(Node node, PickRay pickRay,
  82             PickResultChooser pickResult) {
  83                 return ((Sphere) node).doComputeIntersects(pickRay, pickResult);
  84             }
  85         });
  86     }
  87 
  88     static final int DEFAULT_DIVISIONS = 64;
  89     static final double DEFAULT_RADIUS = 1;
  90     private int divisions = DEFAULT_DIVISIONS;
  91     private TriangleMesh mesh;
  92 
  93     /**
  94      * Creates a new instance of {@code Sphere} of radius of 1.0.
  95      * The resolution defaults to MID_RESOLUTION divisions along sphere's axes.
  96      */
  97     public Sphere() {
  98         this(DEFAULT_RADIUS, DEFAULT_DIVISIONS);
  99     }
 100 
 101     /**
 102      * Creates a new instance of {@code Sphere} of a given radius.
 103      * The resolution defaults to MID_RESOLUTION divisions along sphere's axes.
 104      *


 132      * @defaultValue 1.0
 133      */
 134     private DoubleProperty radius;
 135 
 136     public final void setRadius(double value) {
 137         radiusProperty().set(value);
 138     }
 139 
 140     public final double getRadius() {
 141         return radius == null ? 1 : radius.get();
 142     }
 143 
 144     public final DoubleProperty radiusProperty() {
 145         if (radius == null) {
 146             radius = new SimpleDoubleProperty(Sphere.this, "radius", DEFAULT_RADIUS) {
 147                 @Override
 148                 public void invalidated() {
 149                     NodeHelper.markDirty(Sphere.this, DirtyBits.MESH_GEOM);
 150                     manager.invalidateSphereMesh(key);
 151                     key = 0;
 152                     NodeHelper.geomChanged(Sphere.this);
 153                 }
 154             };
 155         }
 156         return radius;
 157     }
 158 
 159     /**
 160      * Retrieves the divisions attribute use to generate this sphere.
 161      *
 162      * @return the divisions attribute.
 163      */
 164     public int getDivisions() {
 165         return divisions;
 166     }
 167 
 168     /*
 169      * Note: This method MUST only be called via its accessor method.
 170      */
 171     private NGNode doCreatePeer() {
 172         return new NGSphere();


 175     /*
 176      * Note: This method MUST only be called via its accessor method.
 177      */
 178     private void doUpdatePeer() {
 179         if (NodeHelper.isDirty(this, DirtyBits.MESH_GEOM)) {
 180             final NGSphere pgSphere = NodeHelper.getPeer(this);
 181             final float r = (float) getRadius();
 182             if (r < 0) {
 183                 pgSphere.updateMesh(null);
 184             } else {
 185                 if (key == 0) {
 186                     key = generateKey(r, divisions);
 187                 }
 188                 mesh = manager.getSphereMesh(r, divisions, key);
 189                 mesh.updatePG();
 190                 pgSphere.updateMesh(mesh.getPGTriangleMesh());
 191             }
 192         }
 193     }
 194 
 195     /*
 196      * Note: This method MUST only be called via its accessor method.

 197      */
 198     private BaseBounds doComputeGeomBounds(BaseBounds bounds, BaseTransform tx) {


 199         final float r = (float) getRadius();
 200 
 201         if (r < 0) {
 202             return bounds.makeEmpty();
 203         }
 204 
 205         bounds = bounds.deriveWithNewBounds(-r, -r, -r, r, r ,r);
 206         bounds = tx.transform(bounds, bounds);
 207         return bounds;
 208     }
 209 
 210     /*
 211      * Note: This method MUST only be called via its accessor method.

 212      */
 213     private boolean doComputeContains(double localX, double localY) {


 214         double r = getRadius();
 215         double n2 = localX * localX + localY * localY;
 216         return n2 <= r * r;
 217     }
 218 
 219     /*
 220      * Note: This method MUST only be called via its accessor method.

 221      */
 222     private boolean doComputeIntersects(PickRay pickRay, PickResultChooser pickResult) {


 223 
 224         final boolean exactPicking = divisions < DEFAULT_DIVISIONS && mesh != null;
 225 
 226         final double r = getRadius();
 227         final Vec3d dir = pickRay.getDirectionNoClone();
 228         final double dirX = dir.x;
 229         final double dirY = dir.y;
 230         final double dirZ = dir.z;
 231         final Vec3d origin = pickRay.getOriginNoClone();
 232         final double originX = origin.x;
 233         final double originY = origin.y;
 234         final double originZ = origin.z;
 235 
 236         // Coeficients of a quadratic equation desribing intersection with sphere
 237         final double a = dirX * dirX + dirY * dirY + dirZ * dirZ;
 238         final double b = 2 * (dirX * originX + dirY * originY + dirZ * originZ);
 239         final double c = originX * originX + originY * originY + originZ * originZ - r * r;
 240 
 241         final double discriminant = b * b - 4 * a * c;
 242         if (discriminant < 0) {


< prev index next >