Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Topics - jaychang0917

Pages: [1]
1
Bones / AnimatedGroup.applySkeletonPose() is too slow on Android
« on: April 18, 2017, 09:07:18 am »
My model has around 8000 polygons, I use the following code to rotate a joint, but I found the call animatedModel.applySkeletonPose() cause around 800 ms, which is too slow, have any idea to improve the performance? The method is called in game loop. Thanks.

Code: [Select]
void updateModel() {
    leftEyeRotateMatrix.setIdentity();
    leftEyeRotateMatrix.rotateX(eulerX);
    skeletonHelper.transformJoint("left_eye_sk", leftEyeRotateMatrix);
    skeletonHelper.pose.setToBindPose();
    skeletonHelper.pose.updateTransforms();
    animatedGroup.applySkeletonPose();
    animatedGroup.applyAnimation();
}

2
Support / How to set directional light and light euler angle?
« on: April 13, 2017, 12:29:18 pm »
Does jpct-ae support directional light? And how to set the light euler angle? Thanks!

3
Support / Model is not rendered correctly in Android using jpct-ae
« on: April 11, 2017, 12:14:32 pm »
I found a weird issue that the model (.bones) is not rendered correctly in Android using jpct-ae, but it is rendered correctly in desktop using jpct. The code are almost identical except the FrameBuffer object creation.

For android (jpct-ae)
Code: [Select]
frameBuffer = new FrameBuffer(width, height);

For desktop (jpct)
Code: [Select]
frameBuffer = new FrameBuffer(width, height, FrameBuffer.SAMPLINGMODE_NORMAL);

The following code is used to render model in Android
Code: [Select]
    if (frameBuffer != null) {
      frameBuffer.dispose();
    }

    frameBuffer = new FrameBuffer(width, height);

    if (world == null) {
      world = new World();
     
      // load model
      // mode.bones, which is exported using bones script (dae -> bones)
      InputStream stream = context.getResources().openRawResource(R.raw.model);
      try {
  animatedModel = BonesIO.loadGroup(stream);
  model = animatedModel.getRoot();

  Texture blueHead = new Texture((BitmapHelper.convert(context.getResources().getDrawable(R.drawable.blue_head))));
  Texture blue = new Texture((BitmapHelper.convert(context.getResources().getDrawable(R.drawable.blue))));
  Texture eye = new Texture((BitmapHelper.convert(context.getResources().getDrawable(R.drawable.eye))));
  Texture face = new Texture((BitmapHelper.convert(context.getResources().getDrawable(R.drawable.face))));
  Texture headTop = new Texture((BitmapHelper.convert(context.getResources().getDrawable(R.drawable.head_top))));
  Texture side = new Texture((BitmapHelper.convert(context.getResources().getDrawable(R.drawable.side))));
  Texture metalLightGrey = new Texture(8, 8, new RGBColor(61, 61, 61));
  Texture metalDark = new Texture(8, 8, new RGBColor(16, 16, 16));
  Texture metalGrey = new Texture(8, 8, new RGBColor(41, 41, 41));
  Texture metalBlue = new Texture(8, 8, new RGBColor(0, 52, 112));
  Texture metal = new Texture(8, 8, new RGBColor(102, 102, 102));
  Texture black = new Texture(8, 8, new RGBColor(0, 0, 0));
  // image
  TextureManager.getInstance().addTexture("blueHead", blueHead);
  TextureManager.getInstance().addTexture("blue", blue);
  TextureManager.getInstance().addTexture("eye", eye);
  TextureManager.getInstance().addTexture("face", face);
  TextureManager.getInstance().addTexture("headTop", headTop);
  TextureManager.getInstance().addTexture("side", side);
  // color
  TextureManager.getInstance().addTexture("metalLightGrey", metalLightGrey);
  TextureManager.getInstance().addTexture("metalDark", metalDark);
  TextureManager.getInstance().addTexture("metalGrey", metalGrey);
  TextureManager.getInstance().addTexture("metalBlue", metalBlue);
  TextureManager.getInstance().addTexture("metal", metal);
  TextureManager.getInstance().addTexture("black", black);

  for (Animated3D o : animatedModel) {
    o.build();
    o.discardMeshData();
  }
  // set texture
  animatedModel.get(0).setTexture("blueHead");
  animatedModel.get(1).setTexture("headTop");
  animatedModel.get(2).setTexture("metalLightGrey");
  animatedModel.get(3).setTexture("metalDark");
  animatedModel.get(4).setTexture("eye");
  animatedModel.get(5).setTexture("face");
  ....
   
          animatedModel.addToWorld(world);
} catch (Exception e) {
  e.printStackTrace();
} finally {
  try {
    stream.close();
  } catch (IOException e) {
    e.printStackTrace();
  }
}

      // camera
      com.threed.jpct.Camera cam = world.getCamera();
      cam.moveCamera(com.threed.jpct.Camera.CAMERA_MOVEOUT, 80);
      cam.lookAt(model.getTransformedCenter());

      // light
      world.setAmbientLight(20, 20, 20);
      sun = new Light(world);
      sun.setIntensity(250, 250, 250);
      SimpleVector sv = new SimpleVector();
      sv.set(model.getTransformedCenter());
      sv.y -= 100;
      sv.z -= 100;
      sun.setPosition(sv);
   }
}

