de.javagl.obj.Obj Java Examples

The following examples show how to use de.javagl.obj.Obj. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: ObjWriter.java    From paintera with GNU General Public License v2.0 6 votes vote down vote up
@Override
public void writeMesh(
		final TriangleMesh mesh,
		final Path path) throws IOException {

	final float[] texCoords = new float[mesh.getTexCoords().size()];
	final float[] vertices = new float[mesh.getPoints().size()];
	final float[] normals = new float[mesh.getNormals().size()];
	final int[] faces = new int[mesh.getFaces().size()];
	mesh.getTexCoords().toArray(texCoords);
	mesh.getPoints().toArray(vertices);
	mesh.getNormals().toArray(normals);
	mesh.getFaces().toArray(faces);

	final Obj obj = Objs.createFromIndexedTriangleData(
			IntBuffer.wrap(faces),
			FloatBuffer.wrap(vertices),
			FloatBuffer.wrap(texCoords),
			FloatBuffer.wrap(normals));

	try (final OutputStream fos = new FileOutputStream(path.toFile())) {
		de.javagl.obj.ObjWriter.write(obj, fos);
	}
}
 
Example #2
Source File: ObjGltfAssetCreatorV1.java    From JglTF with MIT License 6 votes vote down vote up
/**
 * Create a {@link GltfAssetV1} from the OBJ file with the given URI
 * 
 * @param objUri The OBJ URI
 * @return The {@link GltfAssetV1}
 * @throws IOException If an IO error occurs
 */
public GltfAssetV1 create(URI objUri) throws IOException
{
    logger.log(level, "Creating glTF with " + bufferStrategy + 
        " buffer strategy");
    
    // Obtain the relative path information and file names
    logger.log(level, "Resolving paths from " + objUri);
    URI baseUri = IO.getParent(objUri);
    String objFileName = IO.extractFileName(objUri);
    String baseName = stripFileNameExtension(objFileName);
    String mtlFileName = baseName + ".mtl";
    URI mtlUri = IO.makeAbsolute(baseUri, mtlFileName);
    
    // Read the input data
    Obj obj = readObj(objUri);
    Map<String, Mtl> mtls = Collections.emptyMap();
    if (IO.existsUnchecked(mtlUri))
    {
        mtls = readMtls(mtlUri);
    }
    return convert(obj, mtls, baseName, baseUri);
}
 
Example #3
Source File: ObjGltfAssetCreatorV2.java    From JglTF with MIT License 6 votes vote down vote up
/**
 * Create a {@link GltfAssetV2} from the OBJ file with the given URI
 * 
 * @param objUri The OBJ URI
 * @return The {@link GltfAssetV2}
 * @throws IOException If an IO error occurs
 */
public GltfAssetV2 create(URI objUri) throws IOException
{
    logger.log(level, "Creating glTF with " + bufferStrategy + 
        " buffer strategy");
    
    // Obtain the relative path information and file names
    logger.log(level, "Resolving paths from " + objUri);
    URI baseUri = IO.getParent(objUri);
    String objFileName = IO.extractFileName(objUri);
    String baseName = stripFileNameExtension(objFileName);
    String mtlFileName = baseName + ".mtl";
    URI mtlUri = IO.makeAbsolute(baseUri, mtlFileName);
    
    // Read the input data
    Obj obj = readObj(objUri);
    Map<String, Mtl> mtls = Collections.emptyMap();
    if (IO.existsUnchecked(mtlUri))
    {
        mtls = readMtls(mtlUri);
    }
    return convert(obj, mtls, baseName, baseUri);
}
 
Example #4
Source File: ObjectRenderer.java    From react-native-arcore with MIT License 5 votes vote down vote up
/**
 * Creates and initializes OpenGL resources needed for rendering the model.
 *
 * @param context Context for loading the shader and below-named model and texture assets.
 * @param objAssetName  Name of the OBJ file containing the model geometry.
 * @param diffuseTextureAssetName  Name of the PNG file containing the diffuse texture map.
 */

public void createOnGlThread(Context context, String objAssetName,
                             String diffuseTextureAssetName)  throws IOException {
    Bitmap textureBitmap = BitmapFactory.decodeStream(
        context.getAssets().open(diffuseTextureAssetName));
    InputStream objInputStream = context.getAssets().open(objAssetName);
    Obj obj = ObjReader.read(objInputStream);
    this.createOnGlThread(context,obj,textureBitmap);
}
 
Example #5
Source File: ObjGltfAssetCreatorV1.java    From JglTF with MIT License 5 votes vote down vote up
/**
 * Read the OBJ from the given URI, and return it as a "renderable" OBJ,
 * which contains only triangles, has unique vertex coordinates and
 * normals, and is single-indexed 
 * 
 * @param objUri The OBJ URI
 * @return The OBJ
 * @throws IOException If an IO error occurs
 */
private static Obj readObj(URI objUri) throws IOException
{
    logger.log(level, "Reading OBJ from " + objUri);
    
    try (InputStream objInputStream =  objUri.toURL().openStream())
    {
        Obj obj = ObjReader.read(objInputStream);
        return ObjUtils.convertToRenderable(obj);
    }
}
 
