001: /*
002: * $RCSfile: Appearance.java,v $
003: *
004: * @(#)Appearance.java 1.31 99/03/09 17:02:07
005: *
006: * Copyright (c) 1996-1998 Sun Microsystems, Inc. All Rights Reserved.
007: *
008: * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
009: * modify and redistribute this software in source and binary code form,
010: * provided that i) this copyright notice and license appear on all copies of
011: * the software; and ii) Licensee does not utilize the software in a manner
012: * which is disparaging to Sun.
013: *
014: * This software is provided "AS IS," without a warranty of any kind. ALL
015: * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
016: * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
017: * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
018: * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
019: * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
020: * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
021: * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
022: * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
023: * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
024: * POSSIBILITY OF SUCH DAMAGES.
025: *
026: * This software is not designed or intended for use in on-line control of
027: * aircraft, air traffic, aircraft navigation or aircraft communications; or in
028: * the design, construction, operation or maintenance of any nuclear
029: * facility. Licensee represents and warrants that it will not use or
030: * redistribute the Software for such purposes.
031: *
032: * $Revision: 1.5 $
033: * $Date: 2006/04/03 12:43:39 $
034: * $State: Exp $
035: */
036: /*
037: *
038: * @author Rick Goldberg
039: * @author Doug Gehringer
040: * @author Nikolai V. Chr.
041: *
042: */
043: package org.jdesktop.j3d.loaders.vrml97.impl;
044:
045: import javax.media.j3d.BoundingBox;
046: import javax.media.j3d.TexCoordGeneration;
047: import javax.media.j3d.Texture;
048: import javax.media.j3d.Transform3D;
049: import javax.media.j3d.TransparencyAttributes;
050:
051: import java.beans.*;
052:
053: import javax.vecmath.Point3d;
054: import javax.vecmath.Vector3d;
055: import javax.vecmath.Vector4f;
056:
057: /** Description of the Class */
058: public class Appearance extends Node {
059:
060: javax.media.j3d.Appearance impl;
061:
062: // exposedField
063: SFNode material;// all default NULL
064: SFNode texture;
065: SFNode textureTransform;
066:
067: TransparencyAttributes implTransp = null;
068: private TransparencyListener listener = new TransparencyListener();
069:
070: class TransparencyListener implements PropertyChangeListener {
071: Material material = null;
072: ImageTexture texture = null;
073:
074: public void setMaterial(Material m) {
075: if (m != material) {
076: if (material != null) {
077: material.removePropertyChangeListener(
078: Material.TRANSPARENCY, this );
079: material = null;
080: }
081: material = m;
082: if (m != null) {
083: m.addPropertyChangeListener(Material.TRANSPARENCY,
084: this );
085: }
086: }
087: }
088:
089: public void setTexture(TextureSrc t) {
090: if (t != texture) {
091: if (texture != null) {
092: texture.removePropertyChangeListener(
093: ImageTexture.TRANSPARENCY, this );
094: texture = null;
095: }
096: if (t instanceof ImageTexture) {
097: texture = (ImageTexture) t;
098: if (t != null) {
099: texture.addPropertyChangeListener(
100: ImageTexture.TRANSPARENCY, this );
101: }
102: }
103: }
104: }
105:
106: public void propertyChange(PropertyChangeEvent e) {
107: updateTransparency();
108: }
109: };
110:
111: boolean haveTexture = false;
112: int numUses = 0;
113: TexCoordGeneration texGen;
114: javax.media.j3d.TextureAttributes ta = new javax.media.j3d.TextureAttributes();
115: Transform3D tr = new Transform3D();
116: Transform3D T = new Transform3D();
117: Transform3D C = new Transform3D();
118: Transform3D R = new Transform3D();
119: Transform3D S = new Transform3D();
120: Vector3d v1 = new Vector3d();
121: Vector3d v2 = new Vector3d();
122: Vector3d v3 = new Vector3d();
123: Vector3d v4 = new Vector3d();
124: javax.vecmath.AxisAngle4f al = new javax.vecmath.AxisAngle4f();
125:
126: /**
127: *Constructor for the Appearance object
128: *
129: *@param loader Description of the Parameter
130: */
131: public Appearance(Loader loader) {
132: super (loader);
133: material = new SFNode(null);
134: texture = new SFNode(null);
135: textureTransform = new SFNode(null);
136: initFields();
137: }
138:
139: /**
140: *Constructor for the Appearance object
141: *
142: *@param loader Description of the Parameter
143: *@param material Description of the Parameter
144: *@param texture Description of the Parameter
145: *@param textureTransform Description of the Parameter
146: */
147: Appearance(Loader loader, SFNode material, SFNode texture,
148: SFNode textureTransform) {
149: super (loader);
150: this .material = material;
151: this .texture = texture;
152: this .textureTransform = textureTransform;
153: initFields();
154: }
155:
156: /** Description of the Method */
157: private void updateMaterial() {
158: listener.setMaterial((Material) material.node);
159: updateTransparency();
160: if (material.node == null) {
161: //impl.setLightingEnable(false);
162: } else {
163: impl.setMaterial(((Material) material.node).impl);
164: //impl.setLightingEnable(true);
165: }
166: }
167:
168: /** Description of the Method */
169: private void updateTexture() {
170: haveTexture = false;
171: if (texture.node != null) {
172: Texture tex = ((TextureSrc) texture.node).getImplTexture();
173: if (tex != null) {
174: impl.setTexture(tex);
175: tex.setEnable(true);
176: haveTexture = true;
177: }
178: }
179: listener.setTexture((TextureSrc) texture.node);
180: updateTransparency();
181: }
182:
183: public void updateTransparency() {
184: if (loader.debug) {
185: System.out.print(toStringId() + ": Updating transparency ");
186: }
187: boolean transparent = false;
188: float value = 0.0f;
189: if (material != null && material.node != null) {
190: value = ((Material) material.node).getTransparency();
191: transparent = value > 0.0f;
192: if (loader.debug) {
193: System.out.print(" Material=" + value);
194: }
195: }
196: if (texture != null && texture.node != null
197: && texture.node instanceof ImageTexture) {
198: transparent = transparent
199: || ((ImageTexture) texture.node).getTransparency();
200: if (loader.debug) {
201: System.out.print(" Texture="
202: + ((ImageTexture) texture.node)
203: .getTransparency());
204: }
205: }
206: if (loader.debug) {
207: System.out.println(" Result=" + transparent);
208: }
209: int mode;
210: if (transparent) {
211: mode = TransparencyAttributes.NICEST;
212: } else {
213: mode = TransparencyAttributes.NONE;
214: }
215: if (implTransp == null) {
216: implTransp = new TransparencyAttributes(mode, value);
217: implTransp
218: .setCapability(javax.media.j3d.TransparencyAttributes.ALLOW_MODE_WRITE);
219: implTransp
220: .setCapability(javax.media.j3d.TransparencyAttributes.ALLOW_VALUE_WRITE);
221: } else {
222: implTransp.setTransparency(value);
223: implTransp.setTransparencyMode(mode);
224: }
225: impl.setTransparencyAttributes(implTransp);
226: }
227:
228: /** Description of the Method */
229: void updateTextureTransform() {
230: if (textureTransform.node != null) {
231: // need to notify Appearance for this case
232: ((TextureTransform) textureTransform.node).owner = this ;
233: double cx;
234: double cy;
235: double tx;
236: double ty;
237: double r;
238: double sx;
239: double sy;
240:
241: // implemented for readability, several steps are can be
242: // optimized away
243:
244: TextureTransform tf = (TextureTransform) textureTransform.node;
245:
246: tx = tf.translation.vec2f[0];
247: ty = tf.translation.vec2f[0];
248: v1.set(tx, ty, 0.0);
249: T.set(v1);
250:
251: cx = tf.center.vec2f[0];
252: cy = tf.center.vec2f[1];
253: v2.set(cx, cy, 0.0);
254: C.set(v2);
255:
256: r = tf.rotation.value;
257: al.set(0.0f, 0.0f, 1.0f, (float) r);
258: R.setRotation(al);
259:
260: sx = tf.scale.vec2f[0];
261: sy = tf.scale.vec2f[1];
262: v3.set(sx, sy, 1.0);
263: S.setScale(v3);
264:
265: tr.setIdentity();
266: tr.mul(T);
267: tr.mul(C);
268: tr.mul(R);
269: tr.mul(S);
270: v2.negate();
271: C.set(v2);
272: tr.mul(C);
273:
274: ta.setTextureTransform(tr);
275: impl.setTextureAttributes(ta);
276: }
277: ta.setTextureMode(ta.COMBINE);
278: ta.setCombineAlphaMode(ta.COMBINE_MODULATE);
279: ta.setCombineRgbMode(ta.COMBINE_REPLACE);
280: ta.setCombineAlphaSource(0, ta.COMBINE_OBJECT_COLOR);
281: ta.setCombineAlphaSource(1, ta.COMBINE_TEXTURE_COLOR);
282: ta.setCombineRgbSource(0, ta.COMBINE_TEXTURE_COLOR);
283: impl.setTextureAttributes(ta);
284: }
285:
286: /**
287: * Sets the texGen attribute of the Appearance object
288: *
289: *@param box The new texGen value
290: */
291: public void setTexGen(BoundingBox box) {
292:
293: Point3d min = new Point3d();
294: Point3d max = new Point3d();
295:
296: box.getLower(min);
297: box.getUpper(max);
298:
299: float xRange = (float) (max.x - min.x);
300: float yRange = (float) (max.y - min.y);
301: float zRange = (float) (max.z - min.z);
302: Vector4f sEq;
303: Vector4f tEq;
304: Vector4f xEq = new Vector4f(1.0f / xRange, 0.0f, 0.0f,
305: (float) -min.x / xRange);
306: Vector4f yEq = new Vector4f(0.0f, 1.0f / yRange, 0.0f,
307: (float) -min.y / xRange);
308: Vector4f zEq = new Vector4f(0.0f, 0.0f, 1.0f / zRange,
309: (float) -min.z / xRange);
310:
311: // handle the S mapping which is to the largest
312: if (xRange >= yRange) {
313: if (xRange >= zRange) {
314: sEq = xEq;
315: if (yRange >= zRange) {
316: tEq = yEq;
317: } else {
318: tEq = zEq;
319: }
320: } else {// z is max
321: sEq = zEq;
322: tEq = xEq;// x > y
323: }
324: } else {// y > x
325: if (yRange >= zRange) {
326: sEq = yEq;
327: if (xRange >= zRange) {
328: tEq = xEq;
329: } else {
330: tEq = zEq;
331: }
332: } else {// z is max
333: sEq = zEq;
334: tEq = yEq;// y > x
335: }
336: }
337: texGen = new TexCoordGeneration(
338: TexCoordGeneration.OBJECT_LINEAR,
339: TexCoordGeneration.TEXTURE_COORDINATE_2, sEq, tEq);
340: impl.setTexCoordGeneration(texGen);
341: texGen.setEnable(true);
342: }
343:
344: /** Description of the Method */
345: public void initImpl() {
346: impl = new javax.media.j3d.Appearance();
347: updateMaterial();
348: updateTexture();
349: updateTextureTransform();
350: implReady = true;
351: }
352:
353: /**
354: * Description of the Method
355: *
356: *@param eventInName Description of the Parameter
357: *@param time Description of the Parameter
358: */
359: public void notifyMethod(String eventInName, double time) {
360: if (eventInName.equals("material")) {
361: updateMaterial();
362: } else if (eventInName.equals("texture")) {
363: updateTexture();
364: } else if (eventInName.equals("textureTransform")) {
365: if (textureTransform.node != null) {
366: System.err.println("Appearance: textureTransform not "
367: + "implemented");
368: }
369: } else if (eventInName.equals("route_material")) {
370: impl
371: .setCapability(javax.media.j3d.Appearance.ALLOW_MATERIAL_WRITE);
372: } else if (eventInName.equals("route_texture")) {
373: impl
374: .setCapability(javax.media.j3d.Appearance.ALLOW_TEXTURE_WRITE);
375: } else if (eventInName.equals("route_textureTransform")) {
376: impl
377: .setCapability(javax.media.j3d.Appearance.ALLOW_TEXTURE_ATTRIBUTES_WRITE);
378: } else {
379: System.err.println("Appearance: unknown eventInName "
380: + eventInName);
381: }
382: }
383:
384: /**
385: * Description of the Method
386: *
387: *@return Description of the Return Value
388: */
389: public Object clone() {
390: Appearance a = new Appearance(loader,
391: (SFNode) material.clone(), (SFNode) texture.clone(),
392: (SFNode) textureTransform.clone());
393: return a;
394: }
395:
396: /**
397: * Gets the type attribute of the Appearance object
398: *
399: *@return The type value
400: */
401: public String getType() {
402: return "Appearance";
403: }
404:
405: /** Description of the Method */
406: void initFields() {
407: material.init(this , FieldSpec, Field.EXPOSED_FIELD, "material");
408: texture.init(this , FieldSpec, Field.EXPOSED_FIELD, "texture");
409: textureTransform.init(this , FieldSpec, Field.EXPOSED_FIELD,
410: "textureTransform");
411: }
412:
413: }
|