001: /*
002: * $RCSfile: TexCoordGenerationRetained.java,v $
003: *
004: * Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
006: *
007: * This code is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU General Public License version 2 only, as
009: * published by the Free Software Foundation. Sun designates this
010: * particular file as subject to the "Classpath" exception as provided
011: * by Sun in the LICENSE file that accompanied this code.
012: *
013: * This code is distributed in the hope that it will be useful, but WITHOUT
014: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
015: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
016: * version 2 for more details (a copy is included in the LICENSE file that
017: * accompanied this code).
018: *
019: * You should have received a copy of the GNU General Public License version
020: * 2 along with this work; if not, write to the Free Software Foundation,
021: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
022: *
023: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
024: * CA 95054 USA or visit www.sun.com if you need additional information or
025: * have any questions.
026: *
027: * $Revision: 1.7 $
028: * $Date: 2008/02/28 20:17:31 $
029: * $State: Exp $
030: */
031:
032: package javax.media.j3d;
033:
034: import javax.vecmath.Vector4f;
035: import java.util.ArrayList;
036:
037: /**
038: * The TexCoordGeneration object contains all parameters needed for texture
039: * coordinate generation. It is included as part of an Appearance
040: * component object.
041: */
042: class TexCoordGenerationRetained extends NodeComponentRetained {
043:
044: // A list of pre-defined bits to indicate which component
045: // in this TexCoordGeneration object changed.
046: private static final int ENABLE_CHANGED = 0x01;
047: private static final int PLANE_S_CHANGED = 0x02;
048: private static final int PLANE_T_CHANGED = 0x04;
049: private static final int PLANE_R_CHANGED = 0x08;
050: private static final int PLANE_Q_CHANGED = 0x10;
051:
052: //
053: // State variables
054: //
055: int genMode = TexCoordGeneration.OBJECT_LINEAR;
056: int format = TexCoordGeneration.TEXTURE_COORDINATE_2;
057:
058: Vector4f planeS = new Vector4f(1.0f, 0.0f, 0.0f, 0.0f);
059: Vector4f planeT = new Vector4f(0.0f, 1.0f, 0.0f, 0.0f);
060: Vector4f planeR = new Vector4f(0.0f, 0.0f, 0.0f, 0.0f);
061: Vector4f planeQ = new Vector4f(0.0f, 0.0f, 0.0f, 0.0f);
062:
063: /**
064: * Flag to enable/disable Texture coordinate generation.
065: */
066: boolean enable = true;
067:
068: // true when mirror texCoord component set
069: boolean mirrorCompDirty = false;
070:
071: /**
072: * Enables or disables texture coordinate generation for this
073: * appearance component object.
074: * @param state true or false to enable or disable texture coordinate
075: * generation
076: */
077: final void initEnable(boolean state) {
078: enable = state;
079: }
080:
081: /**
082: * Enables or disables texture coordinate generation for this
083: * appearance component object and sends a message notifying
084: * the interested structures of the change.
085: * @param state true or false to enable or disable texture coordinate
086: * generation
087: */
088: final void setEnable(boolean state) {
089: initEnable(state);
090: sendMessage(ENABLE_CHANGED, (state ? Boolean.TRUE
091: : Boolean.FALSE));
092: }
093:
094: /**
095: * Retrieves the state of the texCoordGeneration enable flag.
096: * @return true if texture coordinate generation is enabled,
097: * false if texture coordinate generation is disabled
098: */
099: final boolean getEnable() {
100: return enable;
101: }
102:
103: /**
104: * Sets the TexCoordGeneration format to the specified value.
105: * @param format texture format, one of: TEXTURE_COORDINATE_2
106: * or TEXTURE_COORDINATE_3
107: */
108: final void initFormat(int format) {
109: this .format = format;
110: }
111:
112: /**
113: * Retrieves the current TexCoordGeneration format.
114: * @return the texture format
115: */
116: final int getFormat() {
117: return format;
118: }
119:
120: /**
121: * Sets the TexCoordGeneration generation mode to the specified value.
122: * @param genMode texture generation mode, one of: OBJECT_LINEAR,
123: * EYE_LINEAR, or SPHERE_MAP
124: */
125: final void initGenMode(int genMode) {
126: this .genMode = genMode;
127: }
128:
129: /**
130: * Retrieves the current TexCoordGeneration generation mode.
131: * @return the texture generation mode
132: */
133: final int getGenMode() {
134: return genMode;
135: }
136:
137: /**
138: * Sets the S coordinate plane equation. This plane equation
139: * is used to generate the S coordinate in OBJECT_LINEAR and EYE_LINEAR
140: * texture generation modes.
141: * @param planeS plane equation for the S coordinate
142: */
143: final void setPlaneS(Vector4f planeS) {
144: initPlaneS(planeS);
145: sendMessage(PLANE_S_CHANGED, new Vector4f(planeS));
146: }
147:
148: /**
149: * Sets the S coordinate plane equation. This plane equation
150: * is used to generate the S coordinate in OBJECT_LINEAR and EYE_LINEAR
151: * texture generation modes.
152: * @param planeS plane equation for the S coordinate
153: */
154: final void initPlaneS(Vector4f planeS) {
155: this .planeS.set(planeS);
156: }
157:
158: /**
159: * Retrieves a copy of the plane equation used to
160: * generate the S coordinate.
161: * @param planeS the S coordinate plane equation
162: */
163: final void getPlaneS(Vector4f planeS) {
164: planeS.set(this .planeS);
165: }
166:
167: /**
168: * Sets the T coordinate plane equation. This plane equation
169: * is used to generate the T coordinate in OBJECT_LINEAR and EYE_LINEAR
170: * texture generation modes.
171: * @param planeT plane equation for the T coordinate
172: */
173: final void setPlaneT(Vector4f planeT) {
174: initPlaneT(planeT);
175: sendMessage(PLANE_T_CHANGED, new Vector4f(planeT));
176: }
177:
178: /**
179: * Sets the T coordinate plane equation. This plane equation
180: * is used to generate the T coordinate in OBJECT_LINEAR and EYE_LINEAR
181: * texture generation modes.
182: * @param planeT plane equation for the T coordinate
183: */
184: final void initPlaneT(Vector4f planeT) {
185: this .planeT.set(planeT);
186: }
187:
188: /**
189: * Retrieves a copy of the plane equation used to
190: * generate the T coordinate.
191: * @param planeT the T coordinate plane equation
192: */
193: final void getPlaneT(Vector4f planeT) {
194: planeT.set(this .planeT);
195: }
196:
197: /**
198: * Sets the R coordinate plane equation. This plane equation
199: * is used to generate the R coordinate in OBJECT_LINEAR and EYE_LINEAR
200: * texture generation modes.
201: * @param planeR plane equation for the R coordinate
202: */
203: final void setPlaneR(Vector4f planeR) {
204: initPlaneR(planeR);
205: sendMessage(PLANE_R_CHANGED, new Vector4f(planeR));
206: }
207:
208: /**
209: * Sets the R coordinate plane equation. This plane equation
210: * is used to generate the R coordinate in OBJECT_LINEAR and EYE_LINEAR
211: * texture generation modes.
212: * @param planeR plane equation for the R coordinate
213: */
214: final void initPlaneR(Vector4f planeR) {
215: this .planeR.set(planeR);
216: }
217:
218: /**
219: * Retrieves a copy of the plane equation used to
220: * generate the R coordinate.
221: * @param planeR the R coordinate plane equation
222: */
223: final void getPlaneR(Vector4f planeR) {
224: planeR.set(this .planeR);
225: }
226:
227: /**
228: * Sets the Q coordinate plane equation. This plane equation
229: * is used to generate the Q coordinate in OBJECT_LINEAR and EYE_LINEAR
230: * texture generation modes.
231: * @param planeQ plane equation for the Q coordinate
232: */
233: final void setPlaneQ(Vector4f planeQ) {
234: initPlaneQ(planeQ);
235: sendMessage(PLANE_Q_CHANGED, new Vector4f(planeQ));
236: }
237:
238: /**
239: * Sets the Q coordinate plane equation. This plane equation
240: * is used to generate the Q coordinate in OBJECT_LINEAR and EYE_LINEAR
241: * texture generation modes.
242: * @param planeQ plane equation for the Q coordinate
243: */
244: final void initPlaneQ(Vector4f planeQ) {
245: this .planeQ.set(planeQ);
246: }
247:
248: /**
249: * Retrieves a copy of the plane equation used to
250: * generate the Q coordinate.
251: * @param planeQ the Q coordinate plane equation
252: */
253: final void getPlaneQ(Vector4f planeQ) {
254: planeQ.set(this .planeQ);
255: }
256:
257: /**
258: * Creates a mirror object, point the mirror object to the retained
259: * object if the object is not editable
260: */
261: synchronized void createMirrorObject() {
262: if (mirror == null) {
263: // Check the capability bits and let the mirror object
264: // point to itself if is not editable
265: if (isStatic()) {
266: mirror = this ;
267: } else {
268: TexCoordGenerationRetained mirrorTg = new TexCoordGenerationRetained();
269: mirrorTg.set(this );
270: mirrorTg.source = source;
271: mirror = mirrorTg;
272: }
273: } else {
274: ((TexCoordGenerationRetained) mirror).set(this );
275: }
276: }
277:
278: void updateNative(Canvas3D cv) {
279: int gMode = genMode;
280: Transform3D trans = null;
281: Transform3D m = cv.vworldToEc;
282:
283: if (((cv.textureExtendedFeatures & Canvas3D.TEXTURE_CUBE_MAP) == 0)
284: && ((genMode == TexCoordGeneration.NORMAL_MAP) || (genMode == TexCoordGeneration.REFLECTION_MAP))) {
285: gMode = TexCoordGeneration.SPHERE_MAP;
286: }
287:
288: if (VirtualUniverse.mc.isD3D()
289: && (gMode == TexCoordGeneration.EYE_LINEAR)) {
290: trans = new Transform3D(cv.vworldToEc);
291: trans.invert();
292: m = trans;
293: }
294:
295: Pipeline.getPipeline().updateTexCoordGeneration(cv.ctx, enable,
296: gMode, format, planeS.x, planeS.y, planeS.z, planeS.w,
297: planeT.x, planeT.y, planeT.z, planeT.w, planeR.x,
298: planeR.y, planeR.z, planeR.w, planeQ.x, planeQ.y,
299: planeQ.z, planeQ.w, m.mat);
300: }
301:
302: /**
303: * Initializes a mirror object, point the mirror object to the retained
304: * object if the object is not editable
305: */
306: synchronized void initMirrorObject() {
307: ((TexCoordGenerationRetained) mirror).set(this );
308: }
309:
310: /** Update the "component" field of the mirror object with the
311: * given "value"
312: */
313: synchronized void updateMirrorObject(int component, Object value) {
314:
315: TexCoordGenerationRetained mirrorTc = (TexCoordGenerationRetained) mirror;
316:
317: mirrorTc.mirrorCompDirty = true;
318:
319: if ((component & ENABLE_CHANGED) != 0) {
320: mirrorTc.enable = ((Boolean) value).booleanValue();
321: } else if ((component & PLANE_S_CHANGED) != 0) {
322: mirrorTc.planeS = (Vector4f) value;
323: } else if ((component & PLANE_T_CHANGED) != 0) {
324: mirrorTc.planeT = (Vector4f) value;
325: } else if ((component & PLANE_R_CHANGED) != 0) {
326: mirrorTc.planeR = (Vector4f) value;
327: } else if ((component & PLANE_Q_CHANGED) != 0) {
328: mirrorTc.planeQ = (Vector4f) value;
329: }
330: }
331:
332: boolean equivalent(TexCoordGenerationRetained tr) {
333:
334: if (tr == null) {
335: return (false);
336:
337: } else if ((this .changedFrequent != 0)
338: || (tr.changedFrequent != 0)) {
339: return (this == tr);
340: }
341:
342: return ((tr.genMode == genMode) && (tr.format == format)
343: && (tr.enable == enable) && tr.planeS.equals(planeS)
344: && tr.planeT.equals(planeT) && tr.planeR.equals(planeR));
345: }
346:
347: protected Object clone() {
348: TexCoordGenerationRetained tr = (TexCoordGenerationRetained) super
349: .clone();
350: tr.planeS = new Vector4f(planeS);
351: tr.planeT = new Vector4f(planeT);
352: tr.planeR = new Vector4f(planeR);
353: // other attributes is copied in super.clone()
354: return tr;
355:
356: }
357:
358: protected void set(TexCoordGenerationRetained tr) {
359: super .set(tr);
360: genMode = tr.genMode;
361: format = tr.format;
362: enable = tr.enable;
363: planeS.set(tr.planeS);
364: planeT.set(tr.planeT);
365: planeR.set(tr.planeR);
366: }
367:
368: final void sendMessage(int attrMask, Object attr) {
369:
370: ArrayList univList = new ArrayList();
371: ArrayList gaList = Shape3DRetained.getGeomAtomsList(
372: mirror.users, univList);
373:
374: // Send to rendering attribute structure, regardless of
375: // whether there are users or not (alternate appearance case ..)
376: J3dMessage createMessage = new J3dMessage();
377: createMessage.threads = J3dThread.UPDATE_RENDERING_ATTRIBUTES;
378: createMessage.type = J3dMessage.TEXCOORDGENERATION_CHANGED;
379: createMessage.universe = null;
380: createMessage.args[0] = this ;
381: createMessage.args[1] = new Integer(attrMask);
382: createMessage.args[2] = attr;
383: createMessage.args[3] = new Integer(changedFrequent);
384: VirtualUniverse.mc.processMessage(createMessage);
385:
386: // System.err.println("univList.size is " + univList.size());
387: for (int i = 0; i < univList.size(); i++) {
388: createMessage = new J3dMessage();
389: createMessage.threads = J3dThread.UPDATE_RENDER;
390: createMessage.type = J3dMessage.TEXCOORDGENERATION_CHANGED;
391:
392: createMessage.universe = (VirtualUniverse) univList.get(i);
393: createMessage.args[0] = this ;
394: createMessage.args[1] = new Integer(attrMask);
395: createMessage.args[2] = attr;
396:
397: ArrayList gL = (ArrayList) gaList.get(i);
398: GeometryAtom[] gaArr = new GeometryAtom[gL.size()];
399: gL.toArray(gaArr);
400: createMessage.args[3] = gaArr;
401:
402: VirtualUniverse.mc.processMessage(createMessage);
403: }
404: }
405:
406: void handleFrequencyChange(int bit) {
407: switch (bit) {
408: case TexCoordGeneration.ALLOW_ENABLE_WRITE:
409: case TexCoordGeneration.ALLOW_PLANE_WRITE: {
410: setFrequencyChangeMask(bit, bit);
411: }
412: default:
413: break;
414: }
415: }
416: }
|