Displaying multiple boxes

Started by gamerfan, September 08, 2011, 03:06:59 PM

Previous topic - Next topic

gamerfan

I am displaying a solid wall (platform) using Box primitive.The code works fine and it displays th boxes continuously on x-axis.But the problem is that it gives a space between the two adjuscent boxes.That way it reduces the impression of wall.

package org.me.home;

import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.MotionEvent;
import com.threed.jpct.Camera;
import com.threed.jpct.FrameBuffer;
import com.threed.jpct.Light;
import com.threed.jpct.Logger;
import com.threed.jpct.Object3D;
import com.threed.jpct.Primitives;
import com.threed.jpct.RGBColor;
import com.threed.jpct.SimpleVector;
import com.threed.jpct.World;
import com.threed.jpct.util.MemoryHelper;
import java.lang.reflect.Field;
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLDisplay;
import javax.microedition.khronos.opengles.GL10;

/**
*
* @author Gamerfan
*/

public class MainActivity extends Activity {

// Used to handle pause and resume...
private static MainActivity master = null;

private GLSurfaceView mGLView;
private MyRenderer renderer = null;
private FrameBuffer fb = null;
private World world = null;
private RGBColor back = new RGBColor(50, 50, 100);

private float touchTurn = 0;
private float touchTurnUp = 0;

private float xpos = -1;
private float ypos = -1;

private Object3D cube = null;
        private Object3D box = null;
        private Object3D newbox = null;

       
private int fps = 0;

private Light sun = null;

        private float xDelta = 0;
        private float yDelta = 0;
        private float zDelta = 0;
        private int counter = 0;
       
       
    @Override
protected void onCreate(Bundle savedInstanceState) {

Logger.log("onCreate");

if (master != null) {
copy(master);
}

super.onCreate(savedInstanceState);
mGLView = new GLSurfaceView(getApplication());

mGLView.setEGLConfigChooser(new GLSurfaceView.EGLConfigChooser() {
public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
// Ensure that we get a 16bit framebuffer. Otherwise, we'll fall
// back to Pixelflinger on some device (read: Samsung I7500)
int[] attributes = new int[] { EGL10.EGL_DEPTH_SIZE, 16, EGL10.EGL_NONE };
EGLConfig[] configs = new EGLConfig[1];
int[] result = new int[1];
egl.eglChooseConfig(display, attributes, configs, 1, result);
return configs[0];
}
});

renderer = new MyRenderer();
mGLView.setRenderer(renderer);
setContentView(mGLView);
}

@Override
protected void onPause() {
super.onPause();
mGLView.onPause();
}

@Override
protected void onResume() {
super.onResume();
mGLView.onResume();
}

@Override
protected void onStop() {
super.onStop();
}

