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