View Javadoc

1   /* -------------------------------------------------------------------
2    * Java source file for the class GSphere
3    * 
4    * Copyright (c), 2003, Masahiro Takatsuka.
5    * All Rights Researved.
6    * 
7    * Original Author: Masahiro Takatsuka (masa@jbeans.net)
8    * $Author: takatsukam $
9    * 
10   * $Date: 2004/03/03 11:53:06 $
11   * 
12   * $Id: GSphere.java,v 1.3 2004/03/03 11:53:06 takatsukam Exp $
13   * 
14   * Reference:		Document no:
15   * ___				___
16   * 
17   * To Do:
18   * ___
19   * 
20  ------------------------------------------------------------------- */
21  
22  /* --------------------------- Package ---------------------------- */
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                      Implementation of class GSphere                    
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  		}; // no essential attributes.
60  		Method m = null;
61  
62  		/*
63  		* setRadius
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  		* setDivisions
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  	/* ------------------------ not serialized ------------------------ */
88  	transient private Sphere sRefSphere = new Sphere();
89  	transient private PropertyChangeSupport changes;
90  
91  	/* -------------------------- serialized -------------------------- */
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 		//		resetReferenceSphere();
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 	/* --------------------- begin: GlyphSource --------------------- */
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 		// set capabilites before return it.
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 		// Set TransformGroup capabilities
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 	* Returns an array containing indices of essential setters.
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 }