Spec-Zone .ru
спецификации, руководства, описания, API
|
001/* 002 * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. Oracle designates this 008 * particular file as subject to the "Classpath" exception as provided 009 * by Oracle in the LICENSE file that accompanied this code. 010 * 011 * This code is distributed in the hope that it will be useful, but WITHOUT 012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 014 * version 2 for more details (a copy is included in the LICENSE file that 015 * accompanied this code). 016 * 017 * You should have received a copy of the GNU General Public License version 018 * 2 along with this work; if not, write to the Free Software Foundation, 019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 020 * 021 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 022 * or visit www.oracle.com if you need additional information or have any 023 * questions. 024 */ 025 026package javafx.scene.shape; 027 028import com.sun.javafx.geom.BaseBounds; 029import com.sun.javafx.geom.BoxBounds; 030import com.sun.javafx.geom.transform.BaseTransform; 031import com.sun.javafx.jmx.MXNodeAlgorithm; 032import com.sun.javafx.jmx.MXNodeAlgorithmContext; 033import com.sun.javafx.scene.DirtyBits; 034import com.sun.javafx.sg.PGPhongMaterial; 035import com.sun.javafx.sg.PGShape3D; 036import javafx.application.ConditionalFeature; 037import javafx.application.Platform; 038import javafx.beans.property.ObjectProperty; 039import javafx.beans.property.SimpleObjectProperty; 040import javafx.beans.value.ChangeListener; 041import javafx.beans.value.ObservableValue; 042import javafx.scene.Node; 043import javafx.scene.paint.Material; 044import javafx.scene.paint.PhongMaterial; 045import sun.util.logging.PlatformLogger; 046 047 048/** 049 * The {@code Shape3D} base class provides definitions of common properties for 050 * objects that represent some form of 3D geometric shape. These properties 051 * include: 052 * <ul> 053 * <li>The {@link Material} to be applied to the fillable interior of the 054 * shape or the outline of the shape (see {@link #setMaterial}). 055 * <li>The draw model properties that defines how to render its geometry (see {@link #setDrawMode}). 056 * <li>The face culling properties that defines which face to cull (see {@link #setCullFace}). 057 * </ul> 058 * 059 * Note that this is a conditional feature. See 060 * {@link javafx.application.ConditionalFeature#SCENE3D ConditionalFeature.SCENE3D} 061 * for more information. 062 * 063 * @since JavaFX 8 064 */ 065public abstract class Shape3D extends Node { 066 // NOTE: Need a way to specify shape tessellation resolution, may use metric relate to window resolution 067 // Will not support dynamic refinement in FX8 068 069 // TODO: 3D - May provide user convenient utility to compose images in a single image for shapes such as Box or Cylinder 070 071 private static final PhongMaterial DEFAULT_MATERIAL = new PhongMaterial(); 072 073 protected Shape3D() { 074 if (!Platform.isSupported(ConditionalFeature.SCENE3D)) { 075 String logname = Shape3D.class.getName(); 076 PlatformLogger.getLogger(logname).warning("System can't support " 077 + "ConditionalFeature.SCENE3D"); 078 } 079 } 080 081 PredefinedMeshManager manager = PredefinedMeshManager.getInstance(); 082 int key = 0; 083 084 /** 085 * Defines the material this {@code Shape3D}. 086 * The default material is null. If {@code Material} is null, a PhongMaterial 087 * with a diffuse color of Color.LIGHTGRAY is used for rendering. 088 * 089 * @defaultValue null 090 */ 091 private ObjectProperty<Material> material; 092 093 public final void setMaterial(Material value) { 094 materialProperty().set(value); 095 } 096 097 public final Material getMaterial() { 098 return material == null ? null : material.get(); 099 } 100 101 private final ChangeListener<Boolean> materialListener = new ChangeListener<Boolean>() { 102 @Override public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) { 103 if (newValue) { 104 impl_markDirty(DirtyBits.MATERIAL_PROPERTY); 105 //impl_geomChanged(); 106 } 107 } 108 }; 109 110 public final ObjectProperty<Material> materialProperty() { 111 if (material == null) { 112 material = new SimpleObjectProperty<Material>(Shape3D.this, 113 "material") { 114 115 private Material old = null; 116 @Override protected void invalidated() { 117 if (old != null) { 118 old.impl_dirtyProperty().removeListener(materialListener); 119 } 120 Material newMaterial = get(); 121 if (newMaterial != null) { 122 newMaterial.impl_dirtyProperty().addListener(materialListener); 123 } 124 impl_markDirty(DirtyBits.MATERIAL); 125 impl_geomChanged(); 126 old = newMaterial; 127 } 128 }; 129 } 130 return material; 131 } 132 133 /** 134 * Defines the drawMode this {@code Shape3D}. 135 * 136 * @defaultValue DrawMode.FILL 137 */ 138 private ObjectProperty<DrawMode> drawMode; 139 140 public final void setDrawMode(DrawMode value) { 141 drawModeProperty().set(value); 142 } 143 144 public final DrawMode getDrawMode() { 145 return drawMode == null ? DrawMode.FILL : drawMode.get(); 146 } 147 148 public final ObjectProperty<DrawMode> drawModeProperty() { 149 if (drawMode == null) { 150 drawMode = new SimpleObjectProperty<DrawMode>(Shape3D.this, 151 "drawMode", DrawMode.FILL) { 152 153 @Override 154 protected void invalidated() { 155 impl_markDirty(DirtyBits.NODE_DRAWMODE); 156 } 157 }; 158 } 159 return drawMode; 160 } 161 162 /** 163 * Defines the drawMode this {@code Shape3D}. 164 * 165 * @defaultValue CullFace.BACK 166 */ 167 private ObjectProperty<CullFace> cullFace; 168 169 public final void setCullFace(CullFace value) { 170 cullFaceProperty().set(value); 171 } 172 173 public final CullFace getCullFace() { 174 return cullFace == null ? CullFace.BACK : cullFace.get(); 175 } 176 177 public final ObjectProperty<CullFace> cullFaceProperty() { 178 if (cullFace == null) { 179 cullFace = new SimpleObjectProperty<CullFace>(Shape3D.this, 180 "cullFace", CullFace.BACK) { 181 182 @Override 183 protected void invalidated() { 184 impl_markDirty(DirtyBits.NODE_CULLFACE); 185 } 186 }; 187 } 188 return cullFace; 189 } 190 191 /** 192 * @treatAsPrivate implementation detail 193 * @deprecated This is an internal API that is not intended for use and will be removed in the next version 194 */ 195 @Deprecated 196 @Override 197 public BaseBounds impl_computeGeomBounds(BaseBounds bounds, BaseTransform tx) { 198 // TODO: 3D - Evaluate this logic 199 return new BoxBounds(0, 0, 0, 0, 0, 0); 200 } 201 202 /** 203 * @treatAsPrivate implementation detail 204 * @deprecated This is an internal API that is not intended for use and will be removed in the next version 205 */ 206 @Deprecated 207 @Override 208 protected boolean impl_computeContains(double localX, double localY) { 209 return false; 210 } 211 212 /** 213 * @treatAsPrivate implementation detail 214 * @deprecated This is an internal API that is not intended for use and will be removed in the next version 215 */ 216 @Deprecated 217 @Override 218 public void impl_updatePG() { 219 super.impl_updatePG(); 220 221 // TODO: 3D - Why do we have separate dirty bits for MATERIAL 222 // and MATERIAL_PROPERTY ? 223 Material material = getMaterial(); 224 if (impl_isDirty(DirtyBits.MATERIAL_PROPERTY) && material != null) { 225 material.impl_updatePG(); 226 } 227 PGShape3D pgShape3D = (PGShape3D) impl_getPGNode(); 228 if (impl_isDirty(DirtyBits.MATERIAL)) { 229 if (material != null) { 230 material.impl_updatePG(); // new material should be updated 231 pgShape3D.setMaterial((PGPhongMaterial) material.impl_getPGMaterial()); 232 } else { 233 DEFAULT_MATERIAL.impl_updatePG(); 234 pgShape3D.setMaterial(DEFAULT_MATERIAL.impl_getPGMaterial()); 235 } 236 } 237 if (impl_isDirty(DirtyBits.NODE_DRAWMODE)) { 238 pgShape3D.setDrawMode(getDrawMode()); 239 } 240 if (impl_isDirty(DirtyBits.NODE_CULLFACE)) { 241 pgShape3D.setCullFace(getCullFace()); 242 } 243 } 244 245 /** 246 * @treatAsPrivate implementation detail 247 * @deprecated This is an internal API that is not intended for use and will be removed in the next version 248 */ 249 @Deprecated 250 @Override 251 public Object impl_processMXNode(MXNodeAlgorithm alg, MXNodeAlgorithmContext ctx) { 252 throw new UnsupportedOperationException("Not supported yet."); 253 } 254 255}