001: /*
002: * $RCSfile: RenderAtom.java,v $
003: *
004: * Copyright 1999-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.5 $
028: * $Date: 2008/02/28 20:17:28 $
029: * $State: Exp $
030: */
031:
032: package javax.media.j3d;
033:
034: import javax.vecmath.*;
035:
036: /**
037: * A RenderAtom is a wrapper for a GeometryAtom in a given RenderBin.
038: */
039:
040: class RenderAtom extends Object implements ObjectUpdate {
041: /**
042: * The geometry atom of this render atom
043: */
044: GeometryAtom geometryAtom = null;
045:
046: /**
047: * The RenderMolecule for this RenderAtom
048: */
049: RenderMolecule renderMolecule = null;
050:
051: /**
052: * The lights that influence this RenderAtom
053: */
054: LightRetained[] lights = null;
055:
056: /**
057: * The fog that influences this RenderAtom
058: */
059: FogRetained fog = null;
060:
061: /**
062: * The model clip that influences this RenderAtom
063: */
064: ModelClipRetained modelClip = null;
065:
066: /**
067: * The appearance that influences this RenderAtom
068: */
069: AppearanceRetained app = null;
070:
071: //
072: // Convert all boolean to a bitmask, saves memory since
073: // there are many RenderAtoms per view
074: //
075:
076: /**
077: * Indicates whether or not this object is in
078: * the render bin.
079: */
080: static int IN_RENDERBIN = 0x1;
081:
082: // True if the above localeVwcBounds is a local copy rather
083: // than a reference to the bounds in shape
084: static int HAS_SEPARATE_LOCALE_VWC_BOUNDS = 0x2;
085:
086: // true if one of the geometries not going to a display list, hence
087: // need to maintain a local localeVwcBounds in order to avoid
088: // conflict with the vwcBounds in shape which is CURRENT
089: // while the checking of localeVwcBounds in rendering time
090: // should be LAST. In order words, localeVwcBounds contain
091: // the last vwcBounds, whereas, shape.vwcBounds contain the
092: // current vwcBounds
093: //
094: static int NEED_SEPARATE_LOCALE_VWC_BOUNDS = 0x4;
095:
096: static int ON_UPDATELIST = 0x8;
097: static int ON_LOCALE_VWC_BOUNDS_UPDATELIST = 0x10;
098: // true if comes from Oriented Shape3D
099: static int IS_ORIENTED = 0x20;
100: // true if in dirty oriented render atom list
101: static int IN_DIRTY_ORIENTED_RAs = 0x40;
102:
103: // true if in dirty depth sort position list
104: static int IN_SORTED_POS_DIRTY_TRANSP_LIST = 0x80;
105:
106: // A bitmask for all the bit specified above in this renderAtom
107: int dirtyMask = 0;
108:
109: /**
110: * Environment set that this renderAtom belongs to, used
111: * to compare the new env set with the old one when the
112: * scoping/bounds of a light/fog changes
113: */
114: EnvironmentSet envSet;
115:
116: /**
117: * Used for non-text3d
118: */
119: BoundingBox localeVwcBounds = null;
120:
121: /**
122: * The last time this atom was reported visible
123: */
124: long lastVisibleTime = -1;
125:
126: /**
127: * Next and Previous references for the list of RenderAtoms
128: * groupType is a mask set to true if this renderAtom is part of the displaylist array
129: * of the renderMolecule
130: * One per geometry in the geometryArr in the geometryAtom, since
131: * each geometry in the geometryAtom can end up in a different
132: * atomList(primary, secondary, seperatedlist) of the renderMoceule
133: */
134: RenderAtomListInfo[] rListInfo;
135:
136: /**
137: * Used in depthSorted transparency, once per rInfo
138: */
139: TransparentRenderingInfo[] parentTInfo = null;
140:
141: /**
142: * Used when depth sorted transparecy is turned on
143: * one dlist per rinfo
144: */
145: int[] dlistIds = null;
146:
147: // One per geometry in the geometryArr in the geometryAtom
148: static int TEXT3D = 0x1;
149: static int DLIST = 0x2;
150: static int CG = 0x4;
151: static int OTHER = 0x8;
152: static int SEPARATE_DLIST_PER_GEO = 0x10;
153: static int VARRAY = 0x20;
154: static int SEPARATE_DLIST_PER_RINFO = 0x40;
155: static int PRIMARY = TEXT3D | DLIST | CG | OTHER
156: | SEPARATE_DLIST_PER_RINFO;
157:
158: // Rendermolecule to which its currently being added
159: RenderMolecule added = null;
160:
161: // Rendermolecule from which its currently being removed
162: RenderMolecule removed = null;
163:
164: // non-null, if part of the add list(for the next frame) in the renderMolecule
165: RenderAtom nextAdd = null;
166: RenderAtom prevAdd = null;
167:
168: // non-null, if part of the remove list(for the next frame) in the renderMolecule
169: RenderAtom nextRemove = null;
170: RenderAtom prevRemove = null;
171:
172: RenderAtom() {
173: }
174:
175: /**
176: * This sets the inRenderBin flag
177: */
178: synchronized void setRenderBin(boolean value) {
179: if (value == false) {
180: app = null;
181: dirtyMask &= ~IN_RENDERBIN;
182: dirtyMask &= ~ON_LOCALE_VWC_BOUNDS_UPDATELIST;
183: dirtyMask &= ~ON_UPDATELIST;
184: } else {
185: dirtyMask |= IN_RENDERBIN;
186: }
187:
188: }
189:
190: /**
191: * This returns whether or not this atom goes into the opaque
192: * light bin
193: */
194: boolean isOpaque() {
195: AppearanceRetained app = geometryAtom.source.appearance;
196:
197: if (app == null) {
198: return true;
199: }
200:
201: TransparencyAttributesRetained ta = app.transparencyAttributes;
202:
203: if (!VirtualUniverse.mc.isD3D()) {
204: // D3D doesn't support line/point antialiasing
205: switch (geometryAtom.geoType) {
206: case GeometryRetained.GEO_TYPE_POINT_SET:
207: case GeometryRetained.GEO_TYPE_INDEXED_POINT_SET:
208: if ((app.pointAttributes != null)
209: && app.pointAttributes.pointAntialiasing) {
210: return false;
211: }
212: break;
213: case GeometryRetained.GEO_TYPE_LINE_SET:
214: case GeometryRetained.GEO_TYPE_LINE_STRIP_SET:
215: case GeometryRetained.GEO_TYPE_INDEXED_LINE_SET:
216: case GeometryRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET:
217: if ((app.lineAttributes != null)
218: && app.lineAttributes.lineAntialiasing) {
219: return false;
220: }
221: break;
222: case GeometryRetained.GEO_TYPE_RASTER:
223: case GeometryRetained.GEO_TYPE_COMPRESSED:
224: break;
225: default:
226: if (app.polygonAttributes != null) {
227: if ((app.polygonAttributes.polygonMode == PolygonAttributes.POLYGON_POINT)
228: && (app.pointAttributes != null)
229: && app.pointAttributes.pointAntialiasing) {
230: return false;
231: } else if ((app.polygonAttributes.polygonMode == PolygonAttributes.POLYGON_LINE)
232: && (app.lineAttributes != null)
233: && app.lineAttributes.lineAntialiasing) {
234: return false;
235: }
236: }
237: break;
238: }
239:
240: return ((ta == null)
241: || (ta.transparencyMode == TransparencyAttributes.NONE) || (ta.transparencyMode == TransparencyAttributes.SCREEN_DOOR));
242: } else {
243: return ((ta == null) || (ta.transparencyMode == TransparencyAttributes.NONE));
244: }
245: }
246:
247: boolean inRenderBin() {
248: return ((dirtyMask & IN_RENDERBIN) != 0);
249: }
250:
251: boolean hasSeparateLocaleVwcBounds() {
252: return ((dirtyMask & HAS_SEPARATE_LOCALE_VWC_BOUNDS) != 0);
253: }
254:
255: boolean needSeparateLocaleVwcBounds() {
256: return ((dirtyMask & NEED_SEPARATE_LOCALE_VWC_BOUNDS) != 0);
257: }
258:
259: boolean onUpdateList() {
260: return ((dirtyMask & ON_UPDATELIST) != 0);
261: }
262:
263: boolean onLocaleVwcBoundsUpdateList() {
264: return ((dirtyMask & ON_LOCALE_VWC_BOUNDS_UPDATELIST) != 0);
265: }
266:
267: boolean isOriented() {
268: return ((dirtyMask & IS_ORIENTED) != 0);
269: }
270:
271: boolean inDepthSortList() {
272: return ((dirtyMask & IN_SORTED_POS_DIRTY_TRANSP_LIST) != 0);
273: }
274:
275: boolean inDirtyOrientedRAs() {
276: return ((dirtyMask & IN_DIRTY_ORIENTED_RAs) != 0);
277: }
278:
279: public void updateObject() {
280: if (inRenderBin()) {
281: int lastLVWIndex = renderMolecule.localToVworldIndex[NodeRetained.LAST_LOCAL_TO_VWORLD];
282:
283: for (int i = 0; i < rListInfo.length; i++) {
284: if (rListInfo[i].geometry() == null)
285: continue;
286:
287: if (geometryAtom.source.inBackgroundGroup) {
288: if (rListInfo[i].infLocalToVworld == null)
289: rListInfo[i].infLocalToVworld = new Transform3D();
290:
291: // to preserve the character transformation for Text3D atoms
292: renderMolecule.localToVworld[lastLVWIndex]
293: .getRotation(rListInfo[i].infLocalToVworld);
294: rListInfo[i].infLocalToVworld
295: .mul(geometryAtom.lastLocalTransformArray[i]);
296: } else {
297: rListInfo[i].localToVworld
298: .mul(
299: renderMolecule.localeLocalToVworld[lastLVWIndex],
300: geometryAtom.lastLocalTransformArray[i]);
301: }
302: }
303: }
304: dirtyMask &= ~ON_UPDATELIST;
305: }
306:
307: void updateOrientedTransform() {
308: int lastLVWIndex = renderMolecule.localToVworldIndex[NodeRetained.LAST_LOCAL_TO_VWORLD];
309: Transform3D orientedTransform = ((OrientedShape3DRetained) geometryAtom.source)
310: .getOrientedTransform(renderMolecule.renderBin.view.viewIndex);
311: for (int i = 0; i < rListInfo.length; i++) {
312:
313: if (geometryAtom.geoType == GeometryRetained.GEO_TYPE_TEXT3D
314: && geometryAtom.lastLocalTransformArray[i] != null) {
315: if (geometryAtom.source.inBackgroundGroup) {
316: if (rListInfo[i].infLocalToVworld == null)
317: rListInfo[i].infLocalToVworld = new Transform3D();
318:
319: rListInfo[i].infLocalToVworld
320: .mul(
321: renderMolecule.infLocalToVworld[lastLVWIndex],
322: orientedTransform);
323: rListInfo[i].infLocalToVworld
324: .mul(geometryAtom.lastLocalTransformArray[i]);
325: } else {
326: rListInfo[i].localToVworld
327: .mul(
328: renderMolecule.localeLocalToVworld[lastLVWIndex],
329: orientedTransform);
330: rListInfo[i].localToVworld
331: .mul(geometryAtom.lastLocalTransformArray[i]);
332: }
333: } else {
334: if (geometryAtom.source.inBackgroundGroup) {
335: if (rListInfo[i].infLocalToVworld == null)
336: rListInfo[i].infLocalToVworld = new Transform3D();
337:
338: rListInfo[i].infLocalToVworld
339: .mul(
340: renderMolecule.infLocalToVworld[lastLVWIndex],
341: orientedTransform);
342: } else {
343: rListInfo[i].localToVworld
344: .mul(
345: renderMolecule.localeLocalToVworld[lastLVWIndex],
346: orientedTransform);
347: }
348: }
349: }
350: }
351:
352: // updateLocaleVwcBounds is called from RenderBin.updateObject()
353: // to update the local copy of the localeVwcBounds
354:
355: void updateLocaleVwcBounds() {
356:
357: // it is possible that inRenderBin could be false because
358: // the renderAtom could have been removed from RenderBin
359: // in the same frame, and removeRenderAtoms does happen
360: // before updateLocaleVwcBounds
361: if (inRenderBin()) {
362: // Check if the locale of this is different from the
363: // locale on which the view is,then compute the translated
364: // localeVwcBounds
365: if (renderMolecule.renderBin.locale != geometryAtom.source.locale) {
366:
367: geometryAtom.source.locale.hiRes.difference(
368: renderMolecule.renderBin.locale.hiRes,
369: renderMolecule.renderBin.localeTranslation);
370: localeVwcBounds.translate(
371: geometryAtom.source.vwcBounds,
372: renderMolecule.renderBin.localeTranslation);
373: } else {
374: localeVwcBounds.set(geometryAtom.source.vwcBounds);
375: }
376: dirtyMask &= ~ON_LOCALE_VWC_BOUNDS_UPDATELIST;
377: }
378: }
379: }
|