001: /*
002: * $RCSfile: MaterialRetained.java,v $
003: *
004: * Copyright 1997-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.6 $
028: * $Date: 2008/02/28 20:17:26 $
029: * $State: Exp $
030: */
031:
032: package javax.media.j3d;
033:
034: import javax.vecmath.Color3f;
035: import java.util.ArrayList;
036:
037: /**
038: * The MaterialRetained object defines the appearance of an object under
039: * illumination.
040: */
041: class MaterialRetained extends NodeComponentRetained {
042: // Initialize default values for all class variables
043: Color3f ambientColor = new Color3f(0.2f, 0.2f, 0.2f);
044: Color3f emissiveColor = new Color3f(0.0f, 0.0f, 0.0f);
045: Color3f diffuseColor = new Color3f(1.0f, 1.0f, 1.0f);
046: Color3f specularColor = new Color3f(1.0f, 1.0f, 1.0f);
047: float shininess = 64.0f;
048: int colorTarget = Material.DIFFUSE;
049:
050: // Lighting enable switch for this material object
051: boolean lightingEnable = true;
052:
053: // A list of pre-defined bits to indicate which component
054: // in this Material object changed.
055: static final int AMBIENT_COLOR_CHANGED = 0x01;
056:
057: static final int EMISSIVE_COLOR_CHANGED = 0x02;
058:
059: static final int DIFFUSE_COLOR_CHANGED = 0x04;
060:
061: static final int SPECULAR_COLOR_CHANGED = 0x08;
062:
063: static final int SHININESS_CHANGED = 0x10;
064:
065: static final int ENABLE_CHANGED = 0x20;
066:
067: static final int COLORTARGET_CHANGED = 0x40;
068:
069: /**
070: * Constructs and initializes a new material object using the specified
071: * parameters.
072: * @param ambientColor the material's ambient color
073: * @param emissiveColor the material's emissive color
074: * @param diffuseColor the material's diffuse color when illuminated by a
075: * light
076: * @param specularColor the material's specular color when illuminated
077: * to generate a highlight
078: * @param shininess the material's shininess in the
079: * range [1.0, 128.0] with 1.0 being not shiny and 128.0 being very shiny
080: */
081: void createMaterial(Color3f aColor, Color3f eColor, Color3f dColor,
082: Color3f sColor, float shine) {
083: ambientColor.set(aColor);
084: emissiveColor.set(eColor);
085: diffuseColor.set(dColor);
086: specularColor.set(sColor);
087: shininess = shine;
088: }
089:
090: /** Initializes this material's ambient color
091: * This specifies how much ambient light is reflected by
092: * the surface. The ambient light color is the product of this
093: * color and the material diffuseColor.
094: * @param color the material's ambient color
095: */
096: final void initAmbientColor(Color3f color) {
097: this .ambientColor.set(color);
098: }
099:
100: /**
101: * Sets this material's ambient color and sends a message notifying
102: * the interested structures of the change.
103: * This specifies how much ambient light is reflected by
104: * the surface. The ambient light color is the product of this
105: * color and the material diffuseColor.
106: * @param color the material's ambient color
107: */
108: final void setAmbientColor(Color3f color) {
109: initAmbientColor(color);
110: sendMessage(AMBIENT_COLOR_CHANGED, new Color3f(color));
111: }
112:
113: /**
114: * Sets this material's ambient color
115: * @param r the new ambient color's red component
116: * @param g the new ambient color's green component
117: * @param b the new ambient color's blue component
118: */
119: final void initAmbientColor(float r, float g, float b) {
120: this .ambientColor.set(r, g, b);
121: }
122:
123: /**
124: * Sets this material's ambient color and sends a message notifying
125: * the interested structures of the change.
126: * @param r the new ambient color's red component
127: * @param g the new ambient color's green component
128: * @param b the new ambient color's blue component
129: */
130: final void setAmbientColor(float r, float g, float b) {
131: initAmbientColor(r, g, b);
132: sendMessage(AMBIENT_COLOR_CHANGED, new Color3f(r, g, b));
133: }
134:
135: /**
136: * Retrieves this material's ambient color.
137: * @return the material's ambient color
138: */
139: final void getAmbientColor(Color3f color) {
140: color.set(this .ambientColor);
141: }
142:
143: /**
144: * Sets this material's emissive color
145: * This is the color of light, if any, that the material emits.
146: * @param color the new emissive color
147: */
148: final void initEmissiveColor(Color3f color) {
149: this .emissiveColor.set(color);
150: }
151:
152: /**
153: * Sets this material's emissive color and sends a message notifying
154: * the interested structures of the change.
155: * This is the color of light, if any, that the material emits.
156: * @param color the new emissive color
157: */
158: final void setEmissiveColor(Color3f color) {
159: initEmissiveColor(color);
160: sendMessage(EMISSIVE_COLOR_CHANGED, new Color3f(color));
161: }
162:
163: /**
164: * Sets this material's emissive color.
165: * This is the color of light, if any, that the material emits.
166: * @param r the new emissive color's red component
167: * @param g the new emissive color's green component
168: * @param b the new emissive color's blue component
169: */
170: final void initEmissiveColor(float r, float g, float b) {
171: this .emissiveColor.set(r, g, b);
172: }
173:
174: /**
175: * Sets this material's emissive color and sends a message notifying
176: * the interested structures of the change.
177: * This is the color of light, if any, that the material emits.
178: * @param r the new emissive color's red component
179: * @param g the new emissive color's green component
180: * @param b the new emissive color's blue component
181: */
182: final void setEmissiveColor(float r, float g, float b) {
183: initEmissiveColor(r, g, b);
184: sendMessage(EMISSIVE_COLOR_CHANGED, new Color3f(r, g, b));
185: }
186:
187: /**
188: * Retrieves this material's emissive color and stores it in the
189: * argument provided.
190: * @param color the vector that will receive this material's emissive color
191: */
192: final void getEmissiveColor(Color3f color) {
193: color.set(this .emissiveColor);
194: }
195:
196: /**
197: * Sets this material's diffuse color.
198: * This is the color of the material when illuminated by a light source.
199: * @param color the new diffuse color
200: */
201: final void initDiffuseColor(Color3f color) {
202: this .diffuseColor.set(color);
203: }
204:
205: /**
206: * Sets this material's diffuse color and sends a message notifying
207: * the interested structures of the change.
208: * This is the color of the material when illuminated by a light source.
209: * @param color the new diffuse color
210: */
211: final void setDiffuseColor(Color3f color) {
212: initDiffuseColor(color);
213: sendMessage(DIFFUSE_COLOR_CHANGED, new Color3f(color));
214: }
215:
216: /**
217: * Sets this material's diffuse color.
218: * @param r the new diffuse color's red component
219: * @param g the new diffuse color's green component
220: * @param b the new diffuse color's blue component
221: */
222: final void initDiffuseColor(float r, float g, float b) {
223: this .diffuseColor.set(r, g, b);
224: }
225:
226: /**
227: * Sets this material's diffuse color and sends a message notifying
228: * the interested structures of the change.
229: * @param r the new diffuse color's red component
230: * @param g the new diffuse color's green component
231: * @param b the new diffuse color's blue component
232: */
233: final void setDiffuseColor(float r, float g, float b) {
234: initDiffuseColor(r, g, b);
235: sendMessage(DIFFUSE_COLOR_CHANGED, new Color3f(r, g, b));
236: }
237:
238: /**
239: * Sets this material's diffuse color plus alpha.
240: * This is the color of the material when illuminated by a light source.
241: * @param r the new diffuse color's red component
242: * @param g the new diffuse color's green component
243: * @param b the new diffuse color's blue component
244: * @param a the alpha component used to set transparency
245: */
246: final void initDiffuseColor(float r, float g, float b, float a) {
247: this .diffuseColor.set(r, g, b);
248: }
249:
250: /**
251: * Sets this material's diffuse color plus alpha and sends
252: * a message notifying the interested structures of the change.
253: * This is the color of the material when illuminated by a light source.
254: * @param r the new diffuse color's red component
255: * @param g the new diffuse color's green component
256: * @param b the new diffuse color's blue component
257: * @param a the alpha component used to set transparency
258: */
259: final void setDiffuseColor(float r, float g, float b, float a) {
260: initDiffuseColor(r, g, b);
261: sendMessage(DIFFUSE_COLOR_CHANGED, new Color3f(r, g, b));
262: }
263:
264: /**
265: * Retrieves this material's diffuse color.
266: * @param color the vector that will receive this material's diffuse color
267: */
268: final void getDiffuseColor(Color3f color) {
269: color.set(this .diffuseColor);
270: }
271:
272: /**
273: * Sets this material's specular color.
274: * This is the specular highlight color of the material.
275: * @param color the new specular color
276: */
277: final void initSpecularColor(Color3f color) {
278: this .specularColor.set(color);
279: }
280:
281: /**
282: * Sets this material's specular color and sends a message notifying
283: * the interested structures of the change.
284: * This is the specular highlight color of the material.
285: * @param color the new specular color
286: */
287: final void setSpecularColor(Color3f color) {
288: initSpecularColor(color);
289: sendMessage(SPECULAR_COLOR_CHANGED, new Color3f(color));
290: }
291:
292: /**
293: * Sets this material's specular color.
294: * This is the specular highlight color of the material.
295: * @param r the new specular color's red component
296: * @param g the new specular color's green component
297: * @param b the new specular color's blue component
298: */
299: final void initSpecularColor(float r, float g, float b) {
300: this .specularColor.set(r, g, b);
301: }
302:
303: /**
304: * Sets this material's specular color and sends a message notifying
305: * the interested structures of the change.
306: * This is the specular highlight color of the material.
307: * @param r the new specular color's red component
308: * @param g the new specular color's green component
309: * @param b the new specular color's blue component
310: */
311: final void setSpecularColor(float r, float g, float b) {
312: initSpecularColor(r, g, b);
313: sendMessage(SPECULAR_COLOR_CHANGED, new Color3f(r, g, b));
314: }
315:
316: /**
317: * Retrieves this material's specular color.
318: * @param color the vector that will receive this material's specular color
319: */
320: final void getSpecularColor(Color3f color) {
321: color.set(this .specularColor);
322: }
323:
324: /**
325: * Sets this material's shininess.
326: * This specifies a material specular exponent, or shininess.
327: * It takes a floating point number in the range [1.0, 128.0]
328: * with 1.0 being not shiny and 128.0 being very shiny.
329: * @param shininess the material's shininess
330: */
331: final void initShininess(float shininess) {
332: // Clamp shininess value
333: if (shininess < 1.0f)
334: this .shininess = 1.0f;
335: else if (shininess > 128.0f)
336: this .shininess = 128.0f;
337: else
338: this .shininess = shininess;
339:
340: }
341:
342: /**
343: * Sets this material's shininess and sends a message notifying
344: * the interested structures of the change.
345: * This specifies a material specular exponent, or shininess.
346: * It takes a floating point number in the range [1.0, 128.0]
347: * with 1.0 being not shiny and 128.0 being very shiny.
348: * @param shininess the material's shininess
349: */
350: final void setShininess(float shininess) {
351: initShininess(shininess);
352: sendMessage(SHININESS_CHANGED, new Float(this .shininess));
353: }
354:
355: /**
356: * Retrieves this material's shininess.
357: * @return the material's shininess
358: */
359: final float getShininess() {
360: return this .shininess;
361: }
362:
363: /**
364: * Enables or disables lighting for this appearance component object.
365: * @param state true or false to enable or disable lighting
366: */
367: void initLightingEnable(boolean state) {
368: lightingEnable = state;
369: }
370:
371: /**
372: * Enables or disables lighting for this appearance component object
373: * and sends a message notifying
374: * the interested structures of the change.
375: * @param state true or false to enable or disable lighting
376: */
377: void setLightingEnable(boolean state) {
378: initLightingEnable(state);
379: sendMessage(ENABLE_CHANGED, (state ? Boolean.TRUE
380: : Boolean.FALSE));
381: }
382:
383: /**
384: * Retrieves the state of the lighting enable flag.
385: * @return true if lighting is enabled, false if lighting is disabled
386: */
387: boolean getLightingEnable() {
388: return lightingEnable;
389: }
390:
391: void initColorTarget(int colorTarget) {
392: this .colorTarget = colorTarget;
393: }
394:
395: final void setColorTarget(int colorTarget) {
396: initColorTarget(colorTarget);
397: sendMessage(COLORTARGET_CHANGED, new Integer(colorTarget));
398: }
399:
400: final int getColorTarget() {
401: return colorTarget;
402: }
403:
404: synchronized void createMirrorObject() {
405: if (mirror == null) {
406: // Check the capability bits and let the mirror object
407: // point to itself if is not editable
408: if (isStatic()) {
409: mirror = this ;
410: } else {
411: MaterialRetained mirrorMat = new MaterialRetained();
412: mirrorMat.set(this );
413: mirrorMat.source = source;
414: mirror = mirrorMat;
415: }
416: } else {
417: ((MaterialRetained) mirror).set(this );
418: }
419: }
420:
421: /**
422: * Updates the native context.
423: */
424: void updateNative(Context ctx, float red, float green, float blue,
425: float alpha, boolean enableLighting) {
426: Pipeline.getPipeline().updateMaterial(ctx, red, green, blue,
427: alpha, ambientColor.x, ambientColor.y, ambientColor.z,
428: emissiveColor.x, emissiveColor.y, emissiveColor.z,
429: diffuseColor.x, diffuseColor.y, diffuseColor.z,
430: specularColor.x, specularColor.y, specularColor.z,
431: shininess, colorTarget, enableLighting);
432: }
433:
434: /**
435: * Creates a mirror object, point the mirror object to the retained
436: * object if the object is not editable
437: */
438: synchronized void initMirrorObject() {
439: MaterialRetained mirrorMaterial = (MaterialRetained) mirror;
440: mirrorMaterial.set(this );
441: }
442:
443: /**
444: * Update the "component" field of the mirror object with the
445: * given "value"
446: */
447: synchronized void updateMirrorObject(int component, Object value) {
448: MaterialRetained mirrorMaterial = (MaterialRetained) mirror;
449: if ((component & AMBIENT_COLOR_CHANGED) != 0) {
450: mirrorMaterial.ambientColor = (Color3f) value;
451: } else if ((component & EMISSIVE_COLOR_CHANGED) != 0) {
452: mirrorMaterial.emissiveColor = (Color3f) value;
453: } else if ((component & DIFFUSE_COLOR_CHANGED) != 0) {
454: mirrorMaterial.diffuseColor = (Color3f) value;
455: } else if ((component & SPECULAR_COLOR_CHANGED) != 0) {
456: mirrorMaterial.specularColor = (Color3f) value;
457: } else if ((component & SHININESS_CHANGED) != 0) {
458: mirrorMaterial.shininess = ((Float) value).floatValue();
459: } else if ((component & ENABLE_CHANGED) != 0) {
460: mirrorMaterial.lightingEnable = ((Boolean) value)
461: .booleanValue();
462: } else if ((component & COLORTARGET_CHANGED) != 0) {
463: mirrorMaterial.colorTarget = ((Integer) value).intValue();
464: }
465:
466: }
467:
468: boolean equivalent(MaterialRetained m) {
469: return ((m != null) && lightingEnable == m.lightingEnable
470: && diffuseColor.equals(m.diffuseColor)
471: && emissiveColor.equals(m.emissiveColor)
472: && specularColor.equals(m.specularColor)
473: && ambientColor.equals(m.ambientColor)
474: && colorTarget == m.colorTarget && shininess == m.shininess);
475: }
476:
477: // This functions clones the retained side only and is used
478: // internally
479: protected Object clone() {
480: MaterialRetained mr = (MaterialRetained) super .clone();
481: // color can't share the same reference
482: mr.ambientColor = new Color3f(ambientColor);
483: mr.emissiveColor = new Color3f(emissiveColor);
484: mr.diffuseColor = new Color3f(diffuseColor);
485: mr.specularColor = new Color3f(specularColor);
486: // other attributes are copy by clone() automatically
487: return mr;
488: }
489:
490: protected void set(MaterialRetained mat) {
491: super .set(mat);
492:
493: // duplicate any referenced data
494: ambientColor.set(mat.ambientColor);
495: emissiveColor.set(mat.emissiveColor);
496: diffuseColor.set(mat.diffuseColor);
497: specularColor.set(mat.specularColor);
498: shininess = mat.shininess;
499: lightingEnable = mat.lightingEnable;
500: colorTarget = mat.colorTarget;
501: }
502:
503: final void sendMessage(int attrMask, Object attr) {
504: ArrayList univList = new ArrayList();
505: ArrayList gaList = Shape3DRetained.getGeomAtomsList(
506: mirror.users, univList);
507: // Send to rendering attribute structure, regardless of
508: // whether there are users or not (alternate appearance case ..)
509: J3dMessage createMessage = new J3dMessage();
510: createMessage.threads = J3dThread.UPDATE_RENDERING_ATTRIBUTES;
511: createMessage.type = J3dMessage.MATERIAL_CHANGED;
512: createMessage.universe = null;
513: createMessage.args[0] = this ;
514: createMessage.args[1] = new Integer(attrMask);
515: createMessage.args[2] = attr;
516: createMessage.args[3] = new Integer(changedFrequent);
517: VirtualUniverse.mc.processMessage(createMessage);
518:
519: int size = univList.size();
520: for (int i = 0; i < size; i++) {
521: createMessage = new J3dMessage();
522: createMessage.threads = J3dThread.UPDATE_RENDER;
523: createMessage.type = J3dMessage.MATERIAL_CHANGED;
524:
525: createMessage.universe = (VirtualUniverse) univList.get(i);
526: createMessage.args[0] = this ;
527: createMessage.args[1] = new Integer(attrMask);
528: createMessage.args[2] = attr;
529:
530: ArrayList gL = (ArrayList) gaList.get(i);
531: GeometryAtom[] gaArr = new GeometryAtom[gL.size()];
532: gL.toArray(gaArr);
533: createMessage.args[3] = gaArr;
534: VirtualUniverse.mc.processMessage(createMessage);
535: }
536:
537: }
538:
539: void handleFrequencyChange(int bit) {
540: if (bit == Material.ALLOW_COMPONENT_WRITE) {
541: setFrequencyChangeMask(Material.ALLOW_COMPONENT_WRITE, 0x1);
542: }
543: }
544: }
|