Example #1
1
 @Override
 public void draw(Batch batch, float parentAlpha) {
   elapsedTime += Gdx.graphics.getDeltaTime();
   if (playerControlled == true) {
     batch.draw(standingAnimation.getKeyFrame(elapsedTime, true), this.x + 16, this.y + 16);
   } else {
     batch.draw(standingAnimation.getKeyFrame(elapsedTime, true), this.x, this.y);
   }
   batch.draw(texture, x, y);
   bitmapFont.draw(batch, characterList.get(heroNumber - 1).name, x, y + 74);
 }
Example #2
0
 /**
  * Clean up any batches on the session
  *
  * @param sessionScope - the session to clean up
  */
 public void cleanup(SessionScope sessionScope) {
   Batch batch = (Batch) sessionScope.getBatch();
   if (batch != null) {
     batch.cleanupBatch(sessionScope);
     sessionScope.setBatch(null);
   }
 }
 /**
  * Moving forward through the results it's expected that the batches are arbitrarily size. Moving
  * backward through the results it's expected that the batches will match the fetch size.
  */
 public List<?> getCurrentRow() throws SQLException {
   if (currentRow != null) {
     return currentRow;
   }
   if (this.currentRowNumber == 0
       || (lastRowNumber != -1 && this.currentRowNumber > lastRowNumber)) {
     return null;
   }
   for (int i = 0; i < batches.size(); i++) {
     Batch batch = batches.get(i);
     if (this.currentRowNumber < batch.getBeginRow()) {
       continue;
     }
     if (this.currentRowNumber > batch.getEndRow()) {
       continue;
     }
     if (i != 0) {
       batches.add(0, batches.remove(i));
     }
     setCurrentRow(batch);
     return currentRow;
   }
   requestBatchAndWait(this.currentRowNumber);
   Batch batch = batches.get(0);
   setCurrentRow(batch);
   return currentRow;
 }
Example #4
0
  @Override
  public void render() {
    // Update
    getInput();

    b2dWorld.step(1f / 60f, 6, 2);

    camera.update();
    cameraBak.update();
    manager.update();
    background.update();

    // Draw
    Gdx.gl.glClearColor(0, 0, 0, 1);
    Gdx.gl.glClear(GL30.GL_COLOR_BUFFER_BIT);

    // Background
    batch.setProjectionMatrix(cameraBak.combined);
    batch.begin();
    background.draw(batch);
    batch.end();

    batch.setProjectionMatrix(camera.combined);
    debugMatrix = batch.getProjectionMatrix().cpy().scale(PPM, PPM, 0);
    // debugRenderer.render(b2dWorld, debugMatrix);
    batch.begin();
    manager.draw(batch);
    batch.end();

    // GUI
    batch.setProjectionMatrix(cameraBak.combined);
    batch.begin();
    drawGUI(batch);
    batch.end();
  }
Example #5
0
 /**
  * Adds a statement to a batch
  *
  * @param statementScope - the request scope
  * @param conn - the database connection
  * @param sql - the sql statement
  * @param parameters - the parameters for the statement
  * @throws SQLException - if the statement fails
  */
 public void addBatch(
     StatementScope statementScope, Connection conn, String sql, Object[] parameters)
     throws SQLException {
   Batch batch = (Batch) statementScope.getSession().getBatch();
   if (batch == null) {
     batch = new Batch();
     statementScope.getSession().setBatch(batch);
   }
   batch.addBatch(statementScope, conn, sql, parameters);
 }
Example #6
0
  public void updateBatch(Batch batch) throws Throwable {
    PreparedStatement statement =
        conn.prepareStatement(
            "UPDATE `yamaloo`.`batch` SET `Status` = ?, `CrawlBeginTime` = ?, `CrawlEndTime` = ? WHERE `BatchID` = ?");
    statement.setString(1, batch.getStatus().toString());
    statement.setTimestamp(2, batch.getCrawlBeginTime());
    statement.setTimestamp(3, batch.getCrawlEndTime());
    statement.setInt(4, batch.getBatchID());

    statement.executeUpdate();
    statement.close();
  }
Example #7
0
 /**
  * Execute a batch of statements
  *
  * @param sessionScope - the session scope
  * @return - a List of BatchResult objects (may be null if no batch has been initiated). There
  *     will be one BatchResult object in the list for each sub-batch executed
  * @throws SQLException if a database access error occurs, or the drive does not support batch
  *     statements
  * @throws BatchException if the driver throws BatchUpdateException
  */
 public List executeBatchDetailed(SessionScope sessionScope) throws SQLException, BatchException {
   List answer = null;
   Batch batch = (Batch) sessionScope.getBatch();
   if (batch != null) {
     try {
       answer = batch.executeBatchDetailed();
     } finally {
       batch.cleanupBatch(sessionScope);
     }
   }
   return answer;
 }
Example #8
0
 /**
  * Execute a batch of statements
  *
  * @param sessionScope - the session scope
  * @return - the number of rows impacted by the batch
  * @throws SQLException - if a statement fails
  */
 public int executeBatch(SessionScope sessionScope) throws SQLException {
   int rows = 0;
   Batch batch = (Batch) sessionScope.getBatch();
   if (batch != null) {
     try {
       rows = batch.executeBatch();
     } finally {
       batch.cleanupBatch(sessionScope);
     }
   }
   return rows;
 }
 void setBatch(Batch batch) {
   if (batches.size() == savedBatches) {
     batches.remove(savedBatches - 1);
   }
   if (batch.getLastRow() != -1) {
     this.lastRowNumber = batch.getLastRow();
     this.highestRowNumber = batch.getLastRow();
   } else {
     highestRowNumber = Math.max(batch.getEndRow(), highestRowNumber);
     tailLast = batch.isLast();
   }
   this.batches.add(0, batch);
 }
Example #10
0
  protected void updateSubBatch(Geometry bg) {
    Batch batch = batchesByGeom.get(bg);
    if (batch != null) {
      Mesh mesh = batch.geometry.getMesh();
      Mesh origMesh = bg.getMesh();

      VertexBuffer pvb = mesh.getBuffer(VertexBuffer.Type.Position);
      FloatBuffer posBuf = (FloatBuffer) pvb.getData();
      VertexBuffer nvb = mesh.getBuffer(VertexBuffer.Type.Normal);
      FloatBuffer normBuf = (FloatBuffer) nvb.getData();

      VertexBuffer opvb = origMesh.getBuffer(VertexBuffer.Type.Position);
      FloatBuffer oposBuf = (FloatBuffer) opvb.getData();
      VertexBuffer onvb = origMesh.getBuffer(VertexBuffer.Type.Normal);
      FloatBuffer onormBuf = (FloatBuffer) onvb.getData();
      Matrix4f transformMat = getTransformMatrix(bg);

      if (mesh.getBuffer(VertexBuffer.Type.Tangent) != null) {

        VertexBuffer tvb = mesh.getBuffer(VertexBuffer.Type.Tangent);
        FloatBuffer tanBuf = (FloatBuffer) tvb.getData();
        VertexBuffer otvb = origMesh.getBuffer(VertexBuffer.Type.Tangent);
        FloatBuffer otanBuf = (FloatBuffer) otvb.getData();
        doTransformsTangents(
            oposBuf,
            onormBuf,
            otanBuf,
            posBuf,
            normBuf,
            tanBuf,
            bg.startIndex,
            bg.startIndex + bg.getVertexCount(),
            transformMat);
        tvb.updateData(tanBuf);
      } else {
        doTransforms(
            oposBuf,
            onormBuf,
            posBuf,
            normBuf,
            bg.startIndex,
            bg.startIndex + bg.getVertexCount(),
            transformMat);
      }
      pvb.updateData(posBuf);
      nvb.updateData(normBuf);

      batch.needMeshUpdate = true;
    }
  }
