Java源码示例:de.javagl.obj.Obj

示例1
@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);
	}
}
 
示例2
/**
 * 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);
}
 
示例3
/**
 * 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);
}
 
示例4
/**
 * 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);
}
 
示例5
/**
 * 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);
    }
}
 
示例6
/**
 * 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);
    }
}
 
示例7
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);
}
 
示例8
/**
 * 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;
}
 
示例9
/**
 * 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;
}
 
示例10
/**
 * 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);
    
}
 
示例11
/**
 * 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);
    
}