@nayan-ui/engine 0.0.0-stage → 1.0.0-beta.4
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/LICENSE +21 -0
- package/NayanEngine.podspec +28 -0
- package/README.md +308 -2
- package/lib/module/assets/AssetBytesCache.js +76 -0
- package/lib/module/assets/AssetCache.js +19 -0
- package/lib/module/assets/AssetLoader.js +52 -0
- package/lib/module/assets/CacheGeneration.js +7 -0
- package/lib/module/assets/IndexedDbCache.web.js +149 -0
- package/lib/module/assets/ProceduralCache.js +249 -0
- package/lib/module/assets/font.js +139 -0
- package/lib/module/assets/loft.js +142 -0
- package/lib/module/assets/model.js +96 -0
- package/lib/module/assets/modelling.js +254 -0
- package/lib/module/assets/shape.js +926 -0
- package/lib/module/assets/source.js +58 -0
- package/lib/module/assets/source.web.js +22 -0
- package/lib/module/assets/storage.js +4 -0
- package/lib/module/assets/storage.shared.js +38 -0
- package/lib/module/assets/storage.web.js +38 -0
- package/lib/module/assets/surface.js +47 -0
- package/lib/module/assets/texture.js +69 -0
- package/lib/module/drawing/DrawingCanvas.js +38 -0
- package/lib/module/drawing/DrawingCanvas.web.js +206 -0
- package/lib/module/drawing/DrawingDocument.js +256 -0
- package/lib/module/drawing/types.js +4 -0
- package/lib/module/globals.d.ts +12 -0
- package/lib/module/index.js +39 -0
- package/lib/module/input/Joystick.js +84 -0
- package/lib/module/input/Joystick.web.js +93 -0
- package/lib/module/input/keyboard.js +250 -0
- package/lib/module/media/audio-worklet.js +34 -0
- package/lib/module/media/audio.js +97 -0
- package/lib/module/media/haptics.js +82 -0
- package/lib/module/media/output.web.js +66 -0
- package/lib/module/native/BrowserEngine.js +568 -0
- package/lib/module/native/EngineBridge.js +4 -0
- package/lib/module/native/NativeNayanEngine.js +7 -0
- package/lib/module/native/NativeNayanEngine.web.js +62 -0
- package/lib/module/native/prepare.js +7 -0
- package/lib/module/native/prepare.web.js +17 -0
- package/lib/module/native/spec/NativeNayanEngine.js +17 -0
- package/lib/module/package.json +1 -0
- package/lib/module/render/GameView.js +317 -0
- package/lib/module/render/camera.js +34 -0
- package/lib/module/render/host.js +39 -0
- package/lib/module/render/host.web.js +104 -0
- package/lib/module/render/light.js +24 -0
- package/lib/module/render/meshes.js +159 -0
- package/lib/module/render/quality.js +119 -0
- package/lib/module/render/responder.js +4 -0
- package/lib/module/render/responder.web.js +97 -0
- package/lib/module/render/touch.js +185 -0
- package/lib/module/render/useWorld.js +72 -0
- package/lib/module/types.js +30 -0
- package/lib/module/world/Scoreboard.js +161 -0
- package/lib/module/world/TransformBatch.js +128 -0
- package/lib/module/world/World.js +704 -0
- package/lib/module/world/color.js +80 -0
- package/lib/module/world/desc.js +187 -0
- package/lib/module/world/effects.js +463 -0
- package/lib/module/world/quat.js +86 -0
- package/lib/module/world/types.js +4 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/assets/AssetBytesCache.d.ts +7 -0
- package/lib/typescript/src/assets/AssetCache.d.ts +9 -0
- package/lib/typescript/src/assets/AssetLoader.d.ts +11 -0
- package/lib/typescript/src/assets/CacheGeneration.d.ts +3 -0
- package/lib/typescript/src/assets/IndexedDbCache.web.d.ts +20 -0
- package/lib/typescript/src/assets/ProceduralCache.d.ts +45 -0
- package/lib/typescript/src/assets/font.d.ts +53 -0
- package/lib/typescript/src/assets/loft.d.ts +31 -0
- package/lib/typescript/src/assets/model.d.ts +58 -0
- package/lib/typescript/src/assets/modelling.d.ts +157 -0
- package/lib/typescript/src/assets/shape.d.ts +203 -0
- package/lib/typescript/src/assets/source.d.ts +10 -0
- package/lib/typescript/src/assets/source.web.d.ts +8 -0
- package/lib/typescript/src/assets/storage.d.ts +2 -0
- package/lib/typescript/src/assets/storage.shared.d.ts +7 -0
- package/lib/typescript/src/assets/storage.web.d.ts +7 -0
- package/lib/typescript/src/assets/surface.d.ts +17 -0
- package/lib/typescript/src/assets/texture.d.ts +30 -0
- package/lib/typescript/src/drawing/DrawingCanvas.d.ts +5 -0
- package/lib/typescript/src/drawing/DrawingCanvas.web.d.ts +4 -0
- package/lib/typescript/src/drawing/DrawingDocument.d.ts +210 -0
- package/lib/typescript/src/drawing/types.d.ts +12 -0
- package/lib/typescript/src/index.d.ts +45 -0
- package/lib/typescript/src/input/Joystick.d.ts +20 -0
- package/lib/typescript/src/input/Joystick.web.d.ts +13 -0
- package/lib/typescript/src/input/keyboard.d.ts +17 -0
- package/lib/typescript/src/media/audio.d.ts +46 -0
- package/lib/typescript/src/media/haptics.d.ts +22 -0
- package/lib/typescript/src/media/output.web.d.ts +4 -0
- package/lib/typescript/src/native/BrowserEngine.d.ts +8 -0
- package/lib/typescript/src/native/EngineBridge.d.ts +26 -0
- package/lib/typescript/src/native/NativeNayanEngine.d.ts +5 -0
- package/lib/typescript/src/native/NativeNayanEngine.web.d.ts +10 -0
- package/lib/typescript/src/native/prepare.d.ts +3 -0
- package/lib/typescript/src/native/prepare.web.d.ts +2 -0
- package/lib/typescript/src/native/spec/NativeNayanEngine.d.ts +211 -0
- package/lib/typescript/src/render/GameView.d.ts +107 -0
- package/lib/typescript/src/render/camera.d.ts +6 -0
- package/lib/typescript/src/render/host.d.ts +29 -0
- package/lib/typescript/src/render/host.web.d.ts +16 -0
- package/lib/typescript/src/render/light.d.ts +12 -0
- package/lib/typescript/src/render/meshes.d.ts +45 -0
- package/lib/typescript/src/render/quality.d.ts +48 -0
- package/lib/typescript/src/render/responder.d.ts +2 -0
- package/lib/typescript/src/render/responder.web.d.ts +40 -0
- package/lib/typescript/src/render/touch.d.ts +26 -0
- package/lib/typescript/src/render/useWorld.d.ts +20 -0
- package/lib/typescript/src/types.d.ts +81 -0
- package/lib/typescript/src/world/Scoreboard.d.ts +75 -0
- package/lib/typescript/src/world/TransformBatch.d.ts +39 -0
- package/lib/typescript/src/world/World.d.ts +207 -0
- package/lib/typescript/src/world/color.d.ts +18 -0
- package/lib/typescript/src/world/desc.d.ts +17 -0
- package/lib/typescript/src/world/effects.d.ts +157 -0
- package/lib/typescript/src/world/quat.d.ts +31 -0
- package/lib/typescript/src/world/types.d.ts +238 -0
- package/lib/web/audio-worklet.js +29 -0
- package/lib/web/engine_core_bg.wasm +0 -0
- package/lib/web/index.js +8240 -0
- package/lib/web/types/src/assets/AssetBytesCache.d.ts +6 -0
- package/lib/web/types/src/assets/AssetCache.d.ts +8 -0
- package/lib/web/types/src/assets/AssetLoader.d.ts +10 -0
- package/lib/web/types/src/assets/CacheGeneration.d.ts +2 -0
- package/lib/web/types/src/assets/IndexedDbCache.d.ts +19 -0
- package/lib/web/types/src/assets/ProceduralCache.d.ts +44 -0
- package/lib/web/types/src/assets/font.d.ts +52 -0
- package/lib/web/types/src/assets/loft.d.ts +30 -0
- package/lib/web/types/src/assets/model.d.ts +57 -0
- package/lib/web/types/src/assets/modelling.d.ts +156 -0
- package/lib/web/types/src/assets/shape.d.ts +202 -0
- package/lib/web/types/src/assets/source.d.ts +7 -0
- package/lib/web/types/src/assets/storage.d.ts +6 -0
- package/lib/web/types/src/assets/storage.shared.d.ts +6 -0
- package/lib/web/types/src/assets/surface.d.ts +16 -0
- package/lib/web/types/src/assets/texture.d.ts +29 -0
- package/lib/web/types/src/drawing/DrawingCanvas.d.ts +3 -0
- package/lib/web/types/src/drawing/DrawingDocument.d.ts +209 -0
- package/lib/web/types/src/drawing/types.d.ts +11 -0
- package/lib/web/types/src/index.d.ts +44 -0
- package/lib/web/types/src/input/Joystick.d.ts +12 -0
- package/lib/web/types/src/input/keyboard.d.ts +16 -0
- package/lib/web/types/src/media/audio.d.ts +45 -0
- package/lib/web/types/src/media/haptics.d.ts +21 -0
- package/lib/web/types/src/media/output.d.ts +3 -0
- package/lib/web/types/src/native/BrowserEngine.d.ts +7 -0
- package/lib/web/types/src/native/EngineBridge.d.ts +25 -0
- package/lib/web/types/src/native/NativeNayanEngine.d.ts +9 -0
- package/lib/web/types/src/native/prepare.d.ts +1 -0
- package/lib/web/types/src/native/spec/NativeNayanEngine.d.ts +210 -0
- package/lib/web/types/src/render/GameView.d.ts +106 -0
- package/lib/web/types/src/render/camera.d.ts +5 -0
- package/lib/web/types/src/render/host.d.ts +15 -0
- package/lib/web/types/src/render/light.d.ts +11 -0
- package/lib/web/types/src/render/meshes.d.ts +44 -0
- package/lib/web/types/src/render/quality.d.ts +47 -0
- package/lib/web/types/src/render/responder.d.ts +39 -0
- package/lib/web/types/src/render/touch.d.ts +25 -0
- package/lib/web/types/src/render/useWorld.d.ts +19 -0
- package/lib/web/types/src/types.d.ts +80 -0
- package/lib/web/types/src/world/Scoreboard.d.ts +74 -0
- package/lib/web/types/src/world/TransformBatch.d.ts +38 -0
- package/lib/web/types/src/world/World.d.ts +206 -0
- package/lib/web/types/src/world/color.d.ts +17 -0
- package/lib/web/types/src/world/desc.d.ts +16 -0
- package/lib/web/types/src/world/effects.d.ts +156 -0
- package/lib/web/types/src/world/quat.d.ts +30 -0
- package/lib/web/types/src/world/types.d.ts +237 -0
- package/native/android/CMakeLists.txt +34 -0
- package/native/android/NayanEngineSpec.h +15 -0
- package/native/android/build.gradle +26 -0
- package/native/android/codegen/CMakeLists.txt +3 -0
- package/native/android/proguard-rules.pro +2 -0
- package/native/android/src/main/java/com/nayanui/engine/EngineSurfaceView.java +295 -0
- package/native/android/src/main/java/com/nayanui/engine/EngineSurfaceViewManager.java +45 -0
- package/native/android/src/main/java/com/nayanui/engine/NayanEnginePackage.java +24 -0
- package/native/core/build/EngineCore.xcframework/Info.plist +43 -0
- package/native/core/build/EngineCore.xcframework/ios-arm64/libengine_core.a +0 -0
- package/native/core/build/EngineCore.xcframework/ios-arm64-simulator/libengine_core.a +0 -0
- package/native/core/build/android/arm64-v8a/libengine_core.a +0 -0
- package/native/core/build/android/armeabi-v7a/libengine_core.a +0 -0
- package/native/core/build/android/x86/libengine_core.a +0 -0
- package/native/core/build/android/x86_64/libengine_core.a +0 -0
- package/native/core/include/drawing-licenses.txt +58 -0
- package/native/core/include/engine_core.h +331 -0
- package/native/cpp/NayanEngineModule.cpp +998 -0
- package/native/cpp/NayanEngineModule.h +174 -0
- package/native/cpp/generated/NayanEngineSpecJSI.cpp +2 -0
- package/native/cpp/generated/NayanEngineSpecJSI.h +1026 -0
- package/native/ios/NayanEngineProvider.h +5 -0
- package/native/ios/NayanEngineProvider.mm +21 -0
- package/native/ios/NayanEngineSurface.mm +252 -0
- package/native/scripts/check-package.mjs +39 -0
- package/package.json +162 -4
- package/react-native.config.js +18 -0
- package/src/native/spec/NativeNayanEngine.ts +265 -0
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import { type TurboModule } from 'react-native';
|
|
2
|
+
/**
|
|
3
|
+
* Bridge to the Rust core. Use the `World`, `audio` and `haptics` APIs instead of calling this.
|
|
4
|
+
*
|
|
5
|
+
* Worlds are identified by the number `createWorld` returns; entity ids are opaque numbers.
|
|
6
|
+
* Entities are created and changed with one call each: `spawnDesc` / `setDesc` take a
|
|
7
|
+
* Float64Array's ArrayBuffer encoding every option (layout in native/core/include/engine_core.h).
|
|
8
|
+
* Capacity is fixed at creation, so the buffers returned by `get*` alias Rust memory (zero-copy)
|
|
9
|
+
* and stay valid until `destroyWorld`.
|
|
10
|
+
*/
|
|
11
|
+
export interface Spec extends TurboModule {
|
|
12
|
+
createWorld(capacity: number): number;
|
|
13
|
+
destroyWorld(world: number): void;
|
|
14
|
+
/** Returns the entity id, or -1 if the world is full or the description is rejected. */
|
|
15
|
+
spawnDesc(world: number, desc: Object): number;
|
|
16
|
+
/** Returns false if the entity is gone or a field was rejected (the rest still apply). */
|
|
17
|
+
setDesc(world: number, entity: number, desc: Object): boolean;
|
|
18
|
+
/** Packed draw transforms, 16 doubles per record: id, flags, position, rotation, scale, color. */
|
|
19
|
+
setTransforms(world: number, data: Object, count: number): number;
|
|
20
|
+
/** Returns false for stale or unknown ids. */
|
|
21
|
+
despawn(world: number, entity: number): boolean;
|
|
22
|
+
/** Instant change in momentum (dynamic bodies only). */
|
|
23
|
+
impulse(world: number, entity: number, x: number, y: number, z: number): void;
|
|
24
|
+
setGravity(world: number, x: number, y: number, z: number): void;
|
|
25
|
+
setBounds(world: number, minX: number, minZ: number, maxX: number, maxZ: number): void;
|
|
26
|
+
/** Entity used to pan/attenuate impact sounds (-1 clears). */
|
|
27
|
+
setListener(world: number, entity: number): void;
|
|
28
|
+
/** Returns the hit entity or -1; on a hit the scratch buffer holds distance, normal, point. */
|
|
29
|
+
raycast(world: number, ox: number, oy: number, oz: number, dx: number, dy: number, dz: number, maxDistance: number, mask: number): number;
|
|
30
|
+
/** Nearest pickable entity along a ray (as last drawn), or -1; on a hit the scratch buffer holds distance, point. */
|
|
31
|
+
pick(world: number, ox: number, oy: number, oz: number, dx: number, dy: number, dz: number): number;
|
|
32
|
+
/** Nearest pickable entity under a screen point (in view points), or -1; scratch holds distance, point. */
|
|
33
|
+
pickScreen(world: number, x: number, y: number): number;
|
|
34
|
+
/** Stores the view-projection matrix (16 column-major floats) and view size in points. */
|
|
35
|
+
setView(world: number, viewProj: Object, width: number, height: number): void;
|
|
36
|
+
/** World ray [origin xyz, direction xyz] through a view point. Writes into scratch[0..6]. Returns true on success. */
|
|
37
|
+
screenRay(world: number, x: number, y: number): boolean;
|
|
38
|
+
/** Where a view point lands on a plane. Writes into scratch[0..3]. Returns true on success. */
|
|
39
|
+
screenToWorld(world: number, x: number, y: number, ppx: number, ppy: number, ppz: number, pnx: number, pny: number, pnz: number): boolean;
|
|
40
|
+
/** Where a world position appears on screen (points from top-left). Writes into scratch[0..2]. */
|
|
41
|
+
toScreen(world: number, x: number, y: number, z: number): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Write position / velocity to the scratch buffer (`getScratch`). Return false if not alive.
|
|
44
|
+
* `rendered`: where it was last drawn, in world space (otherwise simulated, relative to its parent).
|
|
45
|
+
*/
|
|
46
|
+
readPosition(world: number, entity: number, rendered: boolean): boolean;
|
|
47
|
+
readVelocity(world: number, entity: number): boolean;
|
|
48
|
+
/** Starts an animation (Float64Array buffer, layout in engine_core.h). Returns its id, or 0 if nothing started. */
|
|
49
|
+
animate(world: number, animation: Object): number;
|
|
50
|
+
stopAnimation(world: number, entity: number): boolean;
|
|
51
|
+
/** Spawns a particle burst (Float64Array buffer). Returns how many particles were spawned. */
|
|
52
|
+
burst(world: number, burst: Object): number;
|
|
53
|
+
update(world: number, dt: number): void;
|
|
54
|
+
/** Starts a timer firing `seconds` of update time from now; its id is reported in `getDone`. Returns the id, or 0. */
|
|
55
|
+
after(world: number, seconds: number): number;
|
|
56
|
+
/** Drops every pending timer. Returns how many were dropped. */
|
|
57
|
+
cancelTimers(world: number): number;
|
|
58
|
+
/** Score / lives / clock operation (layout in engine_core.h). Returns the score after it. */
|
|
59
|
+
scoreboard(world: number, op: number, a: number, b: number): number;
|
|
60
|
+
/** 8 doubles: score, lives, seconds, shown seconds, changed flags, running, points per second, best. Aliases native memory. */
|
|
61
|
+
getScoreboard(world: number): Object;
|
|
62
|
+
count(world: number): number;
|
|
63
|
+
/** capacity * 16 floats, column-major, grouped by mesh. */
|
|
64
|
+
getMatrices(world: number): Object;
|
|
65
|
+
/** capacity * 4 floats (rgba), same order as the matrices. */
|
|
66
|
+
getColors(world: number): Object;
|
|
67
|
+
/** capacity * 4 floats: texture region (u0 v0 u1 v1), same order as the matrices. */
|
|
68
|
+
getRegions(world: number): Object;
|
|
69
|
+
/** MAX_MESHES * 4 u32: [first, count] per mesh id for opaque instances, then for transparent ones. */
|
|
70
|
+
getRanges(world: number): Object;
|
|
71
|
+
/** Ids of animations that ended since the last update began (room for capacity * 5 + 64). */
|
|
72
|
+
getDone(world: number): Object;
|
|
73
|
+
doneLength(world: number): number;
|
|
74
|
+
/** Collision events from the last update, 4 u32 each: [a, b, flags, speed as f32 bits]. */
|
|
75
|
+
getEvents(world: number): Object;
|
|
76
|
+
eventLength(world: number): number;
|
|
77
|
+
/** 16 floats. */
|
|
78
|
+
getScratch(world: number): Object;
|
|
79
|
+
/** Parses a glTF/GLB ArrayBuffer. Returns its mesh id, or -1 (see `loadError`). */
|
|
80
|
+
/** Joint count and animation clips as JSON, loaded once with the model. */
|
|
81
|
+
modelRig(mesh: number): string;
|
|
82
|
+
playClip(world: number, entity: number, clip: string, loop: boolean, speed: number, fade: number, time: number): boolean;
|
|
83
|
+
stopClip(world: number, entity: number, reset: boolean): boolean;
|
|
84
|
+
skinPoints(world: number, entity: number, vertices: Object, output: Object, after: number): boolean;
|
|
85
|
+
/** Rust owns cache hashing, persistence, validation and mesh preparation. */
|
|
86
|
+
cacheRead(key: string): Object;
|
|
87
|
+
cacheWrite(key: string, data: Object): boolean;
|
|
88
|
+
cacheRemove(key: string): boolean;
|
|
89
|
+
cacheClear(): boolean;
|
|
90
|
+
shapePrepare(vertices: Object, indices: Object, options: string): number;
|
|
91
|
+
solidPrepare(recipe: string, options: string): number;
|
|
92
|
+
modelLoad(data: Object, center: boolean, fit: number): number;
|
|
93
|
+
/** `modelLoad` on a background native thread (the data is copied first): resolves to the mesh id, or -1. */
|
|
94
|
+
modelLoadAsync(data: Object, center: boolean, fit: number): Promise<number>;
|
|
95
|
+
/** 11 floats per vertex (position, normal, color, uv); aliases native memory. */
|
|
96
|
+
modelVertices(mesh: number): Object;
|
|
97
|
+
/** u32 triangle indices; aliases native memory. */
|
|
98
|
+
modelIndices(mesh: number): Object;
|
|
99
|
+
/** Full bounding-box size [x, y, z]. */
|
|
100
|
+
modelSize(mesh: number): Array<number>;
|
|
101
|
+
/** The model's base color texture id, or -1. */
|
|
102
|
+
modelTexture(mesh: number): number;
|
|
103
|
+
/** A new mesh id with `base`'s geometry (to give it another texture), or -1. */
|
|
104
|
+
meshAlias(base: number): number;
|
|
105
|
+
/** Registers geometry (copied): 11 floats per vertex, u32 triangle indices. Returns the mesh id, or -1. */
|
|
106
|
+
meshCreate(vertices: Object, indices: Object): number;
|
|
107
|
+
/**
|
|
108
|
+
* Hands a core model's own geometry (from `meshCreate`, `modelLoad`, a font) to the renderer, in
|
|
109
|
+
* Rust: nothing is copied through JS. `texture` -1 for none. False if the mesh is unknown.
|
|
110
|
+
*/
|
|
111
|
+
renderModel(mesh: number, texture: number, shine: number): boolean;
|
|
112
|
+
/**
|
|
113
|
+
* Fills 2D contours ([x, y] f32 pairs, `counts[k]` points per contour) by the non-zero or even-odd
|
|
114
|
+
* rule and extrudes them `depth` deep. Returns an ArrayBuffer of 11 floats per vertex (unindexed).
|
|
115
|
+
*/
|
|
116
|
+
pathExtrude(points: Object, counts: Array<number>, depth: number, evenOdd: boolean): Object;
|
|
117
|
+
/** Recomputes normals in place (vertex / u32 index ArrayBuffers), averaged across vertices at the same place. */
|
|
118
|
+
geometrySmoothNormals(vertices: Object, indices: Object): void;
|
|
119
|
+
/** Tessellates a solid recipe; returns independent vertex/index ArrayBuffers, with no mesh registration. */
|
|
120
|
+
geometrySolid(recipe: string): Object;
|
|
121
|
+
/** Cleans, simplifies and optimizes a mesh, preserving normal/color/UV attributes. */
|
|
122
|
+
geometryOptimize(vertices: Object, indices: Object, ratio: number, error: number, lockBorders: boolean): Object;
|
|
123
|
+
/** Flips triangles in place whose winding disagrees with their vertex normals. */
|
|
124
|
+
geometryFaceOutward(vertices: Object, indices: Object): void;
|
|
125
|
+
/**
|
|
126
|
+
* Bakes a part into merged buffers: `placement` = position xyz, rotation quat xyzw, scale xyz, color
|
|
127
|
+
* rgb. Writes at `vertexOffset` floats / `indexOffset` indices, indices offset by `first`.
|
|
128
|
+
*/
|
|
129
|
+
geometryPlace(vertices: Object, indices: Object, placement: Array<number>, first: number, outVertices: Object, vertexOffset: number, outIndices: Object, indexOffset: number): void;
|
|
130
|
+
/** Decodes a PNG/JPEG ArrayBuffer. Returns the texture id, or -1. */
|
|
131
|
+
textureLoad(data: Object): number;
|
|
132
|
+
/** `textureLoad` on a background native thread: resolves to the texture id, or -1. */
|
|
133
|
+
textureLoadAsync(data: Object): Promise<number>;
|
|
134
|
+
/** RGBA8 pixels, top row first; aliases native memory. */
|
|
135
|
+
texturePixels(texture: number): Object;
|
|
136
|
+
/** [width, height]. */
|
|
137
|
+
textureSize(texture: number): Array<number>;
|
|
138
|
+
/** Builds extruded glyph meshes for `chars`. Returns the font id, or -1. */
|
|
139
|
+
fontLoad(data: Object, depth: number, chars: string, weight: number): number;
|
|
140
|
+
/** `fontLoad` (outlines and glyph meshes) on a background native thread: resolves to the font id, or -1. */
|
|
141
|
+
fontLoadAsync(data: Object, depth: number, chars: string, weight: number): Promise<number>;
|
|
142
|
+
/** [codepoint, mesh (-1 = nothing drawn), advance, ...] followed by the cap height. */
|
|
143
|
+
fontGlyphs(font: number): Array<number>;
|
|
144
|
+
/** Why the last model / texture / font / alias load failed ("" after a success). */
|
|
145
|
+
loadError(): string;
|
|
146
|
+
/** Generates and registers all built-in shape meshes (cube, sphere, etc.) in the native renderer. */
|
|
147
|
+
generateBuiltinMeshes(): void;
|
|
148
|
+
/**
|
|
149
|
+
* Builds the GPU device and shader pipelines on a background thread, ahead of the first surface.
|
|
150
|
+
* Returns at once; repeat calls do nothing.
|
|
151
|
+
*/
|
|
152
|
+
renderWarmUp(): void;
|
|
153
|
+
/** Returns a copy of a registered mesh's vertices (11 floats per vertex), or empty if not found. */
|
|
154
|
+
renderMeshVertices(mesh: number): Object;
|
|
155
|
+
/** Returns a copy of a registered mesh's indices (u32 triangle list), or empty if not found. */
|
|
156
|
+
renderMeshIndices(mesh: number): Object;
|
|
157
|
+
/** Geometry (copied) drawn for a mesh id: 11 floats per vertex, u32 indices. `texture` -1 = none. */
|
|
158
|
+
renderMesh(mesh: number, vertices: Object, indices: Object, texture: number, shine: number): void;
|
|
159
|
+
/**
|
|
160
|
+
* Draws a frame into surface `surface`. `frame`: Float64Array buffer (layout in engine_core.h);
|
|
161
|
+
* instance buffers hold the same number of instances; `viewProj` (16 floats) gets the camera used.
|
|
162
|
+
* Returns 1 (drawn), 0 (surface not ready yet / frame skipped) or -1 (see `renderError`).
|
|
163
|
+
*/
|
|
164
|
+
renderFrame(surface: number, frame: Object, matrices: Object, colors: Object, regions: Object, ranges: Object, count: number, viewProj: Object, world: number): number;
|
|
165
|
+
/**
|
|
166
|
+
* `renderFrame`'s arguments, but the frame is copied and drawn on the native render thread: returns
|
|
167
|
+
* at once, with `viewProj` written. 1 once the surface has presented a frame, 0 before, -1 if the
|
|
168
|
+
* last frame failed (see `renderError`).
|
|
169
|
+
*/
|
|
170
|
+
publishFrame(surface: number, frame: Object, matrices: Object, colors: Object, regions: Object, ranges: Object, count: number, viewProj: Object, world: number): number;
|
|
171
|
+
/** [frames presented, smoothed render milliseconds] for a surface drawn by the render thread. */
|
|
172
|
+
renderStats(surface: number): Array<number>;
|
|
173
|
+
/** True where the platform drives frames from its display clock (`startFrames`); else use requestAnimationFrame. */
|
|
174
|
+
hasFrameClock(): boolean;
|
|
175
|
+
/**
|
|
176
|
+
* Calls `onFrame` on the JS thread once per display refresh while the surface is attached and
|
|
177
|
+
* visible, with the frame time in milliseconds. A frame JS hasn't started yet isn't queued again.
|
|
178
|
+
*/
|
|
179
|
+
startFrames(surface: number, onFrame: (timeMs: number) => void): void;
|
|
180
|
+
stopFrames(surface: number): void;
|
|
181
|
+
/**
|
|
182
|
+
* The screen-space overlay drawn over surface `surface` from its next frame on, copied from a world's
|
|
183
|
+
* buffers. In points: x right and y up from the view's top-left (on screen y <= 0), z toward the
|
|
184
|
+
* viewer within -100..100; `width` x `height` is the view in points. Unlit, always in front of the
|
|
185
|
+
* scene. count 0 removes it.
|
|
186
|
+
*/
|
|
187
|
+
renderOverlay(surface: number, matrices: Object, colors: Object, regions: Object, ranges: Object, count: number, width: number, height: number): void;
|
|
188
|
+
renderError(): string;
|
|
189
|
+
/** "vulkan", "gl" or "metal" ("" before the first surface). */
|
|
190
|
+
renderBackend(): string;
|
|
191
|
+
/** Native 2D drawing documents; commands return owned JSON results. */
|
|
192
|
+
drawingCreate(width: number, height: number, ratio: number): number;
|
|
193
|
+
drawingCommand(document: number, command: string): string;
|
|
194
|
+
drawingDestroy(document: number): void;
|
|
195
|
+
/** Decodes a WAV ArrayBuffer. Returns a sound id, or -1. */
|
|
196
|
+
audioLoad(data: Object): number;
|
|
197
|
+
/** `audioLoad` on a background native thread: resolves to the sound id, or -1. */
|
|
198
|
+
audioLoadAsync(data: Object): Promise<number>;
|
|
199
|
+
/** Returns a voice id (> 0), or 0 if nothing played. */
|
|
200
|
+
audioPlay(sound: number, volume: number, pan: number, pitch: number, loop: boolean): number;
|
|
201
|
+
audioStop(voice: number): void;
|
|
202
|
+
audioSetVolume(volume: number): void;
|
|
203
|
+
audioSetMuted(muted: boolean): void;
|
|
204
|
+
audioIsRunning(): boolean;
|
|
205
|
+
hapticsSupported(): boolean;
|
|
206
|
+
/** Taps as flat [time, intensity, sharpness, ...] triples. */
|
|
207
|
+
hapticsPlay(taps: Array<number>, throttle: boolean): void;
|
|
208
|
+
}
|
|
209
|
+
declare const _default: Spec | null | undefined;
|
|
210
|
+
export default _default;
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { type Camera, type Light, type RenderSource } from '../types';
|
|
2
|
+
import { type ColorInput } from '../world/color';
|
|
3
|
+
import { type ViewStyle } from './host';
|
|
4
|
+
import { type RenderQuality, type RenderQualitySetting } from './quality';
|
|
5
|
+
/**
|
|
6
|
+
* Runs `fn` right after the next frame a GameView hands to the screen, on the same display clock
|
|
7
|
+
* (the native one where the platform has it): the time a frame leaves is the best moment for
|
|
8
|
+
* background work, such as loading in slices. With no GameView running it falls back to
|
|
9
|
+
* requestAnimationFrame. Returns a function that cancels it.
|
|
10
|
+
*
|
|
11
|
+
* ```ts
|
|
12
|
+
* const cancel = afterNextFrame(() => buildNextChunk());
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
export declare function afterNextFrame(fn: () => void): () => void;
|
|
16
|
+
export type GameViewStats = {
|
|
17
|
+
fps: number;
|
|
18
|
+
/** Mean time spent in `onUpdate` per frame, in milliseconds. */
|
|
19
|
+
updateMs: number;
|
|
20
|
+
/** Average milliseconds per frame spent drawing (CPU side, including waiting on the GPU). */
|
|
21
|
+
renderMs: number;
|
|
22
|
+
/** The quality level drawn with (with `quality="auto"`, the one it settled on so far). */
|
|
23
|
+
quality: RenderQuality;
|
|
24
|
+
/** The graphics API drawing: "vulkan", "gl" (OpenGL ES) or "metal". */
|
|
25
|
+
backend: string;
|
|
26
|
+
};
|
|
27
|
+
export type SwipeDirection = 'left' | 'right' | 'up' | 'down';
|
|
28
|
+
export type OverlayTouchPhase = 'start' | 'move' | 'end' | 'cancel';
|
|
29
|
+
export type DragEvent = {
|
|
30
|
+
phase: 'start' | 'move' | 'end';
|
|
31
|
+
/** Finger position in the view, in points. */
|
|
32
|
+
x: number;
|
|
33
|
+
y: number;
|
|
34
|
+
/** Distance moved since the drag started, in points. */
|
|
35
|
+
dx: number;
|
|
36
|
+
dy: number;
|
|
37
|
+
/** On "end": the drag was interrupted (a second finger started a pinch, or the system took the touch). Put a held piece back. */
|
|
38
|
+
cancelled?: boolean;
|
|
39
|
+
};
|
|
40
|
+
export type PinchEvent = {
|
|
41
|
+
phase: 'start' | 'move' | 'end';
|
|
42
|
+
/** Finger spread relative to the start: 2 = twice as far apart (zoom in). */
|
|
43
|
+
scale: number;
|
|
44
|
+
/** Radians the two fingers turned since the start, clockwise on screen. */
|
|
45
|
+
rotation: number;
|
|
46
|
+
/** Midpoint between the fingers in the view, in points. */
|
|
47
|
+
x: number;
|
|
48
|
+
y: number;
|
|
49
|
+
};
|
|
50
|
+
export type GameViewProps = {
|
|
51
|
+
/** What to draw (usually a `World`). Changing it restarts the view; never pass a disposed world. */
|
|
52
|
+
source: RenderSource;
|
|
53
|
+
/**
|
|
54
|
+
* Your game loop, called once per frame before drawing, with the elapsed seconds (capped at 0.1;
|
|
55
|
+
* 0 until the first frame is on screen, so nothing plays out unseen): read input, spawn, move the
|
|
56
|
+
* camera. The world (and `overlay`) is stepped for you right after; call `world.update(dt)` here
|
|
57
|
+
* yourself only to step it at a different point or with a different `dt`.
|
|
58
|
+
*/
|
|
59
|
+
onUpdate?: (dt: number) => void;
|
|
60
|
+
/** Mutate this object (e.g. `camera.eye`) from `onUpdate`; it is read every frame. */
|
|
61
|
+
camera?: Camera;
|
|
62
|
+
light?: Light;
|
|
63
|
+
/** Sky / clear color: a CSS color or linear 0..1 RGB (alpha ignored). Also the fog color. Default dark navy. */
|
|
64
|
+
background?: ColorInput;
|
|
65
|
+
/** Distance fog density towards `background` (e.g. 0.02). Default 0 (off). */
|
|
66
|
+
fog?: number;
|
|
67
|
+
/**
|
|
68
|
+
* Resolution, anti-aliasing and shadow quality. "auto" (default) starts at "high", steps down only
|
|
69
|
+
* while the GPU really can't keep up (shadow detail first, then anti-aliasing, resolution last) and
|
|
70
|
+
* steps back up once frames are smooth again, so every phone gets the best look it can hold.
|
|
71
|
+
*/
|
|
72
|
+
quality?: RenderQualitySetting;
|
|
73
|
+
/** Suspend updates and drawing while keeping the native surface mounted. */
|
|
74
|
+
paused?: boolean;
|
|
75
|
+
style?: ViewStyle;
|
|
76
|
+
/** A quick tap, at `x, y` points in the view. `world.pick(x, y)` finds what was tapped. */
|
|
77
|
+
onTap?: (x: number, y: number) => void;
|
|
78
|
+
/** A quick flick in one direction (2048, runners, sliding puzzles). */
|
|
79
|
+
onSwipe?: (direction: SwipeDirection) => void;
|
|
80
|
+
/** Finger down, moving and up (aiming, dragging pieces, slicing). */
|
|
81
|
+
onDrag?: (drag: DragEvent) => void;
|
|
82
|
+
/** A finger held still for half a second (pick up, show moves). No tap follows. */
|
|
83
|
+
onLongPress?: (x: number, y: number) => void;
|
|
84
|
+
/** Two fingers spreading, pinching or turning (zoom and rotate a board). Ends any drag in progress. */
|
|
85
|
+
onPinch?: (pinch: PinchEvent) => void;
|
|
86
|
+
/** Host primary action for keyboard input, such as Start/Stop or Play Again. */
|
|
87
|
+
onPrimaryAction?: () => void;
|
|
88
|
+
/**
|
|
89
|
+
* A screen-space layer drawn over the scene by the renderer (scoreboards, buttons): usually a second
|
|
90
|
+
* `World`, in points from the view's top-left with y up (so on screen y <= 0) and z toward the viewer
|
|
91
|
+
* within -100..100. Unlit (flat faces show their exact color) and always in front. Stepped each
|
|
92
|
+
* frame like `source`.
|
|
93
|
+
*/
|
|
94
|
+
overlay?: RenderSource;
|
|
95
|
+
/**
|
|
96
|
+
* Touches for the overlay, in points in the view. Return true from "start" to claim the touch (a
|
|
97
|
+
* button was hit): its moves and end come here, and the game gets no drag, tap or swipe for it.
|
|
98
|
+
* "cancel" when the system takes the touch.
|
|
99
|
+
*/
|
|
100
|
+
onOverlayTouch?: (phase: OverlayTouchPhase, x: number, y: number) => boolean | void;
|
|
101
|
+
/** Called once a second. */
|
|
102
|
+
onStats?: (stats: GameViewStats) => void;
|
|
103
|
+
/** GPU setup failures and rendering errors. Defaults to console.error. */
|
|
104
|
+
onError?: (error: Error) => void;
|
|
105
|
+
};
|
|
106
|
+
export declare function GameView(props: GameViewProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Camera, RenderSource } from '../types';
|
|
2
|
+
/** `camera.follow`: ease the target toward the entity (where it was last drawn) and keep the eye at the offset. */
|
|
3
|
+
export declare function follow(camera: Camera, source: RenderSource, out: [number, number, number], dt: number): void;
|
|
4
|
+
/** `camera.shake`: a jittered copy of the camera; the strength fades by itself. */
|
|
5
|
+
export declare function shake(camera: Camera, out: Camera, dt: number): Camera;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type CSSProperties } from 'react';
|
|
2
|
+
import { createTouchResponder } from './touch';
|
|
3
|
+
export { createTouchResponder };
|
|
4
|
+
export type ViewStyle = CSSProperties;
|
|
5
|
+
export declare const pixelRatio: () => number;
|
|
6
|
+
export declare function useActive(): boolean;
|
|
7
|
+
interface SurfaceProps {
|
|
8
|
+
surfaceId: number;
|
|
9
|
+
style?: CSSProperties;
|
|
10
|
+
onSize: (width: number, height: number) => void;
|
|
11
|
+
onError: (error: Error) => void;
|
|
12
|
+
touch?: ReturnType<typeof createTouchResponder>;
|
|
13
|
+
onPrimaryAction?: () => void;
|
|
14
|
+
}
|
|
15
|
+
export declare function Surface({ surfaceId, style, onSize, onError, touch, onPrimaryAction }: SurfaceProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Light } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* A light for flat, front-facing scenes (boards, puzzles, 2D games looking down -z): surfaces facing
|
|
4
|
+
* the camera (+z) are lit at exactly 1, so flat panels show their color unchanged, while rounded
|
|
5
|
+
* shapes keep their shading (lighter toward the light, darker away). Shadows are off.
|
|
6
|
+
*
|
|
7
|
+
* ```tsx
|
|
8
|
+
* <GameView source={world} light={frontLight([-0.45, 0.6, 1], 0.5)} />
|
|
9
|
+
* ```
|
|
10
|
+
*/
|
|
11
|
+
export declare function frontLight(direction: [number, number, number], ambient: number): Light;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export declare const VERTEX_FLOATS = 11;
|
|
2
|
+
type V3 = readonly [number, number, number];
|
|
3
|
+
export declare class Builder {
|
|
4
|
+
vertices: number[];
|
|
5
|
+
indices: number[];
|
|
6
|
+
/** Adds a vertex, returns its index. */
|
|
7
|
+
vertex(p: V3, n: V3, u: number, v: number): number;
|
|
8
|
+
/** Two triangles, counter-clockwise a b c d as seen from the front. */
|
|
9
|
+
quad(a: number, b: number, c: number, d: number): void;
|
|
10
|
+
/**
|
|
11
|
+
* A (rows + 1) x (cols + 1) vertex grid; `at(u, v)` gives position and normal. u runs along a row and
|
|
12
|
+
* v down the rows; the grid faces the side from which u goes right and v goes down.
|
|
13
|
+
*/
|
|
14
|
+
grid(rows: number, cols: number, at: (u: number, v: number) => [V3, V3]): void;
|
|
15
|
+
/** A flat disc at height y facing up (+1) or down (-1). */
|
|
16
|
+
disc(y: number, radius: number, facing: 1 | -1, segments: number): void;
|
|
17
|
+
}
|
|
18
|
+
/** Render-ready geometry: VERTEX_FLOATS floats per vertex, u32 triangle indices. */
|
|
19
|
+
export type MeshGeometry = {
|
|
20
|
+
vertices: Float32Array;
|
|
21
|
+
indices: Uint32Array;
|
|
22
|
+
};
|
|
23
|
+
/** What the renderer draws for a mesh id: geometry, and a texture id (see `loadTexture`) if any. */
|
|
24
|
+
/** `shine` 0..1: how glossy (sun highlight and sky reflection), 0 = matte. */
|
|
25
|
+
export type MeshInfo = {
|
|
26
|
+
geometry: MeshGeometry;
|
|
27
|
+
texture?: number;
|
|
28
|
+
shine?: number;
|
|
29
|
+
};
|
|
30
|
+
/** Registers what a mesh id draws (loaded models, glyphs, textured variants). */
|
|
31
|
+
export declare function registerMesh(mesh: number, info: MeshInfo, uploadGeometry?: boolean): void;
|
|
32
|
+
/** One past the highest mesh id in use: per-frame scans of a source's ranges stop here. */
|
|
33
|
+
export declare const getMeshIdLimit: () => number;
|
|
34
|
+
/** Generates the built-in shapes in the Rust core and registers them with the native renderer (once). */
|
|
35
|
+
export declare function uploadBuiltInMeshes(): void;
|
|
36
|
+
/**
|
|
37
|
+
* Initializes the shared core and built-in meshes. Await before using the engine on the web.
|
|
38
|
+
* Mobile initialization remains synchronous and also warms the GPU on a background thread.
|
|
39
|
+
* Repeat calls reuse initialization and mesh registration.
|
|
40
|
+
*/
|
|
41
|
+
export declare function warmUpEngine(): Promise<void>;
|
|
42
|
+
/** What to draw for a mesh id, or undefined ("none", or unknown). Built-in shapes use native geometry. */
|
|
43
|
+
export declare function meshInfo(mesh: number): MeshInfo | undefined;
|
|
44
|
+
export {};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export type RenderQuality = 'high' | 'medium' | 'low' | 'lowest';
|
|
2
|
+
/** `"auto"` starts at "high" and steps down only while the device really can't keep up. */
|
|
3
|
+
export type RenderQualitySetting = RenderQuality | 'auto';
|
|
4
|
+
export type QualityLevel = {
|
|
5
|
+
/** Most device pixels drawn per point (the screen's own ratio when lower). */
|
|
6
|
+
maxPixelRatio: number;
|
|
7
|
+
/** MSAA samples: 4 or 1 (off). */
|
|
8
|
+
samples: 1 | 4;
|
|
9
|
+
/** Shadow map width and height in texels. */
|
|
10
|
+
shadowSize: number;
|
|
11
|
+
/** 3x3 filtered (soft) shadow edges, or a single tap (hard). */
|
|
12
|
+
softShadows: boolean;
|
|
13
|
+
};
|
|
14
|
+
/** From best looking to cheapest; "auto" walks down this list only as far as it must. */
|
|
15
|
+
export declare const QUALITIES: readonly RenderQuality[];
|
|
16
|
+
export declare const QUALITY_LEVELS: Record<RenderQuality, QualityLevel>;
|
|
17
|
+
/** One second of frames, as the frame loop measured it. */
|
|
18
|
+
export type FrameReport = {
|
|
19
|
+
/** The typical (median) time between frames, in ms: hiccups (garbage collection, a busy JS frame) don't move it. */
|
|
20
|
+
frameMs: number;
|
|
21
|
+
/** The typical (median) time spent drawing a frame, in ms (including any wait for the screen). */
|
|
22
|
+
renderMs: number;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Picks the level for "auto": starts at the best, steps down one level after `SLOW_SECONDS`
|
|
26
|
+
* consecutive seconds whose typical frame misses ~50 fps while drawing took most of it (after a
|
|
27
|
+
* single second when it misses ~33 fps, so a struggling phone recovers in seconds rather than
|
|
28
|
+
* stuttering through every level), and steps back up after `FAST_SECONDS` smooth seconds. A level that fails again soon after being restored
|
|
29
|
+
* becomes the ceiling, so it never bounces.
|
|
30
|
+
*/
|
|
31
|
+
export declare class AutoQuality {
|
|
32
|
+
private index;
|
|
33
|
+
/** The best level it may return to (raised past a level that keeps failing). */
|
|
34
|
+
private ceiling;
|
|
35
|
+
private started;
|
|
36
|
+
private changed;
|
|
37
|
+
private raisedAt;
|
|
38
|
+
private slow;
|
|
39
|
+
private verySlow;
|
|
40
|
+
private fast;
|
|
41
|
+
get quality(): RenderQuality;
|
|
42
|
+
/** Feeds one second of frames; returns true when the level changed. */
|
|
43
|
+
report(now: number, frames: FrameReport): boolean;
|
|
44
|
+
private moved;
|
|
45
|
+
}
|
|
46
|
+
/** The middle value of `values` (sorted in place). */
|
|
47
|
+
export declare function median(values: number[]): number;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { PointerEvent as ReactPointerEvent } from 'react';
|
|
2
|
+
type Touch = {
|
|
3
|
+
pageX: number;
|
|
4
|
+
pageY: number;
|
|
5
|
+
};
|
|
6
|
+
interface Event {
|
|
7
|
+
nativeEvent: Touch & {
|
|
8
|
+
locationX: number;
|
|
9
|
+
locationY: number;
|
|
10
|
+
touches: Touch[];
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
interface Gesture {
|
|
14
|
+
dx: number;
|
|
15
|
+
dy: number;
|
|
16
|
+
}
|
|
17
|
+
interface Callbacks {
|
|
18
|
+
onStartShouldSetPanResponder: () => boolean;
|
|
19
|
+
onMoveShouldSetPanResponder: () => boolean;
|
|
20
|
+
onPanResponderGrant: (event: Event) => void;
|
|
21
|
+
onPanResponderMove: (event: Event, gesture: Gesture) => void;
|
|
22
|
+
onPanResponderRelease: (event: Event, gesture: Gesture) => void;
|
|
23
|
+
onPanResponderTerminate: (event: Event, gesture: Gesture) => void;
|
|
24
|
+
}
|
|
25
|
+
export interface PanResponderInstance {
|
|
26
|
+
panHandlers: {
|
|
27
|
+
onPointerDown: (event: ReactPointerEvent<HTMLDivElement>) => void;
|
|
28
|
+
onPointerMove: (event: ReactPointerEvent<HTMLDivElement>) => void;
|
|
29
|
+
onPointerUp: (event: ReactPointerEvent<HTMLDivElement>) => void;
|
|
30
|
+
onPointerCancel: (event: ReactPointerEvent<HTMLDivElement>) => void;
|
|
31
|
+
onLostPointerCapture: (event: ReactPointerEvent<HTMLDivElement>) => void;
|
|
32
|
+
};
|
|
33
|
+
cancel: () => void;
|
|
34
|
+
}
|
|
35
|
+
/** Adapt DOM pointer capture to the gesture recognizer used on mobile. Coordinates stay in CSS pixels. */
|
|
36
|
+
export declare const PanResponder: {
|
|
37
|
+
create(callbacks: Callbacks): PanResponderInstance;
|
|
38
|
+
};
|
|
39
|
+
export {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { DragEvent, OverlayTouchPhase, PinchEvent, SwipeDirection } from './GameView';
|
|
2
|
+
import { type PanResponderInstance } from './responder';
|
|
3
|
+
declare const TAP_SLOP = 10;
|
|
4
|
+
declare const TAP_TIME = 300;
|
|
5
|
+
declare const SWIPE_DISTANCE = 30;
|
|
6
|
+
declare const SWIPE_SPEED = 0.3;
|
|
7
|
+
declare const LONG_PRESS_TIME = 500;
|
|
8
|
+
type Handlers = {
|
|
9
|
+
onTap?: (x: number, y: number) => void;
|
|
10
|
+
onSwipe?: (direction: SwipeDirection) => void;
|
|
11
|
+
onDrag?: (drag: DragEvent) => void;
|
|
12
|
+
onLongPress?: (x: number, y: number) => void;
|
|
13
|
+
onPinch?: (pinch: PinchEvent) => void;
|
|
14
|
+
onOverlayTouch?: (phase: OverlayTouchPhase, x: number, y: number) => boolean | void;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Creates a PanResponder that recognizes taps, swipes, drags, long presses and pinches.
|
|
18
|
+
* `getHandlers` is called on each event so the caller can swap handlers without recreating the responder.
|
|
19
|
+
*/
|
|
20
|
+
export declare function createTouchResponder(getHandlers: () => Handlers): {
|
|
21
|
+
responder: PanResponderInstance;
|
|
22
|
+
dispose: () => void;
|
|
23
|
+
cancel: () => void;
|
|
24
|
+
};
|
|
25
|
+
export { TAP_SLOP, TAP_TIME, SWIPE_DISTANCE, SWIPE_SPEED, LONG_PRESS_TIME };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type DependencyList } from 'react';
|
|
2
|
+
import { World } from '../world/World';
|
|
3
|
+
/** What `useWorld`'s setup may return: a cleanup, run just before the world is disposed. */
|
|
4
|
+
export type WorldSetup = (world: World) => void | (() => void);
|
|
5
|
+
/**
|
|
6
|
+
* A `World` owned by a component: the engine is warmed up (needed on the web, cheap on mobile), the
|
|
7
|
+
* world is created with `capacity` entity slots and handed to `setup` to fill, and it is disposed on
|
|
8
|
+
* unmount. A change in `deps` replaces it with a fresh one. Returns null until it's ready (one frame),
|
|
9
|
+
* and while the engine is unavailable (Expo Go) or failed to start (`onError`, console by default).
|
|
10
|
+
*
|
|
11
|
+
* ```tsx
|
|
12
|
+
* const world = useWorld(100, (w) => {
|
|
13
|
+
* w.spawn({ mesh: 'plane', scale: [20, 1, 20], color: '#4C9A4C', physics: 'fixed' });
|
|
14
|
+
* w.spawn({ mesh: 'sphere', position: [0, 4, 0], color: '#3399FF', physics: 'dynamic' });
|
|
15
|
+
* });
|
|
16
|
+
* return world && <GameView source={world} style={{ flex: 1 }} />;
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export declare function useWorld(capacity: number, setup?: WorldSetup, deps?: DependencyList, onError?: (error: Error) => void): World | null;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { ColorInput } from './world/color';
|
|
2
|
+
import type { Entity } from './world/types';
|
|
3
|
+
export type Vec3 = readonly [number, number, number];
|
|
4
|
+
/** Number of mesh ids: built-in shapes (0..15), then loaded models, glyphs and textured variants. */
|
|
5
|
+
export declare const MAX_MESHES = 4096;
|
|
6
|
+
/** What the renderer draws. `World` implements it; so can any custom simulation. */
|
|
7
|
+
export interface RenderSource {
|
|
8
|
+
/** Native world id, when this source supports skeletal characters. */
|
|
9
|
+
readonly nativeWorld?: number;
|
|
10
|
+
/** Column-major mat4 per instance (16 floats), grouped by mesh. Only the first `count` are valid. */
|
|
11
|
+
readonly matrices: Float32Array;
|
|
12
|
+
/** RGBA per instance (4 floats), same order as `matrices`. Alpha below 1 draws see-through. */
|
|
13
|
+
readonly colors: Float32Array;
|
|
14
|
+
/** Texture region per instance (u0 v0 u1 v1), same order. Optional: the whole texture by default. */
|
|
15
|
+
readonly regions?: Float32Array;
|
|
16
|
+
/**
|
|
17
|
+
* `[first, count]` per mesh id, in instances: opaque instances at `ranges[2 * mesh]`, transparent ones
|
|
18
|
+
* at `ranges[2 * (MAX_MESHES + mesh)]`. Shorter arrays just have no transparent part.
|
|
19
|
+
*/
|
|
20
|
+
readonly ranges: Uint32Array;
|
|
21
|
+
/** Total number of valid instances. */
|
|
22
|
+
readonly count: number;
|
|
23
|
+
/** Maximum number of instances (sizes the GPU buffers). */
|
|
24
|
+
readonly capacity: number;
|
|
25
|
+
/** Called by GameView after each frame with the camera it drew with (for picking and `toScreen`). */
|
|
26
|
+
setView?(viewProj: Float32Array, width: number, height: number): void;
|
|
27
|
+
/**
|
|
28
|
+
* Steps the source. When present, GameView calls it once a frame after `onUpdate`, unless
|
|
29
|
+
* `onUpdate` already did (`updateCount` changed) or the source is disposed.
|
|
30
|
+
*/
|
|
31
|
+
update?(dt: number): void;
|
|
32
|
+
/** How many times `update` has run. */
|
|
33
|
+
readonly updateCount?: number;
|
|
34
|
+
readonly isDisposed?: boolean;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Built-in shapes, each 1 unit across before scaling. "none" isn't drawn (groups, pivots, trigger zones).
|
|
38
|
+
* "puff" is a soft, round sprite that always faces the camera and is always see-through: overlapping
|
|
39
|
+
* puffs blend into smoke, dust, steam and clouds. "flame" is the same sprite drawn additively: it adds
|
|
40
|
+
* light to what's behind it, so overlapping flames build up to a hot white core and stay bright over
|
|
41
|
+
* smoke (fire, sparks, explosions, magic, glows). Use them as a burst's `mesh`.
|
|
42
|
+
*/
|
|
43
|
+
export type Shape = 'cube' | 'sphere' | 'plane' | 'cylinder' | 'cone' | 'capsule' | 'torus' | 'roundedBox' | 'puff' | 'flame' | 'none';
|
|
44
|
+
/** Mesh ids of the built-in shapes, as the core and renderer know them. */
|
|
45
|
+
export declare const SHAPE_MESH: Record<Shape, number>;
|
|
46
|
+
export type Camera = {
|
|
47
|
+
eye: [number, number, number];
|
|
48
|
+
target: [number, number, number];
|
|
49
|
+
/** Vertical field of view in radians (ignored when `ortho` is set). */
|
|
50
|
+
fov: number;
|
|
51
|
+
/** Orthographic: half the visible height in world units. Board and puzzle games look flat and tidy. */
|
|
52
|
+
ortho?: number;
|
|
53
|
+
/**
|
|
54
|
+
* Chase an entity: each frame the target moves toward it and the eye keeps `offset` from the target.
|
|
55
|
+
* `smoothing` is roughly the seconds it takes to catch up (0 = rigid, default 0.15).
|
|
56
|
+
*/
|
|
57
|
+
follow?: {
|
|
58
|
+
target: Entity;
|
|
59
|
+
offset: Vec3;
|
|
60
|
+
smoothing?: number;
|
|
61
|
+
} | null;
|
|
62
|
+
/** Shake strength in world units (e.g. 0.3 for a hit). Fades out by itself. */
|
|
63
|
+
shake?: number;
|
|
64
|
+
};
|
|
65
|
+
export type Light = {
|
|
66
|
+
/** Direction *towards* the light. Need not be normalized. */
|
|
67
|
+
direction: [number, number, number];
|
|
68
|
+
/** 0..1 ambient term. */
|
|
69
|
+
ambient: number;
|
|
70
|
+
/** Cast shadows (one directional shadow map centred on the camera target). Default true. */
|
|
71
|
+
shadows?: boolean;
|
|
72
|
+
/** Half-size in world units of the shadowed area around the camera target. Default 30. */
|
|
73
|
+
shadowExtent?: number;
|
|
74
|
+
/**
|
|
75
|
+
* Color and brightness of the light, multiplying both sun and ambient: e.g. [0.35, 0.38, 0.6] for
|
|
76
|
+
* moonlight, or a CSS color. Glowing colors (channels above 1) aren't affected. Alpha, if given, is
|
|
77
|
+
* ignored. Default [1, 1, 1].
|
|
78
|
+
*/
|
|
79
|
+
color?: ColorInput;
|
|
80
|
+
};
|