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.
- package/README.md +297 -0
- package/dist/index.html +83 -0
- package/dist/static/image/arrow.6f27b59f.png +0 -0
- package/dist/static/image/blocksAtlasLatest.7850afa3.png +0 -0
- package/dist/static/image/blocksAtlasLegacy.5c76823d.png +0 -0
- package/dist/static/image/itemsAtlasLatest.36036f95.png +0 -0
- package/dist/static/image/itemsAtlasLegacy.dcb1b58d.png +0 -0
- package/dist/static/image/tipped_arrow.6f27b59f.png +0 -0
- package/dist/static/js/365.f05233ab.js +8462 -0
- package/dist/static/js/365.f05233ab.js.LICENSE.txt +52 -0
- package/dist/static/js/async/738.efa27644.js +1 -0
- package/dist/static/js/index.092ec5be.js +56 -0
- package/dist/static/js/lib-polyfill.98986ac5.js +1 -0
- package/dist/static/js/lib-react.5c9129e0.js +2 -0
- package/dist/static/js/lib-react.5c9129e0.js.LICENSE.txt +39 -0
- package/package.json +104 -0
- package/src/assets/destroy_stage_0.png +0 -0
- package/src/assets/destroy_stage_1.png +0 -0
- package/src/assets/destroy_stage_2.png +0 -0
- package/src/assets/destroy_stage_3.png +0 -0
- package/src/assets/destroy_stage_4.png +0 -0
- package/src/assets/destroy_stage_5.png +0 -0
- package/src/assets/destroy_stage_6.png +0 -0
- package/src/assets/destroy_stage_7.png +0 -0
- package/src/assets/destroy_stage_8.png +0 -0
- package/src/assets/destroy_stage_9.png +0 -0
- package/src/examples/README.md +146 -0
- package/src/examples/appViewerExample.ts +205 -0
- package/src/examples/initialMenuStart.ts +161 -0
- package/src/graphicsBackend/appViewer.ts +297 -0
- package/src/graphicsBackend/config.ts +119 -0
- package/src/graphicsBackend/index.ts +10 -0
- package/src/graphicsBackend/playerState.ts +61 -0
- package/src/graphicsBackend/types.ts +143 -0
- package/src/index.ts +97 -0
- package/src/lib/DebugGui.ts +190 -0
- package/src/lib/animationController.ts +85 -0
- package/src/lib/buildSharedConfig.mjs +1 -0
- package/src/lib/cameraBobbing.ts +94 -0
- package/src/lib/canvas2DOverlay.example.ts +361 -0
- package/src/lib/canvas2DOverlay.quickstart.ts +242 -0
- package/src/lib/canvas2DOverlay.ts +381 -0
- package/src/lib/cleanupDecorator.ts +29 -0
- package/src/lib/createPlayerObject.ts +55 -0
- package/src/lib/frameTimingCollector.ts +164 -0
- package/src/lib/guiRenderer.ts +283 -0
- package/src/lib/items.ts +140 -0
- package/src/lib/mesherlogReader.ts +131 -0
- package/src/lib/moreBlockDataGenerated.json +714 -0
- package/src/lib/preflatMap.json +1741 -0
- package/src/lib/simpleUtils.ts +40 -0
- package/src/lib/smoothSwitcher.ts +168 -0
- package/src/lib/spiral.ts +29 -0
- package/src/lib/ui/newStats.ts +120 -0
- package/src/lib/utils/proxy.ts +23 -0
- package/src/lib/utils/skins.ts +63 -0
- package/src/lib/utils.ts +76 -0
- package/src/lib/workerProxy.ts +342 -0
- package/src/lib/worldrendererCommon.ts +1088 -0
- package/src/mesher/mesher.ts +253 -0
- package/src/mesher/models.ts +769 -0
- package/src/mesher/modelsGeometryCommon.ts +142 -0
- package/src/mesher/shared.ts +80 -0
- package/src/mesher/standaloneRenderer.ts +270 -0
- package/src/mesher/test/a.ts +3 -0
- package/src/mesher/test/mesherTester.ts +76 -0
- package/src/mesher/test/playground.ts +19 -0
- package/src/mesher/test/test-perf.ts +74 -0
- package/src/mesher/test/tests.test.ts +56 -0
- package/src/mesher/world.ts +294 -0
- package/src/mesher/worldConstants.ts +1 -0
- package/src/modules/index.ts +11 -0
- package/src/modules/starfield.ts +313 -0
- package/src/modules/types.ts +110 -0
- package/src/playerState/playerState.ts +78 -0
- package/src/playerState/types.ts +36 -0
- package/src/playground/allEntitiesDebug.ts +170 -0
- package/src/playground/baseScene.ts +587 -0
- package/src/playground/mobileControls.tsx +268 -0
- package/src/playground/playground.html +83 -0
- package/src/playground/playground.ts +11 -0
- package/src/playground/playgroundUi.tsx +140 -0
- package/src/playground/reactUtils.ts +71 -0
- package/src/playground/scenes/allEntities.ts +13 -0
- package/src/playground/scenes/entities.ts +37 -0
- package/src/playground/scenes/floorRandom.ts +33 -0
- package/src/playground/scenes/frequentUpdates.ts +148 -0
- package/src/playground/scenes/geometryExport.ts +142 -0
- package/src/playground/scenes/index.ts +12 -0
- package/src/playground/scenes/lightingStarfield.ts +40 -0
- package/src/playground/scenes/main.ts +313 -0
- package/src/playground/scenes/railsCobweb.ts +14 -0
- package/src/playground/scenes/rotationIssue.ts +7 -0
- package/src/playground/scenes/slabsOptimization.ts +16 -0
- package/src/playground/scenes/transparencyIssue.ts +11 -0
- package/src/playground/shared.ts +79 -0
- package/src/resourcesManager/index.ts +5 -0
- package/src/resourcesManager/resourcesManager.ts +314 -0
- package/src/shims/minecraftData.ts +41 -0
- package/src/sign-renderer/index.html +21 -0
- package/src/sign-renderer/index.ts +216 -0
- package/src/sign-renderer/noop.js +1 -0
- package/src/sign-renderer/playground.ts +38 -0
- package/src/sign-renderer/tests.test.ts +69 -0
- package/src/sign-renderer/vite.config.ts +10 -0
- package/src/three/appShared.ts +75 -0
- package/src/three/bannerRenderer.ts +275 -0
- package/src/three/cameraShake.ts +120 -0
- package/src/three/cinimaticScript.ts +350 -0
- package/src/three/documentRenderer.ts +491 -0
- package/src/three/entities.ts +1580 -0
- package/src/three/entity/EntityMesh.ts +707 -0
- package/src/three/entity/animations.js +171 -0
- package/src/three/entity/armorModels.json +204 -0
- package/src/three/entity/armorModels.ts +36 -0
- package/src/three/entity/entities.json +6230 -0
- package/src/three/entity/exportedModels.js +38 -0
- package/src/three/entity/externalTextures.json +1 -0
- package/src/three/entity/models/allay.obj +325 -0
- package/src/three/entity/models/arrow.obj +60 -0
- package/src/three/entity/models/axolotl.obj +509 -0
- package/src/three/entity/models/blaze.obj +601 -0
- package/src/three/entity/models/boat.obj +417 -0
- package/src/three/entity/models/camel.obj +1061 -0
- package/src/three/entity/models/cat.obj +509 -0
- package/src/three/entity/models/chicken.obj +371 -0
- package/src/three/entity/models/cod.obj +371 -0
- package/src/three/entity/models/creeper.obj +279 -0
- package/src/three/entity/models/dolphin.obj +371 -0
- package/src/three/entity/models/ender_dragon.obj +2993 -0
- package/src/three/entity/models/enderman.obj +325 -0
- package/src/three/entity/models/endermite.obj +187 -0
- package/src/three/entity/models/fox.obj +463 -0
- package/src/three/entity/models/frog.obj +739 -0
- package/src/three/entity/models/ghast.obj +463 -0
- package/src/three/entity/models/goat.obj +601 -0
- package/src/three/entity/models/guardian.obj +1015 -0
- package/src/three/entity/models/horse.obj +1061 -0
- package/src/three/entity/models/llama.obj +509 -0
- package/src/three/entity/models/minecart.obj +233 -0
- package/src/three/entity/models/parrot.obj +509 -0
- package/src/three/entity/models/piglin.obj +739 -0
- package/src/three/entity/models/pillager.obj +371 -0
- package/src/three/entity/models/rabbit.obj +555 -0
- package/src/three/entity/models/sheep.obj +555 -0
- package/src/three/entity/models/shulker.obj +141 -0
- package/src/three/entity/models/sniffer.obj +693 -0
- package/src/three/entity/models/spider.obj +509 -0
- package/src/three/entity/models/tadpole.obj +95 -0
- package/src/three/entity/models/turtle.obj +371 -0
- package/src/three/entity/models/vex.obj +325 -0
- package/src/three/entity/models/villager.obj +509 -0
- package/src/three/entity/models/warden.obj +463 -0
- package/src/three/entity/models/witch.obj +647 -0
- package/src/three/entity/models/wolf.obj +509 -0
- package/src/three/entity/models/zombie_villager.obj +463 -0
- package/src/three/entity/objModels.js +1 -0
- package/src/three/fireworks.ts +661 -0
- package/src/three/fireworksRenderer.ts +434 -0
- package/src/three/globals.d.ts +7 -0
- package/src/three/graphicsBackend.ts +274 -0
- package/src/three/graphicsBackendOffThread.ts +107 -0
- package/src/three/hand.ts +89 -0
- package/src/three/holdingBlock.ts +926 -0
- package/src/three/index.ts +20 -0
- package/src/three/itemMesh.ts +427 -0
- package/src/three/modules.d.ts +14 -0
- package/src/three/panorama.ts +308 -0
- package/src/three/panoramaShared.ts +1 -0
- package/src/three/renderSlot.ts +82 -0
- package/src/three/skyboxRenderer.ts +406 -0
- package/src/three/starField.ts +13 -0
- package/src/three/threeJsMedia.ts +731 -0
- package/src/three/threeJsMethods.ts +15 -0
- package/src/three/threeJsParticles.ts +160 -0
- package/src/three/threeJsSound.ts +95 -0
- package/src/three/threeJsUtils.ts +90 -0
- package/src/three/waypointSprite.ts +435 -0
- package/src/three/waypoints.ts +163 -0
- package/src/three/world/cursorBlock.ts +172 -0
- package/src/three/world/vr.ts +257 -0
- package/src/three/worldGeometryExport.ts +259 -0
- package/src/three/worldGeometryHandler.ts +279 -0
- package/src/three/worldRendererThree.ts +1381 -0
- package/src/worldView/index.ts +6 -0
- package/src/worldView/types.ts +66 -0
- package/src/worldView/worldView.ts +424 -0
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EXAMPLES: How to use Canvas2DOverlay with Three.js
|
|
3
|
+
* Works in both main thread and Web Workers!
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import * as THREE from 'three'
|
|
7
|
+
import { DocumentRenderer } from '../three/documentRenderer'
|
|
8
|
+
import { Canvas2DOverlay, WebGLDirect2DOverlay } from './canvas2DOverlay'
|
|
9
|
+
|
|
10
|
+
// ============================================
|
|
11
|
+
// EXAMPLE 1: Simple Black Box (100px) at Bottom Left
|
|
12
|
+
// ============================================
|
|
13
|
+
export function example1_SimpleBlackBox(documentRenderer: DocumentRenderer) {
|
|
14
|
+
const overlay = new Canvas2DOverlay(documentRenderer.renderer, documentRenderer.canvas)
|
|
15
|
+
|
|
16
|
+
// Register to render overlay after main scene
|
|
17
|
+
documentRenderer.onRender.push((sizeChanged) => {
|
|
18
|
+
if (sizeChanged) {
|
|
19
|
+
overlay.updateSize(documentRenderer.canvas.width, documentRenderer.canvas.height)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
overlay.clear()
|
|
23
|
+
|
|
24
|
+
// Draw black box at bottom-left corner
|
|
25
|
+
// Position is from TOP-left, so for bottom we calculate from height
|
|
26
|
+
const boxSize = 100
|
|
27
|
+
const x = 10 // 10px from left
|
|
28
|
+
const y = documentRenderer.canvas.height - boxSize - 10 // 10px from bottom
|
|
29
|
+
|
|
30
|
+
overlay.drawRect(x, y, boxSize, boxSize, 0x000000, 0.8) // Black with 80% opacity
|
|
31
|
+
|
|
32
|
+
overlay.render()
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
return overlay
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// ============================================
|
|
39
|
+
// EXAMPLE 2: FPS Counter with Background
|
|
40
|
+
// ============================================
|
|
41
|
+
export function example2_FPSCounter(documentRenderer: DocumentRenderer) {
|
|
42
|
+
const overlay = new Canvas2DOverlay(documentRenderer.renderer, documentRenderer.canvas)
|
|
43
|
+
|
|
44
|
+
let fps = 0
|
|
45
|
+
let lastTime = performance.now()
|
|
46
|
+
let frameCount = 0
|
|
47
|
+
|
|
48
|
+
documentRenderer.onRender.push((sizeChanged) => {
|
|
49
|
+
if (sizeChanged) {
|
|
50
|
+
overlay.updateSize(documentRenderer.canvas.width, documentRenderer.canvas.height)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Calculate FPS
|
|
54
|
+
frameCount++
|
|
55
|
+
const now = performance.now()
|
|
56
|
+
if (now - lastTime >= 1000) {
|
|
57
|
+
fps = Math.round((frameCount * 1000) / (now - lastTime))
|
|
58
|
+
frameCount = 0
|
|
59
|
+
lastTime = now
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
overlay.clear()
|
|
63
|
+
|
|
64
|
+
// Background box
|
|
65
|
+
overlay.drawRect(10, 10, 120, 40, 0x000000, 0.7)
|
|
66
|
+
|
|
67
|
+
// FPS text
|
|
68
|
+
overlay.drawText(`FPS: ${fps}`, 15, 15, {
|
|
69
|
+
fontSize: 20,
|
|
70
|
+
color: fps > 50 ? '#00ff00' : fps > 30 ? '#ffff00' : '#ff0000',
|
|
71
|
+
backgroundColor: 'transparent',
|
|
72
|
+
opacity: 1
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
overlay.render()
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
return overlay
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// ============================================
|
|
82
|
+
// EXAMPLE 3: Coordinate Display (Bottom-Left)
|
|
83
|
+
// ============================================
|
|
84
|
+
export function example3_CoordinateDisplay(
|
|
85
|
+
documentRenderer: DocumentRenderer,
|
|
86
|
+
getPosition: () => { x: number; y: number; z: number }
|
|
87
|
+
) {
|
|
88
|
+
const overlay = new Canvas2DOverlay(documentRenderer.renderer, documentRenderer.canvas)
|
|
89
|
+
|
|
90
|
+
documentRenderer.onRender.push((sizeChanged) => {
|
|
91
|
+
if (sizeChanged) {
|
|
92
|
+
overlay.updateSize(documentRenderer.canvas.width, documentRenderer.canvas.height)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const pos = getPosition()
|
|
96
|
+
|
|
97
|
+
overlay.clear()
|
|
98
|
+
|
|
99
|
+
// Bottom-left position display
|
|
100
|
+
const x = 10
|
|
101
|
+
const y = documentRenderer.canvas.height - 100
|
|
102
|
+
|
|
103
|
+
// Background
|
|
104
|
+
overlay.drawRect(x, y, 200, 80, 0x000000, 0.8)
|
|
105
|
+
|
|
106
|
+
// Coordinate text
|
|
107
|
+
overlay.drawText(`X: ${pos.x.toFixed(2)}`, x + 10, y + 10, {
|
|
108
|
+
fontSize: 16,
|
|
109
|
+
color: '#ffffff',
|
|
110
|
+
backgroundColor: 'transparent'
|
|
111
|
+
})
|
|
112
|
+
overlay.drawText(`Y: ${pos.y.toFixed(2)}`, x + 10, y + 35, {
|
|
113
|
+
fontSize: 16,
|
|
114
|
+
color: '#ffffff',
|
|
115
|
+
backgroundColor: 'transparent'
|
|
116
|
+
})
|
|
117
|
+
overlay.drawText(`Z: ${pos.z.toFixed(2)}`, x + 10, y + 60, {
|
|
118
|
+
fontSize: 16,
|
|
119
|
+
color: '#ffffff',
|
|
120
|
+
backgroundColor: 'transparent'
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
overlay.render()
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
return overlay
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// ============================================
|
|
130
|
+
// EXAMPLE 4: Mini-map (Top-Right Corner)
|
|
131
|
+
// ============================================
|
|
132
|
+
export function example4_MiniMap(
|
|
133
|
+
documentRenderer: DocumentRenderer,
|
|
134
|
+
playerPos: { x: number; z: number }
|
|
135
|
+
) {
|
|
136
|
+
const overlay = new Canvas2DOverlay(documentRenderer.renderer, documentRenderer.canvas)
|
|
137
|
+
|
|
138
|
+
documentRenderer.onRender.push((sizeChanged) => {
|
|
139
|
+
if (sizeChanged) {
|
|
140
|
+
overlay.updateSize(documentRenderer.canvas.width, documentRenderer.canvas.height)
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
overlay.clear()
|
|
144
|
+
|
|
145
|
+
const mapSize = 150
|
|
146
|
+
const x = documentRenderer.canvas.width - mapSize - 10
|
|
147
|
+
const y = 10
|
|
148
|
+
|
|
149
|
+
// Background
|
|
150
|
+
overlay.drawRect(x, y, mapSize, mapSize, 0x1a1a1a, 0.9)
|
|
151
|
+
|
|
152
|
+
// Border
|
|
153
|
+
overlay.drawRectOutline(x, y, mapSize, mapSize, 0x666666, 2)
|
|
154
|
+
|
|
155
|
+
// Player position (center dot)
|
|
156
|
+
const centerX = x + mapSize / 2
|
|
157
|
+
const centerY = y + mapSize / 2
|
|
158
|
+
overlay.drawCircle(centerX, centerY, 5, 0xff0000, 1)
|
|
159
|
+
|
|
160
|
+
// Compass directions
|
|
161
|
+
overlay.drawText('N', centerX - 5, y + 5, {
|
|
162
|
+
fontSize: 12,
|
|
163
|
+
color: '#ffffff',
|
|
164
|
+
backgroundColor: 'transparent'
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
overlay.render()
|
|
168
|
+
})
|
|
169
|
+
|
|
170
|
+
return overlay
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// ============================================
|
|
174
|
+
// EXAMPLE 5: Performance WebGL Direct Rendering
|
|
175
|
+
// ============================================
|
|
176
|
+
export function example5_DirectWebGL(documentRenderer: DocumentRenderer) {
|
|
177
|
+
const overlay = new WebGLDirect2DOverlay(documentRenderer.renderer, documentRenderer.canvas)
|
|
178
|
+
|
|
179
|
+
documentRenderer.onRender.push(() => {
|
|
180
|
+
// This renders directly with WebGL - very fast!
|
|
181
|
+
// After Three.js renders, draw on top
|
|
182
|
+
|
|
183
|
+
// Black box at bottom-left
|
|
184
|
+
overlay.drawRect(10, documentRenderer.canvas.height - 110, 100, 100, 0, 0, 0, 0.8)
|
|
185
|
+
|
|
186
|
+
// Red box at top-left
|
|
187
|
+
overlay.drawRect(10, 10, 50, 50, 1, 0, 0, 1)
|
|
188
|
+
|
|
189
|
+
// Semi-transparent blue box
|
|
190
|
+
overlay.drawRect(70, 10, 50, 50, 0, 0, 1, 0.5)
|
|
191
|
+
})
|
|
192
|
+
|
|
193
|
+
return overlay
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// ============================================
|
|
197
|
+
// EXAMPLE 6: Health/Status Bar
|
|
198
|
+
// ============================================
|
|
199
|
+
export function example6_HealthBar(
|
|
200
|
+
documentRenderer: DocumentRenderer,
|
|
201
|
+
getHealth: () => { current: number; max: number }
|
|
202
|
+
) {
|
|
203
|
+
const overlay = new Canvas2DOverlay(documentRenderer.renderer, documentRenderer.canvas)
|
|
204
|
+
|
|
205
|
+
documentRenderer.onRender.push((sizeChanged) => {
|
|
206
|
+
if (sizeChanged) {
|
|
207
|
+
overlay.updateSize(documentRenderer.canvas.width, documentRenderer.canvas.height)
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
const health = getHealth()
|
|
211
|
+
const healthPercent = health.current / health.max
|
|
212
|
+
|
|
213
|
+
overlay.clear()
|
|
214
|
+
|
|
215
|
+
// Position at bottom center
|
|
216
|
+
const barWidth = 200
|
|
217
|
+
const barHeight = 20
|
|
218
|
+
const x = (documentRenderer.canvas.width - barWidth) / 2
|
|
219
|
+
const y = documentRenderer.canvas.height - barHeight - 20
|
|
220
|
+
|
|
221
|
+
// Background (dark gray)
|
|
222
|
+
overlay.drawRect(x, y, barWidth, barHeight, 0x333333, 0.8)
|
|
223
|
+
|
|
224
|
+
// Health bar (red to green based on health)
|
|
225
|
+
const healthBarWidth = barWidth * healthPercent
|
|
226
|
+
const color = healthPercent > 0.5 ? 0x00ff00 : healthPercent > 0.25 ? 0xffff00 : 0xff0000
|
|
227
|
+
overlay.drawRect(x, y, healthBarWidth, barHeight, color, 0.9)
|
|
228
|
+
|
|
229
|
+
// Border
|
|
230
|
+
overlay.drawRectOutline(x, y, barWidth, barHeight, 0xffffff, 2)
|
|
231
|
+
|
|
232
|
+
// Text
|
|
233
|
+
overlay.drawText(`${health.current}/${health.max}`, x + barWidth / 2 - 30, y + 2, {
|
|
234
|
+
fontSize: 14,
|
|
235
|
+
color: '#ffffff',
|
|
236
|
+
backgroundColor: 'transparent'
|
|
237
|
+
})
|
|
238
|
+
|
|
239
|
+
overlay.render()
|
|
240
|
+
})
|
|
241
|
+
|
|
242
|
+
return overlay
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// ============================================
|
|
246
|
+
// EXAMPLE 7: Debug Grid Overlay
|
|
247
|
+
// ============================================
|
|
248
|
+
export function example7_DebugGrid(documentRenderer: DocumentRenderer) {
|
|
249
|
+
const overlay = new Canvas2DOverlay(documentRenderer.renderer, documentRenderer.canvas)
|
|
250
|
+
|
|
251
|
+
documentRenderer.onRender.push((sizeChanged) => {
|
|
252
|
+
if (sizeChanged) {
|
|
253
|
+
overlay.updateSize(documentRenderer.canvas.width, documentRenderer.canvas.height)
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
overlay.clear()
|
|
257
|
+
|
|
258
|
+
const gridSize = 50
|
|
259
|
+
const width = documentRenderer.canvas.width
|
|
260
|
+
const height = documentRenderer.canvas.height
|
|
261
|
+
|
|
262
|
+
// Draw vertical lines
|
|
263
|
+
for (let x = 0; x < width; x += gridSize) {
|
|
264
|
+
const points = [
|
|
265
|
+
new THREE.Vector3(x, 0, 0),
|
|
266
|
+
new THREE.Vector3(x, height, 0)
|
|
267
|
+
]
|
|
268
|
+
const geometry = new THREE.BufferGeometry().setFromPoints(points)
|
|
269
|
+
const material = new THREE.LineBasicMaterial({ color: 0x333333, opacity: 0.3, transparent: true })
|
|
270
|
+
const line = new THREE.Line(geometry, material)
|
|
271
|
+
overlay['overlayScene'].add(line)
|
|
272
|
+
overlay['overlayObjects'].push(line as any)
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// Draw horizontal lines
|
|
276
|
+
for (let y = 0; y < height; y += gridSize) {
|
|
277
|
+
const points = [
|
|
278
|
+
new THREE.Vector3(0, y, 0),
|
|
279
|
+
new THREE.Vector3(width, y, 0)
|
|
280
|
+
]
|
|
281
|
+
const geometry = new THREE.BufferGeometry().setFromPoints(points)
|
|
282
|
+
const material = new THREE.LineBasicMaterial({ color: 0x333333, opacity: 0.3, transparent: true })
|
|
283
|
+
const line = new THREE.Line(geometry, material)
|
|
284
|
+
overlay['overlayScene'].add(line)
|
|
285
|
+
overlay['overlayObjects'].push(line as any)
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
overlay.render()
|
|
289
|
+
})
|
|
290
|
+
|
|
291
|
+
return overlay
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// ============================================
|
|
295
|
+
// EXAMPLE 8: Simple Usage in DocumentRenderer
|
|
296
|
+
// ============================================
|
|
297
|
+
export function integrateWithDocumentRenderer(documentRenderer: DocumentRenderer) {
|
|
298
|
+
// Method 1: Using Three.js-based overlay (easier, more features)
|
|
299
|
+
const overlay = new Canvas2DOverlay(documentRenderer.renderer, documentRenderer.canvas)
|
|
300
|
+
|
|
301
|
+
// Add to render loop
|
|
302
|
+
const originalRender = documentRenderer.render
|
|
303
|
+
documentRenderer.render = (sizeChanged) => {
|
|
304
|
+
// Call original render
|
|
305
|
+
originalRender.call(documentRenderer, sizeChanged)
|
|
306
|
+
|
|
307
|
+
// Update overlay size if needed
|
|
308
|
+
if (sizeChanged) {
|
|
309
|
+
overlay.updateSize(documentRenderer.canvas.width, documentRenderer.canvas.height)
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// Clear previous frame
|
|
313
|
+
overlay.clear()
|
|
314
|
+
|
|
315
|
+
// Draw your 2D elements
|
|
316
|
+
const boxSize = 100
|
|
317
|
+
const x = 10
|
|
318
|
+
const y = documentRenderer.canvas.height - boxSize - 10
|
|
319
|
+
overlay.drawRect(x, y, boxSize, boxSize, 0x000000, 0.8)
|
|
320
|
+
|
|
321
|
+
// Render overlay
|
|
322
|
+
overlay.render()
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
return overlay
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
// ============================================
|
|
329
|
+
// EXAMPLE 9: Worker-Compatible Usage
|
|
330
|
+
// ============================================
|
|
331
|
+
export function workerCompatibleOverlay(documentRenderer: DocumentRenderer) {
|
|
332
|
+
// This works the same in both main thread and worker!
|
|
333
|
+
const overlay = new Canvas2DOverlay(documentRenderer.renderer, documentRenderer.canvas)
|
|
334
|
+
|
|
335
|
+
documentRenderer.onRender.push((sizeChanged) => {
|
|
336
|
+
if (sizeChanged) {
|
|
337
|
+
overlay.updateSize(documentRenderer.canvas.width, documentRenderer.canvas.height)
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
overlay.clear()
|
|
341
|
+
|
|
342
|
+
// Bottom-left black box
|
|
343
|
+
overlay.drawRect(10, documentRenderer.canvas.height - 110, 100, 100, 0x000000, 0.8)
|
|
344
|
+
|
|
345
|
+
// Add some text (works in worker because we use OffscreenCanvas!)
|
|
346
|
+
overlay.drawText('Worker Render', 15, documentRenderer.canvas.height - 100, {
|
|
347
|
+
fontSize: 12,
|
|
348
|
+
color: '#00ff00',
|
|
349
|
+
backgroundColor: 'transparent'
|
|
350
|
+
})
|
|
351
|
+
|
|
352
|
+
overlay.render()
|
|
353
|
+
})
|
|
354
|
+
|
|
355
|
+
return overlay
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* QUICK START: Add a black 100px box at bottom-left corner
|
|
3
|
+
*
|
|
4
|
+
* This is the minimal code needed to render 2D graphics on your Three.js canvas.
|
|
5
|
+
* Works in both main thread and Web Workers!
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { DocumentRenderer } from '../three/documentRenderer'
|
|
9
|
+
import { Canvas2DOverlay } from './canvas2DOverlay'
|
|
10
|
+
|
|
11
|
+
// ============================================
|
|
12
|
+
// STEP 1: Create the overlay
|
|
13
|
+
// ============================================
|
|
14
|
+
export function addBlackBoxOverlay(documentRenderer: DocumentRenderer) {
|
|
15
|
+
const overlay = new Canvas2DOverlay(
|
|
16
|
+
documentRenderer.renderer,
|
|
17
|
+
documentRenderer.canvas
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
// ============================================
|
|
21
|
+
// STEP 2: Hook into the render loop
|
|
22
|
+
// ============================================
|
|
23
|
+
documentRenderer.onRender.push((sizeChanged) => {
|
|
24
|
+
// Update overlay camera when canvas size changes
|
|
25
|
+
if (sizeChanged) {
|
|
26
|
+
overlay.updateSize(
|
|
27
|
+
documentRenderer.canvas.width,
|
|
28
|
+
documentRenderer.canvas.height
|
|
29
|
+
)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Clear previous frame's overlay
|
|
33
|
+
overlay.clear()
|
|
34
|
+
|
|
35
|
+
// ============================================
|
|
36
|
+
// STEP 3: Draw your 2D elements
|
|
37
|
+
// ============================================
|
|
38
|
+
|
|
39
|
+
// Black box at bottom-left corner (100x100 pixels)
|
|
40
|
+
const boxSize = 100
|
|
41
|
+
const x = 10 // 10px from left edge
|
|
42
|
+
const y = documentRenderer.canvas.height - boxSize - 10 // 10px from bottom
|
|
43
|
+
|
|
44
|
+
overlay.drawRect(
|
|
45
|
+
x, // x position
|
|
46
|
+
y, // y position
|
|
47
|
+
boxSize, // width
|
|
48
|
+
boxSize, // height
|
|
49
|
+
0x000000, // color (black)
|
|
50
|
+
0.8 // opacity (80%)
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
// ============================================
|
|
54
|
+
// STEP 4: Render the overlay
|
|
55
|
+
// ============================================
|
|
56
|
+
overlay.render()
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
return overlay
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// ============================================
|
|
63
|
+
// Usage Example
|
|
64
|
+
// ============================================
|
|
65
|
+
/*
|
|
66
|
+
|
|
67
|
+
In your viewer initialization code:
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
import { addBlackBoxOverlay } from './lib/canvas2DOverlay.quickstart'
|
|
71
|
+
|
|
72
|
+
// After creating documentRenderer:
|
|
73
|
+
const overlay = addBlackBoxOverlay(documentRenderer)
|
|
74
|
+
|
|
75
|
+
// That's it! The black box will now render on every frame.
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
*/
|
|
79
|
+
|
|
80
|
+
// ============================================
|
|
81
|
+
// Add More Elements
|
|
82
|
+
// ============================================
|
|
83
|
+
export function addMultipleElements(documentRenderer: DocumentRenderer) {
|
|
84
|
+
const overlay = new Canvas2DOverlay(
|
|
85
|
+
documentRenderer.renderer,
|
|
86
|
+
documentRenderer.canvas
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
documentRenderer.onRender.push((sizeChanged) => {
|
|
90
|
+
if (sizeChanged) {
|
|
91
|
+
overlay.updateSize(documentRenderer.canvas.width, documentRenderer.canvas.height)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
overlay.clear()
|
|
95
|
+
|
|
96
|
+
// Bottom-left black box
|
|
97
|
+
const boxSize = 100
|
|
98
|
+
overlay.drawRect(
|
|
99
|
+
10,
|
|
100
|
+
documentRenderer.canvas.height - boxSize - 10,
|
|
101
|
+
boxSize,
|
|
102
|
+
boxSize,
|
|
103
|
+
0x000000,
|
|
104
|
+
0.8
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
// Add label inside the box
|
|
108
|
+
overlay.drawText('Info', 15, documentRenderer.canvas.height - boxSize, {
|
|
109
|
+
fontSize: 14,
|
|
110
|
+
color: '#ffffff',
|
|
111
|
+
backgroundColor: 'transparent'
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
// Top-right red box
|
|
115
|
+
overlay.drawRect(
|
|
116
|
+
documentRenderer.canvas.width - 60,
|
|
117
|
+
10,
|
|
118
|
+
50,
|
|
119
|
+
50,
|
|
120
|
+
0xff0000, // red
|
|
121
|
+
0.9
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
// Bottom-center health bar style
|
|
125
|
+
const barWidth = 200
|
|
126
|
+
const barHeight = 20
|
|
127
|
+
const barX = (documentRenderer.canvas.width - barWidth) / 2
|
|
128
|
+
const barY = documentRenderer.canvas.height - 30
|
|
129
|
+
|
|
130
|
+
// Background
|
|
131
|
+
overlay.drawRect(barX, barY, barWidth, barHeight, 0x333333, 0.8)
|
|
132
|
+
// Filled portion (e.g., 75% health)
|
|
133
|
+
overlay.drawRect(barX, barY, barWidth * 0.75, barHeight, 0x00ff00, 0.9)
|
|
134
|
+
// Border
|
|
135
|
+
overlay.drawRectOutline(barX, barY, barWidth, barHeight, 0xffffff, 2)
|
|
136
|
+
|
|
137
|
+
overlay.render()
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
return overlay
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// ============================================
|
|
144
|
+
// Dynamic Data Example
|
|
145
|
+
// ============================================
|
|
146
|
+
export function addDynamicOverlay(
|
|
147
|
+
documentRenderer: DocumentRenderer,
|
|
148
|
+
getData: () => { fps: number; x: number; y: number; z: number }
|
|
149
|
+
) {
|
|
150
|
+
const overlay = new Canvas2DOverlay(
|
|
151
|
+
documentRenderer.renderer,
|
|
152
|
+
documentRenderer.canvas
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
documentRenderer.onRender.push((sizeChanged) => {
|
|
156
|
+
if (sizeChanged) {
|
|
157
|
+
overlay.updateSize(documentRenderer.canvas.width, documentRenderer.canvas.height)
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const data = getData() // Get current game data
|
|
161
|
+
|
|
162
|
+
overlay.clear()
|
|
163
|
+
|
|
164
|
+
// Info panel at bottom-left
|
|
165
|
+
const panelX = 10
|
|
166
|
+
const panelY = documentRenderer.canvas.height - 120
|
|
167
|
+
const panelWidth = 180
|
|
168
|
+
const panelHeight = 110
|
|
169
|
+
|
|
170
|
+
// Background
|
|
171
|
+
overlay.drawRect(panelX, panelY, panelWidth, panelHeight, 0x000000, 0.7)
|
|
172
|
+
|
|
173
|
+
// FPS (colored based on value)
|
|
174
|
+
const fpsColor = data.fps > 50 ? '#00ff00' : data.fps > 30 ? '#ffff00' : '#ff0000'
|
|
175
|
+
overlay.drawText(`FPS: ${data.fps}`, panelX + 10, panelY + 10, {
|
|
176
|
+
fontSize: 16,
|
|
177
|
+
color: fpsColor,
|
|
178
|
+
backgroundColor: 'transparent'
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
// Coordinates
|
|
182
|
+
overlay.drawText(`X: ${data.x.toFixed(2)}`, panelX + 10, panelY + 40, {
|
|
183
|
+
fontSize: 14,
|
|
184
|
+
color: '#ffffff',
|
|
185
|
+
backgroundColor: 'transparent'
|
|
186
|
+
})
|
|
187
|
+
overlay.drawText(`Y: ${data.y.toFixed(2)}`, panelX + 10, panelY + 60, {
|
|
188
|
+
fontSize: 14,
|
|
189
|
+
color: '#ffffff',
|
|
190
|
+
backgroundColor: 'transparent'
|
|
191
|
+
})
|
|
192
|
+
overlay.drawText(`Z: ${data.z.toFixed(2)}`, panelX + 10, panelY + 80, {
|
|
193
|
+
fontSize: 14,
|
|
194
|
+
color: '#ffffff',
|
|
195
|
+
backgroundColor: 'transparent'
|
|
196
|
+
})
|
|
197
|
+
|
|
198
|
+
overlay.render()
|
|
199
|
+
})
|
|
200
|
+
|
|
201
|
+
return overlay
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// ============================================
|
|
205
|
+
// High-Performance WebGL Version
|
|
206
|
+
// ============================================
|
|
207
|
+
import { WebGLDirect2DOverlay } from './canvas2DOverlay'
|
|
208
|
+
|
|
209
|
+
export function addHighPerformanceOverlay(documentRenderer: DocumentRenderer) {
|
|
210
|
+
const overlay = new WebGLDirect2DOverlay(
|
|
211
|
+
documentRenderer.renderer,
|
|
212
|
+
documentRenderer.canvas
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
documentRenderer.onRender.push(() => {
|
|
216
|
+
// Direct WebGL rendering - very fast!
|
|
217
|
+
// No need to clear or call render() - draws immediately
|
|
218
|
+
|
|
219
|
+
// Black box at bottom-left (r, g, b, a values 0-1)
|
|
220
|
+
const boxSize = 100
|
|
221
|
+
const x = 10
|
|
222
|
+
const y = documentRenderer.canvas.height - boxSize - 10
|
|
223
|
+
|
|
224
|
+
overlay.drawRect(
|
|
225
|
+
x, // x
|
|
226
|
+
y, // y
|
|
227
|
+
boxSize, // width
|
|
228
|
+
boxSize, // height
|
|
229
|
+
0, // red (0-1)
|
|
230
|
+
0, // green (0-1)
|
|
231
|
+
0, // blue (0-1)
|
|
232
|
+
0.8 // alpha (0-1)
|
|
233
|
+
)
|
|
234
|
+
})
|
|
235
|
+
|
|
236
|
+
return overlay
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
|