Search in sources :

Example 1 with VertexNormal

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

the class OBJBakedModel method getQuads.

@Override
public List<BakedQuad> getQuads(@Nullable final IBlockState state, @Nullable final EnumFacing side, final long rand) {
    if (this.quads == null) {
        this.quads = new LinkedList<>();
        final TRSRTransformation transformation = this.state.apply(Optional.empty()).orElse(null);
        Face particleFace = null;
        TextureAtlasSprite particleAtlasSprite = null;
        for (final Group group : this.model.getGroups()) {
            final MaterialDefinition materialDefinition = group.getMaterialDefinition().orElse(null);
            TextureAtlasSprite diffuseSprite = this.spriteOverride;
            if (diffuseSprite == null) {
                if (materialDefinition != null) {
                    if (materialDefinition.getDiffuseTexture().isPresent()) {
                        final ResourceLocation diffuseLocation = materialDefinition.getDiffuseTexture().orElse(null);
                        if (diffuseLocation != null) {
                            if (diffuseLocation.getResourcePath().endsWith(".png")) {
                                diffuseSprite = this.bakedTextureGetter.apply(new ResourceLocation(diffuseLocation.getResourceDomain(), diffuseLocation.getResourcePath().split("\\.")[0]));
                            } else {
                                diffuseSprite = this.bakedTextureGetter.apply(diffuseLocation);
                            }
                        }
                    }
                }
            }
            if (diffuseSprite == null) {
                diffuseSprite = ModelLoader.White.INSTANCE;
            }
            particleAtlasSprite = diffuseSprite;
            for (final Face face : group.getFaces()) {
                particleFace = face;
                final UnpackedBakedQuad.Builder quadBuilder = new UnpackedBakedQuad.Builder(this.format);
                quadBuilder.setContractUVs(true);
                quadBuilder.setTexture(diffuseSprite);
                VertexNormal normal = null;
                for (final VertexDefinition vertexDef : face.getVertices()) {
                    if (normal == null) {
                        normal = vertexDef.getNormal().orElse(null);
                    }
                    for (int e = 0; e < this.format.getElementCount(); e++) {
                        switch(this.format.getElement(e).getUsage()) {
                            case POSITION:
                                final Vertex vertex = vertexDef.getVertex();
                                if (transformation != null) {
                                    final Matrix4f transform = transformation.getMatrix();
                                    final Vector4f position = new Vector4f(vertex.getX(), vertex.getY(), vertex.getZ(), 1f);
                                    final Vector4f transformed = new Vector4f();
                                    transform.transform(position, transformed);
                                    quadBuilder.put(e, transformed.getX(), transformed.getY(), transformed.getZ());
                                } else {
                                    quadBuilder.put(e, vertex.getX(), vertex.getY(), vertex.getZ());
                                }
                                break;
                            case UV:
                                final float u;
                                final float v;
                                if (this.spriteOverride == null) {
                                    final VertexTextureCoordinate textureCoordinate = vertexDef.getTextureCoordinate().orElse(null);
                                    if (textureCoordinate != null) {
                                        u = textureCoordinate.getU();
                                        v = 1f - textureCoordinate.getV();
                                    } else {
                                        u = 0f;
                                        v = 1f;
                                    }
                                } else {
                                    switch(vertexDef.getIndex()) {
                                        case 1:
                                            u = 0f;
                                            v = 0f;
                                            break;
                                        case 2:
                                            u = 1f;
                                            v = 0f;
                                            break;
                                        case 3:
                                            u = 1f;
                                            v = 1f;
                                            break;
                                        case 4:
                                            u = 0f;
                                            v = 1f;
                                            break;
                                        default:
                                            u = 0f;
                                            v = 0f;
                                    }
                                }
                                quadBuilder.put(e, diffuseSprite.getInterpolatedU(u * 16f), diffuseSprite.getInterpolatedV(v * 16f));
                                break;
                            case NORMAL:
                                if (normal != null) {
                                    quadBuilder.put(e, normal.getX(), normal.getY(), normal.getZ());
                                }
                                break;
                            case COLOR:
                                quadBuilder.put(e, 1f, 1f, 1f, 1f);
                                break;
                            default:
                                quadBuilder.put(e);
                        }
                    }
                }
                if (normal != null) {
                    quadBuilder.setQuadOrientation(EnumFacing.getFacingFromVector(normal.getX(), normal.getY(), normal.getZ()));
                }
                this.quads.add(quadBuilder.build());
            }
        }
        if (particleFace != null && particleAtlasSprite != null) {
            // For now, last face = particle generation
            this.particleDiffuseSprite = this.createParticleSpriteFor(particleFace, particleAtlasSprite);
        }
    }
    return this.quads;
}
Also used : TRSRTransformation(net.minecraftforge.common.model.TRSRTransformation) Group(com.almuradev.content.model.obj.geometry.Group) Vertex(com.almuradev.content.model.obj.geometry.Vertex) UnpackedBakedQuad(net.minecraftforge.client.model.pipeline.UnpackedBakedQuad) IMixinTextureAtlasSprite(com.almuradev.content.mixin.iface.IMixinTextureAtlasSprite) TextureAtlasSprite(net.minecraft.client.renderer.texture.TextureAtlasSprite) VertexNormal(com.almuradev.content.model.obj.geometry.VertexNormal) VertexDefinition(com.almuradev.content.model.obj.geometry.VertexDefinition) VertexTextureCoordinate(com.almuradev.content.model.obj.geometry.VertexTextureCoordinate) Matrix4f(javax.vecmath.Matrix4f) Vector4f(javax.vecmath.Vector4f) MaterialDefinition(com.almuradev.content.model.obj.material.MaterialDefinition) ResourceLocation(net.minecraft.util.ResourceLocation) Face(com.almuradev.content.model.obj.geometry.Face)

Example 2 with VertexNormal

use of com.almuradev.content.model.obj.geometry.VertexNormal 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)2 Group (com.almuradev.content.model.obj.geometry.Group)2 Vertex (com.almuradev.content.model.obj.geometry.Vertex)2 VertexDefinition (com.almuradev.content.model.obj.geometry.VertexDefinition)2 VertexNormal (com.almuradev.content.model.obj.geometry.VertexNormal)2 VertexTextureCoordinate (com.almuradev.content.model.obj.geometry.VertexTextureCoordinate)2 MaterialDefinition (com.almuradev.content.model.obj.material.MaterialDefinition)2 ResourceLocation (net.minecraft.util.ResourceLocation)2 IMixinTextureAtlasSprite (com.almuradev.content.mixin.iface.IMixinTextureAtlasSprite)1 MalformedGeometryException (com.almuradev.content.model.obj.geometry.MalformedGeometryException)1 MalformedMaterialLibraryException (com.almuradev.content.model.obj.material.MalformedMaterialLibraryException)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 Matrix4f (javax.vecmath.Matrix4f)1 Vector4f (javax.vecmath.Vector4f)1 TextureAtlasSprite (net.minecraft.client.renderer.texture.TextureAtlasSprite)1