UNPKG

war3-model

Version:

Warcraft 3 model parser, generator, convertor and previewer

623 lines (611 loc) 20 kB
import { DdsInfo } from 'dds-parser'; import { vec3, quat, mat4 } from 'gl-matrix'; interface ModelInfo { Name: string; MinimumExtent: Float32Array; MaximumExtent: Float32Array; BoundsRadius: number; BlendTime: number; NumGeosets?: number; NumGeosetAnims?: number; NumBones?: number; NumLights?: number; NumAttachments?: number; NumEvents?: number; NumParticleEmitters?: number; NumParticleEmitters2?: number; NumRibbonEmitters?: number; } interface Sequence { Name: string; Interval: Uint32Array; NonLooping: boolean; MinimumExtent: Float32Array; MaximumExtent: Float32Array; BoundsRadius: number; MoveSpeed: number; Rarity: number; } declare enum TextureFlags { WrapWidth = 1, WrapHeight = 2 } interface Texture { Image: string; ReplaceableId?: number; Flags?: TextureFlags; } declare enum FilterMode { None = 0, Transparent = 1, Blend = 2, Additive = 3, AddAlpha = 4, Modulate = 5, Modulate2x = 6 } declare enum LineType { DontInterp = 0, Linear = 1, Hermite = 2, Bezier = 3 } interface AnimKeyframe { Frame: number; Vector: Float32Array | Int32Array; InTan?: Float32Array | Int32Array; OutTan?: Float32Array | Int32Array; } interface AnimVector { LineType: LineType; GlobalSeqId?: number; Keys: AnimKeyframe[]; } declare enum LayerShading { Unshaded = 1, SphereEnvMap = 2, TwoSided = 16, Unfogged = 32, NoDepthTest = 64, NoDepthSet = 128 } interface Layer { FilterMode?: FilterMode; Shading?: number; TextureID?: AnimVector | number; TVertexAnimId?: number; CoordId: number; Alpha?: AnimVector | number; EmissiveGain?: AnimVector | number; FresnelColor?: AnimVector | Float32Array; FresnelOpacity?: AnimVector | number; FresnelTeamColor?: AnimVector | number; ShaderTypeId?: number; NormalTextureID?: AnimVector | number; ORMTextureID?: AnimVector | number; EmissiveTextureID?: AnimVector | number; TeamColorTextureID?: AnimVector | number; ReflectionsTextureID?: AnimVector | number; } declare enum MaterialRenderMode { ConstantColor = 1, SortPrimsFarZ = 16, FullResolution = 32 } interface Material { PriorityPlane?: number; RenderMode?: number; Layers: Layer[]; Shader?: string; } interface GeosetAnimInfo { MinimumExtent: Float32Array; MaximumExtent: Float32Array; BoundsRadius: number; } interface Geoset { Vertices: Float32Array; Normals: Float32Array; TVertices: Float32Array[]; VertexGroup: Uint8Array; Faces: Uint16Array; Groups: number[][]; TotalGroupsCount: number; MinimumExtent: Float32Array; MaximumExtent: Float32Array; BoundsRadius: number; Anims: GeosetAnimInfo[]; MaterialID: number; SelectionGroup: number; Unselectable: boolean; LevelOfDetail?: number; Name?: string; Tangents?: Float32Array; SkinWeights?: Uint8Array; } declare enum GeosetAnimFlags { DropShadow = 1, Color = 2 } interface GeosetAnim { GeosetId: number; Alpha: AnimVector | number; Color: AnimVector | Float32Array; Flags: number; } declare enum NodeFlags { DontInheritTranslation = 1, DontInheritRotation = 2, DontInheritScaling = 4, Billboarded = 8, BillboardedLockX = 16, BillboardedLockY = 32, BillboardedLockZ = 64, CameraAnchored = 128 } declare enum NodeType { Helper = 0, Bone = 256, Light = 512, EventObject = 1024, Attachment = 2048, ParticleEmitter = 4096, CollisionShape = 8192, RibbonEmitter = 16384 } interface Node { Name: string; ObjectId: number; Parent?: number | null; PivotPoint: Float32Array; Flags: number; Translation?: AnimVector; Rotation?: AnimVector; Scaling?: AnimVector; } interface Bone extends Node { GeosetId?: number; GeosetAnimId?: number; } declare type Helper = Node; interface Attachment extends Node { Path?: string; AttachmentID?: number; Visibility?: AnimVector; } interface EventObject extends Node { EventTrack: Uint32Array; } declare enum CollisionShapeType { Box = 0, Sphere = 2 } interface CollisionShape extends Node { Shape: CollisionShapeType; Vertices: Float32Array; BoundsRadius?: number; } declare enum ParticleEmitterFlags { EmitterUsesMDL = 32768, EmitterUsesTGA = 65536 } interface ParticleEmitter extends Node { EmissionRate: AnimVector | number; Gravity: AnimVector | number; Longitude: AnimVector | number; Latitude: AnimVector | number; Path: string; LifeSpan: AnimVector | number; InitVelocity: AnimVector | number; Visibility: AnimVector; } declare enum ParticleEmitter2Flags { Unshaded = 32768, SortPrimsFarZ = 65536, LineEmitter = 131072, Unfogged = 262144, ModelSpace = 524288, XYQuad = 1048576 } declare enum ParticleEmitter2FilterMode { Blend = 0, Additive = 1, Modulate = 2, Modulate2x = 3, AlphaKey = 4 } declare enum ParticleEmitter2FramesFlags { Head = 1, Tail = 2 } interface ParticleEmitter2 extends Node { Speed?: AnimVector | number; Variation?: AnimVector | number; Latitude?: AnimVector | number; Gravity?: AnimVector | number; Visibility?: AnimVector | number; Squirt?: boolean; LifeSpan?: number; EmissionRate?: AnimVector | number; Width?: AnimVector | number; Length?: AnimVector | number; FilterMode?: ParticleEmitter2FilterMode; Rows?: number; Columns?: number; FrameFlags: number; TailLength?: number; Time?: number; SegmentColor?: Float32Array[]; Alpha?: Uint8Array; ParticleScaling?: Float32Array; LifeSpanUVAnim?: Uint32Array; DecayUVAnim?: Uint32Array; TailUVAnim?: Uint32Array; TailDecayUVAnim?: Uint32Array; TextureID?: number; ReplaceableId?: number; PriorityPlane?: number; } interface Camera { Name: string; Position: Float32Array; FieldOfView: number; NearClip: number; FarClip: number; TargetPosition: Float32Array; TargetTranslation?: AnimVector; Translation?: AnimVector; Rotation?: AnimVector; } declare enum LightType { Omnidirectional = 0, Directional = 1, Ambient = 2 } interface Light extends Node { LightType: LightType; AttenuationStart?: AnimVector | number; AttenuationEnd?: AnimVector | number; Color?: AnimVector | Float32Array; Intensity?: AnimVector | number; AmbIntensity?: AnimVector | number; AmbColor?: AnimVector | Float32Array; Visibility?: AnimVector; } interface RibbonEmitter extends Node { HeightAbove?: AnimVector | number; HeightBelow?: AnimVector | number; Alpha?: AnimVector | number; Color?: Float32Array; LifeSpan?: number; TextureSlot?: AnimVector | number; EmissionRate?: number; Rows?: number; Columns?: number; MaterialID?: number; Gravity?: number; Visibility?: AnimVector; } interface TVertexAnim { Translation?: AnimVector; Rotation?: AnimVector; Scaling?: AnimVector; } interface FaceFX { Name: string; Path: string; } interface BindPose { Matrices: Float32Array[]; } declare enum ParticleEmitterPopcornFlags { Unshaded = 32768, SortPrimsFarZ = 65536, Unfogged = 262144 } interface ParticleEmitterPopcorn extends Node { LifeSpan?: AnimVector | number; EmissionRate?: AnimVector | number; Speed?: AnimVector | number; Color?: AnimVector | Float32Array; Alpha?: AnimVector | number; ReplaceableId?: number; Path?: string; AnimVisibilityGuide?: string; Visibility?: AnimVector; } interface Model { Version: number; Info: ModelInfo; Sequences: Sequence[]; Textures: Texture[]; Materials: Material[]; Geosets: Geoset[]; GeosetAnims: GeosetAnim[]; Bones: Bone[]; Helpers: Helper[]; Attachments: Attachment[]; Nodes: Node[]; PivotPoints: Float32Array[]; EventObjects: EventObject[]; CollisionShapes: CollisionShape[]; GlobalSequences: number[]; ParticleEmitters: ParticleEmitter[]; ParticleEmitters2: ParticleEmitter2[]; Cameras: Camera[]; Lights: Light[]; RibbonEmitters: RibbonEmitter[]; TextureAnims: TVertexAnim[]; FaceFX?: FaceFX[]; BindPoses?: BindPose[]; ParticleEmitterPopcorns?: ParticleEmitterPopcorn[]; } type model_AnimKeyframe = AnimKeyframe; type model_AnimVector = AnimVector; type model_Attachment = Attachment; type model_BindPose = BindPose; type model_Bone = Bone; type model_Camera = Camera; type model_CollisionShape = CollisionShape; type model_CollisionShapeType = CollisionShapeType; declare const model_CollisionShapeType: typeof CollisionShapeType; type model_EventObject = EventObject; type model_FaceFX = FaceFX; type model_FilterMode = FilterMode; declare const model_FilterMode: typeof FilterMode; type model_Geoset = Geoset; type model_GeosetAnim = GeosetAnim; type model_GeosetAnimFlags = GeosetAnimFlags; declare const model_GeosetAnimFlags: typeof GeosetAnimFlags; type model_GeosetAnimInfo = GeosetAnimInfo; type model_Helper = Helper; type model_Layer = Layer; type model_LayerShading = LayerShading; declare const model_LayerShading: typeof LayerShading; type model_Light = Light; type model_LightType = LightType; declare const model_LightType: typeof LightType; type model_LineType = LineType; declare const model_LineType: typeof LineType; type model_Material = Material; type model_MaterialRenderMode = MaterialRenderMode; declare const model_MaterialRenderMode: typeof MaterialRenderMode; type model_Model = Model; type model_ModelInfo = ModelInfo; type model_Node = Node; type model_NodeFlags = NodeFlags; declare const model_NodeFlags: typeof NodeFlags; type model_NodeType = NodeType; declare const model_NodeType: typeof NodeType; type model_ParticleEmitter = ParticleEmitter; type model_ParticleEmitter2 = ParticleEmitter2; type model_ParticleEmitter2FilterMode = ParticleEmitter2FilterMode; declare const model_ParticleEmitter2FilterMode: typeof ParticleEmitter2FilterMode; type model_ParticleEmitter2Flags = ParticleEmitter2Flags; declare const model_ParticleEmitter2Flags: typeof ParticleEmitter2Flags; type model_ParticleEmitter2FramesFlags = ParticleEmitter2FramesFlags; declare const model_ParticleEmitter2FramesFlags: typeof ParticleEmitter2FramesFlags; type model_ParticleEmitterFlags = ParticleEmitterFlags; declare const model_ParticleEmitterFlags: typeof ParticleEmitterFlags; type model_ParticleEmitterPopcorn = ParticleEmitterPopcorn; type model_ParticleEmitterPopcornFlags = ParticleEmitterPopcornFlags; declare const model_ParticleEmitterPopcornFlags: typeof ParticleEmitterPopcornFlags; type model_RibbonEmitter = RibbonEmitter; type model_Sequence = Sequence; type model_TVertexAnim = TVertexAnim; type model_Texture = Texture; type model_TextureFlags = TextureFlags; declare const model_TextureFlags: typeof TextureFlags; declare namespace model { export { model_CollisionShapeType as CollisionShapeType, model_FilterMode as FilterMode, model_GeosetAnimFlags as GeosetAnimFlags, model_LayerShading as LayerShading, model_LightType as LightType, model_LineType as LineType, model_MaterialRenderMode as MaterialRenderMode, model_NodeFlags as NodeFlags, model_NodeType as NodeType, model_ParticleEmitter2FilterMode as ParticleEmitter2FilterMode, model_ParticleEmitter2Flags as ParticleEmitter2Flags, model_ParticleEmitter2FramesFlags as ParticleEmitter2FramesFlags, model_ParticleEmitterFlags as ParticleEmitterFlags, model_ParticleEmitterPopcornFlags as ParticleEmitterPopcornFlags, model_TextureFlags as TextureFlags }; export type { model_AnimKeyframe as AnimKeyframe, model_AnimVector as AnimVector, model_Attachment as Attachment, model_BindPose as BindPose, model_Bone as Bone, model_Camera as Camera, model_CollisionShape as CollisionShape, model_EventObject as EventObject, model_FaceFX as FaceFX, model_Geoset as Geoset, model_GeosetAnim as GeosetAnim, model_GeosetAnimInfo as GeosetAnimInfo, model_Helper as Helper, model_Layer as Layer, model_Light as Light, model_Material as Material, model_Model as Model, model_ModelInfo as ModelInfo, model_Node as Node, model_ParticleEmitter as ParticleEmitter, model_ParticleEmitter2 as ParticleEmitter2, model_ParticleEmitterPopcorn as ParticleEmitterPopcorn, model_RibbonEmitter as RibbonEmitter, model_Sequence as Sequence, model_TVertexAnim as TVertexAnim, model_Texture as Texture }; } declare function parse$1(str: string): Model; declare function parse(arrayBuffer: ArrayBuffer): Model; declare function generate$1(model: Model): string; declare function generate(model: Model): ArrayBuffer; declare enum BLPType { BLP0 = 0, BLP1 = 1, BLP2 = 2 } declare enum BLPContent { JPEG = 0, Direct = 1 } interface BLPMipMap { offset: number; size: number; } interface BLPImage { type: BLPType; width: number; height: number; content: BLPContent; alphaBits: number; mipmaps: BLPMipMap[]; data: ArrayBuffer; } type blpimage_BLPContent = BLPContent; declare const blpimage_BLPContent: typeof BLPContent; type blpimage_BLPImage = BLPImage; type blpimage_BLPMipMap = BLPMipMap; type blpimage_BLPType = BLPType; declare const blpimage_BLPType: typeof BLPType; declare namespace blpimage { export { blpimage_BLPContent as BLPContent, blpimage_BLPType as BLPType }; export type { blpimage_BLPImage as BLPImage, blpimage_BLPMipMap as BLPMipMap }; } interface ImageDataLike { width: number; height: number; data: Uint8ClampedArray; colorSpace: 'srgb' | 'display-p3' | undefined; } declare function decode(arrayBuffer: ArrayBuffer): BLPImage; declare function getImageData(blp: BLPImage, mipmapLevel: number): ImageDataLike; declare type DDS_FORMAT = WEBGL_compressed_texture_s3tc['COMPRESSED_RGBA_S3TC_DXT1_EXT'] | WEBGL_compressed_texture_s3tc['COMPRESSED_RGBA_S3TC_DXT3_EXT'] | WEBGL_compressed_texture_s3tc['COMPRESSED_RGBA_S3TC_DXT5_EXT'] | WEBGL_compressed_texture_s3tc['COMPRESSED_RGB_S3TC_DXT1_EXT']; declare class ModelRenderer { private isHD; private canvas; private gl; private device; private gpuContext; private anisotropicExt; private colorBufferFloatExt; private vertexShader; private fragmentShader; private shaderProgram; private vsBindGroupLayout; private fsBindGroupLayout; private gpuShaderModule; private gpuDepthShaderModule; private gpuPipelines; private gpuWireframePipeline; private gpuShadowPipeline; private gpuPipelineLayout; private gpuRenderPassDescriptor; private shaderProgramLocations; private skeletonShaderProgram; private skeletonVertexShader; private skeletonFragmentShader; private skeletonShaderProgramLocations; private skeletonVertexBuffer; private skeletonColorBuffer; private skeletonShaderModule; private skeletonBindGroupLayout; private skeletonPipelineLayout; private skeletonPipeline; private skeletonGPUVertexBuffer; private skeletonGPUColorBuffer; private skeletonGPUUniformsBuffer; private model; private interp; private rendererData; private particlesController; private ribbonsController; private softwareSkinning; private vertexBuffer; private normalBuffer; private vertices; private texCoordBuffer; private indexBuffer; private wireframeIndexBuffer; private wireframeIndexGPUBuffer; private groupBuffer; private skinWeightBuffer; private tangentBuffer; private envShaderModeule; private envPiepeline; private envVSBindGroupLayout; private envFSBindGroupLayout; private envVSUniformsBuffer; private envVSBindGroup; private envSampler; private cubeVertexBuffer; private cubeGPUVertexBuffer; private squareVertexBuffer; private brdfLUT; private gpuBrdfLUT; private gpuBrdfSampler; private envToCubemap; private envToCubemapShaderModule; private envToCubemapPiepeline; private envToCubemapVSBindGroupLayout; private envToCubemapFSBindGroupLayout; private envToCubemapSampler; private envSphere; private convoluteDiffuseEnv; private convoluteDiffuseEnvShaderModule; private convoluteDiffuseEnvPiepeline; private convoluteDiffuseEnvVSBindGroupLayout; private convoluteDiffuseEnvFSBindGroupLayout; private convoluteDiffuseEnvSampler; private prefilterEnv; private prefilterEnvShaderModule; private prefilterEnvPiepeline; private prefilterEnvVSBindGroupLayout; private prefilterEnvFSBindGroupLayout; private prefilterEnvSampler; private integrateBRDF; private gpuMultisampleTexture; private gpuDepthTexture; private gpuVertexBuffer; private gpuNormalBuffer; private gpuTexCoordBuffer; private gpuGroupBuffer; private gpuIndexBuffer; private gpuSkinWeightBuffer; private gpuTangentBuffer; private gpuVSUniformsBuffer; private gpuVSUniformsBindGroup; private gpuFSUniformsBuffers; constructor(model: Model); destroy(): void; private initRequiredEnvMaps; initGL(glContext: WebGL2RenderingContext | WebGLRenderingContext): void; initGPUDevice(canvas: HTMLCanvasElement, device: GPUDevice, context: GPUCanvasContext): Promise<void>; setTextureImage(path: string, img: HTMLImageElement): void; setTextureImageData(path: string, imageData: ImageData[]): void; setTextureCompressedImage(path: string, format: DDS_FORMAT, imageData: ArrayBuffer, ddsInfo: DdsInfo): void; setGPUTextureCompressedImage(path: string, format: GPUTextureFormat, imageData: ArrayBuffer, ddsInfo: DdsInfo): void; setCamera(cameraPos: vec3, cameraQuat: quat): void; setLightPosition(lightPos: vec3): void; setLightColor(lightColor: vec3): void; setSequence(index: number): void; getSequence(): number; setFrame(frame: number): void; getFrame(): number; setTeamColor(color: vec3): void; update(delta: number): void; render(mvMatrix: mat4, pMatrix: mat4, { wireframe, env, levelOfDetail, useEnvironmentMap, shadowMapTexture, shadowMapMatrix, shadowBias, shadowSmoothingStep, depthTextureTarget }: { wireframe?: boolean; env?: boolean; levelOfDetail?: number; useEnvironmentMap?: boolean; shadowMapTexture?: WebGLTexture | GPUTexture; shadowMapMatrix?: mat4; shadowBias?: number; shadowSmoothingStep?: number; depthTextureTarget?: GPUTexture; }): void; private renderEnvironmentGPU; private renderEnvironment; /** * @param mvMatrix * @param pMatrix * @param nodes Nodes to highlight. null means draw all */ renderSkeleton(mvMatrix: mat4, pMatrix: mat4, nodes: string[] | null): void; private initSkeletonShaderProgram; private generateGeosetVertices; private setTextureParameters; private processEnvMaps; private initShaderProgram; private destroyShaderProgramObject; private initShaders; private initGPUShaders; private createWireframeBuffer; private createWireframeGPUBuffer; private initBuffers; private createGPUPipeline; private createGPUPipelineByLayer; private getGPUPipeline; private initGPUPipeline; private initGPUBuffers; private initGPUUniformBuffers; private initGPUMultisampleTexture; private initGPUDepthTexture; private initGPUEmptyTexture; private initCube; private initSquare; private initBRDFLUT; private initGPUBRDFLUT; private updateGlobalSequences; private updateNode; private findAlpha; private getTexCoordMatrix; private setLayerProps; private setLayerPropsHD; } export { ModelRenderer, blpimage as blp, decode as decodeBLP, generate$1 as generateMDL, generate as generateMDX, getImageData as getBLPImageData, model, parse$1 as parseMDL, parse as parseMDX };