@nayan-ui/engine 1.0.0-beta.4 → 1.0.0-beta.6
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 +225 -116
- package/lib/module/assets/ProceduralCache.js +5 -0
- package/lib/module/assets/loft.js +15 -63
- package/lib/module/assets/procedural.js +500 -0
- package/lib/module/assets/shape.js +147 -245
- package/lib/module/assets/texture.js +65 -0
- package/lib/module/drawing/DrawingDocument.js +1 -1
- package/lib/module/index.js +4 -1
- package/lib/module/media/audio-worklet.js +27 -0
- package/lib/module/media/audio.js +20 -0
- package/lib/module/media/input.web.js +107 -0
- package/lib/module/media/microphone.js +89 -0
- package/lib/module/media/speech.js +80 -0
- package/lib/module/media/speechPlatform.js +12 -0
- package/lib/module/media/speechPlatform.web.js +16 -0
- package/lib/module/native/BrowserEngine.js +122 -0
- package/lib/module/native/NativeNayanEngine.web.js +2 -0
- package/lib/module/render/GameView.js +45 -13
- package/lib/module/render/quality.js +151 -17
- package/lib/module/world/World.js +63 -0
- package/lib/typescript/src/assets/ProceduralCache.d.ts +2 -0
- package/lib/typescript/src/assets/loft.d.ts +3 -1
- package/lib/typescript/src/assets/procedural.d.ts +394 -0
- package/lib/typescript/src/assets/shape.d.ts +13 -7
- package/lib/typescript/src/assets/texture.d.ts +63 -0
- package/lib/typescript/src/index.d.ts +8 -2
- package/lib/typescript/src/media/audio.d.ts +13 -0
- package/lib/typescript/src/media/input.web.d.ts +4 -0
- package/lib/typescript/src/media/microphone.d.ts +51 -0
- package/lib/typescript/src/media/speech.d.ts +38 -0
- package/lib/typescript/src/media/speechPlatform.d.ts +5 -0
- package/lib/typescript/src/media/speechPlatform.web.d.ts +5 -0
- package/lib/typescript/src/native/EngineBridge.d.ts +7 -1
- package/lib/typescript/src/native/spec/NativeNayanEngine.d.ts +72 -0
- package/lib/typescript/src/render/GameView.d.ts +30 -3
- package/lib/typescript/src/render/quality.d.ts +54 -2
- package/lib/typescript/src/types.d.ts +9 -2
- package/lib/typescript/src/world/World.d.ts +16 -0
- package/lib/typescript/src/world/types.d.ts +8 -0
- package/lib/web/audio-worklet.js +27 -0
- package/lib/web/engine_core_bg.wasm +0 -0
- package/lib/web/index.js +1181 -422
- package/lib/web/types/src/assets/ProceduralCache.d.ts +2 -0
- package/lib/web/types/src/assets/loft.d.ts +3 -1
- package/lib/web/types/src/assets/procedural.d.ts +393 -0
- package/lib/web/types/src/assets/shape.d.ts +13 -7
- package/lib/web/types/src/assets/texture.d.ts +63 -0
- package/lib/web/types/src/index.d.ts +8 -2
- package/lib/web/types/src/media/audio.d.ts +13 -0
- package/lib/web/types/src/media/input.d.ts +3 -0
- package/lib/web/types/src/media/microphone.d.ts +50 -0
- package/lib/web/types/src/media/speech.d.ts +37 -0
- package/lib/web/types/src/media/speechPlatform.d.ts +4 -0
- package/lib/web/types/src/native/EngineBridge.d.ts +7 -1
- package/lib/web/types/src/native/spec/NativeNayanEngine.d.ts +72 -0
- package/lib/web/types/src/render/GameView.d.ts +30 -3
- package/lib/web/types/src/render/quality.d.ts +54 -2
- package/lib/web/types/src/types.d.ts +9 -2
- package/lib/web/types/src/world/World.d.ts +16 -0
- package/lib/web/types/src/world/types.d.ts +8 -0
- package/native/android/src/main/AndroidManifest.xml +10 -0
- package/native/android/src/main/java/com/nayanui/engine/EngineMicrophone.java +60 -0
- package/native/android/src/main/java/com/nayanui/engine/EngineSpeech.java +28 -0
- package/native/android/src/main/java/com/nayanui/engine/EngineSurfaceView.java +1 -0
- package/native/android/src/main/java/com/nayanui/engine/NayanEnginePackage.java +2 -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/engine_core.h +63 -1
- package/native/cpp/NayanEngineModule.cpp +296 -0
- package/native/cpp/NayanEngineModule.h +40 -0
- package/native/cpp/generated/NayanEngineSpecJSI.h +397 -0
- package/package.json +1 -1
- package/src/native/spec/NativeNayanEngine.ts +77 -0
|
@@ -186,6 +186,7 @@ NayanEngineModule::NayanEngineModule(std::shared_ptr<CallInvoker> jsInvoker)
|
|
|
186
186
|
|
|
187
187
|
// Worlds are freed when the module and every buffer aliasing them are gone.
|
|
188
188
|
NayanEngineModule::~NayanEngineModule() {
|
|
189
|
+
engine_speech_shutdown();
|
|
189
190
|
{
|
|
190
191
|
std::lock_guard<std::mutex> lock(framesMutex);
|
|
191
192
|
liveModules.erase(this);
|
|
@@ -564,6 +565,20 @@ jsi::Array NayanEngineModule::modelSize(jsi::Runtime &rt, double mesh) {
|
|
|
564
565
|
return jsi::Array::createWithElements(rt, size[0], size[1], size[2]);
|
|
565
566
|
}
|
|
566
567
|
|
|
568
|
+
jsi::Array NayanEngineModule::modelBake(jsi::Runtime &rt, double mesh, jsi::String spec) {
|
|
569
|
+
const auto json = spec.utf8(rt);
|
|
570
|
+
float out[4] = {0, 0, 0, 0};
|
|
571
|
+
if (!engine_model_bake(id(mesh), reinterpret_cast<const uint8_t *>(json.data()), json.size(), out)) {
|
|
572
|
+
return jsi::Array(rt, 0);
|
|
573
|
+
}
|
|
574
|
+
return jsi::Array::createWithElements(rt, out[0], out[1], out[2], out[3]);
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
bool NayanEngineModule::bakeKept(jsi::Runtime &rt, jsi::String key) {
|
|
578
|
+
const auto k = key.utf8(rt);
|
|
579
|
+
return engine_bake_kept(reinterpret_cast<const uint8_t *>(k.data()), k.size()) != 0;
|
|
580
|
+
}
|
|
581
|
+
|
|
567
582
|
double NayanEngineModule::modelTexture(jsi::Runtime &, double mesh) {
|
|
568
583
|
return engine_model_texture(id(mesh));
|
|
569
584
|
}
|
|
@@ -838,6 +853,19 @@ void NayanEngineModule::renderOverlay(
|
|
|
838
853
|
static_cast<float>(width), static_cast<float>(height));
|
|
839
854
|
}
|
|
840
855
|
|
|
856
|
+
void NayanEngineModule::renderBackdrop(
|
|
857
|
+
jsi::Runtime &rt, double surface, jsi::Object matrices, jsi::Object colors, jsi::Object regions, jsi::Object ranges, double count) {
|
|
858
|
+
jsi::ArrayBuffer m = fileData(rt, matrices, "renderBackdrop");
|
|
859
|
+
jsi::ArrayBuffer c = fileData(rt, colors, "renderBackdrop");
|
|
860
|
+
jsi::ArrayBuffer g = fileData(rt, regions, "renderBackdrop");
|
|
861
|
+
jsi::ArrayBuffer r = fileData(rt, ranges, "renderBackdrop");
|
|
862
|
+
size_t capacity = std::min({m.size(rt) / (16 * sizeof(float)), c.size(rt) / (4 * sizeof(float)), g.size(rt) / (4 * sizeof(float))});
|
|
863
|
+
size_t n = count > 0 ? std::min(static_cast<size_t>(count), capacity) : 0;
|
|
864
|
+
engine_render_backdrop(
|
|
865
|
+
static_cast<int32_t>(surface), reinterpret_cast<const float *>(m.data(rt)), reinterpret_cast<const float *>(c.data(rt)),
|
|
866
|
+
reinterpret_cast<const float *>(g.data(rt)), capacity, reinterpret_cast<const uint32_t *>(r.data(rt)), r.size(rt) / sizeof(uint32_t), n);
|
|
867
|
+
}
|
|
868
|
+
|
|
841
869
|
jsi::String NayanEngineModule::renderError(jsi::Runtime &rt) {
|
|
842
870
|
std::string message(engine_render_error(nullptr, 0) + 1, '\0');
|
|
843
871
|
message.resize(engine_render_error(message.data(), message.size()));
|
|
@@ -901,6 +929,97 @@ bool NayanEngineModule::audioIsRunning(jsi::Runtime &) {
|
|
|
901
929
|
return engine_audio_is_running() != 0;
|
|
902
930
|
}
|
|
903
931
|
|
|
932
|
+
void NayanEngineModule::audioRelease(jsi::Runtime &, double sound) {
|
|
933
|
+
engine_audio_release(id(sound));
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
double NayanEngineModule::audioDuration(jsi::Runtime &, double sound) {
|
|
937
|
+
return engine_audio_duration(id(sound));
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
jsi::Object NayanEngineModule::audioLevels(jsi::Runtime &rt, double sound, double perSecond) {
|
|
941
|
+
const uint32_t s = id(sound);
|
|
942
|
+
const size_t count = engine_audio_levels(s, static_cast<float>(perSecond), nullptr, 0);
|
|
943
|
+
auto buffer = std::make_shared<OwnedBuffer>(count * sizeof(float));
|
|
944
|
+
engine_audio_levels(s, static_cast<float>(perSecond), reinterpret_cast<float *>(buffer->data()), count);
|
|
945
|
+
return jsi::ArrayBuffer(rt, buffer);
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
namespace {
|
|
949
|
+
// A pending microphone prompt: the promise it resolves, owned until the answer arrives.
|
|
950
|
+
using MicPromise = AsyncPromise<bool>;
|
|
951
|
+
|
|
952
|
+
#ifndef __ANDROID__
|
|
953
|
+
void micAnswered(void *context, int32_t granted) {
|
|
954
|
+
std::unique_ptr<std::shared_ptr<MicPromise>> promise(static_cast<std::shared_ptr<MicPromise> *>(context));
|
|
955
|
+
(*promise)->resolve(granted != 0);
|
|
956
|
+
}
|
|
957
|
+
#endif
|
|
958
|
+
|
|
959
|
+
#ifdef __ANDROID__
|
|
960
|
+
facebook::jni::alias_ref<facebook::jni::JClass> microphoneClass() {
|
|
961
|
+
static auto cls = facebook::jni::findClassStatic("com/nayanui/engine/EngineMicrophone");
|
|
962
|
+
return cls;
|
|
963
|
+
}
|
|
964
|
+
#endif
|
|
965
|
+
} // namespace
|
|
966
|
+
|
|
967
|
+
double NayanEngineModule::micPermission(jsi::Runtime &) {
|
|
968
|
+
#ifdef __ANDROID__
|
|
969
|
+
try {
|
|
970
|
+
static const auto permission = microphoneClass()->getStaticMethod<jint()>("permission");
|
|
971
|
+
return permission(microphoneClass());
|
|
972
|
+
} catch (...) {
|
|
973
|
+
return 0;
|
|
974
|
+
}
|
|
975
|
+
#else
|
|
976
|
+
return engine_audio_mic_permission();
|
|
977
|
+
#endif
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
jsi::Value NayanEngineModule::micRequestPermission(jsi::Runtime &rt) {
|
|
981
|
+
auto promise = std::make_shared<MicPromise>(rt, jsInvoker_);
|
|
982
|
+
jsi::Value result(rt, promise->get(rt));
|
|
983
|
+
#ifdef __ANDROID__
|
|
984
|
+
// Java answers through nativePermissionResult(token, granted) below, which frees the token.
|
|
985
|
+
auto *token = new std::shared_ptr<MicPromise>(promise);
|
|
986
|
+
try {
|
|
987
|
+
static const auto request = microphoneClass()->getStaticMethod<void(jlong)>("request");
|
|
988
|
+
request(microphoneClass(), static_cast<jlong>(reinterpret_cast<intptr_t>(token)));
|
|
989
|
+
} catch (...) {
|
|
990
|
+
delete token;
|
|
991
|
+
promise->resolve(false);
|
|
992
|
+
}
|
|
993
|
+
#else
|
|
994
|
+
engine_audio_mic_request(micAnswered, new std::shared_ptr<MicPromise>(promise));
|
|
995
|
+
#endif
|
|
996
|
+
return result;
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
bool NayanEngineModule::micStart(jsi::Runtime &, double maxSeconds) {
|
|
1000
|
+
return engine_audio_mic_start(static_cast<float>(maxSeconds)) != 0;
|
|
1001
|
+
}
|
|
1002
|
+
|
|
1003
|
+
void NayanEngineModule::micStop(jsi::Runtime &) {
|
|
1004
|
+
engine_audio_mic_stop();
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
double NayanEngineModule::micState(jsi::Runtime &) {
|
|
1008
|
+
return engine_audio_mic_state();
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
double NayanEngineModule::micLevel(jsi::Runtime &) {
|
|
1012
|
+
return engine_audio_mic_level();
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
double NayanEngineModule::micHeld(jsi::Runtime &) {
|
|
1016
|
+
return engine_audio_mic_held();
|
|
1017
|
+
}
|
|
1018
|
+
|
|
1019
|
+
double NayanEngineModule::micTake(jsi::Runtime &, double seconds, double skipEnd) {
|
|
1020
|
+
return engine_audio_mic_take(static_cast<float>(seconds), static_cast<float>(skipEnd));
|
|
1021
|
+
}
|
|
1022
|
+
|
|
904
1023
|
bool NayanEngineModule::hapticsSupported(jsi::Runtime &) {
|
|
905
1024
|
return engine_haptics_supported() != 0;
|
|
906
1025
|
}
|
|
@@ -915,6 +1034,158 @@ void NayanEngineModule::hapticsPlay(jsi::Runtime &rt, jsi::Array taps, bool thro
|
|
|
915
1034
|
engine_haptics_play(values.data(), static_cast<uint32_t>(n / 3), throttle ? 1 : 0);
|
|
916
1035
|
}
|
|
917
1036
|
|
|
1037
|
+
// Procedural worlds. Handles are the core's own (u32, 0 = none); no JSI object owns them.
|
|
1038
|
+
|
|
1039
|
+
namespace {
|
|
1040
|
+
|
|
1041
|
+
uint32_t handle(double v) {
|
|
1042
|
+
return (v >= 0 && v <= static_cast<double>(UINT32_MAX)) ? static_cast<uint32_t>(v) : 0;
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1045
|
+
const uint8_t *utf8(const std::string &text) {
|
|
1046
|
+
return reinterpret_cast<const uint8_t *>(text.data());
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
/** A core function's f64 output (two calls: size, then copy) as an owned ArrayBuffer. */
|
|
1050
|
+
jsi::Object doubles(jsi::Runtime &rt, const std::function<size_t(double *, size_t)> &read) {
|
|
1051
|
+
const size_t count = read(nullptr, 0);
|
|
1052
|
+
auto out = std::make_shared<OwnedBuffer>(count * sizeof(double));
|
|
1053
|
+
if (count > 0 && read(reinterpret_cast<double *>(out->data()), count) != count) {
|
|
1054
|
+
throw jsi::JSError(rt, "NayanEngine worldgen: output changed while reading");
|
|
1055
|
+
}
|
|
1056
|
+
return jsi::ArrayBuffer(rt, std::move(out));
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
std::string text(const std::function<size_t(uint8_t *, size_t)> &read) {
|
|
1060
|
+
std::string out(read(nullptr, 0), '\0');
|
|
1061
|
+
if (!out.empty()) read(reinterpret_cast<uint8_t *>(out.data()), out.size() + 1);
|
|
1062
|
+
return out;
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
} // namespace
|
|
1066
|
+
|
|
1067
|
+
double NayanEngineModule::worldgenBuild(jsi::Runtime &rt, jsi::String recipe, jsi::String key, bool prepareTerrain) {
|
|
1068
|
+
const auto r = recipe.utf8(rt), k = key.utf8(rt);
|
|
1069
|
+
return engine_worldgen_build(utf8(r), r.size(), utf8(k), k.size(), prepareTerrain ? 1 : 0);
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
jsi::Value NayanEngineModule::worldgenBuildAsync(jsi::Runtime &rt, jsi::String recipe, jsi::String key, bool prepareTerrain) {
|
|
1073
|
+
auto r = std::make_shared<std::string>(recipe.utf8(rt));
|
|
1074
|
+
auto k = std::make_shared<std::string>(key.utf8(rt));
|
|
1075
|
+
return runInBackground(rt, jsInvoker_, [r, k, prepareTerrain]() {
|
|
1076
|
+
return static_cast<double>(engine_worldgen_build(utf8(*r), r->size(), utf8(*k), k->size(), prepareTerrain ? 1 : 0));
|
|
1077
|
+
});
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
jsi::String NayanEngineModule::worldgenError(jsi::Runtime &rt) {
|
|
1081
|
+
return jsi::String::createFromUtf8(rt, text([](uint8_t *out, size_t cap) { return engine_worldgen_error(out, cap); }));
|
|
1082
|
+
}
|
|
1083
|
+
|
|
1084
|
+
bool NayanEngineModule::worldgenKept(jsi::Runtime &rt, jsi::String key) {
|
|
1085
|
+
const auto k = key.utf8(rt);
|
|
1086
|
+
return engine_worldgen_kept(utf8(k), k.size()) != 0;
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1089
|
+
void NayanEngineModule::worldgenFree(jsi::Runtime &, double world) {
|
|
1090
|
+
engine_worldgen_free(handle(world));
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
jsi::String NayanEngineModule::worldgenInfo(jsi::Runtime &rt, double world) {
|
|
1094
|
+
const uint32_t w = handle(world);
|
|
1095
|
+
return jsi::String::createFromUtf8(rt, text([w](uint8_t *out, size_t cap) { return engine_worldgen_info(w, out, cap); }));
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1098
|
+
jsi::Object NayanEngineModule::worldgenLayer(jsi::Runtime &rt, double world, jsi::String name) {
|
|
1099
|
+
const uint32_t w = handle(world);
|
|
1100
|
+
const auto n = name.utf8(rt);
|
|
1101
|
+
return doubles(rt, [w, &n](double *out, size_t cap) { return engine_worldgen_layer(w, utf8(n), n.size(), out, cap); });
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
jsi::Object NayanEngineModule::worldgenReachable(jsi::Runtime &rt, double world) {
|
|
1105
|
+
const uint32_t w = handle(world);
|
|
1106
|
+
return doubles(rt, [w](double *out, size_t cap) { return engine_worldgen_reachable(w, out, cap); });
|
|
1107
|
+
}
|
|
1108
|
+
|
|
1109
|
+
jsi::Object NayanEngineModule::worldgenOverview(jsi::Runtime &rt, double world) {
|
|
1110
|
+
const uint32_t w = handle(world);
|
|
1111
|
+
const size_t count = engine_worldgen_overview(w, nullptr, 0);
|
|
1112
|
+
auto out = std::make_shared<OwnedBuffer>(count);
|
|
1113
|
+
if (count > 0) engine_worldgen_overview(w, out->data(), count);
|
|
1114
|
+
return jsi::ArrayBuffer(rt, std::move(out));
|
|
1115
|
+
}
|
|
1116
|
+
|
|
1117
|
+
bool NayanEngineModule::worldgenPick(jsi::Runtime &, double world, double run) {
|
|
1118
|
+
return engine_worldgen_pick(handle(world), handle(run)) != 0;
|
|
1119
|
+
}
|
|
1120
|
+
|
|
1121
|
+
jsi::Object NayanEngineModule::worldgenTerrain(jsi::Runtime &rt, double world, double material) {
|
|
1122
|
+
return geometryResult(rt, engine_worldgen_terrain(handle(world), handle(material)));
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
jsi::Object NayanEngineModule::worldgenMesh(jsi::Runtime &rt, jsi::String recipe) {
|
|
1126
|
+
const auto r = recipe.utf8(rt);
|
|
1127
|
+
return geometryResult(rt, engine_worldgen_mesh(utf8(r), r.size()));
|
|
1128
|
+
}
|
|
1129
|
+
|
|
1130
|
+
bool NayanEngineModule::worldgenPaint(jsi::Runtime &rt, jsi::Object vertices, jsi::String recipe) {
|
|
1131
|
+
jsi::ArrayBuffer v = fileData(rt, vertices, "worldgenPaint");
|
|
1132
|
+
if (v.size(rt) % (11 * sizeof(float)) != 0) {
|
|
1133
|
+
throw jsi::JSError(rt, "NayanEngine.worldgenPaint: incomplete vertices");
|
|
1134
|
+
}
|
|
1135
|
+
const auto r = recipe.utf8(rt);
|
|
1136
|
+
return engine_worldgen_paint(reinterpret_cast<float *>(v.data(rt)), v.size(rt) / (11 * sizeof(float)), utf8(r), r.size()) != 0;
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1139
|
+
double NayanEngineModule::worldgenGround(jsi::Runtime &, double world, double x, double z) {
|
|
1140
|
+
return engine_worldgen_ground(handle(world), x, z);
|
|
1141
|
+
}
|
|
1142
|
+
|
|
1143
|
+
double NayanEngineModule::worldgenSurface(jsi::Runtime &, double world, double x, double z) {
|
|
1144
|
+
return engine_worldgen_surface(handle(world), x, z);
|
|
1145
|
+
}
|
|
1146
|
+
|
|
1147
|
+
double NayanEngineModule::worldgenPlatform(jsi::Runtime &, double world, double x, double z) {
|
|
1148
|
+
return engine_worldgen_platform(handle(world), x, z);
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
bool NayanEngineModule::worldgenWalkable(jsi::Runtime &, double world, double x, double z, double radius) {
|
|
1152
|
+
return engine_worldgen_walkable(handle(world), x, z, radius) != 0;
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1155
|
+
double NayanEngineModule::worldgenClearance(jsi::Runtime &, double world, double x, double z, double radius) {
|
|
1156
|
+
return engine_worldgen_clearance(handle(world), x, z, radius);
|
|
1157
|
+
}
|
|
1158
|
+
|
|
1159
|
+
double NayanEngineModule::worldgenSolidClearance(jsi::Runtime &, double world, double x, double z, double radius, double bottom, double top) {
|
|
1160
|
+
return engine_worldgen_solid_clearance(handle(world), x, z, radius, bottom, top);
|
|
1161
|
+
}
|
|
1162
|
+
|
|
1163
|
+
double NayanEngineModule::worldgenFieldIndex(jsi::Runtime &rt, double world, jsi::String name) {
|
|
1164
|
+
const auto n = name.utf8(rt);
|
|
1165
|
+
return engine_worldgen_field_index(handle(world), utf8(n), n.size());
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1168
|
+
double NayanEngineModule::worldgenField(jsi::Runtime &, double world, double field, double x, double z) {
|
|
1169
|
+
return engine_worldgen_field(handle(world), handle(field), x, z);
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
jsi::Array NayanEngineModule::worldgenTilt(jsi::Runtime &rt, double world, double x, double z, double yaw) {
|
|
1173
|
+
double q[4] = {0, 0, 0, 1};
|
|
1174
|
+
engine_worldgen_tilt(handle(world), x, z, yaw, q);
|
|
1175
|
+
return jsi::Array::createWithElements(rt, q[0], q[1], q[2], q[3]);
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1178
|
+
bool NayanEngineModule::worldgenSight(jsi::Runtime &, double world, double ax, double az, double bx, double bz, double radius, double step, double rise) {
|
|
1179
|
+
return engine_worldgen_sight(handle(world), ax, az, bx, bz, radius, step, rise) != 0;
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
jsi::Array NayanEngineModule::worldgenMove(jsi::Runtime &rt, double world, double x, double z, double dx, double dz, double radius, jsi::Object bodies) {
|
|
1183
|
+
auto list = fileData(rt, bodies, "worldgenMove");
|
|
1184
|
+
double point[2] = {x, z};
|
|
1185
|
+
engine_worldgen_move(handle(world), point, dx, dz, radius, reinterpret_cast<const double *>(list.data(rt)), list.size(rt) / (3 * sizeof(double)));
|
|
1186
|
+
return jsi::Array::createWithElements(rt, point[0], point[1]);
|
|
1187
|
+
}
|
|
1188
|
+
|
|
918
1189
|
} // namespace facebook::react
|
|
919
1190
|
|
|
920
1191
|
#ifdef __ANDROID__
|
|
@@ -963,6 +1234,13 @@ Java_com_nayanui_engine_EngineSurfaceView_nativeAttach(JNIEnv *env, jclass, jint
|
|
|
963
1234
|
return engine_render_attach(surface, window, static_cast<uint32_t>(width), static_cast<uint32_t>(height)) == 1 ? JNI_TRUE : JNI_FALSE;
|
|
964
1235
|
}
|
|
965
1236
|
|
|
1237
|
+
/** EngineMicrophone's answer to micRequestPermission: resolves the promise and frees its token. */
|
|
1238
|
+
extern "C" JNIEXPORT void JNICALL Java_com_nayanui_engine_EngineMicrophone_nativePermissionResult(JNIEnv *, jclass, jlong token, jboolean granted) {
|
|
1239
|
+
std::unique_ptr<std::shared_ptr<facebook::react::AsyncPromise<bool>>> promise(
|
|
1240
|
+
reinterpret_cast<std::shared_ptr<facebook::react::AsyncPromise<bool>> *>(static_cast<intptr_t>(token)));
|
|
1241
|
+
if (promise) (*promise)->resolve(granted == JNI_TRUE);
|
|
1242
|
+
}
|
|
1243
|
+
|
|
966
1244
|
extern "C" JNIEXPORT void JNICALL Java_com_nayanui_engine_EngineSurfaceView_nativeDetach(JNIEnv *, jclass, jint surface) {
|
|
967
1245
|
releaseWindow(surface);
|
|
968
1246
|
}
|
|
@@ -996,3 +1274,21 @@ extern "C" JNIEXPORT jbyteArray JNICALL Java_com_nayanui_engine_EngineSurfaceVie
|
|
|
996
1274
|
return result;
|
|
997
1275
|
}
|
|
998
1276
|
#endif
|
|
1277
|
+
|
|
1278
|
+
namespace {
|
|
1279
|
+
void speechAnswered(void *context, const uint8_t *data, size_t len) {
|
|
1280
|
+
using Promise = facebook::react::AsyncPromise<std::string>;
|
|
1281
|
+
std::unique_ptr<std::shared_ptr<Promise>> promise(static_cast<std::shared_ptr<Promise> *>(context));
|
|
1282
|
+
(*promise)->resolve(std::string(reinterpret_cast<const char *>(data), len));
|
|
1283
|
+
}
|
|
1284
|
+
}
|
|
1285
|
+
namespace facebook::react {
|
|
1286
|
+
jsi::Value NayanEngineModule::speechRequest(jsi::Runtime &rt, jsi::String command) {
|
|
1287
|
+
auto promise = std::make_shared<AsyncPromise<std::string>>(rt, jsInvoker_);
|
|
1288
|
+
jsi::Value result(rt, promise->get(rt));
|
|
1289
|
+
const std::string text = command.utf8(rt);
|
|
1290
|
+
engine_speech_request(reinterpret_cast<const uint8_t *>(text.data()), text.size(), speechAnswered,
|
|
1291
|
+
new std::shared_ptr<AsyncPromise<std::string>>(promise));
|
|
1292
|
+
return result;
|
|
1293
|
+
}
|
|
1294
|
+
}
|
|
@@ -15,6 +15,8 @@ class NayanEngineModule : public NativeNayanEngineCxxSpec<NayanEngineModule> {
|
|
|
15
15
|
explicit NayanEngineModule(std::shared_ptr<CallInvoker> jsInvoker);
|
|
16
16
|
~NayanEngineModule();
|
|
17
17
|
|
|
18
|
+
jsi::Value speechRequest(jsi::Runtime &rt, jsi::String command);
|
|
19
|
+
|
|
18
20
|
double createWorld(jsi::Runtime &rt, double capacity);
|
|
19
21
|
void destroyWorld(jsi::Runtime &rt, double world);
|
|
20
22
|
double spawnDesc(jsi::Runtime &rt, double world, jsi::Object desc);
|
|
@@ -67,6 +69,8 @@ class NayanEngineModule : public NativeNayanEngineCxxSpec<NayanEngineModule> {
|
|
|
67
69
|
jsi::Object modelVertices(jsi::Runtime &rt, double mesh);
|
|
68
70
|
jsi::Object modelIndices(jsi::Runtime &rt, double mesh);
|
|
69
71
|
jsi::Array modelSize(jsi::Runtime &rt, double mesh);
|
|
72
|
+
jsi::Array modelBake(jsi::Runtime &rt, double mesh, jsi::String spec);
|
|
73
|
+
bool bakeKept(jsi::Runtime &rt, jsi::String key);
|
|
70
74
|
double modelTexture(jsi::Runtime &rt, double mesh);
|
|
71
75
|
double meshAlias(jsi::Runtime &rt, double base);
|
|
72
76
|
double meshCreate(jsi::Runtime &rt, jsi::Object vertices, jsi::Object indices);
|
|
@@ -137,6 +141,7 @@ class NayanEngineModule : public NativeNayanEngineCxxSpec<NayanEngineModule> {
|
|
|
137
141
|
double count,
|
|
138
142
|
double width,
|
|
139
143
|
double height);
|
|
144
|
+
void renderBackdrop(jsi::Runtime &rt, double surface, jsi::Object matrices, jsi::Object colors, jsi::Object regions, jsi::Object ranges, double count);
|
|
140
145
|
jsi::String renderError(jsi::Runtime &rt);
|
|
141
146
|
jsi::String renderBackend(jsi::Runtime &rt);
|
|
142
147
|
double drawingCreate(jsi::Runtime &rt, double width, double height, double ratio);
|
|
@@ -149,8 +154,43 @@ class NayanEngineModule : public NativeNayanEngineCxxSpec<NayanEngineModule> {
|
|
|
149
154
|
void audioSetVolume(jsi::Runtime &rt, double volume);
|
|
150
155
|
void audioSetMuted(jsi::Runtime &rt, bool muted);
|
|
151
156
|
bool audioIsRunning(jsi::Runtime &rt);
|
|
157
|
+
void audioRelease(jsi::Runtime &rt, double sound);
|
|
158
|
+
double audioDuration(jsi::Runtime &rt, double sound);
|
|
159
|
+
jsi::Object audioLevels(jsi::Runtime &rt, double sound, double perSecond);
|
|
160
|
+
double micPermission(jsi::Runtime &rt);
|
|
161
|
+
jsi::Value micRequestPermission(jsi::Runtime &rt);
|
|
162
|
+
bool micStart(jsi::Runtime &rt, double maxSeconds);
|
|
163
|
+
void micStop(jsi::Runtime &rt);
|
|
164
|
+
double micState(jsi::Runtime &rt);
|
|
165
|
+
double micLevel(jsi::Runtime &rt);
|
|
166
|
+
double micHeld(jsi::Runtime &rt);
|
|
167
|
+
double micTake(jsi::Runtime &rt, double seconds, double skipEnd);
|
|
152
168
|
bool hapticsSupported(jsi::Runtime &rt);
|
|
153
169
|
void hapticsPlay(jsi::Runtime &rt, jsi::Array taps, bool throttle);
|
|
170
|
+
double worldgenBuild(jsi::Runtime &rt, jsi::String recipe, jsi::String key, bool prepareTerrain);
|
|
171
|
+
jsi::Value worldgenBuildAsync(jsi::Runtime &rt, jsi::String recipe, jsi::String key, bool prepareTerrain);
|
|
172
|
+
jsi::String worldgenError(jsi::Runtime &rt);
|
|
173
|
+
bool worldgenKept(jsi::Runtime &rt, jsi::String key);
|
|
174
|
+
void worldgenFree(jsi::Runtime &rt, double world);
|
|
175
|
+
jsi::String worldgenInfo(jsi::Runtime &rt, double world);
|
|
176
|
+
jsi::Object worldgenLayer(jsi::Runtime &rt, double world, jsi::String name);
|
|
177
|
+
jsi::Object worldgenReachable(jsi::Runtime &rt, double world);
|
|
178
|
+
jsi::Object worldgenOverview(jsi::Runtime &rt, double world);
|
|
179
|
+
bool worldgenPick(jsi::Runtime &rt, double world, double run);
|
|
180
|
+
jsi::Object worldgenTerrain(jsi::Runtime &rt, double world, double material);
|
|
181
|
+
jsi::Object worldgenMesh(jsi::Runtime &rt, jsi::String recipe);
|
|
182
|
+
bool worldgenPaint(jsi::Runtime &rt, jsi::Object vertices, jsi::String recipe);
|
|
183
|
+
double worldgenGround(jsi::Runtime &rt, double world, double x, double z);
|
|
184
|
+
double worldgenSurface(jsi::Runtime &rt, double world, double x, double z);
|
|
185
|
+
double worldgenPlatform(jsi::Runtime &rt, double world, double x, double z);
|
|
186
|
+
bool worldgenWalkable(jsi::Runtime &rt, double world, double x, double z, double radius);
|
|
187
|
+
double worldgenClearance(jsi::Runtime &rt, double world, double x, double z, double radius);
|
|
188
|
+
double worldgenSolidClearance(jsi::Runtime &rt, double world, double x, double z, double radius, double bottom, double top);
|
|
189
|
+
double worldgenFieldIndex(jsi::Runtime &rt, double world, jsi::String name);
|
|
190
|
+
double worldgenField(jsi::Runtime &rt, double world, double field, double x, double z);
|
|
191
|
+
jsi::Array worldgenTilt(jsi::Runtime &rt, double world, double x, double z, double yaw);
|
|
192
|
+
bool worldgenSight(jsi::Runtime &rt, double world, double ax, double az, double bx, double bz, double radius, double step, double rise);
|
|
193
|
+
jsi::Array worldgenMove(jsi::Runtime &rt, double world, double x, double z, double dx, double dz, double radius, jsi::Object bodies);
|
|
154
194
|
|
|
155
195
|
private:
|
|
156
196
|
std::shared_ptr<::World> owner(double id) const;
|