Code: [Select]
@Override
  public void draw() {
    super.draw();
    frameBuffer.clear();
    world.renderScene(frameBuffer);
    world.draw(frameBuffer);
    frameBuffer.display();
  }


I have no idea why this happens. Thanks!

4
Bones / How to set texture to object material
« on: April 05, 2017, 09:42:51 am »
Suppose my model is a composite of objects, and each object contains few materials, I need to map different texture for each material.

I tried to print the name, i can't get the material name but object name. How can I get the material name of each object?
Code: [Select]
for (Animated3D o : skinnedGroup) {
    System.out.println("name:" + o.getName());
    o.build();
    o.discardMeshData();
}
// output
name:headMesh_triangles
name:headMesh_triangles
name:headMesh_triangles
name:headMesh_triangles
name:headMesh_triangles
name:headMesh_triangles
name:headMesh_triangles
name:headMesh_triangles
name:headMesh_triangles
name:headMesh_triangles
name:Cover_LMesh_triangles
name:Cover_LMesh_triangles
name:Cover_RMesh_triangles
...



5
Is there any method that i can rotate a model by euler angles (pitch, yaw, roll)?
Thanks!

6
Support / How to place object at specific location of world?
« on: March 24, 2017, 04:37:34 am »
I wanna place an object at the bottom right corner of world with the following code, it doesn't work.

How to place object at specific location of world?

Code: [Select]
Texture waterMarkTexture = new Texture(BitmapHelper.rescale(BitmapHelper.convert(context.getResources().getDrawable(R.drawable.logo_camino_white)), 128, 128));
      boolean isWaterMarkTextureAdded = TextureManager.getInstance().containsTexture("watermark");
      if (!isWaterMarkTextureAdded) {
        TextureManager.getInstance().addTexture("watermark", waterMarkTexture);
      }
      Object3D waterMarkModel = Primitives.getPlane(1, AppUtils.dp2px(context, 4));
      waterMarkModel.setTexture("watermark");
      int screenX = AppUtils.getScreenWidthPixels(context) - 20;
      SimpleVector position = Interact2D.reproject2D3DWS(world.getCamera(), frameBuffer, screenX, screenX);
      waterMarkModel.setOrigin(position);
      waterMarkModel.build();
      world.addObject(waterMarkModel);

7
Hi, I try to create a square image using the following code, i found that the object will be stretch in some device (i.e. full screen SurfaceView with different aspect ratio), how to keep the model in square? Thanks!

