Complete internal submodule smoke closure
This commit is contained in:
@@ -128,6 +128,7 @@ target_link_options(web_engine PRIVATE
|
||||
"-sUSE_FREETYPE=1"
|
||||
"-sENVIRONMENT=web,node,worker"
|
||||
"-sALLOW_MEMORY_GROWTH=1"
|
||||
"-sNO_DISABLE_EXCEPTION_CATCHING=1"
|
||||
"-sINITIAL_MEMORY=67108864"
|
||||
"-sMAXIMUM_MEMORY=2147483648"
|
||||
"-sSTACK_SIZE=8388608"
|
||||
|
||||
@@ -1744,6 +1744,9 @@ EMSCRIPTEN_KEEPALIVE int web_engine_apply_command(const int handle,
|
||||
type == "assignMaterialFaces" || type == "setMaterialPrincipled" ||
|
||||
type == "importImage" || type == "setMaterialImageNode" || type == "setShaderGraph" ||
|
||||
type == "setGeometryNodeGraph" || type == "setPhysicsSimulation" ||
|
||||
type == "setRigidBodySettings" || type == "setClothSettings" ||
|
||||
type == "setFluidSettings" || type == "setParticleCache" ||
|
||||
type == "setSimulationPlayback" ||
|
||||
type == "insertObjectKeyframe" || type == "deleteObjectKeyframe" ||
|
||||
type == "createAction" || type == "removeAction" || type == "setKeyframe" || type == "setFCurveKeyframes" ||
|
||||
type == "setDriverExpression" || type == "setActionGroups" || type == "setKeyingSet" || type == "bakeAnimation" || type == "setTimelineMarkers" ||
|
||||
@@ -1764,7 +1767,8 @@ EMSCRIPTEN_KEEPALIVE int web_engine_apply_command(const int handle,
|
||||
type == "setGreasePencilStrokes" || type == "setGreasePencilDrawing" ||
|
||||
type == "setGreasePencilMaterial" || type == "setGreasePencilSelection" ||
|
||||
type == "setGreasePencilInterpolate" || type == "setVertexColors" ||
|
||||
type == "setVertexWeights" || type == "setCameraProperties" || type == "setLightProperties" ||
|
||||
type == "setVertexWeights" || type == "setCameraProperties" || type == "setCameraView" ||
|
||||
type == "setLightProperties" || type == "setRenderPasses" ||
|
||||
type == "setWorldProperties" || type == "renderFrame" || type == "renderAnimation" || type == "setSceneProperties" || type == "setSceneRenderSettings" || type == "setSceneAudioSettings" || type == "setSceneUnitSettings" || type == "setSceneTimelineSettings" || type == "setScenePipelineSettings" || type == "setSceneBindings" || type == "setSceneViewLayerSettings" || type == "setSceneCollectionSettings" || type == "setSceneBorderSettings" || type == "setSceneSimplifySettings" || type == "setSceneColorManagement" || type == "setSceneImageFormat" || type == "setSceneMotionBlur" || type == "setSceneHairSettings" || type == "setSceneCompositorSettings" || type == "setScenePerformanceSettings" || type == "setSceneSamplingSettings" || type == "setSceneMultiviewSettings" || type == "setSceneStampSettings" || type == "setSceneLineSettings" || type == "setSceneViewLayerPassSettings" || type == "setSceneViewLayerAOVs" || type == "setSceneViewLayerLightgroups" || type == "setTrackingMarkers" || type == "setTrackingSolve" || type == "setMaskSpline" || type == "setMaskPoint" || type == "clearObjectTransform" || type == "createObjectData" || type == "setObjectSelection" || type == "setCollectionVisibility" || type == "setObjectLightgroup" || type == "setWorldLightgroup" || type == "setLightLinking" ||
|
||||
type == "setSculptMeshAttributes" ||
|
||||
type == "sculptStroke") {
|
||||
@@ -1885,6 +1889,23 @@ EMSCRIPTEN_KEEPALIVE int web_engine_apply_command(const int handle,
|
||||
applied = web_engine_blend_main_set_physics_simulation(
|
||||
engine->authoritative_main, manifest.dump().c_str(), main_error);
|
||||
}
|
||||
else if (type == "setRigidBodySettings" || type == "setClothSettings" ||
|
||||
type == "setFluidSettings" || type == "setParticleCache")
|
||||
{
|
||||
const std::string family = type == "setRigidBodySettings" ?
|
||||
command.value("family", "RIGID_BODY") :
|
||||
type == "setClothSettings" ? "CLOTH" :
|
||||
type == "setFluidSettings" ? "FLUID" : "PARTICLE";
|
||||
const json settings = command.value("settings", json::object());
|
||||
applied = web_engine_blend_main_patch_physics_settings(
|
||||
engine->authoritative_main, command.value("objectId", "").c_str(), family.c_str(),
|
||||
settings.dump().c_str(), main_error);
|
||||
}
|
||||
else if (type == "setSimulationPlayback") {
|
||||
const json settings = command.value("settings", json::object());
|
||||
applied = web_engine_blend_main_set_simulation_playback(
|
||||
engine->authoritative_main, settings.dump().c_str(), main_error);
|
||||
}
|
||||
else if (type == "setShaderGraph") {
|
||||
const json graph = command.value("graph", json::object());
|
||||
const std::string material_id = command.value("materialId", "");
|
||||
|
||||
@@ -5832,6 +5832,11 @@ std::string web_engine_sha256_hex(const std::string &value)
|
||||
return sha256_hex(value);
|
||||
}
|
||||
|
||||
std::string web_engine_modifier_type_name(const int64_t type)
|
||||
{
|
||||
return modifier_type_name(type);
|
||||
}
|
||||
|
||||
WebBlendReadResult web_engine_read_blend_scene_ir(const uint8_t *data,
|
||||
const uint32_t length,
|
||||
const uint64_t revision)
|
||||
|
||||
@@ -18,3 +18,4 @@ WebBlendReadResult web_engine_read_blend_scene_ir(const uint8_t *data,
|
||||
uint64_t revision);
|
||||
|
||||
std::string web_engine_sha256_hex(const std::string &value);
|
||||
std::string web_engine_modifier_type_name(int64_t type);
|
||||
|
||||
@@ -138,6 +138,7 @@ template<typename T> struct WebListWrapper {
|
||||
#include "SEQ_add.hh"
|
||||
#include "SEQ_edit.hh"
|
||||
#include "SEQ_relations.hh"
|
||||
|
||||
#include "SEQ_sequencer.hh"
|
||||
#include "SEQ_utils.hh"
|
||||
|
||||
@@ -662,6 +663,7 @@ constexpr char WEB_ENGINE_GEOMETRY_OVERRIDE_PROPERTY[] = "web_geometry_node_grap
|
||||
constexpr char WEB_ENGINE_GEOMETRY_GRAPH_PROPERTY[] = "web_geometry_node_graph";
|
||||
constexpr char WEB_ENGINE_PHYSICS_OVERRIDE_TEXT[] = "WBV2 Physics Simulation Override";
|
||||
constexpr char WEB_ENGINE_PHYSICS_OVERRIDE_PROPERTY[] = "web_physics_simulation_override";
|
||||
constexpr char WEB_ENGINE_PHYSICS_PLAYBACK_PROPERTY[] = "web_physics_simulation_playback";
|
||||
constexpr char WEB_ENGINE_MEDIA_RETENTION_TEXT[] = "WBV2 Media Datablock Retention";
|
||||
|
||||
std::string text_contents(Text &text)
|
||||
@@ -1869,7 +1871,9 @@ bool web_engine_blend_main_add_modifier(WebBlendMainState *state,
|
||||
ModifierType type = eModifierType_None;
|
||||
for (int candidate = eModifierType_None + 1; candidate < NUM_MODIFIER_TYPES; candidate++) {
|
||||
const ModifierTypeInfo *info = BKE_modifier_get_info(ModifierType(candidate));
|
||||
if (info != nullptr && STREQ(info->idname, modifier_type)) {
|
||||
if (info != nullptr && (STREQ(info->idname, modifier_type) ||
|
||||
web_engine_modifier_type_name(candidate) == modifier_type))
|
||||
{
|
||||
type = ModifierType(candidate);
|
||||
break;
|
||||
}
|
||||
@@ -7710,6 +7714,126 @@ bool web_engine_blend_main_set_physics_simulation(WebBlendMainState *state,
|
||||
}
|
||||
}
|
||||
|
||||
bool web_engine_blend_main_patch_physics_settings(WebBlendMainState *state,
|
||||
const char *owner_object_id,
|
||||
const char *family,
|
||||
const char *settings_json,
|
||||
std::string &error)
|
||||
{
|
||||
if (state == nullptr || state->main == nullptr || owner_object_id == nullptr || family == nullptr ||
|
||||
settings_json == nullptr)
|
||||
{
|
||||
error = "PHYSICS_MANIFEST_INVALID: physics settings require an open Main, owner, family and settings";
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
Object *owner = find_object(state->main, owner_object_id);
|
||||
const std::string family_name(family);
|
||||
const std::array<const char *, 7> families = {
|
||||
"RIGID_BODY", "SOFT_BODY", "CLOTH", "FLUID", "DYNAMIC_PAINT", "PARTICLE", "HAIR"};
|
||||
const json patch = json::parse(settings_json);
|
||||
if (owner == nullptr || std::find(families.begin(), families.end(), family_name) == families.end() ||
|
||||
!patch.is_object() || patch.empty() || patch.size() > 256 || patch.dump().size() > 64 * 1024)
|
||||
{
|
||||
error = "PHYSICS_MANIFEST_INVALID: physics owner, family or settings are invalid";
|
||||
return false;
|
||||
}
|
||||
for (const auto &[key, value] : patch.items()) {
|
||||
if (key.empty() || key.size() > 128 ||
|
||||
!(value.is_null() || value.is_boolean() || value.is_string() ||
|
||||
(value.is_number() && std::isfinite(value.get<double>()))))
|
||||
{
|
||||
error = "PHYSICS_MANIFEST_INVALID: physics settings must contain bounded scalar values";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::string manifest_json;
|
||||
if (!web_engine_blend_main_physics_simulation_json(state, manifest_json, error)) return false;
|
||||
json manifest = json::parse(manifest_json);
|
||||
json *target = nullptr;
|
||||
for (json &system : manifest["systems"]) {
|
||||
const std::string system_family = system.value("family", "");
|
||||
const bool family_matches = system_family == family_name ||
|
||||
(family_name == "PARTICLE" && system_family == "HAIR");
|
||||
if (family_matches && system.value("ownerObjectId", "") == owner_object_id) {
|
||||
target = &system;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (target == nullptr) {
|
||||
std::string slug = family_name;
|
||||
std::transform(slug.begin(), slug.end(), slug.begin(), [](const unsigned char character) {
|
||||
return character == '_' ? '-' : char(std::tolower(character));
|
||||
});
|
||||
manifest["systems"].push_back({{"id", "physics:" + slug + ":" + id_name(owner->id)},
|
||||
{"family", family_name},
|
||||
{"ownerObjectId", owner_object_id},
|
||||
{"settingsHash", std::string(64, '0')},
|
||||
{"settings", json::object()},
|
||||
{"dependencyIds", json::array()}});
|
||||
target = &manifest["systems"].back();
|
||||
}
|
||||
json &settings = (*target)["settings"];
|
||||
for (const auto &[key, value] : patch.items()) settings[key] = value;
|
||||
(*target)["settingsHash"] = web_engine_sha256_hex(settings.dump());
|
||||
target->erase("cache");
|
||||
return web_engine_blend_main_set_physics_simulation(state, manifest.dump().c_str(), error);
|
||||
}
|
||||
catch (const std::exception &exception) {
|
||||
error = std::string("PHYSICS_MANIFEST_INVALID: physics settings JSON is invalid: ") + exception.what();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool web_engine_blend_main_set_simulation_playback(WebBlendMainState *state,
|
||||
const char *settings_json,
|
||||
std::string &error)
|
||||
{
|
||||
if (state == nullptr || state->scene == nullptr || settings_json == nullptr) {
|
||||
error = "PHYSICS_PLAYBACK_INVALID: simulation playback requires an open Main and settings";
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
const json settings = json::parse(settings_json);
|
||||
if (!settings.is_object() || settings.empty()) {
|
||||
error = "PHYSICS_PLAYBACK_INVALID: simulation playback settings are empty";
|
||||
return false;
|
||||
}
|
||||
const std::array<const char *, 4> allowed = {"frame", "playing", "direction", "reset"};
|
||||
for (const auto &[key, value] : settings.items()) {
|
||||
if (std::find(allowed.begin(), allowed.end(), key) == allowed.end()) {
|
||||
error = "PHYSICS_PLAYBACK_INVALID: simulation playback contains an unsupported setting";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if ((settings.contains("frame") && (!settings["frame"].is_number_integer() ||
|
||||
settings["frame"].get<int64_t>() < -1000000 ||
|
||||
settings["frame"].get<int64_t>() > 1000000)) ||
|
||||
(settings.contains("playing") && !settings["playing"].is_boolean()) ||
|
||||
(settings.contains("reset") && !settings["reset"].is_boolean()) ||
|
||||
(settings.contains("direction") && (!settings["direction"].is_number_integer() ||
|
||||
std::abs(settings["direction"].get<int>()) != 1)))
|
||||
{
|
||||
error = "PHYSICS_PLAYBACK_INVALID: simulation playback settings are outside the bounded range";
|
||||
return false;
|
||||
}
|
||||
const bool reset = settings.value("reset", false);
|
||||
const int frame = reset ? state->scene->r.sfra : settings.value("frame", state->scene->r.cfra);
|
||||
if (!web_engine_blend_main_set_frame(state, frame, error)) return false;
|
||||
if (!write_id_string(state->scene->id, WEB_ENGINE_PHYSICS_PLAYBACK_PROPERTY, settings.dump())) {
|
||||
error = "PHYSICS_PLAYBACK_INVALID: simulation playback metadata could not be persisted";
|
||||
return false;
|
||||
}
|
||||
state->scene->id.recalc |= ID_RECALC_PARAMETERS;
|
||||
return true;
|
||||
}
|
||||
catch (const std::exception &exception) {
|
||||
error = std::string("PHYSICS_PLAYBACK_INVALID: simulation playback JSON is invalid: ") + exception.what();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool web_engine_blend_main_particle_settings_json(WebBlendMainState *state,
|
||||
std::string &particle_settings_json,
|
||||
std::string &error)
|
||||
|
||||
@@ -636,6 +636,14 @@ bool web_engine_blend_main_physics_simulation_json(WebBlendMainState *state,
|
||||
bool web_engine_blend_main_set_physics_simulation(WebBlendMainState *state,
|
||||
const char *manifest_json,
|
||||
std::string &error);
|
||||
bool web_engine_blend_main_patch_physics_settings(WebBlendMainState *state,
|
||||
const char *owner_object_id,
|
||||
const char *family,
|
||||
const char *settings_json,
|
||||
std::string &error);
|
||||
bool web_engine_blend_main_set_simulation_playback(WebBlendMainState *state,
|
||||
const char *settings_json,
|
||||
std::string &error);
|
||||
bool web_engine_blend_main_particle_settings_json(WebBlendMainState *state,
|
||||
std::string &particle_settings_json,
|
||||
std::string &error);
|
||||
|
||||
Reference in New Issue
Block a user