Advertisement
ginkage

Untitled

May 31st, 2012
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import java.io.BufferedInputStream;
  2. import java.io.File;
  3. import java.io.FileInputStream;
  4. import java.io.FileNotFoundException;
  5. import java.io.IOException;
  6. import java.util.ArrayList;
  7.  
  8. import android.opengl.Matrix;
  9. import android.os.Environment;
  10.  
  11. public class Load3DS {
  12.     private final int CHUNK_MAIN     = 0x4D4D;
  13.     private final int CHUNK_OBJMESH  = 0x3D3D;
  14.     private final int CHUNK_OBJBLOCK = 0x4000;
  15.     private final int CHUNK_TRIMESH  = 0x4100;
  16.     private final int CHUNK_VERTLIST = 0x4110;
  17.     private final int CHUNK_FACELIST = 0x4120;
  18.     private final int CHUNK_FACEMAT  = 0x4130;
  19.     private final int CHUNK_MAPLIST  = 0x4140;
  20.     private final int CHUNK_SMOOTHG  = 0x4150;
  21.     private final int CHUNK_TRMATRIX = 0x4160;
  22.     private final int CHUNK_LIGHT    = 0x4600;
  23.     private final int CHUNK_SPOTL    = 0x4610;
  24.     private final int CHUNK_ONOFF    = 0x4620;
  25.     private final int CHUNK_CAMERA   = 0x4700;
  26.     private final int CHUNK_RGBC     = 0x0010;
  27.     private final int CHUNK_RGB24    = 0x0011;
  28.     private final int CHUNK_SHORT    = 0x0030;
  29.     private final int CHUNK_BACKCOL  = 0x1200;
  30.     private final int CHUNK_AMB      = 0x2100;
  31.     private final int CHUNK_MATERIAL = 0xAFFF;
  32.     private final int CHUNK_MATNAME  = 0xA000;
  33.     private final int CHUNK_AMBIENT  = 0xA010;
  34.     private final int CHUNK_DIFFUSE  = 0xA020;
  35.     private final int CHUNK_SPECULAR = 0xA030;
  36.     private final int CHUNK_SHININES = 0xA040;
  37.     private final int CHUNK_SHINSTRN = 0xA041;
  38.     private final int CHUNK_TRANSP   = 0xA050;
  39.     private final int CHUNK_SELFILL  = 0xA084;
  40.     private final int CHUNK_MTLTYPE  = 0xA100;
  41.     private final int CHUNK_TEXTURE  = 0xA200;
  42.     private final int CHUNK_REFLMAP  = 0xA220;
  43.     private final int CHUNK_BUMPMAP  = 0xA230;
  44.     private final int CHUNK_MAPFILE  = 0xA300;
  45.     private final int CHUNK_MAPPARAM = 0xA351;
  46.     private final int CHUNK_KEYFRAMER = 0xB000;
  47.     private final int CHUNK_TRACKINFO = 0xB002;
  48.     private final int CHUNK_SPOTINFO  = 0xB007;
  49.     private final int CHUNK_FRAMES    = 0xB008;
  50.     private final int CHUNK_OBJNAME   = 0xB010;
  51.     private final int CHUNK_PIVOT     = 0xB013;
  52.     private final int CHUNK_TRACKPOS  = 0xB020;
  53.     private final int CHUNK_TRACKROT  = 0xB021;
  54.     private final int CHUNK_TRACKSCL  = 0xB022;
  55.     private final int CHUNK_HIERARCHY = 0xB030;
  56.  
  57.     private BufferedInputStream file;
  58.     private byte[] bytes = new byte[8];
  59.     private long filePos;
  60.  
  61.     public Scene3D Load(String fileName)
  62.     {
  63.         file = null;
  64.         Scene3D scene = null;
  65.         File dir = new File(Environment.getExternalStorageDirectory().getAbsolutePath());
  66.         File fil = new File(dir.getAbsolutePath() + File.separator + fileName);
  67.         if (!fil.exists()) return scene;
  68.  
  69.         try {
  70.             filePos = 0;
  71.             file = new BufferedInputStream(new FileInputStream(fil));
  72.             scene = ProcessFile(fil.length());
  73.         } catch (FileNotFoundException e) {
  74.             e.printStackTrace();
  75.         } catch (IOException e) {
  76.             e.printStackTrace();
  77.         }
  78.        
  79.         try {
  80.             if (file != null)
  81.                 file.close();
  82.         } catch (IOException e) {
  83.             e.printStackTrace();
  84.         }
  85.        
  86.         return scene;
  87.     }
  88.    
  89.     private void Skip(long count) throws IOException
  90.     {
  91.         file.skip(count);
  92.         filePos += count;
  93.     }
  94.  
  95.     private void Seek(long end) throws IOException
  96.     {
  97.         if (filePos < end) {
  98.             Skip(end - filePos);
  99.             filePos = end;
  100.         }
  101.     }
  102.  
  103.     private byte ReadByte() throws IOException
  104.     {
  105.         file.read(bytes, 0, 1);
  106.         filePos++;
  107.         return bytes[0];
  108.     }
  109.  
  110.     private int ReadUnsignedByte() throws IOException
  111.     {
  112.         file.read(bytes, 0, 1);
  113.         filePos++;
  114.         return (bytes[0]&0xff);
  115.     }
  116.  
  117.     private int ReadUnsignedShort() throws IOException
  118.     {
  119.         file.read(bytes, 0, 2);
  120.         filePos += 2;
  121.         return ((bytes[1]&0xff) << 8 | (bytes[0]&0xff));
  122.     }
  123.  
  124.     private int ReadInt() throws IOException
  125.     {
  126.         file.read(bytes, 0, 4);
  127.         filePos += 4;
  128.         return (bytes[3]) << 24 | (bytes[2]&0xff) << 16 | (bytes[1]&0xff) <<  8 | (bytes[0]&0xff);
  129.     }
  130.    
  131.     private float ReadFloat() throws IOException
  132.     {
  133.         return Float.intBitsToFloat(ReadInt());
  134.     }
  135.  
  136.     private Scene3D ProcessFile(long fileLen) throws IOException
  137.     {
  138.         Scene3D scene = null;
  139.  
  140.         while (filePos < fileLen) {
  141.             int chunkID = ReadUnsignedShort();
  142.             int chunkLen = ReadInt() - 6;
  143.  
  144.             switch (chunkID) {
  145.             case CHUNK_MAIN:
  146.                 if (scene == null)
  147.                     scene = ChunkMain(chunkLen);
  148.                 else
  149.                     Skip(chunkLen);
  150.                 break;
  151.  
  152.             default:
  153.                 Skip(chunkLen);
  154.             }
  155.         }
  156.        
  157.         return scene;
  158.     }
  159.  
  160.     private Scene3D ChunkMain(int len) throws IOException
  161.     {
  162.         Scene3D scene = new Scene3D();
  163.         scene.materials = new ArrayList<Material3D>();
  164.         scene.objects = new ArrayList<Object3D>();
  165.         scene.lights = new ArrayList<Light3D>();
  166.         scene.animations = new ArrayList<Animation>();
  167.  
  168.         long end = filePos + len;
  169.         while (filePos < end) {
  170.             int chunkID = ReadUnsignedShort();
  171.             int chunkLen = ReadInt() - 6;
  172.  
  173.             switch (chunkID) {
  174.             case CHUNK_OBJMESH:
  175.                 Chunk3DEditor(scene, chunkLen);
  176.                 break;
  177.  
  178.             case CHUNK_KEYFRAMER:
  179.                 ChunkKeyframer(scene, chunkLen);
  180.                 break;
  181.  
  182.             case CHUNK_BACKCOL:
  183.                 scene.background = new float[4];
  184.                 ChunkColor(chunkLen, scene.background);
  185.                 break;
  186.  
  187.             case CHUNK_AMB:
  188.                 scene.ambient = new float[4];
  189.                 ChunkColor(chunkLen, scene.ambient);
  190.                 break;
  191.  
  192.             default:
  193.                 Skip(chunkLen);
  194.             }
  195.         }
  196.         Seek(end);
  197.  
  198.         scene.Compute(0);
  199.  
  200.         return scene;
  201.     }
  202.  
  203.     private void Chunk3DEditor(Scene3D scene, int len) throws IOException
  204.     {
  205.         long end = filePos + len;
  206.         while (filePos < end) {
  207.             int chunkID = ReadUnsignedShort();
  208.             int chunkLen = ReadInt() - 6;
  209.  
  210.             switch (chunkID) {
  211.             case CHUNK_OBJBLOCK:
  212.                 ChunkObject(scene, chunkLen);
  213.                 break;
  214.  
  215.             case CHUNK_MATERIAL:
  216.                 Material3D mat = ChunkMaterial(scene, chunkLen);
  217.                 if (mat != null)
  218.                     scene.materials.add(mat);
  219.                 break;
  220.  
  221.             default:
  222.                 Skip(chunkLen);
  223.             }
  224.         }
  225.         Seek(end);
  226.     }
  227.  
  228.     private void ChunkObject(Scene3D scene, int len) throws IOException
  229.     {
  230.         long end = filePos + len;
  231.  
  232.         if (len == 0) return;
  233.         String name = ChunkName(0);
  234.  
  235.         while (filePos < end) {
  236.             int chunkID = ReadUnsignedShort();
  237.             int chunkLen = ReadInt() - 6;
  238.  
  239.             switch (chunkID) {
  240.             case CHUNK_TRIMESH:
  241.                 Object3D obj = ChunkTrimesh(chunkLen, name, scene);
  242.                 if (obj != null)
  243.                     scene.objects.add(obj);
  244.                 break;
  245.  
  246.             case CHUNK_LIGHT:
  247.                 Light3D light = ChunkLight(chunkLen, name);
  248.                 if (light != null)
  249.                     scene.lights.add(light);
  250.                 break;
  251.  
  252.             case CHUNK_CAMERA:
  253.             default:
  254.                 Skip(chunkLen);
  255.             }
  256.         }
  257.         Seek(end);
  258.     }
  259.  
  260.     private Object3D ChunkTrimesh(int len, String name, Scene3D scene) throws IOException
  261.     {
  262.         long end = filePos + len;
  263.  
  264.         Object3D obj = new Object3D();
  265.         obj.name = name;
  266.         obj.faceMats = new ArrayList<FaceMat>();
  267.         obj.indCount = 0;
  268.  
  269.         int i, k, num;
  270.  
  271.         while (filePos < end) {
  272.             int chunkID = ReadUnsignedShort();
  273.             int chunkLen = ReadInt() - 6;
  274.  
  275.             switch (chunkID) {
  276.             case CHUNK_FACELIST:
  277.                 ChunkFaceList(chunkLen, obj, scene);
  278.                 break;
  279.  
  280.             case CHUNK_MAPLIST:
  281.                 num = ReadUnsignedShort();
  282.                 for (i = 0, k = 6; i < num; i++, k += 8) {
  283.                     obj.vertexBuffer[k + 0] = ReadFloat();
  284.                     obj.vertexBuffer[k + 1] = 1 - ReadFloat();
  285.                 }
  286.                 break;
  287.  
  288.             case CHUNK_VERTLIST:
  289.                 num = ReadUnsignedShort();
  290.                 obj.vertCount = num;
  291.                 obj.vertexBuffer = new float[8*num];
  292.                 for (i = 0, k = 0; i < num; i++, k += 8) {
  293.                     ChunkVector(obj.vertexBuffer, k);
  294.                     obj.vertexBuffer[k + 3] = 0;
  295.                     obj.vertexBuffer[k + 4] = 0;
  296.                     obj.vertexBuffer[k + 5] = 0;
  297.                     obj.vertexBuffer[k + 6] = 0;
  298.                     obj.vertexBuffer[k + 7] = 0;
  299.                 }
  300.                 break;
  301.  
  302.             case CHUNK_TRMATRIX:
  303.                 float[] localCoord = new float[16];
  304.                 ChunkVector(localCoord, 4*0);
  305.                 ChunkVector(localCoord, 4*2);
  306.                 ChunkVector(localCoord, 4*1);
  307.                 ChunkVector(localCoord, 4*3);
  308.                 localCoord[3] = localCoord[7] = localCoord[11] = 0;
  309.                 localCoord[15] = 1;
  310.  
  311.                 obj.trMatrix = new float[16];
  312.                 Matrix.invertM(obj.trMatrix, 0, localCoord, 0);
  313.                 break;
  314.  
  315.             default:
  316.                 Skip(chunkLen);
  317.             }
  318.         }
  319.         Seek(end);
  320.  
  321.         return obj;
  322.     }
  323.    
  324.     private static void CrossProduct(float[] res, float[] v1, float[] v2)
  325.     {
  326.         res[0] = v1[1]*v2[2] - v1[2]*v2[1];
  327.         res[1] = v1[2]*v2[0] - v1[0]*v2[2];
  328.         res[2] = v1[0]*v2[1] - v1[1]*v2[0];
  329.     }
  330.  
  331.     private static float DotSquare(float[] v, int offset)
  332.     {
  333.         return v[offset + 0]*v[offset + 0] + v[offset + 1]*v[offset + 1] + v[offset + 2]*v[offset + 2];
  334.     }
  335.  
  336.     private static void VecSubstract(float[] res, float[] v, int offset1, int offset2)
  337.     {
  338.         res[0] = v[offset1 + 0] - v[offset2 + 0];
  339.         res[1] = v[offset1 + 1] - v[offset2 + 1];
  340.         res[2] = v[offset1 + 2] - v[offset2 + 2];
  341.     }
  342.  
  343.     private static void VecAdd(float[] v, int offset, float[] a)
  344.     {
  345.         v[offset + 0] += a[0];
  346.         v[offset + 1] += a[1];
  347.         v[offset + 2] += a[2];
  348.     }
  349.    
  350.     private void VecNormalize(float[] v, int offset)
  351.     {
  352.         double nlen = 1 / Math.sqrt(DotSquare(v, offset));
  353.         v[offset + 0] *= nlen;
  354.         v[offset + 1] *= nlen;
  355.         v[offset + 2] *= nlen;
  356.     }
  357.  
  358.     private void ChunkFaceList(int len, Object3D obj, Scene3D scene) throws IOException
  359.     {
  360.         long end = filePos + len;
  361.  
  362.         int i, j, k, l, num = ReadUnsignedShort(), unused = num, idx;
  363.  
  364.         obj.faceCount = num;
  365.         obj.faceBuffer = new int[3*num];
  366.         obj.faceUsed = new boolean[num];
  367.         float[] v = new float[3];
  368.         float[] v1 = new float[3];
  369.         float[] v2 = new float[3];
  370.  
  371.         for (i = 0, idx = 0; i < num; i++, idx += 3) {
  372.             j = ReadUnsignedShort();
  373.             k = ReadUnsignedShort();
  374.             l = ReadUnsignedShort();
  375.             Skip(2);
  376.  
  377.             obj.faceUsed[i] = false;
  378.             obj.faceBuffer[idx + 0] = j;
  379.             obj.faceBuffer[idx + 2] = k;
  380.             obj.faceBuffer[idx + 1] = l;
  381.  
  382.             j *= 8;
  383.             k *= 8;
  384.             l *= 8;
  385.             VecSubstract(v1, obj.vertexBuffer, l, j);
  386.             VecSubstract(v2, obj.vertexBuffer, k, j);
  387.             CrossProduct(v, v1, v2);
  388.  
  389.             VecAdd(obj.vertexBuffer, j + 3, v);
  390.             VecAdd(obj.vertexBuffer, k + 3, v);
  391.             VecAdd(obj.vertexBuffer, l + 3, v);
  392.         }
  393.  
  394.         for (i = 0, k = 3; i < obj.vertCount; i++, k += 8)
  395.             VecNormalize(obj.vertexBuffer, k);
  396.  
  397.         v = null;
  398.         v1 = null;
  399.         v2 = null;
  400.  
  401.         while (filePos < end) {
  402.             int chunkID = ReadUnsignedShort();
  403.             int chunkLen = ReadInt() - 6;
  404.  
  405.             switch (chunkID) {
  406.             case CHUNK_FACEMAT:
  407.                 FaceMat mat = new FaceMat();
  408.                 String name = ChunkName(0);
  409.                 mat.material = scene.FindMaterial(name);
  410.                 num = ReadUnsignedShort();
  411.                 mat.faces = num;
  412.                 mat.indexBuffer = new short[3*num];
  413.                 mat.bufOffset = obj.indCount;
  414.                 obj.indCount += 3*num;
  415.                 k = 0;
  416.                 for (i = 0; i < num; i++) {
  417.                     j = ReadUnsignedShort();
  418.                     if (!obj.faceUsed[j]) {
  419.                         obj.faceUsed[j] = true;
  420.                         unused--;
  421.                     }
  422.                     j *= 3;
  423.                     mat.indexBuffer[k++] = (short) obj.faceBuffer[j + 0];
  424.                     mat.indexBuffer[k++] = (short) obj.faceBuffer[j + 1];
  425.                     mat.indexBuffer[k++] = (short) obj.faceBuffer[j + 2];
  426.                 }
  427.                 obj.faceMats.add(mat);
  428.                 break;
  429.  
  430.             case CHUNK_SMOOTHG:
  431.             default:
  432.                 Skip(chunkLen);
  433.             }
  434.         }
  435.         Seek(end);
  436.        
  437.         if (unused > 0) {
  438.             FaceMat mat = new FaceMat();
  439.             mat.faces = unused;
  440.             mat.indexBuffer = new short[3*unused];
  441.             mat.bufOffset = obj.indCount;
  442.             obj.indCount += 3*unused;
  443.             k = 0;
  444.             for (i = 0; i < obj.faceCount; i++)
  445.                 if (!obj.faceUsed[i]) {
  446.                     obj.faceUsed[i] = true;
  447.                     j = i * 3;
  448.                     mat.indexBuffer[k++] = (short) obj.faceBuffer[j + 0];
  449.                     mat.indexBuffer[k++] = (short) obj.faceBuffer[j + 1];
  450.                     mat.indexBuffer[k++] = (short) obj.faceBuffer[j + 2];
  451.                 }
  452.             obj.faceMats.add(mat);
  453.         }
  454.  
  455.         obj.faceBuffer = null;
  456.         obj.faceUsed = null;
  457.     }
  458.  
  459.     private Light3D ChunkLight(int len, String name) throws IOException
  460.     {
  461.         long end = filePos + len;
  462.  
  463.         Light3D light = new Light3D();
  464.         light.name = name;
  465.         light.pos = new float[3];
  466.         ChunkVector(light.pos, 0);
  467.  
  468.         while (filePos < end) {
  469.             int chunkID = ReadUnsignedShort();
  470.             int chunkLen = ReadInt() - 6;
  471.  
  472.             switch (chunkID) {
  473.             case CHUNK_RGBC:
  474.                 light.color = new float[4];
  475.                 ChunkRGBC(light.color);
  476.                 break;
  477.  
  478.             case CHUNK_RGB24:
  479.                 light.color = new float[4];
  480.                 ChunkRGB24(light.color);
  481.                 break;
  482.  
  483.             case CHUNK_SPOTL:
  484.                 light.dir = new float[4];
  485.                 ChunkVector(light.dir, 0);
  486.                 light.theta = (float) (ReadFloat() * Math.PI / 180.0f);
  487.                 light.phi = (float) (ReadFloat() * Math.PI / 180.0f);
  488.                 break;
  489.  
  490.             case CHUNK_ONOFF:
  491.             default:
  492.                 Skip(chunkLen);
  493.             }
  494.         }
  495.         Seek(end);
  496.        
  497.         return light;
  498.     }
  499.  
  500.     private Material3D ChunkMaterial(Scene3D scene, int len) throws IOException
  501.     {
  502.         long end = filePos + len;
  503.        
  504.         Material3D mat = new Material3D();
  505.  
  506.         while (filePos < end) {
  507.             int chunkID = ReadUnsignedShort();
  508.             int chunkLen = ReadInt() - 6;
  509.  
  510.             switch (chunkID) {
  511.             case CHUNK_TEXTURE:
  512.                 mat.texture = ChunkMap(chunkLen);
  513.                 break;
  514.  
  515.             case CHUNK_BUMPMAP:
  516.             case CHUNK_REFLMAP:
  517.                 ChunkMap(chunkLen);
  518.                 break;
  519.  
  520.             case CHUNK_AMBIENT:
  521.                 mat.ambient = new float[4];
  522.                 ChunkColor(chunkLen, mat.ambient);
  523.                 break;
  524.  
  525.             case CHUNK_DIFFUSE:
  526.                 mat.diffuse = new float[4];
  527.                 ChunkColor(chunkLen, mat.diffuse);
  528.                 break;
  529.  
  530.             case CHUNK_SPECULAR:
  531.                 mat.specular = new float[4];
  532.                 ChunkColor(chunkLen, mat.specular);
  533.                 break;
  534.  
  535.             case CHUNK_MATNAME:
  536.                 mat.name = ChunkName(chunkLen);
  537.                 break;
  538.  
  539.             case CHUNK_MTLTYPE:
  540.                 mat.type = ReadUnsignedShort();
  541.                 break;
  542.  
  543.             case CHUNK_SHININES:
  544.                 mat.shininess = ChunkPercent(chunkLen) * 1000;
  545.                 break;
  546.  
  547.             case CHUNK_SHINSTRN:
  548.                 mat.shinStren = ChunkPercent(chunkLen);
  549.                 break;
  550.  
  551.             case CHUNK_TRANSP:
  552.                 mat.transparency = ChunkPercent(chunkLen);
  553.                 break;
  554.  
  555.             case CHUNK_SELFILL:
  556.                 mat.selfIllum = ChunkPercent(chunkLen);
  557.                 break;
  558.  
  559.             default:
  560.                 Skip(chunkLen);
  561.             }
  562.         }
  563.         Seek(end);
  564.        
  565.         return mat;
  566.     }
  567.  
  568.     private String ChunkMap(int len) throws IOException
  569.     {
  570.         long end = filePos + len;
  571.  
  572.         String name = null;
  573.  
  574.         while (filePos < end) {
  575.             int chunkID = ReadUnsignedShort();
  576.             int chunkLen = ReadInt() - 6;
  577.  
  578.             switch (chunkID) {
  579.             case CHUNK_MAPFILE:
  580.                 name = ChunkName(chunkLen);
  581.                 break;
  582.  
  583.             case CHUNK_MAPPARAM:
  584.             default:
  585.                 Skip(chunkLen);
  586.             }
  587.         }
  588.         Seek(end);
  589.        
  590.         return name;
  591.     }
  592.  
  593.     private void ChunkKeyframer(Scene3D scene, int len) throws IOException
  594.     {
  595.         int fstart = 0, fend = 100;
  596.  
  597.         long end = filePos + len;
  598.         while (filePos < end) {
  599.             int chunkID = ReadUnsignedShort();
  600.             int chunkLen = ReadInt() - 6;
  601.  
  602.             switch (chunkID) {
  603.             case CHUNK_FRAMES:
  604.                 fstart = ReadInt();
  605.                 fend = ReadInt();
  606.                 break;
  607.  
  608.             case CHUNK_TRACKINFO:
  609.                 Animation anim = ChunkMeshTrack(chunkLen, scene);
  610.                 if (anim != null)
  611.                     scene.animations.add(anim);
  612.                 break;
  613.  
  614.             case CHUNK_SPOTINFO:
  615.             default:
  616.                 Skip(chunkLen);
  617.             }
  618.         }
  619.  
  620.         if (fstart < fend)
  621.             for (int i = 0; i < scene.animations.size(); i++) {
  622.                 Animation anim = scene.animations.get(i);
  623.                 if (anim.position != null)
  624.                     for (int j = 0; j < anim.position.length; j++)
  625.                         anim.position[j].time = (anim.position[j].time - fstart) / (fend - fstart);
  626.                 if (anim.rotation != null)
  627.                     for (int j = 0; j < anim.rotation.length; j++)
  628.                         anim.rotation[j].time = (anim.rotation[j].time - fstart) / (fend - fstart);
  629.                 if (anim.scaling != null)
  630.                     for (int j = 0; j < anim.scaling.length; j++)
  631.                         anim.scaling[j].time = (anim.scaling[j].time - fstart) / (fend - fstart);
  632.             }
  633.  
  634.         Seek(end);
  635.     }
  636.  
  637.     private Animation ChunkMeshTrack(int len, Scene3D scene) throws IOException
  638.     {
  639.         Animation anim = new Animation();
  640.         int num, i, j, k;
  641.        
  642.         anim.result = new float[16];
  643.         Matrix.setIdentityM(anim.result, 0);
  644.  
  645.         anim.world = new float[16];
  646.         Matrix.setIdentityM(anim.world, 0);
  647.  
  648.         long end = filePos + len;
  649.         while (filePos < end) {
  650.             int chunkID = ReadUnsignedShort();
  651.             int chunkLen = ReadInt() - 6;
  652.  
  653.             switch (chunkID) {
  654.             case CHUNK_HIERARCHY:
  655.                 anim.id = ReadUnsignedShort();
  656.                 break;
  657.  
  658.             case CHUNK_OBJNAME:
  659.                 String name = ChunkName(0);
  660.                 anim.light = scene.FindLight(name);
  661.                 anim.object = scene.FindObject(name);
  662.                 Skip(4);
  663.                 anim.idParent = ReadUnsignedShort();
  664.                 anim.parent = scene.FindAnimation(anim.idParent);
  665.                 if (anim.parent != null) {
  666.                     anim.parent.childNext = anim.parent.childFirst;
  667.                     anim.parent.childFirst = anim;
  668.                 }
  669.                 break;
  670.  
  671.             case CHUNK_PIVOT:
  672.                 anim.pivot = new float[3];
  673.                 ChunkVector(anim.pivot, 0);
  674.                 break;
  675.  
  676.             case CHUNK_TRACKPOS:
  677.                 Skip(10);
  678.                 num = ReadInt();
  679.                 anim.position = new AnimKey[num];
  680.                 for (i = 0; i < num; i++) {
  681.                     anim.position[i] = new AnimKey();
  682.                     anim.position[i].time = ReadInt();
  683.                     k = ReadUnsignedShort();
  684.                     for (j = 0; j < 5; j++)
  685.                         if ((k & (1 << j)) != 0)
  686.                             Skip(4);
  687.                     anim.position[i].data = new float[3];
  688.                     ChunkVector(anim.position[i].data, 0);
  689.                 }
  690.                 break;
  691.  
  692.             case CHUNK_TRACKROT:
  693.                 Skip(10);
  694.                 num = ReadInt();
  695.                 anim.rotation = new AnimKey[num];
  696.                 for (i = 0; i < num; i++) {
  697.                     anim.rotation[i] = new AnimKey();
  698.                     anim.rotation[i].time = ReadInt();
  699.                     k = ReadUnsignedShort();
  700.                     for (j = 0; j < 5; j++)
  701.                         if ((k & (1 << j)) != 0)
  702.                             Skip(4);
  703.  
  704.                     anim.rotation[i].data = new float[4];
  705.                     anim.rotation[i].data[3] = ReadFloat();
  706.                     ChunkVector(anim.rotation[i].data, 0);
  707.                 }
  708.                 break;
  709.  
  710.             case CHUNK_TRACKSCL:
  711.                 Skip(10);
  712.                 num = ReadInt();
  713.                 anim.scaling = new AnimKey[num];
  714.                 for (i = 0; i < num; i++) {
  715.                     anim.scaling[i] = new AnimKey();
  716.                     anim.scaling[i].time = ReadInt();
  717.                     k = ReadUnsignedShort();
  718.                     for (j = 0; j < 5; j++)
  719.                         if ((k & (1 << j)) != 0)
  720.                             Skip(4);
  721.                     anim.scaling[i].data = new float[3];
  722.                     ChunkVector(anim.scaling[i].data, 0);
  723.                 }
  724.                 break;
  725.  
  726.             default:
  727.                 Skip(chunkLen);
  728.             }
  729.         }
  730.         Seek(end);
  731.  
  732.         return anim;
  733.     }
  734.  
  735.     private void ChunkColor(int len, float[] color) throws IOException
  736.     {
  737.         long end = filePos + len;
  738.         while (filePos < end) {
  739.             int chunkID = ReadUnsignedShort();
  740.             int chunkLen = ReadInt() - 6;
  741.  
  742.             switch (chunkID) {
  743.             case CHUNK_RGBC:
  744.                 ChunkRGBC(color);
  745.                 break;
  746.  
  747.             case CHUNK_RGB24:
  748.                 ChunkRGB24(color);
  749.                 break;
  750.  
  751.             default:
  752.                 Skip(chunkLen);
  753.             }
  754.         }
  755.         Seek(end);
  756.     }
  757.  
  758.     private float ChunkPercent(int len) throws IOException
  759.     {
  760.         float v = 0;
  761.  
  762.         long end = filePos + len;
  763.         while (filePos < end) {
  764.             int chunkID = ReadUnsignedShort();
  765.             int chunkLen = ReadInt() - 6;
  766.  
  767.             switch (chunkID) {
  768.             case CHUNK_SHORT:
  769.                 v = ReadUnsignedShort() / 100.0f;
  770.                 break;
  771.  
  772.             default:
  773.                 Skip(chunkLen);
  774.             }
  775.         }
  776.         Seek(end);
  777.  
  778.         return v;
  779.     }
  780.  
  781.     private String ChunkName(int len) throws IOException
  782.     {
  783.         long end = filePos + len;
  784.         int slen = 0;
  785.         byte[] buffer = new byte[128];
  786.         byte c;
  787.  
  788.         do {
  789.             c = ReadByte();
  790.             if (c != 0)
  791.                 buffer[slen++] = c;
  792.         } while (c != 0);
  793.  
  794.         if (len != 0)
  795.             Seek(end);
  796.         String name = new String(buffer, 0, slen);
  797.  
  798.         return name;
  799.     }
  800.  
  801.     private void ChunkVector(float[] vec, int offset) throws IOException
  802.     {
  803.         vec[offset + 0] = ReadFloat();
  804.         vec[offset + 2] = ReadFloat();
  805.         vec[offset + 1] = ReadFloat();
  806.     }
  807.  
  808.     private void ChunkRGBC(float[] c) throws IOException
  809.     {
  810.         c[0] = ReadFloat();
  811.         c[1] = ReadFloat();
  812.         c[2] = ReadFloat();
  813.         c[3] = 1;
  814.     }
  815.  
  816.     private void ChunkRGB24(float[] c) throws IOException
  817.     {
  818.         c[0] = ReadUnsignedByte() / 255.0f;
  819.         c[1] = ReadUnsignedByte() / 255.0f;
  820.         c[2] = ReadUnsignedByte() / 255.0f;
  821.         c[3] = 1;
  822.     }
  823. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement