You can do such stuff with a VertexController, but the idea is a little different (and a bit hacky...). Basically, you create an Object3D, which is "big enough", move all unused vertices out of the view and update those that should be visible. Here's an example for desktop jPCT:
import java.awt.Color;
import com.threed.jpct.*;
import com.threed.jpct.util.Light;
public class TrailTest
{
private static int TRAIL_POLYGONS = 1000;
private World world;
private FrameBuffer buffer;
private Object3D sphere;
private Object3D trail;
public static void main(String[] args)
throws Exception
{
new TrailTest().loop();
}
public TrailTest()
throws Exception
{
world = new World();
world.setAmbientLight(100, 100, 100);
sphere = Primitives.getSphere(20, 1f);
sphere.build();
sphere.compile();
sphere.translate(-100, 0, 50);
world.addObject(sphere);
Camera cam = world.getCamera();
cam.setPosition(0, -50, 0);
cam.lookAt(sphere.getTransformedCenter());
Light light = new Light(world);
light.setPosition(new SimpleVector(-100, 0, -150));
light.setAttenuation(-1);
trail = createTrailObject(sphere);
trail.build();
trail.compile(true);
world.addObject(trail);
}
/**
* This looks a bit hacky...it creates an object with a defined number of unique polygons that are all out of sight.
* The vertex controller will then take polygons from this soup that arrange them to form the trail.
*
* @param emitter
* @return
*/
private Object3D createTrailObject(Object3D emitter)
{
Logger.log("Creating trail object...");
Object3D trail = new Object3D(TRAIL_POLYGONS);
trail.disableVertexSharing();
for (int i = 0; i < TRAIL_POLYGONS / 2; i++)
{
trail.addTriangle(new SimpleVector(-1100000 + i, -1200000 + i, -1300000 + i), new SimpleVector(-1400000 + i,
-1500000 + i, -1600000 + i), new SimpleVector(-1700000 + i, -1800000 + i, -1900000 + i));
trail.addTriangle(new SimpleVector(2000000 + i, 2100000 + i, 2200000 + i), new SimpleVector(2300000 + i,
2400000 + i, 2500000 + i), new SimpleVector(2600000 + i, 2700000 + i, 2800000 + i));
}
trail.calcNormals();
trail.getMesh().setVertexController(new TrailBlazer(emitter), false);
trail.forceGeometryIndices(false);
trail.compile(true);
trail.build();
trail.setAdditionalColor(Color.YELLOW);
trail.setCulling(Object3D.CULLING_DISABLED);
trail.setTransparency(0);
return trail;
}
private void loop()
throws Exception
{
Config.glUseVBO = true;
buffer = new FrameBuffer(640, 480, FrameBuffer.SAMPLINGMODE_NORMAL);
buffer.disableRenderer(IRenderer.RENDERER_SOFTWARE);
buffer.enableRenderer(IRenderer.RENDERER_OPENGL);
float cnt = 0;
float y = 0;
float yAdd = -0.1f;
while (!org.lwjgl.opengl.Display.isCloseRequested())
{
SimpleVector lastTrans = sphere.getTranslation();
sphere.translate((float) Math.sin(cnt), yAdd, (float) Math.cos(cnt));
SimpleVector newTrans = sphere.getTranslation();
lastTrans.sub(newTrans);
sphere.getRotationMatrix().setTo(lastTrans.getRotationMatrix());
trail.getMesh().applyVertexController();
trail.touch();
cnt += 0.05f;
if (y < -40)
{
yAdd = 0.1f;
}
else if (y > 40)
{
yAdd = -0.1f;
}
y += yAdd;
buffer.clear(java.awt.Color.BLACK);
world.renderScene(buffer);
world.draw(buffer);
buffer.update();
buffer.displayGLOnly();
Thread.sleep(10);
}
System.exit(0);
}
private static class TrailBlazer
extends GenericVertexController
{
private int maxPos = TRAIL_POLYGONS / 2;
private int pos = 0;
private Object3D emitter = null;
private SimpleVector p0 = new SimpleVector();
private SimpleVector p1 = new SimpleVector();
private SimpleVector p2 = new SimpleVector();
private SimpleVector p3 = new SimpleVector();
private SimpleVector center = new SimpleVector();
private SimpleVector lastP2 = null;
private SimpleVector lastP3 = null;
private SimpleVector z = new SimpleVector();
private SimpleVector x = new SimpleVector();
private SimpleVector tmp = new SimpleVector();
private static final long serialVersionUID = 1L;
public TrailBlazer(Object3D emitter)
{
this.emitter = emitter;
}
public void apply()
{
center = emitter.getTransformedCenter(center);
SimpleVector[] dest = this.getDestinationMesh();
z = emitter.getRotationMatrix().getZAxis(z);
x = emitter.getRotationMatrix().getXAxis(z);
if (lastP2 == null)
{
tmp.set(center);
tmp.sub(x);
lastP2 = new SimpleVector(tmp);
tmp.add(x);
tmp.add(x);
lastP3 = new SimpleVector(tmp);
}
p0.set(lastP2);
p1.set(lastP3);
int cPos = pos * 6;
tmp.set(center);
tmp.sub(z);
tmp.sub(x);
p2.set(tmp);
tmp.add(x);
tmp.add(x);
p3.set(tmp);
dest[cPos++].set(p0);
dest[cPos++].set(p1);
dest[cPos++].set(p3);
dest[cPos++].set(p2);
dest[cPos++].set(p0);
dest[cPos].set(p3);
pos++;
if (pos >= maxPos)
{
pos = 0;
}
lastP2.set(p2);
lastP3.set(p3);
}
}
}