protected boolean onMoveHotPoint(MoveHotPointEvent event) { NullCheck.notNull(event, "event"); final int x = event.getNewHotPointX(); final int y = event.getNewHotPointY(); final int newY; if (y >= getLineCount()) { if (event.precisely()) return false; newY = getLineCount() - 1; } else newY = y; if (getItemIndexOnLine(newY) >= 0) { // Line with item, not empty final Object item = model.getItem(getItemIndexOnLine(newY)); final int leftBound = appearance.getObservableLeftBound(item); final int rightBound = appearance.getObservableRightBound(item); if (event.precisely() && (x < leftBound || x > rightBound)) return false; hotPointY = newY; hotPointX = x; if (hotPointX < leftBound) hotPointX = leftBound; if (hotPointX > rightBound) hotPointX = rightBound; environment.onAreaNewHotPoint(this); return true; } // On empty line hotPointY = newY; hotPointX = 0; environment.onAreaNewHotPoint(this); return true; }
protected boolean onChar(KeyboardEvent event) { if (noContent()) return true; final int count = model.getItemCount(); final char c = event.getChar(); final String beginning; if (selected() != null) { if (hotPointX >= appearance.getObservableRightBound(selected())) return false; final String name = getObservableSubstr(selected()); final int pos = Math.min(hotPointX - appearance.getObservableLeftBound(selected()), name.length()); if (pos < 0) return false; beginning = name.substring(0, pos); } else beginning = ""; Log.debug("list", "beginning:" + beginning); final String mustBegin = beginning + c; for (int i = 0; i < count; ++i) { Log.debug("list", "checking:" + i); final String name = getObservableSubstr(model.getItem(i)); Log.debug("list", "name:" + name); if (!name.startsWith(mustBegin)) continue; hotPointY = getLineIndexByItemIndex(i); Log.debug("list", "hotPointY:" + hotPointY); ++hotPointX; appearance.announceItem(model.getItem(hotPointY), NONE_APPEARANCE_FLAGS); environment.onAreaNewHotPoint(this); return true; } return false; }
protected boolean onBeginListeningQuery(BeginListeningQuery query) { NullCheck.notNull(query, "query"); final int index = selectedIndex(); if (index < 0) return false; final int count = model.getItemCount(); if (index >= count) return false; final Object current = model.getItem(index); final String text = appearance .getScreenAppearance(current, NONE_APPEARANCE_FLAGS) .substring(hotPointX, appearance.getObservableRightBound(current)); // Log.debug("listen", appearance.getScreenAppearance(current, NONE_APPEARANCE_FLAGS)); // Log.debug("listen", "" + hotPointX); if (text.isEmpty() && index + 1 >= count) return false; if (index + 1 < count) { final Object next = model.getItem(index + 1); query.answer( new BeginListeningQuery.Answer( text, new ListeningInfo(index + 1, appearance.getObservableLeftBound(next)))); } else query.answer( new BeginListeningQuery.Answer( text, new ListeningInfo(index, appearance.getObservableRightBound(current)))); return true; }
private boolean onAltLeft(KeyboardEvent event) { if (noContent()) return true; final Object item = selected(); if (item == null) { environment.hint(Hints.EMPTY_LINE); return true; } final String line = appearance.getScreenAppearance(item, NONE_APPEARANCE_FLAGS); NullCheck.notNull(line, "line"); if (line.isEmpty()) { environment.hint(Hints.EMPTY_LINE); return true; } final int leftBound = appearance.getObservableLeftBound(item); final int rightBound = appearance.getObservableRightBound(item); if (hotPointX <= leftBound) { environment.hint(Hints.BEGIN_OF_LINE); return true; } final String subline = line.substring(leftBound, rightBound); final WordIterator it = new WordIterator(subline, hotPointX - leftBound); if (!it.stepBackward()) { environment.hint(Hints.BEGIN_OF_LINE); return true; } hotPointX = it.pos() + leftBound; environment.say(it.announce()); environment.onAreaNewHotPoint(this); return true; }
// In this method, the objects for the scene are generated and added to // the SimpleUniverse. public void createSceneGraph(SimpleUniverse su) { // *** The root of the graph containing the scene (with a cube and a sphere). *** BranchGroup theScene = new BranchGroup(); // Generate an Appearance. Color3f ambientColourShaded = new Color3f(0.0f, 0.4f, 0.4f); Color3f emissiveColourShaded = new Color3f(0.0f, 0.0f, 0.0f); Color3f diffuseColourShaded = new Color3f(0.0f, 0.7f, 0.7f); Color3f specularColourShaded = new Color3f(0.0f, 0.5f, 0.5f); float shininessShaded = 20.0f; Appearance shadedApp = new Appearance(); shadedApp.setMaterial( new Material( ambientColourShaded, emissiveColourShaded, diffuseColourShaded, specularColourShaded, shininessShaded)); float r = 0.3f; // The radius of the sphere. float boxHL = 0.7f * r; // Half the vertex length of the cube. float shift = 3.0f * r; // Distance between cube and sphere. // *** The sphere and its transformation group *** Sphere s = new Sphere(r, Sphere.GENERATE_NORMALS, 100, shadedApp); Transform3D tfSphere = new Transform3D(); tfSphere.setTranslation(new Vector3f(-0.95f + r, 0.0f, 0.0f)); TransformGroup tgSphere = new TransformGroup(tfSphere); tgSphere.addChild(s); theScene.addChild(tgSphere); // *** The cube and its transformation group *** Box b2 = new Box(boxHL, boxHL, boxHL, shadedApp); Transform3D tfBox2 = new Transform3D(); tfBox2.setTranslation(new Vector3f(-0.95f + r + shift, 0.0f, 0.0f)); Transform3D rotation = new Transform3D(); rotation.rotY(Math.PI / 4); Transform3D rotationX = new Transform3D(); rotationX.rotX(Math.PI / 6); rotation.mul(rotationX); tfBox2.mul(rotation); TransformGroup tgBox2 = new TransformGroup(tfBox2); tgBox2.addChild(b2); theScene.addChild(tgBox2); // Generate a white background. Background bg = new Background(new Color3f(1.0f, 1.0f, 1.0f)); BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), Double.MAX_VALUE); bg.setApplicationBounds(bounds); theScene.addChild(bg); theScene.compile(); // Add the scene to the universe. su.addBranchGraph(theScene); }
/** * Simple algorithm to add or remove an edge from the selection Ideas: 1. Use one shape per quad * => easy, but can become very fast too big to fit in memory. => pb: flicker when adding / * removing because the scene is detached 2. Use only one shape, modify geometry TODO: pre-create * an empty shape to avoid initial flicker * * @param on * @param p * @param u * @param v * @param groupIdx2 */ protected void toggleSelectedEdge(boolean on, SelectionEdge se) { if (on) { // add the given edge to the list if (edgeSelection.contains(se)) return; // already in edgeSelection.add(se); } else { // remove the given edge from the list if (!edgeSelection.contains(se)) return; // not present edgeSelection.remove(se); if (edgeSelection.size() == 0) { LineArray la = (LineArray) edgeSelectionShape.getGeometry(); la.setValidVertexCount(0); return; } } // Use in-memory arrays instead of NIO because edgeSelection should not // be too big // => faster LineArray la = new LineArray( edgeSelection.size() * 2, GeometryArray.COORDINATES | GeometryArray.COLOR_3 | GeometryArray.BY_REFERENCE); double[] coords = new double[edgeSelection.size() * 2 * 3]; float[] colors = new float[edgeSelection.size() * 2 * 3]; for (int i = 0; i < coords.length; i += 6) { SelectionEdge edge = edgeSelection.get(i / 6); edge.updateCoords(grid, coords, i); edge.updateColors(colors, i); } la.setCoordRefDouble(coords); la.setColorRefFloat(colors); la.setCapability(GeometryArray.ALLOW_COUNT_WRITE); // update edgeSelection Shape with the new edgeSelection list if (edgeSelectionShape == null) { Appearance a = new Appearance(); // PolygonAttributes pa = new // PolygonAttributes(PolygonAttributes.POLYGON_LINE, // PolygonAttributes.CULL_NONE, 0); // pa.setPolygonOffset(1); // above edges // pa.setPolygonOffsetFactor(1); LineAttributes lat = new LineAttributes(); lat.setLineWidth(2.0f); lat.setLineAntialiasingEnable(true); a.setLineAttributes(lat); // a.setPolygonAttributes(pa); edgeSelectionShape = new Shape3D(la, a); edgeSelectionShape.setUserData(this); edgeSelectionShape.setPickable(false); edgeSelectionShape.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE); edgeSelectionShape.setCapability(Shape3D.ALLOW_GEOMETRY_READ); BranchGroup bg = new BranchGroup(); bg.addChild(edgeSelectionShape); addChild(bg); } else edgeSelectionShape.setGeometry(la); }
// In this method, the objects for the scene are generated and added to // the SimpleUniverse. public void createSceneGraph(SimpleUniverse su) { // Create the root of the branch group for the scene. BranchGroup theScene = new BranchGroup(); // Generate an Appearance for the sphere. Color3f ambientColourSphere = new Color3f(0.2f, 0.2f, 0.2f); Color3f emissiveColourSphere = new Color3f(0.0f, 0.0f, 0.0f); Color3f diffuseColourSphere = new Color3f(0.6f, 0.6f, 0.6f); Color3f specularColourSphere = new Color3f(0.5f, 0.5f, 0.5f); float shininessSphere = 20.0f; Appearance sphereApp = new Appearance(); sphereApp.setMaterial( new Material( ambientColourSphere, emissiveColourSphere, diffuseColourSphere, specularColourSphere, shininessSphere)); // n spheres with radius r will be shown. int n = 5; float r = 0.15f; float shift = 2 * r + 0.05f; // The distance between the centres of the spheres. // Arrays for the sphere, their transformations and their transformation groups // transformation groups (for positioning). Sphere[] spheres = new Sphere[n]; TransformGroup[] tg = new TransformGroup[n]; Transform3D[] tf = new Transform3D[n]; // Generate the sphere, their transformations and their // transformation groups. Add everyting to the scene. for (int i = 0; i < n; i++) { spheres[i] = new Sphere(r, Sphere.GENERATE_NORMALS, 4 + i * i * i, sphereApp); tf[i] = new Transform3D(); tf[i].setTranslation(new Vector3f(-0.95f + r + shift * i, 0.0f, 0.0f)); tg[i] = new TransformGroup(tf[i]); tg[i].addChild(spheres[i]); theScene.addChild(tg[i]); } // Generate a white background. Background bg = new Background(new Color3f(1.0f, 1.0f, 1.0f)); BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 1000.0); bg.setApplicationBounds(bounds); theScene.addChild(bg); theScene.compile(); // Add the scene to the universe. su.addBranchGraph(theScene); }
protected String getObservableSubstr(Object item) { NullCheck.notNull(item, "item"); final String line = appearance.getScreenAppearance(item, NONE_APPEARANCE_FLAGS); NullCheck.notNull(line, "line"); if (line.isEmpty()) return ""; final int leftBound = Math.min(appearance.getObservableLeftBound(item), line.length()); final int rightBound = Math.min(appearance.getObservableRightBound(item), line.length()); if (leftBound >= rightBound) return ""; return line.substring(leftBound, rightBound); }
private void createAppearance() { Appearance app = new Appearance(); PolygonAttributes pa = new PolygonAttributes(); pa.setCullFace(PolygonAttributes.CULL_NONE); // so can see the ColouredTiles from both sides app.setPolygonAttributes(pa); setAppearance(app); } // end of createAppearance()
private boolean updateFrame() { if (frame < 0 || frame >= frameList.getNumResources()) { return false; } Appearance newAppearance = (Appearance) frameList.getResource(frame); if ((animation != null && newAppearance != animation) || animation == null) { return newAppearance.toSprite(this); } else { return false; } }
private boolean onAltHome(KeyboardEvent event) { if (noContent()) return true; final Object item = selected(); NullCheck.notNull(item, "item"); final String line = appearance.getScreenAppearance(item, NONE_APPEARANCE_FLAGS); NullCheck.notNull(line, "line"); hotPointX = appearance.getObservableLeftBound(item); announceChar(line, hotPointX, appearance.getObservableRightBound(item)); environment.onAreaNewHotPoint(this); return true; }
/** * Simple algorithm to add or remove a quad from the selection Ideas: 1. Use one shape per quad => * easy, but can become very fast too big to fit in memory. => pb: flicker when adding / removing * because the scene is detached 2. Use only one shape, modify geometry TODO: pre-create an empty * shape to avoid initial flicker * * @param on * @param p * @param u * @param v * @param groupIdx2 */ protected void toggleSelectedQuad(boolean on, SelectionQuad sq) { LOGGER.finest("on=" + on + " selectionQuad=" + sq); if (on) { // add the given quad to the list if (selection.contains(sq)) return; // already in selection.add(sq); } else { // remove the given quad from the list if (!selection.contains(sq)) return; // not present selection.remove(sq); if (selection.size() == 0) { QuadArray qa = (QuadArray) selectionShape.getGeometry(); qa.setValidVertexCount(0); return; } } // Use in-memory arrays instead of NIO because selection should not be // too big // => faster QuadArray qa = new QuadArray( selection.size() * 4, GeometryArray.COORDINATES | GeometryArray.COLOR_3 | GeometryArray.BY_REFERENCE); float[] coords = new float[selection.size() * 4 * 3]; float[] colors = new float[selection.size() * 4 * 3]; for (int i = 0; i < coords.length; i += 12) { SelectionQuad quad = selection.get(i / 12); quad.updateCoords(grid, coords, i); quad.updateColors(colors, i); } qa.setCoordRefFloat(coords); qa.setColorRefFloat(colors); qa.setCapability(GeometryArray.ALLOW_COUNT_WRITE); // update selection Shape with the new selection list if (selectionShape == null) { Appearance a = new Appearance(); PolygonAttributes pa = new PolygonAttributes(PolygonAttributes.POLYGON_FILL, PolygonAttributes.CULL_NONE, 0); pa.setPolygonOffset(0.5f); // between faces and edges pa.setPolygonOffsetFactor(0.5f); a.setPolygonAttributes(pa); selectionShape = new Shape3D(qa, a); selectionShape.setUserData(this); selectionShape.setPickable(false); selectionShape.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE); selectionShape.setCapability(Shape3D.ALLOW_GEOMETRY_READ); BranchGroup bg = new BranchGroup(); bg.addChild(selectionShape); addChild(bg); } else selectionShape.setGeometry(qa); }
/** * Searches for the item in the model and sets hot point on it. Given an arbitrary object, this * method looks through all items in the model and does a couple of checks: literal pointers * equality and a check with {@code equals()} method. If at least one of these checks succeeds, * the item is considered equal to the given one, and hot points is set on it. * * @param obj The object to search for * @param introduce Must be true if it is necessary to introduce the object, once it's found * @return True if the request object is found, false otherwise */ public boolean select(Object obj, boolean introduce) { NullCheck.notNull(obj, "obj"); for (int i = 0; i < model.getItemCount(); ++i) { final Object o = model.getItem(i); if (o == null || (obj != o && !obj.equals(o))) continue; hotPointY = i; hotPointX = appearance.getObservableLeftBound(o); environment.onAreaNewHotPoint(this); if (introduce) appearance.announceItem(o, NONE_APPEARANCE_FLAGS); return true; } return false; }
private boolean onAltEnd(KeyboardEvent event) { if (noContent()) return true; final Object item = selected(); if (item == null) { environment.hint(Hints.EMPTY_LINE); return true; } final String line = appearance.getScreenAppearance(item, NONE_APPEARANCE_FLAGS); NullCheck.notNull(line, "line"); hotPointX = appearance.getObservableRightBound(item); environment.hint(Hints.END_OF_LINE); environment.onAreaNewHotPoint(this); return true; }
protected boolean onListeningFinishedEvent(ListeningFinishedEvent event) { NullCheck.notNull(event, "event"); if (!(event.getExtraInfo() instanceof ListeningInfo)) return false; final ListeningInfo info = (ListeningInfo) event.getExtraInfo(); final int count = model.getItemCount(); if (info.itemIndex >= count) return false; final Object item = model.getItem(info.itemIndex); final int leftBound = appearance.getObservableLeftBound(item); final int rightBound = appearance.getObservableRightBound(item); if (info.pos < leftBound || info.pos > rightBound) return false; hotPointY = getLineIndexByItemIndex(info.itemIndex); hotPointX = info.pos; environment.onAreaNewHotPoint(this); return true; }
/** * Selects the item by its index. Given the non-negative integer value as an index, this method * sets the hot point on the item addressed with this index, checking only that index is in * appropriate bounds. Index must address the object as a number in the model, ignoring any empty * lines. * * @param index The item index to select * @param announce Must be true, if it is necessary to announce the item , once it has been * selected * @return True if the index is valid and the item gets hot point on it */ public boolean select(int index, boolean announce) { if (index < 0 || index >= model.getItemCount()) return false; final int emptyCountAbove = flags.contains(Flags.EMPTY_LINE_TOP) ? 1 : 0; hotPointY = index + emptyCountAbove; final Object item = model.getItem(index); if (item != null) { hotPointX = appearance.getObservableLeftBound(item); if (announce) appearance.announceItem(item, NONE_APPEARANCE_FLAGS); } else { hotPointX = 0; if (announce) environment.hint(Hints.EMPTY_LINE); } environment.onAreaNewHotPoint(this); return true; }
@Override public String getLine(int index) { if (isEmpty()) return index == 0 ? noContentStr() : ""; final int itemIndex = getItemIndexOnLine(index); if (itemIndex < 0 || itemIndex >= model.getItemCount()) return ""; final Object res = model.getItem(itemIndex); return res != null ? appearance.getScreenAppearance(res, NONE_APPEARANCE_FLAGS) : ""; }
/** * Sets the sprite's appearance. * * @param appearance */ public void setAppearance(Appearance appearance) { if (appearance == null) { image = null; setAnimation(null); rewind(); } else { appearance.toSprite(this); } }
public void resetHotPoint(boolean introduce) { hotPointY = 0; final int count = model.getItemCount(); if (count < 1) { hotPointX = 0; environment.onAreaNewHotPoint(this); return; } final Object item = model.getItem(0); if (item != null) { hotPointX = item != null ? appearance.getObservableLeftBound(item) : 0; if (introduce) appearance.announceItem(item, NONE_APPEARANCE_FLAGS); } else { hotPointX = 0; environment.hint(Hints.EMPTY_LINE); } environment.onAreaNewHotPoint(this); }
protected boolean onAnnounce() { environment.playSound(Sounds.INTRO_REGULAR); String item = ""; if (selected() != null) item = appearance.getScreenAppearance(selected(), EnumSet.noneOf(Appearance.Flags.class)).trim(); if (!item.isEmpty()) item = " " + item; environment.say(getAreaName() + item); return true; }
protected boolean onAnnounceLine() { if (isEmpty()) return false; final Object item = selected(); if (item == null) { environment.hint(Hints.EMPTY_LINE); return true; } appearance.announceItem(item, NONE_APPEARANCE_FLAGS); return true; }
protected void onNewHotPointY(boolean briefAnnouncement) { final int index = selectedIndex(); if (index < 0) { environment.hint(Hints.EMPTY_LINE); hotPointX = 0; environment.onAreaNewHotPoint(this); return; } final Object item = model.getItem(index); if (item == null) { environment.hint(Hints.EMPTY_LINE); hotPointX = 0; environment.onAreaNewHotPoint(this); return; } appearance.announceItem( item, briefAnnouncement ? BRIEF_ANNOUNCEMENT_ONLY : NONE_APPEARANCE_FLAGS); hotPointX = appearance.getObservableLeftBound(item); environment.onAreaNewHotPoint(this); }
protected boolean onArrowRight(KeyboardEvent event) { if (noContent()) return true; final Object item = selected(); NullCheck.notNull(item, "item"); final String line = appearance.getScreenAppearance(item, NONE_APPEARANCE_FLAGS); NullCheck.notNull(line, "line"); if (line.isEmpty()) { environment.hint(Hints.EMPTY_LINE); return true; } final int rightBound = appearance.getObservableRightBound(item); if (hotPointX >= rightBound) { environment.hint(Hints.END_OF_LINE); return true; } ++hotPointX; announceChar(line, hotPointX, rightBound); environment.onAreaNewHotPoint(this); return true; }
@Override public RegionContent getRegion(int fromX, int fromY, int toX, int toY) { if (model == null || model.getItemCount() < 0) return null; if (fromY >= model.getItemCount() || toY > model.getItemCount()) return null; if (fromY == toY) { final String line = appearance.getScreenAppearance(model.getItem(fromY), NONE_APPEARANCE_FLAGS); if (line == null || line.isEmpty()) return null; final int fromPos = fromX < line.length() ? fromX : line.length(); final int toPos = toX < line.length() ? toX : line.length(); if (fromPos >= toPos) return null; return new RegionContent(new String[] {line.substring(fromPos, toPos)}); } final LinkedList<String> res = new LinkedList<String>(); for (int i = fromY; i < toY; ++i) { final String line = appearance.getScreenAppearance(model.getItem(i), NONE_APPEARANCE_FLAGS); res.add(line != null ? line : ""); } res.add(""); return new RegionContent(res.toArray(new String[res.size()])); }
@Override public RegionContent getWholeRegion() { if (model == null || model.getItemCount() < 0) return null; final LinkedList<String> res = new LinkedList<String>(); final int count = model.getItemCount(); for (int i = 0; i < count; ++i) { final String line = appearance.getScreenAppearance(model.getItem(i), NONE_APPEARANCE_FLAGS); res.add(line != null ? line : ""); } res.add(""); return new RegionContent(res.toArray(new String[res.size()])); }
/** * Refreshes the content of the list. This method calls {@code refresh()} method of the model and * displays new items. It does not produce any speech announcement of the change. HotPointY is * preserved if it is possible (meaning, the new number of lines not less than old value of * hotPointY), but hotPointX is moved to the beginning of the line. */ public void refresh() { model.refresh(); final int count = model.getItemCount(); if (count == 0) { hotPointX = 0; hotPointY = 0; environment.onAreaNewContent(this); environment.onAreaNewHotPoint(this); return; } hotPointY = hotPointY < count ? hotPointY : count - 1; final Object item = model.getItem(hotPointY); if (item != null) hotPointX = appearance.getObservableLeftBound(item); else hotPointX = 0; environment.onAreaNewContent(this); environment.onAreaNewHotPoint(this); }
protected void makeGroups() { int totalQuads = 0; int totalInternalEdges = 0; int totalExternalEdges = 0; // loop over each group // loop over each group int[] groupID = provider.getDomainIDs(); for (int g = 0; g < groupID.length; ++g) { LOGGER.finest("generating java3d tree for group number " + groupID[g]); // Set of EdgeLine objects. Overlapping edges on the same line are // merged together HashMap<EdgeLine, EdgeLine> externalEdges = new HashMap<EdgeLine, EdgeLine>(); // Same trick for internal edges. HashMap<EdgeLine, EdgeLine> internalEdges = new HashMap<EdgeLine, EdgeLine>(); FDDomain fdDomain = (FDDomain) provider.getDomain(groupID[g]); baseColor.put(new Integer(g), fdDomain.getColor()); Plate[] plates = domainToPlates(fdDomain); if (plates.length == 0) continue; // Create plates for this group FloatBuffer nioCoords = ByteBuffer.allocateDirect(plates.length * 4 * 3 * 4) .order(ByteOrder.nativeOrder()) .asFloatBuffer(); FloatBuffer nioColors = ByteBuffer.allocateDirect(plates.length * 4 * 3 * 4) .order(ByteOrder.nativeOrder()) .asFloatBuffer(); float[] baseColor = getColorForOrder(g, 0); // System.out.println(baseColor[0]+" "+baseColor[1]+" "+baseColor[2]); for (int np = 0; np < plates.length; ++np) { Plate p = plates[np]; // put coordinates nioCoords.put(p.getCoordinates(grid)); // put colors for the 4 vertices nioColors.put(baseColor); nioColors.put(baseColor); nioColors.put(baseColor); nioColors.put(baseColor); // Merge external edges addEdge(externalEdges, getLine(p, 2, p.min1), p.min2, p.max2); addEdge(externalEdges, getLine(p, 2, p.max1), p.min2, p.max2); addEdge(externalEdges, getLine(p, 1, p.min2), p.min1, p.max1); addEdge(externalEdges, getLine(p, 1, p.max2), p.min1, p.max1); // Merge internal edges for (int i = p.min1 + 1; i < p.max1; ++i) addEdge(internalEdges, getLine(p, 2, i), p.min2, p.max2); for (int j = p.min2 + 1; j < p.max2; ++j) addEdge(internalEdges, getLine(p, 1, j), p.min1, p.max1); } // use by reference array of colors => fast to change! QuadArray qa = new NioQuadArray(plates.length * 4, GeometryArray.COORDINATES | GeometryArray.COLOR_3); qa.setCoordRefBuffer(new J3DBuffer(nioCoords)); qa.setColorRefBuffer(new J3DBuffer(nioColors)); qa.setCapability(GeometryArray.ALLOW_COLOR_WRITE); qa.setCapabilityIsFrequent(GeometryArray.ALLOW_COLOR_WRITE); Appearance a = new Appearance(); PolygonAttributes pa = new PolygonAttributes(PolygonAttributes.POLYGON_FILL, PolygonAttributes.CULL_NONE, 0); pa.setPolygonOffset(1); pa.setPolygonOffsetFactor(1); a.setPolygonAttributes(pa); Shape3D s3d = new Shape3D(qa, a); PickTool.setCapabilities(s3d, PickTool.INTERSECT_FULL); s3d.setCapability(Shape3D.ALLOW_APPEARANCE_READ); s3d.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE); s3d.setCapability(Node.ALLOW_PICKABLE_READ); s3d.setCapability(Node.ALLOW_PICKABLE_WRITE); s3d.setPickable(true); s3d.setUserData(new BehindShape(s3d, plates, g)); this.addChild(s3d); // Create edge shapes directly, don't make them appear in graph int nInternalEdges = 0; for (Iterator<EdgeLine> it = internalEdges.keySet().iterator(); it.hasNext(); ) { EdgeLine el = it.next(); nInternalEdges += el.getNumberOfEdges(); } if (nInternalEdges > 0) { DoubleBuffer nioInternalEdges = ByteBuffer.allocateDirect(nInternalEdges * 2 * 3 * 8) .order(ByteOrder.nativeOrder()) .asDoubleBuffer(); // create edge coords for (Iterator<EdgeLine> it = internalEdges.keySet().iterator(); it.hasNext(); ) { EdgeLine el = it.next(); nioInternalEdges.put(el.getCoords(grid)); } LineArray la = new NioLineArray(nInternalEdges * 2, GeometryArray.COORDINATES | GeometryArray.COLOR_3); la.setCoordRefBuffer(new J3DBuffer(nioInternalEdges)); int colSize = nInternalEdges * 2 * 3; FloatBuffer nioInternalColors = ByteBuffer.allocateDirect(colSize * 4).order(ByteOrder.nativeOrder()).asFloatBuffer(); float[] colors = getColorForOrder(g, 2); for (int i = 0; i < colSize; i += 3) nioInternalColors.put(colors); la.setColorRefBuffer(new J3DBuffer(nioInternalColors)); la.setUserData(new int[] {g, 2}); a = new Appearance(); // pa = new PolygonAttributes(PolygonAttributes.POLYGON_LINE, // PolygonAttributes.CULL_NONE, 0); // pa.setPolygonOffset(4); // pa.setPolygonOffsetFactor(4); // a.setPolygonAttributes(pa); // LineAttributes lat = new LineAttributes(); // lat.setLineAntialiasingEnable(true); // a.setLineAttributes(lat); // RenderingAttributes ra = new RenderingAttributes(); // ra.setAlphaTestFunction(RenderingAttributes.GREATER); // ra.setAlphaTestValue(0.5f); // a.setRenderingAttributes(ra); s3d = new Shape3D(la, a); PickTool.setCapabilities(s3d, PickTool.INTERSECT_FULL); s3d.setCapability(Shape3D.ALLOW_APPEARANCE_READ); s3d.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE); s3d.setCapability(Node.ALLOW_PICKABLE_READ); s3d.setCapability(Node.ALLOW_PICKABLE_WRITE); s3d.setPickable(false); // by default, see actions s3d.setUserData(this); // this object will handle edges this.addChild(s3d); allEdgeShapes.add(s3d); } // Now, create external edge int nExternalEdges = 0; for (Iterator<EdgeLine> it = externalEdges.keySet().iterator(); it.hasNext(); ) { EdgeLine el = it.next(); nExternalEdges += el.getNumberOfEdges(); } if (nExternalEdges > 0) { DoubleBuffer nioExternalEdges = ByteBuffer.allocateDirect(nExternalEdges * 2 * 3 * 8) .order(ByteOrder.nativeOrder()) .asDoubleBuffer(); // create edge coords for (Iterator<EdgeLine> it = externalEdges.keySet().iterator(); it.hasNext(); ) { EdgeLine el = it.next(); nioExternalEdges.put(el.getCoords(grid)); } LineArray la = new NioLineArray(nExternalEdges * 2, GeometryArray.COORDINATES | GeometryArray.COLOR_3); la.setCoordRefBuffer(new J3DBuffer(nioExternalEdges)); int colSize = nExternalEdges * 2 * 3; FloatBuffer nioExternalColors = ByteBuffer.allocateDirect(colSize * 4).order(ByteOrder.nativeOrder()).asFloatBuffer(); float[] colors = getColorForOrder(g, 4); for (int i = 0; i < colSize; i += 3) nioExternalColors.put(colors); la.setColorRefBuffer(new J3DBuffer(nioExternalColors)); la.setUserData(new int[] {g, 4}); a = new Appearance(); // pa = new PolygonAttributes(PolygonAttributes.POLYGON_LINE, // PolygonAttributes.CULL_NONE, 0); // pa.setPolygonOffset(3); // pa.setPolygonOffsetFactor(3); // a.setPolygonAttributes(pa); s3d = new Shape3D(la, a); PickTool.setCapabilities(s3d, PickTool.INTERSECT_FULL); s3d.setCapability(Shape3D.ALLOW_APPEARANCE_READ); s3d.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE); s3d.setCapability(Node.ALLOW_PICKABLE_READ); s3d.setCapability(Node.ALLOW_PICKABLE_WRITE); s3d.setPickable(false); // by default, see actions s3d.setUserData(this); // this object will handle edges this.addChild(s3d); allEdgeShapes.add(s3d); } totalQuads += plates.length; totalInternalEdges += nInternalEdges; totalExternalEdges += nExternalEdges; } System.out.println("Total quads: " + totalQuads); System.out.println("Total Internal Plate edges: " + totalInternalEdges); System.out.println("Total External Plate edges: " + totalExternalEdges); }
public void setTransparencyAndRenderingAttributes( TransparencyAttributes transparencyAttributes, boolean rendering) { super.setTransparencyAttributes(transparencyAttributes); super.getRenderingAttributes().setDepthBufferEnable(rendering); }
/** Setup the basic scene which consists of a quad and a viewpoint */ private void setupSceneGraph() { // View group Viewpoint vp = new Viewpoint(); Vector3f trans = new Vector3f(0, 0, 1); Matrix4f mat = new Matrix4f(); mat.setIdentity(); mat.setTranslation(trans); TransformGroup tx = new TransformGroup(); tx.addChild(vp); tx.setTransform(mat); Group scene_root = new Group(); scene_root.addChild(tx); // Flat panel that has the viewable object as the demo float[] coord = {0, 0, -1, 0.25f, 0, -1, 0, 0.25f, -1}; float[] normal = {0, 0, 1, 0, 0, 1, 0, 0, 1}; TriangleArray geom = new TriangleArray(); geom.setValidVertexCount(3); geom.setVertices(TriangleArray.COORDINATE_3, coord); geom.setNormals(normal); Material material = new Material(); material.setDiffuseColor(new float[] {0, 0, 1}); material.setEmissiveColor(new float[] {0, 0, 1}); material.setSpecularColor(new float[] {1, 1, 1}); material.setTransparency(0.5f); Appearance app = new Appearance(); app.setMaterial(material); Shape3D shape = new Shape3D(); shape.setGeometry(geom); shape.setAppearance(app); TransformGroup tg = new TransformGroup(); Matrix4f transform = new Matrix4f(); transform.setIdentity(); transform.setTranslation(new Vector3f(0.15f, 0, -1)); tg.setTransform(transform); Shape3D backShape = new Shape3D(); Material material2 = new Material(); material2.setDiffuseColor(new float[] {1, 0, 0}); material2.setEmissiveColor(new float[] {1, 0, 0}); material2.setSpecularColor(new float[] {1, 1, 1}); Appearance app2 = new Appearance(); app2.setMaterial(material2); backShape.setGeometry(geom); backShape.setAppearance(app2); tg.addChild(backShape); scene_root.addChild(tg); scene_root.addChild(shape); SimpleScene scene = new SimpleScene(); scene.setRenderedGeometry(scene_root); scene.setActiveView(vp); // Then the basic layer and viewport at the top: SimpleViewport view = new SimpleViewport(); view.setDimensions(0, 0, 500, 500); view.setScene(scene); SimpleLayer layer = new SimpleLayer(); layer.setViewport(view); Layer[] layers = {layer}; displayManager.setLayers(layers, 1); }
public static Object3D[] load(byte[] data, int offset) { DataInputStream old = dis; dis = new DataInputStream(new ByteArrayInputStream(data)); try { while (dis.available() > 0) { int objectType = readByte(); int length = readInt(); System.out.println("objectType: " + objectType); System.out.println("length: " + length); dis.mark(Integer.MAX_VALUE); if (objectType == 0) { int versionHigh = readByte(); int versionLow = readByte(); boolean hasExternalReferences = readBoolean(); int totolFileSize = readInt(); int approximateContentSize = readInt(); String authoringField = readString(); objs.addElement(new Group()); // dummy } else if (objectType == 255) { // TODO: load external resource System.out.println("Loader: Loading external resources not implemented."); String uri = readString(); } else if (objectType == 1) { System.out.println("Loader: AnimationController not implemented."); objs.addElement(new Group()); // dummy } else if (objectType == 2) { System.out.println("Loader: AnimationTrack not implemented."); objs.addElement(new Group()); // dummy } else if (objectType == 3) { // System.out.println("Appearance"); Appearance appearance = new Appearance(); loadObject3D(appearance); appearance.setLayer(readByte()); appearance.setCompositingMode((CompositingMode) getObject(readInt())); appearance.setFog((Fog) getObject(readInt())); appearance.setPolygonMode((PolygonMode) getObject(readInt())); appearance.setMaterial((Material) getObject(readInt())); int numTextures = readInt(); for (int i = 0; i < numTextures; ++i) appearance.setTexture(i, (Texture2D) getObject(readInt())); objs.addElement(appearance); } else if (objectType == 4) { // System.out.println("Background"); Background background = new Background(); loadObject3D(background); background.setColor(readRGBA()); background.setImage((Image2D) getObject(readInt())); int modeX = readByte(); int modeY = readByte(); background.setImageMode(modeX, modeY); int cropX = readInt(); int cropY = readInt(); int cropWidth = readInt(); int cropHeight = readInt(); background.setCrop(cropX, cropY, cropWidth, cropHeight); background.setDepthClearEnable(readBoolean()); background.setColorClearEnable(readBoolean()); objs.addElement(background); // dummy } else if (objectType == 5) { // System.out.println("Camera"); Camera camera = new Camera(); loadNode(camera); int projectionType = readByte(); if (projectionType == Camera.GENERIC) { Transform t = new Transform(); t.set(readMatrix()); camera.setGeneric(t); } else { float fovy = readFloat(); float aspect = readFloat(); float near = readFloat(); float far = readFloat(); if (projectionType == Camera.PARALLEL) camera.setParallel(fovy, aspect, near, far); else camera.setPerspective(fovy, aspect, near, far); } objs.addElement(camera); } else if (objectType == 6) { // System.out.println("CompositingMode"); CompositingMode compositingMode = new CompositingMode(); loadObject3D(compositingMode); compositingMode.setDepthTestEnabled(readBoolean()); compositingMode.setDepthWriteEnabled(readBoolean()); compositingMode.setColorWriteEnabled(readBoolean()); compositingMode.setAlphaWriteEnabled(readBoolean()); compositingMode.setBlending(readByte()); compositingMode.setAlphaThreshold((float) readByte() / 255.0f); compositingMode.setDepthOffsetFactor(readFloat()); compositingMode.setDepthOffsetUnits(readFloat()); objs.addElement(compositingMode); } else if (objectType == 7) { // System.out.println("Fog"); Fog fog = new Fog(); loadObject3D(fog); fog.setColor(readRGB()); fog.setMode(readByte()); if (fog.getMode() == Fog.EXPONENTIAL) fog.setDensity(readFloat()); else { fog.setNearDistance(readFloat()); fog.setFarDistance(readFloat()); } objs.addElement(fog); } else if (objectType == 9) { // System.out.println("Group"); Group group = new Group(); loadGroup(group); objs.addElement(group); } else if (objectType == 10) { // System.out.println("Image2D"); Image2D image = null; loadObject3D(new Group()); // dummy int format = readByte(); boolean isMutable = readBoolean(); int width = readInt(); int height = readInt(); if (!isMutable) { // Read palette int paletteSize = readInt(); byte[] palette = null; if (paletteSize > 0) { palette = new byte[paletteSize]; dis.readFully(palette); } // Read pixels int pixelSize = readInt(); byte[] pixel = new byte[pixelSize]; dis.readFully(pixel); // Create image if (palette != null) image = new Image2D(format, width, height, pixel, palette); else image = new Image2D(format, width, height, pixel); } else image = new Image2D(format, width, height); dis.reset(); loadObject3D(image); objs.addElement(image); } else if (objectType == 19) { System.out.println("Loader: KeyframeSequence not implemented."); /* Byte interpolation; Byte repeatMode; Byte encoding; UInt32 duration; UInt32 validRangeFirst; UInt32 validRangeLast; UInt32 componentCount; UInt32 keyframeCount; IF encoding == 0 FOR each key frame... UInt32 time; Float32[componentCount] vectorValue; END ELSE IF encoding == 1 Float32[componentCount] vectorBias; Float32[componentCount] vectorScale; FOR each key frame... UInt32 time; Byte[componentCount] vectorValue; END ELSE IF encoding == 2 Float32[componentCount] vectorBias; Float32[componentCount] vectorScale; FOR each key frame... UInt32 time; UInt16[componentCount] vectorValue; END END */ objs.addElement(new Group()); // dummy } else if (objectType == 12) { // System.out.println("Light"); Light light = new Light(); loadNode(light); float constant = readFloat(); float linear = readFloat(); float quadratic = readFloat(); light.setAttenuation(constant, linear, quadratic); light.setColor(readRGB()); light.setMode(readByte()); light.setIntensity(readFloat()); light.setSpotAngle(readFloat()); light.setSpotExponent(readFloat()); objs.addElement(light); } else if (objectType == 13) { // System.out.println("Material"); Material material = new Material(); loadObject3D(material); material.setColor(Material.AMBIENT, readRGB()); material.setColor(Material.DIFFUSE, readRGBA()); material.setColor(Material.EMISSIVE, readRGB()); material.setColor(Material.SPECULAR, readRGB()); material.setShininess(readFloat()); material.setVertexColorTrackingEnable(readBoolean()); objs.addElement(material); } else if (objectType == 14) { // System.out.println("Mesh"); loadNode(new Group()); // dummy VertexBuffer vertices = (VertexBuffer) getObject(readInt()); int submeshCount = readInt(); IndexBuffer[] submeshes = new IndexBuffer[submeshCount]; Appearance[] appearances = new Appearance[submeshCount]; for (int i = 0; i < submeshCount; ++i) { submeshes[i] = (IndexBuffer) getObject(readInt()); appearances[i] = (Appearance) getObject(readInt()); } Mesh mesh = new Mesh(vertices, submeshes, appearances); dis.reset(); loadNode(mesh); objs.addElement(mesh); } else if (objectType == 15) { System.out.println("Loader: MorphingMesh not implemented."); /* UInt32 morphTargetCount; FOR each target buffer... ObjectIndex morphTarget; Float32 initialWeight; END */ objs.addElement(new Group()); // dummy } else if (objectType == 8) { // System.out.println("PolygonMode"); PolygonMode polygonMode = new PolygonMode(); loadObject3D(polygonMode); polygonMode.setCulling(readByte()); polygonMode.setShading(readByte()); polygonMode.setWinding(readByte()); polygonMode.setTwoSidedLightingEnable(readBoolean()); polygonMode.setLocalCameraLightingEnable(readBoolean()); polygonMode.setPerspectiveCorrectionEnable(readBoolean()); objs.addElement(polygonMode); } else if (objectType == 16) { System.out.println("Loader: SkinnedMesh not implemented."); /* ObjectIndex skeleton; UInt32 transformReferenceCount; FOR each bone reference... ObjectIndex transformNode; UInt32 firstVertex; UInt32 vertexCount; Int32 weight; END */ objs.addElement(new Group()); // dummy } else if (objectType == 18) { System.out.println("Loader: Sprite not implemented."); /* ObjectIndex image; ObjectIndex appearance; Boolean isScaled; Int32 cropX; Int32 cropY; Int32 cropWidth; Int32 cropHeight; */ objs.addElement(new Group()); // dummy } else if (objectType == 17) { // System.out.println("Texture2D"); loadTransformable(new Group()); // dummy Texture2D texture = new Texture2D((Image2D) getObject(readInt())); texture.setBlendColor(readRGB()); texture.setBlending(readByte()); int wrapS = readByte(); int wrapT = readByte(); texture.setWrapping(wrapS, wrapT); int levelFilter = readByte(); int imageFilter = readByte(); texture.setFiltering(levelFilter, imageFilter); dis.reset(); loadTransformable(texture); objs.addElement(texture); } else if (objectType == 11) { // System.out.println("TriangleStripArray"); loadObject3D(new Group()); // dummy int encoding = readByte(); int firstIndex = 0; int[] indices = null; if (encoding == 0) firstIndex = readInt(); else if (encoding == 1) firstIndex = readByte(); else if (encoding == 2) firstIndex = readShort(); else if (encoding == 128) { int numIndices = readInt(); indices = new int[numIndices]; for (int i = 0; i < numIndices; ++i) indices[i] = readInt(); } else if (encoding == 129) { int numIndices = readInt(); indices = new int[numIndices]; for (int i = 0; i < numIndices; ++i) indices[i] = readByte(); } else if (encoding == 130) { int numIndices = readInt(); indices = new int[numIndices]; for (int i = 0; i < numIndices; ++i) indices[i] = readShort(); } int numStripLengths = readInt(); int[] stripLengths = new int[numStripLengths]; for (int i = 0; i < numStripLengths; ++i) stripLengths[i] = readInt(); dis.reset(); TriangleStripArray triStrip = null; if (indices == null) triStrip = new TriangleStripArray(firstIndex, stripLengths); else triStrip = new TriangleStripArray(indices, stripLengths); loadObject3D(triStrip); objs.addElement(triStrip); } else if (objectType == 20) { // System.out.println("VertexArray"); loadObject3D(new Group()); // dummy int componentSize = readByte(); int componentCount = readByte(); int encoding = readByte(); int vertexCount = readShort(); VertexArray vertices = new VertexArray(vertexCount, componentCount, componentSize); if (componentSize == 1) { byte[] values = new byte[componentCount * vertexCount]; if (encoding == 0) dis.readFully(values); else { byte last = 0; for (int i = 0; i < vertexCount * componentCount; ++i) { last += readByte(); values[i] = last; } } vertices.set(0, vertexCount, values); } else { short last = 0; short[] values = new short[componentCount * vertexCount]; for (int i = 0; i < componentCount * vertexCount; ++i) { if (encoding == 0) values[i] = (short) readShort(); else { last += (short) readShort(); values[i] = last; } } vertices.set(0, vertexCount, values); } dis.reset(); loadObject3D(vertices); objs.addElement(vertices); } else if (objectType == 21) { // System.out.println("VertexBuffer"); VertexBuffer vertices = new VertexBuffer(); loadObject3D(vertices); vertices.setDefaultColor(readRGBA()); VertexArray positions = (VertexArray) getObject(readInt()); float[] bias = new float[3]; bias[0] = readFloat(); bias[1] = readFloat(); bias[2] = readFloat(); float scale = readFloat(); vertices.setPositions(positions, scale, bias); vertices.setNormals((VertexArray) getObject(readInt())); vertices.setColors((VertexArray) getObject(readInt())); int texCoordArrayCount = readInt(); for (int i = 0; i < texCoordArrayCount; ++i) { VertexArray texcoords = (VertexArray) getObject(readInt()); bias[0] = readFloat(); bias[1] = readFloat(); bias[2] = readFloat(); scale = readFloat(); vertices.setTexCoords(i, texcoords, scale, bias); } objs.addElement(vertices); } else if (objectType == 22) { // System.out.println("World"); World world = new World(); loadGroup(world); world.setActiveCamera((Camera) getObject(readInt())); world.setBackground((Background) getObject(readInt())); objs.addElement(world); } else { System.out.println("Loader: unsupported objectType " + objectType + "."); } dis.reset(); dis.skipBytes(length); } } catch (Exception e) { System.out.println("Exception: " + e.getMessage()); e.printStackTrace(); } dis = old; return null; }