aboutsummaryrefslogtreecommitdiffstats
path: root/src/javax/media/j3d/RenderAtom.java
blob: 1d1bb8d45268ff4012497f676fc94187f88b5f38 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
/*
 * Copyright 1999-2008 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 *
 */

package javax.media.j3d;

/**
 * A RenderAtom is a wrapper for a GeometryAtom in a given RenderBin.
 */

class RenderAtom extends Object implements ObjectUpdate {
    /**
     * The geometry atom of this render atom
     */
    GeometryAtom geometryAtom = null;

    /**
     * The RenderMolecule for this RenderAtom
     */
    RenderMolecule renderMolecule = null;


    /**
     * The lights that influence this RenderAtom
     */
    LightRetained[] lights = null;

    /**
     * The fog that influences this RenderAtom
     */
    FogRetained fog = null;

    /**
     * The model clip that influences this RenderAtom
     */
    ModelClipRetained modelClip = null;

    /**
     * The appearance that influences this RenderAtom
     */
    AppearanceRetained app = null;

    //
    // Convert all boolean to a bitmask, saves memory since
    // there are many RenderAtoms per view
    //

    /**
     * Indicates whether or not this object is in
     * the render bin.
     */
    static int IN_RENDERBIN               = 0x1;

    // True if the above localeVwcBounds is a local copy rather
    // than a reference to the bounds in shape
    static int HAS_SEPARATE_LOCALE_VWC_BOUNDS     = 0x2;

    // true if one of the geometries not going to a display list, hence
    // need to maintain a local localeVwcBounds in order to avoid
    // conflict with the vwcBounds in shape which is CURRENT
    // while the checking of localeVwcBounds in rendering time
    // should be LAST. In order words, localeVwcBounds contain
    // the last vwcBounds, whereas, shape.vwcBounds contain the
    // current vwcBounds
    //
    static int NEED_SEPARATE_LOCALE_VWC_BOUNDS    = 0x4;

    static int ON_UPDATELIST                      = 0x8;
    static int ON_LOCALE_VWC_BOUNDS_UPDATELIST    = 0x10;
    // true if comes from Oriented Shape3D
    static int IS_ORIENTED                         = 0x20;
    // true if in dirty oriented render atom list
    static int IN_DIRTY_ORIENTED_RAs               = 0x40;

    // true if in dirty depth sort position list
    static int IN_SORTED_POS_DIRTY_TRANSP_LIST     = 0x80;

    // A bitmask for all the bit specified above in this renderAtom
    int dirtyMask = 0;

    /**
     * Environment set that this renderAtom belongs to, used
     * to compare the new env set with the old one when the
     * scoping/bounds of a light/fog changes
     */
    EnvironmentSet envSet;

    /**
     * Used for non-text3d
     */
    BoundingBox localeVwcBounds = null;


    /**
     * The last time this atom was reported visible
     */
    long lastVisibleTime = -1;

    /**
     * Next and Previous references for the list of RenderAtoms
     * groupType is a  mask set to true if this renderAtom is part of the displaylist array
     * of the renderMolecule
     * One per geometry in the geometryArr in the geometryAtom, since
     * each geometry in the geometryAtom can end up in a different
     * atomList(primary, secondary, seperatedlist) of the renderMoceule
     */
    RenderAtomListInfo[] rListInfo;

    /**
     * Used in depthSorted transparency, once per rInfo
     */
    TransparentRenderingInfo[] parentTInfo = null;

    /**
     * Used when depth sorted transparecy is turned on
     * one dlist per rinfo
     */
    int[] dlistIds = null;

    // One per geometry in the geometryArr in the geometryAtom
    static int TEXT3D  = 0x1;
    static int DLIST   = 0x2;
    static int CG      = 0x4;
    static int OTHER   = 0x8;
    static int SEPARATE_DLIST_PER_GEO   = 0x10;
    static int VARRAY = 0x20;
    static int SEPARATE_DLIST_PER_RINFO = 0x40;
    static int PRIMARY = TEXT3D | DLIST | CG | OTHER|SEPARATE_DLIST_PER_RINFO;

