| Index: chrome/browser/android/vr_shell/gltf_parser.cc
|
| diff --git a/chrome/browser/android/vr_shell/gltf_parser.cc b/chrome/browser/android/vr_shell/gltf_parser.cc
|
| index 17be0c8c098129ba39c62fd4acb0652695d2fa89..fbb59dce1f76e84409062cfa1fa28df866f03c4e 100644
|
| --- a/chrome/browser/android/vr_shell/gltf_parser.cc
|
| +++ b/chrome/browser/android/vr_shell/gltf_parser.cc
|
| @@ -4,36 +4,57 @@
|
|
|
| #include "chrome/browser/android/vr_shell/gltf_parser.h"
|
|
|
| -#include "base/base64.h"
|
| +#include "base/bind.h"
|
| +#include "base/bind_helpers.h"
|
| +#include "base/callback_helpers.h"
|
| +#include "base/files/file_util.h"
|
| +#include "base/json/json_file_value_serializer.h"
|
| #include "base/logging.h"
|
| #include "base/memory/ptr_util.h"
|
| +#include "net/base/data_url.h"
|
| +#include "net/base/filename_util.h"
|
| +#include "url/gurl.h"
|
|
|
| namespace vr_shell {
|
|
|
| -constexpr char kBase64Header[] = "data:application/octet-stream;base64,";
|
| -constexpr size_t kBase64HeaderSize = 37;
|
| -
|
| GltfParser::GltfParser() {}
|
|
|
| GltfParser::~GltfParser() = default;
|
|
|
| std::unique_ptr<gltf::Asset> GltfParser::Parse(
|
| - const base::DictionaryValue& dict) {
|
| - std::string gltf_version;
|
| - if (!dict.GetString("asset.version", &gltf_version) || gltf_version != "1.0")
|
| - return nullptr;
|
| -
|
| + const base::DictionaryValue& dict,
|
| + const base::FilePath& path) {
|
| + path_ = path;
|
| asset_ = base::MakeUnique<gltf::Asset>();
|
|
|
| - if (!ParseInternal(dict)) {
|
| - asset_.reset();
|
| + base::ScopedClosureRunner runner(
|
| + base::Bind(&GltfParser::Clear, base::Unretained(this)));
|
| +
|
| + if (!ParseInternal(dict))
|
| return nullptr;
|
| - }
|
|
|
| return std::move(asset_);
|
| }
|
|
|
| +std::unique_ptr<gltf::Asset> GltfParser::Parse(
|
| + const base::FilePath& gltf_path) {
|
| + JSONFileValueDeserializer json_deserializer(gltf_path);
|
| + int error_code;
|
| + std::string error_msg;
|
| + auto asset_value = json_deserializer.Deserialize(&error_code, &error_msg);
|
| + if (!asset_value)
|
| + return nullptr;
|
| + base::DictionaryValue* asset;
|
| + if (!asset_value->GetAsDictionary(&asset))
|
| + return nullptr;
|
| + return Parse(*asset, gltf_path);
|
| +}
|
| +
|
| bool GltfParser::ParseInternal(const base::DictionaryValue& dict) {
|
| + std::string gltf_version;
|
| + if (!dict.GetString("asset.version", &gltf_version) || gltf_version != "1.0")
|
| + return false;
|
| +
|
| const base::DictionaryValue* sub_dict;
|
| if (dict.GetDictionary("buffers", &sub_dict) && !SetBuffers(*sub_dict))
|
| return false;
|
| @@ -66,14 +87,11 @@ bool GltfParser::SetBuffers(const base::DictionaryValue& dict) {
|
| if (!it.value().GetAsDictionary(&buffer_dict))
|
| return false;
|
|
|
| - std::string uri;
|
| - // TODO(acondor): Support files. Only inline data is supported now.
|
| - if (!buffer_dict->GetString("uri", &uri) ||
|
| - uri.substr(0, kBase64HeaderSize) != kBase64Header)
|
| + std::string uri_str;
|
| + if (!buffer_dict->GetString("uri", &uri_str))
|
| return false;
|
| -
|
| - auto buffer = base::MakeUnique<gltf::Buffer>();
|
| - if (!base::Base64Decode(uri.substr(kBase64HeaderSize), buffer.get()))
|
| + auto buffer = ProcessUri(uri_str);
|
| + if (!buffer)
|
| return false;
|
|
|
| int byte_length;
|
| @@ -86,6 +104,30 @@ bool GltfParser::SetBuffers(const base::DictionaryValue& dict) {
|
| return true;
|
| }
|
|
|
| +std::unique_ptr<gltf::Buffer> GltfParser::ProcessUri(
|
| + const std::string& uri_str) {
|
| + auto uri = path_.empty() ? GURL(uri_str)
|
| + : net::FilePathToFileURL(path_).Resolve(uri_str);
|
| + if (!uri.is_valid())
|
| + return nullptr;
|
| + if (uri.SchemeIs(url::kDataScheme)) {
|
| + std::string mime_type;
|
| + std::string charset;
|
| + auto data = base::MakeUnique<gltf::Buffer>();
|
| + if (!net::DataURL::Parse(uri, &mime_type, &charset, data.get()))
|
| + return nullptr;
|
| + return data;
|
| + }
|
| + if (uri.SchemeIsFile()) {
|
| + auto data = base::MakeUnique<gltf::Buffer>();
|
| + if (!base::ReadFileToString(base::FilePath(uri.path()), data.get()))
|
| + return nullptr;
|
| + return data;
|
| + }
|
| + // No other schemes are supported yet.
|
| + return nullptr;
|
| +}
|
| +
|
| bool GltfParser::SetBufferViews(const base::DictionaryValue& dict) {
|
| for (base::DictionaryValue::Iterator it(dict); !it.IsAtEnd(); it.Advance()) {
|
| const base::DictionaryValue* buffer_view_dict;
|
| @@ -271,4 +313,15 @@ bool GltfParser::SetScenes(const base::DictionaryValue& dict) {
|
| return true;
|
| }
|
|
|
| +void GltfParser::Clear() {
|
| + asset_.reset();
|
| + path_.clear();
|
| + buffer_ids_.clear();
|
| + buffer_view_ids_.clear();
|
| + accessor_ids_.clear();
|
| + node_ids_.clear();
|
| + mesh_ids_.clear();
|
| + scene_ids_.clear();
|
| +}
|
| +
|
| } // namespace vr_shell
|
|
|