mirror of
https://git.mirrors.martin98.com/https://github.com/syoyo/tinygltf.git
synced 2025-08-14 19:05:59 +08:00
Added parsing and serializing of audio emitters for scene (global sources)
This commit is contained in:
parent
c9657be1de
commit
879cb473a3
133
tiny_gltf.h
133
tiny_gltf.h
@ -1105,6 +1105,7 @@ struct Asset {
|
|||||||
struct Scene {
|
struct Scene {
|
||||||
std::string name;
|
std::string name;
|
||||||
std::vector<int> nodes;
|
std::vector<int> nodes;
|
||||||
|
std::vector<int> audioEmitters; // KHR_audio global emitters
|
||||||
|
|
||||||
ExtensionMap extensions;
|
ExtensionMap extensions;
|
||||||
Value extras;
|
Value extras;
|
||||||
@ -1176,34 +1177,58 @@ struct PositionalEmitter {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct AudioEmitter {
|
struct AudioEmitter {
|
||||||
std::string name;
|
std::string name;
|
||||||
double gain{1.0};
|
double gain{1.0};
|
||||||
bool loop{false};
|
bool loop{false};
|
||||||
bool playing{false};
|
bool playing{false};
|
||||||
std::string type; // global/positional
|
std::string
|
||||||
std::string distanceModel;
|
type; // positional - Positional audio emitters. Using sound cones, the
|
||||||
PositionalEmitter positional;
|
// orientation is +Z having the same front side for a glTF asset.
|
||||||
int source{-1};
|
// global - Global audio emitters are not affected by the position
|
||||||
|
// of audio listeners. coneInnerAngle, coneOuterAngle,
|
||||||
|
// coneOuterGain, distanceModel, maxDistance, refDistance, and
|
||||||
|
// rolloffFactor should all be ignored when set.
|
||||||
|
std::string
|
||||||
|
distanceModel; // linear - A linear distance model calculating the
|
||||||
|
// gain induced by the distance according to: 1.0
|
||||||
|
// - rolloffFactor * (distance - refDistance) /
|
||||||
|
// (maxDistance - refDistance)
|
||||||
|
// inverse - (default) An inverse distance model
|
||||||
|
// calculating the gain induced by the distance according
|
||||||
|
// to: refDistance / (refDistance + rolloffFactor *
|
||||||
|
// (Math.max(distance, refDistance) - refDistance))
|
||||||
|
// exponential - An exponential distance model calculating
|
||||||
|
// the gain induced by the distance according to:
|
||||||
|
// pow((Math.max(distance, refDistance) / refDistance,
|
||||||
|
// -rolloffFactor))
|
||||||
|
PositionalEmitter positional;
|
||||||
|
int source{-1};
|
||||||
|
|
||||||
AudioEmitter() : gain(1.0), loop(false), playing(false), type("global"), distanceModel("linear") {}
|
AudioEmitter()
|
||||||
DEFAULT_METHODS(AudioEmitter)
|
: gain(1.0),
|
||||||
|
loop(false),
|
||||||
|
playing(false),
|
||||||
|
type("global"),
|
||||||
|
distanceModel("inverse") {}
|
||||||
|
DEFAULT_METHODS(AudioEmitter)
|
||||||
|
|
||||||
bool operator==(const AudioEmitter &) const;
|
bool operator==(const AudioEmitter &) const;
|
||||||
|
|
||||||
ExtensionMap extensions;
|
ExtensionMap extensions;
|
||||||
Value extras;
|
Value extras;
|
||||||
|
|
||||||
// Filled when SetStoreOriginalJSONForExtrasAndExtensions is enabled.
|
// Filled when SetStoreOriginalJSONForExtrasAndExtensions is enabled.
|
||||||
std::string extras_json_string;
|
std::string extras_json_string;
|
||||||
std::string extensions_json_string;
|
std::string extensions_json_string;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AudioSource {
|
struct AudioSource {
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string uri;
|
std::string uri;
|
||||||
int bufferView{-1}; // (required if no uri)
|
int bufferView{-1}; // (required if no uri)
|
||||||
std::string mimeType; // (required if no uri) ["audio/mp3", "audio/ogg",
|
std::string mimeType; // (required if no uri) The audio's MIME type. Required if
|
||||||
// "audio/wav", "audio/m4a"]
|
// bufferView is defined. Unless specified by another
|
||||||
|
// extension, the only supported mimeType is audio/mpeg.
|
||||||
|
|
||||||
AudioSource() {}
|
AudioSource() {}
|
||||||
DEFAULT_METHODS(AudioSource)
|
DEFAULT_METHODS(AudioSource)
|
||||||
@ -5077,6 +5102,35 @@ static bool ParseNode(Node *node, std::string *err, const detail::json &o,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool ParseScene(Scene *scene, std::string *err, const detail::json &o,
|
||||||
|
bool store_original_json_for_extras_and_extensions) {
|
||||||
|
ParseStringProperty(&scene->name, err, o, "name", false);
|
||||||
|
ParseIntegerArrayProperty(&scene->nodes, err, o, "nodes", false);
|
||||||
|
|
||||||
|
ParseExtrasAndExtensions(scene, err, o,
|
||||||
|
store_original_json_for_extras_and_extensions);
|
||||||
|
|
||||||
|
// Parse KHR_audio global emitters
|
||||||
|
if (scene->extensions.count("KHR_audio") != 0) {
|
||||||
|
auto const &audio_ext = scene->extensions["KHR_audio"];
|
||||||
|
if (audio_ext.Has("emitters")) {
|
||||||
|
auto emittersArr = audio_ext.Get("emitters");
|
||||||
|
for (size_t i = 0; i < emittersArr.ArrayLen(); ++i) {
|
||||||
|
scene->audioEmitters.emplace_back(emittersArr.Get(i).GetNumberAsInt());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (err) {
|
||||||
|
*err +=
|
||||||
|
"Node has extension KHR_audio, but does not reference "
|
||||||
|
"a audio emitter.\n";
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool ParsePbrMetallicRoughness(
|
static bool ParsePbrMetallicRoughness(
|
||||||
PbrMetallicRoughness *pbr, std::string *err, const detail::json &o,
|
PbrMetallicRoughness *pbr, std::string *err, const detail::json &o,
|
||||||
bool store_original_json_for_extras_and_extensions) {
|
bool store_original_json_for_extras_and_extensions) {
|
||||||
@ -6057,15 +6111,13 @@ bool TinyGLTF::LoadFromString(Model *model, std::string *err, std::string *warn,
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
std::vector<int> nodes;
|
|
||||||
ParseIntegerArrayProperty(&nodes, err, o, "nodes", false);
|
|
||||||
|
|
||||||
Scene scene;
|
Scene scene;
|
||||||
scene.nodes = std::move(nodes);
|
if (!ParseScene(&scene, err, o,
|
||||||
|
store_original_json_for_extras_and_extensions_)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
ParseStringProperty(&scene.name, err, o, "name", false);
|
|
||||||
|
|
||||||
ParseExtrasAndExtensions(&scene, err, o, store_original_json_for_extras_and_extensions_);
|
|
||||||
model->scenes.emplace_back(std::move(scene));
|
model->scenes.emplace_back(std::move(scene));
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
@ -7681,6 +7733,37 @@ static void SerializeGltfScene(const Scene &scene, detail::json &o) {
|
|||||||
SerializeStringProperty("name", scene.name, o);
|
SerializeStringProperty("name", scene.name, o);
|
||||||
}
|
}
|
||||||
SerializeExtrasAndExtensions(scene, o);
|
SerializeExtrasAndExtensions(scene, o);
|
||||||
|
|
||||||
|
// KHR_audio
|
||||||
|
if (!scene.audioEmitters.empty()) {
|
||||||
|
detail::json_iterator it;
|
||||||
|
if (!detail::FindMember(o, "extensions", it)) {
|
||||||
|
detail::json extensions;
|
||||||
|
detail::JsonSetObject(extensions);
|
||||||
|
detail::JsonAddMember(o, "extensions", std::move(extensions));
|
||||||
|
detail::FindMember(o, "extensions", it);
|
||||||
|
}
|
||||||
|
auto &extensions = detail::GetValue(it);
|
||||||
|
if (!detail::FindMember(extensions, "KHR_audio", it)) {
|
||||||
|
detail::json audio;
|
||||||
|
detail::JsonSetObject(audio);
|
||||||
|
detail::JsonAddMember(extensions, "KHR_audio", std::move(audio));
|
||||||
|
detail::FindMember(o, "KHR_audio", it);
|
||||||
|
}
|
||||||
|
SerializeNumberArrayProperty("emitters", scene.audioEmitters, detail::GetValue(it));
|
||||||
|
} else {
|
||||||
|
detail::json_iterator ext_it;
|
||||||
|
if (detail::FindMember(o, "extensions", ext_it)) {
|
||||||
|
auto &extensions = detail::GetValue(ext_it);
|
||||||
|
detail::json_iterator lp_it;
|
||||||
|
if (detail::FindMember(extensions, "KHR_audio", lp_it)) {
|
||||||
|
detail::Erase(extensions, lp_it);
|
||||||
|
}
|
||||||
|
if (detail::IsEmpty(extensions)) {
|
||||||
|
detail::Erase(o, ext_it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SerializeGltfSkin(const Skin &skin, detail::json &o) {
|
static void SerializeGltfSkin(const Skin &skin, detail::json &o) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user