minecraft-renderer 0.1.0

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 (187) hide show
  1. package/README.md +297 -0
  2. package/dist/index.html +83 -0
  3. package/dist/static/image/arrow.6f27b59f.png +0 -0
  4. package/dist/static/image/blocksAtlasLatest.7850afa3.png +0 -0
  5. package/dist/static/image/blocksAtlasLegacy.5c76823d.png +0 -0
  6. package/dist/static/image/itemsAtlasLatest.36036f95.png +0 -0
  7. package/dist/static/image/itemsAtlasLegacy.dcb1b58d.png +0 -0
  8. package/dist/static/image/tipped_arrow.6f27b59f.png +0 -0
  9. package/dist/static/js/365.f05233ab.js +8462 -0
  10. package/dist/static/js/365.f05233ab.js.LICENSE.txt +52 -0
  11. package/dist/static/js/async/738.efa27644.js +1 -0
  12. package/dist/static/js/index.092ec5be.js +56 -0
  13. package/dist/static/js/lib-polyfill.98986ac5.js +1 -0
  14. package/dist/static/js/lib-react.5c9129e0.js +2 -0
  15. package/dist/static/js/lib-react.5c9129e0.js.LICENSE.txt +39 -0
  16. package/package.json +104 -0
  17. package/src/assets/destroy_stage_0.png +0 -0
  18. package/src/assets/destroy_stage_1.png +0 -0
  19. package/src/assets/destroy_stage_2.png +0 -0
  20. package/src/assets/destroy_stage_3.png +0 -0
  21. package/src/assets/destroy_stage_4.png +0 -0
  22. package/src/assets/destroy_stage_5.png +0 -0
  23. package/src/assets/destroy_stage_6.png +0 -0
  24. package/src/assets/destroy_stage_7.png +0 -0
  25. package/src/assets/destroy_stage_8.png +0 -0
  26. package/src/assets/destroy_stage_9.png +0 -0
  27. package/src/examples/README.md +146 -0
  28. package/src/examples/appViewerExample.ts +205 -0
  29. package/src/examples/initialMenuStart.ts +161 -0
  30. package/src/graphicsBackend/appViewer.ts +297 -0
  31. package/src/graphicsBackend/config.ts +119 -0
  32. package/src/graphicsBackend/index.ts +10 -0
  33. package/src/graphicsBackend/playerState.ts +61 -0
  34. package/src/graphicsBackend/types.ts +143 -0
  35. package/src/index.ts +97 -0
  36. package/src/lib/DebugGui.ts +190 -0
  37. package/src/lib/animationController.ts +85 -0
  38. package/src/lib/buildSharedConfig.mjs +1 -0
  39. package/src/lib/cameraBobbing.ts +94 -0
  40. package/src/lib/canvas2DOverlay.example.ts +361 -0
  41. package/src/lib/canvas2DOverlay.quickstart.ts +242 -0
  42. package/src/lib/canvas2DOverlay.ts +381 -0
  43. package/src/lib/cleanupDecorator.ts +29 -0
  44. package/src/lib/createPlayerObject.ts +55 -0
  45. package/src/lib/frameTimingCollector.ts +164 -0
  46. package/src/lib/guiRenderer.ts +283 -0
  47. package/src/lib/items.ts +140 -0
  48. package/src/lib/mesherlogReader.ts +131 -0
  49. package/src/lib/moreBlockDataGenerated.json +714 -0
  50. package/src/lib/preflatMap.json +1741 -0
  51. package/src/lib/simpleUtils.ts +40 -0
  52. package/src/lib/smoothSwitcher.ts +168 -0
  53. package/src/lib/spiral.ts +29 -0
  54. package/src/lib/ui/newStats.ts +120 -0
  55. package/src/lib/utils/proxy.ts +23 -0
  56. package/src/lib/utils/skins.ts +63 -0
  57. package/src/lib/utils.ts +76 -0
  58. package/src/lib/workerProxy.ts +342 -0
  59. package/src/lib/worldrendererCommon.ts +1088 -0
  60. package/src/mesher/mesher.ts +253 -0
  61. package/src/mesher/models.ts +769 -0
  62. package/src/mesher/modelsGeometryCommon.ts +142 -0
  63. package/src/mesher/shared.ts +80 -0
  64. package/src/mesher/standaloneRenderer.ts +270 -0
  65. package/src/mesher/test/a.ts +3 -0
  66. package/src/mesher/test/mesherTester.ts +76 -0
  67. package/src/mesher/test/playground.ts +19 -0
  68. package/src/mesher/test/test-perf.ts +74 -0
  69. package/src/mesher/test/tests.test.ts +56 -0
  70. package/src/mesher/world.ts +294 -0
  71. package/src/mesher/worldConstants.ts +1 -0
  72. package/src/modules/index.ts +11 -0
  73. package/src/modules/starfield.ts +313 -0
  74. package/src/modules/types.ts +110 -0
  75. package/src/playerState/playerState.ts +78 -0
  76. package/src/playerState/types.ts +36 -0
  77. package/src/playground/allEntitiesDebug.ts +170 -0
  78. package/src/playground/baseScene.ts +587 -0
  79. package/src/playground/mobileControls.tsx +268 -0
  80. package/src/playground/playground.html +83 -0
  81. package/src/playground/playground.ts +11 -0
  82. package/src/playground/playgroundUi.tsx +140 -0
  83. package/src/playground/reactUtils.ts +71 -0
  84. package/src/playground/scenes/allEntities.ts +13 -0
  85. package/src/playground/scenes/entities.ts +37 -0
  86. package/src/playground/scenes/floorRandom.ts +33 -0
  87. package/src/playground/scenes/frequentUpdates.ts +148 -0
  88. package/src/playground/scenes/geometryExport.ts +142 -0
  89. package/src/playground/scenes/index.ts +12 -0
  90. package/src/playground/scenes/lightingStarfield.ts +40 -0
  91. package/src/playground/scenes/main.ts +313 -0
  92. package/src/playground/scenes/railsCobweb.ts +14 -0
  93. package/src/playground/scenes/rotationIssue.ts +7 -0
  94. package/src/playground/scenes/slabsOptimization.ts +16 -0
  95. package/src/playground/scenes/transparencyIssue.ts +11 -0
  96. package/src/playground/shared.ts +79 -0
  97. package/src/resourcesManager/index.ts +5 -0
  98. package/src/resourcesManager/resourcesManager.ts +314 -0
  99. package/src/shims/minecraftData.ts +41 -0
  100. package/src/sign-renderer/index.html +21 -0
  101. package/src/sign-renderer/index.ts +216 -0
  102. package/src/sign-renderer/noop.js +1 -0
  103. package/src/sign-renderer/playground.ts +38 -0
  104. package/src/sign-renderer/tests.test.ts +69 -0
  105. package/src/sign-renderer/vite.config.ts +10 -0
  106. package/src/three/appShared.ts +75 -0
  107. package/src/three/bannerRenderer.ts +275 -0
  108. package/src/three/cameraShake.ts +120 -0
  109. package/src/three/cinimaticScript.ts +350 -0
  110. package/src/three/documentRenderer.ts +491 -0
  111. package/src/three/entities.ts +1580 -0
  112. package/src/three/entity/EntityMesh.ts +707 -0
  113. package/src/three/entity/animations.js +171 -0
  114. package/src/three/entity/armorModels.json +204 -0
  115. package/src/three/entity/armorModels.ts +36 -0
  116. package/src/three/entity/entities.json +6230 -0
  117. package/src/three/entity/exportedModels.js +38 -0
  118. package/src/three/entity/externalTextures.json +1 -0
  119. package/src/three/entity/models/allay.obj +325 -0
  120. package/src/three/entity/models/arrow.obj +60 -0
  121. package/src/three/entity/models/axolotl.obj +509 -0
  122. package/src/three/entity/models/blaze.obj +601 -0
  123. package/src/three/entity/models/boat.obj +417 -0
  124. package/src/three/entity/models/camel.obj +1061 -0
  125. package/src/three/entity/models/cat.obj +509 -0
  126. package/src/three/entity/models/chicken.obj +371 -0
  127. package/src/three/entity/models/cod.obj +371 -0
  128. package/src/three/entity/models/creeper.obj +279 -0
  129. package/src/three/entity/models/dolphin.obj +371 -0
  130. package/src/three/entity/models/ender_dragon.obj +2993 -0
  131. package/src/three/entity/models/enderman.obj +325 -0
  132. package/src/three/entity/models/endermite.obj +187 -0
  133. package/src/three/entity/models/fox.obj +463 -0
  134. package/src/three/entity/models/frog.obj +739 -0
  135. package/src/three/entity/models/ghast.obj +463 -0
  136. package/src/three/entity/models/goat.obj +601 -0
  137. package/src/three/entity/models/guardian.obj +1015 -0
  138. package/src/three/entity/models/horse.obj +1061 -0
  139. package/src/three/entity/models/llama.obj +509 -0
  140. package/src/three/entity/models/minecart.obj +233 -0
  141. package/src/three/entity/models/parrot.obj +509 -0
  142. package/src/three/entity/models/piglin.obj +739 -0
  143. package/src/three/entity/models/pillager.obj +371 -0
  144. package/src/three/entity/models/rabbit.obj +555 -0
  145. package/src/three/entity/models/sheep.obj +555 -0
  146. package/src/three/entity/models/shulker.obj +141 -0
  147. package/src/three/entity/models/sniffer.obj +693 -0
  148. package/src/three/entity/models/spider.obj +509 -0
  149. package/src/three/entity/models/tadpole.obj +95 -0
  150. package/src/three/entity/models/turtle.obj +371 -0
  151. package/src/three/entity/models/vex.obj +325 -0
  152. package/src/three/entity/models/villager.obj +509 -0
  153. package/src/three/entity/models/warden.obj +463 -0
  154. package/src/three/entity/models/witch.obj +647 -0
  155. package/src/three/entity/models/wolf.obj +509 -0
  156. package/src/three/entity/models/zombie_villager.obj +463 -0
  157. package/src/three/entity/objModels.js +1 -0
  158. package/src/three/fireworks.ts +661 -0
  159. package/src/three/fireworksRenderer.ts +434 -0
  160. package/src/three/globals.d.ts +7 -0
  161. package/src/three/graphicsBackend.ts +274 -0
  162. package/src/three/graphicsBackendOffThread.ts +107 -0
  163. package/src/three/hand.ts +89 -0
  164. package/src/three/holdingBlock.ts +926 -0
  165. package/src/three/index.ts +20 -0
  166. package/src/three/itemMesh.ts +427 -0
  167. package/src/three/modules.d.ts +14 -0
  168. package/src/three/panorama.ts +308 -0
  169. package/src/three/panoramaShared.ts +1 -0
  170. package/src/three/renderSlot.ts +82 -0
  171. package/src/three/skyboxRenderer.ts +406 -0
  172. package/src/three/starField.ts +13 -0
  173. package/src/three/threeJsMedia.ts +731 -0
  174. package/src/three/threeJsMethods.ts +15 -0
  175. package/src/three/threeJsParticles.ts +160 -0
  176. package/src/three/threeJsSound.ts +95 -0
  177. package/src/three/threeJsUtils.ts +90 -0
  178. package/src/three/waypointSprite.ts +435 -0
  179. package/src/three/waypoints.ts +163 -0
  180. package/src/three/world/cursorBlock.ts +172 -0
  181. package/src/three/world/vr.ts +257 -0
  182. package/src/three/worldGeometryExport.ts +259 -0
  183. package/src/three/worldGeometryHandler.ts +279 -0
  184. package/src/three/worldRendererThree.ts +1381 -0
  185. package/src/worldView/index.ts +6 -0
  186. package/src/worldView/types.ts +66 -0
  187. package/src/worldView/worldView.ts +424 -0