    // Rendermolecule to which its currently being added
    RenderMolecule added = null;

    // Rendermolecule from which its currently being removed
    RenderMolecule removed = null;

    // non-null, if part of the add list(for the next frame) in the renderMolecule
    RenderAtom nextAdd = null;
    RenderAtom prevAdd = null;

    // non-null, if part of the remove list(for the next frame) in the renderMolecule
    RenderAtom nextRemove = null;
    RenderAtom prevRemove = null;

    RenderAtom() {
    }

    /**
     * This sets the inRenderBin flag
     */
    synchronized void setRenderBin(boolean value) {
	if (value == false) {
	    app = null;
	    dirtyMask &= ~IN_RENDERBIN;
	    dirtyMask &= ~ON_LOCALE_VWC_BOUNDS_UPDATELIST;
	    dirtyMask &= ~ON_UPDATELIST;
	}
	else {
	    dirtyMask |= IN_RENDERBIN;
	}

    }

    /**
     * This returns whether or not this atom goes into the opaque
     * light bin
     */
    boolean isOpaque() {
	AppearanceRetained app = geometryAtom.source.appearance;

        if (app == null) {
            return true;
        }

	TransparencyAttributesRetained ta = app.transparencyAttributes;

    switch (geometryAtom.geoType) {
    case GeometryRetained.GEO_TYPE_POINT_SET:
    case GeometryRetained.GEO_TYPE_INDEXED_POINT_SET:
	if ((app.pointAttributes != null) &&
	    app.pointAttributes.pointAntialiasing) {
	    return false;
	}
	break;
    case GeometryRetained.GEO_TYPE_LINE_SET:
    case GeometryRetained.GEO_TYPE_LINE_STRIP_SET:
    case GeometryRetained.GEO_TYPE_INDEXED_LINE_SET:
    case GeometryRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET:
	if ((app.lineAttributes != null) &&
	    app.lineAttributes.lineAntialiasing) {
	    return false;
	}
	break;
    case GeometryRetained.GEO_TYPE_RASTER:
    case GeometryRetained.GEO_TYPE_COMPRESSED:
	break;
    default:
	if (app.polygonAttributes != null) {
	    if ((app.polygonAttributes.polygonMode ==
		 PolygonAttributes.POLYGON_POINT) &&
		(app.pointAttributes != null) &&
		app.pointAttributes.pointAntialiasing) {
		return false;
	    } else if ((app.polygonAttributes.polygonMode ==
			PolygonAttributes.POLYGON_LINE) &&
		       (app.lineAttributes != null) &&
		       app.lineAttributes.lineAntialiasing) {
		return false;
	    }
	}
	break;
    }

	return !TransparencyAttributesRetained.useAlpha(ta);
    }

    boolean inRenderBin() {
	return ((dirtyMask & IN_RENDERBIN) != 0);
    }

    boolean hasSeparateLocaleVwcBounds() {
	return ((dirtyMask & HAS_SEPARATE_LOCALE_VWC_BOUNDS) != 0);
    }

    boolean needSeparateLocaleVwcBounds() {
	return ((dirtyMask & NEED_SEPARATE_LOCALE_VWC_BOUNDS) != 0);
    }

    boolean onUpdateList() {
	return ((dirtyMask & ON_UPDATELIST) != 0);
    }

    boolean onLocaleVwcBoundsUpdateList() {
	return ((dirtyMask & ON_LOCALE_VWC_BOUNDS_UPDATELIST) != 0);
    }

    boolean isOriented() {
	return ((dirtyMask & IS_ORIENTED) != 0);
    }

    boolean inDepthSortList() {
	return ((dirtyMask & IN_SORTED_POS_DIRTY_TRANSP_LIST) != 0);
    }


    boolean inDirtyOrientedRAs() {
	return ((dirtyMask & IN_DIRTY_ORIENTED_RAs) != 0);
    }

