@Override boolean intersect(Point3d[] pnts) { Transform3D tempT3D = new Transform3D(); GeometryArrayRetained ga; boolean isIntersect = false; Point3d transPnts[] = new Point3d[pnts.length]; for (int j = pnts.length - 1; j >= 0; j--) { transPnts[j] = new Point3d(); } for (int i = numChars - 1; i >= 0; i--) { ga = geometryList[i]; if (ga != null) { tempT3D.invert(charTransforms[i]); for (int j = pnts.length - 1; j >= 0; j--) { tempT3D.transform(pnts[j], transPnts[j]); } if (ga.intersect(transPnts)) { isIntersect = true; break; } } } return isIntersect; }
@Override boolean intersect(Bounds targetBound) { GeometryArrayRetained ga; for (int i = numChars - 1; i >= 0; i--) { ga = geometryList[i]; if ((ga != null) && ga.intersect(targetBound)) { return true; } } return false; }
@Override boolean intersect(Transform3D thisToOtherVworld, GeometryRetained geom) { GeometryArrayRetained ga; for (int i = numChars - 1; i >= 0; i--) { ga = geometryList[i]; if ((ga != null) && ga.intersect(thisToOtherVworld, geom)) { return true; } } return false; }
// TODO -- Need to rethink. Might have to consider charTransform[] in returns pickInfo. @Override boolean intersect( PickShape pickShape, PickInfo pickInfo, int flags, Point3d iPnt, GeometryRetained geom, int geomIndex) { Transform3D tempT3D = new Transform3D(); GeometryArrayRetained geo = null; int sIndex = -1; PickShape newPS; double minDist = Double.MAX_VALUE; double distance = 0.0; Point3d closestIPnt = new Point3d(); for (int i = 0; i < numChars; i++) { geo = geometryList[i]; if (geo != null) { tempT3D.invert(charTransforms[i]); newPS = pickShape.transform(tempT3D); if (geo.intersect(newPS, pickInfo, flags, iPnt, geom, geomIndex)) { if (flags == 0) { return true; } distance = newPS.distance(iPnt); if (distance < minDist) { sIndex = i; minDist = distance; closestIPnt.set(iPnt); } } } } if (sIndex >= 0) { // We need to transform iPnt to the vworld to compute the actual distance. // In this method we'll transform iPnt by its char. offset. Shape3D will // do the localToVworld transform. iPnt.set(closestIPnt); charTransforms[sIndex].transform(iPnt); return true; } return false; }
/** * Returns a GeometryArray of a glyph in this Font3D. * * @param c character from which to generate a tessellated glyph. * @return a GeometryArray * @since Java 3D 1.4 */ public GeometryArray getGlyphGeometry(char c) { char code[] = {c}; GlyphVector gv = font.createGlyphVector(frc, code); // triangulate the glyph GeometryArrayRetained glyph_gar = triangulateGlyphs(gv, code[0]); // Assume that triangulateGlyphs returns a triangle array with only coords & normals // (and without by-ref, interleaved, etc.) assert glyph_gar instanceof TriangleArrayRetained : "Font3D: GeometryArray is not an instance of TrangleArray"; assert glyph_gar.getVertexFormat() == (GeometryArray.COORDINATES | GeometryArray.NORMALS) : "Font3D: Illegal GeometryArray format -- only coordinates and normals expected"; // create a correctly sized TriangleArray TriangleArray ga = new TriangleArray(glyph_gar.getVertexCount(), glyph_gar.getVertexFormat()); // temp storage for coords, normals float tmp[] = new float[3]; int vertexCount = ga.getVertexCount(); for (int i = 0; i < vertexCount; i++) { // copy the glyph geometry to the TriangleArray glyph_gar.getCoordinate(i, tmp); ga.setCoordinate(i, tmp); glyph_gar.getNormal(i, tmp); ga.setNormal(i, tmp); } return ga; }
Shape3DCompileRetained(Shape3DRetained[] shapes, int nShapes, int compileFlags) { int i, j; Shape3DRetained shape; GeometryArrayRetained geo; Vector list; // Merged list, only merged if geometry is mergeable Object[] mergedList = new Object[GeometryRetained.GEO_TYPE_GEOMETRYARRAY + 1]; // Sorted list of separate geometry by geoType Object[] separateList = new Object[GeometryRetained.GEO_TYPE_GEOMETRYARRAY + 1]; // Assign the num of shapes numShapes = nShapes; Bounds shapeBounds; srcList = new Object[nShapes]; if (nShapes > 0) { boundsAutoCompute = shapes[0].boundsAutoCompute; source = shapes[0].source; } // Remove the null that was added by Shape3DRetained constructor geometryList.remove(0); int geoIndex = 0; // Assign the fields for this compile shape boundsAutoCompute = shapes[0].boundsAutoCompute; isPickable = shapes[0].isPickable; isCollidable = shapes[0].isCollidable; appearanceOverrideEnable = shapes[0].appearanceOverrideEnable; appearance = shapes[0].appearance; collisionBound = shapes[0].collisionBound; localBounds = shapes[0].localBounds; if ((compileFlags & CompileState.GEOMETRY_READ) != 0) geometryInfo = new ArrayList(); for (i = 0; i < nShapes; i++) { shape = shapes[i]; ((Shape3D) shape.source).id = i; shape.source.retained = this; srcList[i] = shape.source; // If the transform has been pushd down // to the shape, don't merge its geometry with other shapes // geometry // Put it in a separate list sorted by geo_type // Have to handle shape.isPickable for (j = 0; j < shape.geometryList.size(); j++) { geo = (GeometryArrayRetained) shape.geometryList.get(j); if (geo != null) { if (shape.willRemainOpaque(geo.geoType) && geo.isMergeable()) { if (mergedList[geo.geoType] == null) { mergedList[geo.geoType] = new ArrayList(); } ((ArrayList) mergedList[geo.geoType]).add(geo); } else { // Keep a sorted list based on geoType; if (separateList[geo.geoType] == null) { separateList[geo.geoType] = new ArrayList(); } // add it to the geometryList separately ((ArrayList) separateList[geo.geoType]).add(geo); } } } // Point to the geometryList's source, so the // retained side will be garbage collected if ((compileFlags & CompileState.GEOMETRY_READ) != 0) { ArrayList sList = new ArrayList(); for (j = 0; j < shape.geometryList.size(); j++) { GeometryRetained g = (GeometryRetained) shape.geometryList.get(j); if (g != null) sList.add(g.source); else sList.add(null); } geometryInfo.add(sList); } } // Now, merged the mergelist and separate list based on geoType, // this enables dlist optmization for (i = 1; i <= GeometryRetained.GEO_TYPE_GEOMETRYARRAY; i++) { GeometryArrayRetained cgeo = null; ArrayList curList; switch (i) { case GeometryArrayRetained.GEO_TYPE_QUAD_SET: if (mergedList[i] != null) { cgeo = new QuadArrayRetained(); curList = (ArrayList) mergedList[i]; cgeo.setCompiled(curList); geometryList.add(cgeo); cgeo.setSource(((SceneGraphObjectRetained) curList.get(0)).source); } if (separateList[i] != null) { ArrayList glist = (ArrayList) separateList[i]; for (int k = 0; k < glist.size(); k++) { geometryList.add(glist.get(k)); } } break; case GeometryArrayRetained.GEO_TYPE_TRI_SET: if (mergedList[i] != null) { cgeo = new TriangleArrayRetained(); curList = (ArrayList) mergedList[i]; cgeo.setCompiled(curList); geometryList.add(cgeo); cgeo.setSource(((SceneGraphObjectRetained) curList.get(0)).source); } if (separateList[i] != null) { ArrayList glist = (ArrayList) separateList[i]; for (int k = 0; k < glist.size(); k++) { geometryList.add(glist.get(k)); } } break; case GeometryArrayRetained.GEO_TYPE_POINT_SET: if (mergedList[i] != null) { cgeo = new PointArrayRetained(); curList = (ArrayList) mergedList[i]; cgeo.setCompiled(curList); geometryList.add(cgeo); cgeo.setSource(((SceneGraphObjectRetained) curList.get(0)).source); } if (separateList[i] != null) { ArrayList glist = (ArrayList) separateList[i]; for (int k = 0; k < glist.size(); k++) { geometryList.add(glist.get(k)); } } break; case GeometryArrayRetained.GEO_TYPE_LINE_SET: if (mergedList[i] != null) { cgeo = new LineArrayRetained(); curList = (ArrayList) mergedList[i]; cgeo.setCompiled(curList); geometryList.add(cgeo); cgeo.setSource(((SceneGraphObjectRetained) curList.get(0)).source); } if (separateList[i] != null) { ArrayList glist = (ArrayList) separateList[i]; for (int k = 0; k < glist.size(); k++) { geometryList.add(glist.get(k)); } } break; case GeometryArrayRetained.GEO_TYPE_TRI_STRIP_SET: if (mergedList[i] != null) { cgeo = new TriangleStripArrayRetained(); curList = (ArrayList) mergedList[i]; cgeo.setCompiled(curList); geometryList.add(cgeo); cgeo.setSource(((SceneGraphObjectRetained) curList.get(0)).source); } if (separateList[i] != null) { ArrayList glist = (ArrayList) separateList[i]; for (int k = 0; k < glist.size(); k++) { geometryList.add(glist.get(k)); } } break; case GeometryArrayRetained.GEO_TYPE_TRI_FAN_SET: if (mergedList[i] != null) { cgeo = new TriangleFanArrayRetained(); curList = (ArrayList) mergedList[i]; cgeo.setCompiled(curList); geometryList.add(cgeo); cgeo.setSource(((SceneGraphObjectRetained) curList.get(0)).source); } if (separateList[i] != null) { ArrayList glist = (ArrayList) separateList[i]; for (int k = 0; k < glist.size(); k++) { geometryList.add(glist.get(k)); } } break; case GeometryArrayRetained.GEO_TYPE_LINE_STRIP_SET: if (mergedList[i] != null) { cgeo = new LineStripArrayRetained(); curList = (ArrayList) mergedList[i]; cgeo.setCompiled(curList); geometryList.add(cgeo); cgeo.setSource(((SceneGraphObjectRetained) curList.get(0)).source); } if (separateList[i] != null) { ArrayList glist = (ArrayList) separateList[i]; for (int k = 0; k < glist.size(); k++) { geometryList.add(glist.get(k)); } } break; case GeometryArrayRetained.GEO_TYPE_INDEXED_QUAD_SET: if (mergedList[i] != null) { cgeo = new IndexedQuadArrayRetained(); curList = (ArrayList) mergedList[i]; cgeo.setCompiled(curList); geometryList.add(cgeo); cgeo.setSource(((SceneGraphObjectRetained) curList.get(0)).source); } if (separateList[i] != null) { ArrayList glist = (ArrayList) separateList[i]; for (int k = 0; k < glist.size(); k++) { geometryList.add(glist.get(k)); } } break; case GeometryArrayRetained.GEO_TYPE_INDEXED_TRI_SET: if (mergedList[i] != null) { cgeo = new IndexedTriangleArrayRetained(); curList = (ArrayList) mergedList[i]; cgeo.setCompiled(curList); geometryList.add(cgeo); cgeo.setSource(((SceneGraphObjectRetained) curList.get(0)).source); } if (separateList[i] != null) { ArrayList glist = (ArrayList) separateList[i]; for (int k = 0; k < glist.size(); k++) { geometryList.add(glist.get(k)); } } break; case GeometryArrayRetained.GEO_TYPE_INDEXED_POINT_SET: if (mergedList[i] != null) { cgeo = new IndexedPointArrayRetained(); curList = (ArrayList) mergedList[i]; cgeo.setCompiled(curList); geometryList.add(cgeo); cgeo.setSource(((SceneGraphObjectRetained) curList.get(0)).source); } if (separateList[i] != null) { ArrayList glist = (ArrayList) separateList[i]; for (int k = 0; k < glist.size(); k++) { geometryList.add(glist.get(k)); } } break; case GeometryArrayRetained.GEO_TYPE_INDEXED_LINE_SET: if (mergedList[i] != null) { cgeo = new IndexedLineArrayRetained(); curList = (ArrayList) mergedList[i]; cgeo.setCompiled(curList); geometryList.add(cgeo); cgeo.setSource(((SceneGraphObjectRetained) curList.get(0)).source); } if (separateList[i] != null) { ArrayList glist = (ArrayList) separateList[i]; for (int k = 0; k < glist.size(); k++) { geometryList.add(glist.get(k)); } } break; case GeometryArrayRetained.GEO_TYPE_INDEXED_TRI_STRIP_SET: if (mergedList[i] != null) { cgeo = new IndexedTriangleStripArrayRetained(); curList = (ArrayList) mergedList[i]; cgeo.setCompiled(curList); geometryList.add(cgeo); cgeo.setSource(((SceneGraphObjectRetained) curList.get(0)).source); } if (separateList[i] != null) { ArrayList glist = (ArrayList) separateList[i]; for (int k = 0; k < glist.size(); k++) { geometryList.add(glist.get(k)); } } break; case GeometryArrayRetained.GEO_TYPE_INDEXED_TRI_FAN_SET: if (mergedList[i] != null) { cgeo = new IndexedTriangleFanArrayRetained(); curList = (ArrayList) mergedList[i]; cgeo.setCompiled(curList); geometryList.add(cgeo); cgeo.setSource(((SceneGraphObjectRetained) curList.get(0)).source); } if (separateList[i] != null) { ArrayList glist = (ArrayList) separateList[i]; for (int k = 0; k < glist.size(); k++) { geometryList.add(glist.get(k)); } } break; case GeometryArrayRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET: if (mergedList[i] != null) { cgeo = new IndexedLineStripArrayRetained(); curList = (ArrayList) mergedList[i]; cgeo.setCompiled(curList); geometryList.add(cgeo); cgeo.setSource(((SceneGraphObjectRetained) curList.get(0)).source); } if (separateList[i] != null) { ArrayList glist = (ArrayList) separateList[i]; for (int k = 0; k < glist.size(); k++) { geometryList.add(glist.get(k)); } } break; } } }