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);
}