mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-26 12:09:50 +01:00
Compare commits
8
Commits
1920be28d8
...
068e0e26b0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
068e0e26b0 | ||
|
|
f6ca77f8c8 | ||
|
|
4c7eda81ca | ||
|
|
3948af9e39 | ||
|
|
aec30e1944 | ||
|
|
4205b16769 | ||
|
|
4d13803b0c | ||
|
|
b950ac1318 |
No files matched your search
@@ -28,7 +28,7 @@ jobs:
|
||||
run: bun run build:bot
|
||||
|
||||
- name: Archive build
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: bot
|
||||
path: dist/bot
|
||||
@@ -46,14 +46,14 @@ jobs:
|
||||
- uses: arduino/setup-protoc@v3
|
||||
with:
|
||||
repo-token: ${{ secrets.GH_TOKEN }}
|
||||
- uses: actions/configure-pages@v5
|
||||
- uses: actions/configure-pages@v6
|
||||
- run: bun run setup
|
||||
|
||||
- name: Build website
|
||||
run: bun run build:website
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-pages-artifact@v4
|
||||
uses: actions/upload-pages-artifact@v5
|
||||
with:
|
||||
path: dist/website
|
||||
|
||||
@@ -69,4 +69,4 @@ jobs:
|
||||
steps:
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v4
|
||||
uses: actions/deploy-pages@v5
|
||||
@@ -1,5 +1,5 @@
|
||||
import { clamp, isEqual, times } from 'lodash-es';
|
||||
import { ReadStream } from './buffer';
|
||||
import { clamp, isEqual, times } from "lodash-es";
|
||||
import { ReadStream } from "./buffer";
|
||||
|
||||
export enum PvrFlags {
|
||||
NoFlag = 0,
|
||||
@@ -96,7 +96,7 @@ export class PvrReadStream extends ReadStream {
|
||||
const header = this.header();
|
||||
this.metadata();
|
||||
|
||||
if (typeof header.pixelFormat === 'number') {
|
||||
if (typeof header.pixelFormat === "number") {
|
||||
switch (header.pixelFormat) {
|
||||
default:
|
||||
throw new TypeError(
|
||||
@@ -142,12 +142,12 @@ export class PvrReadStream extends ReadStream {
|
||||
|
||||
times(pixelCount, (index) => {
|
||||
const buffer = this.consumeUint8Array(2);
|
||||
const bufferIndex = index * 4;
|
||||
const bufferIndex = index * 3;
|
||||
const r = ((buffer[1] & 0b11111000) >>> 3) / 31;
|
||||
const g =
|
||||
((buffer[1] & 0b111) << 3) |
|
||||
(((buffer[0] & 0b11100000) >>> 5) / 31);
|
||||
const b = buffer[0] & 0b11111;
|
||||
(((buffer[1] & 0b111) << 3) | ((buffer[0] & 0b11100000) >>> 5)) /
|
||||
63;
|
||||
const b = (buffer[0] & 0b11111) / 31;
|
||||
|
||||
data[bufferIndex] = Math.round(clamp(r * 255, 0, 255));
|
||||
data[bufferIndex + 1] = Math.round(clamp(g * 255, 0, 255));
|
||||
@@ -186,7 +186,7 @@ export class PvrReadStream extends ReadStream {
|
||||
metadataSize: this.uint32(),
|
||||
};
|
||||
|
||||
if (header.version !== 'PVR\x03') throw new TypeError('Endian mismatch');
|
||||
if (header.version !== "PVR\x03") throw new TypeError("Endian mismatch");
|
||||
|
||||
return header;
|
||||
}
|
||||
@@ -205,19 +205,19 @@ export class PvrReadStream extends ReadStream {
|
||||
resolveBitRatePixelFormat(
|
||||
pixelFormat: Exclude<ReturnType<typeof this.pixelFormat>, number>,
|
||||
) {
|
||||
if (pixelFormat.order === 'rgba') {
|
||||
if (pixelFormat.order === "rgba") {
|
||||
if (isEqual(pixelFormat.bitRates, [4, 4, 4, 4])) {
|
||||
return ResolvedBitRatePixelFormat.R4G4B4A4;
|
||||
} else
|
||||
throw new TypeError(
|
||||
`Unhandled rgba bit rate ${pixelFormat.bitRates.join(', ')}`,
|
||||
`Unhandled rgba bit rate ${pixelFormat.bitRates.join(", ")}`,
|
||||
);
|
||||
} else if (pixelFormat.order === 'rgb\0') {
|
||||
} else if (pixelFormat.order === "rgb\0") {
|
||||
if (isEqual(pixelFormat.bitRates, [5, 6, 5, 0])) {
|
||||
return ResolvedBitRatePixelFormat.R5G6B5A0;
|
||||
} else
|
||||
throw new TypeError(
|
||||
`Unhandled rgb bit rate ${pixelFormat.bitRates.join(', ')}`,
|
||||
`Unhandled rgb bit rate ${pixelFormat.bitRates.join(", ")}`,
|
||||
);
|
||||
} else {
|
||||
throw new TypeError(`Unhandled pixel order ${pixelFormat.order}`);
|
||||
|
||||
@@ -15,6 +15,9 @@ type DataNode = {
|
||||
qualityGroup?: string;
|
||||
fxName?: string;
|
||||
textures?: Textures;
|
||||
customCullMode?: number;
|
||||
enabledPresets?: EnabledPresets;
|
||||
properties?: Properties;
|
||||
} & (
|
||||
| ({
|
||||
configCount: number;
|
||||
@@ -24,7 +27,7 @@ type DataNode = {
|
||||
}
|
||||
);
|
||||
|
||||
interface ConfigArchive {
|
||||
export interface ConfigArchive {
|
||||
configName: string;
|
||||
fxName: string;
|
||||
properties: Properties;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import {
|
||||
bufferToBigInt,
|
||||
ConfigArchive,
|
||||
Hierarchy,
|
||||
Sc2ReadStream,
|
||||
ScgReadStream,
|
||||
@@ -75,6 +76,42 @@ export async function extractModel(vfs: AbstractVFS, path: string) {
|
||||
.setImage(baseColor),
|
||||
);
|
||||
|
||||
let defaultConfigArchive: ConfigArchive | undefined = undefined;
|
||||
|
||||
if (node.configCount) {
|
||||
const names = times(
|
||||
node.configCount,
|
||||
(index) => node[`configArchive_${index}`],
|
||||
);
|
||||
|
||||
defaultConfigArchive = names.find(
|
||||
(archive) => archive.configName === "Default",
|
||||
);
|
||||
defaultConfigArchive ??= node.configArchive_0;
|
||||
}
|
||||
|
||||
const customCullMode =
|
||||
node.customCullMode ?? defaultConfigArchive?.customCullMode;
|
||||
|
||||
if (customCullMode === 0) {
|
||||
material.setDoubleSided(true);
|
||||
} else if (customCullMode !== undefined) {
|
||||
material.setDoubleSided(false);
|
||||
}
|
||||
|
||||
if (
|
||||
node.enabledPresets?.AlphaTest &&
|
||||
node.properties?.alphatestThreshold
|
||||
) {
|
||||
const view = new DataView(node.properties.alphatestThreshold);
|
||||
const alphaCutoff =
|
||||
view.byteLength < 4
|
||||
? 0.5
|
||||
: view.getFloat32(view.byteLength - 4, true);
|
||||
|
||||
material.setAlphaMode("MASK").setAlphaCutoff(alphaCutoff);
|
||||
}
|
||||
|
||||
if (node.configCount) {
|
||||
for (
|
||||
let configIndex = 0;
|
||||
@@ -85,14 +122,17 @@ export async function extractModel(vfs: AbstractVFS, path: string) {
|
||||
|
||||
if (
|
||||
archive.configName !== "Default" ||
|
||||
!archive.enabledPresets?.AlphaTest
|
||||
!archive.enabledPresets?.AlphaTest ||
|
||||
!archive.properties?.alphatestThreshold
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const view = new DataView(archive.properties.alphatestThreshold);
|
||||
const _ = view.getUint8(0); // only god knows what these flags are
|
||||
const alphaCutoff = view.getFloat32(1, true);
|
||||
const alphaCutoff =
|
||||
view.byteLength < 4
|
||||
? 0.5
|
||||
: view.getFloat32(view.byteLength - 4, true);
|
||||
|
||||
material.setAlphaMode("MASK").setAlphaCutoff(alphaCutoff);
|
||||
}
|
||||
@@ -171,8 +211,8 @@ export async function extractModel(vfs: AbstractVFS, path: string) {
|
||||
|
||||
case "TransformComponent": {
|
||||
const localTranslation = component["tc.localTranslation"];
|
||||
// The game resets top-level node translation to [0, 0, 0] on load.
|
||||
// Child nodes must keep their authored local offsets.
|
||||
// The game resets top-level node translation to [0, 0, 0] on load.
|
||||
// Child nodes must keep their authored local offsets.
|
||||
node.setTranslation(
|
||||
parent instanceof Scene ? [0, 0, 0] : localTranslation,
|
||||
);
|
||||
@@ -284,4 +324,4 @@ export async function extractModel(vfs: AbstractVFS, path: string) {
|
||||
await document.transform(prune({ keepAttributes: true }), dedup());
|
||||
|
||||
return document;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user