Author Topic: ArrayIndexOutOfBoundsException in World.renderScene()  (Read 4109 times)

Offline robert

  • byte
  • *
  • Posts: 40
    • View Profile
ArrayIndexOutOfBoundsException in World.renderScene()
« on: October 28, 2012, 11:57:38 pm »
Hi there, I got this report today from a couple of users. Stacktrace follows:

java.lang.ArrayIndexOutOfBoundsException
at com.threed.jpct.CompiledInstance.fill(CompiledInstance.java:1017)
at com.threed.jpct.Object3DCompiler.compile(Object3DCompiler.java:145)
at com.threed.jpct.World.compile(World.java:1911)
at com.threed.jpct.World.renderScene(World.java:1035)

The full code that triggers this crash is the following:

mFrameBuffer.clear();
mSkyBox.render(mWorld, mFrameBuffer);
mWorld.renderScene(mFrameBuffer);    <----- This is the culprit
mWorld.draw(mFrameBuffer);
mFrameBuffer.display();

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11776
    • View Profile
    • http://www.jpct.net
Re: ArrayIndexOutOfBoundsException in World.renderScene()
« Reply #1 on: October 29, 2012, 07:14:50 am »
Using which version of jPCT-AE?

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11776
    • View Profile
    • http://www.jpct.net
Re: ArrayIndexOutOfBoundsException in World.renderScene()
« Reply #2 on: October 29, 2012, 07:22:09 am »
Any chance that you've played around with this setting http://www.jpct.net/jpct-ae/doc/com/threed/jpct/Config.html#vertexBufferSize? If so, don't do that... ;)

Offline robert

  • byte
  • *
  • Posts: 40
    • View Profile
Re: ArrayIndexOutOfBoundsException in World.renderScene()
« Reply #3 on: October 29, 2012, 12:00:49 pm »
Any chance that you've played around with this setting http://www.jpct.net/jpct-ae/doc/com/threed/jpct/Config.html#vertexBufferSize? If so, don't do that... ;)

Hi Egon. No, I've not changed that setting. Since I'm using Bugsense, I know exactly which devices the failure happened on:

- LGL35G (Low end, small screen 240x320).
- LG-E400 (Low end, small screen 240x320).
- XT557 (Motorola, 512MB RAM, 1Ghz Processor, 854x480 screen). This has the same features than my test phone (Xperia Neo V).
- WT19a (CPU Scorpion at 1 GHz, GPU Adreno 205, chipset Qualcomm MSM8255 Snapdragon).
- GT-I9003 (Samsung Galaxy S).

All devices are running Android Gingerbread, and I'm using latest JPCT-AE (1.25).

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11776
    • View Profile
    • http://www.jpct.net
Re: ArrayIndexOutOfBoundsException in World.renderScene()
« Reply #4 on: October 29, 2012, 12:20:37 pm »
I fail to see any relation to the hardware or the Android version ATM...can you please give the latest beta a try: http://jpct.de/download/beta/jpct_ae.jar?

Offline robert

  • byte
  • *
  • Posts: 40
    • View Profile
Re: ArrayIndexOutOfBoundsException in World.renderScene()
« Reply #5 on: October 29, 2012, 01:07:59 pm »
I fail to see any relation to the hardware or the Android version ATM...can you please give the latest beta a try: http://jpct.de/download/beta/jpct_ae.jar?

I'm going to give the beta a try and report back. Thanks.

Offline robert

  • byte
  • *
  • Posts: 40
    • View Profile
Re: ArrayIndexOutOfBoundsException in World.renderScene()
« Reply #6 on: November 01, 2012, 10:16:11 pm »
Egon, the error is still there with the latest beta:

java.lang.ArrayIndexOutOfBoundsException
at com.threed.jpct.CompiledInstance.fill(CompiledInstance.java:1068)
at com.threed.jpct.Object3DCompiler.compile(Object3DCompiler.java:145)
at com.threed.jpct.World.compile(World.java:1928)
at com.threed.jpct.World.renderScene(World.java:1044)
...

This time the device that triggered the error is this one: http://pdadb.net/index.php?m=specs&id=2751&c=samsung_gt-s5660_galaxy_gio  (but running Android 2.3.6 instead of 2.2).

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11776
    • View Profile
    • http://www.jpct.net
