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..0c541a6e8b43ba5c874b6be36fdc981d2d68b5d9 100644 |
--- a/chrome/browser/android/vr_shell/gltf_parser.cc |
+++ b/chrome/browser/android/vr_shell/gltf_parser.cc |
@@ -4,60 +4,73 @@ |
#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 "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; |
+GltfParser::Helper::Helper(const base::FilePath& path) |
+ : asset(base::MakeUnique<gltf::Asset>()), path(path) {} |
+ |
+GltfParser::Helper::~Helper() = default; |
+ |
std::unique_ptr<gltf::Asset> GltfParser::Parse( |
- const base::DictionaryValue& dict) { |
+ const base::DictionaryValue& dict, |
+ const base::FilePath& path) { |
+ Helper helper(path); |
+ helper_ = &helper; |
mthiesse
2017/03/24 18:11:10
Okay, this is worse than what you had before ;)
I
acondor_
2017/03/24 20:36:13
Done.
|
+ |
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(); |
- return nullptr; |
- } |
- |
- return std::move(asset_); |
-} |
- |
-bool GltfParser::ParseInternal(const base::DictionaryValue& dict) { |
const base::DictionaryValue* sub_dict; |
if (dict.GetDictionary("buffers", &sub_dict) && !SetBuffers(*sub_dict)) |
- return false; |
+ return nullptr; |
if (dict.GetDictionary("bufferViews", &sub_dict) && |
!SetBufferViews(*sub_dict)) |
- return false; |
+ return nullptr; |
if (dict.GetDictionary("accessors", &sub_dict) && !SetAccessors(*sub_dict)) |
- return false; |
+ return nullptr; |
if (dict.GetDictionary("meshes", &sub_dict) && !SetMeshes(*sub_dict)) |
- return false; |
+ return nullptr; |
if (dict.GetDictionary("nodes", &sub_dict) && !SetNodes(*sub_dict)) |
- return false; |
+ return nullptr; |
if (dict.GetDictionary("scenes", &sub_dict) && !SetScenes(*sub_dict)) |
- return false; |
+ return nullptr; |
std::string scene_key; |
if (dict.GetString("scene", &scene_key)) { |
- auto scene_it = scene_ids_.find(scene_key); |
- if (scene_it == scene_ids_.end()) |
- return false; |
- asset_->SetMainScene(asset_->GetScene(scene_it->second)); |
+ auto scene_it = helper.scene_ids.find(scene_key); |
+ if (scene_it == helper.scene_ids.end()) |
+ return nullptr; |
+ helper.asset->SetMainScene(helper.asset->GetScene(scene_it->second)); |
} |
- return true; |
+ return std::move(helper.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::SetBuffers(const base::DictionaryValue& dict) { |
@@ -66,14 +79,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; |
@@ -81,11 +91,37 @@ bool GltfParser::SetBuffers(const base::DictionaryValue& dict) { |
static_cast<int>(buffer->length()) != byte_length) |
return false; |
- buffer_ids_[it.key()] = asset_->AddBuffer(std::move(buffer)); |
+ helper_->buffer_ids[it.key()] = |
+ helper_->asset->AddBuffer(std::move(buffer)); |
} |
return true; |
} |
+std::unique_ptr<gltf::Buffer> GltfParser::ProcessUri( |
+ const std::string& uri_str) { |
+ auto uri = helper_->path.empty() |
+ ? GURL(uri_str) |
+ : net::FilePathToFileURL(helper_->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; |
@@ -96,16 +132,17 @@ bool GltfParser::SetBufferViews(const base::DictionaryValue& dict) { |
std::string buffer_key; |
if (!buffer_view_dict->GetString("buffer", &buffer_key)) |
return false; |
- auto buffer_it = buffer_ids_.find(buffer_key); |
- if (buffer_it == buffer_ids_.end()) |
+ auto buffer_it = helper_->buffer_ids.find(buffer_key); |
+ if (buffer_it == helper_->buffer_ids.end()) |
return false; |
- buffer_view->buffer = asset_->GetBuffer(buffer_it->second); |
+ buffer_view->buffer = helper_->asset->GetBuffer(buffer_it->second); |
if (!buffer_view_dict->GetInteger("byteOffset", &buffer_view->byte_offset)) |
return false; |
buffer_view_dict->GetInteger("byteLength", &buffer_view->byte_length); |
buffer_view_dict->GetInteger("target", &buffer_view->target); |
- buffer_view_ids_[it.key()] = asset_->AddBufferView(std::move(buffer_view)); |
+ helper_->buffer_view_ids[it.key()] = |
+ helper_->asset->AddBufferView(std::move(buffer_view)); |
} |
return true; |
} |
@@ -121,10 +158,11 @@ bool GltfParser::SetAccessors(const base::DictionaryValue& dict) { |
std::string type_str; |
if (!accessor_dict->GetString("bufferView", &buffer_view_key)) |
return false; |
- auto buffer_view_it = buffer_view_ids_.find(buffer_view_key); |
- if (buffer_view_it == buffer_view_ids_.end()) |
+ auto buffer_view_it = helper_->buffer_view_ids.find(buffer_view_key); |
+ if (buffer_view_it == helper_->buffer_view_ids.end()) |
return false; |
- accessor->buffer_view = asset_->GetBufferView(buffer_view_it->second); |
+ accessor->buffer_view = |
+ helper_->asset->GetBufferView(buffer_view_it->second); |
if (!accessor_dict->GetInteger("byteOffset", &accessor->byte_offset)) |
return false; |
accessor_dict->GetInteger("byteStride", &accessor->byte_stride); |
@@ -139,7 +177,8 @@ bool GltfParser::SetAccessors(const base::DictionaryValue& dict) { |
return false; |
accessor->type = type; |
- accessor_ids_[it.key()] = asset_->AddAccessor(std::move(accessor)); |
+ helper_->accessor_ids[it.key()] = |
+ helper_->asset->AddAccessor(std::move(accessor)); |
} |
return true; |
} |
@@ -165,7 +204,7 @@ bool GltfParser::SetMeshes(const base::DictionaryValue& dict) { |
} |
} |
- mesh_ids_[it.key()] = asset_->AddMesh(std::move(mesh)); |
+ helper_->mesh_ids[it.key()] = helper_->asset->AddMesh(std::move(mesh)); |
} |
return true; |
} |
@@ -176,10 +215,10 @@ std::unique_ptr<gltf::Mesh::Primitive> GltfParser::ProcessPrimitive( |
std::string indices_key; |
const base::DictionaryValue* attributes; |
if (dict.GetString("indices", &indices_key)) { |
- auto accessor_it = accessor_ids_.find(indices_key); |
- if (accessor_it == accessor_ids_.end()) |
+ auto accessor_it = helper_->accessor_ids.find(indices_key); |
+ if (accessor_it == helper_->accessor_ids.end()) |
return nullptr; |
- primitive->indices = asset_->GetAccessor(accessor_it->second); |
+ primitive->indices = helper_->asset->GetAccessor(accessor_it->second); |
} |
dict.GetInteger("mode", &primitive->mode); |
if (dict.GetDictionary("attributes", &attributes)) { |
@@ -188,11 +227,11 @@ std::unique_ptr<gltf::Mesh::Primitive> GltfParser::ProcessPrimitive( |
std::string accessor_key; |
if (!it.value().GetAsString(&accessor_key)) |
return nullptr; |
- auto accessor_it = accessor_ids_.find(accessor_key); |
- if (accessor_it == accessor_ids_.end()) |
+ auto accessor_it = helper_->accessor_ids.find(accessor_key); |
+ if (accessor_it == helper_->accessor_ids.end()) |
return nullptr; |
primitive->attributes[it.key()] = |
- asset_->GetAccessor(accessor_it->second); |
+ helper_->asset->GetAccessor(accessor_it->second); |
} |
} |
return primitive; |
@@ -212,15 +251,15 @@ bool GltfParser::SetNodes(const base::DictionaryValue& dict) { |
for (const auto& mesh_value : *list) { |
if (!mesh_value->GetAsString(&mesh_key)) |
return false; |
- auto mesh_it = mesh_ids_.find(mesh_key); |
- if (mesh_it == mesh_ids_.end()) |
+ auto mesh_it = helper_->mesh_ids.find(mesh_key); |
+ if (mesh_it == helper_->mesh_ids.end()) |
return false; |
- node->meshes.push_back(asset_->GetMesh(mesh_it->second)); |
+ node->meshes.push_back(helper_->asset->GetMesh(mesh_it->second)); |
} |
} |
nodes[it.key()] = node.get(); |
- node_ids_[it.key()] = asset_->AddNode(std::move(node)); |
+ helper_->node_ids[it.key()] = helper_->asset->AddNode(std::move(node)); |
} |
// Processing children after all nodes have been added to the asset. |
@@ -259,14 +298,14 @@ bool GltfParser::SetScenes(const base::DictionaryValue& dict) { |
for (const auto& node_value : *list) { |
if (!node_value->GetAsString(&node_key)) |
return false; |
- auto node_it = node_ids_.find(node_key); |
- if (node_it == node_ids_.end()) |
+ auto node_it = helper_->node_ids.find(node_key); |
+ if (node_it == helper_->node_ids.end()) |
return false; |
- scene->nodes.push_back(asset_->GetNode(node_it->second)); |
+ scene->nodes.push_back(helper_->asset->GetNode(node_it->second)); |
} |
} |
- scene_ids_[it.key()] = asset_->AddScene(std::move(scene)); |
+ helper_->scene_ids[it.key()] = helper_->asset->AddScene(std::move(scene)); |
} |
return true; |
} |