UNPKG

@minecraft/creator-tools

Version:

Minecraft Creator Tools command line and libraries.

208 lines (207 loc) 7.95 kB
/** * ModelDesignUtilities * * Converts MCP model design format to Minecraft .geo.json format * and generates texture atlases from per-face SVG/color specifications. */ import { IMcpModelDesign, IMcpFaceContent, IMcpColorRGBA, IMcpTextureDefinition, IMcpNoiseConfig, IMcpTexturedRectangle, IMcpPixelArt } from "./IMcpModelDesign"; import IModelGeometry from "./IModelGeometry"; /** * Represents a region in the texture atlas for a cube face */ export interface IAtlasRegion { x: number; y: number; width: number; height: number; content: IMcpFaceContent; faceName: string; cubeIndex: number; boneIndex: number; /** Context string for deterministic noise seeding (e.g., "bone0:cube1:north") */ contextString?: string; /** If true, this region shares atlas space with another region and should not be rendered */ isDuplicate?: boolean; } /** * Result from converting an MCP design to geometry */ export interface IModelDesignConversionResult { /** * The converted Minecraft geometry JSON */ geometry: IModelGeometry; /** * Atlas regions for generating the texture */ atlasRegions: IAtlasRegion[]; /** * Total texture size [width, height] */ textureSize: [number, number]; /** * Pixels per Minecraft unit used for texture generation. * Needed by pixel art renderer to scale properly. */ pixelsPerUnit: number; /** * Any warnings during conversion */ warnings: string[]; /** * Map from content hash to atlas region index, for texture deduplication */ textureDeduplicationMap?: Map<string, number>; } /** * Resolved face content after texture ID lookup. * Contains the actual svg/color/background to render (textureId is resolved away). */ export interface IResolvedFaceContent { /** @deprecated Use background with type:'solid' instead */ color?: string | IMcpColorRGBA; svg?: string; /** @deprecated Use background instead */ noise?: IMcpNoiseConfig; /** Background fill using a textured rectangle (unified color/noise format) */ background?: IMcpTexturedRectangle; /** Pixel art overlays to render on top of background and svg */ pixelArt?: IMcpPixelArt[]; /** Post-processing effects to apply to the face texture */ effects?: import("./TextureEffects").ITextureEffects; rotation?: number; /** The original textureId if this was resolved from a reference */ sourceTextureId?: string; } /** * Bounding box for a model design */ export interface IModelBounds { minX: number; minY: number; minZ: number; maxX: number; maxY: number; maxZ: number; /** Maximum dimension (width, height, or depth) */ maxDimension: number; /** Center point of the bounding box */ center: { x: number; y: number; z: number; }; } /** * Utility class for working with MCP model designs */ export default class ModelDesignUtilities { /** * Calculate the bounding box of a model design. * Iterates through all bones and cubes to find the min/max extents. */ static calculateModelBounds(design: IMcpModelDesign): IModelBounds; /** * Parse a color string or object to RGBA values (0-255) */ static parseColor(color: string | IMcpColorRGBA | undefined): IMcpColorRGBA; /** * Convert color to hex string */ static colorToHex(color: IMcpColorRGBA): string; /** * Resolve face content by looking up textureId references. * Returns the actual svg/color content to render. * Priority: textureId > svg > color * * @param faceContent The face content which may contain a textureId reference * @param textures The texture dictionary from the model design * @param warnings Array to collect any warnings (e.g., missing texture references) * @returns Resolved content with svg/color, or undefined if face should be transparent */ static resolveFaceContent(faceContent: IMcpFaceContent | undefined, textures: { [textureId: string]: IMcpTextureDefinition; } | undefined, warnings: string[]): IResolvedFaceContent | undefined; /** * Generate a content hash for a resolved face content. * Used for texture deduplication - faces with identical content can share atlas regions. * Note: rotation is NOT included in hash since it's applied at UV time, not texture time. * Note: backgrounds with undefined/random seed create unique textures per face (not deduplicated). */ static getContentHash(content: IResolvedFaceContent): string; /** * Get the effective pixels per unit for a design. * Returns the design's pixelsPerUnit if specified, otherwise DEFAULT_PIXELS_PER_UNIT. */ static getPixelsPerUnit(design: IMcpModelDesign): number; /** * Calculate the texture size needed for a face based on cube dimensions. * @param cubeSize The cube dimensions [width, height, depth] in Minecraft units * @param faceName The face to calculate texture size for * @param pixelsPerUnit Pixels per Minecraft unit (default: DEFAULT_PIXELS_PER_UNIT) */ static getFaceTextureSize(cubeSize: [number, number, number], faceName: string, pixelsPerUnit?: number): { width: number; height: number; }; /** * Check if a texture size is sufficient for a design by doing a dry-run pack. * Returns true if the texture needs to be larger. * Takes into account texture deduplication - identical textures at same size share atlas space. */ private static _checkNeedsLargerTexture; /** * Convert an MCP model design to Minecraft geometry JSON format */ static convertToGeometry(design: IMcpModelDesign): IModelDesignConversionResult; /** * Generate SVG for a solid color face */ static generateColorSvg(color: IMcpColorRGBA, width: number, height: number): string; /** * Get the SVG content for a face, either from explicit SVG, noise, or generating from color. * * Priority order: * 1. If noise is specified, generate noise background * 2. If svg is specified, overlay it on top of noise (or use as primary if no noise) * 3. If only color is specified, generate solid color * * @param content Face content configuration * @param width Texture width in pixels * @param height Texture height in pixels * @param contextString Optional context for deterministic noise seeding */ static getFaceSvg(content: IMcpFaceContent, width: number, height: number, contextString?: string): string; /** * Generate a complete SVG document representing the texture atlas * This can be rasterized to PNG using a rendering engine */ static generateAtlasSvg(atlasRegions: IAtlasRegion[], textureSize: [number, number]): string; /** * Check if an SVG string contains non-rect elements that are not Minecraft-style * Returns array of warning messages about non-Minecraft-style SVG elements */ private static validateSvgStyle; /** * Validate pixel art configuration and return any errors or warnings. * Returns array of error/warning messages about invalid pixel art */ private static validatePixelArt; /** * Validate an MCP model design and return any errors or warnings. * Errors are blocking issues that prevent model generation. * Warnings (prefixed with "WARNING:") are style suggestions for better Minecraft compatibility. */ static validateDesign(design: IMcpModelDesign): string[]; /** * Create a simple unit cube model design (for testing) */ static createUnitCubeDesign(identifier: string, faceColors: { north?: string; south?: string; east?: string; west?: string; up?: string; down?: string; }): IMcpModelDesign; }