Example #11
0
  public int createBatch(Batch batch) throws Throwable {
    PreparedStatement statement =
        conn.prepareStatement(
            "INSERT INTO `yamaloo`.`batch` (`SiteID`, `Status`) VALUES (?, ?);",
            PreparedStatement.RETURN_GENERATED_KEYS);
    statement.setInt(1, batch.getSiteID());
    statement.setString(2, batch.getStatus().toString());

    statement.executeUpdate();
    ResultSet rs = statement.getGeneratedKeys();
    rs.next();
    int batchID = rs.getInt(1);
    statement.close();

    return batchID;
  }
Example #12
0
 /**
  * Load all of the rows from the supplied sequence into the buffer.
  *
  * @param sequence the node sequence; may not be null
  * @param extractor the extractor for the sortable value; may not be null
  * @param rowsWithNullKey the buffer into which should be placed all rows for which the extracted
  *     key value is null; may be null if these are not to be kept
  * @return the size of the first batch, or 0 if there are no rows found
  */
 protected int loadAll(
     NodeSequence sequence,
     ExtractFromRow extractor,
     DistinctBuffer<BufferedRow> rowsWithNullKey) {
   // Put all of the batches from the sequence into the buffer
   Batch batch = sequence.nextBatch();
   int batchSize = 0;
   Object value = null;
   while (batch != null && batchSize == 0) {
     while (batch.hasNext()) {
       batch.nextRow();
       value = extractor.getValueInRow(batch);
       if (value instanceof Object[]) {
         // Put each of the values in the buffer ...
         for (Object v : (Object[]) value) {
           buffer.put(v, createRow(batch));
         }
       } else if (value != null) {
         buffer.put(value, createRow(batch));
       } else if (rowsWithNullKey != null) {
         rowsWithNullKey.addIfAbsent(createRow(batch));
       }
       ++batchSize;
     }
     batch = sequence.nextBatch();
   }
   while (batch != null) {
     while (batch.hasNext()) {
       batch.nextRow();
       value = extractor.getValueInRow(batch);
       if (value instanceof Object[]) {
         // Put each of the values in the buffer ...
         for (Object v : (Object[]) value) {
           buffer.put(v, createRow(batch));
         }
       } else if (value != null) {
         buffer.put(value, createRow(batch));
       } else if (rowsWithNullKey != null) {
         rowsWithNullKey.addIfAbsent(createRow(batch));
       }
     }
     batch = sequence.nextBatch();
   }
   return batchSize;
 }
Example #13
0
 /**
  * Used to submit a batch to the import thread pool. Note that this method can block (due to the
  * use of a blocking queue in the thread pool).
  *
  * @param batch The batch to submit <i>(may be null or empty, although that will result in a
  *     no-op)</i>.
  */
 private void submitBatch(final Batch batch) {
   if (batch != null && batch.size() > 0) {
     if (importStatus.inProgress() && !importStatus.isStopping()) {
       importThreadPool.execute(new BatchImportJob(batch));
     } else {
       if (warn(log)) warn(log, "New batch submitted during shutdown - ignoring new work.");
     }
   }
 }
  /**
   * Batch Save processor.
   *
   * <p>Saves a Batch. Note that you should pass-in your console credentials for this method,
   * instead of the API ones
   *
   * <p>{@sample.xml ../../../doc/avalara-connector.xml.sample avalara:save-batch}
   *
   * @param batchType The kind of records to be imported.
   * @param companyId The id of the company. (Need to be retrived from address bar in Avalara after
   *     hitting the Organization Tab)
   * @param content The content of this import, usually a csv file.
   * @param batchName The name of the batch.
   * @return The {@link BatchSaveResult}
   * @throws AvalaraRuntimeException
   */
  @Processor
  public BatchSaveResult saveBatch(
      BatchType batchType, int companyId, String content, @Optional String batchName) {

    final BatchFile batchFile = new BatchFile();
    batchFile.setContent(content.getBytes()); // cxf takes care of base64 encoding
    batchFile.setContentType("application/csv");
    batchFile.setName(
        batchName + ".csv"); // Must set extension, or Avalara will complain about missing ext
    final ArrayOfBatchFile arrayOfBatchFile = new ArrayOfBatchFile();
    arrayOfBatchFile.getBatchFile().add(batchFile);

    // Batch object to contain the file.
    // Have tested batchfile as well but all examples from Avalara is using this one.
    final Batch batch = new Batch();
    batch.setName(batchName);
    batch.setBatchTypeId(batchType.value());
    batch.setCompanyId(companyId);
    batch.setFiles(arrayOfBatchFile);
    return apiClient.sendBatchRequestToAvalara(BatchRequestType.BatchSave, batch);
  }
