@airisu-dev/react-native-live2d-skia 0.0.0-stage → 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/LICENSE +21 -0
- package/Live2dSkia.podspec +159 -0
- package/README.md +64 -2
- package/android/CMakeLists.txt +113 -0
- package/android/build.gradle +223 -0
- package/android/fix-prefab.gradle +51 -0
- package/android/gradle.properties +5 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/cpp/cpp-adapter.cpp +9 -0
- package/android/src/main/java/com/live2dskia/Live2dSkiaPackage.kt +20 -0
- package/app.plugin.js +2 -0
- package/cli/build/index.js +157 -0
- package/cpp/cubism/CubismCompat.hpp +26 -0
- package/cpp/cubism/CubismHelpers.hpp +27 -0
- package/cpp/cubism/CubismRendererStub.cpp +14 -0
- package/cpp/cubism/CubismSetup.cpp +54 -0
- package/cpp/cubism/CubismSetup.hpp +9 -0
- package/cpp/cubism/HeldParameterUpdater.hpp +25 -0
- package/cpp/cubism/Live2DUserModel.cpp +125 -0
- package/cpp/cubism/Live2DUserModel.hpp +57 -0
- package/cpp/cubism/Live2DUserModelAnimation.cpp +107 -0
- package/cpp/drawing/JsiUnwrap.hpp +25 -0
- package/cpp/drawing/MeshCache.cpp +75 -0
- package/cpp/drawing/MeshCache.hpp +45 -0
- package/cpp/drawing/SkiaDrawer.cpp +138 -0
- package/cpp/drawing/SkiaDrawer.hpp +42 -0
- package/cpp/hybrid/HybridLive2DModel.cpp +174 -0
- package/cpp/hybrid/HybridLive2DModel.hpp +64 -0
- package/cpp/hybrid/HybridLive2dSkia.cpp +10 -0
- package/cpp/hybrid/HybridLive2dSkia.hpp +11 -0
- package/ios/Bridge.h +8 -0
- package/nitro.json +20 -0
- package/nitrogen/generated/.gitattributes +1 -0
- package/nitrogen/generated/android/Live2dSkia+autolinking.cmake +82 -0
- package/nitrogen/generated/android/Live2dSkia+autolinking.gradle +27 -0
- package/nitrogen/generated/android/Live2dSkiaOnLoad.cpp +49 -0
- package/nitrogen/generated/android/Live2dSkiaOnLoad.hpp +34 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/live2dskia/Live2dSkiaOnLoad.kt +35 -0
- package/nitrogen/generated/ios/Live2dSkia+autolinking.rb +62 -0
- package/nitrogen/generated/ios/Live2dSkia-Swift-Cxx-Bridge.cpp +17 -0
- package/nitrogen/generated/ios/Live2dSkia-Swift-Cxx-Bridge.hpp +27 -0
- package/nitrogen/generated/ios/Live2dSkia-Swift-Cxx-Umbrella.hpp +38 -0
- package/nitrogen/generated/ios/Live2dSkiaAutolinking.mm +35 -0
- package/nitrogen/generated/ios/Live2dSkiaAutolinking.swift +16 -0
- package/nitrogen/generated/shared/c++/DrawableData.hpp +116 -0
- package/nitrogen/generated/shared/c++/HybridLive2DModelSpec.cpp +39 -0
- package/nitrogen/generated/shared/c++/HybridLive2DModelSpec.hpp +86 -0
- package/nitrogen/generated/shared/c++/HybridLive2dSkiaSpec.cpp +21 -0
- package/nitrogen/generated/shared/c++/HybridLive2dSkiaSpec.hpp +66 -0
- package/nitrogen/generated/shared/c++/MotionPriority.hpp +80 -0
- package/package.json +146 -4
- package/plugin/build/index.d.ts +14 -0
- package/plugin/build/index.js +81 -0
- package/src/components/Live2D.tsx +131 -0
- package/src/components/index.ts +2 -0
- package/src/hooks/index.ts +8 -0
- package/src/hooks/useLive2DGesture.ts +140 -0
- package/src/hooks/useLive2DModel.ts +47 -0
- package/src/index.ts +5 -0
- package/src/loader/cubismJson.ts +23 -0
- package/src/loader/index.ts +9 -0
- package/src/loader/loadModel.ts +194 -0
- package/src/loader/modelContext.ts +80 -0
- package/src/loader/modelUrl.ts +112 -0
- package/src/native.ts +4 -0
- package/src/rendering/drawer.ts +256 -0
- package/src/rendering/skia.ts +114 -0
- package/src/rendering/ticker/addToTicker.ts +52 -0
- package/src/rendering/ticker/constants.ts +11 -0
- package/src/rendering/ticker/frames.ts +35 -0
- package/src/rendering/ticker/index.ts +5 -0
- package/src/rendering/ticker/loop.ts +115 -0
- package/src/rendering/ticker/state.ts +65 -0
- package/src/rendering/ticker/stats.ts +36 -0
- package/src/rendering/ticker/types.ts +57 -0
- package/src/specs/react-native-live2d-skia.nitro.ts +88 -0
- package/src/utils/clock.ts +10 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { Synchronizable } from 'react-native-worklets'
|
|
2
|
+
import type { Live2DModel as NativeModel } from '../../specs/react-native-live2d-skia.nitro'
|
|
3
|
+
import type { CanvasInfo } from '../drawer'
|
|
4
|
+
import type { SkImage, SkPicture, SkShader } from '../skia'
|
|
5
|
+
|
|
6
|
+
/** Averages per frame over the last second, in milliseconds unless noted. */
|
|
7
|
+
export interface Live2DFrameStats {
|
|
8
|
+
fps: number
|
|
9
|
+
/** The frame rate the loop aims for: the display's refresh rate, or `maxFps`. */
|
|
10
|
+
targetFps: number
|
|
11
|
+
/** All work for this model's frame on the animation thread. */
|
|
12
|
+
workMs: number
|
|
13
|
+
/** Motions, physics and so on in C++ (`update`). */
|
|
14
|
+
updateMs: number
|
|
15
|
+
/** Copying vertex data out of C++ (`getDrawables`). 0 when drawn in C++. */
|
|
16
|
+
drawablesMs: number
|
|
17
|
+
/** Recording the picture, including `meshMs`. */
|
|
18
|
+
drawMs: number
|
|
19
|
+
/** Building Skia vertices for drawables that moved. */
|
|
20
|
+
meshMs: number
|
|
21
|
+
/** Meshes rebuilt per frame (a count). */
|
|
22
|
+
meshesBuilt: number
|
|
23
|
+
/**
|
|
24
|
+
* Mask layers per frame (a count). Their cost is in the UI thread's Skia
|
|
25
|
+
* draw, which these stats don't cover.
|
|
26
|
+
*/
|
|
27
|
+
layers: number
|
|
28
|
+
/** Models animated by the loop, this one included (a count). */
|
|
29
|
+
models: number
|
|
30
|
+
/** All work for a frame of the loop, every model included. */
|
|
31
|
+
loopWorkMs: number
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** A newly drawn frame, for the UI thread to pick up. */
|
|
35
|
+
export type PublishedFrame = { frame: number; picture: SkPicture } | null
|
|
36
|
+
|
|
37
|
+
export interface TickerView {
|
|
38
|
+
target: Synchronizable<PublishedFrame>
|
|
39
|
+
/** The frame the UI thread shows (-1 before the first). Frames are freed once every view is past them. */
|
|
40
|
+
shown: Synchronizable<number>
|
|
41
|
+
/** Set to false to stop showing frames here. */
|
|
42
|
+
running: Synchronizable<boolean>
|
|
43
|
+
/** The display's frame interval, measured on the UI thread; 0 until known. */
|
|
44
|
+
displayMs: Synchronizable<number>
|
|
45
|
+
/** Shortest frame time for this view (`maxFps`); 0 for no cap. */
|
|
46
|
+
capMs: number
|
|
47
|
+
/** Gets frame stats about once a second; null if not wanted. */
|
|
48
|
+
report: ((stats: Live2DFrameStats) => void) | null
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface TickerModel {
|
|
52
|
+
id: number
|
|
53
|
+
native: NativeModel
|
|
54
|
+
textures: SkImage[]
|
|
55
|
+
shaders: SkShader[]
|
|
56
|
+
canvas: CanvasInfo
|
|
57
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import type { HybridObject } from 'react-native-nitro-modules'
|
|
2
|
+
|
|
3
|
+
export interface DrawableData {
|
|
4
|
+
/** Index into the model's drawables; `masks` refers to these. */
|
|
5
|
+
index: number
|
|
6
|
+
/** Cubism's visibility flag. Hidden drawables can still be used as masks. */
|
|
7
|
+
visible: boolean
|
|
8
|
+
textureIndex: number
|
|
9
|
+
opacity: number
|
|
10
|
+
/** Cubism constant flags (`csmBlendAdditive`, `csmIsInvertedMask`, ...). */
|
|
11
|
+
constantFlags: number
|
|
12
|
+
/** Indices of the drawables that clip this one. Empty if unmasked. */
|
|
13
|
+
masks: number[]
|
|
14
|
+
/** float32 x/y pairs in model units, y-up. */
|
|
15
|
+
positions: ArrayBuffer
|
|
16
|
+
/** float32 u/v pairs in 0..1, v-up. */
|
|
17
|
+
uvs: ArrayBuffer
|
|
18
|
+
/** uint16 triangle indices. */
|
|
19
|
+
indices: ArrayBuffer
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** Like the Cubism SDK samples: a higher priority interrupts a lower one. */
|
|
23
|
+
export type MotionPriority = 'idle' | 'normal' | 'force'
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Thread-safe: the model can be updated on one thread while another starts
|
|
27
|
+
* motions or moves the focus.
|
|
28
|
+
*/
|
|
29
|
+
export interface Live2DModel extends HybridObject<{ ios: 'c++'; android: 'c++' }> {
|
|
30
|
+
readonly canvasWidth: number
|
|
31
|
+
readonly canvasHeight: number
|
|
32
|
+
readonly originX: number
|
|
33
|
+
readonly originY: number
|
|
34
|
+
readonly pixelsPerUnit: number
|
|
35
|
+
readonly drawableCount: number
|
|
36
|
+
/** All drawables sorted by render order (back to front), including hidden ones. */
|
|
37
|
+
getDrawables(): DrawableData[]
|
|
38
|
+
loadPhysics(json: string): void
|
|
39
|
+
loadPose(json: string): void
|
|
40
|
+
/**
|
|
41
|
+
* Loads one `motion3.json` as entry `index` of motion `group`.
|
|
42
|
+
* Fade times come from `model3.json` when it defines them.
|
|
43
|
+
*/
|
|
44
|
+
loadMotion(group: string, index: number, json: string): void
|
|
45
|
+
/**
|
|
46
|
+
* Starts a loaded motion, or a random one of `group` without `index`.
|
|
47
|
+
* Returns false if it isn't loaded or a higher priority motion is playing.
|
|
48
|
+
*/
|
|
49
|
+
startMotion(group: string, index?: number, priority?: MotionPriority): boolean
|
|
50
|
+
loadExpression(name: string, json: string): void
|
|
51
|
+
/**
|
|
52
|
+
* Fades to a loaded expression, or a random one without `name`.
|
|
53
|
+
* Returns false if it isn't loaded.
|
|
54
|
+
*/
|
|
55
|
+
setExpression(name?: string): boolean
|
|
56
|
+
clearExpression(): void
|
|
57
|
+
/**
|
|
58
|
+
* Holds a parameter at `value` until `clearParameter`. Applied after motions,
|
|
59
|
+
* expressions, eye blink, look and breath, before physics and pose.
|
|
60
|
+
*/
|
|
61
|
+
setParameter(id: string, value: number): void
|
|
62
|
+
clearParameter(id: string): void
|
|
63
|
+
/**
|
|
64
|
+
* Makes the model look at a point, easing towards it: -1..1 on each axis,
|
|
65
|
+
* y-up, (0, 0) is straight ahead.
|
|
66
|
+
*/
|
|
67
|
+
focus(x: number, y: number): void
|
|
68
|
+
/**
|
|
69
|
+
* Names of the `model3.json` hit areas containing a point in model units
|
|
70
|
+
* (y-up, see `originX`/`pixelsPerUnit`), in the order they're listed.
|
|
71
|
+
*/
|
|
72
|
+
hitTest(x: number, y: number): string[]
|
|
73
|
+
/**
|
|
74
|
+
* Advances the model by `deltaSeconds`: motions (a random `Idle` motion
|
|
75
|
+
* whenever nothing plays), expression, eye blink, look, breath, held
|
|
76
|
+
* parameters, physics and pose.
|
|
77
|
+
* Pass 0 to just apply the current state.
|
|
78
|
+
*/
|
|
79
|
+
update(deltaSeconds: number): void
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export interface Live2dSkia extends HybridObject<{ ios: 'c++'; android: 'c++' }> {
|
|
83
|
+
/**
|
|
84
|
+
* Loads a `.moc3` file with its `model3.json` (used for eye blink and lip
|
|
85
|
+
* sync parameters and motion fade times). Throws if the moc is invalid.
|
|
86
|
+
*/
|
|
87
|
+
loadModel(moc: ArrayBuffer, settingsJson: string): Live2DModel
|
|
88
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// performance.now() exists on the JS thread and on worklet runtimes, but this
|
|
2
|
+
// package's TypeScript lib (esnext, no DOM) doesn't declare it.
|
|
3
|
+
type WithPerformance = { performance: { now(): number } }
|
|
4
|
+
|
|
5
|
+
export function now(): number {
|
|
6
|
+
'worklet'
|
|
7
|
+
// Read globalThis here, not from a module constant: a worklet copies what it
|
|
8
|
+
// captures to its runtime, and the global object can't be copied (it's cyclic).
|
|
9
|
+
return (globalThis as unknown as WithPerformance).performance.now()
|
|
10
|
+
}
|