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