novaparse
Version:
An EV Nova file parser for NovaJS
145 lines • 5.75 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const BaseParse_1 = require("./BaseParse");
const SpriteSheetData_1 = require("novadatainterface/SpriteSheetData");
const pngjs_1 = require("pngjs");
const path = require("path");
const hull = require("hull.js");
const SHEET_LOOP = 10;
class DimensionError extends Error {
}
;
function getWH(frames) {
var singleFrameWidth = frames[0].width;
var singleFrameHeight = frames[0].width;
var fullPixelWidth = Math.min(SHEET_LOOP, frames.length) * singleFrameWidth;
var fullPixelHeight = Math.ceil(frames.length / SHEET_LOOP) * singleFrameHeight;
return {
fullPixelHeight,
fullPixelWidth,
singleFrameHeight,
singleFrameWidth
};
}
function buildPNG(frames) {
var { fullPixelHeight, fullPixelWidth, singleFrameHeight, singleFrameWidth } = getWH(frames);
var outPNG = new pngjs_1.PNG({
filterType: 4,
width: fullPixelWidth,
height: fullPixelHeight
});
for (let f = 0; f < frames.length; f++) {
let frame = frames[f];
// Validation for sanity
if (frame.width != singleFrameWidth || frame.height != singleFrameHeight) {
throw new DimensionError("Wrong dimensions " + frame.width + " by " + frame.height
+ ". Expected " + singleFrameWidth + " by " + singleFrameHeight + ".");
}
var col = f % SHEET_LOOP;
var row = Math.floor(f / SHEET_LOOP);
for (var y = 0; y < frame.height; y++) {
for (var x = 0; x < frame.width; x++) {
var frameIDX = (frame.width * y + x) << 2;
var pngIDX = (outPNG.width * y + // skip to next row of pixels
outPNG.width * // skip to next row of frames
singleFrameHeight * row +
x + // skip to next col of pixels
singleFrameWidth * col // skip to next col of frames
) << 2;
outPNG.data[pngIDX] = frame.data[frameIDX];
outPNG.data[pngIDX + 1] = frame.data[frameIDX + 1];
outPNG.data[pngIDX + 2] = frame.data[frameIDX + 2];
outPNG.data[pngIDX + 3] = frame.data[frameIDX + 3];
// is there a better way?
}
}
}
return outPNG;
}
// Includes in its output any points that are not black
function makeVisibleArray(png) {
var visibleArray = [];
var origin = [png.width / 2, png.height / 2];
for (var y = 0; y < png.height; y++) {
for (var x = 0; x < png.width; x++) {
var idx = (png.width * y + x) << 2;
if (png.data[idx + 3] === 255) {
visibleArray.push([x - origin[0], -(y - origin[1])]);
}
}
}
return visibleArray;
}
function makeConvexHull(png) {
// No concavity. Convex hull.
var visibleArray = makeVisibleArray(png);
var hullWithRepeat = hull(visibleArray, Infinity);
// Cut off the last point since it's the same as the first.
return hullWithRepeat.slice(0, hullWithRepeat.length - 1);
}
function buildConvexHulls(frames) {
return frames.map(makeConvexHull);
}
function buildSpriteSheetFrames(rled) {
var frames = rled.frames;
var { fullPixelHeight, fullPixelWidth, singleFrameHeight, singleFrameWidth } = getWH(frames);
var imagePath = path.join(SpriteSheetData_1.DefaultImageLocation, rled.globalID + ".png");
var meta = {
format: "RGBA8888",
size: {
w: fullPixelWidth,
h: fullPixelHeight
},
scale: "1",
image: imagePath
};
var frameInfoObj = {};
for (var f = 0; f < frames.length; f++) {
var col = f % SHEET_LOOP;
var row = Math.floor(f / SHEET_LOOP);
frameInfoObj[rled.globalID + " " + f + ".png"] = {
frame: {
x: col * singleFrameWidth,
y: row * singleFrameHeight,
w: singleFrameWidth,
h: singleFrameHeight
},
rotated: false,
trimmed: false,
sourceSize: { w: fullPixelWidth, h: fullPixelHeight }
};
}
return {
frames: frameInfoObj,
meta
};
}
// Parses SpriteSheet, SpriteSheetImage, and SpriteSheetFrames at the same time
// They are separated from each other due to PIXI.js peculiarities.
function SpriteSheetMultiParse(rled, notFoundFunction) {
return __awaiter(this, void 0, void 0, function* () {
var base = yield BaseParse_1.BaseParse(rled, notFoundFunction);
var assembledPNG = buildPNG(rled.frames);
var spriteSheetImage = pngjs_1.PNG.sync.write(assembledPNG);
// TODO: Convex Hulls
var convexHulls = buildConvexHulls(rled.frames);
var spriteSheet = Object.assign({}, base, { convexHulls });
var spriteSheetFrames = buildSpriteSheetFrames(rled);
return {
spriteSheet,
spriteSheetImage,
spriteSheetFrames
};
});
}
exports.SpriteSheetMultiParse = SpriteSheetMultiParse;
;
//# sourceMappingURL=SpriteSheetMultiParse.js.map