Merge pull request #422 from agnat/fix/add_missing_extras_and_extensions

Add missing extras and extensions fields
diff --git a/tiny_gltf.h b/tiny_gltf.h
index 62a8ee6..55b17e2 100644
--- a/tiny_gltf.h
+++ b/tiny_gltf.h
@@ -1054,6 +1054,7 @@
   std::string name;
   int skin;
   int mesh;
+  int light;  // light source index (KHR_lights_punctual)
   std::vector<int> children;
   std::vector<double> rotation;     // length must be 0 or 4
   std::vector<double> scale;        // length must be 0 or 3
@@ -4920,6 +4921,22 @@
 
   ParseExtrasAndExtensions(node, err, o, store_original_json_for_extras_and_extensions);
 
+  // KHR_lights_punctual: parse light source reference
+  int light = -1;
+  if (node->extensions.count("KHR_lights_punctual") != 0) {
+    auto const& light_ext = node->extensions["KHR_lights_punctual"];
+    if (light_ext.Has("light")) {
+      light = light_ext.Get("light").GetNumberAsInt();
+    } else {
+      if (err) {
+        *err += "Node has extension KHR_lights_punctual, but does not reference "
+          "a light source.\n";
+      }
+      return false;
+    }
+  }
+  node->light = light;
+  
   return true;
 }
 
@@ -5448,6 +5465,24 @@
   return true;
 }
 
+namespace detail {
+
+template <typename Callback>
+bool ForEachInArray(const detail::json &_v, const char *member, Callback && cb) {
+  detail::json_const_iterator itm;
+  if (detail::FindMember(_v, member, itm) && detail::IsArray(detail::GetValue(itm))) {
+    const detail::json &root = detail::GetValue(itm);
+    auto it = detail::ArrayBegin(root);
+    auto end = detail::ArrayEnd(root);
+    for (; it != end; ++it) {
+      if (!cb(*it)) return false;
+    }
+  }
+  return true;
+};
+
+} // end of namespace detail
+
 bool TinyGLTF::LoadFromString(Model *model, std::string *err, std::string *warn,
                               const char *json_str,
                               unsigned int json_str_length,
@@ -5597,28 +5632,7 @@
     }
   }
 
-#ifdef TINYGLTF_USE_CPP14
-  auto ForEachInArray = [](const detail::json &_v, const char *member,
-                           const auto &cb) -> bool
-#else
-  // The std::function<> implementation can be less efficient because it will
-  // allocate heap when the size of the captured lambda is above 16 bytes with
-  // clang and gcc, but it does not require C++14.
-  auto ForEachInArray = [](const detail::json &_v, const char *member,
-                           const std::function<bool(const detail::json &)> &cb) -> bool
-#endif
-  {
-    detail::json_const_iterator itm;
-    if (detail::FindMember(_v, member, itm) && detail::IsArray(detail::GetValue(itm))) {
-      const detail::json &root = detail::GetValue(itm);
-      auto it = detail::ArrayBegin(root);
-      auto end = detail::ArrayEnd(root);
-      for (; it != end; ++it) {
-        if (!cb(*it)) return false;
-      }
-    }
-    return true;
-  };
+  using detail::ForEachInArray;
 
   // 2. Parse extensionUsed
   {