bis-toolkit 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -10,4 +10,5 @@ export * as PAA from '@bis-toolkit/paa';
10
10
  export * as P3D from '@bis-toolkit/p3d';
11
11
  export * as EDDS from '@bis-toolkit/edds';
12
12
  export * as CPPParser from '@bis-toolkit/cppparser';
13
+ export * as ANM from '@bis-toolkit/anm';
13
14
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,KAAK,MAAM,oBAAoB,CAAC;AAG5C,OAAO,KAAK,GAAG,MAAM,kBAAkB,CAAC;AAGxC,OAAO,KAAK,GAAG,MAAM,kBAAkB,CAAC;AAGxC,OAAO,KAAK,GAAG,MAAM,kBAAkB,CAAC;AAGxC,OAAO,KAAK,IAAI,MAAM,mBAAmB,CAAC;AAG1C,OAAO,KAAK,SAAS,MAAM,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,KAAK,MAAM,oBAAoB,CAAC;AAG5C,OAAO,KAAK,GAAG,MAAM,kBAAkB,CAAC;AAGxC,OAAO,KAAK,GAAG,MAAM,kBAAkB,CAAC;AAGxC,OAAO,KAAK,GAAG,MAAM,kBAAkB,CAAC;AAGxC,OAAO,KAAK,IAAI,MAAM,mBAAmB,CAAC;AAG1C,OAAO,KAAK,SAAS,MAAM,wBAAwB,CAAC;AAGpD,OAAO,KAAK,GAAG,MAAM,kBAAkB,CAAC"}
package/dist/index.js CHANGED
@@ -1,3 +1,9 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __export = (target, all) => {
3
+ for (var name in all)
4
+ __defProp(target, name, { get: all[name], enumerable: true });
5
+ };
6
+
1
7
  // src/index.ts
2
8
  import * as Utils from "@bis-toolkit/utils";
3
9
  import * as BCN from "@bis-toolkit/bcn";
@@ -5,7 +11,334 @@ import * as PAA from "@bis-toolkit/paa";
5
11
  import * as P3D from "@bis-toolkit/p3d";
6
12
  import * as EDDS from "@bis-toolkit/edds";
7
13
  import * as CPPParser from "@bis-toolkit/cppparser";
