@divinevoxel/vlox 0.0.79 → 0.0.81

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 (167) hide show
  1. package/Builder/Tools/Brush/BrushTool.d.ts +12 -2
  2. package/Builder/Tools/Brush/BrushTool.js +53 -28
  3. package/Builder/Tools/Debug/DebugTool.d.ts +18 -0
  4. package/Builder/Tools/Debug/DebugTool.js +36 -0
  5. package/Builder/Tools/Path/PahtTool.d.ts +1 -1
  6. package/Builder/Tools/Path/PahtTool.js +1 -1
  7. package/Builder/Tools/Sculpt/SculptTool.js +8 -0
  8. package/Builder/Tools/Wrench/WrenchTool.js +10 -23
  9. package/Builder/Util/SurfaceBoxSelection.js +2 -0
  10. package/Builder/VoxelBuildSpace.js +3 -3
  11. package/Contexts/Base/Remote/InitDataSync.js +1 -1
  12. package/Math/UtilFunctions.js +7 -8
  13. package/Math/VoxelFaces.d.ts +2 -2
  14. package/Math/VoxelFaces.js +46 -55
  15. package/Math/WorldIndexing.d.ts +11 -0
  16. package/Math/WorldIndexing.js +34 -0
  17. package/Mesher/Geometry/Geometry.types.d.ts +2 -2
  18. package/Mesher/Geometry/Geometry.types.js +7 -20
  19. package/Mesher/Geometry/Primitives/QuadVertexData.js +118 -119
  20. package/Mesher/Geometry/Primitives/TriangleVertexData.js +89 -90
  21. package/Mesher/Geometry/Proto/ProtoMesh.d.ts +1 -1
  22. package/Mesher/Geometry/Proto/ProtoMesh.js +22 -29
  23. package/Mesher/Geometry/Proto/ProtoMeshBuffer.d.ts +4 -2
  24. package/Mesher/Geometry/Proto/ProtoMeshBuffer.js +14 -6
  25. package/Mesher/Geometry/Shapes/Box.js +6 -7
  26. package/Mesher/Geometry/Transform/TransformBox.js +8 -9
  27. package/Mesher/Geometry/Transform/TransformQuad.js +4 -5
  28. package/Mesher/Geometry/Transform/TransformTriangle.js +3 -4
  29. package/Mesher/InitMesher.js +4 -9
  30. package/Mesher/Items/Geometry/ItemGeometryBuilder.js +7 -8
  31. package/Mesher/Items/MeshTexture.js +125 -57
  32. package/Mesher/Voxels/Base/BuildVoxel.d.ts +6 -0
  33. package/Mesher/Voxels/Base/BuildVoxel.js +101 -0
  34. package/Mesher/Voxels/Base/CompactVoxelSectionMesh.js +1 -21
  35. package/Mesher/Voxels/Base/MeshSectionBase.js +3 -26
  36. package/Mesher/Voxels/Geometry/VoxelGeometryBuilder.js +33 -31
  37. package/Mesher/Voxels/Geometry/VoxelShaderData.js +3 -7
  38. package/Mesher/Voxels/MeshTemplate.js +6 -26
  39. package/Mesher/Voxels/MeshVoxel.js +5 -10
  40. package/Mesher/Voxels/Models/Common/Calc/CalcConstants.js +41 -42
  41. package/Mesher/Voxels/Models/Common/Calc/FaceDataCalc.js +6 -9
  42. package/Mesher/Voxels/Models/Common/Faces/CullRulledFace.js +64 -47
  43. package/Mesher/Voxels/Models/Common/Faces/ShadeRulledFace.js +57 -43
  44. package/Mesher/Voxels/Models/Nodes/Custom/Liquid/FlowGradient.js +4 -5
  45. package/Mesher/Voxels/Models/Nodes/Custom/Liquid/LiquidGeometryNode.d.ts +1 -1
  46. package/Mesher/Voxels/Models/Nodes/Custom/Liquid/LiquidGeometryNode.js +116 -118
  47. package/Mesher/Voxels/Models/Nodes/Default/QuadVoxelGeometryNode.js +4 -4
  48. package/Mesher/Voxels/Models/Nodes/VoxelGeometryConstructor.js +2 -2
  49. package/Mesher/Voxels/Models/Procedures/Default/OutlinedTextureProcedure.js +19 -21
  50. package/Mesher/Voxels/Models/Procedures/Default/PillarTextureProcedure.js +45 -38
  51. package/Mesher/Voxels/Models/RenderedMaterials.d.ts +1 -1
  52. package/Mesher/Voxels/Models/RenderedMaterials.js +8 -5
  53. package/Mesher/Voxels/Models/VoxelGeometryBuilderCacheSpace.d.ts +18 -4
  54. package/Mesher/Voxels/Models/VoxelGeometryBuilderCacheSpace.js +135 -22
  55. package/Mesher/Voxels/Models/VoxelGeometryBuilderCacheSpaceN.d.ts +33 -0
  56. package/Mesher/Voxels/Models/VoxelGeometryBuilderCacheSpaceN.js +204 -0
  57. package/Mesher/Voxels/Models/{VoxelModelConstructorRegister.d.ts → VoxelGeometryConstructorRegister.d.ts} +1 -6
  58. package/Mesher/Voxels/Models/VoxelGeometryConstructorRegister.js +20 -0
  59. package/Mesher/Voxels/Models/VoxelModelBuilder.js +15 -16
  60. package/Mesher/Voxels/Models/VoxelModelEffect.d.ts +1 -3
  61. package/Mesher/Voxels/Models/VoxelModelEffect.js +1 -3
  62. package/Renderer/DVERenderNode.types.d.ts +1 -0
  63. package/Renderer/InitTasks.js +2 -0
  64. package/Tasks/Paint/Erase/EraseVoxel.js +1 -1
  65. package/Tasks/Propagation/Illumanation/RGBUpdate.js +191 -48
  66. package/Tasks/Propagation/Illumanation/SunUpdate.d.ts +1 -1
  67. package/Tasks/Propagation/Illumanation/SunUpdate.js +167 -63
  68. package/Tasks/Propagation/Illumanation/WorldSun.js +96 -60
  69. package/Tasks/WorldGeneration/WorldGenBrush.d.ts +2 -0
  70. package/Tasks/WorldGeneration/WorldGenBrush.js +31 -0
  71. package/Templates/Archive/ArchivedVoxelTemplate.js +1 -1
  72. package/Templates/Archive/Functions/CreateArchivedTemplate.js +1 -1
  73. package/Templates/Archive/Functions/CreateArchivedTemplateFromFull.d.ts +6 -0
  74. package/Templates/Archive/Functions/CreateArchivedTemplateFromFull.js +174 -0
  75. package/Textures/Classes/CompactedTextureReader.d.ts +22 -0
  76. package/Textures/Classes/CompactedTextureReader.js +90 -0
  77. package/Textures/Classes/CompiledTexture.d.ts +4 -1
  78. package/Textures/Classes/CompiledTexture.js +36 -8
  79. package/Textures/Classes/TextureAtlasIndex.d.ts +7 -0
  80. package/Textures/Classes/TextureAtlasIndex.js +14 -0
  81. package/Textures/Classes/TextureLoader.d.ts +20 -0
  82. package/Textures/Classes/TextureLoader.js +95 -0
  83. package/Textures/Functions/BuildTextureData.d.ts +1 -1
  84. package/Textures/Functions/BuildTextureData.js +19 -122
  85. package/Textures/Functions/CreateCompactedTexture.d.ts +6 -0
  86. package/Textures/Functions/CreateCompactedTexture.js +105 -0
  87. package/Textures/Functions/ReadCompactedTexture.d.ts +2 -0
  88. package/Textures/Functions/ReadCompactedTexture.js +42 -0
  89. package/Textures/Texture.types.d.ts +14 -0
  90. package/Textures/TextureManager.d.ts +7 -1
  91. package/Textures/TextureManager.js +13 -0
  92. package/Tools/Brush/Brush.d.ts +4 -2
  93. package/Tools/Brush/Brush.js +28 -6
  94. package/Util/BinaryBuffer/Functions/BinaryBufferConvert.d.ts +1 -1
  95. package/Util/TickInterval.d.ts +3 -0
  96. package/Util/TickInterval.js +31 -3
  97. package/Voxels/Archive/VoxelPaletteArchiveReader.d.ts +1 -0
  98. package/Voxels/Archive/VoxelPaletteArchiveReader.js +9 -10
  99. package/Voxels/Archive/VoxelPaletteArechive.js +5 -4
  100. package/Voxels/Cursor/VoxelCursor.interface.d.ts +1 -1
  101. package/Voxels/Cursor/VoxelCursor.interface.js +22 -16
  102. package/Voxels/Data/VoxelLUT.d.ts +69 -42
  103. package/Voxels/Data/VoxelLUT.js +110 -53
  104. package/Voxels/Functions/BuildLUTs.js +100 -45
  105. package/Voxels/Functions/Geometry/CalcFunctions.js +6 -7
  106. package/Voxels/Functions/Geometry/Compile/BuildCompiled.d.ts +1 -1
  107. package/Voxels/Functions/Geometry/Inputs/BuildBoxInputs.d.ts +1 -1
  108. package/Voxels/Functions/Geometry/Inputs/BuildCustomInputs.d.ts +1 -1
  109. package/Voxels/Functions/Geometry/Inputs/BuildQuadInputs.d.ts +1 -1
  110. package/Voxels/Functions/Geometry/Inputs/BuildTriangleInputs.d.ts +1 -1
  111. package/Voxels/Functions/Geometry/Inputs/BuildTriangleInputs.js +3 -0
  112. package/Voxels/Indexes/VoxelIndex.js +3 -1
  113. package/Voxels/InitVoxelData.js +3 -1
  114. package/Voxels/Interaction/Functions/PickVoxel.js +3 -5
  115. package/Voxels/Interaction/Functions/PickVoxelWorld.js +4 -6
  116. package/Voxels/Models/Defaults/Examples.d.ts +2 -0
  117. package/Voxels/Models/Defaults/Examples.js +151 -2
  118. package/Voxels/State/Reltional/ReltionalStateBuilder.js +2 -0
  119. package/Voxels/State/Schema/BinarySchema.d.ts +1 -0
  120. package/Voxels/State/Schema/BinarySchema.js +14 -0
  121. package/Voxels/State/VoxelSchemas.d.ts +11 -4
  122. package/Voxels/State/VoxelSchemas.js +42 -9
  123. package/Voxels/Types/PaintVoxelData.js +6 -2
  124. package/World/Archive/Classes/ImportedSection.js +1 -1
  125. package/World/Archive/Classes/ImportedSector.js +0 -1
  126. package/World/Archive/Functions/Sector/ArchiveSector.js +2 -2
  127. package/World/Archive/Functions/Sector/ImportSector.d.ts +1 -0
  128. package/World/Archive/Functions/Sector/ImportSector.js +183 -7
  129. package/World/Cursor/SectorCursor.js +1 -4
  130. package/World/Cursor/WorldCursor.d.ts +12 -3
  131. package/World/Cursor/WorldCursor.js +60 -30
  132. package/World/InitTasks.js +1 -1
  133. package/World/Lock/Function/LockSectors.js +5 -1
  134. package/World/Lock/Function/UnLockSectors.js +5 -1
  135. package/World/SnapShot/SectionSnapShot.d.ts +7 -3
  136. package/World/SnapShot/SectionSnapShot.js +47 -21
  137. package/World/SnapShot/SectionSnapShotCursor.d.ts +4 -2
  138. package/World/SnapShot/SectionSnapShotCursor.js +23 -11
  139. package/World/SnapShot/SnapShots.d.ts +1 -2
  140. package/World/SnapShot/SnapShots.js +3 -3
  141. package/World/WorldSpaces.d.ts +7 -0
  142. package/World/WorldSpaces.js +35 -13
  143. package/WorldSimulation/Dimensions/DimensionSegment.d.ts +2 -0
  144. package/WorldSimulation/Dimensions/DimensionSegment.js +9 -1
  145. package/WorldSimulation/Dimensions/DimensionSimulation.js +6 -7
  146. package/WorldSimulation/Dimensions/Generator.d.ts +4 -0
  147. package/WorldSimulation/Dimensions/Generator.js +15 -1
  148. package/WorldSimulation/Dimensions/SimulationSector.d.ts +1 -0
  149. package/WorldSimulation/Dimensions/SimulationSector.js +18 -0
  150. package/WorldSimulation/Internal/WorldSimulationTasks.js +11 -7
  151. package/WorldSimulation/Procedures/InitalLoad.d.ts +1 -0
  152. package/WorldSimulation/Procedures/InitalLoad.js +18 -8
  153. package/WorldSimulation/Tasks/SimulationTaskBase.d.ts +4 -1
  154. package/WorldSimulation/Tasks/SimulationTaskBase.js +13 -2
  155. package/WorldSimulation/Tasks/TaskSegment.d.ts +4 -2
  156. package/WorldSimulation/Tasks/TaskSegment.js +36 -22
  157. package/WorldSimulation/Voxels/Ticks/Types/LiquidVoxelUpdate.js +1 -2
  158. package/WorldSimulation/WorldSimulation.d.ts +6 -3
  159. package/WorldSimulation/WorldSimulation.js +44 -20
  160. package/package.json +1 -1
  161. package/Mesher/Items/MeshTextureO.d.ts +0 -1
  162. package/Mesher/Items/MeshTextureO.js +0 -277
  163. package/Mesher/Voxels/Models/VoxelConstructor.d.ts +0 -8
  164. package/Mesher/Voxels/Models/VoxelConstructor.js +0 -78
  165. package/Mesher/Voxels/Models/VoxelModelConstructorRegister.js +0 -37
  166. package/WorldSimulation/Procedures/BuildOnly.d.ts +0 -10
  167. package/WorldSimulation/Procedures/BuildOnly.js +0 -55
