1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package net.jbeans.j3d.modeler.scene.glyph;
24
25 /* ------------------ Import classes (packages) ------------------- *//package-summary/html">class="comment"> ------------------ Import classes (packages) ------------------- *//package-summary.html">class="comment">/* ------------------ Import classes (packages) ------------------- *//package-summary.html">class="comment"> ------------------ Import classes (packages) ------------------- */
26 import java.beans.*;
27 import java.io.*;
28 import java.lang.reflect.*;
29 import java.util.Enumeration;
30
31 import javax.media.j3d.*;
32 import javax.vecmath.*;
33 import com.sun.j3d.utils.geometry.*;
34
35 import net.jbeans.j3d.modeler.scene.*;
36
37
38
39
40 /***
41 * GSphere is a glyph source which generatees sphere geometry object.
42 *
43 * @version $Revision: 1.3 $
44 * @author Masahiro Takatsuka (masa@jbeans.net)
45 * @see GlyphSource, Serializable
46 */
47
48 public class GSphere implements GlyphSource, Serializable {
49 private static Method[] sSetMethods;
50 private static int[] sEssentials;
51 static {
52 setSetMethods();
53 }
54
55 private static void setSetMethods() {
56 Class clazz = GSphere.class;
57 sSetMethods = new Method[2];
58 sEssentials = new int[] {
59 };
60 Method m = null;
61
62
63
64
65 try {
66 m = clazz.getMethod("setRadius", new Class[] { Float.TYPE });
67 sSetMethods[0] = m;
68 }
69 catch (Exception e) {
70 sSetMethods[0] = null;
71 }
72
73
74
75
76 try {
77 m = clazz.getMethod("setDivisions", new Class[] { Integer.TYPE });
78 sSetMethods[1] = m;
79 }
80 catch (Exception e) {
81 sSetMethods[1] = null;
82 }
83 }
84
85 private static final int MID_REZ_DIV = 15;
86
87
88 transient private Sphere sRefSphere = new Sphere();
89 transient private PropertyChangeSupport changes;
90
91
92 private float radius = 1.0f;
93 private int divisions = MID_REZ_DIV;
94
95 public GSphere() {
96 super();
97 initialize();
98 }
99
100 private void initialize() {
101 this.changes = new PropertyChangeSupport(this);
102 }
103
104 public void addPropertyChangeListener(PropertyChangeListener l) {
105 this.changes.addPropertyChangeListener(l);
106 }
107
108 public void removePropertyChangeListener(PropertyChangeListener l) {
109 this.changes.removePropertyChangeListener(l);
110 }
111
112 public void setRadius(float r) {
113 r = (r <= 0.0f) ? 1.0f : r;
114 float old = this.radius;
115 this.radius = r;
116
117 this.changes.firePropertyChange("radius", new Float(old), new Float(this.radius));
118 }
119 public float getRadius() {
120 return this.radius;
121 }
122
123 public void setDivisions(int div) {
124 div = (div < 1) ? 1 : div;
125 int old = this.divisions;
126 this.divisions = div;
127 resetReferenceSphere();
128 this.changes.firePropertyChange("divisions", old, this.divisions);
129 }
130
131 public int getDivisions() {
132 return this.divisions;
133 }
134
135 private void resetReferenceSphere() {
136 sRefSphere =
137 new Sphere(
138 1.0f,
139 Primitive.GENERATE_NORMALS | Primitive.GENERATE_TEXTURE_COORDS | Primitive.GEOMETRY_NOT_SHARED,
140 this.divisions);
141 }
142
143
144 /***
145 * Returns javax.media.3d.Shape3D object.
146 */
147 public Node getNode() {
148 Transform3D t3d = new Transform3D();
149 t3d.setScale(radius);
150 TransformGroup tg = new TransformGroup(t3d);
151 Shape3D shape3d = (Shape3D) sRefSphere.getShape().cloneNode(true);
152
153
154 shape3d.setCapability(Node.ALLOW_BOUNDS_READ);
155 shape3d.setCapability(Node.ALLOW_BOUNDS_WRITE);
156 shape3d.setCapability(Node.ALLOW_AUTO_COMPUTE_BOUNDS_READ);
157 shape3d.setCapability(Node.ALLOW_AUTO_COMPUTE_BOUNDS_WRITE);
158 shape3d.setCapability(Shape3D.ALLOW_APPEARANCE_READ);
159 shape3d.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE);
160 shape3d.setCapability(Shape3D.ALLOW_COLLISION_BOUNDS_READ);
161 shape3d.setCapability(Shape3D.ALLOW_COLLISION_BOUNDS_WRITE);
162 shape3d.setCapability(Shape3D.ALLOW_GEOMETRY_READ);
163 shape3d.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE);
164
165 Geometry geom = shape3d.getGeometry();
166 geom.setCapability(GeometryArray.ALLOW_COUNT_READ);
167 geom.setCapability(GeometryArray.ALLOW_FORMAT_READ);
168 geom.setCapability(GeometryArray.ALLOW_COORDINATE_READ);
169 geom.setCapability(GeometryArray.ALLOW_COORDINATE_WRITE);
170 geom.setCapability(GeometryArray.ALLOW_NORMAL_READ);
171 geom.setCapability(GeometryArray.ALLOW_NORMAL_WRITE);
172 geom.setCapability(IndexedGeometryArray.ALLOW_COORDINATE_INDEX_READ);
173 geom.setCapability(IndexedGeometryArray.ALLOW_COORDINATE_INDEX_WRITE);
174 geom.setCapability(IndexedGeometryArray.ALLOW_NORMAL_INDEX_READ);
175 geom.setCapability(IndexedGeometryArray.ALLOW_NORMAL_INDEX_WRITE);
176
177
178 tg.setCapability(Group.ALLOW_CHILDREN_EXTEND);
179 tg.setCapability(Group.ALLOW_CHILDREN_READ);
180 tg.setCapability(Group.ALLOW_CHILDREN_WRITE);
181 tg.setCapability(Group.ALLOW_COLLISION_BOUNDS_READ);
182 tg.setCapability(Group.ALLOW_COLLISION_BOUNDS_WRITE);
183 tg.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
184 tg.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
185
186 tg.addChild(shape3d);
187 tg.setUserData(new Integer(divisions));
188
189 return tg;
190 }
191
192 /***
193 * Updates the specified Shape3D object.
194 */
195 public Node updateNode(Node node) {
196 if (!(node instanceof TransformGroup)) {
197 return node;
198 }
199
200 TransformGroup tg = (TransformGroup) node;
201
202 Object userData = tg.getUserData();
203 if ((userData instanceof Integer) && ((Integer) userData).intValue() != divisions) {
204 return getNode();
205 }
206
207 Transform3D t3d = new Transform3D();
208 t3d.setScale(radius);
209 tg.setTransform(t3d);
210
211 return node;
212 }
213
214 /***
215 * Returns an array containing methods to set data to construct
216 * a glyph source.
217 * setRadius, setDivisions
218 */
219 public Method[] getSetMethods() {
220 return sSetMethods;
221 }
222
223
224
225
226 public int[] getEssentials() {
227 return sEssentials;
228 }
229
230 /***
231 * Returns javax.media.3d.Appearance object.
232 */
233 public Appearance getAppearanceOfNode(Node node) {
234 return (node instanceof Shape3D) ? ((Shape3D) node).getAppearance() : null;
235 }
236
237 /***
238 * Updates the specified Appearance object.
239 */
240 public void setAppearanceOfNode(Node node, Appearance appearance) {
241 if (node instanceof Shape3D) {
242 ((Shape3D) node).setAppearance(appearance);
243 }
244 if (node instanceof Group) {
245 Group group = (Group) node;
246
247 Enumeration children = group.getAllChildren();
248 while (children.hasMoreElements()) {
249 Node child = (Node) children.nextElement();
250
251 setAppearanceOfNode(child, appearance);
252 }
253 }
254 }
255 }