Example #1
0
 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;
 }
Example #2
0
 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;
 }
Example #3
0
 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;
 }
Example #4
0
 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);
  }
Example #6
0
  /**
   * 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);
  }
Example #8
0
 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);
 }
Example #9
0
  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;
   }
 }
Example #11
0
 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;
 }
Example #12
0
  /**
   * 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);
  }
Example #13
0
 /**
  * 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;
 }
Example #14
0
 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;
 }
Example #15
0
 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;
 }
Example #16
0
 /**
  * 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;
 }
Example #17
0
 @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);
   }
 }
Example #19
0
 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);
 }
Example #20
0
 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;
 }
Example #21
0
 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;
 }
Example #22
0
 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);
 }
Example #23
0
 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;
 }
Example #24
0
 @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()]));
 }
Example #25
0
 @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()]));
 }
Example #26
0
 /**
  * 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);
 }
Example #27
0
  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);
  }
Example #28
0
 public void setTransparencyAndRenderingAttributes(
     TransparencyAttributes transparencyAttributes, boolean rendering) {
   super.setTransparencyAttributes(transparencyAttributes);
   super.getRenderingAttributes().setDepthBufferEnable(rendering);
 }
Example #29
0
  /** 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);
  }
Example #30
0
  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;
  }