private int decodeChunk(int prof) { int offset = 6; int id = getUShort(); int longueur = getInt(); if (longueur < 0) return 0; this.pushChunk(id); /* for(int x=0;x<prof;x++) System.out.print(" "); Log.log(prof + " - ID=" + Integer.toHexString(id) + " LONGUEUR=" + longueur ); */ switch (id) { case FILE_VERSION: { long ver = getUInt(); this.fileVersion = (int) ver; // System.out.println("FILE VERSION="+this.fileVersion); offset += 4; } break; case KEYFRAME_VERSION: { long ver = getUInt(); this.keyFrameVersion = (int) ver; offset += 4; // System.out.println("KEYFRAME VERSION="+this.keyFrameVersion); } break; case MESH_VERSION: { long ver = getUInt(); this.meshVersion = (int) ver; offset += 4; // System.out.println("MESH VERSION="+this.meshVersion); } break; /* case 0x0100: { double scl=(double) getFloat(); offset+=4; System.out.println("MASTER SCALE="+scl); } break; */ case UNIT: // MASTER_SCALE 1.0 <=> 1==1inch this.unit = getFloat(); offset += 4; while (offset < longueur) offset += decodeChunk(prof + 1); break; case BGCOLOR: do { int colorBId = getUShort(); int lBColor = getInt(); offset += 6; switch (colorBId) { case RGBF: case RGBFG: this.backgroundColor = readFloatColor(); offset += 12; break; case RGBB: case RGBBG: this.backgroundColor = readByteColor(); offset += 3; break; } } while (offset < longueur); break; case OBJECT: lastObjectName = getString(); offset += lastObjectName.length() + 1; while (offset < longueur) offset += decodeChunk(prof + 1); // TODO: 3DS LOADING MAY BE IT IS NOT NEEDED if (cObjet instanceof Mesh3D) { // ((Mesh3D)cObjet).buildVertexId(); // ((Mesh3D)cObjet).buildFaceId(); // ((Mesh3D)cObjet).removeDuplicateVertices(); // ((Mesh3D)cObjet).buildFacesNormals(); // ((Mesh3D)cObjet).buildSphereBoxAndCenter(); // Auto octree // ((Mesh3D)cObjet).buildMesh3DOctree(); } // if(cObjet!=null) // cObjet.build(); break; case OBJECT_HIDDEN: ((Mesh3D) cObjet).setVisible(false); break; case OBJECT_DONT_CAST_SHADOW: if (cObjet instanceof Mesh3D) ((Mesh3D) cObjet).setCastShadow(false); break; case OBJECT_DONT_RECV_SHADOW: if (cObjet instanceof Mesh3D) ((Mesh3D) cObjet).setRecvShadow(false); break; case CAMERA_ATMOS_RANGE: float nearAtmosRange = getFloat(); float farAtmosRange = getFloat(); offset += 8; break; case CAMERA: { cObjet = new Camera3D(); cObjet.id = -1; cObjet.nom = lastObjectName; cAxe = new Axis3D(); cObjet.axes = cAxe; tObjets3D[nbObjet] = cObjet; nbObjet++; float x = getFloat(); float y = getFloat(); float z = getFloat(); float tx = getFloat(); float ty = getFloat(); float tz = getFloat(); float rz = getFloat(); float focus = getFloat(); // System.out.println("focal lenght="+focus); double FOV = 180.0 * 2.0 * Math.atan(44.1828 / (focus * 2)) / Math.PI; // System.out.println("FOV CALC="+FOV); cObjet.position.set(x, z, y); // cObjet.axes.add(x,z,y); // Log.log(cObjet.position.toString()); cObjet.axes.origine.set(x, z, y); cObjet.axes.axeZ.set(tx - x, tz - z, ty - y); cObjet.axes.axeX.set(ty - y, 0, -(tx - x)); cObjet.axes.axeY.copy(cObjet.axes.axeZ).cross(cObjet.axes.axeX); cObjet.axes.axeX.normalize(); cObjet.axes.axeY.normalize(); cObjet.axes.axeZ.normalize(); cObjet.rotation.z = rz; cObjet.pivot.set(0, 0, 0); if (this.meshVersion == 0) focus = (float) ((Camera3D) cObjet).width; ((Camera3D) cObjet).focus = focus; // rotation.rz=rz; offset += 32; // tObjets3D[nbObjet]=new Scene3DObject(); // nbObjet++; while (offset < longueur) offset += decodeChunk(prof + 1); } break; case LIGHT: { float x = getFloat(); float y = getFloat(); float z = getFloat(); offset += 12; while (offset < longueur) offset += decodeChunk(prof + 1); } break; case TRIMESH: cObjet = new Mesh3D(); cObjet.nom = lastObjectName; cObjet.id = -1; tObjets3D[nbObjet] = cObjet; nbObjet++; cAxe = new Axis3D(); while (offset < longueur) offset += decodeChunk(prof + 1); cObjet.axes = cAxe; break; case VERTEXL: int nbV = getUShort(); offset += 2; cPoints3D = new Vertex3D[nbV]; mappingU = new float[nbV]; mappingV = new float[nbV]; for (int nV = 0; nV < nbV; nV++) { float x = getFloat(); float y = getFloat(); float z = getFloat(); cPoints3D[nV] = new Vertex3D(x, z, y); offset += 12; } while (offset < longueur) offset += decodeChunk(prof + 1); break; case FACEL: int nbP = getUShort(); offset += 2; cPolygones3D = new Face3D[nbP]; for (int nP = 0; nP < nbP; nP++) { int p1 = getUShort(); int p2 = getUShort(); int p3 = getUShort(); int info = getUShort(); Vertex3D p3D[] = new Vertex3D[3]; p3D[0] = cPoints3D[p3]; p3D[1] = cPoints3D[p2]; p3D[2] = cPoints3D[p1]; cPolygones3D[nP] = new Face3D(p3D[0], p3D[1], p3D[2]); cPolygones3D[nP].u0 = mappingU[p3]; cPolygones3D[nP].v0 = mappingV[p3]; cPolygones3D[nP].u1 = mappingU[p2]; cPolygones3D[nP].v1 = mappingV[p2]; cPolygones3D[nP].u2 = mappingU[p1]; cPolygones3D[nP].v2 = mappingV[p1]; offset += 8; } ((Mesh3D) cObjet).vertices3D = cPoints3D; ((Mesh3D) cObjet).faces3D = cPolygones3D; while (offset < longueur) offset += decodeChunk(prof + 1); break; case SMOOTHL: int nbpoly = cPolygones3D.length; for (int nP = 0; nP < nbpoly; nP++) { int nbSmooth = getInt(); cPolygones3D[nP].smoothGroupMask = nbSmooth; offset += 4; } break; case FACEM: String nom = getString(); offset += nom.length() + 1; cMateriau = getTempMateriauByName(nom); int nbF = getUShort(); offset += 2; for (int nF = 0; nF < nbF; nF++) { int numF = getUShort(); cPolygones3D[numF].material = cMateriau; offset += 2; } while (offset < longueur) offset += decodeChunk(prof + 1); break; case MAPPINGVL: int nbMV = getUShort(); offset += 2; for (int nV = 0; nV < nbMV; nV++) { float u = getFloat(); float v = getFloat(); mappingU[nV] = u; mappingV[nV] = -v; offset += 8; } while (offset < longueur) offset += decodeChunk(prof + 1); break; case OBJAXES: double x = getFloat(); double y = getFloat(); double z = getFloat(); cAxe.axeX.set(x, z, y); x = getFloat(); y = getFloat(); z = getFloat(); cAxe.axeZ.set(x, z, y); x = getFloat(); y = getFloat(); z = getFloat(); cAxe.axeY.set(x, z, y); x = getFloat(); y = getFloat(); z = getFloat(); cAxe.origine.set(x, z, y); offset += 48; while (offset < longueur) offset += decodeChunk(prof + 1); break; case MATERIAL: cMateriau = new Material(); tMateriaux3D[nbMaterial] = cMateriau; nbMaterial++; while (offset < longueur) offset += decodeChunk(prof + 1); break; case MATERIALNAME: cMateriau.nom = getString(); offset += cMateriau.nom.length() + 1; while (offset < longueur) offset += decodeChunk(prof + 1); break; case MATERIALAMBIENTCOLOR: do { int colorAId = getUShort(); int lAColor = getInt(); offset += 6; switch (colorAId) { case RGBF: case RGBFG: cMateriau.ambientColor = readFloatColor(); offset += 12; break; case RGBB: case RGBBG: cMateriau.ambientColor = readByteColor(); offset += 3; break; } } while (offset < longueur); break; case MATERIALDIFFUSECOLOR: do { int colorDId = getUShort(); int lDColor = getInt(); offset += 6; switch (colorDId) { case RGBF: case RGBFG: cMateriau.diffuseColor = readFloatColor(); offset += 12; break; case RGBB: case RGBBG: cMateriau.diffuseColor = readByteColor(); offset += 3; break; } } while (offset < longueur); break; case MATERIALSPECULARCOLOR: do { int colorSId = getUShort(); int lSColor = getInt(); offset += 6; switch (colorSId) { case RGBF: case RGBFG: cMateriau.specularColor = readFloatColor(); offset += 12; break; case RGBB: case RGBBG: cMateriau.specularColor = readByteColor(); offset += 3; break; } } while (offset < longueur); break; case MATERIALSHINEPERCENT: int shineId = getUShort(); int lShine = getInt(); offset += 6; switch (shineId) { case PERCENTF: cMateriau.specularPower = readFloatPercent(); offset += 4; break; case PERCENTI: cMateriau.specularPower = readIntPercent(); offset += 2; break; } break; case MATERIALILLUMPERCENT: int illumId = getUShort(); int lIllum = getInt(); offset += 6; switch (illumId) { case PERCENTF: cMateriau.selfIlluminationLevel = readFloatPercent(); offset += 4; break; case PERCENTI: cMateriau.selfIlluminationLevel = readIntPercent(); offset += 2; break; } // Log.log(cMateriau.nom+" emi="+emi); break; case MATERIALSHINEFPERCENT: int shineFId = getUShort(); int lShineF = getInt(); offset += 6; switch (shineFId) { case PERCENTF: cMateriau.specularLevel = readFloatPercent() * 255 / 100; offset += 4; break; case PERCENTI: cMateriau.specularLevel = (readIntPercent() * 255) / 100; offset += 2; break; } break; case MATERIALTRANSPERCENT: int transId = getUShort(); int lTrans = getInt(); offset += 6; switch (transId) { case PERCENTF: cMateriau.alphaLevel = readFloatPercent() * 255 / 100; offset += 4; break; case PERCENTI: cMateriau.alphaLevel = (readIntPercent() * 255) / 100; offset += 2; break; } break; case MATERIALTRANSFPERCENT: int transFId = getUShort(); int lTransF = getInt(); offset += 6; switch (transFId) { case PERCENTF: cMateriau.alphaFalloff = readFloatPercent() * 255 / 100; offset += 4; break; case PERCENTI: cMateriau.alphaFalloff = (readIntPercent() * 255) / 100; offset += 2; break; } break; case MATERIALTEXTUREDIFF: cMapping = new MappingUV(); cMateriau.mapping = cMapping; while (offset < longueur) offset += decodeChunk(prof + 1); break; case MATERIALTEXTUREBUMP: cMapping = new MappingUV(); while (offset < longueur) offset += decodeChunk(prof + 1); break; case MATERIALTEXTUREENV: cMapping = new MappingUV(); while (offset < longueur) offset += decodeChunk(prof + 1); break; case MATERIALTEXTUREOPAC: cMapping = new MappingUV(); while (offset < longueur) offset += decodeChunk(prof + 1); break; case MATERIALTEXTURESPEC: cMapping = new MappingUV(); while (offset < longueur) offset += decodeChunk(prof + 1); break; case MATERIALTEXTURESHIN: cMapping = new MappingUV(); while (offset < longueur) offset += decodeChunk(prof + 1); break; case MATERIALTEXTUREILLUM: cMapping = new MappingUV(); while (offset < longueur) offset += decodeChunk(prof + 1); break; case MAPPINGFILE: String fileName = getString(); // System.out.println("MAPPINGFILE="+fileName); offset += fileName.length() + 1; String textureCacheKey = this.ressourcePath + fileName; URLTexture nTexture = (URLTexture) textureCache.get(textureCacheKey); if (nTexture == null) { nTexture = new URLTexture(); nTexture.nom = fileName; nTexture.sourceFile = fileName; nTexture.baseURL = this.ressourcePath; textureCache.put(textureCacheKey, nTexture); this.textures[this.nbTexture++] = nTexture; } // There cache will cause trouble if same texture used for different kind of map if (this.getLastParentChunk() == MATERIALTEXTUREDIFF) { nTexture.type = DzzD.TT_RGB; cMateriau.diffuseTexture = nTexture; } if (this.getLastParentChunk() == MATERIALTEXTUREBUMP) { nTexture.type = DzzD.TT_HNORMAL; cMateriau.bumpNormalTexture = nTexture; } if (this.getLastParentChunk() == MATERIALTEXTUREENV) { nTexture.type = DzzD.TT_ENV; cMateriau.envTexture = nTexture; } while (offset < longueur) offset += decodeChunk(prof + 1); break; case MAPPINGOFFSETU: float offseMappingU = getFloat(); offset += 4; cMapping.ofsU = offseMappingU; break; case MAPPINGOFFSETV: float offseMappingV = getFloat(); offset += 4; cMapping.ofsV = offseMappingV; break; /* * KEYFRAME BEGIN */ case KEYFHIER: // System.out.println("KEYFHIER"); lastObjectName = getString(); // Name in mesh section // System.out.println("Mesh section name="+lastObjectName); offset += lastObjectName.length() + 1; int info1 = getUShort(); int info2 = getUShort(); int idObjetParent = getShort(); // System.out.println("------- info1: "+info1); // System.out.println("------- info2: "+info2); // System.out.println("------- idObjetParent parent:("+idObjetParent+")"); offset += 6; if ((this.meshVersion >= 3) && ((info1 & 0x4000) == 0) && (!lastObjectName.equals("$$$DUMMY"))) { // Log.log("------------ Instance From Object" + lastObjectName); cObjet = (Scene3DObject) getTempObjetByName(lastObjectName).getClone(false); cObjet.nom = "Instance" + nbObjet; // lastObjectName; cObjet.id = this.cObjetId; tObjets3D[nbObjet] = cObjet; nbObjet++; } else { if (lastObjectName.equals("$$$DUMMY")) { // System.out.println("New object"); cObjet = new Mesh3D(); cObjet.nom = "$$$DUMMY"; cObjet.id = this.cObjetId; tObjets3D[nbObjet] = cObjet; nbObjet++; } else { this.cObjet = getTempObjetByName(lastObjectName); if (this.cObjet instanceof Camera3D) { if (getLastParentChunk() == KEYFCAMTARGETFRAME) { // System.out.println("TARGET FOR "+lastObjectName); // this.cObjet.setTarget(DzzD.newPoint3D()); } } } } // System.out.println("ID objet==" + cObjetId); this.cObjet.id = this.cObjetId; if (idObjetParent != 65535) { Scene3DObject parent = getTempObjetById(idObjetParent); if (parent != null) this.cObjet.parent = parent; // System.out.println(cObjet.getName()+" is child of "+cObjet.getParent().getName()); } /* if(this.cObjet.parent!=null && !lastObjectName.equals("$$$DUMMY")) System.out.println("-" + lastObjectName+"("+ this.cObjet.id +"):parent:("+idObjetParent+")"+this.cObjet.parent.nom); */ while (offset < longueur) offset += decodeChunk(prof + 1); break; case KEYFNAME: // - Instance objects name. String instanceName = getString(); // Log.log("instanceName="+instanceName); cObjet.nom = instanceName; offset += instanceName.length() + 1; break; case KEYFID: int idObjet = getUShort(); offset += 2; this.cObjetId = idObjet; // System.out.println("ID OBJ="+cObjetId); while (offset < longueur) offset += decodeChunk(prof + 1); break; case KEYFTRANS: // Read Track Header int info = getShort(); offset += 2; for (int niu = 0; niu < 8; niu++) { // Read Unknow TrackHeader info 8 byte byte infoUnknow = (byte) getByte(); offset += 1; } // Read number ok keys int nbKey = (int) getUInt(); offset += 4; Point3D cPosition = new Point3D(); Point3D lastPosition = new Point3D(); if (this.animators[cObjetId] == null) this.animators[cObjetId] = new Scene3DObjectAnimator(); // Read all track for (int xKey = 0; xKey < nbKey; xKey++) { // Read the frame number for this key int nKey = (int) getUInt(); offset += 4; // Read Spline flag int splinef = getShort(); offset += 2; // Read Spline info depending on spline flag if ((splinef & 1) != 0) { // Read tension getFloat(); offset += 4; } if ((splinef & 2) != 0) { // Read continuity getFloat(); offset += 4; } if ((splinef & 4) != 0) { // Read bias getFloat(); offset += 4; } if ((splinef & 8) != 0) { // Read ease to getFloat(); offset += 4; } if ((splinef & 16) != 0) { // Read ease from getFloat(); offset += 4; } // Read this key pos (global coordinate x = getFloat(); y = getFloat(); z = getFloat(); if (xKey == 0) this.key3DTrans[cObjetId] = new Point3D(x, z, y); cPosition.set(x, z, y); Point3D position = new Point3D(); position.copy(cPosition); /* if(cObjetId!=-1) { System.out.println(tObjets3D[cObjetId].getName()); System.out.println("pos="+position.toString()); } */ this.animators[cObjetId].addKeyPosition(nKey * 30, position); lastPosition.copy(cPosition); offset += 12; } break; case KEYFROT: int infor = getShort(); offset += 2; for (int niu = 0; niu < 8; niu++) { byte infoUnknow = (byte) getByte(); offset += 1; } int nbKeyr = (int) getUInt(); offset += 4; Axis3D cAxis = new Axis3D(); cAxis.init(); Point3D cRotation = new Point3D(); Point3D lastRotation = new Point3D(); if (this.animators[cObjetId] == null) this.animators[cObjetId] = new Scene3DObjectAnimator(); for (int xKey = 0; xKey < nbKeyr; xKey++) { int nKey = (int) getUInt(); offset += 4; int infoAcceleration = getShort(); offset += 2; double a = getFloat(); offset += 4; x = getFloat(); y = getFloat(); z = getFloat(); if (a > Math.PI && xKey != 0) a = 2.0 * Math.PI - a; if (xKey == 0) { this.key3DRotAng[cObjetId] = a; this.key3DRotAxe[cObjetId] = new Point3D(x, z, y); } cAxis.rotate(a, -x, -z, -y); cAxis.getRotationXZY(cRotation); Point3D rotation = new Point3D(); rotation.copy(cRotation); this.animators[cObjetId].addKeyRotation(nKey * 30, rotation, new Point3D(-x, -z, -y), a); offset += 12; } break; case KEYFZOOM: int infoz = getShort(); offset += 2; for (int niu = 0; niu < 8; niu++) { byte infoUnknow = (byte) getByte(); offset += 1; } int nbKeyz = (int) getUInt(); offset += 4; for (int xKey = 0; xKey < nbKeyz; xKey++) { int nKey = (int) getUInt(); offset += 4; int infoAcceleration = getShort(); offset += 2; x = getFloat(); y = getFloat(); z = getFloat(); if (xKey == 0) this.key3DZoom[cObjetId] = new Point3D(x, z, y); offset += 12; } break; case KEYFCAMFOVFRAME: int infof = getShort(); offset += 2; for (int niu = 0; niu < 8; niu++) { byte infoUnknow = (byte) getByte(); offset += 1; } int nbKeyf = (int) getUInt(); offset += 4; for (int xKey = 0; xKey < nbKeyf; xKey++) { int nKey = (int) getUInt(); offset += 4; int infoAcceleration = getShort(); offset += 2; float fov = getFloat(); if (this.cObjet instanceof Camera3D) { ((Camera3D) this.cObjet).setFOV(fov); } offset += 4; } break; case KEYFPIVOT: x = getFloat(); y = getFloat(); z = getFloat(); offset += 12; this.cObjet.pivot.set(x, z, y); break; case KEYFBOX: double x1 = getFloat(); double y1 = getFloat(); double z1 = getFloat(); offset += 12; double x2 = getFloat(); double y2 = getFloat(); double z2 = getFloat(); offset += 12; this.cObjet.center.set((x1 + x2) * 0.5, (z1 + z2) * 0.5, (y1 + y2) * 0.5); break; case KEYF3DS: this.isKeyFrame = true; // System.out.println("KEYF3DS"); this.cObjetId = 0; while (offset < longueur) offset += decodeChunk(prof + 1); break; case KEYFHEADERACTIVE: long startf = getUInt(); long endf = getUInt(); // System.out.println("KEYFRAME START FRAME="+ startf); // System.out.println("KEYFRAME END FRAME="+ endf); offset += 8; while (offset < longueur) offset += decodeChunk(prof + 1); break; case KEYFHEADERCURRENT: long currentf = getUInt(); // System.out.println("KEYFRAME CURRENT FRAME="+currentf); offset += 4; while (offset < longueur) offset += decodeChunk(prof + 1); break; case KEYFHEADERGLOBAL: this.keyFrameRevision = getShort(); this.keyFrameFileName = getString(); this.KeyFrameNbFrame = getUInt(); offset += 2; offset += this.keyFrameFileName.length() + 1; offset += 4; while (offset < longueur) offset += decodeChunk(prof + 1); break; case MAIN3DS: this.cObjetId = 0; while (offset < longueur) offset += decodeChunk(prof + 1); break; case EDIT3DS: while (offset < longueur) offset += decodeChunk(prof + 1); break; case KEYFOBJFRAME: this.cObjetId++; while (offset < longueur) offset += decodeChunk(prof + 1); break; case KEYFCAMFRAME: this.cObjetId++; // System.out.println("-----CAMERA-------"); // System.out.println("ID1="+cObjetId); while (offset < longueur) offset += decodeChunk(prof + 1); // System.out.println("-----END CAMERA-------"); break; case KEYFCAMTARGETFRAME: this.cObjetId++; // System.out.println("-----CAMERA TARGET-------"); // System.out.println("ID1="+cObjetId); // MUST DO SPECIAL DECODE OF CHILD TO NOT OVERWRITE CAMERA TRACK POS/ROT // while(offset<longueur) // offset+=decodeChunk(prof+1); // System.out.println("-----END CAMERA TARGET-------"); break; default: break; } this.setProgress(50 + (50 * this.nbBytesDecoded) / this.data.length); skip(id, offset, longueur - offset); this.popChunk(); return longueur; }
private void loadAndDecode() { // LOAD 3DS FILE this.setAction(IProgressListener.ACTION_FILE_DOWNLOAD); ProgressListener pl = new ProgressListener(); IOManagerAsynch aLoader = new IOManagerAsynch(); aLoader.downloadData(this.baseURL + this.fileName, getClass(), null, pl, false); while (aLoader.running || !pl.getFinished()) { this.setProgress((50 * (pl.getProgress()) / pl.getMaximumProgress())); try { Thread.sleep(5); } catch (InterruptedException ie) { pl.setFinished(true); pl.setError(true); return; } } this.data = aLoader.getData(); if (pl.getError() || this.data == null) { this.setError(true); this.setFinished(true); return; } // DECODE 3DS FILE this.input = new ByteArrayInputStream(this.data); this.setProgress(50); this.setAction(IProgressListener.ACTION_FILE_DECOMPRESS); int offset = 0; while (offset < data.length) offset += decodeChunk(0); // CREATE SCENE FROM LOADED SCENE (INIT WITH KEYFRAME IF AVAILABLE) objets3D = new Scene3DObject[nbObjet + 1]; objets3D[0] = new Mesh3D(); objets3D[0].setName(this.fileName); double zx = 1; double zy = 1; double zz = 1; for (int nbo = 0; nbo < nbObjet; nbo++) { cObjet = tObjets3D[nbo]; objets3D[nbo + 1] = cObjet; Axis3D cAxe = cObjet.axes; Point3D o = cAxe.origine; Point3D ax = cAxe.axeX; Point3D ay = cAxe.axeY; Point3D az = cAxe.axeZ; // READ ZOOM FROM AXIS zx = ax.norm(); zy = ay.norm(); zz = az.norm(); ax.add(o); ay.add(o); az.add(o); // if(cObjet instanceof Camera3D) // System.out.println(cObjet.getPosition().toString()); // NORMALIZE AXIS cAxe.normalize(); if (cObjet instanceof Mesh3D) { Point3D vertex[] = ((Mesh3D) cObjet).vertices3D; for (int np = 0; np < vertex.length; np++) vertex[np].toLocalAxe(cAxe).zoom(1.0 / zx, 1.0 / zy, 1.0 / zz); } ax.sub(o); ay.sub(o); az.sub(o); // KEEP AXZ (TO KNOW IF ZOOM NEGATIVE) Point3D axz = new Point3D(); axz.copy(ax).cross(ay); // IF ZOOM NEGATIVE INVERT ALL AXIS AND FLIP OBJECT'S FACES NORMALS if (az.dot(axz) < 0.0) { ax.mul(-1.0); ay.mul(-1.0); az.mul(-1.0); zx = -zx; zy = -zy; zz = -zz; } ax.add(o); ay.add(o); az.add(o); // SET OBJECT ROTATION AND PIVOT FROM AXIS cObjet.axes.getPosition(cObjet.position); cObjet.axes.getRotationXZY(cObjet.rotation); // SET OBJECT ZOOM cObjet.zoom.set(zx, zy, zz); } // SET OBJECT AXIS IN WORLD SPACE WITH PIVOT,POSITION,ROTATION for (int nbo = 1; nbo < objets3D.length; nbo++) { cObjet = objets3D[nbo]; cObjet.axes.init(); cObjet.axes.set(cObjet.pivot, cObjet.position, cObjet.rotation); } // UPDATE OBJECT HIERARCHY for (int nbo = 1; nbo < objets3D.length; nbo++) { cObjet = objets3D[nbo]; if (cObjet.parent == null) cObjet.parent = objets3D[0]; cObjet.setParent(cObjet.parent); } // UPDATE OBJECT FOR HIERARCHY NEW for (int nbo = 1; nbo < objets3D.length; nbo++) { cObjet = objets3D[nbo]; // cObjet.axes.push(); IAxis3D a = DzzD.newAxis3D(); a.copy(cObjet.axes); if (cObjet.parent == null) cObjet.parent = objets3D[0]; cObjet.toLocalAxe(cObjet.parent.axes); // if(cObjet.parent instanceof ICamera3D) // cObjet.axes.pop(); cObjet.axes.copy(a); } try { // UPDATE ALL OBJECT WITH FIRST KEYFRAMER KEY if (this.isKeyFrame) { for (int nbo = 1; nbo < objets3D.length; nbo++) { cObjet = objets3D[nbo]; if (cObjet.id == -1) continue; IAxis3D a = DzzD.newAxis3D(); a.copy(cObjet.axes); // cObjet.axes.push(); Point3D rot = this.key3DRotAxe[cObjet.id]; if (rot != null) { double rota = this.key3DRotAng[cObjet.id]; cObjet.axes.init(); cObjet.axes.rotate(rota, -rot.x, -rot.y, -rot.z); cObjet.axes.getRotationXZY(cObjet.rotation); // cObjet.axes.pop(); cObjet.axes.copy(a); } Point3D trans = this.key3DTrans[cObjet.id]; if (trans != null) { cObjet.position.set(trans.x, trans.y, trans.z); if (cObjet.parent != null) cObjet.position.add(cObjet.parent.pivot); } Point3D zoom = this.key3DZoom[cObjet.id]; if (zoom != null) { cObjet.zoom.set(zoom.x, zoom.y, zoom.z); } cObjet.axes.copy(a); // cObjet.axes.pop(); } } // Add animator to object for (int nbo = 1; nbo < objets3D.length; nbo++) { cObjet = objets3D[nbo]; if (cObjet.id == -1) continue; if (this.animators[cObjet.id] != null) cObjet.setScene3DObjectAnimator(this.animators[cObjet.id]); } } catch (ArrayIndexOutOfBoundsException aioobe) { Log.log(aioobe); } catch (NullPointerException npe) { Log.log(npe); } for (int nbo = 1; nbo < objets3D.length; nbo++) { cObjet = objets3D[nbo]; Point3D zoom = cObjet.zoom; cObjet.zoom(zoom.x, zoom.y, zoom.z); } this.setFinished(true); this.setProgress(100); return; }