private void copy(Object src) {
try {
Logger.log("Copying data from master Activity!");
Field[] fs = src.getClass().getDeclaredFields();
for (Field f : fs) {
f.setAccessible(true);
f.set(this, f.get(src));
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}

    @Override
public boolean onTouchEvent(MotionEvent me) {

if (me.getAction() == MotionEvent.ACTION_DOWN) {
xpos = me.getX();
ypos = me.getY();
return true;
}

if (me.getAction() == MotionEvent.ACTION_UP) {
xpos = -1;
ypos = -1;
touchTurn = 0;
touchTurnUp = 0;
return true;
}

if (me.getAction() == MotionEvent.ACTION_MOVE) {
float xd = me.getX() - xpos;
float yd = me.getY() - ypos;

xpos = me.getX();
ypos = me.getY();

touchTurn = xd / -100f;
touchTurnUp = yd / -100f;
return true;
}

try {
Thread.sleep(15);
} catch (Exception e) {
// No need for this...
}

return super.onTouchEvent(me);
}

    @Override
        public boolean onKeyDown(int keyCode, KeyEvent msg) {
          if( keyCode == KeyEvent.KEYCODE_A ) {
              System.out.println(" total angle swept " + box.getTransformedCenter().calcAngle(box.getXAxis()) );
              newbox = box.cloneObject();
              newbox.setAdditionalColor(new RGBColor(225, 0, 10));
              SimpleVector sv = new SimpleVector();
              sv.x+=xDelta;
//              sv.y+=yDelta;
//              sv.z+=zDelta;
              newbox.translate( sv );
              world.addObject( newbox );
             
              world.buildAllObjects();
              xDelta+=1.5f;
             // yDelta+=0.25f;
  //            zDelta+=1.25f;
              return true;
          }
         return true;
        }

        private Object3D drawRectangle() {
            Object3D rectangle = new Object3D(20);
            for (int y=0; y < 10; y++) {
        float fY = y / -10f;
        rectangle.addTriangle(new SimpleVector(-1, fY, 1), 0, 0,
                        new SimpleVector(-1, fY, -1), 0, 1,
                        new SimpleVector(1, fY, -1), 1, 1);
        rectangle.addTriangle(new SimpleVector(1, fY, -1), 1, 1,
                        new SimpleVector(1, fY, 1), 1, 0,
                        new SimpleVector(-1, fY, 1), 0, 0);
    }

            return rectangle;
        }
protected boolean isFullscreenOpaque() {
return true;
}

class MyRenderer implements GLSurfaceView.Renderer {

private long time = System.currentTimeMillis();

public MyRenderer() {
}

public void onSurfaceChanged(GL10 gl, int w, int h) {
if (fb != null) {
fb.dispose();
}
fb = new FrameBuffer(gl, w, h);

if (master == null) {

world = new World();
world.setAmbientLight(20, 20, 20);

sun = new Light(world);
sun.setIntensity(250, 250, 250);

// Create a texture out of the icon...:-)
//Texture texture = new Texture(BitmapHelper.rescale(BitmapHelper.convert(getResources().getDrawable(R.drawable.icon)), 64, 64));
//TextureManager.getInstance().addTexture("texture", texture);

cube = Primitives.getCube(1);
//cube.calcTextureWrapSpherical();
//cube.setTexture("texture");
//cube.strip();
//cube.build();


                                box = Primitives.getBox(1.5f, 0.75f);
                                box.translate(-10, 10, 0);
                                box.translateMesh();

world.addObject(cube);
                                world.addObject(box);

Camera cam = world.getCamera();
cam.moveCamera(Camera.CAMERA_MOVEOUT, 50);
cam.lookAt(cube.getTransformedCenter());

SimpleVector sv = new SimpleVector();
sv.set(cube.getTransformedCenter());
sv.y -= 100;
sv.z -= 100;
sun.setPosition(sv);
MemoryHelper.compact();

if (master == null) {
Logger.log("Saving master Activity!");
master = MainActivity.this;
}
}
}

public void onSurfaceCreated(GL10 gl, EGLConfig config) {
}

public void onDrawFrame(GL10 gl) {
if (touchTurn != 0) {
    cube.rotateY(touchTurn);
                            box.rotateY(touchTurn) ;
                           
                            if( newbox != null)
                            newbox.rotateY(touchTurn) ;

    touchTurn = 0;
                            yDelta +=0.02f;
}

if (touchTurnUp != 0) {
    cube.rotateX( touchTurnUp );
    touchTurnUp = 0;
}

fb.clear(back);
world.renderScene(fb);
world.draw(fb);
fb.display();

if (System.currentTimeMillis() - time >= 1000) {
//Logger.log(fps + "fps");
fps = 0;
time = System.currentTimeMillis();
}
fps++;
}
}
}

When I press 'A' key , a new box is created using cloning the existing one.The following piece of code that performs it.

@Override
        public boolean onKeyDown(int keyCode, KeyEvent msg) {
          if( keyCode == KeyEvent.KEYCODE_A ) {
              System.out.println(" total angle swept " + box.getTransformedCenter().calcAngle(box.getXAxis()) );
              newbox = box.cloneObject();
              newbox.setAdditionalColor(new RGBColor(225, 0, 10));
              SimpleVector sv = new SimpleVector();
              sv.x+=xDelta;
//              sv.y+=yDelta;
//              sv.z+=zDelta;
              newbox.translate( sv );
              world.addObject( newbox );
             
              world.buildAllObjects();
              xDelta+=1.5f;
             // yDelta+=0.25f;
  //            zDelta+=1.25f;
              return true;
          }
         return true;
        }



[attachment deleted by admin]

EgonOlsen

Adjacent polygons only really match if they share the exact same vertices. In your case, inaccuracies in translation (and rotation?) add up to those gaps and jaggies. It's not a good solution to build a wall that way anyway unless you have a good reason for it. Have you?

gamerfan

I do not have that much idea about it.However, I just tried that way and a I said earlier, it got working. :)  So I thought of continuing that way,but not able to figure out the issues.How it can be improved according to you?

