Not a member of Pastebin yet?
                        Sign Up,
                        it unlocks many cool features!                    
                - import java.io.BufferedInputStream;
 - import java.io.File;
 - import java.io.FileInputStream;
 - import java.io.FileNotFoundException;
 - import java.io.IOException;
 - import java.util.ArrayList;
 - import android.opengl.Matrix;
 - import android.os.Environment;
 - import android.util.Log;
 - public class Load3DS {
 - private final int CHUNK_MAIN = 0x4D4D;
 - private final int CHUNK_OBJMESH = 0x3D3D;
 - private final int CHUNK_OBJBLOCK = 0x4000;
 - private final int CHUNK_TRIMESH = 0x4100;
 - private final int CHUNK_VERTLIST = 0x4110;
 - private final int CHUNK_FACELIST = 0x4120;
 - private final int CHUNK_FACEMAT = 0x4130;
 - private final int CHUNK_MAPLIST = 0x4140;
 - private final int CHUNK_SMOOTHG = 0x4150;
 - private final int CHUNK_TRMATRIX = 0x4160;
 - private final int CHUNK_LIGHT = 0x4600;
 - private final int CHUNK_SPOTL = 0x4610;
 - private final int CHUNK_ONOFF = 0x4620;
 - private final int CHUNK_CAMERA = 0x4700;
 - private final int CHUNK_RGBC = 0x0010;
 - private final int CHUNK_RGB24 = 0x0011;
 - private final int CHUNK_SHORT = 0x0030;
 - private final int CHUNK_BACKCOL = 0x1200;
 - private final int CHUNK_AMB = 0x2100;
 - private final int CHUNK_MATERIAL = 0xAFFF;
 - private final int CHUNK_MATNAME = 0xA000;
 - private final int CHUNK_AMBIENT = 0xA010;
 - private final int CHUNK_DIFFUSE = 0xA020;
 - private final int CHUNK_SPECULAR = 0xA030;
 - private final int CHUNK_SHININES = 0xA040;
 - private final int CHUNK_SHINSTRN = 0xA041;
 - private final int CHUNK_TRANSP = 0xA050;
 - private final int CHUNK_SELFILL = 0xA084;
 - private final int CHUNK_MTLTYPE = 0xA100;
 - private final int CHUNK_TEXTURE = 0xA200;
 - private final int CHUNK_REFLMAP = 0xA220;
 - private final int CHUNK_BUMPMAP = 0xA230;
 - private final int CHUNK_MAPFILE = 0xA300;
 - private final int CHUNK_MAPPARAM = 0xA351;
 - private final int CHUNK_KEYFRAMER = 0xB000;
 - private final int CHUNK_TRACKINFO = 0xB002;
 - private final int CHUNK_SPOTINFO = 0xB007;
 - private final int CHUNK_FRAMES = 0xB008;
 - private final int CHUNK_OBJNAME = 0xB010;
 - private final int CHUNK_PIVOT = 0xB013;
 - private final int CHUNK_TRACKPOS = 0xB020;
 - private final int CHUNK_TRACKROT = 0xB021;
 - private final int CHUNK_TRACKSCL = 0xB022;
 - private final int CHUNK_HIERARCHY = 0xB030;
 - private BufferedInputStream file;
 - private byte[] bytes = new byte[8];
 - private long filePos;
 - public Scene3D Load(String fileName)
 - {
 - file = null;
 - Scene3D scene = null;
 - File dir = new File(Environment.getExternalStorageDirectory().getAbsolutePath());
 - File fil = new File(dir.getAbsolutePath() + File.separator + fileName);
 - if (!fil.exists()) return scene;
 - try {
 - filePos = 0;
 - file = new BufferedInputStream(new FileInputStream(fil));
 - scene = ProcessFile(fil.length());
 - } catch (FileNotFoundException e) {
 - e.printStackTrace();
 - } catch (IOException e) {
 - e.printStackTrace();
 - }
 - try {
 - if (file != null)
 - file.close();
 - } catch (IOException e) {
 - e.printStackTrace();
 - }
 - return scene;
 - }
 - private void Skip(long count) throws IOException
 - {
 - file.skip(count);
 - filePos += count;
 - }
 - private void Seek(long end) throws IOException
 - {
 - if (filePos < end) {
 - Skip(end - filePos);
 - filePos = end;
 - }
 - }
 - private byte ReadByte() throws IOException
 - {
 - file.read(bytes, 0, 1);
 - filePos++;
 - return bytes[0];
 - }
 - private int ReadUnsignedByte() throws IOException
 - {
 - file.read(bytes, 0, 1);
 - filePos++;
 - return (bytes[0]&0xff);
 - }
 - private int ReadUnsignedShort() throws IOException
 - {
 - file.read(bytes, 0, 2);
 - filePos += 2;
 - return ((bytes[1]&0xff) << 8 | (bytes[0]&0xff));
 - }
 - private int ReadInt() throws IOException
 - {
 - file.read(bytes, 0, 4);
 - filePos += 4;
 - return (bytes[3]) << 24 | (bytes[2]&0xff) << 16 | (bytes[1]&0xff) << 8 | (bytes[0]&0xff);
 - }
 - private float ReadFloat() throws IOException
 - {
 - return Float.intBitsToFloat(ReadInt());
 - }
 - private Scene3D ProcessFile(long fileLen) throws IOException
 - {
 - Scene3D scene = null;
 - while (filePos < fileLen) {
 - int chunkID = ReadUnsignedShort();
 - int chunkLen = ReadInt() - 6;
 - switch (chunkID) {
 - case CHUNK_MAIN:
 - if (scene == null)
 - scene = ChunkMain(chunkLen);
 - else
 - Skip(chunkLen);
 - break;
 - default:
 - Skip(chunkLen);
 - }
 - }
 - return scene;
 - }
 - private Scene3D ChunkMain(int len) throws IOException
 - {
 - Scene3D scene = new Scene3D();
 - scene.materials = new ArrayList<Material3D>();
 - scene.objects = new ArrayList<Object3D>();
 - scene.lights = new ArrayList<Light3D>();
 - scene.animations = new ArrayList<Animation>();
 - long end = filePos + len;
 - while (filePos < end) {
 - int chunkID = ReadUnsignedShort();
 - int chunkLen = ReadInt() - 6;
 - switch (chunkID) {
 - case CHUNK_OBJMESH:
 - Chunk3DEditor(scene, chunkLen);
 - break;
 - case CHUNK_KEYFRAMER:
 - ChunkKeyframer(scene, chunkLen);
 - break;
 - case CHUNK_BACKCOL:
 - scene.background = new float[4];
 - ChunkColor(chunkLen, scene.background);
 - break;
 - case CHUNK_AMB:
 - scene.ambient = new float[4];
 - ChunkColor(chunkLen, scene.ambient);
 - break;
 - default:
 - Skip(chunkLen);
 - }
 - }
 - Seek(end);
 - scene.Compute(0);
 - return scene;
 - }
 - private void Chunk3DEditor(Scene3D scene, int len) throws IOException
 - {
 - long end = filePos + len;
 - while (filePos < end) {
 - int chunkID = ReadUnsignedShort();
 - int chunkLen = ReadInt() - 6;
 - switch (chunkID) {
 - case CHUNK_OBJBLOCK:
 - ChunkObject(scene, chunkLen);
 - break;
 - case CHUNK_MATERIAL:
 - Material3D mat = ChunkMaterial(scene, chunkLen);
 - if (mat != null)
 - scene.materials.add(mat);
 - break;
 - default:
 - Skip(chunkLen);
 - }
 - }
 - Seek(end);
 - }
 - private void ChunkObject(Scene3D scene, int len) throws IOException
 - {
 - long end = filePos + len;
 - if (len == 0) return;
 - String name = ChunkName(0);
 - while (filePos < end) {
 - int chunkID = ReadUnsignedShort();
 - int chunkLen = ReadInt() - 6;
 - switch (chunkID) {
 - case CHUNK_TRIMESH:
 - Object3D obj = ChunkTrimesh(chunkLen, name, scene);
 - if (obj != null)
 - scene.objects.add(obj);
 - break;
 - case CHUNK_LIGHT:
 - Light3D light = ChunkLight(chunkLen, name);
 - if (light != null)
 - scene.lights.add(light);
 - break;
 - case CHUNK_CAMERA:
 - default:
 - Skip(chunkLen);
 - }
 - }
 - Seek(end);
 - }
 - private Object3D ChunkTrimesh(int len, String name, Scene3D scene) throws IOException
 - {
 - long end = filePos + len;
 - Object3D obj = new Object3D();
 - obj.name = name;
 - obj.faceMats = new ArrayList<FaceMat>();
 - obj.indCount = 0;
 - int i, k, num;
 - while (filePos < end) {
 - int chunkID = ReadUnsignedShort();
 - int chunkLen = ReadInt() - 6;
 - switch (chunkID) {
 - case CHUNK_FACELIST:
 - ChunkFaceList(chunkLen, obj, scene);
 - break;
 - case CHUNK_MAPLIST:
 - num = ReadUnsignedShort();
 - for (i = 0, k = 6; i < num; i++, k += 8) {
 - obj.vertexBuffer[k + 0] = ReadFloat();
 - obj.vertexBuffer[k + 1] = 1 - ReadFloat();
 - }
 - break;
 - case CHUNK_VERTLIST:
 - num = ReadUnsignedShort();
 - obj.vertCount = num;
 - obj.vertexBuffer = new float[8*num];
 - for (i = 0, k = 0; i < num; i++, k += 8) {
 - ChunkVector(obj.vertexBuffer, k);
 - obj.vertexBuffer[k + 3] = 0;
 - obj.vertexBuffer[k + 4] = 0;
 - obj.vertexBuffer[k + 5] = 0;
 - obj.vertexBuffer[k + 6] = 0;
 - obj.vertexBuffer[k + 7] = 0;
 - }
 - break;
 - case CHUNK_TRMATRIX:
 - float[] localCoord = new float[16];
 - ChunkVector(localCoord, 4*0);
 - ChunkVector(localCoord, 4*2);
 - ChunkVector(localCoord, 4*1);
 - ChunkVector(localCoord, 4*3);
 - localCoord[3] = localCoord[7] = localCoord[11] = 0;
 - localCoord[15] = 1;
 - obj.trMatrix = new float[16];
 - Matrix.invertM(obj.trMatrix, 0, localCoord, 0);
 - break;
 - default:
 - Skip(chunkLen);
 - }
 - }
 - Seek(end);
 - return obj;
 - }
 - private static void CrossProduct(float[] res, float[] v1, float[] v2)
 - {
 - res[0] = v1[1]*v2[2] - v1[2]*v2[1];
 - res[1] = v1[2]*v2[0] - v1[0]*v2[2];
 - res[2] = v1[0]*v2[1] - v1[1]*v2[0];
 - }
 - private static float DotSquare(float[] v, int offset)
 - {
 - return v[offset + 0]*v[offset + 0] + v[offset + 1]*v[offset + 1] + v[offset + 2]*v[offset + 2];
 - }
 - private static void VecSubstract(float[] res, float[] v, int offset1, int offset2)
 - {
 - res[0] = v[offset1 + 0] - v[offset2 + 0];
 - res[1] = v[offset1 + 1] - v[offset2 + 1];
 - res[2] = v[offset1 + 2] - v[offset2 + 2];
 - }
 - private static void VecAdd(float[] v, int offset, float[] a, int off)
 - {
 - v[offset + 0] += a[off + 0];
 - v[offset + 1] += a[off + 1];
 - v[offset + 2] += a[off + 2];
 - }
 - private void VecNormalize(float[] v, int offset)
 - {
 - double nlen = 1 / Math.sqrt(DotSquare(v, offset));
 - v[offset + 0] *= nlen;
 - v[offset + 1] *= nlen;
 - v[offset + 2] *= nlen;
 - }
 - private void ChunkFaceList(int len, Object3D obj, Scene3D scene) throws IOException
 - {
 - long end = filePos + len;
 - int i, j, k, l, m, t, num = ReadUnsignedShort(), unused = num, idx;
 - int faceCount = num;
 - int[] faceBuffer = new int[3*faceCount];
 - boolean[] faceUsed = new boolean[faceCount];
 - float[] v = new float[3];
 - float[] v1 = new float[3];
 - float[] v2 = new float[3];
 - float[] vgNorm = new float[3*3*faceCount]; // per-vertex normal for each face
 - int[] vertGroup = new int[3*faceCount]; // per-vertex group for each face
 - boolean[] vgUsed = new boolean[3*faceCount]; // per-vertex "group used" bit for each face
 - int[] vgNum = new int[obj.vertCount + 1]; // per-vertex face count, and then offset
 - int[] faceGroup = new int[faceCount]; // per-face smoothing group
 - int[] vgUniqs = new int[obj.vertCount + 1]; // per-vertex unique groups count
 - int[] vertUGroup = new int[3*faceCount]; // per-vertex unique groups list for each face
 - for (i = 0; i <= obj.vertCount; i++)
 - vgNum[i] = vgUniqs[i] = 0;
 - for (i = 0, idx = 0; i < faceCount; i++, idx += 3) {
 - j = ReadUnsignedShort();
 - k = ReadUnsignedShort();
 - l = ReadUnsignedShort();
 - Skip(2);
 - faceUsed[i] = false;
 - faceBuffer[idx + 0] = j;
 - faceBuffer[idx + 2] = k;
 - faceBuffer[idx + 1] = l;
 - // initialize smoothing groups data
 - faceGroup[i] = 0;
 - for (t = 0; t < 9; t++)
 - vgNorm[i * 9 + t] = 0;
 - for (t = 0; t < 3; t++) {
 - vertGroup[idx + t] = 0;
 - vertUGroup[idx + t] = 0;
 - vgUsed[idx + t] = false;
 - }
 - vgNum[j]++;
 - vgNum[k]++;
 - vgNum[l]++;
 - }
 - int a, sum = 0;
 - for (i = 0; i < obj.vertCount; i++) {
 - a = vgNum[i];
 - vgNum[i] = sum;
 - sum += a;
 - }
 - vgNum[obj.vertCount] = sum; // now we can store all the faces and their normals and groups per-vertex
 - for (i = 0, idx = 0; i < faceCount; i++, idx += 3) {
 - j = faceBuffer[idx + 0];
 - k = faceBuffer[idx + 2];
 - l = faceBuffer[idx + 1];
 - VecSubstract(v1, obj.vertexBuffer, l*8, j*8);
 - VecSubstract(v2, obj.vertexBuffer, k*8, j*8);
 - CrossProduct(v, v1, v2);
 - VecAdd(vgNorm, vgNum[j]*3, v, 0);
 - VecAdd(vgNorm, vgNum[k]*3, v, 0);
 - VecAdd(vgNorm, vgNum[l]*3, v, 0);
 - vgNum[j]++;
 - vgNum[k]++;
 - vgNum[l]++;
 - }
 - for (i = obj.vertCount - 1; i > 0; i--) // offsets were shifted, so shift them back
 - vgNum[i] = vgNum[i - 1];
 - vgNum[0] = 0;
 - boolean gotSmoothGroups = false;
 - while (filePos < end) {
 - int chunkID = ReadUnsignedShort();
 - int chunkLen = ReadInt() - 6;
 - switch (chunkID) {
 - case CHUNK_FACEMAT:
 - FaceMat mat = new FaceMat();
 - String name = ChunkName(0);
 - mat.material = scene.FindMaterial(name);
 - num = ReadUnsignedShort();
 - mat.indCount = num;
 - mat.indexBuffer = new short[3*num];
 - mat.bufOffset = obj.indCount;
 - obj.indCount += 3*num;
 - k = 0;
 - for (i = 0; i < num; i++) {
 - j = ReadUnsignedShort();
 - if (!faceUsed[j]) {
 - faceUsed[j] = true;
 - unused--;
 - }
 - for (t = 0; t < 3; t++)
 - mat.indexBuffer[k++] = (short) j;
 - }
 - obj.faceMats.add(mat);
 - break;
 - case CHUNK_SMOOTHG:
 - for (i = 0, idx = 0; i < faceCount; i++, idx += 3) {
 - faceGroup[i] = ReadInt();
 - for (t = 0; t < 3; t++) {
 - j = faceBuffer[idx + t];
 - vertGroup[vgNum[j]] = faceGroup[i];
 - vgNum[j]++;
 - }
 - }
 - for (i = obj.vertCount - 1; i > 0; i--)
 - vgNum[i] = vgNum[i - 1];
 - vgNum[0] = 0;
 - gotSmoothGroups = true;
 - break;
 - default:
 - Skip(chunkLen);
 - }
 - }
 - Seek(end);
 - int newVertCount = 0, g;
 - if (gotSmoothGroups) {
 - for (i = 0; i < obj.vertCount; i++) {
 - for (m = vgNum[i]; m < vgNum[i + 1]; m++) { // for every normal and face of this vertex
 - if (!vgUsed[m]) {
 - // vertGroup[m] is a new group...
 - vertUGroup[vgNum[i] + vgUniqs[i]] = vertGroup[m];
 - vgUniqs[i]++;
 - newVertCount++;
 - }
 - for (t = m; t < vgNum[i + 1]; t++) // mark all equal groups (including this one) as duplicates
 - if (vertGroup[t] == vertGroup[m])
 - vgUsed[t] = true;
 - }
 - }
 - if (newVertCount == obj.vertCount)
 - gotSmoothGroups = false;
 - }
 - if (gotSmoothGroups) {
 - // reindex all vertices, build new normals
 - int newIndex = 0;
 - int[] vertIndex = new int[faceCount*3]; // new vertex indices
 - float[] newVertexBuffer = new float[newVertCount*8];
 - for (i = 0, idx = 0; i < faceCount; i++, idx += 3)
 - for (t = 0; t < 3; t++)
 - vertIndex[idx + t] = 0;
 - idx = 3;
 - for (i = 0; i < obj.vertCount; i++) {
 - for (t = 0; t < vgUniqs[i]; t++) { // for every unique normal and face of this vertex
 - for (m = 0; m < 8; m++)
 - newVertexBuffer[newIndex*8 + m] = obj.vertexBuffer[i*8 + m]; // duplicate all vertex data (including zero normals)
 - g = vertUGroup[vgNum[i] + t]; // unique group mask for this vertex
 - for (m = vgNum[i]; m < vgNum[i + 1]; m++) // for every NON-unique normal and face of this vertex
 - if ((vertGroup[m] & g) != 0 || vertGroup[m] == g) // also works for zero group
 - VecAdd(newVertexBuffer, idx, vgNorm, m*3); // add normal to vertex
 - vertIndex[vgNum[i] + t] = newIndex;
 - newIndex++;
 - idx += 8;
 - }
 - }
 - int fg, vi;
 - for (i = 0, idx = 0; i < faceCount; i++, idx += 3) {
 - fg = faceGroup[i];
 - for (m = 0; m < 3; m++) {
 - vi = faceBuffer[idx + m]; // face vertex
 - for (t = 0; t < vgUniqs[vi]; t++) // for every unique group of this vertex
 - if (fg == vertUGroup[vgNum[vi] + t]) { // found the right one
 - faceBuffer[idx + m] = vertIndex[vgNum[vi] + t];
 - break;
 - }
 - }
 - }
 - Log.i("Load3DS", String.format("Resized object %s from %d to %d vertices", obj.name, obj.vertCount, newVertCount));
 - obj.vertCount = newVertCount;
 - obj.vertexBuffer = newVertexBuffer;
 - }
 - else // nothing changed, no need to recalculate anything
 - for (i = 0, idx = 3; i < obj.vertCount; i++, idx += 8) // just copy all the normals
 - for (m = vgNum[i]; m < vgNum[i + 1]; m++) // for every NON-unique normal and face of this vertex
 - VecAdd(obj.vertexBuffer, idx, vgNorm, m*3); // add normal to vertex
 - for (i = 0, k = 3; i < obj.vertCount; i++, k += 8)
 - VecNormalize(obj.vertexBuffer, k);
 - for (m = 0; m < obj.faceMats.size(); m++) {
 - FaceMat mat = obj.faceMats.get(m);
 - k = 0;
 - for (i = 0; i < mat.indCount; i++)
 - for (t = 0; t < 3; t++) {
 - j = 3 * (int) mat.indexBuffer[k];
 - mat.indexBuffer[k++] = (short) faceBuffer[j + t];
 - }
 - }
 - if (unused > 0) {
 - FaceMat mat = new FaceMat();
 - mat.indexBuffer = new short[3*unused];
 - mat.bufOffset = obj.indCount;
 - obj.indCount += 3*unused;
 - k = 0;
 - for (i = 0; i < faceCount; i++)
 - if (!faceUsed[i]) {
 - faceUsed[i] = true;
 - j = i * 3;
 - for (t = 0; t < 3; t++)
 - mat.indexBuffer[k++] = (short) faceBuffer[j + t];
 - }
 - obj.faceMats.add(mat);
 - }
 - }
 - private Light3D ChunkLight(int len, String name) throws IOException
 - {
 - long end = filePos + len;
 - Light3D light = new Light3D();
 - light.name = name;
 - light.pos = new float[3];
 - ChunkVector(light.pos, 0);
 - while (filePos < end) {
 - int chunkID = ReadUnsignedShort();
 - int chunkLen = ReadInt() - 6;
 - switch (chunkID) {
 - case CHUNK_RGBC:
 - light.color = new float[4];
 - ChunkRGBC(light.color);
 - break;
 - case CHUNK_RGB24:
 - light.color = new float[4];
 - ChunkRGB24(light.color);
 - break;
 - case CHUNK_SPOTL:
 - light.dir = new float[4];
 - ChunkVector(light.dir, 0);
 - light.theta = (float) (ReadFloat() * Math.PI / 180.0f);
 - light.phi = (float) (ReadFloat() * Math.PI / 180.0f);
 - break;
 - case CHUNK_ONOFF:
 - default:
 - Skip(chunkLen);
 - }
 - }
 - Seek(end);
 - return light;
 - }
 - private Material3D ChunkMaterial(Scene3D scene, int len) throws IOException
 - {
 - long end = filePos + len;
 - Material3D mat = new Material3D();
 - while (filePos < end) {
 - int chunkID = ReadUnsignedShort();
 - int chunkLen = ReadInt() - 6;
 - switch (chunkID) {
 - case CHUNK_TEXTURE:
 - mat.texture = ChunkMap(chunkLen);
 - break;
 - case CHUNK_BUMPMAP:
 - case CHUNK_REFLMAP:
 - ChunkMap(chunkLen);
 - break;
 - case CHUNK_AMBIENT:
 - mat.ambient = new float[4];
 - ChunkColor(chunkLen, mat.ambient);
 - break;
 - case CHUNK_DIFFUSE:
 - mat.diffuse = new float[4];
 - ChunkColor(chunkLen, mat.diffuse);
 - break;
 - case CHUNK_SPECULAR:
 - mat.specular = new float[4];
 - ChunkColor(chunkLen, mat.specular);
 - break;
 - case CHUNK_MATNAME:
 - mat.name = ChunkName(chunkLen);
 - break;
 - case CHUNK_MTLTYPE:
 - mat.type = ReadUnsignedShort();
 - break;
 - case CHUNK_SHININES:
 - mat.shininess = 100 - ChunkPercent(chunkLen);
 - break;
 - case CHUNK_SHINSTRN:
 - mat.shinStren = ChunkPercent(chunkLen);
 - break;
 - case CHUNK_TRANSP:
 - mat.transparency = ChunkPercent(chunkLen);
 - break;
 - case CHUNK_SELFILL:
 - mat.selfIllum = ChunkPercent(chunkLen);
 - break;
 - default:
 - Skip(chunkLen);
 - }
 - }
 - Seek(end);
 - return mat;
 - }
 - private String ChunkMap(int len) throws IOException
 - {
 - long end = filePos + len;
 - String name = null;
 - while (filePos < end) {
 - int chunkID = ReadUnsignedShort();
 - int chunkLen = ReadInt() - 6;
 - switch (chunkID) {
 - case CHUNK_MAPFILE:
 - name = ChunkName(chunkLen);
 - break;
 - case CHUNK_MAPPARAM:
 - default:
 - Skip(chunkLen);
 - }
 - }
 - Seek(end);
 - return name;
 - }
 - private void ChunkKeyframer(Scene3D scene, int len) throws IOException
 - {
 - int fstart = 0, fend = 100;
 - long end = filePos + len;
 - while (filePos < end) {
 - int chunkID = ReadUnsignedShort();
 - int chunkLen = ReadInt() - 6;
 - switch (chunkID) {
 - case CHUNK_FRAMES:
 - fstart = ReadInt();
 - fend = ReadInt();
 - break;
 - case CHUNK_TRACKINFO:
 - Animation anim = ChunkMeshTrack(chunkLen, scene);
 - if (anim != null)
 - scene.animations.add(anim);
 - break;
 - case CHUNK_SPOTINFO:
 - default:
 - Skip(chunkLen);
 - }
 - }
 - if (fstart < fend)
 - for (int i = 0; i < scene.animations.size(); i++) {
 - Animation anim = scene.animations.get(i);
 - if (anim.position != null)
 - for (int j = 0; j < anim.position.length; j++)
 - anim.position[j].time = (anim.position[j].time - fstart) / (fend - fstart);
 - if (anim.rotation != null)
 - for (int j = 0; j < anim.rotation.length; j++)
 - anim.rotation[j].time = (anim.rotation[j].time - fstart) / (fend - fstart);
 - if (anim.scaling != null)
 - for (int j = 0; j < anim.scaling.length; j++)
 - anim.scaling[j].time = (anim.scaling[j].time - fstart) / (fend - fstart);
 - }
 - Seek(end);
 - }
 - private Animation ChunkMeshTrack(int len, Scene3D scene) throws IOException
 - {
 - Animation anim = new Animation();
 - int num, i, j, k;
 - anim.result = new float[16];
 - Matrix.setIdentityM(anim.result, 0);
 - anim.world = new float[16];
 - Matrix.setIdentityM(anim.world, 0);
 - long end = filePos + len;
 - while (filePos < end) {
 - int chunkID = ReadUnsignedShort();
 - int chunkLen = ReadInt() - 6;
 - switch (chunkID) {
 - case CHUNK_HIERARCHY:
 - anim.id = ReadUnsignedShort();
 - break;
 - case CHUNK_OBJNAME:
 - String name = ChunkName(0);
 - anim.light = scene.FindLight(name);
 - anim.object = scene.FindObject(name);
 - Skip(4);
 - anim.parent = scene.FindAnimation(ReadUnsignedShort());
 - break;
 - case CHUNK_PIVOT:
 - anim.pivot = new float[3];
 - ChunkVector(anim.pivot, 0);
 - break;
 - case CHUNK_TRACKPOS:
 - Skip(10);
 - num = ReadInt();
 - anim.position = new AnimKey[num];
 - for (i = 0; i < num; i++) {
 - anim.position[i] = new AnimKey();
 - anim.position[i].time = ReadInt();
 - k = ReadUnsignedShort();
 - for (j = 0; j < 5; j++)
 - if ((k & (1 << j)) != 0)
 - Skip(4);
 - anim.position[i].data = new float[3];
 - ChunkVector(anim.position[i].data, 0);
 - }
 - break;
 - case CHUNK_TRACKROT:
 - Skip(10);
 - num = ReadInt();
 - anim.rotation = new AnimKey[num];
 - for (i = 0; i < num; i++) {
 - anim.rotation[i] = new AnimKey();
 - anim.rotation[i].time = ReadInt();
 - k = ReadUnsignedShort();
 - for (j = 0; j < 5; j++)
 - if ((k & (1 << j)) != 0)
 - Skip(4);
 - anim.rotation[i].data = new float[4];
 - anim.rotation[i].data[3] = ReadFloat();
 - ChunkVector(anim.rotation[i].data, 0);
 - }
 - break;
 - case CHUNK_TRACKSCL:
 - Skip(10);
 - num = ReadInt();
 - anim.scaling = new AnimKey[num];
 - for (i = 0; i < num; i++) {
 - anim.scaling[i] = new AnimKey();
 - anim.scaling[i].time = ReadInt();
 - k = ReadUnsignedShort();
 - for (j = 0; j < 5; j++)
 - if ((k & (1 << j)) != 0)
 - Skip(4);
 - anim.scaling[i].data = new float[3];
 - ChunkVector(anim.scaling[i].data, 0);
 - }
 - break;
 - default:
 - Skip(chunkLen);
 - }
 - }
 - Seek(end);
 - return anim;
 - }
 - private void ChunkColor(int len, float[] color) throws IOException
 - {
 - long end = filePos + len;
 - while (filePos < end) {
 - int chunkID = ReadUnsignedShort();
 - int chunkLen = ReadInt() - 6;
 - switch (chunkID) {
 - case CHUNK_RGBC:
 - ChunkRGBC(color);
 - break;
 - case CHUNK_RGB24:
 - ChunkRGB24(color);
 - break;
 - default:
 - Skip(chunkLen);
 - }
 - }
 - Seek(end);
 - }
 - private float ChunkPercent(int len) throws IOException
 - {
 - float v = 0;
 - long end = filePos + len;
 - while (filePos < end) {
 - int chunkID = ReadUnsignedShort();
 - int chunkLen = ReadInt() - 6;
 - switch (chunkID) {
 - case CHUNK_SHORT:
 - v = ReadUnsignedShort() / 100.0f;
 - break;
 - default:
 - Skip(chunkLen);
 - }
 - }
 - Seek(end);
 - return v;
 - }
 - private String ChunkName(int len) throws IOException
 - {
 - long end = filePos + len;
 - int slen = 0;
 - byte[] buffer = new byte[128];
 - byte c;
 - do {
 - c = ReadByte();
 - if (c != 0)
 - buffer[slen++] = c;
 - } while (c != 0);
 - if (len != 0)
 - Seek(end);
 - String name = new String(buffer, 0, slen);
 - return name;
 - }
 - private void ChunkVector(float[] vec, int offset) throws IOException
 - {
 - vec[offset + 0] = ReadFloat();
 - vec[offset + 2] = ReadFloat();
 - vec[offset + 1] = ReadFloat();
 - }
 - private void ChunkRGBC(float[] c) throws IOException
 - {
 - c[0] = ReadFloat();
 - c[1] = ReadFloat();
 - c[2] = ReadFloat();
 - c[3] = 1;
 - }
 - private void ChunkRGB24(float[] c) throws IOException
 - {
 - c[0] = ReadUnsignedByte() / 255.0f;
 - c[1] = ReadUnsignedByte() / 255.0f;
 - c[2] = ReadUnsignedByte() / 255.0f;
 - c[3] = 1;
 - }
 - }
 
Advertisement
 
                    Add Comment                
                
                        Please, Sign In to add comment