Code: [Select]
Texture waterMarkTexture = new Texture(BitmapHelper.rescale(BitmapHelper.convert(context.getResources().getDrawable(R.drawable.watermark)), 128, 128));
      boolean isWaterMarkTextureAdded = TextureManager.getInstance().containsTexture("watermark");
      if (!isWaterMarkTextureAdded) {
        TextureManager.getInstance().addTexture("watermark", waterMarkTexture);
      }
      Object3D waterMarkModel = Primitives.getPlane(1, 16);
      waterMarkModel.setTexture("watermark");
      waterMarkModel.setOrigin(new SimpleVector(45, 55, 0));
      waterMarkModel.rotateX((float) (Math.toRadians(19.3)));
      waterMarkModel.build();
      world.addObject(waterMarkModel);

8
Bones / No animations found in collada file!
« on: March 07, 2017, 10:48:12 am »
Hi, I am trying the sample "ProceduralAnimationSample", it throws the following exception when i use my own .dea file. I want to ask if the animations is necessary? It is because i animate the model programatically, so there is no predefined animations in the model.

Code: [Select]
Exception in thread "main" java.lang.IllegalArgumentException: ColladaStorage contains no skins.
at raft.jpct.bones.BonesImporter.importCollada(BonesImporter.java:52)
at bones.samples.ProceduralAnimationSample.initialize(ProceduralAnimationSample.java:84)
at bones.samples.AbstractSample.loop(AbstractSample.java:91)
at bones.samples.ProceduralAnimationSample.main(ProceduralAnimationSample.java:312)

Thanks!

9
Support / Load 3d model on top of Android camera preview?
« on: February 10, 2017, 04:57:45 pm »
Hi everyone, I have a project that need to achieve the following requirements:
  • Show android camera preview
  • Load a 3d model on top of it
  • Record the current display and save to a video file

And I tried to implement 1&2 with the following code, it throws an ArrayIndexOutOfBoundsException.

Code: [Select]
java.lang.ArrayIndexOutOfBoundsException: length=0; index=0
   at com.threed.jpct.CompiledInstance._fill(CompiledInstance.java:1206)
   at com.threed.jpct.CompiledInstance.fill(CompiledInstance.java:746)
   at com.threed.jpct.Object3DCompiler.compile(Object3DCompiler.java:148)
   at com.threed.jpct.World.compile(World.java:1951)
   at com.threed.jpct.World.renderScene(World.java:1046)
   at test.com.cameratest.MainRenderer.onDrawFrame(MainActivity.java:196)
   at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1522)
   at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1239)

Here is my code:
Code: [Select]
public class MainActivity extends Activity {
  private MainView mView;
  private PowerManager.WakeLock mWL;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // full screen & full brightness
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    mWL = ((PowerManager) getSystemService(Context.POWER_SERVICE)).newWakeLock(PowerManager.FULL_WAKE_LOCK, "WakeLock");
    mWL.acquire();
    mView = new MainView(this);
    setContentView(mView);
  }

  @Override
  protected void onPause() {
    if (mWL.isHeld())
      mWL.release();
    mView.onPause();
    super.onPause();
  }

  @Override
  protected void onResume() {
    super.onResume();
    mView.onResume();
    if (!mWL.isHeld()) mWL.acquire();
  }
}


// View
class MainView extends GLSurfaceView {
  MainRenderer mRenderer;

  MainView(Context context) {
    super(context);
    mRenderer = new MainRenderer(this);
    setEGLContextClientVersion(2);
    setRenderer(mRenderer);
    setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
  }

  public void surfaceCreated(SurfaceHolder holder) {
    super.surfaceCreated(holder);
  }

  public void surfaceDestroyed(SurfaceHolder holder) {
    mRenderer.close();
    super.surfaceDestroyed(holder);
  }

  public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
    super.surfaceChanged(holder, format, w, h);
  }

}