I searched some examples in the net to build a wall using this API and found some solutions.However, that too has some some little implementational issues.These are the links.

          http://stackoverflow.com/questions/6003828/stretch-2d-plane-to-3d-cube
          http://i.stack.imgur.com/en1UL.png
          http://i.stack.imgur.com/s8hyX.png

And in my case, this(above links) also did not work the way expected.So I adopted the earlier one .Please share with me if you have better solutions.

stownshend

I've been working with a 3D modeler on a project using JPCT-AE and one of the things he's told me is that you should never have 3D polygons up against each other. You should design the models so that only what is visible has a face - and even the opposite side of the visible sides are not rendered. It's for performance reasons and also because of the weird behaviour when two faces exist in the same space (jaggies etc).

If you want to make a wall, make one big polygon and use textures to give it a brick look. And if you never see the flip side of it, just make it a 2D plane.

gamerfan


EgonOlsen

Wouldn't a simple plane be sufficient? Like Primitives.getPlane() creates it?

gamerfan


gamerfan

one more clarification,I have a box.As per the above pic, if I place one more box next to previous one, then what I need to do is share the vertices of the previous box.Then I think, the placing issues can be resolved.This is what @EgonOlsen has suggested.But using API , I do not know how to do it. :'(

EgonOlsen

You can't....and it doesn't make any sense either (at least to me). Maybe you can tell us, what your actual plans for that wall are. Maybe we are talking about different goals here...

gamerfan

my idea is when I keep click on a button, I shoud get my cube enlarged on x-axis that will have a wall kind of look or by some  other means.Eearlier I used scale factor.But the problem is my cube has been scaled to a bigger one. I do not want that.For example, It is like in 3d modelling tool where I click x-axis, it will increase its size on x-axis.Something similar to that.


EgonOlsen

Souns like as if non-uniform scaling is what you actually want. Here's an old thread about it, maybe it helps: http://www.jpct.net/forum2/index.php/topic,59.msg10162.html


gamerfan

I am getting null pointer exception during runtime.Let me paste the code snippet that I have used and exception details.

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

package org.me.home;

import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.MotionEvent;
import com.threed.jpct.Camera;
import com.threed.jpct.FrameBuffer;
import com.threed.jpct.GenericVertexController;
import com.threed.jpct.Light;
import com.threed.jpct.Logger;
import com.threed.jpct.Object3D;
import com.threed.jpct.Primitives;
import com.threed.jpct.RGBColor;
import com.threed.jpct.SimpleVector;
import com.threed.jpct.World;
import com.threed.jpct.util.MemoryHelper;
import java.lang.reflect.Field;
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLDisplay;
import javax.microedition.khronos.opengles.GL10;

/**
*
* @author Unni Vemanchery Mana
*/

public class MainActivity extends Activity {

// Used to handle pause and resume...
private static MainActivity master = null;

private GLSurfaceView mGLView;
private MyRenderer renderer = null;
private FrameBuffer fb = null;
private World world = null;
private RGBColor back = new RGBColor(50, 50, 100);

private float touchTurn = 0;
private float touchTurnUp = 0;

private float xpos = -1;
private float ypos = -1;

private Object3D cube = null;
        private Object3D box = null;
        private Object3D newbox = null;
        private Object3D line3d = null;

       
private int fps = 0;

private Light sun = null;

        private float xDelta = 1.5f;
        private float yDelta = 0;
        private float zDelta = 0;
        private int counter = 0;
       
       
    @Override
protected void onCreate(Bundle savedInstanceState) {

Logger.log("onCreate");

if (master != null) {
copy(master);
}

super.onCreate(savedInstanceState);
mGLView = new GLSurfaceView(getApplication());

mGLView.setEGLConfigChooser(new GLSurfaceView.EGLConfigChooser() {
public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
// Ensure that we get a 16bit framebuffer. Otherwise, we'll fall
// back to Pixelflinger on some device (read: Samsung I7500)
int[] attributes = new int[] { EGL10.EGL_DEPTH_SIZE, 16, EGL10.EGL_NONE };
EGLConfig[] configs = new EGLConfig[1];
int[] result = new int[1];
egl.eglChooseConfig(display, attributes, configs, 1, result);
return configs[0];
}
});

renderer = new MyRenderer();
mGLView.setRenderer(renderer);
setContentView(mGLView);
}