Example #15
0
  public Batch getBatch(int batchID) throws Throwable {
    System.out.println(batchID);
    PreparedStatement statement =
        conn.prepareStatement("SELECT * FROM `yamaloo`.`batch` WHERE `batch`.`BatchID` = ?");
    statement.setInt(1, batchID);

    ResultSet rs = statement.executeQuery();
    rs.next();
    Batch batch = Batch.Parse(rs);
    statement.close();

    return batch;
  }
Example #16
0
  @Override
  public void updateGeometricState() {
    if ((refreshFlags & RF_LIGHTLIST) != 0) {
      updateWorldLightList();
    }

    if ((refreshFlags & RF_TRANSFORM) != 0) {
      // combine with parent transforms- same for all spatial
      // subclasses.
      updateWorldTransforms();
    }

    if (!children.isEmpty()) {
      // the important part- make sure child geometric state is refreshed
      // first before updating own world bound. This saves
      // a round-trip later on.
      // NOTE 9/19/09
      // Although it does save a round trip,

      for (Spatial child : children.getArray()) {
        child.updateGeometricState();
      }

      for (Batch batch : batches.getArray()) {
        if (batch.needMeshUpdate) {
          batch.geometry.updateModelBound();
          batch.geometry.updateWorldBound();
          batch.needMeshUpdate = false;
        }
      }
    }

    if ((refreshFlags & RF_BOUND) != 0) {
      updateWorldBound();
    }

    assert refreshFlags == 0;
  }
 public Boolean hasNext(int next, boolean wait) throws SQLException {
   while (this.currentRowNumber + next > highestRowNumber && lastRowNumber == -1) {
     if (!wait) {
       return null;
     }
     requestNextBatch();
   }
   boolean result = this.currentRowNumber + next <= highestRowNumber;
   if (result && !wait) {
     for (int i = 0; i < batches.size(); i++) {
       Batch batch = batches.get(i);
       if (this.currentRowNumber + next < batch.getBeginRow()) {
         continue;
       }
       if (this.currentRowNumber + next > batch.getEndRow()) {
         continue;
       }
       return Boolean.TRUE;
     }
     return null; // needs to be fetched
   }
   return result;
 }
  public Batch buildBatch(File batchFile)
      throws IOException, ParserConfigurationException, SAXException, ProcessException {
    Batch batch = Batch.getInstance();

    FileInputStream fis = new FileInputStream(batchFile);
    DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
    Document doc = dBuilder.parse(fis);

    Element pnode = doc.getDocumentElement();
    NodeList nodes = pnode.getChildNodes();
    for (int idx = 0; idx < nodes.getLength(); idx++) {
      Node node = nodes.item(idx);
      if (node.getNodeType() == Node.ELEMENT_NODE) {
        Element elem = (Element) node;
        Command parsedCommand = this.buildCommand(elem);
        batch.addCommand(parsedCommand);

        System.out.println("Command parsing");
      }
    }

    return batch;
  }
