001: /*
002: * $RCSfile: IndexedQuadArrayRetained.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.8 $
028: * $Date: 2008/02/28 20:17:24 $
029: * $State: Exp $
030: */
031:
032: package javax.media.j3d;
033:
034: import javax.vecmath.*;
035: import java.lang.Math;
036:
037: /**
038: * The IndexedQuadArray object draws the array of vertices as individual
039: * quadrilaterals. Each group
040: * of four vertices defines a quadrilateral to be drawn.
041: */
042:
043: class IndexedQuadArrayRetained extends IndexedGeometryArrayRetained {
044:
045: IndexedQuadArrayRetained() {
046: this .geoType = GEO_TYPE_INDEXED_QUAD_SET;
047: }
048:
049: boolean intersect(PickShape pickShape, PickInfo pickInfo,
050: int flags, Point3d iPnt, GeometryRetained geom,
051: int geomIndex) {
052: Point3d pnts[] = new Point3d[4];
053: double sdist[] = new double[1];
054: double minDist = Double.MAX_VALUE;
055: double x = 0, y = 0, z = 0;
056: int[] vtxIndexArr = new int[4];
057:
058: //NVaidya
059: // Bug 447: While loops below now traverse over all
060: // elements in the valid index range from initialIndexIndex
061: // to initialIndexInex + validIndexCount - 1
062: int i = initialIndexIndex;
063: int loopStopIndex = initialIndexIndex + validIndexCount;
064: pnts[0] = new Point3d();
065: pnts[1] = new Point3d();
066: pnts[2] = new Point3d();
067: pnts[3] = new Point3d();
068:
069: switch (pickShape.getPickType()) {
070: case PickShape.PICKRAY:
071: PickRay pickRay = (PickRay) pickShape;
072:
073: while (i < loopStopIndex) {
074: for (int j = 0; j < 4; j++) {
075: vtxIndexArr[j] = indexCoord[i];
076: getVertexData(indexCoord[i++], pnts[j]);
077: }
078: if (intersectRay(pnts, pickRay, sdist, iPnt)) {
079: if (flags == 0) {
080: return true;
081: }
082: if (sdist[0] < minDist) {
083: minDist = sdist[0];
084: x = iPnt.x;
085: y = iPnt.y;
086: z = iPnt.z;
087: if ((flags & PickInfo.CLOSEST_GEOM_INFO) != 0) {
088: storeInterestData(pickInfo, flags, geom,
089: geomIndex, vtxIndexArr, iPnt,
090: sdist[0]);
091: }
092: }
093: if ((flags & PickInfo.ALL_GEOM_INFO) != 0) {
094: storeInterestData(pickInfo, flags, geom,
095: geomIndex, vtxIndexArr, iPnt, sdist[0]);
096: }
097: }
098: }
099: break;
100: case PickShape.PICKSEGMENT:
101: PickSegment pickSegment = (PickSegment) pickShape;
102:
103: while (i < loopStopIndex) {
104: for (int j = 0; j < 4; j++) {
105: vtxIndexArr[j] = indexCoord[i];
106: getVertexData(indexCoord[i++], pnts[j]);
107: }
108: if (intersectSegment(pnts, pickSegment.start,
109: pickSegment.end, sdist, iPnt)) {
110: if (flags == 0) {
111: return true;
112: }
113: if (sdist[0] < minDist) {
114: minDist = sdist[0];
115: x = iPnt.x;
116: y = iPnt.y;
117: z = iPnt.z;
118: if ((flags & PickInfo.CLOSEST_GEOM_INFO) != 0) {
119: storeInterestData(pickInfo, flags, geom,
120: geomIndex, vtxIndexArr, iPnt,
121: sdist[0]);
122: }
123: }
124: if ((flags & PickInfo.ALL_GEOM_INFO) != 0) {
125: storeInterestData(pickInfo, flags, geom,
126: geomIndex, vtxIndexArr, iPnt, sdist[0]);
127: }
128: }
129: }
130: break;
131: case PickShape.PICKBOUNDINGBOX:
132: BoundingBox bbox = (BoundingBox) ((PickBounds) pickShape).bounds;
133: while (i < loopStopIndex) {
134: for (int j = 0; j < 4; j++) {
135: vtxIndexArr[j] = indexCoord[i];
136: getVertexData(indexCoord[i++], pnts[j]);
137: }
138: if (intersectBoundingBox(pnts, bbox, sdist, iPnt)) {
139: if (flags == 0) {
140: return true;
141: }
142: if (sdist[0] < minDist) {
143: minDist = sdist[0];
144: x = iPnt.x;
145: y = iPnt.y;
146: z = iPnt.z;
147: if ((flags & PickInfo.CLOSEST_GEOM_INFO) != 0) {
148: storeInterestData(pickInfo, flags, geom,
149: geomIndex, vtxIndexArr, iPnt,
150: sdist[0]);
151: }
152: }
153: if ((flags & PickInfo.ALL_GEOM_INFO) != 0) {
154: storeInterestData(pickInfo, flags, geom,
155: geomIndex, vtxIndexArr, iPnt, sdist[0]);
156: }
157: }
158: }
159: break;
160: case PickShape.PICKBOUNDINGSPHERE:
161: BoundingSphere bsphere = (BoundingSphere) ((PickBounds) pickShape).bounds;
162: while (i < loopStopIndex) {
163: for (int j = 0; j < 4; j++) {
164: vtxIndexArr[j] = indexCoord[i];
165: getVertexData(indexCoord[i++], pnts[j]);
166: }
167: if (intersectBoundingSphere(pnts, bsphere, sdist, iPnt)) {
168: if (flags == 0) {
169: return true;
170: }
171: if (sdist[0] < minDist) {
172: minDist = sdist[0];
173: x = iPnt.x;
174: y = iPnt.y;
175: z = iPnt.z;
176: if ((flags & PickInfo.CLOSEST_GEOM_INFO) != 0) {
177: storeInterestData(pickInfo, flags, geom,
178: geomIndex, vtxIndexArr, iPnt,
179: sdist[0]);
180: }
181: }
182: if ((flags & PickInfo.ALL_GEOM_INFO) != 0) {
183: storeInterestData(pickInfo, flags, geom,
184: geomIndex, vtxIndexArr, iPnt, sdist[0]);
185: }
186: }
187: }
188: break;
189: case PickShape.PICKBOUNDINGPOLYTOPE:
190: BoundingPolytope bpolytope = (BoundingPolytope) ((PickBounds) pickShape).bounds;
191: while (i < loopStopIndex) {
192: for (int j = 0; j < 4; j++) {
193: vtxIndexArr[j] = indexCoord[i];
194: getVertexData(indexCoord[i++], pnts[j]);
195: }
196: if (intersectBoundingPolytope(pnts, bpolytope, sdist,
197: iPnt)) {
198: if (flags == 0) {
199: return true;
200: }
201: if (sdist[0] < minDist) {
202: minDist = sdist[0];
203: x = iPnt.x;
204: y = iPnt.y;
205: z = iPnt.z;
206: if ((flags & PickInfo.CLOSEST_GEOM_INFO) != 0) {
207: storeInterestData(pickInfo, flags, geom,
208: geomIndex, vtxIndexArr, iPnt,
209: sdist[0]);
210: }
211: }
212: if ((flags & PickInfo.ALL_GEOM_INFO) != 0) {
213: storeInterestData(pickInfo, flags, geom,
214: geomIndex, vtxIndexArr, iPnt, sdist[0]);
215: }
216: }
217: }
218: break;
219: case PickShape.PICKCYLINDER:
220: PickCylinder pickCylinder = (PickCylinder) pickShape;
221: while (i < loopStopIndex) {
222: for (int j = 0; j < 4; j++) {
223: vtxIndexArr[j] = indexCoord[i];
224: getVertexData(indexCoord[i++], pnts[j]);
225: }
226: if (intersectCylinder(pnts, pickCylinder, sdist, iPnt)) {
227: if (flags == 0) {
228: return true;
229: }
230: if (sdist[0] < minDist) {
231: minDist = sdist[0];
232: x = iPnt.x;
233: y = iPnt.y;
234: z = iPnt.z;
235: if ((flags & PickInfo.CLOSEST_GEOM_INFO) != 0) {
236: storeInterestData(pickInfo, flags, geom,
237: geomIndex, vtxIndexArr, iPnt,
238: sdist[0]);
239: }
240: }
241: if ((flags & PickInfo.ALL_GEOM_INFO) != 0) {
242: storeInterestData(pickInfo, flags, geom,
243: geomIndex, vtxIndexArr, iPnt, sdist[0]);
244: }
245: }
246: }
247: break;
248: case PickShape.PICKCONE:
249: PickCone pickCone = (PickCone) pickShape;
250: while (i < loopStopIndex) {
251: for (int j = 0; j < 4; j++) {
252: vtxIndexArr[j] = indexCoord[i];
253: getVertexData(indexCoord[i++], pnts[j]);
254: }
255: if (intersectCone(pnts, pickCone, sdist, iPnt)) {
256: if (flags == 0) {
257: return true;
258: }
259: if (sdist[0] < minDist) {
260: minDist = sdist[0];
261: x = iPnt.x;
262: y = iPnt.y;
263: z = iPnt.z;
264: if ((flags & PickInfo.CLOSEST_GEOM_INFO) != 0) {
265: storeInterestData(pickInfo, flags, geom,
266: geomIndex, vtxIndexArr, iPnt,
267: sdist[0]);
268: }
269: }
270: if ((flags & PickInfo.ALL_GEOM_INFO) != 0) {
271: storeInterestData(pickInfo, flags, geom,
272: geomIndex, vtxIndexArr, iPnt, sdist[0]);
273: }
274: }
275: }
276: break;
277: case PickShape.PICKPOINT:
278: // Should not happen since API already check for this
279: throw new IllegalArgumentException(J3dI18N
280: .getString("IndexedQuadArrayRetained0"));
281: default:
282: throw new RuntimeException(
283: "PickShape not supported for intersection ");
284: }
285:
286: if (minDist < Double.MAX_VALUE) {
287: iPnt.x = x;
288: iPnt.y = y;
289: iPnt.z = z;
290: return true;
291: }
292: return false;
293:
294: }
295:
296: // intersect pnts[] with every quad in this object
297: boolean intersect(Point3d[] pnts) {
298: Point3d[] points = new Point3d[4];
299: double dist[] = new double[1];
300: //NVaidya
301: // Bug 447: correction for loop indices
302: int i = initialIndexIndex;
303: int loopStopIndex = initialIndexIndex + validIndexCount;
304:
305: points[0] = new Point3d();
306: points[1] = new Point3d();
307: points[2] = new Point3d();
308: points[3] = new Point3d();
309:
310: switch (pnts.length) {
311: case 3: // Triangle
312: while (i < loopStopIndex) {
313: getVertexData(indexCoord[i++], points[0]);
314: getVertexData(indexCoord[i++], points[1]);
315: getVertexData(indexCoord[i++], points[2]);
316: getVertexData(indexCoord[i++], points[3]);
317: if (intersectTriTri(points[0], points[1], points[2],
318: pnts[0], pnts[1], pnts[2])
319: || intersectTriTri(points[0], points[2],
320: points[3], pnts[0], pnts[1], pnts[2])) {
321: return true;
322: }
323: }
324: break;
325: case 4: // Quad
326: while (i < loopStopIndex) {
327: getVertexData(indexCoord[i++], points[0]);
328: getVertexData(indexCoord[i++], points[1]);
329: getVertexData(indexCoord[i++], points[2]);
330: getVertexData(indexCoord[i++], points[3]);
331: if (intersectTriTri(points[0], points[1], points[2],
332: pnts[0], pnts[1], pnts[2])
333: || intersectTriTri(points[0], points[1],
334: points[2], pnts[0], pnts[2], pnts[3])
335: || intersectTriTri(points[0], points[2],
336: points[3], pnts[0], pnts[1], pnts[2])
337: || intersectTriTri(points[0], points[2],
338: points[3], pnts[0], pnts[2], pnts[3])) {
339: return true;
340: }
341: }
342: break;
343: case 2: // Line
344: while (i < loopStopIndex) {
345: getVertexData(indexCoord[i++], points[0]);
346: getVertexData(indexCoord[i++], points[1]);
347: getVertexData(indexCoord[i++], points[2]);
348: getVertexData(indexCoord[i++], points[3]);
349: if (intersectSegment(points, pnts[0], pnts[1], dist,
350: null)) {
351: return true;
352: }
353: }
354: break;
355: case 1: // Point
356: while (i < loopStopIndex) {
357: getVertexData(indexCoord[i++], points[0]);
358: getVertexData(indexCoord[i++], points[1]);
359: getVertexData(indexCoord[i++], points[2]);
360: getVertexData(indexCoord[i++], points[3]);
361: if (intersectTriPnt(points[0], points[1], points[2],
362: pnts[0])
363: || intersectTriPnt(points[0], points[2],
364: points[3], pnts[0])) {
365: return true;
366: }
367: }
368: break;
369: }
370: return false;
371: }
372:
373: boolean intersect(Transform3D this ToOtherVworld,
374: GeometryRetained geom) {
375:
376: Point3d[] points = new Point3d[4];
377: //NVaidya
378: // Bug 447: correction for loop indices
379: int i = initialIndexIndex;
380: int loopStopIndex = initialIndexIndex + validIndexCount;
381:
382: points[0] = new Point3d();
383: points[1] = new Point3d();
384: points[2] = new Point3d();
385: points[3] = new Point3d();
386:
387: while (i < loopStopIndex) {
388: getVertexData(indexCoord[i++], points[0]);
389: getVertexData(indexCoord[i++], points[1]);
390: getVertexData(indexCoord[i++], points[2]);
391: getVertexData(indexCoord[i++], points[3]);
392: this ToOtherVworld.transform(points[0]);
393: this ToOtherVworld.transform(points[1]);
394: this ToOtherVworld.transform(points[2]);
395: this ToOtherVworld.transform(points[3]);
396: if (geom.intersect(points)) {
397: return true;
398: }
399: } // for each quad
400: return false;
401: }
402:
403: // the bounds argument is already transformed
404: boolean intersect(Bounds targetBound) {
405: Point3d[] points = new Point3d[4];
406: //NVaidya
407: // Bug 447: correction for loop indices
408: int i = initialIndexIndex;
409: int loopStopIndex = initialIndexIndex + validIndexCount;
410:
411: points[0] = new Point3d();
412: points[1] = new Point3d();
413: points[2] = new Point3d();
414: points[3] = new Point3d();
415:
416: switch (targetBound.getPickType()) {
417: case PickShape.PICKBOUNDINGBOX:
418: BoundingBox box = (BoundingBox) targetBound;
419:
420: while (i < loopStopIndex) {
421: getVertexData(indexCoord[i++], points[0]);
422: getVertexData(indexCoord[i++], points[1]);
423: getVertexData(indexCoord[i++], points[2]);
424: getVertexData(indexCoord[i++], points[3]);
425: if (intersectBoundingBox(points, box, null, null)) {
426: return true;
427: }
428: }
429: break;
430: case PickShape.PICKBOUNDINGSPHERE:
431: BoundingSphere bsphere = (BoundingSphere) targetBound;
432:
433: while (i < loopStopIndex) {
434: getVertexData(indexCoord[i++], points[0]);
435: getVertexData(indexCoord[i++], points[1]);
436: getVertexData(indexCoord[i++], points[2]);
437: getVertexData(indexCoord[i++], points[3]);
438: if (intersectBoundingSphere(points, bsphere, null, null)) {
439: return true;
440: }
441: }
442: break;
443: case PickShape.PICKBOUNDINGPOLYTOPE:
444: BoundingPolytope bpolytope = (BoundingPolytope) targetBound;
445: while (i < loopStopIndex) {
446: getVertexData(indexCoord[i++], points[0]);
447: getVertexData(indexCoord[i++], points[1]);
448: getVertexData(indexCoord[i++], points[2]);
449: getVertexData(indexCoord[i++], points[3]);
450: if (intersectBoundingPolytope(points, bpolytope, null,
451: null)) {
452: return true;
453: }
454: }
455: break;
456: default:
457: throw new RuntimeException(
458: "Bounds not supported for intersection "
459: + targetBound);
460: }
461: return false;
462: }
463:
464: int getClassType() {
465: return QUAD_TYPE;
466: }
467: }
|