Re: ArrayIndexOutOfBoundsException in World.renderScene()
« Reply #7 on: November 01, 2012, 11:15:29 pm »
Are you by any chance doing a call like  object3D.compile(false, true); in your code? If so, do you have to? Are you really changing the uv-coordinates on the fly?

Offline robert

  • byte
  • *
  • Posts: 40
    • View Profile
Re: ArrayIndexOutOfBoundsException in World.renderScene()
« Reply #8 on: November 02, 2012, 12:51:04 am »
Are you by any chance doing a call like  object3D.compile(false, true); in your code? If so, do you have to? Are you really changing the uv-coordinates on the fly?

Nope, I'm not calling compile(), just build(). Here's the code I use to load the mesh:

Code: [Select]
String meshName = mPreferences.getString("mesh", null);
int id = res.getIdentifier(meshName, "raw", mContext.getPackageName());
InputStream is = res.openRawResource(id);
mMesh = Loader.loadSerializedObjectArray(is)[0];
mMesh.rotateX((float)(Math.PI / 2.0f));
mMesh.rotateMesh();
mMesh.setSpecularLighting(true);
mMesh.build();
mWorld.addObject(mMesh);

I suspect it has something to do with short vs int buffers... since I use both Rajawali and your engine, and the author of Rajawali had a similar issue: https://github.com/MasDennis/Rajawali/issues/20

Also, it seems that not all devices support int buffer as shown here: https://github.com/MasDennis/Rajawali/issues/28
« Last Edit: November 02, 2012, 12:55:47 am by robert »

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11776
    • View Profile
    • http://www.jpct.net
Re: ArrayIndexOutOfBoundsException in World.renderScene()
« Reply #9 on: November 02, 2012, 07:24:56 am »
No, it has nothing to do with that. It's just the access to some VM side arrays to process uv-coordinates of the object in question. And i still fail to see any relation to the device's hardware it's running on except that this code is somehow related to the number of texture units that the underlying hardware supports. Maybe that it the problem somehow...how does your code look that assigns the textures to these objects?

Edit: Do you have access to such a device so that i can give you some debug version to run on it?
« Last Edit: November 02, 2012, 07:35:42 am by EgonOlsen »

Offline robert

  • byte
  • *
  • Posts: 40
    • View Profile
Re: ArrayIndexOutOfBoundsException in World.renderScene()
« Reply #10 on: November 02, 2012, 12:54:33 pm »
Hi Egon,

Unfortunately I don't have access to any of those devices. I own a couple of devices, and the code works fine on them.

I don't set any texture on the mesh, I just light it with some color, like this:

Code: [Select]
mKeyLight = new Light(mWorld);
mKeyLight.setIntensity(Color.red(meshColor), Color.green(meshColor), Color.blue(meshColor));
SimpleVector sv = new SimpleVector(mMesh.getTransformedCenter());
sv.y -= 100;
sv.z -= 100;
sv.rotateY((float)(-Math.PI / 8.0f));
mKeyLight.setPosition(sv);

Note that I use two more lights, a fill light and a rim light, but I don't think that really matters. The only other mesh I have in the scene beside the main mesh, is a simple billboarded plane with a 256x256 texture.

