Main Menu
Menu

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.

Show posts Menu

Topics - jaychang0917

#1
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.


void updateModel() {
    leftEyeRotateMatrix.setIdentity();
    leftEyeRotateMatrix.rotateX(eulerX);
    skeletonHelper.transformJoint("left_eye_sk", leftEyeRotateMatrix);
    skeletonHelper.pose.setToBindPose();
    skeletonHelper.pose.updateTransforms();
    animatedGroup.applySkeletonPose();
    animatedGroup.applyAnimation();
}
#2
Does jpct-ae support directional light? And how to set the light euler angle? Thanks!
#3
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)

frameBuffer = new FrameBuffer(width, height);


For desktop (jpct)

frameBuffer = new FrameBuffer(width, height, FrameBuffer.SAMPLINGMODE_NORMAL);


The following code is used to render model in Android

    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);
   }
}



@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
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?

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
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?


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!


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!
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.


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?
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.


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:

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!