@Override
protected void onPause() {
super.onPause();
mGLView.onPause();
}

@Override
protected void onResume() {
super.onResume();
mGLView.onResume();
}

@Override
protected void onStop() {
super.onStop();
}

private void copy(Object src) {
try {
Logger.log("Copying data from master Activity!");
Field[] fs = src.getClass().getDeclaredFields();
for (Field f : fs) {
f.setAccessible(true);
f.set(this, f.get(src));
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}

    @Override
public boolean onTouchEvent(MotionEvent me) {

if (me.getAction() == MotionEvent.ACTION_DOWN) {
xpos = me.getX();
ypos = me.getY();
return true;
}

if (me.getAction() == MotionEvent.ACTION_UP) {
xpos = -1;
ypos = -1;
touchTurn = 0;
touchTurnUp = 0;
return true;
}

if (me.getAction() == MotionEvent.ACTION_MOVE) {
float xd = me.getX() - xpos;
float yd = me.getY() - ypos;

xpos = me.getX();
ypos = me.getY();

touchTurn = xd / -100f;
touchTurnUp = yd / -100f;
return true;
}

try {
Thread.sleep(15);
} catch (Exception e) {
// No need for this...
}

return super.onTouchEvent(me);
}

    @Override
        public boolean onKeyDown(int keyCode, KeyEvent msg) {
          if( keyCode == KeyEvent.KEYCODE_A ) {
              System.out.println(" total angle swept " + box.getTransformedCenter().calcAngle(box.getXAxis()) );
              //world.removeObject(box);
              //box = createBox(xDelta, 0.75f);
              //box.setAdditionalColor(RGBColor.WHITE);
              //box.translate(-10, 10, 0);
              //world.addObject( box );
              //world.buildAllObjects();
              VertexController vc = new VertexController(box);
              vc.scale(box.getTransformedCenter());
              xDelta+=1.5f;
              return true;
          }
         return true;
        }

        private Object3D drawRectangle() {
            Object3D rectangle = new Object3D(20);
            for (int y=0; y < 10; y++) {
        float fY = y / -10f;
        rectangle.addTriangle(new SimpleVector(-1, fY, 1), 0, 0,
                        new SimpleVector(-1, fY, -1), 0, 1,
                        new SimpleVector(1, fY, -1), 1, 1);
        rectangle.addTriangle(new SimpleVector(1, fY, -1), 1, 1,
                        new SimpleVector(1, fY, 1), 1, 0,
                        new SimpleVector(-1, fY, 1), 0, 0);
    }
     return rectangle;
  }

private Object3D createBox(float width, float height) {
     return Primitives.getBox(width, height);
}

private Object3D createLine (SimpleVector pointA, SimpleVector pointB, float width, String textureName)
{
    Object3D line = new Object3D( 8 );
    float offset = width / 2.0f;
    // Quad A:
    line.addTriangle( new SimpleVector( pointA.x, pointA.y - offset, pointA.z ), 0, 0,
                     new SimpleVector( pointA.x, pointA.y + offset, pointA.z ), 0, 1,
                     new SimpleVector( pointB.x, pointB.y + offset, pointB.z ), 1, 1
                     );
    line.addTriangle( new SimpleVector( pointB.x, pointB.y + offset, pointB.z ), 0, 0,
                     new SimpleVector( pointB.x, pointB.y - offset, pointB.z ), 0, 1,
                     new SimpleVector( pointA.x, pointA.y - offset, pointA.z ), 1, 1
                     );
    // Quad A, back-face:
    line.addTriangle( new SimpleVector( pointB.x, pointB.y - offset, pointB.z ), 0, 0,
                     new SimpleVector( pointB.x, pointB.y + offset, pointB.z ), 0, 1,
                     new SimpleVector( pointA.x, pointA.y + offset, pointA.z ), 1, 1
                     );
    line.addTriangle( new SimpleVector( pointA.x, pointA.y + offset, pointA.z ), 0, 0,
                     new SimpleVector( pointA.x, pointA.y - offset, pointA.z ), 0, 1,
                     new SimpleVector( pointB.x, pointB.y - offset, pointB.z ), 1, 1
                     );
    // Quad B:
    line.addTriangle( new SimpleVector( pointA.x, pointA.y, pointA.z + offset ), 0, 0,
                     new SimpleVector( pointA.x, pointA.y, pointA.z - offset ), 0, 1,
                     new SimpleVector( pointB.x, pointB.y, pointB.z - offset ), 1, 1
                     );
    line.addTriangle( new SimpleVector( pointB.x, pointB.y, pointB.z - offset ), 0, 0,
                     new SimpleVector( pointB.x, pointB.y, pointB.z + offset ), 0, 1,
                     new SimpleVector( pointA.x, pointA.y, pointA.z + offset ), 1, 1
                     );

    // Quad B, back-face:
    line.addTriangle( new SimpleVector( pointB.x, pointB.y, pointB.z + offset ), 0, 0,
                     new SimpleVector( pointB.x, pointB.y, pointB.z - offset ), 0, 1,
                     new SimpleVector( pointA.x, pointA.y, pointA.z - offset ), 1, 1
                     );
    line.addTriangle( new SimpleVector( pointA.x, pointA.y, pointA.z - offset ), 0, 0,
                     new SimpleVector( pointA.x, pointA.y, pointA.z + offset ), 0, 1,
                     new SimpleVector( pointB.x, pointB.y, pointB.z + offset ), 1, 1
                     );
 

    // If you don't want the line to react to lighting:
    line.setLighting( Object3D.LIGHTING_NO_LIGHTS );
    line.setAdditionalColor( RGBColor.WHITE );

    // done
    return line;
}

protected boolean isFullscreenOpaque() {
return true;
}

class MyRenderer implements GLSurfaceView.Renderer {

private long time = System.currentTimeMillis();

public MyRenderer() {
}

public void onSurfaceChanged(GL10 gl, int w, int h) {
if (fb != null) {
fb.dispose();
}
fb = new FrameBuffer(gl, w, h);

if (master == null) {

world = new World();
world.setAmbientLight(20, 20, 20);

sun = new Light(world);
sun.setIntensity(250, 250, 250);

// Create a texture out of the icon...:-)
//Texture texture = new Texture(BitmapHelper.rescale(BitmapHelper.convert(getResources().getDrawable(R.drawable.icon)), 64, 64));
//TextureManager.getInstance().addTexture("texture", texture);

cube = Primitives.getCube(1);
//cube.calcTextureWrapSpherical();
//cube.setTexture("texture");
//cube.strip();
//cube.build();

                                box = Primitives.getBox(1.5f, 0.75f);
                                box.setAdditionalColor(RGBColor.RED);
                              //  box.setTransparency(0);

                                box.translate(-10, 10, 0);
                                box.translateMesh();
                                box.strip();
                                System.out.println(" first box center "+ box.getOrigin());

                                // adding one more cube
                                newbox = Primitives.getBox(1.5f, 0.70f);
                                newbox.setAdditionalColor(RGBColor.RED);
                               // newbox.setTransparency(0);
                                newbox.translate((-10.0f + 1.0f), 10.0f, -1.0f);
                                newbox.translateMesh();
                                newbox.strip();


world.addObject(cube);
                                world.addObject(box);
                                world.addObject(newbox);


                                line3d = createLine(new SimpleVector(5,0,0), new SimpleVector(5,10,0), 2, "");
                                line3d.translate(5, 0, 0);
                                line3d.translateMesh();

                                world.addObject(line3d);

Camera cam = world.getCamera();
cam.moveCamera(Camera.CAMERA_MOVEOUT, 50);
cam.lookAt(cube.getTransformedCenter());

SimpleVector sv = new SimpleVector();
sv.set(cube.getTransformedCenter());
sv.y -= 100;
sv.z -= 100;
sun.setPosition(sv);
MemoryHelper.compact();

if (master == null) {
Logger.log("Saving master Activity!");
master = MainActivity.this;
}
}
}

public void onSurfaceCreated(GL10 gl, EGLConfig config) {
}

public void onDrawFrame(GL10 gl) {
if (touchTurn != 0) {
    cube.rotateY(touchTurn);
                            box.rotateY(touchTurn) ;
                            line3d.rotateY(touchTurn);
    touchTurn = 0;
                            yDelta +=0.02f;
}

if (touchTurnUp != 0) {
    cube.rotateX( touchTurnUp );
    touchTurnUp = 0;
}

fb.clear(back);
world.renderScene(fb);
world.draw(fb);
fb.display();

if (System.currentTimeMillis() - time >= 1000) {
//Logger.log(fps + "fps");
fps = 0;
time = System.currentTimeMillis();
}
fps++;
}
}

      class VertexController extends GenericVertexController {

        public VertexController( Object3D toCheck ) {
            if(toCheck.getMesh() == null )
              System.out.println(" ....It is null.... ");
            else
                System.out.println(" ....It is NOT null.... ");
      super.init(toCheck.getMesh(), true);
        }

        public void scale( SimpleVector scale ){
            SimpleVector[] vertices   = getSourceMesh();
    SimpleVector[] destination = getDestinationMesh();
            for (int i = 0; i < vertices.length; i++){
    //vertices[i].x *= scale.x;
              vertices[i].x += scale.x;
    //vertices[i].y *= scale.y;
    //vertices[i].z *= scale.z;
    destination[i].x = vertices[i].x;
    destination[i].y = vertices[i].y;
    destination[i].z = vertices[i].z;
    }
    this.updateMesh();
        }

        public void apply() {
        }
         
      }

}

=============================
  Exception details:
09-19 18:30:50.774: ERROR/AndroidRuntime(299): FATAL EXCEPTION: main
09-19 18:30:50.774: ERROR/AndroidRuntime(299): java.lang.NullPointerException
09-19 18:30:50.774: ERROR/AndroidRuntime(299):     at com.threed.jpct.GenericVertexController.init(GenericVertexController.java:89)
09-19 18:30:50.774: ERROR/AndroidRuntime(299):     at org.me.home.MainActivity$VertexController.<init>(MainActivity.java:372)
09-19 18:30:50.774: ERROR/AndroidRuntime(299):     at org.me.home.MainActivity.onKeyDown(MainActivity.java:175)
09-19 18:30:50.774: ERROR/AndroidRuntime(299):     at android.view.KeyEvent.dispatch(KeyEvent.java:1037)
09-19 18:30:50.774: ERROR/AndroidRuntime(299):     at android.app.Activity.dispatchKeyEvent(Activity.java:2068)
09-19 18:30:50.774: ERROR/AndroidRuntime(299):     at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1643)
09-19 18:30:50.774: ERROR/AndroidRuntime(299):     at android.view.ViewRoot.deliverKeyEventToViewHierarchy(ViewRoot.java:2471)
09-19 18:30:50.774: ERROR/AndroidRuntime(299):     at android.view.ViewRoot.handleFinishedEvent(ViewRoot.java:2441)
09-19 18:30:50.774: ERROR/AndroidRuntime(299):     at android.view.ViewRoot.handleMessage(ViewRoot.java:1735)
09-19 18:30:50.774: ERROR/AndroidRuntime(299):     at android.os.Handler.dispatchMessage(Handler.java:99)
09-19 18:30:50.774: ERROR/AndroidRuntime(299):     at android.os.Looper.loop(Looper.java:123)
09-19 18:30:50.774: ERROR/AndroidRuntime(299):     at android.app.ActivityThread.main(ActivityThread.java:4627)
09-19 18:30:50.774: ERROR/AndroidRuntime(299):     at java.lang.reflect.Method.invokeNative(Native Method)
09-19 18:30:50.774: ERROR/AndroidRuntime(299):     at java.lang.reflect.Method.invoke(Method.java:521)
09-19 18:30:50.774: ERROR/AndroidRuntime(299):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
09-19 18:30:50.774: ERROR/AndroidRuntime(299):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
09-19 18:30:50.774: ERROR/AndroidRuntime(299):     at dalvik.system.NativeStart.main(Native Method)

EgonOlsen

Try to remove the calls to strip(). Maybe i'm not checking for this and then the controller tries to access nulled properties. However, you are using the controller wrong anyway. The idea is to put the logic into apply() and set the controller in the Object3D's mesh. You then call applyVertexController on the Mesh and it will internally call apply() executing your logic.

gamerfan

what exactly the strip() method tries to do here?