Example #6
Source File: ObjGltfAssetCreatorV2.java    From JglTF with MIT License 5 votes vote down vote up
/**
 * Read the OBJ from the given URI, and return it as a "renderable" OBJ,
 * which contains only triangles, has unique vertex coordinates and
 * normals, and is single-indexed 
 * 
 * @param objUri The OBJ URI
 * @return The OBJ
 * @throws IOException If an IO error occurs
 */
private static Obj readObj(URI objUri) throws IOException
{
    logger.log(level, "Reading OBJ from " + objUri);
    
    try (InputStream objInputStream =  objUri.toURL().openStream())
    {
        Obj obj = ObjReader.read(objInputStream);
        return ObjUtils.convertToRenderable(obj);
    }
}
 
Example #7
Source File: ObjectRenderer.java    From react-native-arcore with MIT License 4 votes vote down vote up
public void createOnGlThreadWithBase64Object(Context context, String objBase64,
                                             String bitmapTextureBase64)  throws IOException {
    Bitmap textureBitmap = BitmapFactory.decodeStream(new ByteArrayInputStream(Base64.decode(bitmapTextureBase64, Base64.DEFAULT)));
    Obj obj = ObjReader.read(new ByteArrayInputStream(Base64.decode(objBase64, Base64.DEFAULT)));
    this.createOnGlThread(context,obj,textureBitmap);
}
 
Example #8
Source File: ObjGltfAssetCreatorV1.java    From JglTF with MIT License 4 votes vote down vote up
/**
 * Create the {@link MeshPrimitive}s for the given OBJ- and MTL data
 * 
 * @param obj The OBJ
 * @param mtls The MTLs
 * @return The {@link MeshPrimitive}s
 */
private List<MeshPrimitive> createMeshPrimitives(
    ReadableObj obj, Map<String, Mtl> mtls)
{
    // When there are no materials, create the MeshPrimitives for the OBJ
    int numMaterialGroups = obj.getNumMaterialGroups();
    if (numMaterialGroups == 0 || mtls.isEmpty())
    {
        return createMeshPrimitives(obj);
    }
    
    // Create the MeshPrimitives for the material groups
    List<MeshPrimitive> meshPrimitives = new ArrayList<MeshPrimitive>();
    for (int i = 0; i < numMaterialGroups; i++)
    {
        ObjGroup materialGroup = obj.getMaterialGroup(i);
        String materialGroupName = materialGroup.getName();
        Obj materialObj = ObjUtils.groupToObj(obj, materialGroup, null);
        Mtl mtl = mtls.get(materialGroupName);
        
        logger.log(level, "Creating MeshPrimitive for material " + 
            materialGroupName);

        // If the material group is too large, it may have to
        // be split into multiple parts
        String name = "materialGroup_" + String.valueOf(i);
        List<MeshPrimitive> subMeshPrimitives = 
            createPartMeshPrimitives(materialObj, name);

        assignMaterial(subMeshPrimitives, obj, mtl);
        meshPrimitives.addAll(subMeshPrimitives);
        
        if (bufferStrategy == BufferStrategy.BUFFER_PER_GROUP)
        {
            int bufferCounter = bufferStructureBuilder.getNumBufferModels();
            String bufferName = "buffer" + bufferCounter;
            String uri = bufferName + ".bin";
            bufferStructureBuilder.createBufferModel(bufferName, uri);
        }
        
    }
    return meshPrimitives;
}
 
Example #9
Source File: ObjGltfAssetCreatorV2.java    From JglTF with MIT License 4 votes vote down vote up
/**
 * Create the {@link MeshPrimitive}s for the given OBJ- and MTL data
 * 
 * @param obj The OBJ
 * @param mtls The MTLs
 * @return The {@link MeshPrimitive}s
 */
private List<MeshPrimitive> createMeshPrimitives(
    ReadableObj obj, Map<String, Mtl> mtls)
{
    // When there are no materials, create the MeshPrimitives for the OBJ
    int numMaterialGroups = obj.getNumMaterialGroups();
    if (numMaterialGroups == 0 || mtls.isEmpty())
    {
        return createMeshPrimitives(obj);
    }
    
    // Create the MeshPrimitives for the material groups
    List<MeshPrimitive> meshPrimitives = new ArrayList<MeshPrimitive>();
    for (int i = 0; i < numMaterialGroups; i++)
    {
        ObjGroup materialGroup = obj.getMaterialGroup(i);
        String materialGroupName = materialGroup.getName();
        Obj materialObj = ObjUtils.groupToObj(obj, materialGroup, null);
        Mtl mtl = mtls.get(materialGroupName);
        
        logger.log(level, "Creating MeshPrimitive for material " + 
            materialGroupName);

        // If the material group is too large, it may have to
        // be split into multiple parts
        String name = "materialGroup_" + String.valueOf(i);
        List<MeshPrimitive> subMeshPrimitives = 
            createPartMeshPrimitives(materialObj, name);

        assignMaterial(subMeshPrimitives, obj, mtl);
        meshPrimitives.addAll(subMeshPrimitives);
        
        if (bufferStrategy == BufferStrategy.BUFFER_PER_GROUP)
        {
            int bufferCounter = bufferStructureBuilder.getNumBufferModels();
            String bufferName = "buffer" + bufferCounter;
            String uri = bufferName + ".bin";
            bufferStructureBuilder.createBufferModel(bufferName, uri);
        }
        
    }
    return meshPrimitives;
}
 
