minor non-final changes
Reminder of TODOs: Animation parsing, parsing animation data into visible data. -> * Render animations in HTML client. * Write animations to glTF2 exporter. Considered ideas: * Multi-format file input box (auto-detect format based off first bytes)
This commit is contained in:
parent
d57d9129de
commit
aa53573a14
134
gltf-exporter.js
134
gltf-exporter.js
|
@ -99,13 +99,22 @@ function imf2gltf(icon = null, filename = "untitled") {
|
|||
}]; // no indices because who needs indexing when you're transcoding?
|
||||
gltfOutput.materials = [{
|
||||
"name": `Material (${filename}#${index})`,
|
||||
"pbrMetallicRoughness": {
|
||||
"baseColorTexture": {"index":0, "texCoord": 0}
|
||||
},
|
||||
"pbrMetallicRoughness": null,
|
||||
"extensions": { // or we get annoying PBR and specular stuff we don't need
|
||||
"KHR_materials_unlit": {}
|
||||
}
|
||||
}];
|
||||
if(icon.textureFormat !== "N") {
|
||||
gltfOutput.materials.pbrMetallicRoughness = {
|
||||
"baseColorTexture": {"index":0, "texCoord": 0}
|
||||
};
|
||||
} else {
|
||||
gltfOutput.materials.pbrMetallicRoughness = {
|
||||
"baseColorFactor": [1.0, 1.0, 1.0, 1.0],
|
||||
"metallicFactor": 0.0,
|
||||
"roughnessFactor": 1.0
|
||||
}
|
||||
}
|
||||
gltfOutput.buffers = [{"uri": `${filename}.bin`, "byteLength": outputFloatArray.byteLength}];
|
||||
gltfOutput.bufferViews = [
|
||||
{
|
||||
|
@ -173,16 +182,14 @@ function imf2gltf(icon = null, filename = "untitled") {
|
|||
];
|
||||
gltfOutput.asset = {"version": "2.0", "generator": `icondumper2/${icondumper2.version}`}
|
||||
gltfOutput.extensionsUsed = ["KHR_materials_unlit"];
|
||||
gltfOutput.textures = [{"source": 0}];
|
||||
gltfOutput.images = [{"name": `Texture (${filename}#${index})`, "uri": `${filename}.png`}]
|
||||
if(icon.textureFormat !== "N") {
|
||||
gltfOutput.textures = [{"source": 0}];
|
||||
gltfOutput.images = [{"name": `Texture (${filename}#${index})`, "uri": `${filename}.png`}]
|
||||
}
|
||||
gltfOutputArray[index] = (gltfOutput);
|
||||
}
|
||||
let texture16 = null; // Uint16Array(16384)
|
||||
switch(icon.textureFormat) {
|
||||
case "N": {
|
||||
texture16 = (new Uint16Array(16384)).fill(0xffff);
|
||||
break;
|
||||
}
|
||||
case "C": {
|
||||
texture16 = icondumper2.helpers.uncompressTexture(icon.texture.data);
|
||||
break;
|
||||
|
@ -192,57 +199,61 @@ function imf2gltf(icon = null, filename = "untitled") {
|
|||
break;
|
||||
}
|
||||
}
|
||||
let texture24 = new Uint8Array(49983);
|
||||
texture24.set([
|
||||
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a,
|
||||
0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52,
|
||||
0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80,
|
||||
0x08, 0x02, 0x00, 0x00, 0x00, // you may know
|
||||
0x4c, 0x5c, 0xf6, 0x9c, // what this is from 0x89.
|
||||
0x00, 0x00, 0xc3, 0x06, 0x49, 0x44, 0x41, 0x54,
|
||||
0x78, 0x01 // if you didn't get it, here's a clue
|
||||
],0);
|
||||
let textureOffset = 43;
|
||||
let texture24Data = new Array();
|
||||
let texture24CheckedData = new Array();
|
||||
for (let x = 0; x < 128; x++) {
|
||||
let line = [(x === 127 ? 1 : 0), 0x81, 0x01, 0x7e, 0xfe, 0x00];
|
||||
texture24Data = texture24Data.concat(line);
|
||||
texture24CheckedData.push(0);
|
||||
let scanline = new Array(128*3);
|
||||
for (let y = 0; y < 128; y++) {
|
||||
color = rgb5a1_rgb8(texture16[(x*128)+y]);
|
||||
scanline[(y*3) ] = ((color >> 0 ) & 255);
|
||||
scanline[(y*3)+1] = ((color >> 8 ) & 255);
|
||||
scanline[(y*3)+2] = ((color >> 16) & 255);
|
||||
if(texture16 !== null) {
|
||||
let texture24 = new Uint8Array(49983);
|
||||
texture24.set([
|
||||
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a,
|
||||
0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52,
|
||||
0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80,
|
||||
0x08, 0x02, 0x00, 0x00, 0x00, // you may know
|
||||
0x4c, 0x5c, 0xf6, 0x9c, // what this is from 0x89.
|
||||
0x00, 0x00, 0xc3, 0x06, 0x49, 0x44, 0x41, 0x54,
|
||||
0x78, 0x01 // if you didn't get it, here's a clue
|
||||
],0);
|
||||
let textureOffset = 43;
|
||||
let texture24Data = new Array();
|
||||
let texture24CheckedData = new Array();
|
||||
for (let x = 0; x < 128; x++) {
|
||||
let line = [(x === 127 ? 1 : 0), 0x81, 0x01, 0x7e, 0xfe, 0x00];
|
||||
texture24Data = texture24Data.concat(line);
|
||||
texture24CheckedData.push(0);
|
||||
let scanline = new Array(128*3);
|
||||
for (let y = 0; y < 128; y++) {
|
||||
color = rgb5a1_rgb8(texture16[(x*128)+y]);
|
||||
scanline[(y*3) ] = ((color >> 0 ) & 255);
|
||||
scanline[(y*3)+1] = ((color >> 8 ) & 255);
|
||||
scanline[(y*3)+2] = ((color >> 16) & 255);
|
||||
}
|
||||
texture24Data = texture24Data.concat(scanline);
|
||||
texture24CheckedData = texture24CheckedData.concat(scanline);
|
||||
}
|
||||
texture24Data = texture24Data.concat(scanline);
|
||||
texture24CheckedData = texture24CheckedData.concat(scanline);
|
||||
texture24.set(texture24Data, textureOffset);
|
||||
textureOffset += texture24Data.length;
|
||||
let a32conv = new DataView(new ArrayBuffer(4));
|
||||
a32conv.setInt32(0, getAdler32(new Uint8Array(texture24CheckedData)))
|
||||
texture24.set([a32conv.getUint8(0), a32conv.getUint8(1), a32conv.getUint8(2), a32conv.getUint8(3)], textureOffset);
|
||||
textureOffset += 4;
|
||||
let crc32 = getCrc32(new Uint8Array([
|
||||
0x49, 0x44, 0x41, 0x54, 0x78, 0x01, ...texture24Data,
|
||||
a32conv.getUint8(0), a32conv.getUint8(1),
|
||||
a32conv.getUint8(2), a32conv.getUint8(3)
|
||||
]));
|
||||
texture24.set([
|
||||
(crc32 >> 24) & 0xff,
|
||||
(crc32 >> 16) & 0xff,
|
||||
(crc32 >> 8) & 0xff,
|
||||
crc32 & 0xff
|
||||
], textureOffset);
|
||||
textureOffset += 4;
|
||||
texture24.set([
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x49, 0x45, 0x4E, 0x44,
|
||||
0xae, 0x42, 0x60, 0x82
|
||||
], textureOffset);
|
||||
return {objects: gltfOutputArray, buffer: outputFloatArray, texture: texture24};
|
||||
} else {
|
||||
return {objects: gltfOutputArray, buffer: outputFloatArray, texture: null};
|
||||
}
|
||||
texture24.set(texture24Data, textureOffset);
|
||||
textureOffset += texture24Data.length;
|
||||
let a32conv = new DataView(new ArrayBuffer(4));
|
||||
a32conv.setInt32(0, getAdler32(new Uint8Array(texture24CheckedData)))
|
||||
texture24.set([a32conv.getUint8(0), a32conv.getUint8(1), a32conv.getUint8(2), a32conv.getUint8(3)], textureOffset);
|
||||
textureOffset += 4;
|
||||
let crc32 = getCrc32(new Uint8Array([
|
||||
0x49, 0x44, 0x41, 0x54, 0x78, 0x01, ...texture24Data,
|
||||
a32conv.getUint8(0), a32conv.getUint8(1),
|
||||
a32conv.getUint8(2), a32conv.getUint8(3)
|
||||
]));
|
||||
texture24.set([
|
||||
(crc32 >> 24) & 0xff,
|
||||
(crc32 >> 16) & 0xff,
|
||||
(crc32 >> 8) & 0xff,
|
||||
crc32 & 0xff
|
||||
], textureOffset);
|
||||
textureOffset += 4;
|
||||
texture24.set([
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x49, 0x45, 0x4E, 0x44,
|
||||
0xae, 0x42, 0x60, 0x82
|
||||
], textureOffset);
|
||||
return {objects: gltfOutputArray, buffer: outputFloatArray, texture: texture24};
|
||||
}
|
||||
|
||||
function loadAndConvertIcon(inputData, attemptedFilename = "-") {
|
||||
|
@ -257,9 +268,10 @@ function loadAndConvertIcon(inputData, attemptedFilename = "-") {
|
|||
}
|
||||
(require("fs")).writeFileSync(`${filename}.bin`, glTF_output.buffer);
|
||||
console.info(`Saved glTF buffer as "${filename}.bin".`);
|
||||
|
||||
(require("fs")).writeFileSync(`${filename}.png`, glTF_output.texture);
|
||||
console.info(`Saved texture as "${filename}.png".\n`);
|
||||
if(glTF_output.texture !== null) {
|
||||
(require("fs")).writeFileSync(`${filename}.png`, glTF_output.texture);
|
||||
console.info(`Saved texture as "${filename}.png".\n`);
|
||||
}
|
||||
}
|
||||
|
||||
// can anything de-dupe this code somehow? (index.js)
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<meta charset="utf-8"></meta>
|
||||
<meta name="viewport" content="initial-scale=1.5"></meta>
|
||||
<meta name="description" content="A HTML client for icondumper2"></meta>
|
||||
<title>icondumper2 - HTML reference client</title>
|
||||
<title>icondumper2 HTML reference client</title>
|
||||
<script src="icon.js"></script>
|
||||
<script src="lzari.js"></script>
|
||||
<!-- If you need pako to be optional, remove/comment the bottom line. This will disable support for CBS reading, however -->
|
||||
|
@ -756,12 +756,15 @@
|
|||
if (typeof pako === "undefined") {
|
||||
document.getElementById("cbsinput").disabled = true;
|
||||
}
|
||||
if (typeof decodeLzari === "undefined") {
|
||||
document.getElementById("maxinput").disabled = true;
|
||||
}
|
||||
//todo: More than one model shape rendering, other 2 icons (technically done? NMW though), Animation parsing, animation tweening
|
||||
</script>
|
||||
<span id="version">icondumper2 <a href="./documentation" id="iconjsVersion">(unknown icon.js version)</a> [C: <span id="clientVersion">Loading...</span>] — © <span id="currentYear">2023</span> yellows111</span>
|
||||
<script>
|
||||
document.getElementById("iconjsVersion").textContent = exports.version;
|
||||
document.getElementById("clientVersion").textContent = "0.8.0+u1";
|
||||
document.getElementById("clientVersion").textContent = "0.8.0+u2";
|
||||
document.getElementById("currentYear").textContent = (new Date()).getFullYear().toString();
|
||||
</script>
|
||||
</body>
|
||||
|
|
18
lzari.js
18
lzari.js
|
@ -55,7 +55,7 @@ function BinarySearchSym(x) {
|
|||
let i = 1;
|
||||
let j = 314;
|
||||
while (i < j) {
|
||||
let k = ~~((i + j) / 2);
|
||||
let k = ((i + j) / 2)|0;
|
||||
if (symbolCumulative[k] > x) {
|
||||
i = k + 1;
|
||||
} else {
|
||||
|
@ -69,7 +69,7 @@ function BinarySearchPos(x) {
|
|||
let i = 1;
|
||||
let j = 4096;
|
||||
while (i < j) {
|
||||
let k = ~~((i + j) / 2);
|
||||
let k = ((i + j) / 2)|0;
|
||||
if (positionCumulative[k] > x) {
|
||||
i = k + 1;
|
||||
} else {
|
||||
|
@ -81,9 +81,9 @@ function BinarySearchPos(x) {
|
|||
|
||||
function DecodeChar() {
|
||||
var range = high - low;
|
||||
var sym = BinarySearchSym(~~(((value - low + 1) * symbolCumulative[0] - 1) / range));
|
||||
high = low + ~~((range * symbolCumulative[sym - 1]) / symbolCumulative[0]);
|
||||
low += ~~((range * symbolCumulative[sym ]) / symbolCumulative[0]);
|
||||
var sym = BinarySearchSym((((value - low + 1) * symbolCumulative[0] - 1) / range)|0);
|
||||
high = low + ((range * symbolCumulative[sym - 1]) / symbolCumulative[0])|0;
|
||||
low += ((range * symbolCumulative[sym ]) / symbolCumulative[0])|0;
|
||||
for ( ; ; ) {
|
||||
if (low >= 65536) {
|
||||
value -= 65536;
|
||||
|
@ -132,9 +132,9 @@ function DecodeChar() {
|
|||
|
||||
function DecodePosition() {
|
||||
var range = high - low;
|
||||
var position = BinarySearchPos(~~(((value - low + 1) * positionCumulative[0] - 1) / range));
|
||||
high = low + (~~((range * positionCumulative[position ]) / positionCumulative[0]));
|
||||
low += (~~((range * positionCumulative[position + 1]) / positionCumulative[0]));
|
||||
var position = BinarySearchPos((((value - low + 1) * positionCumulative[0] - 1) / range)|0);
|
||||
high = low + ((range * positionCumulative[position ]) / positionCumulative[0])|0;
|
||||
low += ((range * positionCumulative[position + 1]) / positionCumulative[0])|0;
|
||||
for ( ; ; ) {
|
||||
if (low >= 65536) {
|
||||
value -= 65536;
|
||||
|
@ -203,7 +203,7 @@ function decodeLzari(input) {
|
|||
symbolFrequency[0] = 0;
|
||||
positionCumulative[4096] = 0;
|
||||
for (let i = 4096; i >= 1; i--) {
|
||||
positionCumulative[i - 1] = (positionCumulative[i] + ~~(10000 / (i + 200)));
|
||||
positionCumulative[i - 1] = (positionCumulative[i] + (10000 / (i + 200))|0);
|
||||
}
|
||||
//end transclusion
|
||||
//normal Decode process
|
||||
|
|
Loading…
Reference in New Issue