public void initParticleLocation(int index) {
    Particle p = particles[index];
    if (particleType == ParticleType.GeomMesh) {
      // Update the triangle model on each new particle creation.
      Vector3f[] vertices = new Vector3f[3];
      ((TriMesh) psGeom).getTriangle(index, vertices);
      Triangle t = p.getTriangleModel();
      if (t == null) t = new Triangle(vertices[0], vertices[1], vertices[2]);
      else for (int x = 0; x < 3; x++) t.set(x, vertices[x]);
      t.calculateCenter();
      t.calculateNormal();
      // turn the triangle corners into vector offsets from center
      for (int x = 0; x < 3; x++) {
        vertices[x].subtract(t.getCenter(), vertices[x]);
        t.set(x, vertices[x]);
      }
      p.setTriangleModel(t);
      psGeom.localToWorld(t.getCenter(), p.getPosition());
      p.getPosition().multLocal(getInvScale());

    } else if (getEmitType() == EmitType.Geometry) {
      if (getGeometry() != null && getGeometry() instanceof TriMesh)
        ((TriMesh) getGeometry()).randomPointOnTriangles(p.getPosition(), workVect3);
      else if (getGeometry() != null) getGeometry().randomVertex(p.getPosition());
      p.getPosition().multLocal(getInvScale());

    } else {
      switch (getEmitType()) {
        case Line:
          getLine().random(p.getPosition());
          break;
        case Rectangle:
          getRectangle().random(p.getPosition());
          break;
        case Ring:
          getRing().random(p.getPosition());
          break;
        case Point:
        default:
          p.getPosition().set(originOffset);
          break;
      }
      emitterTransform.multPoint(p.getPosition());
    }
  }