14
+
15
+ // ../anm/dist/index.js
16
+ var dist_exports = {};
17
+ __export(dist_exports, {
18
+ AnimationEntity: () => AnimationEntity,
19
+ DataEntity: () => DataEntity,
20
+ Entity: () => Entity,
21
+ EventsEntity: () => EventsEntity,
22
+ FpsEntity: () => FpsEntity,
23
+ HeadEntity: () => HeadEntity
24
+ });
25
+ var Entity = class {
26
+ constructor(parent) {
27
+ this.tagLen = 4;
28
+ this.expectedTag = [];
29
+ this.tag = "";
30
+ this.entrySize = 0;
31
+ this.dataOffset = 0;
32
+ this.parent = parent;
33
+ }
34
+ get Tag() {
35
+ return this.tag;
36
+ }
37
+ get EntrySize() {
38
+ return this.entrySize;
39
+ }
40
+ get DataOffset() {
41
+ return this.dataOffset;
42
+ }
43
+ /**
44
+ * Read entity from binary reader
45
+ */
46
+ read(br) {
47
+ this.dataOffset = br.pos;
48
+ this.tag = br.readRawString(this.tagLen).replace(/\0/g, "");
49
+ this.validateTag();
50
+ this.entrySize = br.readUInt32();
51
+ this.readData(br);
52
+ }
53
+ /**
54
+ * Validate that the tag matches expected tags
55
+ */
56
+ validateTag() {
57
+ if (this.expectedTag.length > 0 && !this.expectedTag.includes(this.tag)) {
58
+ throw new Error(`Invalid tag. Expected one of [${this.expectedTag.join(", ")}] but got '${this.tag}'`);
59
+ }
60
+ }
61
+ };
62
+ var FpsEntity = class extends Entity {
63
+ constructor(parent) {
64
+ super(parent);
65
+ this.fps = 0;
66
+ this.expectedTag = ["FPS"];
67
+ }
68
+ readData(br) {
69
+ this.fps = br.readInt32();
70
+ }
71
+ };
72
+ var HeadEntity = class extends Entity {
73
+ constructor(parent) {
74
+ super(parent);
75
+ this.bones = [];
76
+ this.expectedTag = ["HEAD"];
77
+ }
78
+ readData(br) {
79
+ if (!this.parent) {
80
+ throw new Error("HeadEntity requires a parent entity");
81
+ }
82
+ switch (this.parent.Tag) {
83
+ case "ANIMSET5":
84
+ this.read5(br);
85
+ break;
86
+ case "ANIMSET6":
87
+ this.read6(br);
88
+ break;
89
+ default:
90
+ throw new Error(`Unknown model type: ${this.parent.Tag}`);
91
+ }
92
+ }
93
+ read5(br) {
94
+ while (br.pos < this.entrySize + this.dataOffset) {
95
+ const name = br.readRawString(32).replace(/\0/g, "");
96
+ const translationBias = br.readFloat();
97
+ const translationMultiplier = br.readFloat();
98
+ const rotationBias = br.readFloat();
99
+ const rotationMultiplier = br.readFloat();
100
+ const numFrames = br.readUInt16();
101
+ const translationFrameCount = br.readUInt16();
102
+ const rotationFrameCount = br.readUInt16();
103
+ const flags = br.readUInt16();
104
+ this.bones.push({
105
+ name,
106
+ translationBias,
107
+ translationMultiplier,
108
+ rotationBias,
109
+ rotationMultiplier,
110
+ scaleBias: 0,
111
+ scaleMultiplier: 0,
112
+ numFrames,
113
+ translationFrameCount,
114
+ rotationFrameCount,
115
+ scaleFrameCount: 0,
116
+ flags
117
+ });
118
+ }
119
+ }
120
+ read6(br) {
121
+ while (br.pos < this.entrySize + this.dataOffset) {
122
+ const translationBias = br.readFloat();
123
+ const translationMultiplier = br.readFloat();
124
+ const rotationBias = br.readFloat();
125
+ const rotationMultiplier = br.readFloat();
126
+ const scaleBias = br.readFloat();
127
+ const scaleMultiplier = br.readFloat();
128
+ const numFrames = br.readUInt16();
129
+ const translationFrameCount = br.readUInt16();
130
+ const rotationFrameCount = br.readUInt16();
131
+ const scaleFrameCount = br.readUInt16();
132
+ const flags = br.readByte();
133
+ const nameLength = br.readByte();
134
+ const name = br.readRawString(nameLength).replace(/\0/g, "");
135
+ this.bones.push({
136
+ name,
137
+ translationBias,
138
+ translationMultiplier,
139
+ rotationBias,
140
+ rotationMultiplier,
141
+ scaleBias,
142
+ scaleMultiplier,
143
+ numFrames,
144
+ translationFrameCount,
145
+ rotationFrameCount,
146
+ scaleFrameCount,
147
+ flags
148
+ });
149
+ }
150
+ }
151
+ };
152
+ var RAD_PER_VAL = 1 / 65535;
153
+ var DataEntity = class extends Entity {
154
+ constructor(parent, headEntity) {
155
+ super(parent);
156
+ this.boneAnimations = /* @__PURE__ */ new Map();
157
+ this.expectedTag = ["DATA"];
158
+ this.headEntity = headEntity;
159
+ }
160
+ readData(br) {
161
+ if (!this.headEntity) {
162
+ throw new Error("DataEntity requires HeadEntity to be initialized");
163
+ }
164
+ for (const bone of this.headEntity.bones) {
165
+ const boneAnim = {
166
+ frameCount: bone.numFrames
167
+ };
168
+ this.readTranslations(br, bone, boneAnim);
169
+ this.readScales(br, bone, boneAnim);
170
+ this.readRotations(br, bone, boneAnim);
171
+ this.boneAnimations.set(bone.name, boneAnim);
172
+ }
173
+ }
174
+ readTranslations(br, boneHead, boneAnimation) {
175
+ if (boneHead.translationFrameCount <= 0) {
176
+ return;
177
+ }
178
+ boneAnimation.translations = /* @__PURE__ */ new Map();
179
+ const translationIds = [];
180
+ for (let i = 0; i < boneHead.translationFrameCount; i++) {
181
+ translationIds.push(br.readUInt16());
182
+ }
183
+ const multiplier = boneHead.translationMultiplier * RAD_PER_VAL;
184
+ for (let i = 0; i < boneHead.translationFrameCount; i++) {
185
+ const x = br.readUInt16() * multiplier + boneHead.translationBias;
186
+ const y = br.readUInt16() * multiplier + boneHead.translationBias;
187
+ const z = br.readUInt16() * multiplier + boneHead.translationBias;
188
+ boneAnimation.translations.set(translationIds[i], { x, y, z });
189
+ }
190
+ }
191
+ readRotations(br, boneHead, boneAnimation) {
192
+ if (boneHead.rotationFrameCount <= 0) {
193
+ return;
194
+ }
195
+ boneAnimation.rotations = /* @__PURE__ */ new Map();
196
+ const rotationIds = [];
197
+ for (let i = 0; i < boneHead.rotationFrameCount; i++) {
198
+ rotationIds.push(br.readUInt16());
199
+ }
200
+ const multiplier = boneHead.rotationMultiplier * RAD_PER_VAL;
201
+ for (let i = 0; i < boneHead.rotationFrameCount; i++) {
202
+ const x = br.readUInt16() * multiplier + boneHead.rotationBias;
203
+ const y = br.readUInt16() * multiplier + boneHead.rotationBias;
204
+ const z = br.readUInt16() * multiplier + boneHead.rotationBias;
205
+ const w = br.readUInt16() * multiplier + boneHead.rotationBias;
206
+ boneAnimation.rotations.set(rotationIds[i], { x, y, z, w });
207
+ }
208
+ }
209
+ readScales(br, boneHead, boneAnimation) {
210
+ if (boneHead.scaleFrameCount <= 0) {
211
+ return;
212
+ }
213
+ boneAnimation.scales = /* @__PURE__ */ new Map();
214
+ const scaleIds = [];
215
+ for (let i = 0; i < boneHead.scaleFrameCount; i++) {
216
+ scaleIds.push(br.readUInt16());
217
+ }
218
+ const multiplier = boneHead.scaleMultiplier * RAD_PER_VAL;
219
+ for (let i = 0; i < boneHead.scaleFrameCount; i++) {
220
+ const x = br.readUInt16() * multiplier + boneHead.scaleBias;
221
+ const y = br.readUInt16() * multiplier + boneHead.scaleBias;
222
+ const z = br.readUInt16() * multiplier + boneHead.scaleBias;
223
+ boneAnimation.scales.set(scaleIds[i], { x, y, z });
224
+ }
225
+ }
226
+ };
227
+ var EventsEntity = class extends Entity {
228
+ constructor(parent) {
229
+ super(parent);
230
+ this.animEvents = [];
231
+ this.expectedTag = ["EVNT"];
232
+ }
233
+ readData(br) {
234
+ const count = br.readUInt16();
235
+ for (let i = 0; i < count; i++) {
236
+ const frame = br.readInt32();
237
+ const nameLength = br.readInt32();
238
+ const name = br.readRawString(nameLength).replace(/\0/g, "");
239
+ const unkValue1Length = br.readInt32();
240
+ const unkValue1 = br.readRawString(unkValue1Length).replace(/\0/g, "");
241
+ const unkValue2 = br.readInt32();
242
+ this.animEvents.push({
243
+ frame,
244
+ name,
245
+ unkValue1,
246
+ unkValue2
247
+ });
248
+ }
249
+ }
250
+ };
251
+ var AnimationEntity = class extends Entity {
252
+ constructor(parent) {
253
+ super(parent);
254
+ this.tagLen = 8;
255
+ this.expectedTag = ["ANIMSET5", "ANIMSET6"];
256
+ }
257
+ validateTag() {
258
+ }
259
+ readData(br) {
260
+ this.fps = new FpsEntity(this);
261
+ this.fps.read(br);
262
+ this.head = new HeadEntity(this);
263
+ this.head.read(br);
264
+ this.data = new DataEntity(this, this.head);
265
+ this.data.read(br);
266
+ this.events = new EventsEntity(this);
267
+ this.events.read(br);
268
+ }
269
+ /**
270
+ * Create a new animation from scratch
271
+ * @param data - Map of bone name to animation data
272
+ * @param events - Array of animation events
273
+ * @param fps - Frames per second
274
+ */
275
+ create(data, events, fps) {
276
+ this.tag = "ANIMSET6";
277
+ this.fps = new FpsEntity(this);
278
+ this.fps.fps = fps;
279
+ this.head = new HeadEntity(this);
280
+ for (const [boneName, anim] of Object.entries(data)) {
281
+ const bone = {
282
+ name: boneName,
283
+ translationFrameCount: anim.translations?.size ?? 0,
284
+ rotationFrameCount: anim.rotations?.size ?? 0,
285
+ scaleFrameCount: anim.scales?.size ?? 0,
286
+ numFrames: anim.frameCount,
287
+ flags: 0,
288
+ translationBias: 0,
289
+ translationMultiplier: 0,
290
+ rotationBias: 0,
291
+ rotationMultiplier: 0,
292
+ scaleBias: 0,
293
+ scaleMultiplier: 0
294
+ };
295
+ if (anim.translations && anim.translations.size > 0) {
296
+ const [min, max] = this.findMinMaxVector3(anim.translations);
297
+ bone.translationBias = min;
298
+ bone.translationMultiplier = this.getMultiplier(min, max);
299
+ }
300
+ if (anim.rotations && anim.rotations.size > 0) {
301
+ const [min, max] = this.findMinMaxQuaternion(anim.rotations);
302
+ bone.rotationBias = min;
303
+ bone.rotationMultiplier = this.getMultiplier(min, max);
304
+ }
305
+ if (anim.scales && anim.scales.size > 0) {
306
+ const [min, max] = this.findMinMaxVector3(anim.scales);
307
+ bone.scaleBias = min;
308
+ bone.scaleMultiplier = this.getMultiplier(min, max);
309
+ }
310
+ this.head.bones.push(bone);
311
+ }
312
+ this.data = new DataEntity(this, this.head);
313
+ for (const [boneName, anim] of Object.entries(data)) {
314
+ this.data.boneAnimations.set(boneName, anim);
315
+ }
316
+ if (events.length > 0) {
317
+ this.events = new EventsEntity(this);
318
+ this.events.animEvents = events;
319
+ }
320
+ }
321
+ getMultiplier(min, max) {
322
+ const epsilon = 9999999974752427e-22;
323
+ return Math.abs(max - min) < epsilon ? 1 : max - min;
324
+ }
325
+ findMinMaxVector3(collection) {
326
+ const values = [];
327
+ for (const v of collection.values()) {
328
+ values.push(v.x, v.y, v.z);
329
+ }
330
+ return [Math.min(...values), Math.max(...values)];
331
+ }
332
+ findMinMaxQuaternion(collection) {
333
+ const values = [];
334
+ for (const q of collection.values()) {
335
+ values.push(q.x, q.y, q.z, q.w);
336
+ }
337
+ return [Math.min(...values), Math.max(...values)];
338
+ }
339
+ };
8
340
  export {
341
+ dist_exports as ANM,
9
342
  BCN,
10
343
  CPPParser,
11
344
  EDDS,
package/dist/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/index.ts"],
4
- "sourcesContent": ["/**\n * Alpine Labs - Complete TypeScript library suite\n * \n * This package provides convenient access to all Alpine Labs libraries\n * for Bohemia Interactive game modding (Arma, DayZ).\n */\n\n// Re-export all utilities\nexport * as Utils from '@bis-toolkit/utils';\n\n// Re-export block compression codecs\nexport * as BCN from '@bis-toolkit/bcn';\n\n// Re-export PAA texture format\nexport * as PAA from '@bis-toolkit/paa';\n\n// Re-export P3D model formats (MLOD and ODOL)\nexport * as P3D from '@bis-toolkit/p3d';\n\n// Re-export EDDS texture format\nexport * as EDDS from '@bis-toolkit/edds';\n\n// Re-export C++ parser\nexport * as CPPParser from '@bis-toolkit/cppparser';\n"],
5
- "mappings": ";AAQA,YAAY,WAAW;AAGvB,YAAY,SAAS;AAGrB,YAAY,SAAS;AAGrB,YAAY,SAAS;AAGrB,YAAY,UAAU;AAGtB,YAAY,eAAe;",
3
+ "sources": ["../src/index.ts", "../../anm/src/Entity.ts", "../../anm/src/entities/FpsEntity.ts", "../../anm/src/entities/HeadEntity.ts", "../../anm/src/entities/DataEntity.ts", "../../anm/src/entities/EventsEntity.ts", "../../anm/src/entities/AnimationEntity.ts"],
4
+ "sourcesContent": ["/**\n * Alpine Labs - Complete TypeScript library suite\n * \n * This package provides convenient access to all Alpine Labs libraries\n * for Bohemia Interactive game modding (Arma, DayZ).\n */\n\n// Re-export all utilities\nexport * as Utils from '@bis-toolkit/utils';\n\n// Re-export block compression codecs\nexport * as BCN from '@bis-toolkit/bcn';\n\n// Re-export PAA texture format\nexport * as PAA from '@bis-toolkit/paa';\n\n// Re-export P3D model formats (MLOD and ODOL)\nexport * as P3D from '@bis-toolkit/p3d';\n\n// Re-export EDDS texture format\nexport * as EDDS from '@bis-toolkit/edds';\n\n// Re-export C++ parser\nexport * as CPPParser from '@bis-toolkit/cppparser';\n\n// Re-export ANM animation format\nexport * as ANM from '@bis-toolkit/anm';", "import { BinaryReader } from '@bis-toolkit/utils';\n\n/**\n * Base entity class for reading binary data structures\n */\nexport abstract class Entity {\n protected tagLen = 4;\n protected expectedTag: string[] = [];\n protected tag = '';\n protected entrySize = 0;\n protected dataOffset = 0;\n \n public parent?: Entity;\n\n constructor(parent?: Entity) {\n this.parent = parent;\n }\n\n get Tag(): string {\n return this.tag;\n }\n\n get EntrySize(): number {\n return this.entrySize;\n }\n\n get DataOffset(): number {\n return this.dataOffset;\n }\n\n /**\n * Read entity from binary reader\n */\n read(br: BinaryReader): void {\n this.dataOffset = br.pos;\n this.tag = br.readRawString(this.tagLen).replace(/\\0/g, '');\n this.validateTag();\n this.entrySize = br.readUInt32();\n this.readData(br);\n }\n\n /**\n * Validate that the tag matches expected tags\n */\n protected validateTag(): void {\n if (this.expectedTag.length > 0 && !this.expectedTag.includes(this.tag)) {\n throw new Error(`Invalid tag. Expected one of [${this.expectedTag.join(', ')}] but got '${this.tag}'`);\n }\n }\n\n /**\n * Read entity-specific data\n */\n protected abstract readData(br: BinaryReader): void;\n}\n", "import { BinaryReader } from '@bis-toolkit/utils';\nimport { Entity } from '../Entity';\n\n/**\n * FPS entity - stores the frames per second of the animation\n */\nexport class FpsEntity extends Entity {\n public fps = 0;\n\n constructor(parent?: Entity) {\n super(parent);\n this.expectedTag = ['FPS'];\n }\n\n protected readData(br: BinaryReader): void {\n this.fps = br.readInt32();\n }\n}\n", "import { BinaryReader } from '@bis-toolkit/utils';\nimport { Entity } from '../Entity';\nimport { BoneHead } from '../types';\n\n/**\n * Head entity - stores bone header information\n */\nexport class HeadEntity extends Entity {\n public bones: BoneHead[] = [];\n\n constructor(parent?: Entity) {\n super(parent);\n this.expectedTag = ['HEAD'];\n }\n\n protected readData(br: BinaryReader): void {\n if (!this.parent) {\n throw new Error('HeadEntity requires a parent entity');\n }\n\n switch (this.parent.Tag) {\n case 'ANIMSET5':\n this.read5(br);\n break;\n case 'ANIMSET6':\n this.read6(br);\n break;\n default:\n throw new Error(`Unknown model type: ${this.parent.Tag}`);\n }\n }\n\n private read5(br: BinaryReader): void {\n while (br.pos < this.entrySize + this.dataOffset) {\n const name = br.readRawString(32).replace(/\\0/g, '');\n const translationBias = br.readFloat();\n const translationMultiplier = br.readFloat();\n const rotationBias = br.readFloat();\n const rotationMultiplier = br.readFloat();\n const numFrames = br.readUInt16();\n const translationFrameCount = br.readUInt16();\n const rotationFrameCount = br.readUInt16();\n const flags = br.readUInt16();\n\n this.bones.push({\n name,\n translationBias,\n translationMultiplier,\n rotationBias,\n rotationMultiplier,\n scaleBias: 0,\n scaleMultiplier: 0,\n numFrames,\n translationFrameCount,\n rotationFrameCount,\n scaleFrameCount: 0,\n flags\n });\n }\n }\n\n private read6(br: BinaryReader): void {\n while (br.pos < this.entrySize + this.dataOffset) {\n const translationBias = br.readFloat();\n const translationMultiplier = br.readFloat();\n const rotationBias = br.readFloat();\n const rotationMultiplier = br.readFloat();\n const scaleBias = br.readFloat();\n const scaleMultiplier = br.readFloat();\n const numFrames = br.readUInt16();\n const translationFrameCount = br.readUInt16();\n const rotationFrameCount = br.readUInt16();\n const scaleFrameCount = br.readUInt16();\n const flags = br.readByte();\n const nameLength = br.readByte();\n const name = br.readRawString(nameLength).replace(/\\0/g, '');\n\n this.bones.push({\n name,\n translationBias,\n translationMultiplier,\n rotationBias,\n rotationMultiplier,\n scaleBias,\n scaleMultiplier,\n numFrames,\n translationFrameCount,\n rotationFrameCount,\n scaleFrameCount,\n flags\n });\n }\n }\n}\n", "import { BinaryReader } from '@bis-toolkit/utils';\nimport { Entity } from '../Entity';\nimport { BoneHead, BoneAnimation } from '../types';\nimport { HeadEntity } from './HeadEntity';\n\nconst RAD_PER_VAL = 1.0 / 65535; // ushort.MaxValue\n\n/**\n * Data entity - stores the actual animation data (translations, rotations, scales)\n */\nexport class DataEntity extends Entity {\n public boneAnimations = new Map<string, BoneAnimation>();\n private headEntity?: HeadEntity;\n\n constructor(parent?: Entity, headEntity?: HeadEntity) {\n super(parent);\n this.expectedTag = ['DATA'];\n this.headEntity = headEntity;\n }\n\n protected readData(br: BinaryReader): void {\n if (!this.headEntity) {\n throw new Error('DataEntity requires HeadEntity to be initialized');\n }\n\n for (const bone of this.headEntity.bones) {\n const boneAnim: BoneAnimation = {\n frameCount: bone.numFrames\n };\n \n this.readTranslations(br, bone, boneAnim);\n this.readScales(br, bone, boneAnim);\n this.readRotations(br, bone, boneAnim);\n \n this.boneAnimations.set(bone.name, boneAnim);\n }\n }\n\n private readTranslations(br: BinaryReader, boneHead: BoneHead, boneAnimation: BoneAnimation): void {\n if (boneHead.translationFrameCount <= 0) {\n return;\n }\n\n boneAnimation.translations = new Map();\n\n const translationIds: number[] = [];\n for (let i = 0; i < boneHead.translationFrameCount; i++) {\n translationIds.push(br.readUInt16());\n }\n\n const multiplier = boneHead.translationMultiplier * RAD_PER_VAL;\n\n for (let i = 0; i < boneHead.translationFrameCount; i++) {\n const x = br.readUInt16() * multiplier + boneHead.translationBias;\n const y = br.readUInt16() * multiplier + boneHead.translationBias;\n const z = br.readUInt16() * multiplier + boneHead.translationBias;\n\n boneAnimation.translations.set(translationIds[i], { x, y, z });\n }\n }\n\n private readRotations(br: BinaryReader, boneHead: BoneHead, boneAnimation: BoneAnimation): void {\n if (boneHead.rotationFrameCount <= 0) {\n return;\n }\n\n boneAnimation.rotations = new Map();\n\n const rotationIds: number[] = [];\n for (let i = 0; i < boneHead.rotationFrameCount; i++) {\n rotationIds.push(br.readUInt16());\n }\n\n const multiplier = boneHead.rotationMultiplier * RAD_PER_VAL;\n\n for (let i = 0; i < boneHead.rotationFrameCount; i++) {\n const x = br.readUInt16() * multiplier + boneHead.rotationBias;\n const y = br.readUInt16() * multiplier + boneHead.rotationBias;\n const z = br.readUInt16() * multiplier + boneHead.rotationBias;\n const w = br.readUInt16() * multiplier + boneHead.rotationBias;\n\n boneAnimation.rotations.set(rotationIds[i], { x, y, z, w });\n }\n }\n\n private readScales(br: BinaryReader, boneHead: BoneHead, boneAnimation: BoneAnimation): void {\n if (boneHead.scaleFrameCount <= 0) {\n return;\n }\n\n boneAnimation.scales = new Map();\n\n const scaleIds: number[] = [];\n for (let i = 0; i < boneHead.scaleFrameCount; i++) {\n scaleIds.push(br.readUInt16());\n }\n\n const multiplier = boneHead.scaleMultiplier * RAD_PER_VAL;\n\n for (let i = 0; i < boneHead.scaleFrameCount; i++) {\n const x = br.readUInt16() * multiplier + boneHead.scaleBias;\n const y = br.readUInt16() * multiplier + boneHead.scaleBias;\n const z = br.readUInt16() * multiplier + boneHead.scaleBias;\n\n boneAnimation.scales.set(scaleIds[i], { x, y, z });\n }\n }\n}\n", "import { BinaryReader } from '@bis-toolkit/utils';\nimport { Entity } from '../Entity';\nimport { AnimEvent } from '../types';\n\n/**\n * Events entity - stores animation events\n */\nexport class EventsEntity extends Entity {\n public animEvents: AnimEvent[] = [];\n\n constructor(parent?: Entity) {\n super(parent);\n this.expectedTag = ['EVNT'];\n }\n\n protected readData(br: BinaryReader): void {\n const count = br.readUInt16();\n for (let i = 0; i < count; i++) {\n const frame = br.readInt32();\n const nameLength = br.readInt32();\n const name = br.readRawString(nameLength).replace(/\\0/g, '');\n const unkValue1Length = br.readInt32();\n const unkValue1 = br.readRawString(unkValue1Length).replace(/\\0/g, '');\n const unkValue2 = br.readInt32();\n \n this.animEvents.push({\n frame,\n name,\n unkValue1,\n unkValue2\n });\n }\n }\n}\n", "import { BinaryReader } from '@bis-toolkit/utils';\nimport { Entity } from '../Entity';\nimport { BoneAnimation, AnimEvent, BoneHead, Vector3, Quaternion } from '../types';\nimport { FpsEntity } from './FpsEntity';\nimport { HeadEntity } from './HeadEntity';\nimport { DataEntity } from './DataEntity';\nimport { EventsEntity } from './EventsEntity';\n\n/**\n * Main animation entity containing FPS, bone headers, animation data, and events\n */\nexport class AnimationEntity extends Entity {\n public fps?: FpsEntity;\n public head?: HeadEntity;\n public data?: DataEntity;\n public events?: EventsEntity;\n\n constructor(parent?: Entity) {\n super(parent);\n this.tagLen = 8;\n this.expectedTag = ['ANIMSET5', 'ANIMSET6'];\n }\n\n protected validateTag(): void {\n // Override to allow any tag (we'll validate in readData if needed)\n }\n\n protected readData(br: BinaryReader): void {\n this.fps = new FpsEntity(this);\n this.fps.read(br);\n\n this.head = new HeadEntity(this);\n this.head.read(br);\n\n this.data = new DataEntity(this, this.head);\n this.data.read(br);\n\n this.events = new EventsEntity(this);\n this.events.read(br);\n }\n\n /**\n * Create a new animation from scratch\n * @param data - Map of bone name to animation data\n * @param events - Array of animation events\n * @param fps - Frames per second\n */\n create(data: Record<string, BoneAnimation>, events: AnimEvent[], fps: number): void {\n this.tag = 'ANIMSET6'; // Default to ANIMSET6 which supports scale\n \n this.fps = new FpsEntity(this);\n this.fps.fps = fps;\n\n this.head = new HeadEntity(this);\n for (const [boneName, anim] of Object.entries(data)) {\n const bone: BoneHead = {\n name: boneName,\n translationFrameCount: anim.translations?.size ?? 0,\n rotationFrameCount: anim.rotations?.size ?? 0,\n scaleFrameCount: anim.scales?.size ?? 0,\n numFrames: anim.frameCount,\n flags: 0,\n translationBias: 0,\n translationMultiplier: 0,\n rotationBias: 0,\n rotationMultiplier: 0,\n scaleBias: 0,\n scaleMultiplier: 0\n };\n\n if (anim.translations && anim.translations.size > 0) {\n const [min, max] = this.findMinMaxVector3(anim.translations);\n bone.translationBias = min;\n bone.translationMultiplier = this.getMultiplier(min, max);\n }\n\n if (anim.rotations && anim.rotations.size > 0) {\n const [min, max] = this.findMinMaxQuaternion(anim.rotations);\n bone.rotationBias = min;\n bone.rotationMultiplier = this.getMultiplier(min, max);\n }\n\n if (anim.scales && anim.scales.size > 0) {\n const [min, max] = this.findMinMaxVector3(anim.scales);\n bone.scaleBias = min;\n bone.scaleMultiplier = this.getMultiplier(min, max);\n }\n\n this.head.bones.push(bone);\n }\n\n this.data = new DataEntity(this, this.head);\n for (const [boneName, anim] of Object.entries(data)) {\n this.data.boneAnimations.set(boneName, anim);\n }\n\n if (events.length > 0) {\n this.events = new EventsEntity(this);\n this.events.animEvents = events;\n }\n }\n\n private getMultiplier(min: number, max: number): number {\n const epsilon = 9.9999999747524271e-7;\n return Math.abs(max - min) < epsilon ? 1.0 : max - min;\n }\n\n private findMinMaxVector3(collection: Map<number, Vector3>): [number, number] {\n const values: number[] = [];\n for (const v of collection.values()) {\n values.push(v.x, v.y, v.z);\n }\n return [Math.min(...values), Math.max(...values)];\n }\n\n private findMinMaxQuaternion(collection: Map<number, Quaternion>): [number, number] {\n const values: number[] = [];\n for (const q of collection.values()) {\n values.push(q.x, q.y, q.z, q.w);\n }\n return [Math.min(...values), Math.max(...values)];\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bis-toolkit",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Complete Alpine Labs TypeScript library suite for DayZ game modding",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -40,6 +40,15 @@
40
40
  ],
41
41
  "author": "Alpine Labs",
42
42
  "license": "GPL-3.0-or-later",
43
+ "repository": {
44
+ "type": "git",
45
+ "url": "https://github.com/Koncord/BIS-Toolkit.git",
46
+ "directory": "packages/bis-toolkit"
47
+ },
48
+ "bugs": {
49
+ "url": "https://github.com/Koncord/BIS-Toolkit/issues"
50
+ },
51
+ "homepage": "https://github.com/Koncord/BIS-Toolkit#readme",
43
52
  "devDependencies": {
44
53
  "@typescript-eslint/eslint-plugin": "^8.52.0",
45
54
  "@typescript-eslint/parser": "^8.52.0",
@@ -49,11 +58,12 @@
49
58
  "typescript-eslint": "^8.52.0"
50
59
  },
51
60
  "dependencies": {
52
- "@bis-toolkit/bcn": "^1.0.0",
53
- "@bis-toolkit/cppparser": "^1.0.0",
54
- "@bis-toolkit/edds": "^1.0.0",
55
- "@bis-toolkit/p3d": "^1.0.0",
56
- "@bis-toolkit/paa": "^1.0.0",
57
- "@bis-toolkit/utils": "^1.0.0"
61
+ "@bis-toolkit/anm": "^1.0.2",
62
+ "@bis-toolkit/bcn": "^1.0.2",
63
+ "@bis-toolkit/cppparser": "^1.0.2",
64
+ "@bis-toolkit/edds": "^1.0.2",
65
+ "@bis-toolkit/p3d": "^1.0.2",
66
+ "@bis-toolkit/paa": "^1.0.2",
67
+ "@bis-toolkit/utils": "^1.0.2"
58
68
  }
59
69
  }