diff --git a/src/graphics/AnimBase.ts b/src/graphics/AnimBase.ts index c4fa190..c5fc6ac 100644 --- a/src/graphics/AnimBase.ts +++ b/src/graphics/AnimBase.ts @@ -83,6 +83,37 @@ export default class AnimBase { return instance; } + static convertFromData377(id: number, fileData: Packet): AnimBase { + const instance = new AnimBase(); + instance.id = id; + + const length = fileData.g1(); + instance.animLength = length; + + const types = new Uint8Array(length); + const labels = new Array(length); + + for (let i = 0; i < length; i++) { + types[i] = fileData.g1(); + } + + for (let i = 0; i < length; i++) { + const labelCount = fileData.g1(); + const groupLabels = new Uint8Array(labelCount); + + for (let j = 0; j < labelCount; j++) { + groupLabels[j] = fileData.g1(); + } + labels[i] = groupLabels; + } + + instance.animTypes = types; + instance.animLabels = labels; + + AnimBase.instances[id] = instance; + return instance; + } + // ---- id: number = 0; diff --git a/src/graphics/AnimSet.ts b/src/graphics/AnimSet.ts new file mode 100644 index 0000000..8187061 --- /dev/null +++ b/src/graphics/AnimSet.ts @@ -0,0 +1,111 @@ +import AnimBase from "#/graphics/AnimBase.js"; +import AnimFrame from "#/graphics/AnimFrame.js"; +import Packet from '#/io/Packet.js'; + +export default class AnimSet { + static convertFromData(baseId: number, fileData: Uint8Array) { + const footer = new Packet(fileData); + footer.pos = fileData.length - 8; + const metaDataSize = footer.g2(); + const flagSize = footer.g2(); + const valuesSize = footer.g2(); + const delaysSize = footer.g2(); + + const metaData = new Packet(fileData); + metaData.pos = 0; + const frameCount = metaData.g2(); + + const flagData = new Packet(fileData); + flagData.pos = metaData.pos + metaDataSize; + + const valueData = new Packet(fileData); + valueData.pos = flagData.pos + flagSize; + + const delayData = new Packet(fileData); + delayData.pos = valueData.pos + valuesSize; + + const animBaseData = new Packet(fileData); + animBaseData.pos = delayData.pos + delaysSize; + + const animBase = AnimBase.convertFromData377(baseId, animBaseData); + + const tempGroups = new Array(500); + const tempX = new Array(500); + const tempY = new Array(500); + const tempZ = new Array(500); + + for (let i = 0; i < frameCount; i++) { + const frameIndex = metaData.g2(); + + const animFrame = new AnimFrame(); + + animFrame.id = frameIndex; + animFrame.frameDelay = delayData.g1(); + animFrame.base = animBase; + + const transformGroupCount = metaData.g1(); + let lastGroup = -1; + let tempIndex = 0; + + for (let j = 0; j < transformGroupCount; j++) { + const transformFlags = flagData.g1(); + + if (transformFlags > 0) { + if (animBase.animTypes![j] !== 0) { + for (let k = j - 1; k > lastGroup; k--) { + if (animBase.animTypes![k] === 0) { + tempGroups[tempIndex] = k; + tempX[tempIndex] = 0; + tempY[tempIndex] = 0; + tempZ[tempIndex] = 0; + tempIndex++; + break; + } + } + } + + tempGroups[tempIndex] = j; + let defaultValue = 0; + if (animBase.animTypes![tempGroups[tempIndex]] === 3) { + defaultValue = 128; + } + + if ((transformFlags & 0x1) == 0) { + tempX[tempIndex] = defaultValue; + } else { + tempX[tempIndex] = valueData.gsmart(); + } + + if ((transformFlags & 0x2) == 0) { + tempY[tempIndex] = defaultValue; + } else { + tempY[tempIndex] = valueData.gsmart(); + } + + if ((transformFlags & 0x4) == 0) { + tempZ[tempIndex] = defaultValue; + } else { + tempZ[tempIndex] = valueData.gsmart(); + } + + lastGroup = j; + tempIndex++; + } + } + + animFrame.frameLength = tempIndex; + animFrame.bases = new Int32Array(tempIndex); + animFrame.x = new Int32Array(tempIndex); + animFrame.y = new Int32Array(tempIndex); + animFrame.z = new Int32Array(tempIndex); + + for (let l = 0; l < tempIndex; l++) { + animFrame.bases[l] = tempGroups[l]; + animFrame.x[l] = tempX[l]; + animFrame.y[l] = tempY[l]; + animFrame.z[l] = tempZ[l]; + } + AnimFrame.instances[frameIndex] = animFrame; + } + } +} \ No newline at end of file diff --git a/src/jaged/FileLoader.ts b/src/jaged/FileLoader.ts index efd6f91..7dbb568 100644 --- a/src/jaged/FileLoader.ts +++ b/src/jaged/FileLoader.ts @@ -1,5 +1,6 @@ import AnimBase from '#/graphics/AnimBase.ts'; import AnimFrame from '#/graphics/AnimFrame.ts'; +import AnimSet from '#/graphics/AnimSet.ts'; import Model from '#/graphics/Model.ts'; import Packet from '#/io/Packet.ts'; import ColorConversion from '#/jaged/ColorConversion.ts'; @@ -923,6 +924,10 @@ export default class FileLoader { file.name.toLowerCase().endsWith(".seq") ); + const animsetFiles = Array.from(files).filter((file) => + file.name.toLowerCase().endsWith(".anim") + ); + const baseFiles = Array.from(files).filter((file) => file.name.toLowerCase().endsWith(".base") ); @@ -1029,6 +1034,17 @@ export default class FileLoader { } } + for (const file of animsetFiles) { + try { + const parts = file.name.split("_"); + const idString = parts[parts.length - 1]; + const currentId = parseInt(idString, 10); + await this.convertAnimset(currentId, file); + } catch (error) { + console.error(`Error processing Animset file ${file.name}:`, error); + } + } + for (const file of baseFiles) { try { const parts = file.name.split("_"); @@ -1107,6 +1123,12 @@ export default class FileLoader { return Model.convertFromData(data); } + async convertAnimset(currentId: number, file: File): Promise { + const arrayBuffer = await this.readFileAsArrayBuffer(file); + const uint8View = new Uint8Array(arrayBuffer); + AnimSet.convertFromData(currentId, uint8View); + } + async convertBase(currentId: number, file: File): Promise { const arrayBuffer = await this.readFileAsArrayBuffer(file); const uint8View = new Uint8Array(arrayBuffer);