Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2687)

Unified Diff: chrome/browser/android/vr_shell/gltf_parser.cc

Issue 2774653002: Support for parsing external file references in a glTF resource. (Closed)
Patch Set: Scoped holders and tests for parsing failures. Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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;
}
« no previous file with comments | « chrome/browser/android/vr_shell/gltf_parser.h ('k') | chrome/browser/android/vr_shell/gltf_parser_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698