java.lang.OutOfMemoryError while Loading .md2 model

Started by gamerfan, October 28, 2011, 03:00:20 PM

Previous topic - Next topic

gamerfan

I have a problem here.I am trying to load a.md2 model first by using Loader.loadSerialize....() method.The size of .ser file is 363 kb.The original size of the .md2 file is 370kb.But at this time there is no error reported in the console and the model does not load or display in the screen or not getting any error on the console. So I decided to load the model using Loader.loadMd2() method. It loads all the animations and finally it says model loaded and followed by it throws this error.This error happens exactly at this line.


world.compileAllObjects(fb);

=========The method that loads the md2 model
So I removed all of the animations except one from it.But still I am getting the same error.

private Object3D drawCrabs(){
       Object3D crab = null;
                Resources res = getResources();
         //       try {
                    System.out.println("Start loading crab md2 model");
                    crab = Loader.loadMD2(res.openRawResource(R.raw.crab), 0.1f);
                    //crab = Loader.loadSerializedObject(new GZIPInputStream(res.openRawResource(R.raw.crabser)));
                    System.out.println("End loading crab md2 model");
         //       }
         //    catch (IOException ex) {
           //     java.util.logging.Logger.getLogger(GameActivity.class.getName()).log(Level.SEVERE, null, ex);
         //   }
                //crab = Loader.loadSerializedObject(res.openRawResource(R.drawable.crabser));
               // crab = Loader.loadMD2(getAssets().open("model/crabser.ser"), 1.0f);
              //  Bitmap image = BitmapFactory.decodeResource(res, R.drawable.crab1);
              //  Texture texture = new Texture(image);
             //   TextureManager.getInstance().addTexture("crabone", texture);
             //   crab.setTexture("crabone");
               // removing some of the animation sequences from the model
                    int flip   = crab.getAnimationSequence().getSequence("flip");
                    int salute = crab.getAnimationSequence().getSequence("salute");
                    int point  = crab.getAnimationSequence().getSequence("point");
                    int attack = crab.getAnimationSequence().getSequence("attack");
                    int pain   = crab.getAnimationSequence().getSequence("pain");
                    int jump   = crab.getAnimationSequence().getSequence("jump");
                    int taunt  = crab.getAnimationSequence().getSequence("taunt");
                    int wave   = crab.getAnimationSequence().getSequence("wave");   
                    int crstnd   = crab.getAnimationSequence().getSequence("crstnd");
                    int crwalk   = crab.getAnimationSequence().getSequence("crwalk");
                    int crattack   = crab.getAnimationSequence().getSequence("crattack");
                    int crpain  = crab.getAnimationSequence().getSequence("crpain");
                    int crdeath  = crab.getAnimationSequence().getSequence("crdeath");
                    int death  = crab.getAnimationSequence().getSequence("death");


                    crab.getAnimationSequence().remove(flip);
                    crab.getAnimationSequence().remove(salute);
                    crab.getAnimationSequence().remove(point);
                    crab.getAnimationSequence().remove(attack);
                    crab.getAnimationSequence().remove(pain);
                    crab.getAnimationSequence().remove(jump);
                    crab.getAnimationSequence().remove(taunt);
                    crab.getAnimationSequence().remove(wave);
                    crab.getAnimationSequence().remove(crstnd);
                    crab.getAnimationSequence().remove(crwalk);
                    crab.getAnimationSequence().remove(crattack);
                    crab.getAnimationSequence().remove(crpain);
                    crab.getAnimationSequence().remove(crdeath);
                    crab.getAnimationSequence().remove(death);
                   
                crab.compile();
             //   crab.strip();
                crab.build();
                System.out.println("....Returning from draw method...");
            return crab;
   }

I am using netbeans android emulator for development.

EgonOlsen

Maybe something else is too large then. Can you post the complete log output?

gamerfan


