clearObject and rebuild? (trying to recreate a object)

Started by Darkflame, April 24, 2012, 10:12:05 PM

Previous topic - Next topic

Darkflame

I have a rectangle created with the following code:


public Rectangle (int quads, float scalex, float scaley) {

super(quads*quads*2+8);
this.quads = quads;

      createRect(quads, scalex, scaley);
   }



private void createRect(int quads, float scalex, float scaley) {

Log.i("text", "building for size: = "+scalex+","+scaley);


float startx=-scalex*(float) quads/2f;
      float starty=startx;
      float tx=0f;
      float ty=0f;
      float dtex=(1f/(float) quads);
      Object3D obj=this;
   
     
      for (int i=0; i<quads; i++) {
         for (int p=0; p<quads; p++) {
            float dtx=tx+dtex;
            float dty=ty+dtex;
            if (dtx>1f) {
               dtx=1f;
            }
            if (dty>1f) {
               dty=1f;
            }
            obj.addTriangle(new SimpleVector(startx, starty, 0), tx, ty, new SimpleVector(startx, starty+scaley, 0), tx, dty, new SimpleVector(startx+scalex, starty, 0),
                            dtx, ty);
            obj.addTriangle(new SimpleVector(startx, starty+scaley, 0), tx, dty, new SimpleVector(startx+scalex, starty+scaley, 0), dtx, dty, new SimpleVector(startx+scalex,
                            starty, 0), dtx, ty);
            startx+=scalex;
            tx+=dtex;
         }
         starty+=scaley;
         startx=-scalex*quads/2;
         tx=0;
         ty+=dtex;
      }
}



I wanted to be able to resize this rectangle in x/y at will, keeping its position/rotation the same, I thought I could do this with a simple clear and recreate like so:



/** rebuilds whole objec to rescale - pretty wastefull I think **/
public void setSize(float scalex, float scaley)

{ Log.i("text", "rebuilding for size: = "+scalex+","+scaley);

this.clearObject();
createRect(quads, scalex, scaley);
super.build();

}



But all that happens when I try to, say, increase its Y scale is the texture vanishes and the object stays its original size.
Any idea whats going on or how to diagnose further? :-/


EgonOlsen

It doesn't work this way, because the data on the gpu isn't aware that the object has been changed in memory. You can try to add a compile(true, true) before calling build and a touch() after you've changed the object. But this isn't the way in which you should it anyway. Either replace the object with a new one (not that much more expensive and it will work for sure) or use an IVertexController (i.e. extend the generic one).

Darkflame

a) Whoops, sorry if I posted in the wrong place - thought I posted to support anyway...

b) Really? Hmz.  I guess recreating the object isnt hard in this case - its basically a billboard with text written on it. I needed the size of the board to adjust to fit the text neatly.
The take updates occasionally (via a XMPP connection) so it shouldn't be too quick.

However, just out of interest, what would be the correct way for a more dynamically updated size?
Say, if I wanted to let the user drag to resize something - surely deleting and recreating each frame would be quite wastefull in that case.
Would in that case a  IVertexController  be better? (I have yet to learn direct vertex manipulation so I havnt delved very deep into this stuff yet)

EgonOlsen

If you want modify an object's mesh at runtime, the vertex controllers are the way to go. Clearing the object is meant to be used for this purpose and will most likely not work correctly.

Darkflame

Ok, trying to get the hang of how to use them.

I create a plane at size 1/1, then apply a scale mod in order to resize it to any value.
This seems to work....once. But if I try to resize it again, it doesn't work.
The vertex values appearing in the log seem very high - I think its multiplying it all based on what they were last time rather then starting afresh....however, I am using IVertexController.PRESERVE_SOURCE_MESH.

Heres my code:

public class Rectangle extends Object3D {

int quads = 0;
  Object3D obj;
  Mesh planeMesh;
 
public Rectangle (int quads, float scalex, float scaley) {

super(quads*quads*2+8);
this.quads = quads;
  obj=this;
 
      createRect(quads, 1,1);
                 
obj.build();

planeMesh = obj.getMesh();

      this.setSize(1, 1);
     
   }



private void createRect(int quads, float scalex, float scaley) {

Log.i("text", "building for size: = "+scalex+","+scaley);

float startx=-scalex*(float) quads/2f;
      float starty=startx;
      float tx=0f;
      float ty=0f;
      float dtex=(1f/(float) quads);
   
     
      for (int i=0; i<quads; i++) {
         for (int p=0; p<quads; p++) {
            float dtx=tx+dtex;
            float dty=ty+dtex;
            if (dtx>1f) {
               dtx=1f;
            }
            if (dty>1f) {
               dty=1f;
            }
            obj.addTriangle(new SimpleVector(startx, starty, 0), tx, ty, new SimpleVector(startx, starty+scaley, 0), tx, dty, new SimpleVector(startx+scalex, starty, 0),
                            dtx, ty);
            obj.addTriangle(new SimpleVector(startx, starty+scaley, 0), tx, dty, new SimpleVector(startx+scalex, starty+scaley, 0), dtx, dty, new SimpleVector(startx+scalex,
                            starty, 0), dtx, ty);
            startx+=scalex;
            tx+=dtex;
         }
         starty+=scaley;
         startx=-scalex*quads/2;
         tx=0;
         ty+=dtex;
      }
}


/** uses a vertex controller to rescale  **/

public void setSize(float scalex, float scaley)
{

IVertexController demoControl=new ResizerMod(scalex,scaley,1);


Log.i("text", "resizing to size: = "+scalex+","+scaley);



planeMesh.setVertexController(demoControl, IVertexController.PRESERVE_SOURCE_MESH);
planeMesh.applyVertexController();
planeMesh.removeVertexController();

}

private static class ResizerMod extends GenericVertexController {
private static final long serialVersionUID = 1L;

float XFactor =1;
float YFactor =1;
float ZFactor =1;

public ResizerMod(float xFactor, float yFactor, float zFactor) {
super();
this.XFactor = xFactor;
this.YFactor = yFactor;
this.ZFactor = zFactor;

  Log.i("vertex", "XFactor="+XFactor+" YFactor="+YFactor);
}




public void apply() {
SimpleVector[] s = getSourceMesh();
SimpleVector[] d = getDestinationMesh();
Log.i("vertex", "XFactor="+XFactor+" YFactor="+YFactor);
for (int i = 0; i < s.length; i++) {

//d[i].z = s[i].z - (10f * ((float) Math.sin(s[i].x / 50f) + (float) Math.cos(s[i].y / 50f)));

         Log.i("vertex", "old vertex="+i+" x="+ d[i].x);
         Log.i("vertex", "old vertex="+i+" y="+ d[i].y);
         Log.i("vertex", "old vertex="+i+" z="+ d[i].z);

d[i].x = s[i].x*XFactor;
d[i].y = s[i].y*YFactor;
d[i].z = s[i].z*ZFactor;

         Log.i("vertex", "vertex="+i+" x="+ d[i].x);
         Log.i("vertex", "vertex="+i+" y="+ d[i].y);
         Log.i("vertex", "vertex="+i+" z="+ d[i].z);
}
}
}
}