war3-model
Version:
Warcraft 3 model parser, generator, convertor and previewer
592 lines (580 loc) • 17.5 kB
TypeScript
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_ModelInfo = ModelInfo;
type model_Sequence = Sequence;
type model_TextureFlags = TextureFlags;
declare const model_TextureFlags: typeof TextureFlags;
type model_Texture = Texture;
type model_FilterMode = FilterMode;
declare const model_FilterMode: typeof FilterMode;
type model_LineType = LineType;
declare const model_LineType: typeof LineType;
type model_AnimKeyframe = AnimKeyframe;
type model_AnimVector = AnimVector;
type model_LayerShading = LayerShading;
declare const model_LayerShading: typeof LayerShading;
type model_Layer = Layer;
type model_MaterialRenderMode = MaterialRenderMode;
declare const model_MaterialRenderMode: typeof MaterialRenderMode;
type model_Material = Material;
type model_GeosetAnimInfo = GeosetAnimInfo;
type model_Geoset = Geoset;
type model_GeosetAnimFlags = GeosetAnimFlags;
declare const model_GeosetAnimFlags: typeof GeosetAnimFlags;
type model_GeosetAnim = GeosetAnim;
type model_NodeFlags = NodeFlags;
declare const model_NodeFlags: typeof NodeFlags;
type model_NodeType = NodeType;
declare const model_NodeType: typeof NodeType;
type model_Node = Node;
type model_Bone = Bone;
type model_Helper = Helper;
type model_Attachment = Attachment;
type model_EventObject = EventObject;
type model_CollisionShapeType = CollisionShapeType;
declare const model_CollisionShapeType: typeof CollisionShapeType;
type model_CollisionShape = CollisionShape;
type model_ParticleEmitterFlags = ParticleEmitterFlags;
declare const model_ParticleEmitterFlags: typeof ParticleEmitterFlags;
type model_ParticleEmitter = ParticleEmitter;
type model_ParticleEmitter2Flags = ParticleEmitter2Flags;
declare const model_ParticleEmitter2Flags: typeof ParticleEmitter2Flags;
type model_ParticleEmitter2FilterMode = ParticleEmitter2FilterMode;
declare const model_ParticleEmitter2FilterMode: typeof ParticleEmitter2FilterMode;
type model_ParticleEmitter2FramesFlags = ParticleEmitter2FramesFlags;
declare const model_ParticleEmitter2FramesFlags: typeof ParticleEmitter2FramesFlags;
type model_ParticleEmitter2 = ParticleEmitter2;
type model_Camera = Camera;
type model_LightType = LightType;
declare const model_LightType: typeof LightType;
type model_Light = Light;
type model_RibbonEmitter = RibbonEmitter;
type model_TVertexAnim = TVertexAnim;
type model_FaceFX = FaceFX;
type model_BindPose = BindPose;
type model_ParticleEmitterPopcornFlags = ParticleEmitterPopcornFlags;
declare const model_ParticleEmitterPopcornFlags: typeof ParticleEmitterPopcornFlags;
type model_ParticleEmitterPopcorn = ParticleEmitterPopcorn;
type model_Model = Model;
declare namespace model {
export {
model_ModelInfo as ModelInfo,
model_Sequence as Sequence,
model_TextureFlags as TextureFlags,
model_Texture as Texture,
model_FilterMode as FilterMode,
model_LineType as LineType,
model_AnimKeyframe as AnimKeyframe,
model_AnimVector as AnimVector,
model_LayerShading as LayerShading,
model_Layer as Layer,
model_MaterialRenderMode as MaterialRenderMode,
model_Material as Material,
model_GeosetAnimInfo as GeosetAnimInfo,
model_Geoset as Geoset,
model_GeosetAnimFlags as GeosetAnimFlags,
model_GeosetAnim as GeosetAnim,
model_NodeFlags as NodeFlags,
model_NodeType as NodeType,
model_Node as Node,
model_Bone as Bone,
model_Helper as Helper,
model_Attachment as Attachment,
model_EventObject as EventObject,
model_CollisionShapeType as CollisionShapeType,
model_CollisionShape as CollisionShape,
model_ParticleEmitterFlags as ParticleEmitterFlags,
model_ParticleEmitter as ParticleEmitter,
model_ParticleEmitter2Flags as ParticleEmitter2Flags,
model_ParticleEmitter2FilterMode as ParticleEmitter2FilterMode,
model_ParticleEmitter2FramesFlags as ParticleEmitter2FramesFlags,
model_ParticleEmitter2 as ParticleEmitter2,
model_Camera as Camera,
model_LightType as LightType,
model_Light as Light,
model_RibbonEmitter as RibbonEmitter,
model_TVertexAnim as TVertexAnim,
model_FaceFX as FaceFX,
model_BindPose as BindPose,
model_ParticleEmitterPopcornFlags as ParticleEmitterPopcornFlags,
model_ParticleEmitterPopcorn as ParticleEmitterPopcorn,
model_Model as Model,
};
}
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_BLPType = BLPType;
declare const blpimage_BLPType: typeof BLPType;
type blpimage_BLPContent = BLPContent;
declare const blpimage_BLPContent: typeof BLPContent;
type blpimage_BLPMipMap = BLPMipMap;
type blpimage_BLPImage = BLPImage;
declare namespace blpimage {
export {
blpimage_BLPType as BLPType,
blpimage_BLPContent as BLPContent,
blpimage_BLPMipMap as BLPMipMap,
blpimage_BLPImage as BLPImage,
};
}
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 gl;
private anisotropicExt;
private colorBufferFloatExt;
private vertexShader;
private fragmentShader;
private shaderProgram;
private shaderProgramLocations;
private skeletonShaderProgram;
private skeletonVertexShader;
private skeletonFragmentShader;
private skeletonShaderProgramLocations;
private skeletonVertexBuffer;
private skeletonColorBuffer;
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 groupBuffer;
private skinWeightBuffer;
private tangentBuffer;
private cubeVertexBuffer;
private squareVertexBuffer;
private brdfLUT;
private envToCubemap;
private envSphere;
private convoluteDiffuseEnv;
private prefilterEnv;
private integrateBRDF;
constructor(model: Model);
destroy(): void;
initGL(glContext: WebGL2RenderingContext | WebGLRenderingContext): void;
setTextureImage(path: string, img: HTMLImageElement, flags: TextureFlags | 0): void;
setTextureImageData(path: string, imageData: ImageData[], flags: TextureFlags): void;
setTextureCompressedImage(path: string, format: DDS_FORMAT, imageData: ArrayBuffer, ddsInfo: DdsInfo, flags: TextureFlags): 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, levelOfDetail, useEnvironmentMap, shadowMapTexture, shadowMapMatrix, shadowBias, shadowSmoothingStep }: {
wireframe: boolean;
levelOfDetail?: number;
useEnvironmentMap?: boolean;
shadowMapTexture?: WebGLTexture;
shadowMapMatrix?: mat4;
shadowBias?: number;
shadowSmoothingStep?: number;
}): void;
renderEnvironment(mvMatrix: mat4, pMatrix: mat4): void;
/**
* @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 createWireframeBuffer;
private initBuffers;
private initCube;
private initSquare;
private initBRDFLUT;
private updateGlobalSequences;
private updateNode;
private findAlpha;
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 };