/* * JAME 6.2.1 * http://jame.sourceforge.net * * Copyright 2001, 2016 Andrea Medeghini * * This file is based on code from idx3dIII * Copyright 1999, 2000 Peter Walser * http://www.idx3d.ch/idx3d/idx3d.html * * This file is part of JAME. * * JAME is an application for creating fractals and other graphics artifacts. * * JAME is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * JAME is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with JAME. If not, see <http://www.gnu.org/licenses/>. * */ package net.sf.jame.core.media.g3d; import java.io.*; import java.net.URL; public class Solid3dsImporter { private boolean endOfStream = false; private int nextJunkOffset = 0; private int currentJunkId = 0; private Assembly assembly; private String partName; private Part part; public Solid3dsImporter() { } public void importFromURL(final URL url, final Assembly assembly) throws IOException { importFromStream(url.openStream(), assembly); } public void importFromFile(final File file, final Assembly assembly) throws IOException { importFromStream(new FileInputStream(file), assembly); } public void importFromStream(final InputStream stream, final Assembly assembly) throws IOException { final BufferedInputStream in = new BufferedInputStream(stream); this.assembly = assembly; readJunkHeader(in); if (currentJunkId != 0x4D4D) { throw new IOException("this is no valid 3ds file!"); } while (!endOfStream) { readNextJunk(in); } } private static String readString(final InputStream in) throws IOException { String result = new String(); byte inByte; while ((inByte = (byte) in.read()) != 0) { result += (char) inByte; } return result; } private static int readInt(final InputStream in) throws IOException { return (in.read() | (in.read() << 8) | (in.read() << 16) | (in.read() << 24)); } private static int readShort(final InputStream in) throws IOException { return (in.read() | (in.read() << 8)); } private static float readFloat(final InputStream in) throws IOException { return Float.intBitsToFloat(Solid3dsImporter.readInt(in)); } private void readJunkHeader(final InputStream in) throws IOException { currentJunkId = Solid3dsImporter.readShort(in); nextJunkOffset = Solid3dsImporter.readInt(in); endOfStream = currentJunkId < 0; } private void readNextJunk(final InputStream in) throws IOException { readJunkHeader(in); if (currentJunkId == 0x3D3D) { return; // Mesh block } if (currentJunkId == 0x4000) // Object block { partName = Solid3dsImporter.readString(in); return; } if (currentJunkId == 0x4100) // Solid object { part = new Part(partName); assembly.addPart(part); return; } if (currentJunkId == 0x4110) // Vertex list { readVertexList(in); return; } if (currentJunkId == 0x4120) // Point list { readPointList(in); return; } if (currentJunkId == 0x4140) // Mapping coordinates { readMappingCoordinates(in); return; } skipJunk(in); } private void skipJunk(final InputStream in) throws IOException, OutOfMemoryError { for (int i = 0; (i < nextJunkOffset - 6) && (!endOfStream); i++) { endOfStream = in.read() < 0; } } private void readVertexList(final InputStream in) throws IOException { float x, y, z; final int vertices = Solid3dsImporter.readShort(in); for (int i = 0; i < vertices; i++) { x = Solid3dsImporter.readFloat(in); y = Solid3dsImporter.readFloat(in); z = Solid3dsImporter.readFloat(in); part.addVertex(new Vertex(+x, -y, +z)); } } private void readPointList(final InputStream in) throws IOException { int v1, v2, v3; final int triangles = Solid3dsImporter.readShort(in); for (int i = 0; i < triangles; i++) { v1 = Solid3dsImporter.readShort(in); v2 = Solid3dsImporter.readShort(in); v3 = Solid3dsImporter.readShort(in); Solid3dsImporter.readShort(in); part.addTriangle(new Triangle(true, part.vertex(v1), part.vertex(v2), part.vertex(v3))); } } private void readMappingCoordinates(final InputStream in) throws IOException { final int vertices = Solid3dsImporter.readShort(in); for (int i = 0; i < vertices; i++) { part.vertex(i).u = Solid3dsImporter.readFloat(in); part.vertex(i).v = Solid3dsImporter.readFloat(in); } } }