Search in sources :

Example 1 with MalformedGeometryException

use of com.almuradev.content.model.obj.geometry.MalformedGeometryException in project Almura by AlmuraDev.

the class OBJModelParser method parse.

public IModel parse() throws Exception {
    final OBJModel.Builder objBuilder = OBJModel.builder();
    try (final InputStream stream = this.resource.getInputStream()) {
        final List<String> lines = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8)).lines().collect(Collectors.toList());
        Group.Builder groupBuilder = null;
        String currentGroupName = null;
        for (int i = 0; i < lines.size(); i++) {
            final String line = lines.get(i);
            // Skip comments and newlines
            if (line.startsWith(OBJModelConfig.COMMENT) || line.isEmpty()) {
                continue;
            }
            final int index = line.indexOf(' ');
            final String[] combinedLineContents = line.split(" ");
            final String lineHeader = line.substring(0, index);
            final String[] lineContents = line.substring(index, line.length()).trim().split(" ");
            switch(lineHeader) {
                case OBJModelConfig.MATERIAL_LIBRARY:
                    @Nullable final ResourceLocation parent = getParent(this.source);
                    objBuilder.materialLibrary(this.parseMaterialLibrary(ResourceLocations.buildResourceLocationPath(lineContents[0], parent.getResourcePath())));
                    break;
                case OBJModelConfig.VERTEX:
                    try {
                        final float x = Float.parseFloat(lineContents[0]);
                        final float y = Float.parseFloat(lineContents[1]);
                        final float z = Float.parseFloat(lineContents[2]);
                        float w = 1f;
                        if (lineContents.length == 4) {
                            w = Float.parseFloat(lineContents[3]);
                        }
                        objBuilder.vertex(new Vertex(x, y, z, w));
                    } catch (final Exception e) {
                        throw new MalformedGeometryException("Illegal vertex encountered! Vertices must have at least three float values. " + "Source -> Line: " + (i + 1) + ", Content: " + Arrays.toString(combinedLineContents), e);
                    }
                    break;
                case OBJModelConfig.VERTEX_NORMAL:
                    try {
                        final float x = Float.parseFloat(lineContents[0]);
                        final float y = Float.parseFloat(lineContents[1]);
                        final float z = Float.parseFloat(lineContents[2]);
                        objBuilder.normal(new VertexNormal(x, y, z));
                    } catch (final Exception e) {
                        throw new MalformedGeometryException("Illegal vertex normal encountered! Vertex normals must have at least three float " + "values. Source -> Line: " + (i + 1) + ", Content: " + Arrays.toString(combinedLineContents), e);
                    }
                    break;
                case OBJModelConfig.VERTEX_TEXTURE_COORDINATE:
                    try {
                        final float u = Math.max(0f, Math.min(1f, Float.parseFloat(lineContents[0])));
                        final float v = Math.max(0f, Math.min(1f, Float.parseFloat(lineContents[1])));
                        float w = 1f;
                        if (lineContents.length == 3) {
                            w = Float.parseFloat(lineContents[2]);
                        }
                        objBuilder.textureCoordinate(new VertexTextureCoordinate(u, v, w));
                    } catch (final Exception e) {
                        throw new MalformedGeometryException("Illegal vertex texture coordinate encountered! Vertex texture coordinates must " + "have at least two float values. Source -> Line: " + (i + 1) + ", Content: " + Arrays.toString(combinedLineContents), e);
                    }
                    break;
                case OBJModelConfig.GROUP:
                    if (groupBuilder != null) {
                        objBuilder.group(groupBuilder.build(currentGroupName));
                    }
                    groupBuilder = Group.builder();
                    currentGroupName = lineContents[0];
                    break;
                case OBJModelConfig.USE_MATERIAL:
                    if (groupBuilder == null) {
                        groupBuilder = Group.builder();
                        currentGroupName = "default";
                    }
                    final MaterialLibrary materialLibrary = objBuilder.materialLibrary();
                    if (materialLibrary == null) {
                        throw new MalformedGeometryException("Encountered material definition but no material library has been specified! Source " + "-> Line: " + (i + 1) + ", Content: " + Arrays.toString(combinedLineContents));
                    }
                    MaterialDefinition materialDefinition = null;
                    for (final MaterialDefinition material : materialLibrary.getMaterialDefinitions()) {
                        if (material.getName().equals(lineContents[0])) {
                            materialDefinition = material;
                        }
                    }
                    if (materialDefinition == null) {
                        throw new MalformedGeometryException("Encountered material definition that does not exist in material library! Source " + "-> Line: " + (i + 1) + ", Content: " + Arrays.toString(combinedLineContents));
                    }
                    groupBuilder.materialDefinition(materialDefinition);
                    break;
                case OBJModelConfig.FACE:
                    if (groupBuilder == null) {
                        groupBuilder = Group.builder();
                        currentGroupName = "default";
                    }
                    final Face.Builder faceBuilder = Face.builder();
                    for (final String lineSegment : lineContents) {
                        final String[] indices = lineSegment.split("/");
                        final VertexDefinition.Builder vertexDefBuilder = VertexDefinition.builder();
                        try {
                            final int vertexIndex = Integer.parseInt(indices[0]);
                            Vertex vertex = null;
                            for (final Map.Entry<Vertex, Integer> entry : objBuilder.vertices().entrySet()) {
                                if (entry.getValue() == vertexIndex) {
                                    vertex = entry.getKey();
                                    break;
                                }
                            }
                            if (vertex == null) {
                                throw new MalformedGeometryException("Illegal face encountered! Faces must " + "have at least a vertex index which is an integer, and exist in the vertices above. Source -> Line: " + (i + 1) + ", Content: " + Arrays.toString(combinedLineContents));
                            }
                            vertexDefBuilder.vertex(vertex);
                            int textureCoordinateIndex = -1;
                            int normalIndex = -1;
                            // 1/
                            if (indices.length > 1) {
                                // 1//1
                                if (indices.length == 3 && indices[1].isEmpty()) {
                                    normalIndex = Integer.parseInt(indices[2]);
                                } else {
                                    // 1/1/1
                                    textureCoordinateIndex = Integer.parseInt(indices[1]);
                                    if (indices.length > 2) {
                                        normalIndex = Integer.parseInt(indices[2]);
                                    }
                                }
                            }
                            if (textureCoordinateIndex != -1) {
                                VertexTextureCoordinate textureCoordinate = null;
                                for (final Map.Entry<VertexTextureCoordinate, Integer> entry : objBuilder.textureCoordinates().entrySet()) {
                                    if (entry.getValue() == textureCoordinateIndex) {
                                        textureCoordinate = entry.getKey();
                                        break;
                                    }
                                }
                                if (textureCoordinate == null) {
                                    throw new MalformedGeometryException("Illegal face encountered! The face has a texture coordinate index " + "which is out of bounds. Source -> Line: " + (i + 1) + ", Content: " + Arrays.toString(combinedLineContents));
                                }
                                vertexDefBuilder.textureCoordinate(textureCoordinate);
                            }
                            if (normalIndex != -1) {
                                VertexNormal normal = null;
                                for (final Map.Entry<VertexNormal, Integer> entry : objBuilder.normals().entrySet()) {
                                    if (entry.getValue() == normalIndex) {
                                        normal = entry.getKey();
                                        break;
                                    }
                                }
                                if (normal == null) {
                                    throw new MalformedGeometryException("Illegal face encountered! The face has a normal index which is out of" + " bounds. Source -> Line: " + (i + 1) + ", Content: " + Arrays.toString(combinedLineContents));
                                }
                                vertexDefBuilder.normal(normal);
                            }
                        } catch (final Exception e) {
                            if (e instanceof MalformedGeometryException) {
                                throw e;
                            }
                            throw new MalformedGeometryException("Illegal face encountered! All indices in a face must be integers. Source -> " + "Line: " + (i + 1) + ", Content: " + Arrays.toString(combinedLineContents), e);
                        }
                        faceBuilder.vertex(vertexDefBuilder.build());
                    }
                    groupBuilder.face(faceBuilder.build());
                    break;
                default:
            }
        }
        if (groupBuilder != null) {
            objBuilder.group(groupBuilder.build(currentGroupName));
        }
    }
    return objBuilder.build(this.source, getFileName(this.source).split("\\.")[0]);
}
Also used : Group(com.almuradev.content.model.obj.geometry.Group) Vertex(com.almuradev.content.model.obj.geometry.Vertex) VertexNormal(com.almuradev.content.model.obj.geometry.VertexNormal) VertexTextureCoordinate(com.almuradev.content.model.obj.geometry.VertexTextureCoordinate) ResourceLocation(net.minecraft.util.ResourceLocation) Face(com.almuradev.content.model.obj.geometry.Face) InputStreamReader(java.io.InputStreamReader) InputStream(java.io.InputStream) MalformedGeometryException(com.almuradev.content.model.obj.geometry.MalformedGeometryException) MalformedGeometryException(com.almuradev.content.model.obj.geometry.MalformedGeometryException) MalformedMaterialLibraryException(com.almuradev.content.model.obj.material.MalformedMaterialLibraryException) VertexDefinition(com.almuradev.content.model.obj.geometry.VertexDefinition) MaterialDefinition(com.almuradev.content.model.obj.material.MaterialDefinition) MaterialLibrary(com.almuradev.content.model.obj.material.MaterialLibrary) BufferedReader(java.io.BufferedReader) Map(java.util.Map) Nullable(javax.annotation.Nullable)

Aggregations

Face (com.almuradev.content.model.obj.geometry.Face)1 Group (com.almuradev.content.model.obj.geometry.Group)1 MalformedGeometryException (com.almuradev.content.model.obj.geometry.MalformedGeometryException)1 Vertex (com.almuradev.content.model.obj.geometry.Vertex)1 VertexDefinition (com.almuradev.content.model.obj.geometry.VertexDefinition)1 VertexNormal (com.almuradev.content.model.obj.geometry.VertexNormal)1 VertexTextureCoordinate (com.almuradev.content.model.obj.geometry.VertexTextureCoordinate)1 MalformedMaterialLibraryException (com.almuradev.content.model.obj.material.MalformedMaterialLibraryException)1 MaterialDefinition (com.almuradev.content.model.obj.material.MaterialDefinition)1 MaterialLibrary (com.almuradev.content.model.obj.material.MaterialLibrary)1 BufferedReader (java.io.BufferedReader)1 InputStream (java.io.InputStream)1 InputStreamReader (java.io.InputStreamReader)1 Map (java.util.Map)1 Nullable (javax.annotation.Nullable)1 ResourceLocation (net.minecraft.util.ResourceLocation)1