// Renderer
class MainRenderer implements GLSurfaceView.Renderer, SurfaceTexture.OnFrameAvailableListener {
  private final String vss =
    "attribute vec2 vPosition;\n" +
      "attribute vec2 vTexCoord;\n" +
      "varying vec2 texCoord;\n" +
      "void main() {\n" +
      "  texCoord = vTexCoord;\n" +
      "  gl_Position = vec4 ( vPosition.x, vPosition.y, 0.0, 1.0 );\n" +
      "}";

  private final String fss =
    "#extension GL_OES_EGL_image_external : require\n" +
      "precision mediump float;\n" +
      "uniform samplerExternalOES sTexture;\n" +
      "varying vec2 texCoord;\n" +
      "void main() {\n" +
      "  gl_FragColor = texture2D(sTexture,texCoord);\n" +
      "}";

  private int[] hTex;
  private FloatBuffer pVertex;
  private FloatBuffer pTexCoord;
  private int hProgram;

  private Camera mCamera;
  private SurfaceTexture mSTexture;

  private boolean mUpdateST = false;

  private MainView mView;

  private FrameBuffer fb = null;
  private World world = null;
  private Object3D model = null;
  private Light sun = null;

  MainRenderer(MainView view) {
    mView = view;
    float[] vtmp = {1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f};
    float[] ttmp = {1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f};
    pVertex = ByteBuffer.allocateDirect(8 * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
    pVertex.put(vtmp);
    pVertex.position(0);
    pTexCoord = ByteBuffer.allocateDirect(8 * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
    pTexCoord.put(ttmp);
    pTexCoord.position(0);
  }

  public void close() {
    mUpdateST = false;
    mSTexture.release();
    mCamera.stopPreview();
    mCamera.release();
    mCamera = null;
    deleteTex();
  }

  public void onSurfaceCreated(GL10 unused, EGLConfig config) {
    System.out.println("onSurfaceCreated");

    //String extensions = GLES20.glGetString(GLES20.GL_EXTENSIONS);
    //Log.i("mr", "Gl extensions: " + extensions);
    //Assert.assertTrue(extensions.contains("OES_EGL_image_external"));

    initTex();
    mSTexture = new SurfaceTexture(hTex[0]);
    mSTexture.setOnFrameAvailableListener(this);

    mCamera = Camera.open();
    try {
      mCamera.setPreviewTexture(mSTexture);
    } catch (IOException ioe) {
    }

    GLES20.glClearColor(1.0f, 1.0f, 0.0f, 1.0f);

    hProgram = loadShader(vss, fss);

    initModel();
  }

  public void onDrawFrame(GL10 unused) {
    System.out.println("onDrawFrame");

    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);

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

    synchronized (this) {
      if (mUpdateST) {
        mSTexture.updateTexImage();
        mUpdateST = false;
      }
    }

    GLES20.glUseProgram(hProgram);

    int ph = GLES20.glGetAttribLocation(hProgram, "vPosition");
    int tch = GLES20.glGetAttribLocation(hProgram, "vTexCoord");
    int th = GLES20.glGetUniformLocation(hProgram, "sTexture");

    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, hTex[0]);
    GLES20.glUniform1i(th, 0);

    GLES20.glVertexAttribPointer(ph, 2, GLES20.GL_FLOAT, false, 4 * 2, pVertex);
    GLES20.glVertexAttribPointer(tch, 2, GLES20.GL_FLOAT, false, 4 * 2, pTexCoord);
    GLES20.glEnableVertexAttribArray(ph);
    GLES20.glEnableVertexAttribArray(tch);

    GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
//    GLES20.glFlush();
  }

  private void initModel() {
    world = new World();
    world.setAmbientLight(20, 20, 20);

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

    Texture texture = new Texture(BitmapHelper.rescale(BitmapHelper.convert(App.context.getResources().getDrawable(R.drawable.monster)), 512, 512));
    TextureManager.getInstance().addTexture("texture", texture);

    model = loadModel(R.raw.monster, 1);
    model.setTexture("texture");
    model.build();

    world.addObject(model);

    com.threed.jpct.Camera cam = world.getCamera();
    cam.moveCamera(com.threed.jpct.Camera.CAMERA_MOVEOUT, 50);
    cam.lookAt(model.getTransformedCenter());

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

  private Object3D loadModel(int filename, float scale) {
    InputStream stream = App.context.getResources().openRawResource(filename);
    Object3D[] model = Loader.load3DS(stream, scale);
    Object3D o3d = new Object3D(0);
    Object3D temp = null;
    for (int i = 0; i < model.length; i++) {
      temp = model[i];
      System.out.println("model:" + temp.getName());
      temp.setCenter(SimpleVector.ORIGIN);
      temp.rotateX((float) (-.5 * Math.PI));
      temp.rotateMesh();
      temp.setRotationMatrix(new Matrix());
      o3d = Object3D.mergeObjects(o3d, temp);
      o3d.build();
    }
    return o3d;
  }


  public void onSurfaceChanged(GL10 unused, int width, int height) {
    System.out.println("onSurfaceChanged");

    if (fb != null) {
      fb.dispose();
    }
    fb = new FrameBuffer(unused, width, height);

    GLES20.glViewport(0, 0, width, height);
    Camera.Parameters param = mCamera.getParameters();
    List<Camera.Size> psize = param.getSupportedPreviewSizes();
    if (psize.size() > 0) {
      int i;
      for (i = 0; i < psize.size(); i++) {
        if (psize.get(i).width < width || psize.get(i).height < height)
          break;
      }
      if (i > 0)
        i--;
      param.setPreviewSize(psize.get(i).width, psize.get(i).height);
      //Log.i("mr","ssize: "+psize.get(i).width+", "+psize.get(i).height);
    }
    param.set("orientation", "landscape");
    mCamera.setParameters(param);
    mCamera.startPreview();
  }

  private void initTex() {
    hTex = new int[1];
    GLES20.glGenTextures(1, hTex, 0);
    GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, hTex[0]);
    GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
    GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
    GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
    GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
  }

  private void deleteTex() {
    GLES20.glDeleteTextures(1, hTex, 0);
  }

  public synchronized void onFrameAvailable(SurfaceTexture st) {
    mUpdateST = true;
    mView.requestRender();
  }

  private static int loadShader(String vss, String fss) {
    int vshader = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);
    GLES20.glShaderSource(vshader, vss);
    GLES20.glCompileShader(vshader);
    int[] compiled = new int[1];
    GLES20.glGetShaderiv(vshader, GLES20.GL_COMPILE_STATUS, compiled, 0);
    if (compiled[0] == 0) {
      Log.e("Shader", "Could not compile vshader");
      Log.v("Shader", "Could not compile vshader:" + GLES20.glGetShaderInfoLog(vshader));
      GLES20.glDeleteShader(vshader);
      vshader = 0;
    }

    int fshader = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
    GLES20.glShaderSource(fshader, fss);
    GLES20.glCompileShader(fshader);
    GLES20.glGetShaderiv(fshader, GLES20.GL_COMPILE_STATUS, compiled, 0);
    if (compiled[0] == 0) {
      Log.e("Shader", "Could not compile fshader");
      Log.v("Shader", "Could not compile fshader:" + GLES20.glGetShaderInfoLog(fshader));
      GLES20.glDeleteShader(fshader);
      fshader = 0;
    }

    int program = GLES20.glCreateProgram();
    GLES20.glAttachShader(program, vshader);
    GLES20.glAttachShader(program, fshader);
    GLES20.glLinkProgram(program);

    return program;
  }
}


Sample project: https://www.dropbox.com/s/d85q88bx27m71oj/CameraTest.zip?dl=0

Is my approach feasible? Please give me some advice, thank you!

Pages: [1]