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