001: /*
002: * $RCSfile: GeometryAtom.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.8 $
028: * $Date: 2008/02/28 20:17:22 $
029: * $State: Exp $
030: */
031:
032: package javax.media.j3d;
033:
034: import java.util.ArrayList;
035: import javax.vecmath.*;
036:
037: /**
038: * A GeometryAtom is the smallest object representing Geometry.
039: */
040:
041: class GeometryAtom extends Object implements BHLeafInterface, NnuId {
042:
043: /**
044: * Array of geometry components of this geometry atom
045: */
046: // The first index of geometryArr should always be 0, unless geometryArr contains
047: // multiple Text3Ds.
048: GeometryRetained[] geometryArray = null;
049:
050: /**
051: * Array of transforms used only for Text3d.
052: */
053: Transform3D[] lastLocalTransformArray = null;
054:
055: /**
056: * The locale that this geometry atom is attatched to. This is only non-null
057: * if this instance is directly linked into a locale.
058: */
059: Locale locale = null;
060:
061: /**
062: * The mirror Shape3DRetained for this GeometryAtom.
063: */
064: Shape3DRetained source = null;
065:
066: /**
067: * The BHLeafNode for this GeometryAtom.
068: */
069: BHLeafNode bhLeafNode = null;
070:
071: // true if alpha channel is editable
072: boolean alphaEditable;
073:
074: // true if this ga is visible. Default is true.
075: boolean visible = true;
076:
077: /**
078: * This is the original geometry type from which this atom came
079: */
080: int geoType = -1;
081:
082: /**
083: * The list of RenderAtoms for this GeometryAtom
084: */
085: RenderAtom[] renderAtoms = new RenderAtom[0];
086:
087: // Id use for quick search.
088: int nnuId;
089:
090: Point3d[] centroid = null;
091: boolean centroidIsDirty = true;
092: Object lockObj = new Object();
093:
094: GeometryAtom() {
095: // Get a not necessary unique Id.
096: nnuId = NnuIdManager.getId();
097: }
098:
099: public int getId() {
100: return nnuId;
101: }
102:
103: public int equal(NnuId obj) {
104: int keyId = obj.getId();
105: if (nnuId < keyId) {
106: return -1;
107: } else if (nnuId > keyId) {
108: return 1;
109: } else { // Found it!
110: return 0;
111: }
112: }
113:
114: public BoundingBox computeBoundingHull() {
115: /*
116: System.err.println("Bounds is " + source.vwcBounds);
117: for(int i=0; i<geometryArray.length; i++) {
118: System.err.println( i + " geoBounds " +
119: geometryArray[i].geoBounds);
120: }
121: */
122:
123: return source.vwcBounds;
124: }
125:
126: // This method is use by picking and collision queries.
127: public boolean isEnable() {
128: return ((source.vwcBounds != null)
129: && (source.vwcBounds.isEmpty() == false) && (source.switchState.currentSwitchOn));
130: }
131:
132: // This method is use by visibility query.
133: public boolean isEnable(int vis) {
134: if ((source.vwcBounds != null)
135: && (source.vwcBounds.isEmpty() == false)
136: && (source.switchState.currentSwitchOn)) {
137: switch (vis) {
138: case View.VISIBILITY_DRAW_VISIBLE:
139: return visible;
140: case View.VISIBILITY_DRAW_INVISIBLE:
141: return (!visible);
142: case View.VISIBILITY_DRAW_ALL:
143: return true;
144: }
145: }
146: return false;
147: }
148:
149: public Locale getLocale2() {
150: return locale;
151: }
152:
153: /**
154: * Gets a RenderAtom for the given viewIndex.
155: * If it doesn't exist, it creates one.
156: */
157: RenderAtom getRenderAtom(View view) {
158: RenderAtom ra;
159: int index;
160: // If renderAtom is not scoped to this view, don't even
161: // bother creating the renderAtom
162:
163: synchronized (renderAtoms) {
164: index = view.viewIndex;
165: if (index >= renderAtoms.length) {
166:
167: // If creating a new RenderAtom, but this ga is not scoped
168: // to this view, then just return ..
169: if (source.viewList != null
170: && !source.viewList.contains(view))
171: return null;
172: RenderAtom[] newList = new RenderAtom[index + 1];
173: for (int i = 0; i < renderAtoms.length; i++) {
174: newList[i] = renderAtoms[i];
175: }
176: ra = new RenderAtom();
177: newList[index] = ra;
178: newList[index].geometryAtom = this ;
179:
180: // Allocate space based on number of geometry in the list
181: ra.rListInfo = new RenderAtomListInfo[geometryArray.length];
182: if (geoType != GeometryRetained.GEO_TYPE_TEXT3D) {
183: for (int j = 0; j < ra.rListInfo.length; j++) {
184: ra.rListInfo[j] = new RenderAtomListInfo();
185: ra.rListInfo[j].renderAtom = ra;
186: ra.rListInfo[j].index = j;
187: }
188: } else {
189: for (int j = 0; j < ra.rListInfo.length; j++) {
190: ra.rListInfo[j] = new RenderAtomListInfo();
191: ra.rListInfo[j].renderAtom = ra;
192: ra.rListInfo[j].index = j;
193: ra.rListInfo[j].localToVworld = new Transform3D();
194: }
195: }
196:
197: // Note this must be the last line in synchronized.
198: // Otherwise the lock is changed to newList and
199: // another thread can come in modified. This cause
200: // NullPointerException in
201: // renderAtoms[index].geometryAtom = this;
202: // which I encounter.
203: renderAtoms = newList;
204: } else {
205: if (renderAtoms[index] == null) {
206: // If creating a new RenderAtom, but this ga is not scoped
207: // to this view, then just return ..
208: if (source.viewList != null
209: && !source.viewList.contains(view))
210: return null;
211:
212: ra = new RenderAtom();
213: renderAtoms[index] = ra;
214: renderAtoms[index].geometryAtom = this ;
215: // Allocate space based on number of geometry in the list
216: ra.rListInfo = new RenderAtomListInfo[geometryArray.length];
217: if (geoType != GeometryRetained.GEO_TYPE_TEXT3D) {
218: for (int j = 0; j < ra.rListInfo.length; j++) {
219: ra.rListInfo[j] = new RenderAtomListInfo();
220: ra.rListInfo[j].renderAtom = ra;
221: ra.rListInfo[j].index = j;
222: }
223: } else {
224: for (int j = 0; j < ra.rListInfo.length; j++) {
225: ra.rListInfo[j] = new RenderAtomListInfo();
226: ra.rListInfo[j].renderAtom = ra;
227: ra.rListInfo[j].index = j;
228: ra.rListInfo[j].localToVworld = new Transform3D();
229: }
230: }
231: }
232: }
233: }
234:
235: return (renderAtoms[index]);
236: }
237:
238: // If the renderAtom is transparent, then make sure that the
239: // value is up-to-date
240:
241: void updateCentroid() {
242: // New for 1.3.2
243: // If the sortShape3DBounds flag is set, the bounds of the
244: // Shape3D node will be used in place of the computed
245: // GeometryArray bounds for transparency sorting for those
246: // Shape3D nodes whose boundsAutoCompute attribute is set to
247: // false.
248: if (VirtualUniverse.mc.sortShape3DBounds
249: && !source.boundsAutoCompute) {
250:
251: synchronized (lockObj) {
252: if (centroid == null) {
253: centroid = new Point3d[geometryArray.length];
254: for (int j = 0; j < centroid.length; j++) {
255: centroid[j] = new Point3d(source.localBounds
256: .getCenter());
257: source.getCurrentLocalToVworld(0).transform(
258: centroid[j]);
259: }
260: } else {
261: for (int j = 0; j < centroid.length; j++) {
262: centroid[j].set(source.localBounds.getCenter());
263: source.getCurrentLocalToVworld(0).transform(
264: centroid[j]);
265: }
266: }
267: }
268:
269: return;
270: }
271: // End of new for 1.3.2
272:
273: synchronized (lockObj) {
274: for (int j = 0; j < geometryArray.length; j++) {
275: if (geometryArray[j] == null)
276: continue;
277: synchronized (geometryArray[j].centroid) {
278: if (geometryArray[j].recompCentroid) {
279: geometryArray[j].computeCentroid();
280: geometryArray[j].recompCentroid = false;
281: }
282: }
283: }
284: if (centroidIsDirty) {
285: if (centroid == null) {
286: centroid = new Point3d[geometryArray.length];
287: for (int j = 0; j < centroid.length; j++) {
288: if (geometryArray[j] == null)
289: continue;
290: centroid[j] = new Point3d(
291: geometryArray[j].centroid);
292: source.getCurrentLocalToVworld(0).transform(
293: centroid[j]);
294: }
295: } else {
296: for (int j = 0; j < centroid.length; j++) {
297: if (geometryArray[j] == null)
298: continue;
299: centroid[j].set(geometryArray[j].centroid);
300: source.getCurrentLocalToVworld(0).transform(
301: centroid[j]);
302: }
303: }
304: centroidIsDirty = false;
305: }
306: }
307: }
308:
309: }
|