diff --git a/tiny_gltf.h b/tiny_gltf.h index 4a5e2d8..32ecf8d 100644 --- a/tiny_gltf.h +++ b/tiny_gltf.h @@ -813,12 +813,32 @@ struct Scene { bool operator==(const Scene &) const; }; +struct SpotLight { + double innerConeAngle; + double outerConeAngle; + + SpotLight() : innerConeAngle(0.0), outerConeAngle(0.0) { } + + bool operator==(const SpotLight &) const; + + ExtensionMap extensions; + Value extras; +}; + struct Light { std::string name; std::vector color; + double intensity; std::string type; + double range; + SpotLight spot; + + Light() : intensity(0.0), range(0.0) {} bool operator==(const Light &) const; + + ExtensionMap extensions; + Value extras; }; class Model { @@ -1364,6 +1384,11 @@ bool Node::operator==(const Node &other) const { Equals(this->translation, other.translation) && Equals(this->weights, other.weights); } +bool SpotLight::operator==(const SpotLight &other) const { + return this->extensions == other.extensions && this->extras == other.extras && + TINYGLTF_DOUBLE_EQUAL(this->innerConeAngle, other.innerConeAngle) && + TINYGLTF_DOUBLE_EQUAL(this->outerConeAngle, other.outerConeAngle); +} bool OrthographicCamera::operator==(const OrthographicCamera &other) const { return this->extensions == other.extensions && this->extras == other.extras && TINYGLTF_DOUBLE_EQUAL(this->xmag, other.xmag) && @@ -3424,13 +3449,6 @@ static bool ParseMesh(Mesh *mesh, Model *model, std::string *err, return true; } -static bool ParseLight(Light *light, std::string *err, const json &o) { - ParseStringProperty(&light->name, err, o, "name", false); - ParseNumberArrayProperty(&light->color, err, o, "color", false); - ParseStringProperty(&light->type, err, o, "type", false); - return true; -} - static bool ParseNode(Node *node, std::string *err, const json &o) { ParseStringProperty(&node->name, err, o, "name", false); @@ -3679,6 +3697,29 @@ static bool ParsePerspectiveCamera(PerspectiveCamera *camera, std::string *err, return true; } +static bool ParseSpotLight(SpotLight *light, + std::string *err, const json &o) { + double innerConeAngle = 0.0; + if (!ParseNumberProperty(&innerConeAngle, err, o, "innerConeAngle", true, "SpotLight")) { + return false; + } + + double outerConeAngle = 0.0; + if (!ParseNumberProperty(&outerConeAngle, err, o, "outerConeAngle", true, "SpotLight")) { + return false; + } + + ParseExtensionsProperty(&light->extensions, err, o); + ParseExtrasProperty(&light->extras, o); + + light->innerConeAngle = innerConeAngle; + light->outerConeAngle = outerConeAngle; + + // TODO(syoyo): Validate parameter values. + + return true; +} + static bool ParseOrthographicCamera(OrthographicCamera *camera, std::string *err, const json &o) { double xmag = 0.0; @@ -3784,6 +3825,40 @@ static bool ParseCamera(Camera *camera, std::string *err, const json &o) { return true; } +static bool ParseLight(Light *light, std::string *err, const json &o) { + if (light->type.compare("spot") == 0) { + if (o.find("spot") == o.end()) { + if (err) { + std::stringstream ss; + ss << "Spot light description not found." << std::endl; + (*err) += ss.str(); + } + return false; + } + + const json &v = o.find("spot").value(); + if (!v.is_object()) { + if (err) { + std::stringstream ss; + ss << "\"spot\" is not a JSON object." << std::endl; + (*err) += ss.str(); + } + return false; + } + + if (!ParseSpotLight(&light->spot, err, v.get())) { + return false; + } + } + + ParseStringProperty(&light->name, err, o, "name", false); + ParseNumberArrayProperty(&light->color, err, o, "color", false); + ParseStringProperty(&light->type, err, o, "type", false); + ParseExtensionsProperty(&light->extensions, err, o); + ParseExtrasProperty(&(light->extras), o); + return true; +} + bool TinyGLTF::LoadFromString(Model *model, std::string *err, std::string *warn, const char *str, unsigned int length, const std::string &base_dir, @@ -4399,8 +4474,8 @@ bool TinyGLTF::LoadFromString(Model *model, std::string *err, std::string *warn, json::const_iterator it(root.begin()); json::const_iterator itEnd(root.end()); for (; it != itEnd; ++it) { - // parse KHR_lights_cmn extension - if ((it.key().compare("KHR_lights_cmn") == 0) && + // parse KHR_lights_punctual extension + if ((it.key().compare("KHR_lights_punctual") == 0) && it.value().is_object()) { const json &object = it.value(); json::const_iterator itLight(object.find("lights"));