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