@carbonenginejs/runtime-resource 0.8.0 → 0.9.1

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.
Files changed (297) hide show
  1. package/LICENSE +21 -21
  2. package/NOTICE +31 -29
  3. package/README.md +67 -548
  4. package/dist/CjsMotherLode.js +1271 -1271
  5. package/dist/CjsResMan.js +3005 -3005
  6. package/dist/CjsResManQueue.js +214 -214
  7. package/dist/CjsResource.js +566 -566
  8. package/dist/CjsResourceSource.js +68 -59
  9. package/dist/CjsResourceSource.js.map +1 -1
  10. package/dist/_virtual/_rollupPluginBabelHelpers.js +153 -153
  11. package/dist/format/CjsBlueReader.js +269 -269
  12. package/dist/format/CjsFormat.js +197 -192
  13. package/dist/format/CjsFormat.js.map +1 -1
  14. package/dist/format/CjsReader.js +18 -18
  15. package/dist/format/CjsResourceProbe.js +277 -277
  16. package/dist/format/payloadContract.js +173 -173
  17. package/dist/formats/black/CjsBlackFormat.js +278 -278
  18. package/dist/formats/black/core/CjsBlackBinaryReader.js +157 -153
  19. package/dist/formats/black/core/CjsBlackBinaryReader.js.map +1 -1
  20. package/dist/formats/black/core/CjsBlackPropertyReaders.js +387 -382
  21. package/dist/formats/black/core/CjsBlackPropertyReaders.js.map +1 -1
  22. package/dist/formats/black/core/CjsBlackReader.js +639 -639
  23. package/dist/formats/black/core/CjsBlackSchemaRegistry.js +437 -433
  24. package/dist/formats/black/core/CjsBlackSchemaRegistry.js.map +1 -1
  25. package/dist/formats/black/core/black-schema-v1-2026-07-23.json.js +4 -0
  26. package/dist/formats/black/core/black-schema-v1-2026-07-23.json.js.map +1 -0
  27. package/dist/formats/black/core/blackConstants.js +7 -7
  28. package/dist/formats/black/core/blackDefinitions.js +10 -10
  29. package/dist/formats/black/core/blackDefinitions.js.map +1 -1
  30. package/dist/formats/black/core/blackEnums.js +6 -6
  31. package/dist/formats/black/core/blackSchema.js +3 -3
  32. package/dist/formats/black/core/blackVersion.js +22 -22
  33. package/dist/formats/black/core/helpers.js +182 -182
  34. package/dist/formats/black/core/schema.js +4 -4
  35. package/dist/formats/black/index.js +2 -2
  36. package/dist/formats/bnk/CjsBnkFormat.js +125 -125
  37. package/dist/formats/bnk/core/graph.js +140 -140
  38. package/dist/formats/bnk/core/helpers.js +409 -409
  39. package/dist/formats/bnk/core/musicNodes.js +493 -489
  40. package/dist/formats/bnk/core/musicNodes.js.map +1 -1
  41. package/dist/formats/bnk/core/soundbanksInfo.js +246 -246
  42. package/dist/formats/bnk/index.js +2 -2
  43. package/dist/formats/cmf/CjsCmfFormat.js +497 -497
  44. package/dist/formats/cmf/core/binary.js +123 -118
  45. package/dist/formats/cmf/core/binary.js.map +1 -1
  46. package/dist/formats/cmf/core/buffers.js +233 -233
  47. package/dist/formats/cmf/core/constants.js +47 -47
  48. package/dist/formats/cmf/core/gr2Anim.js +453 -453
  49. package/dist/formats/cmf/core/helpers.js +287 -287
  50. package/dist/formats/cmf/core/pack.js +276 -276
  51. package/dist/formats/cmf/core/schema.js +364 -364
  52. package/dist/formats/cmf/core/shared.js +268 -268
  53. package/dist/formats/cmf/core/writer.js +517 -517
  54. package/dist/formats/cmf/index.js +2 -2
  55. package/dist/formats/dds/CjsDdsFormat.js +200 -193
  56. package/dist/formats/dds/CjsDdsFormat.js.map +1 -1
  57. package/dist/formats/dds/core/bc6h.js +288 -288
  58. package/dist/formats/dds/core/bc7.js +256 -251
  59. package/dist/formats/dds/core/bc7.js.map +1 -1
  60. package/dist/formats/dds/core/helpers.js +815 -815
  61. package/dist/formats/dds/index.js +2 -2
  62. package/dist/formats/fbx/CjsFbxFormat.js +266 -266
  63. package/dist/formats/fbx/core/helpers.js +3911 -3901
  64. package/dist/formats/fbx/core/helpers.js.map +1 -1
  65. package/dist/formats/fbx/index.js +2 -2
  66. package/dist/formats/flac/CjsFlacFormat.js +93 -87
  67. package/dist/formats/flac/CjsFlacFormat.js.map +1 -1
  68. package/dist/formats/flac/core/helpers.js +295 -295
  69. package/dist/formats/flac/index.js +2 -2
  70. package/dist/formats/gif/CjsGifFormat.js +92 -87
  71. package/dist/formats/gif/CjsGifFormat.js.map +1 -1
  72. package/dist/formats/gif/core/helpers.js +360 -360
  73. package/dist/formats/gif/index.js +2 -2
  74. package/dist/formats/gltf/CjsGltfFormat.js +290 -290
  75. package/dist/formats/gltf/core/helpers.js +292 -292
  76. package/dist/formats/gltf/core/json.js +79 -79
  77. package/dist/formats/gltf/core/parser.js +666 -666
  78. package/dist/formats/gltf/core/targets.js +163 -163
  79. package/dist/formats/gltf/index.js +2 -2
  80. package/dist/formats/gr2/CjsGr2Format.js +46 -0
  81. package/dist/formats/gr2/CjsGr2Format.js.map +1 -0
  82. package/dist/formats/gr2/core/CjsFormatGr2.js +273 -0
  83. package/dist/formats/gr2/core/CjsFormatGr2.js.map +1 -0
  84. package/dist/formats/gr2/core/bitknit2.js +280 -0
  85. package/dist/formats/gr2/core/bitknit2.js.map +1 -0
  86. package/dist/formats/gr2/core/curves.js +1047 -0
  87. package/dist/formats/gr2/core/curves.js.map +1 -0
  88. package/dist/formats/gr2/core/gsf.js +72 -0
  89. package/dist/formats/gr2/core/gsf.js.map +1 -0
  90. package/dist/formats/gr2/core/helpers.js +332 -0
  91. package/dist/formats/gr2/core/helpers.js.map +1 -0
  92. package/dist/formats/gr2/core/json.js +622 -0
  93. package/dist/formats/gr2/core/json.js.map +1 -0
  94. package/dist/formats/gr2/core/oodle1.js +388 -0
  95. package/dist/formats/gr2/core/oodle1.js.map +1 -0
  96. package/dist/formats/gr2/core/reader.js +617 -0
  97. package/dist/formats/gr2/core/reader.js.map +1 -0
  98. package/dist/formats/gr2/core/tangents.js +48 -0
  99. package/dist/formats/gr2/core/tangents.js.map +1 -0
  100. package/dist/formats/gr2/core/targets.js +351 -0
  101. package/dist/formats/gr2/core/targets.js.map +1 -0
  102. package/dist/formats/gr2/index.js +3 -0
  103. package/dist/formats/gr2/index.js.map +1 -0
  104. package/dist/formats/index.js +30 -23
  105. package/dist/formats/index.js.map +1 -1
  106. package/dist/formats/jpeg/CjsJpegFormat.js +212 -206
  107. package/dist/formats/jpeg/CjsJpegFormat.js.map +1 -1
  108. package/dist/formats/jpeg/core/helpers.js +350 -350
  109. package/dist/formats/jpeg/core/jpeg.js +387 -377
  110. package/dist/formats/jpeg/core/jpeg.js.map +1 -1
  111. package/dist/formats/jpeg/index.js +2 -2
  112. package/dist/formats/mp3/CjsMp3Format.js +197 -192
  113. package/dist/formats/mp3/CjsMp3Format.js.map +1 -1
  114. package/dist/formats/mp3/core/helpers.js +338 -338
  115. package/dist/formats/mp3/index.js +2 -2
  116. package/dist/formats/mp4/CjsMp4Format.js +197 -191
  117. package/dist/formats/mp4/CjsMp4Format.js.map +1 -1
  118. package/dist/formats/mp4/core/helpers.js +449 -449
  119. package/dist/formats/mp4/index.js +2 -2
  120. package/dist/formats/obj/CjsObjFormat.js +253 -253
  121. package/dist/formats/obj/core/helpers.js +573 -573
  122. package/dist/formats/obj/core/json.js +64 -64
  123. package/dist/formats/obj/core/parser.js +321 -321
  124. package/dist/formats/obj/index.js +2 -2
  125. package/dist/formats/ogg/CjsOggFormat.js +94 -88
  126. package/dist/formats/ogg/CjsOggFormat.js.map +1 -1
  127. package/dist/formats/ogg/core/helpers.js +387 -387
  128. package/dist/formats/ogg/core/imdct.js +178 -178
  129. package/dist/formats/ogg/core/vorbis.js +1004 -999
  130. package/dist/formats/ogg/core/vorbis.js.map +1 -1
  131. package/dist/formats/ogg/index.js +2 -2
  132. package/dist/formats/png/CjsPngFormat.js +201 -195
  133. package/dist/formats/png/CjsPngFormat.js.map +1 -1
  134. package/dist/formats/png/core/helpers.js +583 -583
  135. package/dist/formats/png/index.js +2 -2
  136. package/dist/formats/red/CjsRedFormat.js +261 -261
  137. package/dist/formats/red/core/CjsRedReader.js +194 -194
  138. package/dist/formats/red/core/blackDefinitions.js +3 -3
  139. package/dist/formats/red/core/helpers.js +139 -139
  140. package/dist/formats/red/core/redGraph.js +68 -68
  141. package/dist/formats/red/core/schema.js +4 -4
  142. package/dist/formats/red/index.js +2 -2
  143. package/dist/formats/stl/CjsStlFormat.js +365 -365
  144. package/dist/formats/stl/core/helpers.js +261 -261
  145. package/dist/formats/stl/core/json.js +51 -51
  146. package/dist/formats/stl/core/stl.js +634 -629
  147. package/dist/formats/stl/core/stl.js.map +1 -1
  148. package/dist/formats/stl/core/targets.js +163 -163
  149. package/dist/formats/stl/index.js +2 -2
  150. package/dist/formats/tga/CjsTgaFormat.js +197 -192
  151. package/dist/formats/tga/CjsTgaFormat.js.map +1 -1
  152. package/dist/formats/tga/core/helpers.js +446 -446
  153. package/dist/formats/tga/index.js +2 -2
  154. package/dist/formats/wav/CjsWavFormat.js +198 -192
  155. package/dist/formats/wav/CjsWavFormat.js.map +1 -1
  156. package/dist/formats/wav/core/helpers.js +328 -328
  157. package/dist/formats/wav/index.js +2 -2
  158. package/dist/formats/webm/CjsWebmFormat.js +197 -191
  159. package/dist/formats/webm/CjsWebmFormat.js.map +1 -1
  160. package/dist/formats/webm/core/helpers.js +537 -537
  161. package/dist/formats/webm/index.js +2 -2
  162. package/dist/formats/webp/CjsWebpFormat.js +91 -86
  163. package/dist/formats/webp/CjsWebpFormat.js.map +1 -1
  164. package/dist/formats/webp/core/helpers.js +214 -214
  165. package/dist/formats/webp/index.js +2 -2
  166. package/dist/formats/wem/CjsWemFormat.js +242 -241
  167. package/dist/formats/wem/CjsWemFormat.js.map +1 -1
  168. package/dist/formats/wem/core/bitStream.js +259 -259
  169. package/dist/formats/wem/core/codebookLibrary.js +164 -164
  170. package/dist/formats/wem/core/helpers.js +417 -417
  171. package/dist/formats/wem/core/packedCodebooksAotuv603.js +30 -30
  172. package/dist/formats/wem/core/ptadpcm.js +77 -77
  173. package/dist/formats/wem/core/resolve.js +121 -121
  174. package/dist/formats/wem/core/wemToOgg.js +485 -485
  175. package/dist/formats/wem/index.js +2 -2
  176. package/dist/formats/yaml/CjsYamlFormat.js +89 -83
  177. package/dist/formats/yaml/CjsYamlFormat.js.map +1 -1
  178. package/dist/formats/yaml/core/CjsYamlReader.js +311 -305
  179. package/dist/formats/yaml/core/CjsYamlReader.js.map +1 -1
  180. package/dist/formats/yaml/core/helpers.js +160 -160
  181. package/dist/formats/yaml/index.js +2 -2
  182. package/dist/index.js +49 -48
  183. package/dist/index.js.map +1 -1
  184. package/dist/resourcePath.js +18 -18
  185. package/dist/resourceStates.js +9 -9
  186. package/dist/resources/AudioGeometryResData.js +47 -47
  187. package/dist/resources/GStateBindingCallbackData.js +31 -31
  188. package/dist/resources/MeshDecalData.js +37 -37
  189. package/dist/resources/MeshDecalLodData.js +34 -34
  190. package/dist/resources/Tr2EffectRes.js +71 -71
  191. package/dist/resources/Tr2GrannyIntersectionResult.js +60 -60
  192. package/dist/resources/Tr2GrannyStateRes.js +44 -44
  193. package/dist/resources/Tr2ImageRes.js +114 -114
  194. package/dist/resources/Tr2LightProfileRes.js +40 -40
  195. package/dist/resources/Tr2MaterialArea.js +34 -34
  196. package/dist/resources/Tr2MaterialMesh.js +31 -31
  197. package/dist/resources/Tr2MaterialRes.js +34 -34
  198. package/dist/resources/Tr2ShaderPermutation.js +43 -43
  199. package/dist/resources/Tr2TextureLodManager.js +80 -80
  200. package/dist/resources/Tr2TextureLodUpdateRequest.js +37 -37
  201. package/dist/resources/Tr2TexturePackChannel.js +37 -37
  202. package/dist/resources/Tr2TexturePipeline.js +52 -52
  203. package/dist/resources/Tr2TexturePipelineParams.js +34 -34
  204. package/dist/resources/Tr2TexturePipelineStepCompress.js +40 -40
  205. package/dist/resources/Tr2TexturePipelineStepGenerateMips.js +22 -0
  206. package/dist/resources/Tr2TexturePipelineStepGenerateMips.js.map +1 -0
  207. package/dist/resources/Tr2TexturePipelineStepLimitSize.js +34 -34
  208. package/dist/resources/Tr2TexturePipelineStepLoad.js +31 -31
  209. package/dist/resources/Tr2TexturePipelineStepPack.js +43 -43
  210. package/dist/resources/TriGeometryRes.js +239 -239
  211. package/dist/resources/TriGeometryResAreaData.js +59 -59
  212. package/dist/resources/TriGeometryResJointData.js +38 -38
  213. package/dist/resources/TriGeometryResLodData.js +88 -88
  214. package/dist/resources/TriGeometryResMeshData.js +63 -63
  215. package/dist/resources/TriGeometryResSkeletonData.js +34 -34
  216. package/dist/resources/TriGrannyRes.js +43 -43
  217. package/dist/resources/TriJointBinding.js +38 -38
  218. package/dist/resources/TriMorphTargetGeometryConstants.js +46 -46
  219. package/dist/resources/TriRtGeometryConstants.js +88 -88
  220. package/dist/resources/TriTextureRes.js +304 -304
  221. package/dist/resources/enums.js +18 -18
  222. package/dist/resources/resourceBoundary.js +47 -47
  223. package/dist/resources/texturePipelineBehavior.js +308 -308
  224. package/dist/texture/CjsTextureArrayRes.js +406 -406
  225. package/dist/texture/CjsTextureParameterProxy.js +133 -133
  226. package/docs/README.md +73 -0
  227. package/docs/architecture.md +86 -0
  228. package/docs/concepts/resource-lifecycle.md +217 -0
  229. package/docs/formats/README.md +105 -0
  230. package/docs/formats/gr2.md +161 -0
  231. package/{FORMAT-PROVENANCE.md → docs/formats/provenance.md} +173 -155
  232. package/docs/formats/stl.md +37 -0
  233. package/docs/formats/wwise.md +44 -0
  234. package/docs/reference/classes/README.md +33 -0
  235. package/docs/reference/classes/core.md +106 -0
  236. package/docs/reference/classes/dropped.md +46 -0
  237. package/docs/reference/classes/formats.md +522 -0
  238. package/docs/reference/classes/resources.md +346 -0
  239. package/docs/reference/classes/texture.md +26 -0
  240. package/docs/reference/events.md +92 -0
  241. package/docs/reference/motherlode-cache.md +244 -0
  242. package/docs/reference/queues.md +102 -0
  243. package/docs/reference/reload.md +107 -0
  244. package/docs/reference/texture-arrays.md +113 -0
  245. package/docs/reference/texture-pipeline.md +53 -0
  246. package/docs/roadmap.md +104 -0
  247. package/format-notices/black/LICENSE +21 -21
  248. package/format-notices/black/NOTICE +47 -47
  249. package/format-notices/bnk/LICENSE +21 -21
  250. package/format-notices/bnk/NOTICE +20 -20
  251. package/format-notices/cmf/LICENSE +21 -21
  252. package/format-notices/cmf/NOTICE +36 -36
  253. package/format-notices/dds/LICENSE +21 -21
  254. package/format-notices/dds/NOTICE +14 -14
  255. package/format-notices/fbx/LICENSE +21 -21
  256. package/format-notices/fbx/NOTICE +14 -14
  257. package/format-notices/flac/LICENSE +21 -21
  258. package/format-notices/flac/NOTICE +14 -14
  259. package/format-notices/gif/LICENSE +21 -21
  260. package/format-notices/gif/NOTICE +14 -14
  261. package/format-notices/gltf/LICENSE +21 -21
  262. package/format-notices/gltf/NOTICE +27 -27
  263. package/format-notices/gr2/LICENSE +21 -0
  264. package/format-notices/gr2/NOTICE +60 -0
  265. package/format-notices/gr2/THIRD-PARTY-NOTICES.md +93 -0
  266. package/format-notices/jpeg/LICENSE +21 -21
  267. package/format-notices/jpeg/NOTICE +14 -14
  268. package/format-notices/mp3/LICENSE +21 -21
  269. package/format-notices/mp3/NOTICE +14 -14
  270. package/format-notices/mp4/LICENSE +21 -21
  271. package/format-notices/mp4/NOTICE +14 -14
  272. package/format-notices/obj/LICENSE +21 -21
  273. package/format-notices/obj/NOTICE +26 -26
  274. package/format-notices/ogg/LICENSE +21 -21
  275. package/format-notices/ogg/NOTICE +28 -28
  276. package/format-notices/png/LICENSE +21 -21
  277. package/format-notices/png/NOTICE +14 -14
  278. package/format-notices/red/LICENSE +21 -21
  279. package/format-notices/red/NOTICE +31 -31
  280. package/format-notices/stl/LICENSE +21 -21
  281. package/format-notices/stl/NOTICE +21 -21
  282. package/format-notices/tga/LICENSE +21 -21
  283. package/format-notices/tga/NOTICE +14 -14
  284. package/format-notices/wav/LICENSE +21 -21
  285. package/format-notices/wav/NOTICE +14 -14
  286. package/format-notices/webm/LICENSE +21 -21
  287. package/format-notices/webm/NOTICE +14 -14
  288. package/format-notices/webp/LICENSE +21 -21
  289. package/format-notices/webp/NOTICE +14 -14
  290. package/format-notices/wem/LICENSE +57 -57
  291. package/format-notices/wem/NOTICE +33 -33
  292. package/format-notices/yaml/LICENSE +21 -21
  293. package/format-notices/yaml/NOTICE +44 -44
  294. package/package.json +52 -51
  295. package/dist/formats/black/core/black-schema-v1-2026-07-11.json.js +0 -4
  296. package/dist/formats/black/core/black-schema-v1-2026-07-11.json.js.map +0 -1
  297. package/resource-lifecycle.md +0 -679
