Advertisement
Guest User

Untitled

a guest
May 31st, 2012
111
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.         int faceCount = num;
  365.         int[] faceBuffer = new int[3*num];
  366.         boolean[] 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.             faceUsed[i] = false;
  378.             faceBuffer[idx + 0] = j;
  379.             faceBuffer[idx + 2] = k;
  380.             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.indexBuffer = new short[3*num];
  412.                 mat.bufOffset = obj.indCount;
  413.                 obj.indCount += 3*num;
  414.                 k = 0;
  415.                 for (i = 0; i < num; i++) {
  416.                     j = ReadUnsignedShort();
  417.                     if (!faceUsed[j]) {
  418.                         faceUsed[j] = true;
  419.                         unused--;
  420.                     }
  421.                     j *= 3;
  422.                     mat.indexBuffer[k++] = (short) faceBuffer[j + 0];
  423.                     mat.indexBuffer[k++] = (short) faceBuffer[j + 1];
  424.                     mat.indexBuffer[k++] = (short) faceBuffer[j + 2];
  425.                 }
  426.                 obj.faceMats.add(mat);
  427.                 break;
  428.  
  429.             case CHUNK_SMOOTHG:
  430.             default:
  431.                 Skip(chunkLen);
  432.             }
  433.         }
  434.         Seek(end);
  435.  
  436.         if (unused > 0) {
  437.             FaceMat mat = new FaceMat();
  438.             mat.indexBuffer = new short[3*unused];
  439.             mat.bufOffset = obj.indCount;
  440.             obj.indCount += 3*unused;
  441.             k = 0;
  442.             for (i = 0; i < faceCount; i++)
  443.                 if (!faceUsed[i]) {
  444.                     faceUsed[i] = true;
  445.                     j = i * 3;
  446.                     mat.indexBuffer[k++] = (short) faceBuffer[j + 0];
  447.                     mat.indexBuffer[k++] = (short) faceBuffer[j + 1];
  448.                     mat.indexBuffer[k++] = (short) faceBuffer[j + 2];
  449.                 }
  450.             obj.faceMats.add(mat);
  451.         }
  452.  
  453.         faceBuffer = null;
  454.         faceUsed = null;
  455.     }
  456.  
  457.     private Light3D ChunkLight(int len, String name) throws IOException
  458.     {
  459.         long end = filePos + len;
  460.  
  461.         Light3D light = new Light3D();
  462.         light.name = name;
  463.         light.pos = new float[3];
  464.         ChunkVector(light.pos, 0);
  465.  
  466.         while (filePos < end) {
  467.             int chunkID = ReadUnsignedShort();
  468.             int chunkLen = ReadInt() - 6;
  469.  
  470.             switch (chunkID) {
  471.             case CHUNK_RGBC:
  472.                 light.color = new float[4];
  473.                 ChunkRGBC(light.color);
  474.                 break;
  475.  
  476.             case CHUNK_RGB24:
  477.                 light.color = new float[4];
  478.                 ChunkRGB24(light.color);
  479.                 break;
  480.  
  481.             case CHUNK_SPOTL:
  482.                 light.dir = new float[4];
  483.                 ChunkVector(light.dir, 0);
  484.                 light.theta = (float) (ReadFloat() * Math.PI / 180.0f);
  485.                 light.phi = (float) (ReadFloat() * Math.PI / 180.0f);
  486.                 break;
  487.  
  488.             case CHUNK_ONOFF:
  489.             default:
  490.                 Skip(chunkLen);
  491.             }
  492.         }
  493.         Seek(end);
  494.  
  495.         return light;
  496.     }
  497.  
  498.     private Material3D ChunkMaterial(Scene3D scene, int len) throws IOException
  499.     {
  500.         long end = filePos + len;
  501.  
  502.         Material3D mat = new Material3D();
  503.  
  504.         while (filePos < end) {
  505.             int chunkID = ReadUnsignedShort();
  506.             int chunkLen = ReadInt() - 6;
  507.  
  508.             switch (chunkID) {
  509.             case CHUNK_TEXTURE:
  510.                 mat.texture = ChunkMap(chunkLen);
  511.                 break;
  512.  
  513.             case CHUNK_BUMPMAP:
  514.             case CHUNK_REFLMAP:
  515.                 ChunkMap(chunkLen);
  516.                 break;
  517.  
  518.             case CHUNK_AMBIENT:
  519.                 mat.ambient = new float[4];
  520.                 ChunkColor(chunkLen, mat.ambient);
  521.                 break;
  522.  
  523.             case CHUNK_DIFFUSE:
  524.                 mat.diffuse = new float[4];
  525.                 ChunkColor(chunkLen, mat.diffuse);
  526.                 break;
  527.  
  528.             case CHUNK_SPECULAR:
  529.                 mat.specular = new float[4];
  530.                 ChunkColor(chunkLen, mat.specular);
  531.                 break;
  532.  
  533.             case CHUNK_MATNAME:
  534.                 mat.name = ChunkName(chunkLen);
  535.                 break;
  536.  
  537.             case CHUNK_MTLTYPE:
  538.                 mat.type = ReadUnsignedShort();
  539.                 break;
  540.  
  541.             case CHUNK_SHININES:
  542.                 mat.shininess = 100 - ChunkPercent(chunkLen);
  543.                 break;
  544.  
  545.             case CHUNK_SHINSTRN:
  546.                 mat.shinStren = ChunkPercent(chunkLen);
  547.                 break;
  548.  
  549.             case CHUNK_TRANSP:
  550.                 mat.transparency = ChunkPercent(chunkLen);
  551.                 break;
  552.  
  553.             case CHUNK_SELFILL:
  554.                 mat.selfIllum = ChunkPercent(chunkLen);
  555.                 break;
  556.  
  557.             default:
  558.                 Skip(chunkLen);
  559.             }
  560.         }
  561.         Seek(end);
  562.  
  563.         return mat;
  564.     }
  565.  
  566.     private String ChunkMap(int len) throws IOException
  567.     {
  568.         long end = filePos + len;
  569.  
  570.         String name = null;
  571.  
  572.         while (filePos < end) {
  573.             int chunkID = ReadUnsignedShort();
  574.             int chunkLen = ReadInt() - 6;
  575.  
  576.             switch (chunkID) {
  577.             case CHUNK_MAPFILE:
  578.                 name = ChunkName(chunkLen);
  579.                 break;
  580.  
  581.             case CHUNK_MAPPARAM:
  582.             default:
  583.                 Skip(chunkLen);
  584.             }
  585.         }
  586.         Seek(end);
  587.  
  588.         return name;
  589.     }
  590.  
  591.     private void ChunkKeyframer(Scene3D scene, int len) throws IOException
  592.     {
  593.         int fstart = 0, fend = 100;
  594.  
  595.         long end = filePos + len;
  596.         while (filePos < end) {
  597.             int chunkID = ReadUnsignedShort();
  598.             int chunkLen = ReadInt() - 6;
  599.  
  600.             switch (chunkID) {
  601.             case CHUNK_FRAMES:
  602.                 fstart = ReadInt();
  603.                 fend = ReadInt();
  604.                 break;
  605.  
  606.             case CHUNK_TRACKINFO:
  607.                 Animation anim = ChunkMeshTrack(chunkLen, scene);
  608.                 if (anim != null)
  609.                     scene.animations.add(anim);
  610.                 break;
  611.  
  612.             case CHUNK_SPOTINFO:
  613.             default:
  614.                 Skip(chunkLen);
  615.             }
  616.         }
  617.  
  618.         if (fstart < fend)
  619.             for (int i = 0; i < scene.animations.size(); i++) {
  620.                 Animation anim = scene.animations.get(i);
  621.                 if (anim.position != null)
  622.                     for (int j = 0; j < anim.position.length; j++)
  623.                         anim.position[j].time = (anim.position[j].time - fstart) / (fend - fstart);
  624.                 if (anim.rotation != null)
  625.                     for (int j = 0; j < anim.rotation.length; j++)
  626.                         anim.rotation[j].time = (anim.rotation[j].time - fstart) / (fend - fstart);
  627.                 if (anim.scaling != null)
  628.                     for (int j = 0; j < anim.scaling.length; j++)
  629.                         anim.scaling[j].time = (anim.scaling[j].time - fstart) / (fend - fstart);
  630.             }
  631.  
  632.         Seek(end);
  633.     }
  634.  
  635.     private Animation ChunkMeshTrack(int len, Scene3D scene) throws IOException
  636.     {
  637.         Animation anim = new Animation();
  638.         int num, i, j, k;
  639.  
  640.         anim.result = new float[16];
  641.         Matrix.setIdentityM(anim.result, 0);
  642.  
  643.         anim.world = new float[16];
  644.         Matrix.setIdentityM(anim.world, 0);
  645.  
  646.         long end = filePos + len;
  647.         while (filePos < end) {
  648.             int chunkID = ReadUnsignedShort();
  649.             int chunkLen = ReadInt() - 6;
  650.  
  651.             switch (chunkID) {
  652.             case CHUNK_HIERARCHY:
  653.                 anim.id = ReadUnsignedShort();
  654.                 break;
  655.  
  656.             case CHUNK_OBJNAME:
  657.                 String name = ChunkName(0);
  658.                 anim.light = scene.FindLight(name);
  659.                 anim.object = scene.FindObject(name);
  660.                 Skip(4);
  661.                 anim.parent = scene.FindAnimation(ReadUnsignedShort());
  662.                 break;
  663.  
  664.             case CHUNK_PIVOT:
  665.                 anim.pivot = new float[3];
  666.                 ChunkVector(anim.pivot, 0);
  667.                 break;
  668.  
  669.             case CHUNK_TRACKPOS:
  670.                 Skip(10);
  671.                 num = ReadInt();
  672.                 anim.position = new AnimKey[num];
  673.                 for (i = 0; i < num; i++) {
  674.                     anim.position[i] = new AnimKey();
  675.                     anim.position[i].time = ReadInt();
  676.                     k = ReadUnsignedShort();
  677.                     for (j = 0; j < 5; j++)
  678.                         if ((k & (1 << j)) != 0)
  679.                             Skip(4);
  680.                     anim.position[i].data = new float[3];
  681.                     ChunkVector(anim.position[i].data, 0);
  682.                 }
  683.                 break;
  684.  
  685.             case CHUNK_TRACKROT:
  686.                 Skip(10);
  687.                 num = ReadInt();
  688.                 anim.rotation = new AnimKey[num];
  689.                 for (i = 0; i < num; i++) {
  690.                     anim.rotation[i] = new AnimKey();
  691.                     anim.rotation[i].time = ReadInt();
  692.                     k = ReadUnsignedShort();
  693.                     for (j = 0; j < 5; j++)
  694.                         if ((k & (1 << j)) != 0)
  695.                             Skip(4);
  696.                     anim.rotation[i].data = new float[4];
  697.                     anim.rotation[i].data[3] = ReadFloat();
  698.                     ChunkVector(anim.rotation[i].data, 0);
  699.                 }
  700.                 break;
  701.  
  702.             case CHUNK_TRACKSCL:
  703.                 Skip(10);
  704.                 num = ReadInt();
  705.                 anim.scaling = new AnimKey[num];
  706.                 for (i = 0; i < num; i++) {
  707.                     anim.scaling[i] = new AnimKey();
  708.                     anim.scaling[i].time = ReadInt();
  709.                     k = ReadUnsignedShort();
  710.                     for (j = 0; j < 5; j++)
  711.                         if ((k & (1 << j)) != 0)
  712.                             Skip(4);
  713.                     anim.scaling[i].data = new float[3];
  714.                     ChunkVector(anim.scaling[i].data, 0);
  715.                 }
  716.                 break;
  717.  
  718.             default:
  719.                 Skip(chunkLen);
  720.             }
  721.         }
  722.         Seek(end);
  723.  
  724.         return anim;
  725.     }
  726.  
  727.     private void ChunkColor(int len, float[] color) throws IOException
  728.     {
  729.         long end = filePos + len;
  730.         while (filePos < end) {
  731.             int chunkID = ReadUnsignedShort();
  732.             int chunkLen = ReadInt() - 6;
  733.  
  734.             switch (chunkID) {
  735.             case CHUNK_RGBC:
  736.                 ChunkRGBC(color);
  737.                 break;
  738.  
  739.             case CHUNK_RGB24:
  740.                 ChunkRGB24(color);
  741.                 break;
  742.  
  743.             default:
  744.                 Skip(chunkLen);
  745.             }
  746.         }
  747.         Seek(end);
  748.     }
  749.  
  750.     private float ChunkPercent(int len) throws IOException
  751.     {
  752.         float v = 0;
  753.  
  754.         long end = filePos + len;
  755.         while (filePos < end) {
  756.             int chunkID = ReadUnsignedShort();
  757.             int chunkLen = ReadInt() - 6;
  758.  
  759.             switch (chunkID) {
  760.             case CHUNK_SHORT:
  761.                 v = ReadUnsignedShort() / 100.0f;
  762.                 break;
  763.  
  764.             default:
  765.                 Skip(chunkLen);
  766.             }
  767.         }
  768.         Seek(end);
  769.  
  770.         return v;
  771.     }
  772.  
  773.     private String ChunkName(int len) throws IOException
  774.     {
  775.         long end = filePos + len;
  776.         int slen = 0;
  777.         byte[] buffer = new byte[128];
  778.         byte c;
  779.  
  780.         do {
  781.             c = ReadByte();
  782.             if (c != 0)
  783.                 buffer[slen++] = c;
  784.         } while (c != 0);
  785.  
  786.         if (len != 0)
  787.             Seek(end);
  788.  
  789.         String name = new String(buffer, 0, slen);
  790.  
  791.         return name;
  792.     }
  793.  
  794.     private void ChunkVector(float[] vec, int offset) throws IOException
  795.     {
  796.         vec[offset + 0] = ReadFloat();
  797.         vec[offset + 2] = ReadFloat();
  798.         vec[offset + 1] = ReadFloat();
  799.     }
  800.  
  801.     private void ChunkRGBC(float[] c) throws IOException
  802.     {
  803.         c[0] = ReadFloat();
  804.         c[1] = ReadFloat();
  805.         c[2] = ReadFloat();
  806.         c[3] = 1;
  807.     }
  808.  
  809.     private void ChunkRGB24(float[] c) throws IOException
  810.     {
  811.         c[0] = ReadUnsignedByte() / 255.0f;
  812.         c[1] = ReadUnsignedByte() / 255.0f;
  813.         c[2] = ReadUnsignedByte() / 255.0f;
  814.         c[3] = 1;
  815.     }
  816. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement