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