Chromium Code Reviews| 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..a489e48da5e58f2a851b02b5c84363108b6ae812 100644 |
| --- a/chrome/browser/android/vr_shell/gltf_parser.cc |
| +++ b/chrome/browser/android/vr_shell/gltf_parser.cc |
| @@ -5,35 +5,52 @@ |
| #include "chrome/browser/android/vr_shell/gltf_parser.h" |
| #include "base/base64.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 "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; |
| - |
| asset_ = base::MakeUnique<gltf::Asset>(); |
| if (!ParseInternal(dict)) { |
| - asset_.reset(); |
| + Clear(); |
|
mthiesse
2017/03/23 15:00:10
You probably want to clear on the success case as
acondor_
2017/03/23 16:28:12
Done.
|
| return nullptr; |
| } |
| return std::move(asset_); |
| } |
| +// Use this method if the glTF file references external files. |
|
mthiesse
2017/03/23 15:00:10
Comments should go in the header.
mthiesse
2017/03/23 15:00:10
It shouldn't matter whether your input is a dictio
acondor_
2017/03/23 15:29:21
Just to clarify, there would be no way to process
acondor_
2017/03/23 16:28:12
Done.
|
| +// If so, use it in the FILE BrowserThread. |
| +std::unique_ptr<gltf::Asset> GltfParser::Parse(const base::FilePath& path) { |
| + JSONFileValueDeserializer json_deserializer(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; |
| + path_ = path; |
| + return Parse(*asset); |
| +} |
| + |
| 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 +83,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 +100,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) |
| + : GURL("file://" + path_.value()).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 +309,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 |