In total, there are 6 512x512 textures for the skybox and 1 256x256 texture for the billboarded plane (and I'm still getting OOM errors on some devices [mostly mdpi 320x480 devices]). Since you asked for it, here's the code that assigns a texture to the billboarded plane:

Code: [Select]
String sunName = "sun" + sufix;
int id = res.getIdentifier(sunName, "drawable", mContext.getPackageName());
Log.d(TAG, "Loading new texture " + sunName);
tm.addTexture("light", new Texture(res.getDrawable(id), true));

// Create sun billboarded plane
Object3D sun = Primitives.getPlane(1, 3.0f);
sun.setBillboarding(true);
sun.translate(1.0f, -2.5f, -3.5f);
sun.setTexture("light");
sun.setTransparency(1000);
sun.setLighting(Object3D.LIGHTING_NO_LIGHTS);
sun.setAdditionalColor(RGBColor.WHITE);
sun.build();
mWorld.addObject(sun);

Maybe it has something to do with the number of polygons in the main mesh ? It has 6432 triangles, 3218 vertices... but please notice that I just use one mesh in the scene besides the simple billboarded plane.

P.D: I serialize the mesh with this code:

Code: [Select]

Object3D[] objs = Loader.loadOBJ(inputFileName, null, 1.0f);
for (Object3D obj : objs) {
obj.build();
}
String outputFileName = inputFileName.substring(0, inputFileName.lastIndexOf('.')) + ".ser";
new DeSerializer().serializeArray(objs, new FileOutputStream(outputFileName), true);

Thank you for your support.
« Last Edit: November 02, 2012, 01:05:48 pm by robert »

Offline K24A3

  • long
  • ***
  • Posts: 231
    • View Profile
Re: ArrayIndexOutOfBoundsException in World.renderScene()
« Reply #11 on: November 02, 2012, 01:23:13 pm »
Are you using multithreading separating the manipulation of 3D objects in one thread and having the render in another?

This has always been troublesome so if you are doing this, try doing everything in the rendering thread using a frame delta to calculate the correct movement of objects.

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11776
    • View Profile
    • http://www.jpct.net
Re: ArrayIndexOutOfBoundsException in World.renderScene()
« Reply #12 on: November 02, 2012, 02:01:02 pm »
Are you using multithreading separating the manipulation of 3D objects in one thread and having the render in another?
That's the only idea that i've left too...it might help to see the rest of the stack trace and not just that part after renderScene().

Offline robert

  • byte
  • *
  • Posts: 40
    • View Profile
Re: ArrayIndexOutOfBoundsException in World.renderScene()
« Reply #13 on: November 02, 2012, 03:51:07 pm »
Are you using multithreading separating the manipulation of 3D objects in one thread and having the render in another?
That's the only idea that i've left too...it might help to see the rest of the stack trace and not just that part after renderScene().

There's not much in the stack frame...

Code: [Select]
java.lang.ArrayIndexOutOfBoundsException
at com.threed.jpct.CompiledInstance.fill(CompiledInstance.java:1068)
at com.threed.jpct.Object3DCompiler.compile(Object3DCompiler.java:145)
at com.threed.jpct.World.compile(World.java:1928)
at com.threed.jpct.World.renderScene(World.java:1044)
at com.wallpaper.MyRenderer.onDrawFrame(MyRenderer.java:264)
at net.rbgrn.android.glwallpaperservice.GLThread.guardedRun(GLWallpaperService.java:627)
at net.rbgrn.android.glwallpaperservice.GLThread.run(GLWallpaperService.java:492)

And yes, as you can see the wallpaperservice creates a thread, but it takes care of the setup. I initialize all JPCT code in onSurfaceChanged() and manipulate it in onDrawFrame() so I don't see how that might be causing the error... In fact, I have coded three wallpapers with Rajawali (which internally uses the GLWallpaperService by Robert Green) and never had any issues.
« Last Edit: November 02, 2012, 03:52:39 pm by robert »

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11776
    • View Profile
    • http://www.jpct.net
Re: ArrayIndexOutOfBoundsException in World.renderScene()
« Reply #14 on: November 02, 2012, 05:34:35 pm »
I've no idea what this wallpaper stuff does exactly, but if it blindly spawns a thread in on<Something>, this might cause a problem. Some Android versions show a strange behaviour when it comes to create and destroy Acitivities. Maybe it happens that two of these threads exist in parallel, at least for a short time. The line that fails is this:

Code: [Select]
smallBufferMT[0][sbPosMT[0]++] = ((int) (u[pind] * 65536f));

pind can't cause the exception, because it has been used multiple times before in that method  on arrays of the exact same size as u. The 0 index can't cause it either, because it's always sized 4. The same goes for sbPosMT. So all that's left is smallBufferMT[0][sbPosMT[0]++]. This can't cause the error either if the code isn't called in multiple threads. If it is, this counter might overflow.

I've updated the beta jar with two changes: Calling the method from multiple threads should now happen in a synchronized way. While this doesn't fix the root problem, it might cure the symptoms. If it doesn't, i've added extended logging that prints out some indices in cause of an exception.

I hope this helps in one way or the other.