@@ -0,0 +1,105 @@
1
+ # Format subpaths
2
+
3
+ Status: Evolving
4
+ Scope: `@carbonenginejs/runtime-resource/formats`
5
+ Audience: Users and integrators
6
+ Summary: Maps every non-shader format subpath and records cross-format output conventions.
7
+
8
+ ## Import rule
9
+
10
+ Concrete formats are never imported or registered by the package root. Each
11
+ format is an explicit tree-shakeable subpath, registered by the caller:
12
+
13
+ ```js
14
+ import { CjsResMan } from "@carbonenginejs/runtime-resource";
15
+ import { CjsMp4Format } from "@carbonenginejs/runtime-resource/formats/mp4";
16
+
17
+ const resMan = new CjsResMan().Register({
18
+ source,
19
+ formats: [ CjsMp4Format ]
20
+ });
21
+
22
+ const resource = resMan.GetResource("res:/video/intro.mp4");
23
+ const video = await resource.Ready();
24
+ ```
25
+
26
+ Formats return plain payload objects. Semantic resource classes apply them
27
+ through `SetPayload()`, validate their own required fields, and throw
28
+ `CJS_RESOURCE_PAYLOAD_INVALID` before replacing a previously valid payload.
29
+ `GetPayload()`, `HasPayload()`, and `ReleasePayload()` manage transient CPU
30
+ retention without introducing a parallel DTO class hierarchy.
31
+
32
+ ## Format map
33
+
34
+ | Format | Class | Import |
35
+ |---|---|---|
36
+ | Black (`.black`) | `CjsBlackFormat` | `@carbonenginejs/runtime-resource/formats/black` |
37
+ | Wwise soundbank (`.bnk`) | `CjsBnkFormat` | `@carbonenginejs/runtime-resource/formats/bnk` |
38
+ | CMF (`.cmf`) | `CjsCmfFormat` | `@carbonenginejs/runtime-resource/formats/cmf` |
39
+ | DDS (`.dds`) | `CjsDdsFormat` | `@carbonenginejs/runtime-resource/formats/dds` |
40
+ | FBX (`.fbx`) | `CjsFbxFormat` | `@carbonenginejs/runtime-resource/formats/fbx` |
41
+ | FLAC (`.flac`) | `CjsFlacFormat` | `@carbonenginejs/runtime-resource/formats/flac` |
42
+ | GIF (`.gif`) | `CjsGifFormat` | `@carbonenginejs/runtime-resource/formats/gif` |
43
+ | glTF (`.gltf`/`.glb`) | `CjsGltfFormat` | `@carbonenginejs/runtime-resource/formats/gltf` |
44
+ | Granny GR2/GSF (`.gr2`/`.gsf`) | `CjsGr2Format` | `@carbonenginejs/runtime-resource/formats/gr2` |
45
+ | JPEG (`.jpg`/`.jpeg`) | `CjsJpegFormat` | `@carbonenginejs/runtime-resource/formats/jpeg` |
46
+ | MP3 (`.mp3`) | `CjsMp3Format` | `@carbonenginejs/runtime-resource/formats/mp3` |
47
+ | MP4 (`.mp4`) | `CjsMp4Format` | `@carbonenginejs/runtime-resource/formats/mp4` |
48
+ | OBJ (`.obj`) | `CjsObjFormat` | `@carbonenginejs/runtime-resource/formats/obj` |
49
+ | Ogg (`.ogg`) | `CjsOggFormat` | `@carbonenginejs/runtime-resource/formats/ogg` |
50
+ | PNG (`.png`) | `CjsPngFormat` | `@carbonenginejs/runtime-resource/formats/png` |
51
+ | Red (`.red`) | `CjsRedFormat` | `@carbonenginejs/runtime-resource/formats/red` |
52
+ | STL (`.stl`) | `CjsStlFormat` | `@carbonenginejs/runtime-resource/formats/stl` |
53
+ | TGA (`.tga`) | `CjsTgaFormat` | `@carbonenginejs/runtime-resource/formats/tga` |
54
+ | WAV (`.wav`) | `CjsWavFormat` | `@carbonenginejs/runtime-resource/formats/wav` |
55
+ | WebM (`.webm`) | `CjsWebmFormat` | `@carbonenginejs/runtime-resource/formats/webm` |
56
+ | WebP (`.webp`) | `CjsWebpFormat` | `@carbonenginejs/runtime-resource/formats/webp` |
57
+ | Wwise media (`.wem`) | `CjsWemFormat` | `@carbonenginejs/runtime-resource/formats/wem` |
58
+ | YAML (`.yaml`/`.yml`) | `CjsYamlFormat` | `@carbonenginejs/runtime-resource/formats/yaml` |
59
+
60
+ Detailed pages: [Granny GR2 and GSF](gr2.md),
61
+ [Wwise soundbanks and media](wwise.md), and [STL export](stl.md). Ownership
62
+ history, retained snapshots, and donor licensing are recorded in
63
+ [provenance.md](provenance.md).
64
+
65
+ ## Granny GR2/GSF
66
+
67
+ `CjsGr2Format` reads `.gr2` geometry/skeleton/animation graphs and `.gsf`
68
+ (GState) profiles with no native tooling: section decompression (None,
69
+ Oodle1, and the clean-room BitKnit2 decoder), reflected type-tree walking,
70
+ GR2 JSON emission, optional curve decompression, CCP packed tangent-frame
71
+ unpacking, and caller-class hydration (`emit: "gr2"`/`"cmf"` with a
72
+ `classes` map). It was migrated from `@carbonenginejs/format-gr2` after that
73
+ package's 2026-07-24 MIT relicense, preserving its behavior and test
74
+ surface; [gr2.md](gr2.md) documents the reader API, output modes, graph
75
+ shape, and hydration contract.
76
+
77
+ ## Red output markers
78
+
79
+ Red payload output reserves configurable type, ID, reference, and sequence
80
+ values markers (`_type`, `_id`, `_reference`, and `_values` by default).
81
+ Repeated or cyclic sequences use an ID-bearing values envelope; unique
82
+ sequences remain arrays. Authored fields may not collide with active markers,
83
+ so remap the marker options when those names are real data. Disabling the
84
+ reference marker preserves actual JavaScript identity; cyclic output in that
85
+ mode is intentionally not JSON-serializable.
86
+
87
+ ## DDS decoded fallback
88
+
89
+ Decoded DDS fallback currently has a narrower contract than native DDS
90
+ texture output. `emit: "rgba"` returns one canonical 2D surface decoded from
91
+ the first DDS subresource; it does not preserve stored mip levels, cube
92
+ faces, array layers, or volume slices. Consumers may use it for ordinary 2D
93
+ fallback when the engine owns any required mip generation, but must not infer
94
+ decoded multi-subresource support from a successful RGBA probe. A future
95
+ richer decoded-texture contract must be introduced explicitly rather than
96
+ overloading the current RGBA fields.
97
+
98
+ The software path includes BC1-BC5 and BC7 as RGBA8, plus signed and unsigned
99
+ BC6H as linear `Float32Array` RGBA without clamping HDR values. These block
100
+ decoders are implemented in-project with no codec package.
101
+
102
+ ## Related documentation
103
+
104
+ - [Queues, publication, and registration](../reference/queues.md)
105
+ - [Format ownership and fork provenance](provenance.md)
@@ -0,0 +1,161 @@
1
+ # Granny GR2 and GSF
2
+
3
+ Status: Evolving
4
+ Scope: `@carbonenginejs/runtime-resource/formats/gr2`
5
+ Audience: Users and integrators
6
+ Summary: Defines the pure-JavaScript GR2/GSF reader, its output modes, conversion options, graph shape, and class-hydration boundary.
7
+
8
+ ## Purpose
9
+
10
+ `CjsGr2Format` reads Granny 3D `.gr2` geometry, skeleton, animation, and
11
+ morph-target data, plus Granny State `.gsf` profiles. It runs in Node and the
12
+ browser without `granny2.dll`, native addons, a GPU, or private assets.
13
+
14
+ The reader owns Granny container parsing, reflected type-tree walking, section
15
+ decompression, JSON projection, optional curve and vertex-channel conversion,
16
+ GSF projection, and caller-class hydration. Resource caching and publication
17
+ remain with `CjsResMan`; GPU realization remains with engine packages.
18
+
19
+ Supported section compression is None, Oodle1, and the in-project clean-room
20
+ BitKnit2 decoder. Licensing and migration history are recorded in
21
+ [format provenance](provenance.md).
22
+
23
+ ## Import and basic use
24
+
25
+ Import the runtime-resource wrapper from its explicit format subpath:
26
+
27
+ ```js
28
+ import { CjsGr2Format } from "@carbonenginejs/runtime-resource/formats/gr2";
29
+
30
+ const graph = CjsGr2Format.read(bytes);
31
+ const summary = CjsGr2Format.inspect(bytes);
32
+ const asynchronousGraph = await CjsGr2Format.readAsync(bytes);
33
+ ```
34
+
35
+ The wrapper exposes the normal runtime-resource format metadata and
36
+ `isSupported(bytes)` magic probe. It also exports the migrated
37
+ `CjsFormatGr2` reader engine for compatibility, but new consumers should use
38
+ `CjsGr2Format`.
39
+
40
+ Register it with `CjsResMan` when GR2/GSF should participate in ordinary
41
+ resource loading:
42
+
43
+ ```js
44
+ import { CjsResMan } from "@carbonenginejs/runtime-resource";
45
+ import { CjsGr2Format } from "@carbonenginejs/runtime-resource/formats/gr2";
46
+
47
+ const resMan = new CjsResMan().Register({
48
+ source,
49
+ formats: [ CjsGr2Format ]
50
+ });
51
+
52
+ const resource = resMan.GetResource("res:/model/ship.gr2");
53
+ const graph = await resource.Ready();
54
+ ```
55
+
56
+ Concrete formats are not imported or registered by the package root.
57
+
58
+ ## Output modes
59
+
60
+ `emit` selects the representation:
61
+
62
+ | Value | Result |
63
+ |---|---|
64
+ | `"json"` | Default stable GR2 graph with plain objects |
65
+ | `"gr2Json"` | Explicit alias for the JSON graph |
66
+ | `"gr2"` | GR2 graph hydrated with caller-supplied classes |
67
+ | `"cmf"` | CMF-shaped graph hydrated with caller-supplied classes |
68
+ | `"raw"` | Low-level reflected `granny_file_info` result |
69
+
70
+ `"gr2"` and `"cmf"` require a non-empty `classes` map. Classes may also be
71
+ supplied with `"json"`/`"gr2Json"` to hydrate selected JSON nodes while
72
+ leaving omitted nodes as plain objects.
73
+
74
+ ## Conversion options
75
+
76
+ | Option | Default | Effect |
77
+ |---|---:|---|
78
+ | `decompressCurves` | `false` | Adds decoded `knots`, `controls`, and `dimension` to supported compressed animation curves while retaining the raw curve fields |
79
+ | `unpackTangents` | `false` | Converts packed CCP tangent frames into separate normal, tangent, and binormal channels |
80
+ | `rebuildMissingNormals` | `false` | Generates absent normals from positions and triangle indices |
81
+ | `rebuildMissingTangents` | `false` | Generates absent tangents from positions, normals, UVs, and triangle indices |
82
+ | `rebuildMissingBiNormals` | `false` | Generates absent binormals from normals and tangents |
83
+ | `classes` | `{}` | Maps supported graph node keys to constructors |
84
+
85
+ Tangent unpacking and missing-channel rebuild options may be functions when a
86
+ caller needs per-mesh policy. Rebuild options fill absent data; they do not
87
+ repair authored channels that are present but incorrect.
88
+
89
+ A reusable reader profile can hold these defaults:
90
+
91
+ ```js
92
+ const reader = new CjsGr2Format({
93
+ decompressCurves: true,
94
+ unpackTangents: true
95
+ });
96
+
97
+ const first = reader.Read(firstBytes);
98
+ const second = reader.Read(secondBytes);
99
+ ```
100
+
101
+ ## JSON graph and hydration
102
+
103
+ The default graph has this general shape:
104
+
105
+ ```text
106
+ Root
107
+ |-- grannyFileFormatRevision, grannyFileSource
108
+ |-- meshes
109
+ | |-- boneBindings, morphTargets
110
+ | |-- vertex: flat numeric channels
111
+ | `-- indices: triangle index groups
112
+ |-- models
113
+ | `-- skeleton -> bones
114
+ `-- animations
115
+ `-- trackGroups -> transformTracks -> curves
116
+ ```
117
+
118
+ Vertex channels include positions, normals, tangents, binormals, UVs, blend
119
+ indices, and blend weights when available. `IndexGroup.faces` is a flat array
120
+ of triangle indices. Sparse morph targets carry `vertexIndices`; native and
121
+ annotation-set morph targets share the same projected shape.
122
+
123
+ For each registered class key, hydration constructs the class without
124
+ arguments and calls:
125
+
126
+ ```js
127
+ new Class().SetValues(nodeFields);
128
+ ```
129
+
130
+ Constructors must therefore support zero-argument construction and
131
+ `SetValues(values)`. Supported GR2 and CMF keys are exposed through
132
+ `CjsGr2Format.CLASS_KEYS`; use `SetClass`, `SetClasses`, `GetClass`, and
133
+ `HasClass` on reusable reader instances.
134
+
135
+ `ToJSON(value)` and static `toJSON(value)` convert hydrated output into a
136
+ JSON-compatible value. They do not write a binary `.gr2` file or return JSON
137
+ text.
138
+
139
+ ## Granny State
140
+
141
+ GSF uses the ordinary Granny container with a GState root schema. The reader
142
+ provides dedicated classification, projection, and inspection:
143
+
144
+ ```js
145
+ if (CjsGr2Format.isGsf(bytes)) {
146
+ const state = CjsGr2Format.readGsf(bytes);
147
+ const dependencies = CjsGr2Format.inspectGsf(bytes);
148
+ }
149
+ ```
150
+
151
+ The stable GSF projection contains container revision data, model and
152
+ retarget hints, the state machine, animation slots and sets, referenced
153
+ relative `.gr2` files, token count, editor data, and extended data.
154
+ `readGsfAsync` provides the equivalent promise-facing entry point.
155
+
156
+ ## Related documentation
157
+
158
+ - [Format subpaths](README.md)
159
+ - [Architecture and boundaries](../architecture.md)
160
+ - [Resource lifecycle](../concepts/resource-lifecycle.md)
161
+ - [Format ownership and provenance](provenance.md)
@@ -1,155 +1,173 @@
1
- # Format ownership and fork provenance
2
-
3
- On 2026-07-13, the non-shader runtime format implementations below were copied
4
- once into `runtime-resource`. Their standalone repositories remain frozen with
5
- their existing APIs and names; they are not upstreams for the runtime copies.
6
-
7
- Copied paths were `src/` and the behavioral `test/` corpus. Package publishing
8
- scripts and CLIs were not copied. Exact donor license and notice files are kept
9
- under `format-notices/<format>/`.
10
-
11
- | Legacy package | Source revision/state | Runtime class | Runtime import |
12
- |---|---|---|---|
13
- | `format-black` | `9fcaaff9e5f28c90b628d8a10b7c79aff7913a90` | `CjsBlackFormat` | `@carbonenginejs/runtime-resource/formats/black` |
14
- | `format-cmf` | unborn working-tree snapshot | `CjsCmfFormat` | `@carbonenginejs/runtime-resource/formats/cmf` |
15
- | `format-dds` | `66fa149cd826e1114ad0be84479f89dee753ed76` | `CjsDdsFormat` | `@carbonenginejs/runtime-resource/formats/dds` |
16
- | `format-fbx` | `8d0fcc2fe44c8096b35e360a903bff30b49eb592` | `CjsFbxFormat` | `@carbonenginejs/runtime-resource/formats/fbx` |
17
- | `format-flac` | unborn working-tree snapshot | `CjsFlacFormat` | `@carbonenginejs/runtime-resource/formats/flac` |
18
- | `format-gif` | `5d831c5c0533a9579682f776274574289a520899` | `CjsGifFormat` | `@carbonenginejs/runtime-resource/formats/gif` |
19
- | `format-gltf` | `d0dadf920828bceec987c2a5fa1f161f81db28aa` | `CjsGltfFormat` | `@carbonenginejs/runtime-resource/formats/gltf` |
20
- | `format-jpeg` | `bed2253ea979bba27812420fa897987d82a91793` | `CjsJpegFormat` | `@carbonenginejs/runtime-resource/formats/jpeg` |
21
- | `format-mp3` | unborn working-tree snapshot | `CjsMp3Format` | `@carbonenginejs/runtime-resource/formats/mp3` |
22
- | `format-mp4` | `cffc5a57b115a99ed9e0947a6b9d3390ffc3581c` | `CjsMp4Format` | `@carbonenginejs/runtime-resource/formats/mp4` |
23
- | `format-obj` | `e5d3f9a1520c7855bd5b6edc1e2304a7b4e18176` | `CjsObjFormat` | `@carbonenginejs/runtime-resource/formats/obj` |
24
- | `format-ogg` | unborn working-tree snapshot | `CjsOggFormat` | `@carbonenginejs/runtime-resource/formats/ogg` |
25
- | `format-png` | `04dbb7c0f289043c3c32d9141ec3ef74aeeb1c43` | `CjsPngFormat` | `@carbonenginejs/runtime-resource/formats/png` |
26
- | `format-red` | `98beab6988111418d6e09827b92d27e08da4c05b` | `CjsRedFormat` | `@carbonenginejs/runtime-resource/formats/red` |
27
- | `format-stl` | `4858f9a37bf140a3c544fa30a13a6fcce015247b` | `CjsStlFormat` | `@carbonenginejs/runtime-resource/formats/stl` |
28
- | `format-tga` | `b0f9df263727057537b2279322e8cd088f366179` | `CjsTgaFormat` | `@carbonenginejs/runtime-resource/formats/tga` |
29
- | `format-wav` | unborn working-tree snapshot | `CjsWavFormat` | `@carbonenginejs/runtime-resource/formats/wav` |
30
- | `format-webm` | `459203ac293d0d53fff0e43494b7e47d8d4c92bd` | `CjsWebmFormat` | `@carbonenginejs/runtime-resource/formats/webm` |
31
- | `format-webp` | `19155e9cc7ae05845c23a3c259d3a586569eba40` | `CjsWebpFormat` | `@carbonenginejs/runtime-resource/formats/webp` |
32
- | `format-yaml` | `3d7e1d1cf9b7a936283d6050efe43a0a9fadb6a4` | `CjsYamlFormat` | `@carbonenginejs/runtime-resource/formats/yaml` |
33
-
34
- The unborn donors had no commit-addressable `HEAD`; this document deliberately
35
- records them as working-tree snapshots rather than inventing a revision. Their
36
- copied runtime files are the deterministic retained snapshot.
37
-
38
- ## Black definition snapshot
39
-
40
- The Black reader uses the package-owned generated definition snapshot at
41
- `src/formats/black/core/black-schema-v1-2026-07-11.json`. The Red format exposes
42
- the same catalog for discovery, but its YAML reader currently accepts named
43
- fields without registry enforcement. The snapshot was copied from
44
- `format-carbon` revision `d2a3c67cf3d46e8ba78ca19e66558d868178ec24`
45
- with SHA-256
46
- `008ECB29E670EFC678B471A6EFF099600A29C2907912FC42B854995904604691`.
47
-
48
- This retained generated artifact keeps the published readers deterministic and
49
- browser-safe without a runtime dependency on a sibling checkout or an
50
- unpublished `format-carbon` export. `format-carbon` remains the build-time
51
- authority for future schema regeneration; an updated snapshot must record its
52
- new source revision and digest here.
53
-
54
- ## Native additions
55
-
56
- Formats below were authored directly in `runtime-resource` and have no legacy
57
- donor package. Their `format-notices/<format>/` entries record third-party
58
- format attribution rather than fork provenance.
59
-
60
- | Format | Runtime class | Runtime import | Notes |
61
- |---|---|---|---|
62
- | Wwise soundbank (`.bnk`) | `CjsBnkFormat` | `@carbonenginejs/runtime-resource/formats/bnk` | Original code; chunk layout from public community documentation (ww2ogg, vgmstream, wwiser), no code copied. Also carries the SoundbanksInfo JSON helpers (`parseSoundbanksInfo`, `buildSoundbanksCatalog`, `joinSoundbanksInfo`) and `wwiseIdFromName` (FNV-1 32 of the lowercased name, verified against EVE bank/language ids). HIRC entries additionally decode version-stable typed fields (event action lists, action type/target, sound and music-track source ids), pinned by hexdump against bank generator version 150, and the `wwise` static namespace groups the domain toolkit (SoundbanksInfo helpers, id hash, `wwise.eventMediaFromBanks` event media resolution over inspected banks — graph interpretation for consumers; never used by the resource lifecycle). |
63
- | Wwise media (`.wem`) | `CjsWemFormat` | `@carbonenginejs/runtime-resource/formats/wem` | Original code; container/codec-tag behavior from public community documentation (ww2ogg, vgmstream, wwiser), no code copied. Includes a Wwise-Vorbis→Ogg repacker (`emit: "ogg"`), an original reimplementation of the ww2ogg algorithm with inline granule computation (no revorb pass needed), and a PTADPCM/16-bit-PCM decoder (`emit: "pcm"` / `toPcm()`, AudioBuffer-ready float32; PTADPCM algorithm from community documentation, verified against EVE media). |
64
-
65
- ## Post-fork additions inside copied formats
66
-
67
- - `formats/dds` gained original, dependency-free **BC6H and BC7 CPU decoders**
68
- in `runtime-resource` 0.8.0 (2026-07-21). BC6H covers all fourteen modes,
69
- signed and unsigned HDR, transformed endpoints, partition/anchor fixups,
70
- interpolation, reserved opaque-black modes, and float RGBA output. BC7 covers
71
- all eight modes,
72
- two- and three-subset partitions, anchor fixups, P-bits, dual index streams,
73
- channel rotation, edge blocks, and the reserved transparent mode. Fixed bit
74
- layouts and tables follow the Khronos Data Format Specification and Microsoft
75
- BC6H/BC7 documentation. Tests cover every mode and signed/unsigned fixtures;
76
- BC7 was also checked against randomized valid-mode blocks and both decoders
77
- were exercised on real EVE textures acquired through `tools-core`.
78
- - `formats/stl` received a writer hardening pass (2026-07-18) without changing
79
- its donor origin: binary provenance headers now round-trip the caller's solid
80
- name, shared triangle indices are validated as in-range safe integers, scaled
81
- coordinates must remain finite, and binary coordinates must fit float32
82
- instead of silently becoming infinities. Writer JSDoc and ASCII/binary
83
- round-trip/error coverage were expanded in the runtime-owned copy.
84
- - `formats/cmf` gained a **binary CMF v1 writer** (2026-07-15,
85
- `src/formats/cmf/core/writer.js`, `CjsCmfFormat.write`/`writeAsync` and
86
- `Write`/`WriteAsync`): original code implementing CarbonEngine's
87
- `cmf::BuildFile` behavior tagged self-relative span flattening with leaf
88
- chunk dedup, BufferView→section remapping in first-encounter order,
89
- meshoptimizer vertex/index compression (index compression canonicalizes
90
- triangle rotation, matching the engine's own writer test expectations), and
91
- the post-crc32 file checksum. Verified by write→read roundtrips against the
92
- runtime reader; `E:\carbonengine\mesh\{include,src}\cmf` was the behavioral
93
- reference, no code copied. `writeShared`/`writeSharedAsync` plus
94
- `core/pack.js` (channel interleaving, index packing, unique buffer-index
95
- assignment) serialize shared geometry directly, enabling GR2/OBJ/glTF→CMF
96
- verified against real EVE `.gr2` models fetched via
97
- `@carbonenginejs/tool-index` (positions exact, triangles equivalent).
98
- - `formats/cmf` also gained the **GR2 skeleton/animation converter**
99
- (2026-07-15, `src/formats/cmf/core/gr2Anim.js`, applied automatically by
100
- `writeShared`): GR2-shaped skeletons (root list or `models[].skeleton`)
101
- convert to CMF bones/parents/rest transforms with inverse binds rebuilt
102
- from the rest hierarchy; decoded Granny curves convert to CMF Step/Linear
103
- channels degree 1 exactly, degree 2 via adaptive de Boor resampling
104
- with discontinuities snapped to one float32 ULP. Consumes only decoded
105
- `{knots, controls}` data so the MIT runtime stays independent of the GR2
106
- package. Validated on EVE ships (cde3_t3, gde3_t3, cfaux1_t1, mfaux1_t1:
107
- 3,377 channels 8.3e-4 positional / ≤ 0.14° rotational vs the GR2 runtime
108
- sampler; 9 Granny curve formats) and characters (basicfemale: 132-bone
109
- skeleton, exact skin weights).
110
- - `formats/ogg` gained a pure-JS **Ogg Vorbis PCM decoder** (2026-07-15,
111
- `src/formats/ogg/core/{vorbis.js,imdct.js}`, `emit: "pcm"`/`"audio"`):
112
- original code implementing the Vorbis I specification (floor 1, residues
113
- 0/1/2, square-polar coupling, FFT-based IMDCT, windowed overlap-add).
114
- stb_vorbis (public domain) was consulted as a behavioral reference and is
115
- the source of the spec's floor1 `inverse_db_table` constants; no licensed
116
- code was copied. Validated bit-comparable to ffmpeg (max diff ~3e-8) and
117
- vgmstream (±1 int16 LSB) across the EVE Vorbis corpus.
118
-
119
- ## Wem packed-codebook snapshot
120
-
121
- The wem Ogg repacker ships a package-owned copy of the aoTuV 6.03 packed
122
- Vorbis codebook library at
123
- `src/formats/wem/core/packedCodebooksAotuv603.js` (base64 module). It was
124
- copied byte-identically from `packed_codebooks_aoTuV_603.bin` in the ww2ogg
125
- distribution (`github.com/hcs64/ww2ogg`), 74,387 bytes, SHA-256
126
- `00a93eab267d281401b1efd54e888a2e183299b9e6c446c48d09f701a89d9d27`, retrieved
127
- 2026-07-15. The data is BSD-licensed (Xiph.org Foundation, Adam Gashlin);
128
- attribution and the full license terms are recorded in
129
- `format-notices/wem/NOTICE` and `format-notices/wem/LICENSE`. An updated
130
- snapshot must record its new source and digest here.
131
-
132
- ## Deliberately not copied
133
-
134
- - `format-gr2` is the intended runtime-resource owner target, but its current
135
- BitKnit-derived implementation is EUPL-1.2. It remains separate and active
136
- until that code is replaced or an explicit distribution-license decision is
137
- made. It has not been deprecated or relabeled as MIT.
138
- - `format-carbon` remains the schema emitter/generator and build-time schema
139
- authority. Black consumes its published definitions; Red exposes the copied
140
- catalog but does not yet enforce it while reading YAML fields.
141
- - `format-dxbc`, `format-hlsl`, `format-webgl`, and `format-webgpu` are active
142
- shader work and were not copied, annotated, or otherwise modified by this
143
- migration.
144
-
145
- ## Typed-array ownership adjustments
146
-
147
- The runtime copies preserve caller byte objects by reference. During the fork,
148
- three avoidable source-buffer copies were changed to views:
149
-
150
- - CMF compressed sections use `Uint8Array.subarray`.
151
- - glTF GLB chunks use `Uint8Array.subarray`.
152
- - FBX raw binary property payloads use `Uint8Array.subarray`.
153
-
154
- Decoder output buffers and GIF per-frame snapshots still allocate because those
155
- values have independent semantic identity.
1
+ # Format ownership and fork provenance
2
+
3
+ Status: Stable
4
+ Scope: `@carbonenginejs/runtime-resource/formats`
5
+ Audience: Users, integrators, and maintainers
6
+ Summary: Records where each format implementation came from, retained snapshots and digests, and what was deliberately not copied.
7
+
8
+ On 2026-07-13, the non-shader runtime format implementations below were copied
9
+ once into `runtime-resource`. Their standalone repositories remain frozen with
10
+ their existing APIs and names; they are not upstreams for the runtime copies.
11
+
12
+ Copied paths were `src/` and the behavioral `test/` corpus. Package publishing
13
+ scripts and CLIs were not copied. Exact donor license and notice files are kept
14
+ under `format-notices/<format>/`.
15
+
16
+ | Legacy package | Source revision/state | Runtime class | Runtime import |
17
+ |---|---|---|---|
18
+ | `format-black` | `9fcaaff9e5f28c90b628d8a10b7c79aff7913a90` | `CjsBlackFormat` | `@carbonenginejs/runtime-resource/formats/black` |
19
+ | `format-cmf` | unborn working-tree snapshot | `CjsCmfFormat` | `@carbonenginejs/runtime-resource/formats/cmf` |
20
+ | `format-dds` | `66fa149cd826e1114ad0be84479f89dee753ed76` | `CjsDdsFormat` | `@carbonenginejs/runtime-resource/formats/dds` |
21
+ | `format-fbx` | `8d0fcc2fe44c8096b35e360a903bff30b49eb592` | `CjsFbxFormat` | `@carbonenginejs/runtime-resource/formats/fbx` |
22
+ | `format-flac` | unborn working-tree snapshot | `CjsFlacFormat` | `@carbonenginejs/runtime-resource/formats/flac` |
23
+ | `format-gif` | `5d831c5c0533a9579682f776274574289a520899` | `CjsGifFormat` | `@carbonenginejs/runtime-resource/formats/gif` |
24
+ | `format-gltf` | `d0dadf920828bceec987c2a5fa1f161f81db28aa` | `CjsGltfFormat` | `@carbonenginejs/runtime-resource/formats/gltf` |
25
+ | `format-jpeg` | `bed2253ea979bba27812420fa897987d82a91793` | `CjsJpegFormat` | `@carbonenginejs/runtime-resource/formats/jpeg` |
26
+ | `format-mp3` | unborn working-tree snapshot | `CjsMp3Format` | `@carbonenginejs/runtime-resource/formats/mp3` |
27
+ | `format-mp4` | `cffc5a57b115a99ed9e0947a6b9d3390ffc3581c` | `CjsMp4Format` | `@carbonenginejs/runtime-resource/formats/mp4` |
28
+ | `format-obj` | `e5d3f9a1520c7855bd5b6edc1e2304a7b4e18176` | `CjsObjFormat` | `@carbonenginejs/runtime-resource/formats/obj` |
29
+ | `format-ogg` | unborn working-tree snapshot | `CjsOggFormat` | `@carbonenginejs/runtime-resource/formats/ogg` |
30
+ | `format-png` | `04dbb7c0f289043c3c32d9141ec3ef74aeeb1c43` | `CjsPngFormat` | `@carbonenginejs/runtime-resource/formats/png` |
31
+ | `format-red` | `98beab6988111418d6e09827b92d27e08da4c05b` | `CjsRedFormat` | `@carbonenginejs/runtime-resource/formats/red` |
32
+ | `format-stl` | `4858f9a37bf140a3c544fa30a13a6fcce015247b` | `CjsStlFormat` | `@carbonenginejs/runtime-resource/formats/stl` |
33
+ | `format-tga` | `b0f9df263727057537b2279322e8cd088f366179` | `CjsTgaFormat` | `@carbonenginejs/runtime-resource/formats/tga` |
34
+ | `format-wav` | unborn working-tree snapshot | `CjsWavFormat` | `@carbonenginejs/runtime-resource/formats/wav` |
35
+ | `format-webm` | `459203ac293d0d53fff0e43494b7e47d8d4c92bd` | `CjsWebmFormat` | `@carbonenginejs/runtime-resource/formats/webm` |
36
+ | `format-webp` | `19155e9cc7ae05845c23a3c259d3a586569eba40` | `CjsWebpFormat` | `@carbonenginejs/runtime-resource/formats/webp` |
37
+ | `format-yaml` | `3d7e1d1cf9b7a936283d6050efe43a0a9fadb6a4` | `CjsYamlFormat` | `@carbonenginejs/runtime-resource/formats/yaml` |
38
+
39
+ The unborn donors had no commit-addressable `HEAD`; this document deliberately
40
+ records them as working-tree snapshots rather than inventing a revision. Their
41
+ copied runtime files are the deterministic retained snapshot.
42
+
43
+ On 2026-07-24, following `format-gr2`'s MIT relicense (its EUPL-derived
44
+ BitKnit decoder was replaced by a clean-room implementation written from the
45
+ published specification in that package's `docs/formats/bitknit2.md`), the
46
+ GR2/GSF reader joined the runtime copies:
47
+
48
+ | Legacy package | Source revision/state | Runtime class | Runtime import |
49
+ |---|---|---|---|
50
+ | `format-gr2` | `fa64607de7a3a96ed3b1aec5288bf71057642043` (v0.2.0, MIT) | `CjsGr2Format` | `@carbonenginejs/runtime-resource/formats/gr2` |
51
+
52
+ The copied engine keeps its donor class name (`CjsFormatGr2`, re-exported)
53
+ under `formats/gr2/core/`; `CjsGr2Format` is the runtime-authored contract
54
+ wrapper. Donor license and notice files are kept under
55
+ `format-notices/gr2/`.
56
+
57
+ ## Black definition snapshot
58
+
59
+ The Black reader uses the package-owned generated definition snapshot at
60
+ `src/formats/black/core/black-schema-v1-2026-07-11.json`. The Red format exposes
61
+ the same catalog for discovery, but its YAML reader currently accepts named
62
+ fields without registry enforcement. The snapshot was copied from
63
+ `format-carbon` revision `d2a3c67cf3d46e8ba78ca19e66558d868178ec24`
64
+ with SHA-256
65
+ `008ECB29E670EFC678B471A6EFF099600A29C2907912FC42B854995904604691`.
66
+
67
+ This retained generated artifact keeps the published readers deterministic and
68
+ browser-safe without a runtime dependency on a sibling checkout or an
69
+ unpublished `format-carbon` export. `format-carbon` remains the build-time
70
+ authority for future schema regeneration; an updated snapshot must record its
71
+ new source revision and digest here.
72
+
73
+ ## Native additions
74
+
75
+ Formats below were authored directly in `runtime-resource` and have no legacy
76
+ donor package. Their `format-notices/<format>/` entries record third-party
77
+ format attribution rather than fork provenance.
78
+
79
+ | Format | Runtime class | Runtime import | Notes |
80
+ |---|---|---|---|
81
+ | Wwise soundbank (`.bnk`) | `CjsBnkFormat` | `@carbonenginejs/runtime-resource/formats/bnk` | Original code; chunk layout from public community documentation (ww2ogg, vgmstream, wwiser), no code copied. Also carries the SoundbanksInfo JSON helpers (`parseSoundbanksInfo`, `buildSoundbanksCatalog`, `joinSoundbanksInfo`) and `wwiseIdFromName` (FNV-1 32 of the lowercased name, verified against EVE bank/language ids). HIRC entries additionally decode version-stable typed fields (event action lists, action type/target, sound and music-track source ids), pinned by hexdump against bank generator version 150, and the `wwise` static namespace groups the domain toolkit (SoundbanksInfo helpers, id hash, `wwise.eventMediaFromBanks` event → media resolution over inspected banks — graph interpretation for consumers; never used by the resource lifecycle). |
82
+ | Wwise media (`.wem`) | `CjsWemFormat` | `@carbonenginejs/runtime-resource/formats/wem` | Original code; container/codec-tag behavior from public community documentation (ww2ogg, vgmstream, wwiser), no code copied. Includes a Wwise-Vorbis→Ogg repacker (`emit: "ogg"`), an original reimplementation of the ww2ogg algorithm with inline granule computation (no revorb pass needed), and a PTADPCM/16-bit-PCM decoder (`emit: "pcm"` / `toPcm()`, AudioBuffer-ready float32; PTADPCM algorithm from community documentation, verified against EVE media). |
83
+
84
+ ## Post-fork additions inside copied formats
85
+
86
+ - `formats/dds` gained original, dependency-free **BC6H and BC7 CPU decoders**
87
+ in `runtime-resource` 0.8.0 (2026-07-21). BC6H covers all fourteen modes,
88
+ signed and unsigned HDR, transformed endpoints, partition/anchor fixups,
89
+ interpolation, reserved opaque-black modes, and float RGBA output. BC7 covers
90
+ all eight modes,
91
+ two- and three-subset partitions, anchor fixups, P-bits, dual index streams,
92
+ channel rotation, edge blocks, and the reserved transparent mode. Fixed bit
93
+ layouts and tables follow the Khronos Data Format Specification and Microsoft
94
+ BC6H/BC7 documentation. Tests cover every mode and signed/unsigned fixtures;
95
+ BC7 was also checked against randomized valid-mode blocks and both decoders
96
+ were exercised on real EVE textures acquired through `tools-core`.
97
+ - `formats/stl` received a writer hardening pass (2026-07-18) without changing
98
+ its donor origin: binary provenance headers now round-trip the caller's solid
99
+ name, shared triangle indices are validated as in-range safe integers, scaled
100
+ coordinates must remain finite, and binary coordinates must fit float32
101
+ instead of silently becoming infinities. Writer JSDoc and ASCII/binary
102
+ round-trip/error coverage were expanded in the runtime-owned copy.
103
+ - `formats/cmf` gained a **binary CMF v1 writer** (2026-07-15,
104
+ `src/formats/cmf/core/writer.js`, `CjsCmfFormat.write`/`writeAsync` and
105
+ `Write`/`WriteAsync`): original code implementing CarbonEngine's
106
+ `cmf::BuildFile` behavior tagged self-relative span flattening with leaf
107
+ chunk dedup, BufferView→section remapping in first-encounter order,
108
+ meshoptimizer vertex/index compression (index compression canonicalizes
109
+ triangle rotation, matching the engine's own writer test expectations), and
110
+ the post-crc32 file checksum. Verified by write→read roundtrips against the
111
+ runtime reader; CarbonEngine's `mesh` CMF sources were the behavioral
112
+ reference, no code copied. `writeShared`/`writeSharedAsync` plus
113
+ `core/pack.js` (channel interleaving, index packing, unique buffer-index
114
+ assignment) serialize shared geometry directly, enabling GR2/OBJ/glTF→CMF
115
+ verified against real EVE `.gr2` models fetched via
116
+ `@carbonenginejs/tool-index` (positions exact, triangles equivalent).
117
+ - `formats/cmf` also gained the **GR2 skeleton/animation converter**
118
+ (2026-07-15, `src/formats/cmf/core/gr2Anim.js`, applied automatically by
119
+ `writeShared`): GR2-shaped skeletons (root list or `models[].skeleton`)
120
+ convert to CMF bones/parents/rest transforms with inverse binds rebuilt
121
+ from the rest hierarchy; decoded Granny curves convert to CMF Step/Linear
122
+ channels degree ≤ 1 exactly, degree 2 via adaptive de Boor resampling
123
+ with discontinuities snapped to one float32 ULP. Consumes only decoded
124
+ `{knots, controls}` data so the MIT runtime stays independent of the GR2
125
+ package. Validated on EVE ships (cde3_t3, gde3_t3, cfaux1_t1, mfaux1_t1:
126
+ 3,377 channels ≤ 8.3e-4 positional / ≤ 0.14° rotational vs the GR2 runtime
127
+ sampler; 9 Granny curve formats) and characters (basicfemale: 132-bone
128
+ skeleton, exact skin weights).
129
+ - `formats/ogg` gained a pure-JS **Ogg Vorbis PCM decoder** (2026-07-15,
130
+ `src/formats/ogg/core/{vorbis.js,imdct.js}`, `emit: "pcm"`/`"audio"`):
131
+ original code implementing the Vorbis I specification (floor 1, residues
132
+ 0/1/2, square-polar coupling, FFT-based IMDCT, windowed overlap-add).
133
+ stb_vorbis (public domain) was consulted as a behavioral reference and is
134
+ the source of the spec's floor1 `inverse_db_table` constants; no licensed
135
+ code was copied. Validated bit-comparable to ffmpeg (max diff ~3e-8) and
136
+ vgmstream (±1 int16 LSB) across the EVE Vorbis corpus.
137
+
138
+ ## Wem packed-codebook snapshot
139
+
140
+ The wem Ogg repacker ships a package-owned copy of the aoTuV 6.03 packed
141
+ Vorbis codebook library at
142
+ `src/formats/wem/core/packedCodebooksAotuv603.js` (base64 module). It was
143
+ copied byte-identically from `packed_codebooks_aoTuV_603.bin` in the ww2ogg
144
+ distribution (`github.com/hcs64/ww2ogg`), 74,387 bytes, SHA-256
145
+ `00a93eab267d281401b1efd54e888a2e183299b9e6c446c48d09f701a89d9d27`, retrieved
146
+ 2026-07-15. The data is BSD-licensed (Xiph.org Foundation, Adam Gashlin);
147
+ attribution and the full license terms are recorded in
148
+ `format-notices/wem/NOTICE` and `format-notices/wem/LICENSE`. An updated
149
+ snapshot must record its new source and digest here.
150
+
151
+ ## Deliberately not copied
152
+
153
+ - `format-gr2` migrated into `formats/gr2` on 2026-07-24 (see the dated
154
+ table above) after its EUPL constraint was resolved; its standalone
155
+ repository is now a frozen legacy distribution like the other donors.
156
+ - `format-carbon` remains the schema emitter/generator and build-time schema
157
+ authority. Black consumes its published definitions; Red exposes the copied
158
+ catalog but does not yet enforce it while reading YAML fields.
159
+ - `format-dxbc`, `format-hlsl`, `format-webgl`, and `format-webgpu` are active
160
+ shader work and were not copied, annotated, or otherwise modified by this
161
+ migration.
162
+
163
+ ## Typed-array ownership adjustments
164
+
165
+ The runtime copies preserve caller byte objects by reference. During the fork,
166
+ three avoidable source-buffer copies were changed to views:
167
+
168
+ - CMF compressed sections use `Uint8Array.subarray`.
169
+ - glTF GLB chunks use `Uint8Array.subarray`.
170
+ - FBX raw binary property payloads use `Uint8Array.subarray`.
171
+
172
+ Decoder output buffers and GIF per-frame snapshots still allocate because those
173
+ values have independent semantic identity.