Example #10
Source File: TestObjAlignmentV1.java    From JglTF with MIT License 4 votes vote down vote up
/**
 * Test whether the padding bytes are inserted that are necessary to
 * align the accessors to the size of their component type.
 */
@Test
public void testObjAlignment() 
{
    // Create an OBJ consisting of a single triangle
    IntBuffer indices = IntBuffer.wrap(new int[] { 0,1,2 });
    FloatBuffer vertices = FloatBuffer.wrap(new float[] 
    {
        0.0f, 0.0f, 0.0f,
        1.0f, 0.0f, 0.0f,
        0.0f, 1.0f, 0.0f,
    });
    Obj obj = Objs.createFromIndexedTriangleData(
        indices, vertices, null, null);
    
    // Create the GltfData, using GL_UNSIGNED_SHORT indices, causing
    // an offset of 6 bytes. (This means that 2 padding bytes will
    // have to be inserted for the subsequent vertex positions data)
    ObjGltfAssetCreatorV1 objGltfAssetCreator = new ObjGltfAssetCreatorV1();
    objGltfAssetCreator.setIndicesComponentType(
        GltfConstants.GL_UNSIGNED_SHORT);
    GltfAssetV1 gltfAsset = 
        objGltfAssetCreator.convert(obj, null, "test", null);
    
    // Obtain the glTF and the accessor and buffer view of the vertices
    GlTF gltf = gltfAsset.getGltf();

    Map<String, Accessor> accessors = gltf.getAccessors();
    Accessor accessor = accessors.get("obj_positions"); 
    
    Map<String, BufferView> bufferViews = gltf.getBufferViews();
    BufferView bufferView = bufferViews.get("obj_attributes_bufferView");
    
    // Compute the byte offset of the accessor referring to the
    // buffer view, and the total byte offset referring to the buffer
    int accessorByteOffset = accessor.getByteOffset();
    int totalByteOffset = 
        accessor.getByteOffset() + bufferView.getByteOffset();
    
    // Check whether the data is properly aligned
    final int sizeOfFloat = 4;
    assertEquals("Byte offset must be divisble by 4",
        0, accessorByteOffset % sizeOfFloat);
    assertEquals("Total byte offset must be divisible by 4",
        0, totalByteOffset % sizeOfFloat);
    
}
 
Example #11
Source File: TestObjAlignmentV2.java    From JglTF with MIT License 4 votes vote down vote up
/**
 * Test whether the padding bytes are inserted that are necessary to
 * align the accessors to the size of their component type.
 */
@Test
public void testObjAlignment() 
{
    // Create an OBJ consisting of a single triangle
    IntBuffer indices = IntBuffer.wrap(new int[] { 0,1,2 });
    FloatBuffer vertices = FloatBuffer.wrap(new float[] 
    {
        0.0f, 0.0f, 0.0f,
        1.0f, 0.0f, 0.0f,
        0.0f, 1.0f, 0.0f,
    });
    Obj obj = Objs.createFromIndexedTriangleData(
        indices, vertices, null, null);
    
    // Create the GltfData, using GL_UNSIGNED_SHORT indices, causing
    // an offset of 6 bytes. (This means that 2 padding bytes will
    // have to be inserted for the subsequent vertex positions data)
    ObjGltfAssetCreatorV2 objGltfAssetCreator = new ObjGltfAssetCreatorV2();
    objGltfAssetCreator.setIndicesComponentType(
        GltfConstants.GL_UNSIGNED_SHORT);
    GltfAssetV2 gltfAsset = 
        objGltfAssetCreator.convert(obj, null, "test", null);
    
    // Obtain the glTF and the accessor and buffer view of the vertices
    GlTF gltf = gltfAsset.getGltf();

    List<Accessor> accessors = gltf.getAccessors();
    Accessor accessor = accessors.get(1); 
    
    List<BufferView> bufferViews = gltf.getBufferViews();
    BufferView bufferView = bufferViews.get(0);
    
    // Compute the byte offset of the accessor referring to the
    // buffer view, and the total byte offset referring to the buffer
    int accessorByteOffset = accessor.getByteOffset();
    int totalByteOffset = 
        accessor.getByteOffset() + bufferView.getByteOffset();
    
    // Check whether the data is properly aligned
    final int sizeOfFloat = 4;
    assertEquals("Byte offset must be divisble by 4",
        0, accessorByteOffset % sizeOfFloat);
    assertEquals("Total byte offset must be divisible by 4",
        0, totalByteOffset % sizeOfFloat);
    
}