@buley/hexgrid-3d 1.0.0 → 1.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/examples/basic-usage.tsx +19 -19
- package/package.json +1 -1
- package/public/hexgrid-worker.js +2350 -1638
- package/src/Snapshot.ts +790 -585
- package/src/adapters.ts +16 -18
- package/src/algorithms/AdvancedStatistics.ts +58 -24
- package/src/algorithms/BayesianStatistics.ts +43 -12
- package/src/algorithms/FlowField.ts +30 -6
- package/src/algorithms/FlowField3D.ts +573 -0
- package/src/algorithms/FluidSimulation.ts +19 -3
- package/src/algorithms/FluidSimulation3D.ts +664 -0
- package/src/algorithms/GraphAlgorithms.ts +19 -12
- package/src/algorithms/OutlierDetection.ts +72 -38
- package/src/algorithms/ParticleSystem.ts +12 -2
- package/src/algorithms/ParticleSystem3D.ts +546 -0
- package/src/algorithms/index.ts +14 -8
- package/src/compat.ts +10 -10
- package/src/components/HexGrid.tsx +10 -23
- package/src/components/NarrationOverlay.tsx +139 -51
- package/src/components/index.ts +2 -1
- package/src/features.ts +31 -31
- package/src/index.ts +11 -11
- package/src/math/HexCoordinates.ts +1 -1
- package/src/math/Matrix4.ts +2 -12
- package/src/math/Vector3.ts +5 -1
- package/src/math/index.ts +6 -6
- package/src/note-adapter.ts +50 -42
- package/src/ontology-adapter.ts +30 -23
- package/src/stores/uiStore.ts +34 -34
- package/src/types.ts +109 -98
- package/src/utils/image-utils.ts +9 -6
- package/src/wasm/HexGridWasmWrapper.ts +436 -388
- package/src/wasm/index.ts +2 -2
- package/src/workers/hexgrid-math.ts +40 -35
- package/src/workers/hexgrid-worker.worker.ts +1992 -1018
|
@@ -1,43 +1,44 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Narration Overlay Component
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
4
|
* Displays play-by-play narration messages with sparklines in a NOC dashboard style.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import React, { useEffect, useRef } from 'react'
|
|
8
|
-
import { NarrationMessage } from '@/lib/narration'
|
|
9
|
-
import { StatsTracker } from '@/lib/stats-tracker'
|
|
10
|
-
import { getAccentRgba, getAccentHex } from '@/lib/theme-colors'
|
|
7
|
+
import React, { useEffect, useRef } from 'react';
|
|
8
|
+
import { NarrationMessage } from '@/lib/narration';
|
|
9
|
+
import { StatsTracker } from '@/lib/stats-tracker';
|
|
10
|
+
import { getAccentRgba, getAccentHex } from '@/lib/theme-colors';
|
|
11
11
|
|
|
12
12
|
export interface NarrationOverlayProps {
|
|
13
|
-
messages: NarrationMessage[]
|
|
14
|
-
statsTracker: StatsTracker | null
|
|
15
|
-
isVisible: boolean
|
|
16
|
-
onClose: () => void
|
|
13
|
+
messages: NarrationMessage[];
|
|
14
|
+
statsTracker: StatsTracker | null;
|
|
15
|
+
isVisible: boolean;
|
|
16
|
+
onClose: () => void;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export const NarrationOverlay: React.FC<NarrationOverlayProps> = ({
|
|
20
20
|
messages,
|
|
21
21
|
statsTracker,
|
|
22
22
|
isVisible,
|
|
23
|
-
onClose
|
|
23
|
+
onClose,
|
|
24
24
|
}) => {
|
|
25
|
-
const messagesEndRef = useRef<HTMLDivElement>(null)
|
|
26
|
-
const scrollContainerRef = useRef<HTMLDivElement>(null)
|
|
25
|
+
const messagesEndRef = useRef<HTMLDivElement>(null);
|
|
26
|
+
const scrollContainerRef = useRef<HTMLDivElement>(null);
|
|
27
27
|
|
|
28
28
|
// Auto-scroll to latest message
|
|
29
29
|
useEffect(() => {
|
|
30
30
|
if (messagesEndRef.current && scrollContainerRef.current) {
|
|
31
|
-
scrollContainerRef.current.scrollTop =
|
|
31
|
+
scrollContainerRef.current.scrollTop =
|
|
32
|
+
scrollContainerRef.current.scrollHeight;
|
|
32
33
|
}
|
|
33
|
-
}, [messages])
|
|
34
|
+
}, [messages]);
|
|
34
35
|
|
|
35
36
|
// Always render the overlay so fade-out can animate smoothly.
|
|
36
37
|
// Toggle visibility via styles.
|
|
37
38
|
|
|
38
|
-
const currentStats = statsTracker?.getCurrentStats()
|
|
39
|
-
const allTimeRecords = statsTracker?.getAllTimeRecords()
|
|
40
|
-
const leaderboard = statsTracker?.getLeaderboard(10)
|
|
39
|
+
const currentStats = statsTracker?.getCurrentStats();
|
|
40
|
+
const allTimeRecords = statsTracker?.getAllTimeRecords();
|
|
41
|
+
const leaderboard = statsTracker?.getLeaderboard(10);
|
|
41
42
|
|
|
42
43
|
return (
|
|
43
44
|
<div
|
|
@@ -62,12 +63,21 @@ export const NarrationOverlay: React.FC<NarrationOverlayProps> = ({
|
|
|
62
63
|
transition: 'opacity 220ms ease, transform 220ms ease',
|
|
63
64
|
opacity: isVisible ? 1 : 0,
|
|
64
65
|
transform: isVisible ? 'translateY(0px)' : 'translateY(-6px)',
|
|
65
|
-
pointerEvents: isVisible ? 'auto' as const : 'none' as const
|
|
66
|
+
pointerEvents: isVisible ? ('auto' as const) : ('none' as const),
|
|
66
67
|
}}
|
|
67
68
|
>
|
|
68
69
|
{/* Header */}
|
|
69
|
-
<div
|
|
70
|
-
|
|
70
|
+
<div
|
|
71
|
+
style={{
|
|
72
|
+
display: 'flex',
|
|
73
|
+
justifyContent: 'space-between',
|
|
74
|
+
alignItems: 'center',
|
|
75
|
+
marginBottom: 8,
|
|
76
|
+
}}
|
|
77
|
+
>
|
|
78
|
+
<div style={{ fontWeight: 'bold', fontSize: 14 }}>
|
|
79
|
+
Play-by-Play Narration
|
|
80
|
+
</div>
|
|
71
81
|
<button
|
|
72
82
|
onClick={onClose}
|
|
73
83
|
style={{
|
|
@@ -77,7 +87,7 @@ export const NarrationOverlay: React.FC<NarrationOverlayProps> = ({
|
|
|
77
87
|
cursor: 'pointer',
|
|
78
88
|
padding: '4px 8px',
|
|
79
89
|
borderRadius: 4,
|
|
80
|
-
fontSize: 11
|
|
90
|
+
fontSize: 11,
|
|
81
91
|
}}
|
|
82
92
|
>
|
|
83
93
|
×
|
|
@@ -87,31 +97,79 @@ export const NarrationOverlay: React.FC<NarrationOverlayProps> = ({
|
|
|
87
97
|
{/* Stats Dashboard (Collapsible) */}
|
|
88
98
|
{currentStats && (
|
|
89
99
|
<details style={{ marginBottom: 8, fontSize: 11 }}>
|
|
90
|
-
<summary
|
|
100
|
+
<summary
|
|
101
|
+
style={{ cursor: 'pointer', color: '#00ffff', marginBottom: 4 }}
|
|
102
|
+
>
|
|
91
103
|
Stats Dashboard
|
|
92
104
|
</summary>
|
|
93
|
-
<div
|
|
94
|
-
|
|
105
|
+
<div
|
|
106
|
+
style={{
|
|
107
|
+
padding: '8px',
|
|
108
|
+
background: 'rgba(0, 255, 255, 0.05)',
|
|
109
|
+
borderRadius: 4,
|
|
110
|
+
}}
|
|
111
|
+
>
|
|
112
|
+
<div
|
|
113
|
+
style={{
|
|
114
|
+
display: 'flex',
|
|
115
|
+
justifyContent: 'space-between',
|
|
116
|
+
marginBottom: 4,
|
|
117
|
+
}}
|
|
118
|
+
>
|
|
95
119
|
<span>Generation:</span>
|
|
96
|
-
<span style={{ fontVariantNumeric: 'tabular-nums' }}>
|
|
120
|
+
<span style={{ fontVariantNumeric: 'tabular-nums' }}>
|
|
121
|
+
{currentStats.generation}
|
|
122
|
+
</span>
|
|
97
123
|
</div>
|
|
98
|
-
<div
|
|
124
|
+
<div
|
|
125
|
+
style={{
|
|
126
|
+
display: 'flex',
|
|
127
|
+
justifyContent: 'space-between',
|
|
128
|
+
marginBottom: 4,
|
|
129
|
+
}}
|
|
130
|
+
>
|
|
99
131
|
<span>Active Memes:</span>
|
|
100
|
-
<span style={{ fontVariantNumeric: 'tabular-nums' }}>
|
|
132
|
+
<span style={{ fontVariantNumeric: 'tabular-nums' }}>
|
|
133
|
+
{currentStats.activeMemesCount}
|
|
134
|
+
</span>
|
|
101
135
|
</div>
|
|
102
|
-
<div
|
|
136
|
+
<div
|
|
137
|
+
style={{
|
|
138
|
+
display: 'flex',
|
|
139
|
+
justifyContent: 'space-between',
|
|
140
|
+
marginBottom: 4,
|
|
141
|
+
}}
|
|
142
|
+
>
|
|
103
143
|
<span>Total Hexes:</span>
|
|
104
|
-
<span style={{ fontVariantNumeric: 'tabular-nums' }}>
|
|
144
|
+
<span style={{ fontVariantNumeric: 'tabular-nums' }}>
|
|
145
|
+
{currentStats.totalHexesInfected}
|
|
146
|
+
</span>
|
|
105
147
|
</div>
|
|
106
|
-
<div
|
|
148
|
+
<div
|
|
149
|
+
style={{
|
|
150
|
+
display: 'flex',
|
|
151
|
+
justifyContent: 'space-between',
|
|
152
|
+
marginBottom: 4,
|
|
153
|
+
}}
|
|
154
|
+
>
|
|
107
155
|
<span>Birth/Death Ratio:</span>
|
|
108
156
|
<span style={{ fontVariantNumeric: 'tabular-nums' }}>
|
|
109
157
|
{currentStats.populationStability.toFixed(2)}
|
|
110
158
|
</span>
|
|
111
159
|
</div>
|
|
112
160
|
{allTimeRecords && (
|
|
113
|
-
<div
|
|
114
|
-
|
|
161
|
+
<div
|
|
162
|
+
style={{
|
|
163
|
+
marginTop: 8,
|
|
164
|
+
paddingTop: 8,
|
|
165
|
+
borderTop: '1px solid rgba(0, 255, 255, 0.2)',
|
|
166
|
+
}}
|
|
167
|
+
>
|
|
168
|
+
<div
|
|
169
|
+
style={{ fontSize: 10, color: '#00ffff', marginBottom: 4 }}
|
|
170
|
+
>
|
|
171
|
+
All-Time Records:
|
|
172
|
+
</div>
|
|
115
173
|
<div style={{ fontSize: 10, marginBottom: 2 }}>
|
|
116
174
|
Highest Territory: {allTimeRecords.highestTerritory.value}
|
|
117
175
|
</div>
|
|
@@ -127,10 +185,18 @@ export const NarrationOverlay: React.FC<NarrationOverlayProps> = ({
|
|
|
127
185
|
{/* Leaderboard (Collapsible) */}
|
|
128
186
|
{leaderboard && leaderboard.length > 0 && (
|
|
129
187
|
<details style={{ marginBottom: 8, fontSize: 11 }}>
|
|
130
|
-
<summary
|
|
188
|
+
<summary
|
|
189
|
+
style={{ cursor: 'pointer', color: '#00ffff', marginBottom: 4 }}
|
|
190
|
+
>
|
|
131
191
|
Top 10 Leaderboard
|
|
132
192
|
</summary>
|
|
133
|
-
<div
|
|
193
|
+
<div
|
|
194
|
+
style={{
|
|
195
|
+
padding: '8px',
|
|
196
|
+
background: 'rgba(0, 255, 255, 0.05)',
|
|
197
|
+
borderRadius: 4,
|
|
198
|
+
}}
|
|
199
|
+
>
|
|
134
200
|
{leaderboard.map((entry, i) => (
|
|
135
201
|
<div
|
|
136
202
|
key={entry.photoId}
|
|
@@ -139,13 +205,15 @@ export const NarrationOverlay: React.FC<NarrationOverlayProps> = ({
|
|
|
139
205
|
justifyContent: 'space-between',
|
|
140
206
|
marginBottom: 2,
|
|
141
207
|
fontSize: 10,
|
|
142
|
-
color: i < 3 ? '#00ff00' : '#00ffff'
|
|
208
|
+
color: i < 3 ? '#00ff00' : '#00ffff',
|
|
143
209
|
}}
|
|
144
210
|
>
|
|
145
211
|
<span>
|
|
146
212
|
{i + 1}. {entry.photoId.slice(0, 20)}...
|
|
147
213
|
</span>
|
|
148
|
-
<span style={{ fontVariantNumeric: 'tabular-nums' }}>
|
|
214
|
+
<span style={{ fontVariantNumeric: 'tabular-nums' }}>
|
|
215
|
+
{entry.territory} hexes
|
|
216
|
+
</span>
|
|
149
217
|
</div>
|
|
150
218
|
))}
|
|
151
219
|
</div>
|
|
@@ -161,11 +229,18 @@ export const NarrationOverlay: React.FC<NarrationOverlayProps> = ({
|
|
|
161
229
|
maxHeight: '400px',
|
|
162
230
|
padding: '8px',
|
|
163
231
|
background: 'rgba(0, 0, 0, 0.3)',
|
|
164
|
-
borderRadius: 4
|
|
232
|
+
borderRadius: 4,
|
|
165
233
|
}}
|
|
166
234
|
>
|
|
167
235
|
{messages.length === 0 ? (
|
|
168
|
-
<div
|
|
236
|
+
<div
|
|
237
|
+
style={{
|
|
238
|
+
color: 'rgba(0, 255, 255, 0.5)',
|
|
239
|
+
fontStyle: 'italic',
|
|
240
|
+
textAlign: 'center',
|
|
241
|
+
padding: '20px',
|
|
242
|
+
}}
|
|
243
|
+
>
|
|
169
244
|
No narration yet. Evolution in progress...
|
|
170
245
|
</div>
|
|
171
246
|
) : (
|
|
@@ -175,14 +250,25 @@ export const NarrationOverlay: React.FC<NarrationOverlayProps> = ({
|
|
|
175
250
|
style={{
|
|
176
251
|
marginBottom: 8,
|
|
177
252
|
padding: '6px',
|
|
178
|
-
background:
|
|
253
|
+
background:
|
|
254
|
+
msg.priority >= 8
|
|
255
|
+
? 'rgba(255, 165, 0, 0.1)'
|
|
256
|
+
: 'rgba(0, 255, 255, 0.05)',
|
|
179
257
|
borderRadius: 4,
|
|
180
|
-
borderLeft: `2px solid ${
|
|
258
|
+
borderLeft: `2px solid ${
|
|
259
|
+
msg.priority >= 8 ? '#ffaa00' : '#00ffff'
|
|
260
|
+
}`,
|
|
181
261
|
fontSize: 11,
|
|
182
|
-
lineHeight: 1.4
|
|
262
|
+
lineHeight: 1.4,
|
|
183
263
|
}}
|
|
184
264
|
>
|
|
185
|
-
<div
|
|
265
|
+
<div
|
|
266
|
+
style={{
|
|
267
|
+
display: 'flex',
|
|
268
|
+
justifyContent: 'space-between',
|
|
269
|
+
marginBottom: 2,
|
|
270
|
+
}}
|
|
271
|
+
>
|
|
186
272
|
<span style={{ color: 'rgba(0, 255, 255, 0.7)', fontSize: 10 }}>
|
|
187
273
|
Gen {msg.generation}
|
|
188
274
|
</span>
|
|
@@ -198,12 +284,15 @@ export const NarrationOverlay: React.FC<NarrationOverlayProps> = ({
|
|
|
198
284
|
marginTop: 4,
|
|
199
285
|
fontFamily: "'Courier New', monospace",
|
|
200
286
|
fontSize: 14,
|
|
201
|
-
color:
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
287
|
+
color:
|
|
288
|
+
msg.eventType === 'slam_dunk' ||
|
|
289
|
+
msg.eventType === 'on_fire'
|
|
290
|
+
? '#00ff00'
|
|
291
|
+
: msg.eventType === 'decline' ||
|
|
292
|
+
msg.eventType === 'missed_shot'
|
|
293
|
+
? '#ff4444'
|
|
294
|
+
: '#00ffff',
|
|
295
|
+
letterSpacing: '2px',
|
|
207
296
|
}}
|
|
208
297
|
>
|
|
209
298
|
{msg.sparkline}
|
|
@@ -216,6 +305,5 @@ export const NarrationOverlay: React.FC<NarrationOverlayProps> = ({
|
|
|
216
305
|
<div ref={messagesEndRef} />
|
|
217
306
|
</div>
|
|
218
307
|
</div>
|
|
219
|
-
)
|
|
220
|
-
}
|
|
221
|
-
|
|
308
|
+
);
|
|
309
|
+
};
|
package/src/components/index.ts
CHANGED
package/src/features.ts
CHANGED
|
@@ -1,48 +1,48 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Feature flags for HexGrid 3D
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
4
|
* Allows enabling/disabling features at runtime for different client environments
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
export interface HexGridFeatureFlags {
|
|
8
8
|
/** Enable/disable play-by-play narration overlay */
|
|
9
|
-
enableNarration?: boolean
|
|
10
|
-
|
|
9
|
+
enableNarration?: boolean;
|
|
10
|
+
|
|
11
11
|
/** Enable/disable statistics tracking and display */
|
|
12
|
-
enableStats?: boolean
|
|
13
|
-
|
|
12
|
+
enableStats?: boolean;
|
|
13
|
+
|
|
14
14
|
/** Enable/disable debug panel */
|
|
15
|
-
enableDebugPanel?: boolean
|
|
16
|
-
|
|
15
|
+
enableDebugPanel?: boolean;
|
|
16
|
+
|
|
17
17
|
/** Enable/disable camera controls UI */
|
|
18
|
-
enableCameraControls?: boolean
|
|
19
|
-
|
|
18
|
+
enableCameraControls?: boolean;
|
|
19
|
+
|
|
20
20
|
/** Enable/disable worker-based rendering */
|
|
21
|
-
enableWorker?: boolean
|
|
22
|
-
|
|
21
|
+
enableWorker?: boolean;
|
|
22
|
+
|
|
23
23
|
/** Enable/disable texture/image loading */
|
|
24
|
-
enableTextures?: boolean
|
|
25
|
-
|
|
24
|
+
enableTextures?: boolean;
|
|
25
|
+
|
|
26
26
|
/** Enable/disable evolution/animation system */
|
|
27
|
-
enableEvolution?: boolean
|
|
28
|
-
|
|
27
|
+
enableEvolution?: boolean;
|
|
28
|
+
|
|
29
29
|
/** Enable/disable autoplay functionality */
|
|
30
|
-
enableAutoplay?: boolean
|
|
31
|
-
|
|
30
|
+
enableAutoplay?: boolean;
|
|
31
|
+
|
|
32
32
|
/** Enable/disable user interactions (clicks, drags) */
|
|
33
|
-
enableInteractions?: boolean
|
|
34
|
-
|
|
33
|
+
enableInteractions?: boolean;
|
|
34
|
+
|
|
35
35
|
/** Enable/disable keyboard shortcuts */
|
|
36
|
-
enableKeyboardShortcuts?: boolean
|
|
37
|
-
|
|
36
|
+
enableKeyboardShortcuts?: boolean;
|
|
37
|
+
|
|
38
38
|
/** Enable/disable performance telemetry */
|
|
39
|
-
enableTelemetry?: boolean
|
|
40
|
-
|
|
39
|
+
enableTelemetry?: boolean;
|
|
40
|
+
|
|
41
41
|
/** Enable/disable sheen/visual effects */
|
|
42
|
-
enableVisualEffects?: boolean
|
|
43
|
-
|
|
42
|
+
enableVisualEffects?: boolean;
|
|
43
|
+
|
|
44
44
|
/** Enable/disable leaderboard system */
|
|
45
|
-
enableLeaderboard?: boolean
|
|
45
|
+
enableLeaderboard?: boolean;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
/**
|
|
@@ -62,7 +62,7 @@ export const DEFAULT_FEATURE_FLAGS: Required<HexGridFeatureFlags> = {
|
|
|
62
62
|
enableTelemetry: true,
|
|
63
63
|
enableVisualEffects: true,
|
|
64
64
|
enableLeaderboard: true,
|
|
65
|
-
}
|
|
65
|
+
};
|
|
66
66
|
|
|
67
67
|
/**
|
|
68
68
|
* Minimal feature flags - only core visualization
|
|
@@ -81,7 +81,7 @@ export const MINIMAL_FEATURE_FLAGS: Required<HexGridFeatureFlags> = {
|
|
|
81
81
|
enableTelemetry: false,
|
|
82
82
|
enableVisualEffects: false,
|
|
83
83
|
enableLeaderboard: false,
|
|
84
|
-
}
|
|
84
|
+
};
|
|
85
85
|
|
|
86
86
|
/**
|
|
87
87
|
* Performance-focused feature flags
|
|
@@ -100,7 +100,7 @@ export const PERFORMANCE_FEATURE_FLAGS: Required<HexGridFeatureFlags> = {
|
|
|
100
100
|
enableTelemetry: false,
|
|
101
101
|
enableVisualEffects: false,
|
|
102
102
|
enableLeaderboard: false,
|
|
103
|
-
}
|
|
103
|
+
};
|
|
104
104
|
|
|
105
105
|
/**
|
|
106
106
|
* Merge user-provided flags with defaults
|
|
@@ -111,7 +111,7 @@ export function mergeFeatureFlags(
|
|
|
111
111
|
return {
|
|
112
112
|
...DEFAULT_FEATURE_FLAGS,
|
|
113
113
|
...userFlags,
|
|
114
|
-
}
|
|
114
|
+
};
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
/**
|
|
@@ -121,5 +121,5 @@ export function isFeatureEnabled(
|
|
|
121
121
|
flags: HexGridFeatureFlags,
|
|
122
122
|
feature: keyof HexGridFeatureFlags
|
|
123
123
|
): boolean {
|
|
124
|
-
return flags[feature] !== false
|
|
124
|
+
return flags[feature] !== false;
|
|
125
125
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,30 +1,30 @@
|
|
|
1
1
|
// Main package exports
|
|
2
|
-
export * from './components'
|
|
3
|
-
export * from './stores'
|
|
4
|
-
export * from './features'
|
|
2
|
+
export * from './components';
|
|
3
|
+
export * from './stores';
|
|
4
|
+
export * from './features';
|
|
5
5
|
|
|
6
6
|
// Export pure mathematical functions
|
|
7
|
-
export * from './workers/hexgrid-math'
|
|
8
|
-
export * from './utils/image-utils'
|
|
7
|
+
export * from './workers/hexgrid-math';
|
|
8
|
+
export * from './utils/image-utils';
|
|
9
9
|
|
|
10
10
|
// Export additional types that aren't in components/stores
|
|
11
|
-
export type { WorkerDebug, Photo, GridItem } from './types'
|
|
11
|
+
export type { WorkerDebug, Photo, GridItem } from './types';
|
|
12
12
|
|
|
13
13
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
14
14
|
// ENHANCED HEXGRID EXPORTS
|
|
15
15
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
16
16
|
|
|
17
17
|
// Math library
|
|
18
|
-
export * from './math'
|
|
18
|
+
export * from './math';
|
|
19
19
|
|
|
20
20
|
// Algorithms (graph, clustering, flow, particles, fluid)
|
|
21
|
-
export * from './algorithms'
|
|
21
|
+
export * from './algorithms';
|
|
22
22
|
|
|
23
23
|
// WASM acceleration layer
|
|
24
|
-
export * from './wasm'
|
|
24
|
+
export * from './wasm';
|
|
25
25
|
|
|
26
26
|
// Unified Snapshot API
|
|
27
|
-
export * from './Snapshot'
|
|
27
|
+
export * from './Snapshot';
|
|
28
28
|
|
|
29
29
|
// Enhanced HexGrid engine with all features integrated
|
|
30
|
-
export * from './HexGridEnhanced'
|
|
30
|
+
export * from './HexGridEnhanced';
|
|
@@ -8,7 +8,7 @@ export class Axial {
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
static fromPixel(x: number, y: number, hexSize: number): Axial {
|
|
11
|
-
const q = (Math.sqrt(3) / 3 * x - (1 / 3) * y) / hexSize;
|
|
11
|
+
const q = ((Math.sqrt(3) / 3) * x - (1 / 3) * y) / hexSize;
|
|
12
12
|
const r = ((2 / 3) * y) / hexSize;
|
|
13
13
|
return new Axial(Math.round(q), Math.round(r));
|
|
14
14
|
}
|
package/src/math/Matrix4.ts
CHANGED
|
@@ -8,21 +8,11 @@ export class Matrix4 {
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
static identity(): Matrix4 {
|
|
11
|
-
return new Matrix4([
|
|
12
|
-
1, 0, 0, 0,
|
|
13
|
-
0, 1, 0, 0,
|
|
14
|
-
0, 0, 1, 0,
|
|
15
|
-
0, 0, 0, 1,
|
|
16
|
-
]);
|
|
11
|
+
return new Matrix4([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);
|
|
17
12
|
}
|
|
18
13
|
|
|
19
14
|
static translation(x: number, y: number, z: number): Matrix4 {
|
|
20
|
-
return new Matrix4([
|
|
21
|
-
1, 0, 0, x,
|
|
22
|
-
0, 1, 0, y,
|
|
23
|
-
0, 0, 1, z,
|
|
24
|
-
0, 0, 0, 1,
|
|
25
|
-
]);
|
|
15
|
+
return new Matrix4([1, 0, 0, x, 0, 1, 0, y, 0, 0, 1, z, 0, 0, 0, 1]);
|
|
26
16
|
}
|
|
27
17
|
|
|
28
18
|
transformPoint(point: Vector3): Vector3 {
|
package/src/math/Vector3.ts
CHANGED
|
@@ -49,7 +49,11 @@ export class Vector3 {
|
|
|
49
49
|
this.z = z;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
static fromLatLng(
|
|
52
|
+
static fromLatLng(
|
|
53
|
+
latitude: number,
|
|
54
|
+
longitude: number,
|
|
55
|
+
radius: number = 1
|
|
56
|
+
): Vector3 {
|
|
53
57
|
const latRad = (latitude * Math.PI) / 180;
|
|
54
58
|
const lonRad = (longitude * Math.PI) / 180;
|
|
55
59
|
|
package/src/math/index.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Math Module Exports
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
4
|
* @module math
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
export * from './Vector3'
|
|
8
|
-
export * from './Matrix4'
|
|
9
|
-
export * from './Quaternion'
|
|
10
|
-
export * from './HexCoordinates'
|
|
11
|
-
export * from './SpatialIndex'
|
|
7
|
+
export * from './Vector3';
|
|
8
|
+
export * from './Matrix4';
|
|
9
|
+
export * from './Quaternion';
|
|
10
|
+
export * from './HexCoordinates';
|
|
11
|
+
export * from './SpatialIndex';
|