@@ -0,0 +1,142 @@
1
+ import { BlockModelPartsResolved } from './world'
2
+
3
+ export type BlockElement = NonNullable<BlockModelPartsResolved[0][0]['elements']>[0]
4
+
5
+
6
+ export function buildRotationMatrix (axis, degree) {
7
+ const radians = degree / 180 * Math.PI
8
+ const cos = Math.cos(radians)
9
+ const sin = Math.sin(radians)
10
+
11
+ const axis0 = { x: 0, y: 1, z: 2 }[axis]
12
+ const axis1 = (axis0 + 1) % 3
13
+ const axis2 = (axis0 + 2) % 3
14
+
15
+ const matrix = [
16
+ [0, 0, 0],
17
+ [0, 0, 0],
18
+ [0, 0, 0]
19
+ ]
20
+
21
+ matrix[axis0][axis0] = 1
22
+ matrix[axis1][axis1] = cos
23
+ matrix[axis1][axis2] = -sin
24
+ matrix[axis2][axis1] = +sin
25
+ matrix[axis2][axis2] = cos
26
+
27
+ return matrix
28
+ }
29
+
30
+ export function vecadd3 (a, b) {
31
+ if (!b) return a
32
+ return [a[0] + b[0], a[1] + b[1], a[2] + b[2]]
33
+ }
34
+
35
+ export function vecsub3 (a, b) {
36
+ if (!b) return a
37
+ return [a[0] - b[0], a[1] - b[1], a[2] - b[2]]
38
+ }
39
+
40
+ export function matmul3 (matrix, vector): [number, number, number] {
41
+ if (!matrix) return vector
42
+ return [
43
+ matrix[0][0] * vector[0] + matrix[0][1] * vector[1] + matrix[0][2] * vector[2],
44
+ matrix[1][0] * vector[0] + matrix[1][1] * vector[1] + matrix[1][2] * vector[2],
45
+ matrix[2][0] * vector[0] + matrix[2][1] * vector[1] + matrix[2][2] * vector[2]
46
+ ]
47
+ }
48
+
49
+ export function matmulmat3 (a, b) {
50
+ const te = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
51
+
52
+ const a11 = a[0][0]; const a12 = a[1][0]; const a13 = a[2][0]
53
+ const a21 = a[0][1]; const a22 = a[1][1]; const a23 = a[2][1]
54
+ const a31 = a[0][2]; const a32 = a[1][2]; const a33 = a[2][2]
55
+
56
+ const b11 = b[0][0]; const b12 = b[1][0]; const b13 = b[2][0]
57
+ const b21 = b[0][1]; const b22 = b[1][1]; const b23 = b[2][1]
58
+ const b31 = b[0][2]; const b32 = b[1][2]; const b33 = b[2][2]
59
+
60
+ te[0][0] = a11 * b11 + a12 * b21 + a13 * b31
61
+ te[1][0] = a11 * b12 + a12 * b22 + a13 * b32
62
+ te[2][0] = a11 * b13 + a12 * b23 + a13 * b33
63
+
64
+ te[0][1] = a21 * b11 + a22 * b21 + a23 * b31
65
+ te[1][1] = a21 * b12 + a22 * b22 + a23 * b32
66
+ te[2][1] = a21 * b13 + a22 * b23 + a23 * b33
67
+
68
+ te[0][2] = a31 * b11 + a32 * b21 + a33 * b31
69
+ te[1][2] = a31 * b12 + a32 * b22 + a33 * b32
70
+ te[2][2] = a31 * b13 + a32 * b23 + a33 * b33
71
+
72
+ return te
73
+ }
74
+
75
+ export const elemFaces = {
76
+ up: {
77
+ dir: [0, 1, 0],
78
+ mask1: [1, 1, 0],
79
+ mask2: [0, 1, 1],
80
+ corners: [
81
+ [0, 1, 1, 0, 1],
82
+ [1, 1, 1, 1, 1],
83
+ [0, 1, 0, 0, 0],
84
+ [1, 1, 0, 1, 0]
85
+ ]
86
+ },
87
+ down: {
88
+ dir: [0, -1, 0],
89
+ mask1: [1, 1, 0],
90
+ mask2: [0, 1, 1],
91
+ corners: [
92
+ [1, 0, 1, 0, 1],
93
+ [0, 0, 1, 1, 1],
94
+ [1, 0, 0, 0, 0],
95
+ [0, 0, 0, 1, 0]
96
+ ]
97
+ },
98
+ east: {
99
+ dir: [1, 0, 0],
100
+ mask1: [1, 1, 0],
101
+ mask2: [1, 0, 1],
102
+ corners: [
103
+ [1, 1, 1, 0, 0],
104
+ [1, 0, 1, 0, 1],
105
+ [1, 1, 0, 1, 0],
106
+ [1, 0, 0, 1, 1]
107
+ ]
108
+ },
109
+ west: {
110
+ dir: [-1, 0, 0],
111
+ mask1: [1, 1, 0],
112
+ mask2: [1, 0, 1],
113
+ corners: [
114
+ [0, 1, 0, 0, 0],
115
+ [0, 0, 0, 0, 1],
116
+ [0, 1, 1, 1, 0],
117
+ [0, 0, 1, 1, 1]
118
+ ]
119
+ },
120
+ north: {
121
+ dir: [0, 0, -1],
122
+ mask1: [1, 0, 1],
123
+ mask2: [0, 1, 1],
124
+ corners: [
125
+ [1, 0, 0, 1, 1],
126
+ [0, 0, 0, 0, 1],
127
+ [1, 1, 0, 1, 0],
128
+ [0, 1, 0, 0, 0]
129
+ ]
130
+ },
131
+ south: {
132
+ dir: [0, 0, 1],
133
+ mask1: [1, 0, 1],
134
+ mask2: [0, 1, 1],
135
+ corners: [
136
+ [0, 0, 1, 0, 1],
137
+ [1, 0, 1, 1, 1],
138
+ [0, 1, 1, 0, 0],
139
+ [1, 1, 1, 1, 0]
140
+ ]
141
+ }
142
+ }
@@ -0,0 +1,80 @@
1
+ import { BlockType } from '../../../playground/shared'
2
+
3
+ // only here for easier testing
4
+ export const defaultMesherConfig = {
5
+ version: '',
6
+ worldMaxY: 256,
7
+ worldMinY: 0,
8
+ enableLighting: true,
9
+ skyLight: 15,
10
+ smoothLighting: false,
11
+ outputFormat: 'threeJs' as 'threeJs' | 'webgpu',
12
+ // textureSize: 1024, // for testing
13
+ debugModelVariant: undefined as undefined | number[],
14
+ clipWorldBelowY: undefined as undefined | number,
15
+ disableBlockEntityTextures: false
16
+ }
17
+
18
+ export type CustomBlockModels = {
19
+ [blockPosKey: string]: string // blockPosKey is "x,y,z" -> model name
20
+ }
21
+
22
+ export type MesherConfig = typeof defaultMesherConfig
23
+
24
+ export type MesherGeometryOutput = {
25
+ sectionYNumber: number,
26
+ chunkKey: string,
27
+ sectionStartY: number,
28
+ sectionEndY: number,
29
+ sectionStartX: number,
30
+ sectionEndX: number,
31
+ sectionStartZ: number,
32
+ sectionEndZ: number,
33
+ // three.js
34
+ sx: number,
35
+ sy: number,
36
+ sz: number,
37
+ // resulting: float32array
38
+ positions: any,
39
+ normals: any,
40
+ colors: any,
41
+ uvs: any,
42
+ t_positions?: number[],
43
+ t_normals?: number[],
44
+ t_colors?: number[],
45
+ t_uvs?: number[],
46
+
47
+ indices: Uint32Array | Uint16Array | number[],
48
+ indicesCount: number,
49
+ using32Array: boolean,
50
+ tiles: Record<string, BlockType>,
51
+ heads: Record<string, any>,
52
+ signs: Record<string, any>,
53
+ banners: Record<string, any>,
54
+ // isFull: boolean
55
+ hadErrors: boolean
56
+ blocksCount: number
57
+ customBlockModels?: CustomBlockModels
58
+ }
59
+
60
+ export interface MesherMainEvents {
61
+ geometry: { type: 'geometry'; key: string; geometry: MesherGeometryOutput; workerIndex: number };
62
+ sectionFinished: { type: 'sectionFinished'; key: string; workerIndex: number; processTime?: number };
63
+ blockStateModelInfo: { type: 'blockStateModelInfo'; info: Record<string, BlockStateModelInfo> };
64
+ heightmap: { type: 'heightmap'; key: string; heightmap: Uint8Array };
65
+ }
66
+
67
+ export type MesherMainEvent = MesherMainEvents[keyof MesherMainEvents]
68
+
69
+ export type HighestBlockInfo = { y: number, stateId: number | undefined, biomeId: number | undefined }
70
+
71
+ export type BlockStateModelInfo = {
72
+ cacheKey: string
73
+ issues: string[]
74
+ modelNames: string[]
75
+ conditions: string[]
76
+ }
77
+
78
+ export const getBlockAssetsCacheKey = (stateId: number, modelNameOverride?: string) => {
79
+ return modelNameOverride ? `${stateId}:${modelNameOverride}` : String(stateId)
80
+ }
@@ -0,0 +1,270 @@
1
+ /* eslint-disable @stylistic/function-call-argument-newline */
2
+ import { Vec3 } from 'vec3'
3
+ import { Block } from 'prismarine-block'
4
+ import { IndexedData } from 'minecraft-data'
5
+ import * as THREE from 'three'
6
+ import { BlockModelPartsResolved } from './world'
7
+ import { BlockElement, buildRotationMatrix, elemFaces, matmul3, matmulmat3, vecadd3, vecsub3 } from './modelsGeometryCommon'
8
+
9
+ type NeighborSide = 'up' | 'down' | 'east' | 'west' | 'north' | 'south'
10
+
11
+ function tintToGl (tint) {
12
+ const r = (tint >> 16) & 0xff
13
+ const g = (tint >> 8) & 0xff
14
+ const b = tint & 0xff
15
+ return [r / 255, g / 255, b / 255]
16
+ }
17
+
18
+ type Neighbors = Partial<Record<NeighborSide, boolean>>
19
+ function renderElement (element: BlockElement, doAO: boolean, attr, globalMatrix, globalShift, block: Block | undefined, biome: string, neighbors: Neighbors) {
20
+ const cursor = new Vec3(0, 0, 0)
21
+
22
+ // const key = `${position.x},${position.y},${position.z}`
23
+ // if (!globalThis.allowedBlocks.includes(key)) return
24
+ // const cullIfIdentical = block.name.indexOf('glass') >= 0
25
+
26
+ // eslint-disable-next-line guard-for-in
27
+ for (const face in element.faces) {
28
+ const eFace = element.faces[face]
29
+ const { corners, mask1, mask2 } = elemFaces[face]
30
+ const dir = matmul3(globalMatrix, elemFaces[face].dir)
31
+
32
+ if (eFace.cullface) {
33
+ if (neighbors[face]) continue
34
+ }
35
+
36
+ const minx = element.from[0]
37
+ const miny = element.from[1]
38
+ const minz = element.from[2]
39
+ const maxx = element.to[0]
40
+ const maxy = element.to[1]
41
+ const maxz = element.to[2]
42
+
43
+ const texture = eFace.texture as any
44
+ const { u } = texture
45
+ const { v } = texture
46
+ const { su } = texture
47
+ const { sv } = texture
48
+
49
+ const ndx = Math.floor(attr.positions.length / 3)
50
+
51
+ let tint = [1, 1, 1]
52
+ if (eFace.tintindex !== undefined) {
53
+ if (eFace.tintindex === 0) {
54
+ // TODO
55
+ // if (block.name === 'redstone_wire') {
56
+ // tint = tints.redstone[`${block.getProperties().power}`]
57
+ // } else if (block.name === 'birch_leaves' ||
58
+ // block.name === 'spruce_leaves' ||
59
+ // block.name === 'lily_pad') {
60
+ // tint = tints.constant[block.name]
61
+ // } else if (block.name.includes('leaves') || block.name === 'vine') {
62
+ // tint = tints.foliage[biome]
63
+ // } else {
64
+ // tint = tints.grass[biome]
65
+ // }
66
+ const grassTint = [145 / 255, 189 / 255, 89 / 255]
67
+ tint = grassTint
68
+ }
69
+ }
70
+
71
+ // UV rotation
72
+ const r = eFace.rotation || 0
73
+ const uvcs = Math.cos(r * Math.PI / 180)
74
+ const uvsn = -Math.sin(r * Math.PI / 180)
75
+
76
+ let localMatrix = null as any
77
+ let localShift = null as any
78
+
79
+ if (element.rotation) {
80
+ // todo do we support rescale?
81
+ localMatrix = buildRotationMatrix(
82
+ element.rotation.axis,
83
+ element.rotation.angle
84
+ )
85
+
86
+ localShift = vecsub3(
87
+ element.rotation.origin,
88
+ matmul3(
89
+ localMatrix,
90
+ element.rotation.origin
91
+ )
92
+ )
93
+ }
94
+
95
+ const aos: number[] = []
96
+ // const neighborPos = position.plus(new Vec3(...dir))
97
+ // const baseLight = world.getLight(neighborPos, undefined, undefined, block.name) / 15
98
+ const baseLight = 1
99
+ for (const pos of corners) {
100
+ let vertex = [
101
+ (pos[0] ? maxx : minx),
102
+ (pos[1] ? maxy : miny),
103
+ (pos[2] ? maxz : minz)
104
+ ]
105
+
106
+ vertex = vecadd3(matmul3(localMatrix, vertex), localShift)
107
+ vertex = vecadd3(matmul3(globalMatrix, vertex), globalShift)
108
+ vertex = vertex.map(v => v / 16)
109
+
110
+ attr.positions.push(
111
+ vertex[0]/* + (cursor.x & 15) - 8 */,
112
+ vertex[1]/* + (cursor.y & 15) x */,
113
+ vertex[2]/* + (cursor.z & 15) - 8 */
114
+ )
115
+
116
+ attr.normals.push(...dir)
117
+
118
+ const baseu = (pos[3] - 0.5) * uvcs - (pos[4] - 0.5) * uvsn + 0.5
119
+ const basev = (pos[3] - 0.5) * uvsn + (pos[4] - 0.5) * uvcs + 0.5
120
+ attr.uvs.push(baseu * su + u, basev * sv + v)
121
+
122
+ let light = 1
123
+ if (doAO) {
124
+ const cornerLightResult = 15
125
+
126
+ const side1Block = 0
127
+ const side2Block = 0
128
+ const cornerBlock = 0
129
+
130
+ const ao = (side1Block && side2Block) ? 0 : (3 - (side1Block + side2Block + cornerBlock))
131
+ // todo light should go upper on lower blocks
132
+ light = (ao + 1) / 4 * (cornerLightResult / 15)
133
+ aos.push(ao)
134
+ }
135
+
136
+ attr.colors.push(baseLight * tint[0] * light, baseLight * tint[1] * light, baseLight * tint[2] * light)
137
+ }
138
+
139
+ // if (needTiles) {
140
+ // attr.tiles[`${cursor.x},${cursor.y},${cursor.z}`] ??= {
141
+ // block: block.name,
142
+ // faces: [],
143
+ // }
144
+ // attr.tiles[`${cursor.x},${cursor.y},${cursor.z}`].faces.push({
145
+ // face,
146
+ // neighbor: `${neighborPos.x},${neighborPos.y},${neighborPos.z}`,
147
+ // light: baseLight
148
+ // // texture: eFace.texture.name,
149
+ // })
150
+ // }
151
+
152
+ if (doAO && aos[0] + aos[3] >= aos[1] + aos[2]) {
153
+ attr.indices.push(
154
+
155
+ ndx, ndx + 3, ndx + 2,
156
+ ndx, ndx + 1, ndx + 3
157
+ )
158
+ } else {
159
+ attr.indices.push(
160
+
161
+ ndx, ndx + 1, ndx + 2,
162
+ ndx + 2, ndx + 1, ndx + 3
163
+ )
164
+ }
165
+ }
166
+ }
167
+
168
+ export const renderBlockThreeAttr = (models: BlockModelPartsResolved, block: Block | undefined, biome: string, mcData: IndexedData, variants = [], neighbors: Neighbors = {}) => {
169
+ const sx = 0
170
+ const sy = 0
171
+ const sz = 0
172
+
173
+ const attr = {
174
+ sx: sx + 0.5,
175
+ sy: sy + 0.5,
176
+ sz: sz + 0.5,
177
+ positions: [],
178
+ normals: [],
179
+ colors: [],
180
+ uvs: [],
181
+ t_positions: [],
182
+ t_normals: [],
183
+ t_colors: [],
184
+ t_uvs: [],
185
+ indices: [],
186
+ tiles: {},
187
+ } as Record<string, any>
188
+
189
+ for (const [i, modelVars] of models.entries()) {
190
+ const model = modelVars[variants[i]] ?? modelVars[0]
191
+ if (!model) continue
192
+ let globalMatrix = null as any
193
+ let globalShift = null as any
194
+ for (const axis of ['x', 'y', 'z'] as const) {
195
+ if (axis in model) {
196
+ if (globalMatrix) { globalMatrix = matmulmat3(globalMatrix, buildRotationMatrix(axis, -(model[axis] ?? 0))) } else { globalMatrix = buildRotationMatrix(axis, -(model[axis] ?? 0)) }
197
+ }
198
+ }
199
+ if (globalMatrix) {
200
+ globalShift = [8, 8, 8]
201
+ globalShift = vecsub3(globalShift, matmul3(globalMatrix, globalShift))
202
+ }
203
+
204
+ const ao = model.ao ?? true
205
+
206
+ for (const element of model.elements ?? []) {
207
+ renderElement(element, ao, attr, globalMatrix, globalShift, block, biome, neighbors)
208
+ }
209
+ }
210
+
211
+ let ndx = attr.positions.length / 3
212
+ for (let i = 0; i < attr.t_positions.length / 12; i++) {
213
+ attr.indices.push(
214
+ ndx, ndx + 1, ndx + 2, ndx + 2, ndx + 1, ndx + 3,
215
+ // back face
216
+ ndx, ndx + 2, ndx + 1, ndx + 2, ndx + 3, ndx + 1
217
+ )
218
+ ndx += 4
219
+ }
220
+
221
+ attr.positions.push(...attr.t_positions)
222
+ attr.normals.push(...attr.t_normals)
223
+ attr.colors.push(...attr.t_colors)
224
+ attr.uvs.push(...attr.t_uvs)
225
+
226
+ delete attr.t_positions
227
+ delete attr.t_normals
228
+ delete attr.t_colors
229
+ delete attr.t_uvs
230
+
231
+ attr.positions = new Float32Array(attr.positions) as any
232
+ attr.normals = new Float32Array(attr.normals) as any
233
+ attr.colors = new Float32Array(attr.colors) as any
234
+ attr.uvs = new Float32Array(attr.uvs) as any
235
+
236
+ return attr
237
+ }
238
+
239
+ export const renderBlockThree = (...args: Parameters<typeof renderBlockThreeAttr>) => {
240
+ const attr = renderBlockThreeAttr(...args)
241
+ const data = {
242
+ geometry: attr
243
+ }
244
+
245
+ const geometry = new THREE.BufferGeometry()
246
+ geometry.setAttribute('position', new THREE.BufferAttribute(data.geometry.positions, 3))
247
+ geometry.setAttribute('normal', new THREE.BufferAttribute(data.geometry.normals, 3))
248
+ geometry.setAttribute('color', new THREE.BufferAttribute(data.geometry.colors, 3))
249
+ geometry.setAttribute('uv', new THREE.BufferAttribute(data.geometry.uvs, 2))
250
+ geometry.setIndex(data.geometry.indices)
251
+ geometry.name = 'block-geometry'
252
+
253
+ return geometry
254
+ }
255
+
256
+ export const getThreeBlockModelGroup = (material: THREE.Material, ...args: Parameters<typeof renderBlockThree>) => {
257
+ const geometry = renderBlockThree(...args)
258
+ const mesh = new THREE.Mesh(geometry, material)
259
+ mesh.position.set(-0.5, -0.5, -0.5)
260
+ const group = new THREE.Group()
261
+ group.add(mesh)
262
+ group.rotation.set(0, -THREE.MathUtils.degToRad(90), 0, 'ZYX')
263
+ globalThis.mesh = group
264
+ return group
265
+ // return new THREE.Mesh(new THREE.BoxGeometry(1, 1, 1), new THREE.MeshPhongMaterial({ color: 0x00_00_ff, transparent: true, opacity: 0.5 }))
266
+ }
267
+
268
+ export const setBlockPosition = (object: THREE.Object3D, position: { x: number, y: number, z: number }) => {
269
+ object.position.set(position.x + 0.5, position.y + 0.5, position.z + 0.5)
270
+ }
@@ -0,0 +1,3 @@
1
+ import {MaxRectsPacker } from 'maxrects-packer'
2
+
3
+ console.log('test', MaxRectsPacker)
@@ -0,0 +1,76 @@
1
+ import ChunkLoader, { PCChunk } from 'prismarine-chunk'
2
+ import { Vec3 } from 'vec3'
3
+ import MinecraftData from 'minecraft-data'
4
+ import blocksAtlasesJson from 'mc-assets/dist/blocksAtlases.json'
5
+ import { World as MesherWorld } from '../world'
6
+ import { setBlockStatesData, getSectionGeometry } from '../models'
7
+
8
+ export const setup = (version, initialBlocks: Array<[number[], string]>) => {
9
+ const mcData = MinecraftData(version)
10
+ const blockStatesModels = require(`mc-assets/dist/blockStatesModels.json`)
11
+ const mesherWorld = new MesherWorld(version)
12
+ const Chunk = ChunkLoader(version)
13
+ const chunk1 = new Chunk(undefined as any)
14
+
15
+ const pos = new Vec3(2, 5, 2)
16
+ for (const [addPos, name] of initialBlocks) {
17
+ chunk1.setBlockStateId(pos.offset(addPos[0], addPos[1], addPos[2]), mcData.blocksByName[name].defaultState)
18
+ }
19
+
20
+ const getGeometry = () => {
21
+ const sectionGeometry = getSectionGeometry(0, 0, 0, mesherWorld)
22
+ const centerFaces = sectionGeometry.tiles[`${pos.x},${pos.y},${pos.z}`]?.faces.length ?? 0
23
+ const totalTiles = Object.values(sectionGeometry.tiles).reduce((acc, val: any) => acc + val.faces.length, 0)
24
+ const centerTileNeighbors = Object.entries(sectionGeometry.tiles).reduce((acc, [key, val]: any) => {
25
+ return acc + val.faces.filter((face: any) => face.neighbor === `${pos.x},${pos.y},${pos.z}`).length
26
+ }, 0)
27
+ return {
28
+ centerFaces,
29
+ totalTiles,
30
+ centerTileNeighbors,
31
+ faces: sectionGeometry.tiles[`${pos.x},${pos.y},${pos.z}`]?.faces ?? [],
32
+ attr: sectionGeometry
33
+ }
34
+ }
35
+
36
+ setBlockStatesData(blockStatesModels, blocksAtlasesJson, true, false, version)
37
+ const reload = () => {
38
+ mesherWorld.removeColumn(0, 0)
39
+ mesherWorld.addColumn(0, 0, chunk1.toJson())
40
+ }
41
+ reload()
42
+
43
+ const getLights = () => {
44
+ return Object.fromEntries(getGeometry().faces.map(({ face, light }) => ([face, (light ?? 0) * 15 - 2])))
45
+ }
46
+
47
+ const setLight = (x: number, y: number, z: number, val = 0) => {
48
+ // create columns first
49
+ chunk1.setBlockLight(pos.offset(x, y, z), 15)
50
+ chunk1.setSkyLight(pos.offset(x, y, z), 15)
51
+ chunk1.setBlockLight(pos.offset(x, y, z), val)
52
+ chunk1.setSkyLight(pos.offset(x, y, z), 0)
53
+ }
54
+
55
+ return {
56
+ mesherWorld,
57
+ setLight,
58
+ getLights,
59
+ getGeometry,
60
+ pos,
61
+ mcData,
62
+ reload,
63
+ chunk: chunk1 as PCChunk
64
+ }
65
+ }
66
+
67
+ // surround it
68
+ const addPositions = [
69
+ // [[0, 0, 0], 'diamond_block'],
70
+ [[1, 0, 0], 'stone'],
71
+ [[-1, 0, 0], 'stone'],
72
+ [[0, 1, 0], 'stone'],
73
+ [[0, -1, 0], 'stone'],
74
+ [[0, 0, 1], 'stone'],
75
+ [[0, 0, -1], 'stone'],
76
+ ]
@@ -0,0 +1,19 @@
1
+ import { setup } from './mesherTester'
2
+
3
+ const addPositions = [
4
+ // [[0, 0, 0], 'diamond_block'],
5
+ [[1, 0, 0], 'stone'],
6
+ [[-1, 0, 0], 'stone'],
7
+ [[0, 1, 0], 'stone'],
8
+ [[0, -1, 0], 'stone'],
9
+ [[0, 0, 1], 'stone'],
10
+ [[0, 0, -1], 'stone'],
11
+ ] as const
12
+
13
+ const { mesherWorld, getGeometry, pos, mcData } = setup('1.21.1', addPositions as any)
14
+
15
+ // mesherWorld.setBlockStateId(pos, 712)
16
+ // mesherWorld.setBlockStateId(pos, mcData.blocksByName.stone_slab.defaultState)
17
+ mesherWorld.setBlockStateId(pos, 11_225)
18
+
19
+ console.log(getGeometry().centerTileNeighbors)
@@ -0,0 +1,74 @@
1
+ import { generateSpiralMatrix } from 'flying-squid/dist/utils'
2
+ import PrismarineWorld from 'prismarine-world'
3
+ import PrismarineChunk from 'prismarine-chunk'
4
+ import { Vec3 } from 'vec3'
5
+ import MinecraftData from 'minecraft-data'
6
+ import { defaultMesherConfig } from '../shared'
7
+ import { setup } from './mesherTester.js'
8
+
9
+ // const version = '1.8.8'
10
+ const version = '1.21.1'
11
+ const World = PrismarineWorld(version)
12
+ const Chunk = PrismarineChunk(version)
13
+ const data = MinecraftData(version)
14
+
15
+ const { chunk, getGeometry, reload } = setup(version, [])
16
+
17
+ const fillers = {
18
+ // 10 iterations no smooth light 66ms m1 pro
19
+ worstPossibleFull () {
20
+ for (let x = 0; x < 16; x++) {
21
+ for (let z = 0; z < 16; z++) {
22
+ for (let y = -64; y < 320; y++) {
23
+ // Create a 3D checkerboard pattern where each block is surrounded by air
24
+ const isEvalPoint = (x % 3 === 0) && (z % 3 === 0) && (y % 3 === 0)
25
+ // chunk.setBlockStateId(new Vec3(x, y, z), isEvalPoint ? 1 : 0)
26
+ chunk.setBlockType(new Vec3(x, y, z), isEvalPoint ? 1 : 0)
27
+ }
28
+ }
29
+ }
30
+ },
31
+ allFilled () {
32
+ for (let x = 0; x < 16; x++) {
33
+ for (let z = 0; z < 16; z++) {
34
+ for (let y = -64; y < 320; y++) {
35
+ chunk.setBlockType(new Vec3(x, y, z), 1)
36
+ }
37
+ }
38
+ }
39
+ }
40
+ }
41
+
42
+ defaultMesherConfig.enableLighting = true
43
+ defaultMesherConfig.smoothLighting = false
44
+
45
+ fillers.worstPossibleFull()
46
+ reload()
47
+
48
+ const sectionsY = Math.floor(384 / 16)
49
+ const chunks = generateSpiralMatrix(5).length
50
+ // const sections = chunks * sectionsY
51
+ const sections = 10
52
+
53
+ const testIterations = 10 * 16 * 16 * 16 * 6
54
+
55
+ console.time('iterate')
56
+ // for (let i = 0; i < testIterations; i++) {
57
+ // const a = new Vec3(Math.random(), Math.random(), Math.random())
58
+ // a[0]
59
+ // }
60
+
61
+ for (let i = 0; i < sections; i++) {
62
+ const { totalTiles } = getGeometry()
63
+ console.log('totalTiles', totalTiles)
64
+ // for (let x = 0; x < 16; x++) {
65
+ // for (let z = 0; z < 16; z++) {
66
+ // for (let y = -64; y < 320; y++) {
67
+ // world.getBlockStateId(new Vec3(x, y, z))
68
+ // }
69
+ // }
70
+ // }
71
+ }
72
+ console.timeEnd('iterate')
73
+ console.log(globalThis.tasksTiming)
74
+ console.log(sections)