001: /*
002: * $RCSfile: LineStripArrayRetained.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 LineStripArray 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 LineStripArrayRetained extends GeometryStripArrayRetained {
047:
048: LineStripArrayRetained() {
049: this .geoType = GEO_TYPE_LINE_STRIP_SET;
050: }
051:
052: boolean intersect(PickShape pickShape, PickInfo pickInfo,
053: int flags, Point3d iPnt, GeometryRetained geom,
054: int geomIndex) {
055: Point3d pnts[] = new Point3d[2];
056: double sdist[] = new double[1];
057: double minDist = Double.MAX_VALUE;
058: double x = 0, y = 0, z = 0;
059: int j, end;
060: int i = 0;
061: pnts[0] = new Point3d();
062: pnts[1] = new Point3d();
063: int[] vtxIndexArr = new int[2];
064:
065: switch (pickShape.getPickType()) {
066: case PickShape.PICKRAY:
067: PickRay pickRay = (PickRay) pickShape;
068:
069: while (i < stripVertexCounts.length) {
070: j = stripStartVertexIndices[i];
071: end = j + stripVertexCounts[i++];
072: vtxIndexArr[0] = j;
073: getVertexData(j++, pnts[0]);
074: while (j < end) {
075: vtxIndexArr[1] = j;
076: getVertexData(j++, pnts[1]);
077: if (intersectLineAndRay(pnts[0], pnts[1],
078: pickRay.origin, pickRay.direction, sdist,
079: iPnt)) {
080: if (flags == 0) {
081: return true;
082: }
083: if (sdist[0] < minDist) {
084: minDist = sdist[0];
085: x = iPnt.x;
086: y = iPnt.y;
087: z = iPnt.z;
088: if ((flags & PickInfo.CLOSEST_GEOM_INFO) != 0) {
089: storeInterestData(pickInfo, flags,
090: geom, geomIndex, vtxIndexArr,
091: iPnt, sdist[0]);
092: }
093: }
094: if ((flags & PickInfo.ALL_GEOM_INFO) != 0) {
095: storeInterestData(pickInfo, flags, geom,
096: geomIndex, vtxIndexArr, iPnt,
097: sdist[0]);
098: }
099: }
100: pnts[0].set(pnts[1]);
101: vtxIndexArr[0] = vtxIndexArr[1];
102: }
103: }
104: break;
105: case PickShape.PICKSEGMENT:
106: PickSegment pickSegment = (PickSegment) pickShape;
107: Vector3d dir = new Vector3d(pickSegment.end.x
108: - pickSegment.start.x, pickSegment.end.y
109: - pickSegment.start.y, pickSegment.end.z
110: - pickSegment.start.z);
111:
112: while (i < stripVertexCounts.length) {
113: j = stripStartVertexIndices[i];
114: end = j + stripVertexCounts[i++];
115: vtxIndexArr[0] = j;
116: getVertexData(j++, pnts[0]);
117: while (j < end) {
118: vtxIndexArr[1] = j;
119: getVertexData(j++, 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 < stripVertexCounts.length) {
152: j = stripStartVertexIndices[i];
153: end = j + stripVertexCounts[i++];
154: vtxIndexArr[0] = j;
155: getVertexData(j++, pnts[0]);
156: while (j < end) {
157: vtxIndexArr[1] = j;
158: getVertexData(j++, pnts[1]);
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[0].set(pnts[1]);
181: vtxIndexArr[0] = vtxIndexArr[1];
182: }
183: }
184:
185: break;
186: case PickShape.PICKBOUNDINGSPHERE:
187: BoundingSphere bsphere = (BoundingSphere) ((PickBounds) pickShape).bounds;
188:
189: while (i < stripVertexCounts.length) {
190: j = stripStartVertexIndices[i];
191: end = j + stripVertexCounts[i++];
192: vtxIndexArr[0] = j;
193: getVertexData(j++, pnts[0]);
194: while (j < end) {
195: vtxIndexArr[1] = j;
196: getVertexData(j++, pnts[1]);
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[0].set(pnts[1]);
220: vtxIndexArr[0] = vtxIndexArr[1];
221: }
222: }
223: break;
224: case PickShape.PICKBOUNDINGPOLYTOPE:
225: BoundingPolytope bpolytope = (BoundingPolytope) ((PickBounds) pickShape).bounds;
226:
227: while (i < stripVertexCounts.length) {
228: j = stripStartVertexIndices[i];
229: end = j + stripVertexCounts[i++];
230: vtxIndexArr[0] = j;
231: getVertexData(j++, pnts[0]);
232: while (j < end) {
233: vtxIndexArr[1] = j;
234: getVertexData(j++, pnts[1]);
235: if (intersectBoundingPolytope(pnts, bpolytope,
236: sdist, iPnt)) {
237: if (flags == 0) {
238: return true;
239: }
240: if (sdist[0] < minDist) {
241: minDist = sdist[0];
242: x = iPnt.x;
243: y = iPnt.y;
244: z = iPnt.z;
245: if ((flags & PickInfo.CLOSEST_GEOM_INFO) != 0) {
246: storeInterestData(pickInfo, flags,
247: geom, geomIndex, vtxIndexArr,
248: iPnt, sdist[0]);
249: }
250: }
251: if ((flags & PickInfo.ALL_GEOM_INFO) != 0) {
252: storeInterestData(pickInfo, flags, geom,
253: geomIndex, vtxIndexArr, iPnt,
254: sdist[0]);
255: }
256: }
257: pnts[0].set(pnts[1]);
258: vtxIndexArr[0] = vtxIndexArr[1];
259: }
260: }
261: break;
262: case PickShape.PICKCYLINDER:
263: PickCylinder pickCylinder = (PickCylinder) pickShape;
264:
265: while (i < stripVertexCounts.length) {
266: j = stripStartVertexIndices[i];
267: end = j + stripVertexCounts[i++];
268: vtxIndexArr[0] = j;
269: getVertexData(j++, pnts[0]);
270: while (j < end) {
271: vtxIndexArr[1] = j;
272: getVertexData(j++, pnts[1]);
273: if (intersectCylinder(pnts, pickCylinder, sdist,
274: iPnt)) {
275: if (flags == 0) {
276: return true;
277: }
278: if (sdist[0] < minDist) {
279: minDist = sdist[0];
280: x = iPnt.x;
281: y = iPnt.y;
282: z = iPnt.z;
283: if ((flags & PickInfo.CLOSEST_GEOM_INFO) != 0) {
284: storeInterestData(pickInfo, flags,
285: geom, geomIndex, vtxIndexArr,
286: iPnt, sdist[0]);
287: }
288: }
289: if ((flags & PickInfo.ALL_GEOM_INFO) != 0) {
290: storeInterestData(pickInfo, flags, geom,
291: geomIndex, vtxIndexArr, iPnt,
292: sdist[0]);
293: }
294: }
295: pnts[0].set(pnts[1]);
296: vtxIndexArr[0] = vtxIndexArr[1];
297: }
298: }
299: break;
300: case PickShape.PICKCONE:
301: PickCone pickCone = (PickCone) pickShape;
302:
303: while (i < stripVertexCounts.length) {
304: j = stripStartVertexIndices[i];
305: end = j + stripVertexCounts[i++];
306: vtxIndexArr[0] = j;
307: getVertexData(j++, pnts[0]);
308: while (j < end) {
309: vtxIndexArr[1] = j;
310: getVertexData(j++, pnts[1]);
311: if (intersectCone(pnts, pickCone, sdist, iPnt)) {
312: if (flags == 0) {
313: return true;
314: }
315: if (sdist[0] < minDist) {
316: minDist = sdist[0];
317: x = iPnt.x;
318: y = iPnt.y;
319: z = iPnt.z;
320: if ((flags & PickInfo.CLOSEST_GEOM_INFO) != 0) {
321: storeInterestData(pickInfo, flags,
322: geom, geomIndex, vtxIndexArr,
323: iPnt, sdist[0]);
324: }
325: }
326: if ((flags & PickInfo.ALL_GEOM_INFO) != 0) {
327: storeInterestData(pickInfo, flags, geom,
328: geomIndex, vtxIndexArr, iPnt,
329: sdist[0]);
330: }
331: }
332: pnts[0].set(pnts[1]);
333: vtxIndexArr[0] = vtxIndexArr[1];
334: }
335: }
336: break;
337: case PickShape.PICKPOINT:
338: // Should not happen since API already check for this
339: throw new IllegalArgumentException(J3dI18N
340: .getString("LineStripArrayRetained0"));
341: default:
342: throw new RuntimeException(
343: "PickShape not supported for intersection");
344: }
345:
346: if (minDist < Double.MAX_VALUE) {
347: iPnt.x = x;
348: iPnt.y = y;
349: iPnt.z = z;
350: return true;
351: }
352: return false;
353: }
354:
355: boolean intersect(Point3d[] pnts) {
356: int j, end;
357: Point3d[] points = new Point3d[2];
358: double dist[] = new double[1];
359: Vector3d dir;
360: int i = 0;
361:
362: points[0] = new Point3d();
363: points[1] = new Point3d();
364:
365: switch (pnts.length) {
366: case 3:
367: case 4: // Triangle, Quad
368: while (i < stripVertexCounts.length) {
369: j = stripStartVertexIndices[i];
370: end = j + stripVertexCounts[i++];
371: getVertexData(j++, points[0]);
372: while (j < end) {
373: getVertexData(j++, points[1]);
374: if (intersectSegment(pnts, points[0], points[1],
375: dist, null)) {
376: return true;
377: }
378: points[0].set(points[1]);
379: }
380: }
381: break;
382: case 2: // Line
383: dir = new Vector3d();
384: while (i < stripVertexCounts.length) {
385: j = stripStartVertexIndices[i];
386: end = j + stripVertexCounts[i++];
387: getVertexData(j++, points[0]);
388: while (j < end) {
389: getVertexData(j++, points[1]);
390: dir.x = points[1].x - points[0].x;
391: dir.y = points[1].y - points[0].y;
392: dir.z = points[1].z - points[0].z;
393: if (intersectLineAndRay(pnts[0], pnts[1],
394: points[0], dir, dist, null)
395: && (dist[0] <= 1.0)) {
396: return true;
397: }
398: points[0].set(points[1]);
399: }
400: }
401: break;
402: case 1: // Point
403: dir = new Vector3d();
404: while (i < stripVertexCounts.length) {
405: j = stripStartVertexIndices[i];
406: end = j + stripVertexCounts[i++];
407: getVertexData(j++, points[0]);
408: while (j < end) {
409: getVertexData(j++, points[1]);
410: dir.x = points[1].x - points[0].x;
411: dir.y = points[1].y - points[0].y;
412: dir.z = points[1].z - points[0].z;
413: if (intersectPntAndRay(pnts[0], points[0], dir,
414: dist)
415: && (dist[0] <= 1.0)) {
416: return true;
417: }
418: points[0].set(points[1]);
419: }
420: }
421: break;
422: }
423: return false;
424: }
425:
426: boolean intersect(Transform3D this ToOtherVworld,
427: GeometryRetained geom) {
428: int i = 0;
429: int j, end;
430: Point3d[] pnts = new Point3d[2];
431: pnts[0] = new Point3d();
432: pnts[1] = new Point3d();
433:
434: while (i < stripVertexCounts.length) {
435: j = stripStartVertexIndices[i];
436: end = j + stripVertexCounts[i++];
437: getVertexData(j++, pnts[0]);
438: this ToOtherVworld.transform(pnts[0]);
439: while (j < end) {
440: getVertexData(j++, pnts[1]);
441: this ToOtherVworld.transform(pnts[1]);
442: if (geom.intersect(pnts)) {
443: return true;
444: }
445: pnts[0].set(pnts[1]);
446: }
447: }
448: return false;
449: }
450:
451: // the bounds argument is already transformed
452: boolean intersect(Bounds targetBound) {
453: int i = 0;
454: int j, offset, end;
455: Point3d[] pnts = new Point3d[2];
456: pnts[0] = new Point3d();
457: pnts[1] = new Point3d();
458:
459: switch (targetBound.getPickType()) {
460: case PickShape.PICKBOUNDINGBOX:
461: BoundingBox box = (BoundingBox) targetBound;
462:
463: while (i < stripVertexCounts.length) {
464: j = stripStartVertexIndices[i];
465: end = j + stripVertexCounts[i++];
466: getVertexData(j++, pnts[0]);
467: while (j < end) {
468: getVertexData(j++, pnts[1]);
469: if (intersectBoundingBox(pnts, box, null, null)) {
470: return true;
471: }
472: pnts[0].set(pnts[1]);
473: }
474: }
475: break;
476: case PickShape.PICKBOUNDINGSPHERE:
477: BoundingSphere bsphere = (BoundingSphere) targetBound;
478: while (i < stripVertexCounts.length) {
479: j = stripStartVertexIndices[i];
480: end = j + stripVertexCounts[i++];
481: getVertexData(j++, pnts[0]);
482: while (j < end) {
483: getVertexData(j++, pnts[1]);
484: if (intersectBoundingSphere(pnts, bsphere, null,
485: null)) {
486: return true;
487: }
488: pnts[0].set(pnts[1]);
489: }
490: }
491: break;
492: case PickShape.PICKBOUNDINGPOLYTOPE:
493: BoundingPolytope bpolytope = (BoundingPolytope) targetBound;
494:
495: while (i < stripVertexCounts.length) {
496: j = stripStartVertexIndices[i];
497: end = j + stripVertexCounts[i++];
498: getVertexData(j++, pnts[0]);
499: while (j < end) {
500: getVertexData(j++, pnts[1]);
501: if (intersectBoundingPolytope(pnts, bpolytope,
502: null, null)) {
503: return true;
504: }
505: pnts[0].set(pnts[1]);
506: }
507: }
508: break;
509: default:
510: throw new RuntimeException(
511: "Bounds not supported for intersection "
512: + targetBound);
513: }
514:
515: return false;
516: }
517:
518: // From Graphics Gems IV (pg5) and Graphics Gems II, Pg170
519: void computeCentroid() {
520: int i = 0;
521: int j;
522: double length;
523: double totallength = 0;
524: int start, end;
525: boolean replaceVertex1;
526: Point3d pnt0 = new Point3d();
527: Point3d pnt1 = new Point3d();
528:
529: centroid.x = 0;
530: centroid.y = 0;
531: centroid.z = 0;
532:
533: while (i < stripVertexCounts.length) {
534: j = stripStartVertexIndices[i];
535: end = j + stripVertexCounts[i++];
536: getVertexData(j++, pnt0);
537: replaceVertex1 = true;
538: while (j < end) {
539: if (replaceVertex1) {
540: getVertexData(j++, pnt1);
541: replaceVertex1 = false;
542: } else {
543: getVertexData(j++, pnt0);
544: replaceVertex1 = true;
545: }
546: length = pnt0.distance(pnt1);
547: centroid.x += (pnt0.x + pnt1.x) * length;
548: centroid.y += (pnt0.y + pnt1.y) * length;
549: centroid.z += (pnt0.z + pnt1.z) * length;
550: totallength += length;
551: }
552: }
553: if (totallength != 0.0) {
554: length = 1.0 / (2.0 * totallength);
555: centroid.x *= length;
556: centroid.y *= length;
557: centroid.z *= length;
558: }
559: }
560:
561: int getClassType() {
562: return LINE_TYPE;
563: }
564:
565: }
|