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