@@ -0,0 +1,174 @@
1
+ import { Flat3DIndex, Vector3Like } from "@amodx/math";
2
+ import { ArchivedVoxelTemplate } from "../ArchivedVoxelTemplate";
3
+ import { NumberPalette } from "../../../Util/NumberPalette";
4
+ import { BinaryBuffer, BinaryBufferFormat, } from "../../../Util/BinaryBuffer/index";
5
+ import { VoxelArchivePalette } from "../../../Voxels/Archive/VoxelPaletteArechive";
6
+ import { VoxelTagsRegister } from "../../../Voxels/Data/VoxelTagsRegister";
7
+ import { VoxelLUT } from "../../../Voxels/Data/VoxelLUT";
8
+ import { EngineSettings } from "../../../Settings/EngineSettings";
9
+ /**
10
+ * Converts a FullVoxelTemplateData into an ArchivedVoxelTemplate.
11
+ */
12
+ export default function CreateArchivedTemplateFromFull(fullData) {
13
+ const index = Flat3DIndex.GetXZYOrder();
14
+ index.setBounds(fullData.bounds.x, fullData.bounds.y, fullData.bounds.z);
15
+ const levelPalette = new NumberPalette();
16
+ const voxelPalette = new VoxelArchivePalette();
17
+ const secondaryPalette = new NumberPalette();
18
+ const ids = new Uint16Array(index.size);
19
+ const levels = new Uint8Array(index.size);
20
+ const secondary = new Uint16Array(index.size);
21
+ let idsAllTheSame = true;
22
+ let levelAllTheSame = true;
23
+ let secondaryAllTheSame = true;
24
+ let firstId = -1;
25
+ let firstLevel = -1;
26
+ let firstSecondary = -1;
27
+ let hasAnyVoxels = false;
28
+ for (let i = 0; i < index.size; i++) {
29
+ const rawId = fullData.ids[i];
30
+ const voxelId = voxelPalette.register(rawId);
31
+ const level = fullData.level[i];
32
+ const levelId = !levelPalette.isRegistered(level)
33
+ ? levelPalette.register(level)
34
+ : levelPalette.getId(level);
35
+ let voxelSecondary = 0;
36
+ const rawSecondary = fullData.secondary[i];
37
+ if (rawSecondary !== 0 &&
38
+ VoxelTagsRegister.VoxelTags[VoxelLUT.voxelIdToTrueId[rawId]]["dve_can_have_secondary"]) {
39
+ voxelSecondary = voxelPalette.register(rawSecondary);
40
+ if (!secondaryPalette.isRegistered(voxelSecondary))
41
+ secondaryPalette.register(voxelSecondary);
42
+ }
43
+ if (!hasAnyVoxels)
44
+ hasAnyVoxels = true;
45
+ if (firstId === -1)
46
+ firstId = voxelId;
47
+ if (firstLevel === -1)
48
+ firstLevel = levelId;
49
+ if (firstSecondary === -1)
50
+ firstSecondary = voxelSecondary;
51
+ ids[i] = voxelId;
52
+ levels[i] = levelId;
53
+ secondary[i] = voxelSecondary;
54
+ if (firstId !== voxelId)
55
+ idsAllTheSame = false;
56
+ if (firstLevel !== levelId)
57
+ levelAllTheSame = false;
58
+ if (firstSecondary !== voxelSecondary)
59
+ secondaryAllTheSame = false;
60
+ }
61
+ const buffers = {};
62
+ const idsPaletted = voxelPalette.size < 0xffff;
63
+ const levelPaletted = levelPalette.size < 0xff;
64
+ const secondaryPaletted = secondaryPalette.size < 0xffff;
65
+ // ids
66
+ if (idsAllTheSame) {
67
+ if (hasAnyVoxels) {
68
+ buffers.ids = BinaryBuffer.Create({
69
+ format: BinaryBufferFormat.Uint16,
70
+ byteLength: ids.length,
71
+ buffer: ids[0],
72
+ });
73
+ }
74
+ }
75
+ else if (idsPaletted) {
76
+ const type = BinaryBuffer.DetermineSubByteArray(voxelPalette.size);
77
+ buffers.ids = BinaryBuffer.Create({
78
+ buffer: BinaryBuffer.Convert(ids, BinaryBufferFormat.Uint16, type).buffer,
79
+ format: type,
80
+ byteLength: ids.length,
81
+ });
82
+ }
83
+ else {
84
+ buffers.ids = BinaryBuffer.Create({
85
+ buffer: ids.buffer,
86
+ format: BinaryBufferFormat.Uint16,
87
+ byteLength: ids.length,
88
+ });
89
+ }
90
+ // level
91
+ if (levelAllTheSame) {
92
+ if (hasAnyVoxels) {
93
+ buffers.level = BinaryBuffer.Create({
94
+ format: BinaryBufferFormat.Uint8,
95
+ byteLength: levels.length,
96
+ buffer: levels[0],
97
+ });
98
+ }
99
+ }
100
+ else if (levelPaletted) {
101
+ const type = BinaryBuffer.DetermineSubByteArray(levelPalette.size);
102
+ buffers.level = BinaryBuffer.Create({
103
+ buffer: BinaryBuffer.Convert(levels, BinaryBufferFormat.Uint8, type)
104
+ .buffer,
105
+ format: type,
106
+ });
107
+ }
108
+ else {
109
+ buffers.level = BinaryBuffer.Create({
110
+ buffer: levels.buffer,
111
+ format: BinaryBufferFormat.Uint8,
112
+ });
113
+ }
114
+ // secondary
115
+ if (secondaryAllTheSame) {
116
+ if (hasAnyVoxels) {
117
+ buffers.secondary = BinaryBuffer.Create({
118
+ format: BinaryBufferFormat.Uint16,
119
+ byteLength: secondary.length,
120
+ buffer: secondary[0],
121
+ });
122
+ }
123
+ }
124
+ else if (secondaryPaletted) {
125
+ const type = BinaryBuffer.DetermineSubByteArray(voxelPalette.size);
126
+ buffers.secondary = BinaryBuffer.Create({
127
+ buffer: BinaryBuffer.Convert(secondary, BinaryBufferFormat.Uint16, type)
128
+ .buffer,
129
+ format: type,
130
+ });
131
+ }
132
+ else {
133
+ buffers.secondary = BinaryBuffer.Create({
134
+ buffer: secondary.buffer,
135
+ format: BinaryBufferFormat.Uint16,
136
+ });
137
+ }
138
+ const palettes = {
139
+ ...voxelPalette.toJSON(),
140
+ };
141
+ if (levelPalette.size > 0 &&
142
+ !(levelPalette.size === 1 && levelPalette._palette[0] === 0)) {
143
+ palettes.level = BinaryBuffer.Create({
144
+ format: BinaryBufferFormat.Uint8,
145
+ byteLength: levelPalette._palette.length,
146
+ buffer: Uint8Array.from(levelPalette._palette).buffer,
147
+ });
148
+ }
149
+ if (secondaryPalette.size > 0 &&
150
+ !(secondaryPalette.size === 1 && secondaryPalette._palette[0] === 0)) {
151
+ palettes.secondary = BinaryBuffer.Create({
152
+ format: BinaryBufferFormat.Uint16,
153
+ byteLength: secondaryPalette._palette.length,
154
+ buffer: Uint16Array.from(secondaryPalette._palette).buffer,
155
+ });
156
+ }
157
+ const data = {
158
+ type: "archived",
159
+ engineVersion: EngineSettings.version,
160
+ formatVersion: "",
161
+ dataKey: {
162
+ voxelPalette: VoxelArchivePalette.GetVoxelPaletteDataKey(),
163
+ arrayOrders: {
164
+ id: "YXZ",
165
+ level: "YXZ",
166
+ secondary: "YXZ",
167
+ },
168
+ },
169
+ bounds: Vector3Like.Create(fullData.bounds.x, fullData.bounds.y, fullData.bounds.z),
170
+ palettes,
171
+ buffers,
172
+ };
173
+ return new ArchivedVoxelTemplate(data);
174
+ }
@@ -0,0 +1,22 @@
1
+ import { Vec2Array } from "@amodx/math";
2
+ import { TextureAtlasIndex } from "./TextureAtlasIndex";
3
+ import { CompactedTextureNodeBaseData } from "Textures/Texture.types";
4
+ export declare class CompactedTextureReader {
5
+ canvas: HTMLCanvasElement;
6
+ context: CanvasRenderingContext2D;
7
+ atlasCanvas: HTMLCanvasElement;
8
+ atlasContext: CanvasRenderingContext2D;
9
+ textureCanvas: HTMLCanvasElement;
10
+ textureContext: CanvasRenderingContext2D;
11
+ index: TextureAtlasIndex;
12
+ atlasIndex: TextureAtlasIndex;
13
+ size: Vec2Array;
14
+ textureSize: Vec2Array;
15
+ constructor();
16
+ setSize(size: Vec2Array, textureSize: Vec2Array): void;
17
+ loadImage(path: string): Promise<boolean>;
18
+ getFinalImage(): HTMLImageElement;
19
+ writeImage(index: number, image: HTMLImageElement): void;
20
+ readImage(data: CompactedTextureNodeBaseData): Promise<HTMLImageElement>;
21
+ readImageAtIndex(index: number): Promise<HTMLImageElement>;
22
+ }
@@ -0,0 +1,90 @@
1
+ import { TextureAtlasIndex } from "./TextureAtlasIndex";
2
+ export class CompactedTextureReader {
3
+ canvas;
4
+ context;
5
+ atlasCanvas;
6
+ atlasContext;
7
+ textureCanvas;
8
+ textureContext;
9
+ index = new TextureAtlasIndex();
10
+ atlasIndex = new TextureAtlasIndex();
11
+ size;
12
+ textureSize;
13
+ constructor() {
14
+ this.canvas = document.createElement("canvas");
15
+ this.context = this.canvas.getContext("2d", {
16
+ willReadFrequently: true,
17
+ });
18
+ this.context.imageSmoothingEnabled = false;
19
+ this.atlasCanvas = document.createElement("canvas");
20
+ this.atlasContext = this.atlasCanvas.getContext("2d", {
21
+ willReadFrequently: true,
22
+ });
23
+ this.atlasContext.imageSmoothingEnabled = false;
24
+ this.textureCanvas = document.createElement("canvas");
25
+ this.textureContext = this.textureCanvas.getContext("2d", {
26
+ willReadFrequently: true,
27
+ });
28
+ this.textureContext.imageSmoothingEnabled = false;
29
+ if (!this.context)
30
+ throw new Error(`Error could not create CanvasRenderingContext2D`);
31
+ }
32
+ setSize(size, textureSize) {
33
+ this.index.setBounds([size[0] / textureSize[0], size[1] / textureSize[1]]);
34
+ this.size = size;
35
+ this.canvas.width = size[0];
36
+ this.canvas.height = size[1];
37
+ this.textureCanvas.width = textureSize[0];
38
+ this.textureCanvas.height = textureSize[1];
39
+ this.textureSize = textureSize;
40
+ }
41
+ loadImage(path) {
42
+ return new Promise((resolve, reject) => {
43
+ const image = new Image();
44
+ image.onerror = reject;
45
+ image.src = path;
46
+ image.onload = () => {
47
+ this.context.drawImage(image, 0, 0, this.canvas.width, this.canvas.height);
48
+ resolve(true);
49
+ };
50
+ });
51
+ }
52
+ getFinalImage() {
53
+ const image = new Image();
54
+ image.src = this.canvas.toDataURL("image/png");
55
+ return image;
56
+ }
57
+ writeImage(index, image) {
58
+ const [x, y] = this.index.getPosition(index);
59
+ this.context.drawImage(image, x * this.textureSize[0], y * this.textureSize[1], this.textureSize[0], this.textureSize[1]);
60
+ }
61
+ async readImage(data) {
62
+ if (!Array.isArray(data.index)) {
63
+ return this.readImageAtIndex(data.index);
64
+ }
65
+ const atlas = data.atlas;
66
+ this.atlasCanvas.width = atlas[0] * this.textureSize[0];
67
+ this.atlasCanvas.height = atlas[1] * this.textureSize[1];
68
+ this.atlasContext.clearRect(0, 0, this.atlasCanvas.width, this.atlasCanvas.height);
69
+ this.atlasIndex.setBounds(atlas);
70
+ const startIndex = data.index[0];
71
+ for (const index of data.index) {
72
+ const [x, y] = this.atlasIndex.getPosition(index - startIndex);
73
+ const image = await this.readImageAtIndex(index);
74
+ this.atlasContext.drawImage(image, x * this.textureSize[0], y * this.textureSize[1], this.textureSize[0], this.textureSize[1]);
75
+ }
76
+ const image = new Image();
77
+ image.src = this.atlasCanvas.toDataURL("image/png");
78
+ return image;
79
+ }
80
+ async readImageAtIndex(index) {
81
+ const tileWidth = this.textureSize[0];
82
+ const tileHeight = this.textureSize[1];
83
+ const [x, y] = this.index.getPosition(index);
84
+ this.textureContext.clearRect(0, 0, tileWidth, tileHeight);
85
+ this.textureContext.drawImage(this.canvas, x * tileWidth, y * tileHeight, tileWidth, tileHeight, 0, 0, tileWidth, tileHeight);
86
+ const image = new Image();
87
+ image.src = this.textureCanvas.toDataURL("image/png");
88
+ return image;
89
+ }
90
+ }
@@ -6,7 +6,6 @@ export declare class CompiledTexture {
6
6
  id: string;
7
7
  static GetAtlasIndex: (x: number, y: number, boundsX: number) => number;
8
8
  static GetAtlasPosition: (index: number, boundsX: number, position?: Vec2Array) => Vec2Array;
9
- originalImages: HTMLImageElement[];
10
9
  images: HTMLImageElement[];
11
10
  /**Maps texture ids to their atlas sizes */
12
11
  atlasSizeMap: Record<string, [width: number, height: number]>;
@@ -19,5 +18,9 @@ export declare class CompiledTexture {
19
18
  constructor(id: string);
20
19
  getTextureIndex(id: TextureId): number;
21
20
  getTexturePath(id: TextureId): string;
21
+ canvas: HTMLCanvasElement;
22
+ context: CanvasRenderingContext2D;
23
+ private setUpCanvas;
22
24
  getTextureData(id: TextureId): Promise<Uint8ClampedArray>;
25
+ getTextureDataSync(id: TextureId): Uint8ClampedArray;
23
26
  }
@@ -7,7 +7,6 @@ export class CompiledTexture {
7
7
  position[0] = Math.floor(index % boundsX);
8
8
  return position;
9
9
  };
10
- originalImages = [];
11
10
  images = [];
12
11
  /**Maps texture ids to their atlas sizes */
13
12
  atlasSizeMap = {};
@@ -54,18 +53,47 @@ export class CompiledTexture {
54
53
  getTexturePath(id) {
55
54
  return this.images[this.getTextureIndex(id)].src;
56
55
  }
56
+ canvas;
57
+ context;
58
+ setUpCanvas() {
59
+ if (this.canvas)
60
+ return;
61
+ this.canvas = document.createElement("canvas");
62
+ this.context = this.canvas.getContext("2d", {
63
+ willReadFrequently: true,
64
+ });
65
+ }
57
66
  async getTextureData(id) {
58
- const path = this.originalImages[this.getTextureIndex(id)].src;
67
+ this.setUpCanvas();
68
+ const path = this.images[this.getTextureIndex(id)].src;
59
69
  const res = await fetch(path);
60
70
  if (!res.ok)
61
71
  throw new Error(`Failed to fetch texture: ${path}`);
62
72
  const blob = await res.blob();
63
73
  const bitmap = await createImageBitmap(blob);
64
- const canvas = new OffscreenCanvas(bitmap.width, bitmap.height);
65
- const ctx = canvas.getContext("2d");
66
- if (!ctx)
67
- throw new Error("OffscreenCanvas context unavailable");
68
- ctx.drawImage(bitmap, 0, 0);
69
- return ctx.getImageData(0, 0, bitmap.width, bitmap.height).data;
74
+ this.canvas.width = bitmap.width;
75
+ this.canvas.height = bitmap.height;
76
+ this.context.translate(0, bitmap.height);
77
+ this.context.scale(1, -1);
78
+ this.context.drawImage(bitmap, 0, 0);
79
+ return this.context.getImageData(0, 0, bitmap.width, bitmap.height).data;
80
+ }
81
+ getTextureDataSync(id) {
82
+ this.setUpCanvas();
83
+ const img = this.images[this.getTextureIndex(id)];
84
+ if (!img) {
85
+ throw new Error(`Texture image not found for ID: ${id}`);
86
+ }
87
+ if (!img.complete || img.naturalWidth === 0) {
88
+ throw new Error(`Texture image is not fully loaded yet: ${img.src}`);
89
+ }
90
+ const width = img.naturalWidth;
91
+ const height = img.naturalHeight;
92
+ this.canvas.width = width;
93
+ this.canvas.height = height;
94
+ this.context.translate(0, height);
95
+ this.context.scale(1, -1);
96
+ this.context.drawImage(img, 0, 0);
97
+ return this.context.getImageData(0, 0, width, height).data;
70
98
  }
71
99
  }
@@ -0,0 +1,7 @@
1
+ import { Vec2Array } from "@amodx/math";
2
+ export declare class TextureAtlasIndex {
3
+ bounds: Vec2Array;
4
+ setBounds(bounds: Vec2Array): void;
5
+ getIndex(x: number, y: number): number;
6
+ getPosition(index: number, position?: Vec2Array): Vec2Array;
7
+ }
@@ -0,0 +1,14 @@
1
+ export class TextureAtlasIndex {
2
+ bounds = [0, 0];
3
+ setBounds(bounds) {
4
+ this.bounds = bounds;
5
+ }
6
+ getIndex(x, y) {
7
+ return x + y * this.bounds[0];
8
+ }
9
+ getPosition(index, position = [0, 0]) {
10
+ position[0] = Math.floor(index % this.bounds[0]);
11
+ position[1] = Math.floor(index / this.bounds[0]);
12
+ return position;
13
+ }
14
+ }
@@ -0,0 +1,20 @@
1
+ import { Vec2Array } from "@amodx/math";
2
+ import { TextureData } from "../Texture.types";
3
+ import { TextureAtlasIndex } from "./TextureAtlasIndex";
4
+ export declare class TextureLoader {
5
+ baseURL: string;
6
+ canvas: HTMLCanvasElement;
7
+ context: CanvasRenderingContext2D;
8
+ atlasCanvas: HTMLCanvasElement;
9
+ atlasContext: CanvasRenderingContext2D;
10
+ size: Vec2Array;
11
+ atlasIndex: TextureAtlasIndex;
12
+ constructor();
13
+ setSize(size: Vec2Array): void;
14
+ getImageBase64(url: string): Promise<string>;
15
+ loadImage(src: string): Promise<HTMLImageElement>;
16
+ sliceImageIntoTiles(src: string, tilesX: number, tilesY: number): Promise<HTMLImageElement[]>;
17
+ getImagePath(data: TextureData, parentId?: string | null): string;
18
+ getTextureId(data: TextureData, parentId?: string | null): string;
19
+ loadImageForShader(imgSrcData: string | HTMLImageElement): Promise<HTMLImageElement>;
20
+ }
@@ -0,0 +1,95 @@
1
+ import { TextureAtlasIndex } from "./TextureAtlasIndex";
2
+ export class TextureLoader {
3
+ baseURL = "assets/textures";
4
+ canvas;
5
+ context;
6
+ atlasCanvas;
7
+ atlasContext;
8
+ size;
9
+ atlasIndex = new TextureAtlasIndex();
10
+ constructor() {
11
+ this.canvas = document.createElement("canvas");
12
+ this.context = this.canvas.getContext("2d", {
13
+ willReadFrequently: true,
14
+ });
15
+ this.context.imageSmoothingEnabled = false;
16
+ this.atlasCanvas = document.createElement("canvas");
17
+ this.atlasContext = this.atlasCanvas.getContext("2d", {
18
+ willReadFrequently: true,
19
+ });
20
+ if (!this.context)
21
+ throw new Error(`Error could not create CanvasRenderingContext2D`);
22
+ }
23
+ setSize(size) {
24
+ this.size = size;
25
+ this.canvas.width = size[0];
26
+ this.canvas.height = size[1];
27
+ }
28
+ async getImageBase64(url) {
29
+ const response = await fetch(url);
30
+ const blob = await response.blob();
31
+ return new Promise((resolve, reject) => {
32
+ const reader = new FileReader();
33
+ reader.readAsDataURL(blob);
34
+ reader.onloadend = () => resolve(reader.result);
35
+ reader.onerror = reject;
36
+ });
37
+ }
38
+ loadImage(src) {
39
+ return new Promise((resolve, reject) => {
40
+ const img = new Image();
41
+ img.src = src;
42
+ img.onload = () => resolve(img);
43
+ img.onerror = reject;
44
+ });
45
+ }
46
+ async sliceImageIntoTiles(src, tilesX, tilesY) {
47
+ const image = await this.loadImage(src);
48
+ this.atlasIndex.setBounds([tilesX, tilesY]);
49
+ const tileWidth = image.width / tilesX;
50
+ const tileHeight = image.height / tilesY;
51
+ this.atlasCanvas.width = tileWidth;
52
+ this.atlasCanvas.height = tileHeight;
53
+ const tiles = [];
54
+ for (let x = 0; x < tilesX; x++) {
55
+ for (let y = 0; y < tilesY; y++) {
56
+ this.atlasContext.clearRect(0, 0, tileWidth, tileHeight);
57
+ this.atlasContext.drawImage(image, x * tileWidth, y * tileHeight, tileWidth, tileHeight, 0, 0, tileWidth, tileHeight);
58
+ tiles[this.atlasIndex.getIndex(x, y)] = await this.loadImage(this.atlasCanvas.toDataURL("image/png"));
59
+ }
60
+ }
61
+ return tiles;
62
+ }
63
+ getImagePath(data, parentId = null) {
64
+ if (data.base64)
65
+ return data.base64;
66
+ if (data.path)
67
+ return data.path;
68
+ if (!parentId)
69
+ return `${this.baseURL}/${data.id}.png`;
70
+ return `${this.baseURL}/${parentId}/${data.id}.png`;
71
+ }
72
+ getTextureId(data, parentId = null) {
73
+ return `${parentId ? parentId : data.id}${!parentId ? "" : ":" + data.id}`;
74
+ }
75
+ async loadImageForShader(imgSrcData) {
76
+ return new Promise((resolve, reject) => {
77
+ const image = typeof imgSrcData === "string" ? new Image() : imgSrcData;
78
+ image.onerror = reject;
79
+ if (typeof imgSrcData === "string")
80
+ image.src = imgSrcData;
81
+ image.onload = () => {
82
+ this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
83
+ this.context.save();
84
+ this.context.translate(0, this.canvas.height);
85
+ this.context.scale(1, -1);
86
+ this.context.drawImage(image, 0, 0, this.canvas.width, this.canvas.height);
87
+ this.context.restore();
88
+ const dataUrl = this.canvas.toDataURL("image/png");
89
+ const returnImage = new Image(this.canvas.width, this.canvas.height);
90
+ returnImage.src = dataUrl;
91
+ returnImage.onload = () => resolve(returnImage);
92
+ };
93
+ });
94
+ }
95
+ }
@@ -8,4 +8,4 @@ export type BuildTextureDataProps = {
8
8
  textures: TextureData[];
9
9
  finalSize?: [width: number, height: number];
10
10
  };
11
- export declare function BuildTextureData({ type, baseURL: currentBaseURL, textures, finalSize: currentFinalSize, createCache, }: BuildTextureDataProps, progress: WorkItemProgress): Promise<CompiledTexture>;
11
+ export declare function BuildTextureData({ type, baseURL, textures, finalSize, createCache }: BuildTextureDataProps, progress: WorkItemProgress): Promise<CompiledTexture>;