Example #19
0
  public void draw(Batch batch, float parentAlpha) {
    super.draw(batch, parentAlpha);
    rotation = (rotation + 0);
    sprite.setSize(screenRectangle.width, screenRectangle.height);
    sprite.setPosition(screenRectangle.x, screenRectangle.y);
    sprite.setOriginCenter();

    if (Gdx.input.isKeyJustPressed(keyRight)) {
      body.setTransform(body.getPosition().x + 5, body.getPosition().y, body.getAngle());
    }

    elapsedTime += Gdx.graphics.getDeltaTime();
    // body.setTransform(body.getPosition(), rotation);
    batch.end();
    batch.begin();

    sprite.setRotation(rotation);
    sprite.draw(batch);

    // batch.draw(animation.getKeyFrame(elapsedTime, true), screenRectangle.x, screenRectangle.y,
    // screenRectangle.width, screenRectangle.height );
    // animation.setFrameDuration(0.09f);

  }
Example #20
0
  public List<Batch> getActiveBatchList(int siteID) throws Throwable {
    PreparedStatement statement =
        conn.prepareStatement(
            "SELECT b.* FROM `yamaloo`.`batch` AS b"
                + " INNER JOIN `yamaloo`.`site` AS s"
                + " ON b.SiteID = s.SiteID"
                + " WHERE b.`SiteID` = ? AND b.`Status` IN ('None', 'Crawling')"
                + " ORDER BY s.Priority");
    statement.setInt(1, siteID);

    List<Batch> list = new ArrayList<Batch>();
    ResultSet rs = statement.executeQuery();

    while (rs.next()) {
      Batch batch = Batch.Parse(rs);
      list.add(batch);
    }

    statement.close();
    return list;
  }
Example #21
0
  @Test(timeOut = 10_000)
  public void testBatchFunctionality() {

    // Component to test
    Batch batch = new Batch(0, BATCH_SIZE);

    // Test initial state is OK
    assertTrue(batch.isEmpty(), "Batch should be empty");
    assertFalse(batch.isFull(), "Batch shouldn't be full");
    assertEquals(batch.getNumEvents(), 0, "Num events should be 0");

    // Test getting or setting an element in the batch greater than the current number of events is
    // illegal
    try {
      batch.get(1);
      fail();
    } catch (IllegalStateException ex) {
      // Expected, as we can not access elements in the batch greater than the current number of
      // events
    }
    try {
      batch.set(1, new PersistEvent());
      fail();
    } catch (IllegalStateException ex) {
      // Expected, as we can not access elements in the batch greater than the current number of
      // events
    }

    // Test when filling the batch with different types of events, that becomes full
    for (int i = 0; i < BATCH_SIZE; i++) {
      if (i % 4 == 0) {
        batch.addTimestamp(ANY_ST, channel, monCtx);
      } else if (i % 4 == 1) {
        batch.addCommit(ANY_ST, ANY_CT, channel, monCtx);
      } else if (i % 4 == 2) {
        batch.addCommitRetry(ANY_ST, channel, monCtx);
      } else {
        batch.addAbort(ANY_ST, channel, monCtx);
      }
    }
    assertFalse(batch.isEmpty(), "Batch should contain elements");
    assertTrue(batch.isFull(), "Batch should be full");
    assertEquals(batch.getNumEvents(), BATCH_SIZE, "Num events should be " + BATCH_SIZE);

    // Test an exception is thrown when batch is full and a new element is going to be added
    try {
      batch.addCommit(ANY_ST, ANY_CT, channel, monCtx);
      fail("Should throw an IllegalStateException");
    } catch (IllegalStateException e) {
      assertEquals(e.getMessage(), "batch is full", "message returned doesn't match");
      LOG.debug("IllegalStateException catch properly");
    }
    assertTrue(batch.isFull(), "Batch shouldn't be empty");

    // Check the first 3 events and the last one correspond to the filling done above
    assertTrue(batch.get(0).getType().equals(PersistEvent.Type.TIMESTAMP));
    assertTrue(batch.get(1).getType().equals(PersistEvent.Type.COMMIT));
    assertTrue(batch.get(2).getType().equals(PersistEvent.Type.COMMIT_RETRY));
    assertTrue(batch.get(3).getType().equals(PersistEvent.Type.ABORT));

    // Set a new value for last element in Batch and check we obtain the right result
    batch.decreaseNumEvents();
    assertEquals(batch.getNumEvents(), BATCH_SIZE - 1, "Num events should be " + (BATCH_SIZE - 1));
    try {
      batch.get(BATCH_SIZE - 1);
      fail();
    } catch (IllegalStateException ex) {
      // Expected, as we can not access elements in the batch greater than the current number of
      // events
    }

    // Re-check that batch is NOT full
    assertFalse(batch.isFull(), "Batch shouldn't be full");

    // Clear the batch and goes back to its initial state
    batch.clear();
    assertTrue(batch.isEmpty(), "Batch should be empty");
    assertFalse(batch.isFull(), "Batch shouldn't be full");
    assertEquals(batch.getNumEvents(), 0, "Num events should be 0");
  }
