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