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.geometry;
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 javax.media.j3d.*;
27 import javax.vecmath.*;
28
29 import net.jbeans.util.debug.*;
30
31
32
33
34 /***
35 * NormalModeler generates a set of surface normals from a specified
36 * Geometry object.
37 *
38 * @version $Revision: 1.3 $
39 * @author Masahiro Takatsuka (masa@jbeans.net)
40 * @see GeometryModeler
41 */
42
43 public class NormalModeler extends GeometryModeler {
44 private static final boolean DEBUG = Debug.getDebugFlag(NormalModeler.class);
45
46 public static final int UPDATE_ALWAYS = 0;
47 public static final int UPDATE_ONCE = 1;
48
49
50 transient private GeometryArray sourceGeom;
51 transient private boolean reset = true;
52 transient private Point3f[] nvertices;
53
54
55 private float scale;
56 private int updateMode = UPDATE_ALWAYS;
57
58 public NormalModeler() {
59 super();
60 this.scale = 1.0f;
61 }
62
63 public NormalModeler(float scale) {
64 this();
65 setScale(scale);
66 }
67
68 public void setUpdateMode(int mode) {
69 switch (mode) {
70 case UPDATE_ALWAYS:
71 default:
72 mode = UPDATE_ALWAYS;
73 break;
74 case UPDATE_ONCE:
75 break;
76 }
77 this.updateMode = mode;
78 }
79
80 public int getUpdateMode() {
81 return this.updateMode;
82 }
83
84 public void setScale(float scale) {
85 this.scale = scale;
86 }
87
88 public float getScale() {
89 return this.scale;
90 }
91
92 public void setGeometryArray(Geometry geometry) {
93 if (! (geometry instanceof GeometryArray)) {
94 return;
95 }
96 GeometryArray geom = (GeometryArray) geometry;
97
98 if (geom != this.sourceGeom || this.updateMode == UPDATE_ALWAYS) {
99 this.sourceGeom = geom;
100 this.reset = true;
101 model();
102 } else {
103 update();
104 }
105 }
106
107 protected void modelGeometry() {
108 GeometryArray geom;
109 if (this.sourceGeom instanceof IndexedGeometryArray) {
110 renderForIndexedGeometryArray((IndexedGeometryArray) this.sourceGeom, this.scale);
111 } else {
112 renderForGeometryArray(this.sourceGeom, this.scale);
113 }
114
115 geom = new LineArray(this.nvertices.length,
116 GeometryArray.COORDINATES
117 | GeometryArray.BY_REFERENCE);
118 setCapabilities(geom);
119
120 geom.setCoordRef3f(this.nvertices);
121
122
123 setGeometry(geom);
124 }
125
126 public void updateData(Geometry geom) {
127 int lineCount = getNumberOfNormals(this.sourceGeom) * 2;
128
129 if (lineCount != this.nvertices.length) {
130 this.reset = true;
131 } else {
132 this.reset = false;
133 }
134 if (this.sourceGeom instanceof IndexedGeometryArray) {
135 renderForIndexedGeometryArray((IndexedGeometryArray) this.sourceGeom, this.scale);
136 } else {
137 renderForGeometryArray(this.sourceGeom, this.scale);
138 }
139 if (this.reset) {
140 ((GeometryArray) geom).setCoordRef3f(this.nvertices);
141 }
142 }
143
144 private int getNumberOfNormals(GeometryArray geom) {
145 if (geom instanceof IndexedGeometryArray) {
146 return ((IndexedGeometryArray) geom).getIndexCount();
147 }
148 return geom.getVertexCount();
149 }
150
151 private Point3f[] renderForIndexedGeometryArray(IndexedGeometryArray geom, float scale) {
152 Point3f[] vertices;
153 Vector3f[] normals;
154 if ((geom.getVertexFormat() & GeometryArray.BY_REFERENCE) != GeometryArray.BY_REFERENCE) {
155 vertices = new Point3f[geom.getVertexCount()];
156 normals = new Vector3f[geom.getVertexCount()];
157
158 for (int i = 0; i < geom.getVertexCount(); i++) {
159 vertices[i] = new Point3f();
160 normals[i] = new Vector3f();
161 }
162 geom.getCoordinates(0, vertices);
163 geom.getNormals(0, normals);
164 } else {
165 vertices = geom.getCoordRef3f();
166 normals = geom.getNormalRef3f();
167 }
168 if (DEBUG) {
169 System.out.println("vnum = " + vertices.length);
170 System.out.println("nnum = " + normals.length);
171 }
172 int size = geom.getIndexCount();
173 int[] coords = new int[size];
174 int[] normls = new int[size];
175 if (this.reset) {
176 this.nvertices = new Point3f[size * 2];
177 }
178 geom.getCoordinateIndices(0, coords);
179 geom.getNormalIndices(0, normls);
180 int n = 0;
181 for (int i = 0; i < size; i++ ) {
182 this.nvertices[n++] = new Point3f(vertices[coords[i]]);
183 this.nvertices[n++] = new Point3f(vertices[coords[i]].x +
184 scale * normals[normls[i]].x,
185 vertices[coords[i]].y +
186 scale * normals[normls[i]].y,
187 vertices[coords[i]].z +
188 scale * normals[normls[i]].z);
189 }
190 return this.nvertices;
191 }
192
193 private Point3f[] renderForGeometryArray(GeometryArray geom, float scale) {
194 Point3f[] vertices;
195 Vector3f[] normals;
196
197 if ((geom.getVertexFormat() & GeometryArray.BY_REFERENCE) != GeometryArray.BY_REFERENCE) {
198 vertices = new Point3f[geom.getVertexCount()];
199 normals = new Vector3f[geom.getVertexCount()];
200
201 for (int i = 0; i < geom.getVertexCount(); i++) {
202 vertices[i] = new Point3f();
203 normals[i] = new Vector3f();
204 }
205 geom.getCoordinates(0, vertices);
206 geom.getNormals(0, normals);
207 } else {
208 vertices = geom.getCoordRef3f();
209 normals = geom.getNormalRef3f();
210 }
211 if (this.reset) {
212 this.nvertices = new Point3f[vertices.length * 2];
213 }
214 int n = 0;
215 for (int i = 0; i < vertices.length; i++ ) {
216 this.nvertices[n++] = new Point3f(vertices[i]);
217 this.nvertices[n++] = new Point3f(vertices[i].x + scale * normals[i].x,
218 vertices[i].y + scale * normals[i].y,
219 vertices[i].z + scale * normals[i].z );
220 }
221 return this.nvertices;
222 }
223
224 private void setCapabilities(GeometryArray geom) {
225 if (geom != null) {
226 geom.setCapability(GeometryArray.ALLOW_FORMAT_READ);
227 geom.setCapability(GeometryArray.ALLOW_COUNT_READ);
228 geom.setCapability(GeometryArray.ALLOW_COORDINATE_READ);
229 geom.setCapability(GeometryArray.ALLOW_COORDINATE_WRITE);
230 geom.setCapability(GeometryArray.ALLOW_NORMAL_READ);
231 geom.setCapability(GeometryArray.ALLOW_NORMAL_WRITE);
232 geom.setCapability(GeometryArray.ALLOW_REF_DATA_WRITE);
233 }
234 }
235 }