Example #22
0
  @Test(timeOut = 10_000)
  public void testBatchFactoryFunctionality() throws Exception {

    // Component to test
    Batch.BatchFactory factory = new Batch.BatchFactory(BATCH_SIZE);

    // Check the factory creates a new batch properly...
    Batch batch = factory.create();
    assertTrue(batch.isEmpty(), "Batch should be empty");
    assertFalse(batch.isFull(), "Batch shouldn't be full");
    assertEquals(batch.getNumEvents(), 0, "Num events should be 0");

    // ...and is wrapped in to a pooled object
    PooledObject<Batch> pooledBatch = factory.wrap(batch);
    assertEquals(pooledBatch.getObject(), batch);

    // Put some elements in the batch...
    batch.addTimestamp(ANY_ST, channel, monCtx);
    batch.addCommit(ANY_ST, ANY_CT, channel, monCtx);
    batch.addCommitRetry(ANY_ST, channel, monCtx);
    batch.addAbort(ANY_ST, channel, monCtx);
    assertFalse(batch.isEmpty(), "Batch should contain elements");
    assertFalse(batch.isFull(), "Batch should NOT be full");
    assertEquals(batch.getNumEvents(), 4, "Num events should be 4");

    // ... and passivate the object through the factory. It should reset the state of the batch
    factory.passivateObject(pooledBatch);
    assertTrue(batch.isEmpty(), "Batch should NOT contain elements");
    assertFalse(batch.isFull(), "Batch should NOT be full");
    assertEquals(batch.getNumEvents(), 0, "Num events should be 0");
  }
Example #23
0
 @Override
 public void draw(Batch batch, float parentAlpha) {
   super.draw(batch, parentAlpha);
   batch.draw(texture, lifePositionX, lifePositionY, 16, 16);
 }