10-31 10:11:38.490: INFO/System.out(285): Start loading crab md2 model
10-31 10:11:38.490: INFO/jPCT-AE(285): Loading file from InputStream
10-31 10:11:38.512: INFO/jPCT-AE(285): Expanding buffers...16384 bytes
10-31 10:11:38.512: INFO/jPCT-AE(285): Expanding buffers...24576 bytes
10-31 10:11:38.512: INFO/jPCT-AE(285): Expanding buffers...32768 bytes
10-31 10:11:38.512: INFO/jPCT-AE(285): Expanding buffers...40960 bytes
10-31 10:11:38.522: INFO/jPCT-AE(285): Expanding buffers...49152 bytes
10-31 10:11:38.522: INFO/jPCT-AE(285): Expanding buffers...57344 bytes
10-31 10:11:38.522: INFO/jPCT-AE(285): Expanding buffers...65536 bytes
10-31 10:11:38.721: INFO/jPCT-AE(285): Expanding buffers...73728 bytes
10-31 10:11:38.721: INFO/jPCT-AE(285): Expanding buffers...81920 bytes
10-31 10:11:38.781: DEBUG/dalvikvm(285): GC_FOR_MALLOC freed 1124 objects / 406824 bytes in 56ms
10-31 10:11:38.791: INFO/jPCT-AE(285): Expanding buffers...163840 bytes
10-31 10:11:38.852: DEBUG/dalvikvm(285): GC_FOR_MALLOC freed 138 objects / 86400 bytes in 61ms
10-31 10:11:38.852: INFO/jPCT-AE(285): Expanding buffers...245760 bytes
10-31 10:11:38.901: DEBUG/dalvikvm(285): GC_FOR_MALLOC freed 70 objects / 166128 bytes in 48ms
10-31 10:11:38.910: INFO/dalvikvm-heap(285): Grow heap (frag case) to 3.948MB for 327696-byte allocation
10-31 10:11:38.991: DEBUG/dalvikvm(285): GC_FOR_MALLOC freed 1 objects / 245784 bytes in 83ms
10-31 10:11:38.991: INFO/jPCT-AE(285): Expanding buffers...327680 bytes
10-31 10:11:38.991: INFO/jPCT-AE(285): Expanding buffers...409600 bytes
10-31 10:11:39.001: INFO/jPCT-AE(285): File from InputStream loaded...378156 bytes
10-31 10:11:39.062: DEBUG/dalvikvm(285): GC_FOR_MALLOC freed 18 objects / 328488 bytes in 59ms
10-31 10:11:39.062: INFO/jPCT-AE(285): Magic number: 844121161
10-31 10:11:39.062: INFO/jPCT-AE(285): Version: 8
10-31 10:11:39.062: INFO/jPCT-AE(285): Skin width: 256
10-31 10:11:39.062: INFO/jPCT-AE(285): Skin height: 256
10-31 10:11:39.062: INFO/jPCT-AE(285): Frame size: 1720
10-31 10:11:39.062: INFO/jPCT-AE(285): Number of skins: 1
10-31 10:11:39.062: INFO/jPCT-AE(285): Number of Vertices: 420
10-31 10:11:39.062: INFO/jPCT-AE(285): Number of Texture coordinates: 420
10-31 10:11:39.062: INFO/jPCT-AE(285): Number of triangles: 715
10-31 10:11:39.062: INFO/jPCT-AE(285): Number of GL-commands: 6801
10-31 10:11:39.062: INFO/jPCT-AE(285): Number of Frames: 198
10-31 10:11:39.071: INFO/jPCT-AE(285): Reading Texture coordinates...
10-31 10:11:39.071: INFO/jPCT-AE(285): Done!
10-31 10:11:39.071: INFO/jPCT-AE(285): Reading polygonal data...
10-31 10:11:39.081: INFO/jPCT-AE(285): Done!
10-31 10:11:39.152: DEBUG/dalvikvm(285): GC_FOR_MALLOC freed 67 objects / 412672 bytes in 56ms
10-31 10:11:39.302: DEBUG/dalvikvm(285): GC_FOR_MALLOC freed 2 objects / 48 bytes in 58ms
10-31 10:11:39.540: DEBUG/dalvikvm(285): GC_FOR_MALLOC freed 2 objects / 48 bytes in 83ms
10-31 10:11:39.812: DEBUG/dalvikvm(285): GC_FOR_MALLOC freed 2 objects / 48 bytes in 97ms
10-31 10:11:40.040: INFO/jPCT-AE(285): Reading keyframes...
10-31 10:11:40.540: INFO/jPCT-AE(285): Done!
10-31 10:11:40.540: INFO/jPCT-AE(285): Coverting MD2-format into jPCT-format...
10-31 10:11:42.092: INFO/jPCT-AE(285): Processing: stand...
10-31 10:11:42.221: DEBUG/dalvikvm(285): GC_FOR_MALLOC freed 2229 objects / 512512 bytes in 107ms
10-31 10:11:43.101: DEBUG/dalvikvm(285): GC_FOR_MALLOC freed 9185 objects / 1014944 bytes in 200ms
10-31 10:11:43.871: DEBUG/dalvikvm(285): GC_FOR_MALLOC freed 8805 objects / 1092064 bytes in 107ms
10-31 10:11:44.821: DEBUG/dalvikvm(285): GC_FOR_MALLOC freed 10257 objects / 1161600 bytes in 124ms
10-31 10:11:44.921: INFO/jPCT-AE(285): Processing: run...
10-31 10:11:45.271: INFO/jPCT-AE(285): Processing: attack...
10-31 10:11:45.712: INFO/ActivityManager(60): Process com.android.settings (pid 120) has died.
10-31 10:11:45.771: INFO/jPCT-AE(285): Processing: pain...
10-31 10:11:45.901: DEBUG/dalvikvm(285): GC_FOR_MALLOC freed 11736 objects / 1387208 bytes in 116ms
10-31 10:11:46.222: WARN/ActivityManager(60): Launch timeout has expired, giving up wake lock!
10-31 10:11:46.541: INFO/jPCT-AE(285): Processing: jump...
10-31 10:11:46.641: WARN/ActivityManager(60): Activity idle timeout for HistoryRecord{4401ab98 org.me.home/.GameActivity}
10-31 10:11:46.891: DEBUG/dalvikvm(285): GC_FOR_MALLOC freed 11728 objects / 1386968 bytes in 120ms
10-31 10:11:47.012: INFO/jPCT-AE(285): Processing: flip...
10-31 10:11:47.780: INFO/jPCT-AE(285): Processing: salute...
10-31 10:11:48.030: DEBUG/dalvikvm(285): GC_FOR_MALLOC freed 11732 objects / 1386968 bytes in 134ms
10-31 10:11:48.511: INFO/jPCT-AE(285): Processing: taunt...
10-31 10:11:49.051: INFO/ActivityManager(60): Process android.process.media (pid 208) has died.
10-31 10:11:49.160: DEBUG/dalvikvm(285): GC_FOR_MALLOC freed 11731 objects / 1386936 bytes in 257ms
10-31 10:11:49.691: INFO/jPCT-AE(285): Processing: wave...
10-31 10:11:50.172: DEBUG/dalvikvm(285): GC_FOR_MALLOC freed 11731 objects / 1386968 bytes in 135ms
10-31 10:11:50.442: INFO/jPCT-AE(285): Processing: point...
10-31 10:11:51.221: DEBUG/dalvikvm(285): GC_FOR_MALLOC freed 11731 objects / 1386912 bytes in 150ms
10-31 10:11:51.281: INFO/jPCT-AE(285): Processing: crstnd...
10-31 10:11:52.262: DEBUG/dalvikvm(285): GC_FOR_MALLOC freed 11731 objects / 1386952 bytes in 148ms
10-31 10:11:52.471: INFO/jPCT-AE(285): Processing: crwalk...
10-31 10:11:52.811: INFO/jPCT-AE(285): Processing: crattack...
10-31 10:11:53.451: DEBUG/dalvikvm(285): GC_FOR_MALLOC freed 11732 objects / 1387008 bytes in 169ms
10-31 10:11:53.611: INFO/jPCT-AE(285): Processing: crpain...
10-31 10:11:53.801: DEBUG/dalvikvm(117): GC_EXPLICIT freed 209 objects / 9944 bytes in 1196ms
10-31 10:11:53.832: INFO/jPCT-AE(285): Processing: crdeath...
10-31 10:11:54.102: INFO/jPCT-AE(285): Processing: death...
10-31 10:11:54.282: INFO/ActivityManager(60): Process com.android.alarmclock (pid 167) has died.
10-31 10:11:54.511: INFO/dalvikvm-heap(285): Clamp target GC heap from 16.486MB to 16.000MB
10-31 10:11:54.511: DEBUG/dalvikvm(285): GC_FOR_MALLOC freed 11733 objects / 1387056 bytes in 163ms
10-31 10:11:55.421: INFO/dalvikvm-heap(285): Clamp target GC heap from 16.975MB to 16.000MB
10-31 10:11:55.421: DEBUG/dalvikvm(285): GC_FOR_MALLOC freed 8072 objects / 1005472 bytes in 240ms
10-31 10:11:55.661: INFO/jPCT-AE(285): Done!
10-31 10:11:55.661: INFO/System.out(285): End loading crab md2 model
10-31 10:11:55.792: INFO/jPCT-AE(285): Normal vectors calculated in 126ms!
10-31 10:11:55.792: INFO/System.out(285): ....Returning from draw method...
10-31 10:11:55.851: INFO/jPCT-AE(285): [ 1320036115857 ] - WARNING: Object object3 hasn't been build yet. Forcing build()!
10-31 10:11:55.851: INFO/jPCT-AE(285): Normal vectors calculated in 2ms!
10-31 10:11:55.861: ERROR/dalvikvm-heap(285): 288-byte external allocation too large for this process.
10-31 10:11:55.861: WARN/OSMemory(285): External allocation of 288 bytes was rejected
10-31 10:11:55.901: WARN/dalvikvm(285): threadid=7: thread exiting with uncaught exception (group=0x4001d800)
10-31 10:11:55.931: INFO/ActivityManager(60): Displayed activity org.me.home/.GameActivity: 19632 ms (total 19632 ms)
10-31 10:11:56.041: ERROR/AndroidRuntime(285): FATAL EXCEPTION: GLThread 8
10-31 10:11:56.041: ERROR/AndroidRuntime(285): java.lang.OutOfMemoryError
10-31 10:11:56.041: ERROR/AndroidRuntime(285):     at org.apache.harmony.luni.platform.OSMemory.malloc(Native Method)
10-31 10:11:56.041: ERROR/AndroidRuntime(285):     at org.apache.harmony.luni.platform.PlatformAddressFactory.alloc(PlatformAddressFactory.java:150)
10-31 10:11:56.041: ERROR/AndroidRuntime(285):     at java.nio.DirectByteBuffer.<init>(DirectByteBuffer.java:66)
10-31 10:11:56.041: ERROR/AndroidRuntime(285):     at java.nio.ReadWriteDirectByteBuffer.<init>(ReadWriteDirectByteBuffer.java:51)
10-31 10:11:56.041: ERROR/AndroidRuntime(285):     at java.nio.BufferFactory.newDirectByteBuffer(BufferFactory.java:93)
10-31 10:11:56.041: ERROR/AndroidRuntime(285):     at java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:68)
10-31 10:11:56.041: ERROR/AndroidRuntime(285):     at com.threed.jpct.CompiledInstance.fill(CompiledInstance.java:740)
10-31 10:11:56.041: ERROR/AndroidRuntime(285):     at com.threed.jpct.Object3DCompiler.compile(Object3DCompiler.java:151)
10-31 10:11:56.041: ERROR/AndroidRuntime(285):     at com.threed.jpct.World.compile(World.java:2055)
10-31 10:11:56.041: ERROR/AndroidRuntime(285):     at com.threed.jpct.World.compileAllObjects(World.java:1000)
10-31 10:11:56.041: ERROR/AndroidRuntime(285):     at org.me.home.GameActivity$MyRenderer.onSurfaceChanged(GameActivity.java:295)
10-31 10:11:56.041: ERROR/AndroidRuntime(285):     at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1325)
10-31 10:11:56.041: ERROR/AndroidRuntime(285):     at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1116)
10-31 10:11:56.231: WARN/ActivityManager(60):   Force finishing activity org.me.home/.GameActivity