    @Override
    public void updateObject() {
	if (inRenderBin()) {
	    int lastLVWIndex =
	      renderMolecule.localToVworldIndex[NodeRetained.LAST_LOCAL_TO_VWORLD];

	    for (int i = 0; i < rListInfo.length; i++) {
		if (rListInfo[i].geometry() == null)
		    continue;

		if (geometryAtom.source.inBackgroundGroup) {
		    if (rListInfo[i].infLocalToVworld == null)
			rListInfo[i].infLocalToVworld = new Transform3D();

		    // to preserve the character transformation for Text3D atoms
		    renderMolecule.localToVworld[lastLVWIndex].getRotation(
			rListInfo[i].infLocalToVworld);
		    rListInfo[i].infLocalToVworld.mul(
			geometryAtom.lastLocalTransformArray[i]);
		} else {
		    rListInfo[i].localToVworld.mul(
			renderMolecule.localeLocalToVworld[lastLVWIndex],
			geometryAtom.lastLocalTransformArray[i]);
		}
	    }
	}
	dirtyMask &= ~ON_UPDATELIST;
    }

    void updateOrientedTransform() {
	int lastLVWIndex =
	  renderMolecule.localToVworldIndex[NodeRetained.LAST_LOCAL_TO_VWORLD];
	Transform3D orientedTransform =
	    ((OrientedShape3DRetained)geometryAtom.source).
	    getOrientedTransform(renderMolecule.renderBin.view.viewIndex);
	for (int i = 0; i < rListInfo.length; i++) {

	    if (geometryAtom.geoType == GeometryRetained.GEO_TYPE_TEXT3D &&
		geometryAtom.lastLocalTransformArray[i] != null) {
		if (geometryAtom.source.inBackgroundGroup) {
		    if (rListInfo[i].infLocalToVworld == null)
			rListInfo[i].infLocalToVworld = new Transform3D();

		    rListInfo[i].infLocalToVworld.mul(
			renderMolecule.infLocalToVworld[lastLVWIndex],
			orientedTransform);
		    rListInfo[i].infLocalToVworld.mul(
			geometryAtom.lastLocalTransformArray[i]);
		} else {
		    rListInfo[i].localToVworld.mul(
			renderMolecule.localeLocalToVworld[lastLVWIndex],
			orientedTransform);
		    rListInfo[i].localToVworld.mul(
			geometryAtom.lastLocalTransformArray[i]);
		}
	    } else {
		if (geometryAtom.source.inBackgroundGroup) {
		    if (rListInfo[i].infLocalToVworld == null)
			rListInfo[i].infLocalToVworld = new Transform3D();

		    rListInfo[i].infLocalToVworld.mul(
			renderMolecule.infLocalToVworld[lastLVWIndex],
			orientedTransform);
		} else {
		    rListInfo[i].localToVworld.mul(
			renderMolecule.localeLocalToVworld[lastLVWIndex],
			orientedTransform);
		}
	    }
	}
    }

    // updateLocaleVwcBounds is called from RenderBin.updateObject()
    // to update the local copy of the localeVwcBounds

    void updateLocaleVwcBounds() {

	// it is possible that inRenderBin could be false because
	// the renderAtom could have been removed from RenderBin
	// in the same frame, and removeRenderAtoms does happen
	// before updateLocaleVwcBounds
	if (inRenderBin()) {
	    // Check if the locale of this is different from the
	    // locale on which the view is,then compute the translated
	    // localeVwcBounds
	    if (renderMolecule.renderBin.locale != geometryAtom.source.locale) {

		geometryAtom.source.locale.
		    hiRes.difference(renderMolecule.renderBin.locale.hiRes,
				     renderMolecule.renderBin.localeTranslation);
		localeVwcBounds.translate(geometryAtom.source.vwcBounds,
					  renderMolecule.renderBin.localeTranslation);
	    } else {
		localeVwcBounds.set(geometryAtom.source.vwcBounds);
	    }
	    dirtyMask &= ~ON_LOCALE_VWC_BOUNDS_UPDATELIST;
	}
    }
}