Example #24
0
  public ScanBatch read() throws IOException, TabletClosedException {

    ScanDataSource dataSource = null;

    Batch results = null;

    try {

      try {
        scannerSemaphore.acquire();
      } catch (InterruptedException e) {
        sawException = true;
      }

      // sawException may have occurred within close, so we cannot assume that an interrupted
      // exception was its cause
      if (sawException)
        throw new IllegalStateException("Tried to use scanner after exception occurred.");

      if (scanClosed) throw new IllegalStateException("Tried to use scanner after it was closed.");

      if (options.isIsolated()) {
        if (isolatedDataSource == null) isolatedDataSource = new ScanDataSource(tablet, options);
        dataSource = isolatedDataSource;
      } else {
        dataSource = new ScanDataSource(tablet, options);
      }

      SortedKeyValueIterator<Key, Value> iter;

      if (options.isIsolated()) {
        if (isolatedIter == null) isolatedIter = new SourceSwitchingIterator(dataSource, true);
        else isolatedDataSource.reattachFileManager();
        iter = isolatedIter;
      } else {
        iter = new SourceSwitchingIterator(dataSource, false);
      }

      results =
          tablet.nextBatch(
              iter, range, options.getNum(), options.getColumnSet(), options.getBatchTimeOut());

      if (results.getResults() == null) {
        range = null;
        return new ScanBatch(new ArrayList<KVEntry>(), false);
      } else if (results.getContinueKey() == null) {
        return new ScanBatch(results.getResults(), false);
      } else {
        range =
            new Range(
                results.getContinueKey(),
                !results.isSkipContinueKey(),
                range.getEndKey(),
                range.isEndKeyInclusive());
        return new ScanBatch(results.getResults(), true);
      }

    } catch (IterationInterruptedException iie) {
      sawException = true;
      if (tablet.isClosed()) throw new TabletClosedException(iie);
      else throw iie;
    } catch (IOException ioe) {
      if (tablet.shutdownInProgress()) {
        log.debug("IOException while shutdown in progress ", ioe);
        throw new TabletClosedException(
            ioe); // assume IOException was caused by execution of HDFS shutdown hook
      }

      sawException = true;
      dataSource.close(true);
      throw ioe;
    } catch (RuntimeException re) {
      sawException = true;
      throw re;
    } finally {
      // code in finally block because always want
      // to return mapfiles, even when exception is thrown
      if (null != dataSource && !options.isIsolated()) {
        dataSource.close(false);
      } else if (null != dataSource) {
        dataSource.detachFileManager();
      }

      if (results != null && results.getResults() != null)
        tablet.updateQueryStats(results.getResults().size(), results.getNumBytes());

      scannerSemaphore.release();
    }
  }
 private void setCurrentRow(Batch batch) {
   currentRow = batch.getRow(this.currentRowNumber);
   if (batch.isLast() && batch.getEndRow() == this.currentRowNumber) {
     currentRow = null;
   }
 }
Example #26
0
  protected void doBatch() {
    Map<Material, List<Geometry>> matMap = new HashMap<Material, List<Geometry>>();
    int nbGeoms = 0;

    gatherGeomerties(matMap, this, needsFullRebatch);
    if (needsFullRebatch) {
      for (Batch batch : batches.getArray()) {
        batch.geometry.removeFromParent();
      }
      batches.clear();
      batchesByGeom.clear();
    }
    // only reset maxVertCount if there is something new to batch
    if (matMap.size() > 0) {
      maxVertCount = 0;
    }

    for (Map.Entry<Material, List<Geometry>> entry : matMap.entrySet()) {
      Mesh m = new Mesh();
      Material material = entry.getKey();
      List<Geometry> list = entry.getValue();
      nbGeoms += list.size();
      String batchName = name + "-batch" + batches.size();
      Batch batch;
      if (!needsFullRebatch) {
        batch = findBatchByMaterial(material);
        if (batch != null) {
          list.add(0, batch.geometry);
          batchName = batch.geometry.getName();
          batch.geometry.removeFromParent();
        } else {
          batch = new Batch();
        }
      } else {
        batch = new Batch();
      }
      mergeGeometries(m, list);
      m.setDynamic();

      batch.updateGeomList(list);

      batch.geometry = new Geometry(batchName);
      batch.geometry.setMaterial(material);
      this.attachChild(batch.geometry);

      batch.geometry.setMesh(m);
      batch.geometry.getMesh().updateCounts();
      batch.geometry.getMesh().updateBound();
      batches.add(batch);
    }
    if (batches.size() > 0) {
      needsFullRebatch = false;
    }

    logger.log(
        Level.FINE,
        "Batched {0} geometries in {1} batches.",
        new Object[] {nbGeoms, batches.size()});

    // init the temp arrays if something has been batched only.
    if (matMap.size() > 0) {
      // TODO these arrays should be allocated by chunk instead to avoid recreating them each time
      // the batch is changed.
      // init temp float arrays
      tmpFloat = new float[maxVertCount * 3];
      tmpFloatN = new float[maxVertCount * 3];
      if (useTangents) {
        tmpFloatT = new float[maxVertCount * 4];
      }
    }
  }