EgonOlsen

Simply looks like as if the model is too large, which is a bit odd. Can you upload that model somewhere to verify this?

gamerfan

I actually the model that I am using not made my me.It is used for some C++ openGL game application.I am just re using the model here. However, I can upload the model here:
http://code.google.com/p/androiddemogame/downloads/list.
From there you can download the models.

EgonOlsen

This model is actually not that small. It has 715 polygons and 420 unique vertices * 198 keyframes, i.e. it uses a total of >140.000 polygons and >83.000 vertices. However, you can get rid of most of this data, simply because it isn't needed in most cases. Just do a call to


crab.getAnimationSequence().strip();


and most of the data of these 140.000 polygon will be removed because it isn't needed for animations only. I just can't do this by default, because one might want to access it in some cases.

gamerfan

I have one clarification here. Using jPCT for desktop, if I call the above method and serialize the model, will the actual size of the model will reduce so that I can use it in AE version?

EgonOlsen

Good question. It should work, but i think i've never really tried it myself. Just give it a try. If it doesn't work, it's a bug and should be fixed.

gamerfan

This is the current method I am using serializing the model.

      private void serializeTheModel(String modelName) {
        System.out.println("[inside serializeTheModel methiod]") ;
        Object3D model = Loader.loadMD2(modelName, 0.1f);
        model.getAnimationSequence().strip();
        model.compile();
        model.build();
        DeSerializer serializer = new DeSerializer();
        try {
              serializer.serialize(model, new FileOutputStream("crab.ser"), true);
        } catch (IOException ex) {
            java.util.logging.Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
        System.out.println("[ serializing the model is over......]") ;
      }

After this method execution, the size of the model becomes extremely large.It comes around 2 MB!. I do not have any idea why this is happening.

EgonOlsen

That's a normal size for a serialized model. MD2 uses a lossy compression to keep files small. The best way to deal with serialized objects is to zip them and load them via a ZipInputStream.

gamerfan

#10
the problem is that when I serialize it, I am not able to load the model in AE.Also,, I tried the way you had suggested in the earlier post.But that way it is not reducing the size of the model

EgonOlsen

Quote from: gamerfan on November 02, 2011, 10:10:54 AM
the problem is that when I serialize it, I am not able to load the model in AE.
Why not?

gamerfan

I was able to load the model that is available in the alien runner AE application.That is loading.This is the code that is used to load it.

private InputStream loadZip() {
    ZipInputStream is = null;
    Resources res = getResources();
    is = new ZipInputStream(res.openRawResource(R.raw.crab));
    try {
  is.getNextEntry();
} catch (IOException e) {
  throw new RuntimeException(e);
}
    System.out.println(" the value of is "+is);
    return is;
   }

I serialized my model and later zipped it manually as you suggested after removing  many of the unwanted animation sequences by just leaving one animation and called strip() method on it with the following code. At this time, the size of the model was reduced considerably less.But when I loaded the model with the above method,I am getting the following exception.

private void serializeTheModel(String modelName) {
        System.out.println("[inside serializeTheModel methiod]") ;
        Object3D model = Loader.loadMD2(modelName, 0.1f);
        Animation animation = model.getAnimationSequence();
        animation.remove(animation.getSequence("stand"));
        animation.remove(animation.getSequence("attack"));
        animation.remove(animation.getSequence("pain"));
        animation.remove(animation.getSequence("jump"));
        animation.remove(animation.getSequence("flip"));
        animation.remove(animation.getSequence("salute"));
        animation.remove(animation.getSequence("taunt"));
        animation.remove(animation.getSequence("wave"));
        animation.remove(animation.getSequence("point"));
        animation.remove(animation.getSequence("crstnd"));
        animation.remove(animation.getSequence("crwalk"));
        animation.remove(animation.getSequence("crattack"));
        animation.remove(animation.getSequence("crpain"));
        animation.remove(animation.getSequence("crdeath"));
        animation.remove(animation.getSequence("death"));
        model.getAnimationSequence().strip();
        model.build();
        DeSerializer serializer = new DeSerializer();
        try {
              FileOutputStream fos = new FileOutputStream("crab.ser");
              serializer.serialize(model, fos, true);
              fos.close();
        } catch (IOException ex) {
            java.util.logging.Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
        System.out.println("[ serializing the model is over......]") ;
      }

Quote
     11-03 11:40:14.390: ERROR/AndroidRuntime(566): java.lang.RuntimeException: [ 1320300614202 ] - ERROR: Can't deserialize object: null
11-03 11:40:14.390: ERROR/AndroidRuntime(566):     at com.threed.jpct.Logger.log(Logger.java:189)
11-03 11:40:14.390: ERROR/AndroidRuntime(566):     at com.threed.jpct.DeSerializer.deserialize(DeSerializer.java:210)
11-03 11:40:14.390: ERROR/AndroidRuntime(566):     at com.threed.jpct.Loader.loadSerializedObject(Loader.java:97)
11-03 11:40:14.390: ERROR/AndroidRuntime(566):     at org.me.home.GameActivity$MyRenderer.drawCrabs(GameActivity.java:405)
11-03 11:40:14.390: ERROR/AndroidRuntime(566):     at org.me.home.GameActivity$MyRenderer.onSurfaceChanged(GameActivity.java:281)
11-03 11:40:14.390: ERROR/AndroidRuntime(566):     at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1325)
11-03 11:40:14.390: ERROR/AndroidRuntime(566):     at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1116)
What I am missing ?

EgonOlsen

Might be that i don't handle stripped animations correctly. I'll look into it.

gamerfan

I was able to resolve the issue here. I just serialized the model and loaded after stripping some of the animation sequences.The .md2 model loaded successfully.But when I told that it was not working means I have some other objects also in the screen.Along with those objects, this model is not displaying.I came to know this when I commented some part of the code where it is loading the other models. :).Thanks for your support.However,I was able to understand some more things!.I  just loaded the model by serialzing it.