Author Topic: [ASK] Object3D max triangles  (Read 1592 times)

Offline naldo

  • byte
  • *
  • Posts: 9
    • View Profile
[ASK] Object3D max triangles
« on: November 13, 2014, 09:31:44 am »
I have been using this superb engine for a week.

So, noob question:
My program needs to generate a mesh dynamically.
Any way to change the max triangles of an Object3D at runtime?

If there isn't, which is recommended:
1. Set the 'maxTriangles' to huge number at the initialization time (Object3D constructor). Will this lower the performance?
2. Remove the old Object3D from the world and add the new Object3D (with new max triangles).

Thank you.

Online EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11745
    • View Profile
    • http://www.jpct.net
Re: [ASK] Object3D max triangles
« Reply #1 on: November 13, 2014, 09:42:55 am »
It depends...what do you want to do exactly?

Offline naldo

  • byte
  • *
  • Posts: 9
    • View Profile
Re: [ASK] Object3D max triangles
« Reply #2 on: November 13, 2014, 12:20:19 pm »
My program will calculate & display a path/route based on user inputs.
Kinda like gps software or google maps.
So the mesh will be different for each new route.



Side question:
how to use update(float[], int) on VertexAttributes to update only a fraction of data?

I've tried something like:
Code: [Select]
float[] data = new float[420];
VertexAttributes attribs = ....;
attribs.setDynamic(true);
....

// then somewhere in code
// modify data
data[6] = 0;
data[7] = 1;
attribs.update(data, 6);


And I got RuntimeException: ERROR: Invalid size: 6/420

But when i use 0 for the start parameter in update(float[] data, int start), i.e. attribs.update(data, 0),
it works fine.

Thanks.

Online EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11745
    • View Profile
    • http://www.jpct.net
Re: [ASK] Object3D max triangles
« Reply #3 on: November 13, 2014, 01:08:53 pm »
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:

Code: [Select]
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);
    }
  }
}


Offline naldo

  • byte
  • *
  • Posts: 9
    • View Profile
Re: [ASK] Object3D max triangles
« Reply #4 on: November 13, 2014, 05:59:38 pm »
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.

oh right.
With VertexController, i don't need to recreate the vertices nor the Object3D instances.
I just need to modify the vertices directly.

I will use this for my final program if my previous method starting to get "ugly" in the future.
Many thanks.


for the side question:
how to update only a fraction of data in VertexAttribute?
Say i just want to update data at index 100 to 200.
Does this do-able?
« Last Edit: November 13, 2014, 06:01:58 pm by naldo »

Online EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11745
    • View Profile
    • http://www.jpct.net
Re: [ASK] Object3D max triangles
« Reply #5 on: November 13, 2014, 06:50:07 pm »
To update a part of the attributes, you have an array with a fitting size. In your example, you are trying to stuff an array with the size of 420 into VAs with the size of 420, starting at index 6. It doesn't work that way. Your array should be 414 in size and the data has to start at index 0, not 6 in that array.

Offline naldo

  • byte
  • *
  • Posts: 9
    • View Profile
Re: [ASK] Object3D max triangles
« Reply #6 on: November 14, 2014, 09:30:41 am »
To update a part of the attributes, you have an array with a fitting size. In your example, you are trying to stuff an array with the size of 420 into VAs with the size of 420, starting at index 6. It doesn't work that way. Your array should be 414 in size and the data has to start at index 0, not 6 in that array.

Does it mean 'start' parameter always has to be zero?
'start' parameter is the index for updatedData right?
With same vertex attribute data above (length 420),  I've tried:

Code: [Select]
float[] updatedData = { 1, 2, 3, 4 };
attribs.update(updatedData, 1);
with same Exception, Invalid size: 1/4.

Now, I'm just curious why it doesn't work when 'start' parameter has a value larger than zero.


And,
when I update VertexAttributes data, the order of the vertex is often change between each run.
Is this the expected behaviour when vertex sharing is enabled?

Thanks.

Online EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11745
    • View Profile
    • http://www.jpct.net
Re: [ASK] Object3D max triangles
« Reply #7 on: November 14, 2014, 09:56:25 am »
That index stuff is a bug. I'll fix it later and upload a new version. About the second question: I'm not sure what you mean by that... ???

Offline naldo

  • byte
  • *
  • Posts: 9
    • View Profile
Re: [ASK] Object3D max triangles
« Reply #8 on: November 14, 2014, 10:20:13 am »
That index stuff is a bug. I'll fix it later and upload a new version. About the second question: I'm not sure what you mean by that... ???

Ok, thanks.

For my second question,
suppose i have these vertices  to make 4 quads.
Code: [Select]
b d f h j
a c e g i

I add it with:
Code: [Select]
addTriangle (a, c, b);
addTriangle (b, c, d);

addTriangle (c, e, d);
addTriangle (d, e, f);

addTriangle (e, g, f);
addTriangle (f, g, h);

addTriangle (g, i, h);
addTriangle (h, i, j);

What is the order of the vertex with vertex sharing enabled?
When i update my VertexAttributes data, the order of vertex sometimes becomes "ab-cd-ef-gh-ij", and sometimes in another run it becomes "ac-bd-eg-fh-ij".

Thanks
« Last Edit: November 14, 2014, 10:22:20 am by naldo »

Online EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11745
    • View Profile
    • http://www.jpct.net
Re: [ASK] Object3D max triangles
« Reply #9 on: November 14, 2014, 10:44:59 am »
Once created, the vertex order doesn't change. I'm not sure what you mean by 'run'?! A new app start or a new attribute update?

Offline naldo

  • byte
  • *
  • Posts: 9
    • View Profile
Re: [ASK] Object3D max triangles
« Reply #10 on: November 14, 2014, 10:59:52 am »
Once created, the vertex order doesn't change. I'm not sure what you mean by 'run'?! A new app start or a new attribute update?

sorry, what i mean with 'run' is start/launch the app.

Online EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11745
    • View Profile
    • http://www.jpct.net
Re: [ASK] Object3D max triangles
« Reply #11 on: November 14, 2014, 11:09:31 am »
Which order changes? The one of the created Object3D or the one of the object on the GPU?

Offline naldo

  • byte
  • *
  • Posts: 9
    • View Profile
Re: [ASK] Object3D max triangles
« Reply #12 on: November 14, 2014, 05:02:27 pm »
Sry.
Can't really check now. I'm away from my computer that containing the code.
But I think it's from the Object3D (or Mesh?).
I remember that i had logged the vertices position days ago.
Sometimes the order is different, even though the add-order is always the same.
The last time I'm sure the order is changing is when I add the vertex attributes data, especially with color information.

Currently i'm using Object(float[] coordinates, float[] uvs, int[] indices, int textureId) to ensure the order.
And it works flawlessly.

Thanks.


Online EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11745
    • View Profile
    • http://www.jpct.net
Re: [ASK] Object3D max triangles
« Reply #13 on: November 14, 2014, 09:53:52 pm »
The vertex sharing internally uses a HashMap. I would think that it will create the same order as long as the input values are deterministic. But maybe that's not the case. Anyway, if the bulk constructor works fine, then just use that.

Online EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11745
    • View Profile
    • http://www.jpct.net
Re: [ASK] Object3D max triangles
« Reply #14 on: November 14, 2014, 09:54:33 pm »