mirror of
https://github.com/LucasDower/ObjToSchematic.git
synced 2024-12-15 02:59:55 +08:00
Added JPEG support
This commit is contained in:
parent
a03e3632d5
commit
62cde694dc
@ -29,6 +29,7 @@ A tool to convert .obj files into Minecraft Schematics.
|
||||
* ✔️ **Quality of life**
|
||||
* ✔️ Model PSR, ✔️ voxel size preview ✔️ limit warnings
|
||||
* ✔️ **.mtl support for block choice**
|
||||
* ✔️ PNG support, ✔️ JPEG support
|
||||
* ✔️ **Convert to TypeScript**
|
||||
* ⌛ Block choice exported
|
||||
|
||||
|
28
src/mesh.ts
28
src/mesh.ts
@ -7,7 +7,12 @@ const expandVertexData: any = require("expand-vertex-data");
|
||||
import { Triangle } from "./triangle";
|
||||
import { Vector3 } from "./vector";
|
||||
import { RGB } from "./util";
|
||||
import { Texture } from "./texture";
|
||||
|
||||
export enum TextureFormat {
|
||||
PNG,
|
||||
JPEG
|
||||
}
|
||||
|
||||
interface objData {
|
||||
vertexNormals: Array<number>;
|
||||
@ -31,7 +36,8 @@ export interface FillMaterial {
|
||||
export interface TextureMaterial {
|
||||
readonly type: MaterialType.Texture
|
||||
texturePath: string,
|
||||
texture?: WebGLTexture
|
||||
texture?: WebGLTexture,
|
||||
format: TextureFormat
|
||||
}
|
||||
|
||||
export enum MaterialType {
|
||||
@ -112,12 +118,13 @@ export class Mesh {
|
||||
this._loadTextures(materials);
|
||||
}
|
||||
|
||||
private _addMaterial(materialsJSON: Materials, materialName: string, materialDiffuseColour: RGB, materialDiffuseTexturePath: string) {
|
||||
private _addMaterial(materialsJSON: Materials, materialName: string, materialDiffuseColour: RGB, materialDiffuseTexturePath: string, materialFormat: TextureFormat) {
|
||||
console.log(materialName, materialDiffuseColour, materialDiffuseTexturePath);
|
||||
if (materialDiffuseTexturePath !== "") {
|
||||
materialsJSON[materialName] = {
|
||||
texturePath: materialDiffuseTexturePath,
|
||||
type: MaterialType.Texture
|
||||
type: MaterialType.Texture,
|
||||
format: materialFormat
|
||||
};
|
||||
} else if (materialName !== "") {
|
||||
materialsJSON[materialName] = {
|
||||
@ -127,6 +134,7 @@ export class Mesh {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Rewrite
|
||||
private _parseMaterial(materialString: string): Materials {
|
||||
var materialsJSON: Materials = {};
|
||||
|
||||
@ -135,6 +143,7 @@ export class Mesh {
|
||||
let materialName: string = "";
|
||||
let materialDiffuseColour: RGB = {r: 1.0, g: 1.0, b: 1.0};
|
||||
let materialDiffuseTexturePath: string = "";
|
||||
let materialTextureFormat: TextureFormat = TextureFormat.PNG;
|
||||
|
||||
for (let i = 0; i < lines.length; ++i) {
|
||||
const line = lines[i];
|
||||
@ -142,7 +151,7 @@ export class Mesh {
|
||||
|
||||
switch (lineTokens[0]) {
|
||||
case "newmtl":
|
||||
this._addMaterial(materialsJSON, materialName, materialDiffuseColour, materialDiffuseTexturePath);
|
||||
this._addMaterial(materialsJSON, materialName, materialDiffuseColour, materialDiffuseTexturePath, materialTextureFormat);
|
||||
materialName = lineTokens[1];
|
||||
materialDiffuseColour = {r: 0, g: 0, b: 0};
|
||||
materialDiffuseTexturePath = ""
|
||||
@ -174,8 +183,13 @@ export class Mesh {
|
||||
throw Error(`Cannot load texture ${texturePath}`);
|
||||
}
|
||||
const _path = path.parse(texturePath);
|
||||
if (_path.ext.toLowerCase() != ".png") {
|
||||
throw Error(`Can only load .png textures`);
|
||||
if (".png" === _path.ext.toLowerCase()) {
|
||||
materialTextureFormat = TextureFormat.PNG;
|
||||
}
|
||||
else if ([".jpeg", ".jpg"].includes(_path.ext.toLowerCase())) {
|
||||
materialTextureFormat = TextureFormat.JPEG;
|
||||
} else {
|
||||
throw Error(`Can only load PNG and JPEG textures`);
|
||||
}
|
||||
|
||||
materialDiffuseTexturePath = texturePath;
|
||||
@ -183,7 +197,7 @@ export class Mesh {
|
||||
}
|
||||
}
|
||||
|
||||
this._addMaterial(materialsJSON, materialName, materialDiffuseColour, materialDiffuseTexturePath);
|
||||
this._addMaterial(materialsJSON, materialName, materialDiffuseColour, materialDiffuseTexturePath, materialTextureFormat);
|
||||
|
||||
return materialsJSON;
|
||||
}
|
||||
|
@ -1,24 +1,31 @@
|
||||
//const fs = require("fs");
|
||||
//const png = require("pngjs").PNG;
|
||||
|
||||
import * as fs from "fs";
|
||||
import { PNG, PNGWithMetadata } from "pngjs";
|
||||
import * as jpeg from "jpeg-js";
|
||||
import { PNG } from "pngjs";
|
||||
import { UV, RGBA } from "./util";
|
||||
import { clamp } from "./math";
|
||||
import { TextureFormat } from "./mesh";
|
||||
|
||||
|
||||
export class Texture {
|
||||
|
||||
private _image: PNGWithMetadata;
|
||||
private _image: {
|
||||
data: Buffer,
|
||||
width: number,
|
||||
height: number
|
||||
};
|
||||
|
||||
constructor(filename: string) {
|
||||
constructor(filename: string, format: TextureFormat) {
|
||||
try {
|
||||
const data = fs.readFileSync(filename);
|
||||
this._image = PNG.sync.read(data);
|
||||
if (format === TextureFormat.PNG) {
|
||||
this._image = PNG.sync.read(data);
|
||||
} else {
|
||||
this._image = jpeg.decode(data);
|
||||
}
|
||||
if (this._image.width * this._image.height * 4 !== this._image.data.length) {
|
||||
throw Error();
|
||||
}
|
||||
} catch (err) {
|
||||
throw Error(`Could not read ${filename}`);
|
||||
}
|
||||
if (this._image.bpp !== 4) {
|
||||
throw Error("Image must be RBGA format");
|
||||
throw Error(`Could not parse ${filename}`);
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,15 +35,14 @@ export class Texture {
|
||||
const x = Math.floor(uv.u * this._image.width);
|
||||
const y = Math.floor(uv.v * this._image.height);
|
||||
|
||||
const index = this._image.bpp * (this._image.width * y + x);
|
||||
const rgba = this._image.data.slice(index, index + this._image.bpp)
|
||||
const index = 4 * (this._image.width * y + x);
|
||||
const rgba = this._image.data.slice(index, index + 4)
|
||||
|
||||
return {
|
||||
r: rgba[0]/255,
|
||||
g: rgba[1]/255,
|
||||
b: rgba[2]/255,
|
||||
a: rgba[3]/255
|
||||
a: 1.0
|
||||
};
|
||||
}
|
||||
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
import { AABB, CubeAABB } from "./aabb";
|
||||
import { CubeAABB } from "./aabb";
|
||||
import { Vector3 } from "./vector.js";
|
||||
import { HashSet, HashMap } from "./hash_map";
|
||||
import { HashSet } from "./hash_map";
|
||||
import { Texture } from "./texture";
|
||||
import { BlockAtlas } from "./block_atlas";
|
||||
import { UV, RGB } from "./util";
|
||||
@ -360,8 +360,8 @@ export class VoxelManager {
|
||||
const materialTriangles = mesh.materialTriangles[materialName];
|
||||
// Setup material
|
||||
if (materialTriangles.material.type === MaterialType.Texture) {
|
||||
this._currentTexture = new Texture(materialTriangles.material.texturePath);
|
||||
this._blockMode = MaterialType.Texture;
|
||||
this._currentTexture = new Texture(materialTriangles.material.texturePath, materialTriangles.material.format);
|
||||
} else {
|
||||
this._currentColour = materialTriangles.material.diffuseColour;
|
||||
this._blockMode = MaterialType.Fill;
|
||||
|
Loading…
Reference in New Issue
Block a user