Chromium Code Reviews| OLD | NEW | 
|---|---|
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "chrome/browser/android/vr_shell/gltf_parser.h" | 5 #include "chrome/browser/android/vr_shell/gltf_parser.h" | 
| 6 | 6 | 
| 7 #include "base/base64.h" | 7 #include "base/files/file_util.h" | 
| 8 #include "base/json/json_file_value_serializer.h" | |
| 8 #include "base/logging.h" | 9 #include "base/logging.h" | 
| 9 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" | 
| 11 #include "net/base/data_url.h" | |
| 12 #include "net/base/filename_util.h" | |
| 13 #include "url/gurl.h" | |
| 10 | 14 | 
| 11 namespace vr_shell { | 15 namespace vr_shell { | 
| 12 | 16 | 
| 13 constexpr char kBase64Header[] = "data:application/octet-stream;base64,"; | |
| 14 constexpr size_t kBase64HeaderSize = 37; | |
| 15 | |
| 16 GltfParser::GltfParser() {} | 17 GltfParser::GltfParser() {} | 
| 17 | 18 | 
| 18 GltfParser::~GltfParser() = default; | 19 GltfParser::~GltfParser() = default; | 
| 19 | 20 | 
| 21 GltfParser::Helper::Helper(const base::FilePath& path) | |
| 22 : asset(base::MakeUnique<gltf::Asset>()), path(path) {} | |
| 23 | |
| 24 GltfParser::Helper::~Helper() = default; | |
| 25 | |
| 20 std::unique_ptr<gltf::Asset> GltfParser::Parse( | 26 std::unique_ptr<gltf::Asset> GltfParser::Parse( | 
| 21 const base::DictionaryValue& dict) { | 27 const base::DictionaryValue& dict, | 
| 28 const base::FilePath& path) { | |
| 29 Helper helper(path); | |
| 30 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.
 
 | |
| 31 | |
| 22 std::string gltf_version; | 32 std::string gltf_version; | 
| 23 if (!dict.GetString("asset.version", &gltf_version) || gltf_version != "1.0") | 33 if (!dict.GetString("asset.version", &gltf_version) || gltf_version != "1.0") | 
| 24 return nullptr; | 34 return nullptr; | 
| 25 | 35 | 
| 26 asset_ = base::MakeUnique<gltf::Asset>(); | |
| 27 | |
| 28 if (!ParseInternal(dict)) { | |
| 29 asset_.reset(); | |
| 30 return nullptr; | |
| 31 } | |
| 32 | |
| 33 return std::move(asset_); | |
| 34 } | |
| 35 | |
| 36 bool GltfParser::ParseInternal(const base::DictionaryValue& dict) { | |
| 37 const base::DictionaryValue* sub_dict; | 36 const base::DictionaryValue* sub_dict; | 
| 38 if (dict.GetDictionary("buffers", &sub_dict) && !SetBuffers(*sub_dict)) | 37 if (dict.GetDictionary("buffers", &sub_dict) && !SetBuffers(*sub_dict)) | 
| 39 return false; | 38 return nullptr; | 
| 40 if (dict.GetDictionary("bufferViews", &sub_dict) && | 39 if (dict.GetDictionary("bufferViews", &sub_dict) && | 
| 41 !SetBufferViews(*sub_dict)) | 40 !SetBufferViews(*sub_dict)) | 
| 42 return false; | 41 return nullptr; | 
| 43 if (dict.GetDictionary("accessors", &sub_dict) && !SetAccessors(*sub_dict)) | 42 if (dict.GetDictionary("accessors", &sub_dict) && !SetAccessors(*sub_dict)) | 
| 44 return false; | 43 return nullptr; | 
| 45 if (dict.GetDictionary("meshes", &sub_dict) && !SetMeshes(*sub_dict)) | 44 if (dict.GetDictionary("meshes", &sub_dict) && !SetMeshes(*sub_dict)) | 
| 46 return false; | 45 return nullptr; | 
| 47 if (dict.GetDictionary("nodes", &sub_dict) && !SetNodes(*sub_dict)) | 46 if (dict.GetDictionary("nodes", &sub_dict) && !SetNodes(*sub_dict)) | 
| 48 return false; | 47 return nullptr; | 
| 49 if (dict.GetDictionary("scenes", &sub_dict) && !SetScenes(*sub_dict)) | 48 if (dict.GetDictionary("scenes", &sub_dict) && !SetScenes(*sub_dict)) | 
| 50 return false; | 49 return nullptr; | 
| 51 | 50 | 
| 52 std::string scene_key; | 51 std::string scene_key; | 
| 53 if (dict.GetString("scene", &scene_key)) { | 52 if (dict.GetString("scene", &scene_key)) { | 
| 54 auto scene_it = scene_ids_.find(scene_key); | 53 auto scene_it = helper.scene_ids.find(scene_key); | 
| 55 if (scene_it == scene_ids_.end()) | 54 if (scene_it == helper.scene_ids.end()) | 
| 56 return false; | 55 return nullptr; | 
| 57 asset_->SetMainScene(asset_->GetScene(scene_it->second)); | 56 helper.asset->SetMainScene(helper.asset->GetScene(scene_it->second)); | 
| 58 } | 57 } | 
| 59 | 58 | 
| 60 return true; | 59 return std::move(helper.asset); | 
| 60 } | |
| 61 | |
| 62 std::unique_ptr<gltf::Asset> GltfParser::Parse( | |
| 63 const base::FilePath& gltf_path) { | |
| 64 JSONFileValueDeserializer json_deserializer(gltf_path); | |
| 65 int error_code; | |
| 66 std::string error_msg; | |
| 67 auto asset_value = json_deserializer.Deserialize(&error_code, &error_msg); | |
| 68 if (!asset_value) | |
| 69 return nullptr; | |
| 70 base::DictionaryValue* asset; | |
| 71 if (!asset_value->GetAsDictionary(&asset)) | |
| 72 return nullptr; | |
| 73 return Parse(*asset, gltf_path); | |
| 61 } | 74 } | 
| 62 | 75 | 
| 63 bool GltfParser::SetBuffers(const base::DictionaryValue& dict) { | 76 bool GltfParser::SetBuffers(const base::DictionaryValue& dict) { | 
| 64 for (base::DictionaryValue::Iterator it(dict); !it.IsAtEnd(); it.Advance()) { | 77 for (base::DictionaryValue::Iterator it(dict); !it.IsAtEnd(); it.Advance()) { | 
| 65 const base::DictionaryValue* buffer_dict; | 78 const base::DictionaryValue* buffer_dict; | 
| 66 if (!it.value().GetAsDictionary(&buffer_dict)) | 79 if (!it.value().GetAsDictionary(&buffer_dict)) | 
| 67 return false; | 80 return false; | 
| 68 | 81 | 
| 69 std::string uri; | 82 std::string uri_str; | 
| 70 // TODO(acondor): Support files. Only inline data is supported now. | 83 if (!buffer_dict->GetString("uri", &uri_str)) | 
| 71 if (!buffer_dict->GetString("uri", &uri) || | |
| 72 uri.substr(0, kBase64HeaderSize) != kBase64Header) | |
| 73 return false; | 84 return false; | 
| 74 | 85 auto buffer = ProcessUri(uri_str); | 
| 75 auto buffer = base::MakeUnique<gltf::Buffer>(); | 86 if (!buffer) | 
| 76 if (!base::Base64Decode(uri.substr(kBase64HeaderSize), buffer.get())) | |
| 77 return false; | 87 return false; | 
| 78 | 88 | 
| 79 int byte_length; | 89 int byte_length; | 
| 80 if (buffer_dict->GetInteger("byteLength", &byte_length) && | 90 if (buffer_dict->GetInteger("byteLength", &byte_length) && | 
| 81 static_cast<int>(buffer->length()) != byte_length) | 91 static_cast<int>(buffer->length()) != byte_length) | 
| 82 return false; | 92 return false; | 
| 83 | 93 | 
| 84 buffer_ids_[it.key()] = asset_->AddBuffer(std::move(buffer)); | 94 helper_->buffer_ids[it.key()] = | 
| 95 helper_->asset->AddBuffer(std::move(buffer)); | |
| 85 } | 96 } | 
| 86 return true; | 97 return true; | 
| 87 } | 98 } | 
| 88 | 99 | 
| 100 std::unique_ptr<gltf::Buffer> GltfParser::ProcessUri( | |
| 101 const std::string& uri_str) { | |
| 102 auto uri = helper_->path.empty() | |
| 103 ? GURL(uri_str) | |
| 104 : net::FilePathToFileURL(helper_->path).Resolve(uri_str); | |
| 105 if (!uri.is_valid()) | |
| 106 return nullptr; | |
| 107 if (uri.SchemeIs(url::kDataScheme)) { | |
| 108 std::string mime_type; | |
| 109 std::string charset; | |
| 110 auto data = base::MakeUnique<gltf::Buffer>(); | |
| 111 if (!net::DataURL::Parse(uri, &mime_type, &charset, data.get())) | |
| 112 return nullptr; | |
| 113 return data; | |
| 114 } | |
| 115 if (uri.SchemeIsFile()) { | |
| 116 auto data = base::MakeUnique<gltf::Buffer>(); | |
| 117 if (!base::ReadFileToString(base::FilePath(uri.path()), data.get())) | |
| 118 return nullptr; | |
| 119 return data; | |
| 120 } | |
| 121 // No other schemes are supported yet. | |
| 122 return nullptr; | |
| 123 } | |
| 124 | |
| 89 bool GltfParser::SetBufferViews(const base::DictionaryValue& dict) { | 125 bool GltfParser::SetBufferViews(const base::DictionaryValue& dict) { | 
| 90 for (base::DictionaryValue::Iterator it(dict); !it.IsAtEnd(); it.Advance()) { | 126 for (base::DictionaryValue::Iterator it(dict); !it.IsAtEnd(); it.Advance()) { | 
| 91 const base::DictionaryValue* buffer_view_dict; | 127 const base::DictionaryValue* buffer_view_dict; | 
| 92 if (!it.value().GetAsDictionary(&buffer_view_dict)) | 128 if (!it.value().GetAsDictionary(&buffer_view_dict)) | 
| 93 return false; | 129 return false; | 
| 94 | 130 | 
| 95 auto buffer_view = base::MakeUnique<gltf::BufferView>(); | 131 auto buffer_view = base::MakeUnique<gltf::BufferView>(); | 
| 96 std::string buffer_key; | 132 std::string buffer_key; | 
| 97 if (!buffer_view_dict->GetString("buffer", &buffer_key)) | 133 if (!buffer_view_dict->GetString("buffer", &buffer_key)) | 
| 98 return false; | 134 return false; | 
| 99 auto buffer_it = buffer_ids_.find(buffer_key); | 135 auto buffer_it = helper_->buffer_ids.find(buffer_key); | 
| 100 if (buffer_it == buffer_ids_.end()) | 136 if (buffer_it == helper_->buffer_ids.end()) | 
| 101 return false; | 137 return false; | 
| 102 buffer_view->buffer = asset_->GetBuffer(buffer_it->second); | 138 buffer_view->buffer = helper_->asset->GetBuffer(buffer_it->second); | 
| 103 if (!buffer_view_dict->GetInteger("byteOffset", &buffer_view->byte_offset)) | 139 if (!buffer_view_dict->GetInteger("byteOffset", &buffer_view->byte_offset)) | 
| 104 return false; | 140 return false; | 
| 105 buffer_view_dict->GetInteger("byteLength", &buffer_view->byte_length); | 141 buffer_view_dict->GetInteger("byteLength", &buffer_view->byte_length); | 
| 106 buffer_view_dict->GetInteger("target", &buffer_view->target); | 142 buffer_view_dict->GetInteger("target", &buffer_view->target); | 
| 107 | 143 | 
| 108 buffer_view_ids_[it.key()] = asset_->AddBufferView(std::move(buffer_view)); | 144 helper_->buffer_view_ids[it.key()] = | 
| 145 helper_->asset->AddBufferView(std::move(buffer_view)); | |
| 109 } | 146 } | 
| 110 return true; | 147 return true; | 
| 111 } | 148 } | 
| 112 | 149 | 
| 113 bool GltfParser::SetAccessors(const base::DictionaryValue& dict) { | 150 bool GltfParser::SetAccessors(const base::DictionaryValue& dict) { | 
| 114 for (base::DictionaryValue::Iterator it(dict); !it.IsAtEnd(); it.Advance()) { | 151 for (base::DictionaryValue::Iterator it(dict); !it.IsAtEnd(); it.Advance()) { | 
| 115 const base::DictionaryValue* accessor_dict; | 152 const base::DictionaryValue* accessor_dict; | 
| 116 if (!it.value().GetAsDictionary(&accessor_dict)) | 153 if (!it.value().GetAsDictionary(&accessor_dict)) | 
| 117 return false; | 154 return false; | 
| 118 | 155 | 
| 119 auto accessor = base::MakeUnique<gltf::Accessor>(); | 156 auto accessor = base::MakeUnique<gltf::Accessor>(); | 
| 120 std::string buffer_view_key; | 157 std::string buffer_view_key; | 
| 121 std::string type_str; | 158 std::string type_str; | 
| 122 if (!accessor_dict->GetString("bufferView", &buffer_view_key)) | 159 if (!accessor_dict->GetString("bufferView", &buffer_view_key)) | 
| 123 return false; | 160 return false; | 
| 124 auto buffer_view_it = buffer_view_ids_.find(buffer_view_key); | 161 auto buffer_view_it = helper_->buffer_view_ids.find(buffer_view_key); | 
| 125 if (buffer_view_it == buffer_view_ids_.end()) | 162 if (buffer_view_it == helper_->buffer_view_ids.end()) | 
| 126 return false; | 163 return false; | 
| 127 accessor->buffer_view = asset_->GetBufferView(buffer_view_it->second); | 164 accessor->buffer_view = | 
| 165 helper_->asset->GetBufferView(buffer_view_it->second); | |
| 128 if (!accessor_dict->GetInteger("byteOffset", &accessor->byte_offset)) | 166 if (!accessor_dict->GetInteger("byteOffset", &accessor->byte_offset)) | 
| 129 return false; | 167 return false; | 
| 130 accessor_dict->GetInteger("byteStride", &accessor->byte_stride); | 168 accessor_dict->GetInteger("byteStride", &accessor->byte_stride); | 
| 131 if (!accessor_dict->GetInteger("componentType", &accessor->component_type)) | 169 if (!accessor_dict->GetInteger("componentType", &accessor->component_type)) | 
| 132 return false; | 170 return false; | 
| 133 if (!accessor_dict->GetInteger("count", &accessor->count)) | 171 if (!accessor_dict->GetInteger("count", &accessor->count)) | 
| 134 return false; | 172 return false; | 
| 135 if (!accessor_dict->GetString("type", &type_str)) | 173 if (!accessor_dict->GetString("type", &type_str)) | 
| 136 return false; | 174 return false; | 
| 137 gltf::Type type = gltf::GetType(type_str); | 175 gltf::Type type = gltf::GetType(type_str); | 
| 138 if (type == gltf::UNKNOWN) | 176 if (type == gltf::UNKNOWN) | 
| 139 return false; | 177 return false; | 
| 140 accessor->type = type; | 178 accessor->type = type; | 
| 141 | 179 | 
| 142 accessor_ids_[it.key()] = asset_->AddAccessor(std::move(accessor)); | 180 helper_->accessor_ids[it.key()] = | 
| 181 helper_->asset->AddAccessor(std::move(accessor)); | |
| 143 } | 182 } | 
| 144 return true; | 183 return true; | 
| 145 } | 184 } | 
| 146 | 185 | 
| 147 bool GltfParser::SetMeshes(const base::DictionaryValue& dict) { | 186 bool GltfParser::SetMeshes(const base::DictionaryValue& dict) { | 
| 148 for (base::DictionaryValue::Iterator it(dict); !it.IsAtEnd(); it.Advance()) { | 187 for (base::DictionaryValue::Iterator it(dict); !it.IsAtEnd(); it.Advance()) { | 
| 149 const base::DictionaryValue* mesh_dict; | 188 const base::DictionaryValue* mesh_dict; | 
| 150 if (!it.value().GetAsDictionary(&mesh_dict)) | 189 if (!it.value().GetAsDictionary(&mesh_dict)) | 
| 151 return false; | 190 return false; | 
| 152 | 191 | 
| 153 auto mesh = base::MakeUnique<gltf::Mesh>(); | 192 auto mesh = base::MakeUnique<gltf::Mesh>(); | 
| 154 const base::ListValue* list; | 193 const base::ListValue* list; | 
| 155 if (mesh_dict->GetList("primitives", &list)) { | 194 if (mesh_dict->GetList("primitives", &list)) { | 
| 156 for (const auto& primitive_value : *list) { | 195 for (const auto& primitive_value : *list) { | 
| 157 const base::DictionaryValue* primitive_dict; | 196 const base::DictionaryValue* primitive_dict; | 
| 158 if (!primitive_value->GetAsDictionary(&primitive_dict)) | 197 if (!primitive_value->GetAsDictionary(&primitive_dict)) | 
| 159 return false; | 198 return false; | 
| 160 | 199 | 
| 161 auto primitive = ProcessPrimitive(*primitive_dict); | 200 auto primitive = ProcessPrimitive(*primitive_dict); | 
| 162 if (!primitive) | 201 if (!primitive) | 
| 163 return false; | 202 return false; | 
| 164 mesh->primitives.push_back(std::move(primitive)); | 203 mesh->primitives.push_back(std::move(primitive)); | 
| 165 } | 204 } | 
| 166 } | 205 } | 
| 167 | 206 | 
| 168 mesh_ids_[it.key()] = asset_->AddMesh(std::move(mesh)); | 207 helper_->mesh_ids[it.key()] = helper_->asset->AddMesh(std::move(mesh)); | 
| 169 } | 208 } | 
| 170 return true; | 209 return true; | 
| 171 } | 210 } | 
| 172 | 211 | 
| 173 std::unique_ptr<gltf::Mesh::Primitive> GltfParser::ProcessPrimitive( | 212 std::unique_ptr<gltf::Mesh::Primitive> GltfParser::ProcessPrimitive( | 
| 174 const base::DictionaryValue& dict) { | 213 const base::DictionaryValue& dict) { | 
| 175 auto primitive = base::MakeUnique<gltf::Mesh::Primitive>(); | 214 auto primitive = base::MakeUnique<gltf::Mesh::Primitive>(); | 
| 176 std::string indices_key; | 215 std::string indices_key; | 
| 177 const base::DictionaryValue* attributes; | 216 const base::DictionaryValue* attributes; | 
| 178 if (dict.GetString("indices", &indices_key)) { | 217 if (dict.GetString("indices", &indices_key)) { | 
| 179 auto accessor_it = accessor_ids_.find(indices_key); | 218 auto accessor_it = helper_->accessor_ids.find(indices_key); | 
| 180 if (accessor_it == accessor_ids_.end()) | 219 if (accessor_it == helper_->accessor_ids.end()) | 
| 181 return nullptr; | 220 return nullptr; | 
| 182 primitive->indices = asset_->GetAccessor(accessor_it->second); | 221 primitive->indices = helper_->asset->GetAccessor(accessor_it->second); | 
| 183 } | 222 } | 
| 184 dict.GetInteger("mode", &primitive->mode); | 223 dict.GetInteger("mode", &primitive->mode); | 
| 185 if (dict.GetDictionary("attributes", &attributes)) { | 224 if (dict.GetDictionary("attributes", &attributes)) { | 
| 186 for (base::DictionaryValue::Iterator it(*attributes); !it.IsAtEnd(); | 225 for (base::DictionaryValue::Iterator it(*attributes); !it.IsAtEnd(); | 
| 187 it.Advance()) { | 226 it.Advance()) { | 
| 188 std::string accessor_key; | 227 std::string accessor_key; | 
| 189 if (!it.value().GetAsString(&accessor_key)) | 228 if (!it.value().GetAsString(&accessor_key)) | 
| 190 return nullptr; | 229 return nullptr; | 
| 191 auto accessor_it = accessor_ids_.find(accessor_key); | 230 auto accessor_it = helper_->accessor_ids.find(accessor_key); | 
| 192 if (accessor_it == accessor_ids_.end()) | 231 if (accessor_it == helper_->accessor_ids.end()) | 
| 193 return nullptr; | 232 return nullptr; | 
| 194 primitive->attributes[it.key()] = | 233 primitive->attributes[it.key()] = | 
| 195 asset_->GetAccessor(accessor_it->second); | 234 helper_->asset->GetAccessor(accessor_it->second); | 
| 196 } | 235 } | 
| 197 } | 236 } | 
| 198 return primitive; | 237 return primitive; | 
| 199 } | 238 } | 
| 200 | 239 | 
| 201 bool GltfParser::SetNodes(const base::DictionaryValue& dict) { | 240 bool GltfParser::SetNodes(const base::DictionaryValue& dict) { | 
| 202 std::unordered_map<std::string, gltf::Node*> nodes; | 241 std::unordered_map<std::string, gltf::Node*> nodes; | 
| 203 for (base::DictionaryValue::Iterator it(dict); !it.IsAtEnd(); it.Advance()) { | 242 for (base::DictionaryValue::Iterator it(dict); !it.IsAtEnd(); it.Advance()) { | 
| 204 const base::DictionaryValue* node_dict; | 243 const base::DictionaryValue* node_dict; | 
| 205 if (!it.value().GetAsDictionary(&node_dict)) | 244 if (!it.value().GetAsDictionary(&node_dict)) | 
| 206 return false; | 245 return false; | 
| 207 | 246 | 
| 208 auto node = base::MakeUnique<gltf::Node>(); | 247 auto node = base::MakeUnique<gltf::Node>(); | 
| 209 const base::ListValue* list; | 248 const base::ListValue* list; | 
| 210 if (node_dict->GetList("meshes", &list)) { | 249 if (node_dict->GetList("meshes", &list)) { | 
| 211 std::string mesh_key; | 250 std::string mesh_key; | 
| 212 for (const auto& mesh_value : *list) { | 251 for (const auto& mesh_value : *list) { | 
| 213 if (!mesh_value->GetAsString(&mesh_key)) | 252 if (!mesh_value->GetAsString(&mesh_key)) | 
| 214 return false; | 253 return false; | 
| 215 auto mesh_it = mesh_ids_.find(mesh_key); | 254 auto mesh_it = helper_->mesh_ids.find(mesh_key); | 
| 216 if (mesh_it == mesh_ids_.end()) | 255 if (mesh_it == helper_->mesh_ids.end()) | 
| 217 return false; | 256 return false; | 
| 218 node->meshes.push_back(asset_->GetMesh(mesh_it->second)); | 257 node->meshes.push_back(helper_->asset->GetMesh(mesh_it->second)); | 
| 219 } | 258 } | 
| 220 } | 259 } | 
| 221 | 260 | 
| 222 nodes[it.key()] = node.get(); | 261 nodes[it.key()] = node.get(); | 
| 223 node_ids_[it.key()] = asset_->AddNode(std::move(node)); | 262 helper_->node_ids[it.key()] = helper_->asset->AddNode(std::move(node)); | 
| 224 } | 263 } | 
| 225 | 264 | 
| 226 // Processing children after all nodes have been added to the asset. | 265 // Processing children after all nodes have been added to the asset. | 
| 227 for (base::DictionaryValue::Iterator it(dict); !it.IsAtEnd(); it.Advance()) { | 266 for (base::DictionaryValue::Iterator it(dict); !it.IsAtEnd(); it.Advance()) { | 
| 228 const base::DictionaryValue* node_dict; | 267 const base::DictionaryValue* node_dict; | 
| 229 it.value().GetAsDictionary(&node_dict); | 268 it.value().GetAsDictionary(&node_dict); | 
| 230 | 269 | 
| 231 gltf::Node* node = nodes[it.key()]; | 270 gltf::Node* node = nodes[it.key()]; | 
| 232 const base::ListValue* list; | 271 const base::ListValue* list; | 
| 233 if (node_dict->GetList("children", &list)) { | 272 if (node_dict->GetList("children", &list)) { | 
| (...skipping 18 matching lines...) Expand all Loading... | |
| 252 if (!it.value().GetAsDictionary(&scene_dict)) | 291 if (!it.value().GetAsDictionary(&scene_dict)) | 
| 253 return false; | 292 return false; | 
| 254 | 293 | 
| 255 auto scene = base::MakeUnique<gltf::Scene>(); | 294 auto scene = base::MakeUnique<gltf::Scene>(); | 
| 256 const base::ListValue* list; | 295 const base::ListValue* list; | 
| 257 if (scene_dict->GetList("nodes", &list)) { | 296 if (scene_dict->GetList("nodes", &list)) { | 
| 258 std::string node_key; | 297 std::string node_key; | 
| 259 for (const auto& node_value : *list) { | 298 for (const auto& node_value : *list) { | 
| 260 if (!node_value->GetAsString(&node_key)) | 299 if (!node_value->GetAsString(&node_key)) | 
| 261 return false; | 300 return false; | 
| 262 auto node_it = node_ids_.find(node_key); | 301 auto node_it = helper_->node_ids.find(node_key); | 
| 263 if (node_it == node_ids_.end()) | 302 if (node_it == helper_->node_ids.end()) | 
| 264 return false; | 303 return false; | 
| 265 scene->nodes.push_back(asset_->GetNode(node_it->second)); | 304 scene->nodes.push_back(helper_->asset->GetNode(node_it->second)); | 
| 266 } | 305 } | 
| 267 } | 306 } | 
| 268 | 307 | 
| 269 scene_ids_[it.key()] = asset_->AddScene(std::move(scene)); | 308 helper_->scene_ids[it.key()] = helper_->asset->AddScene(std::move(scene)); | 
| 270 } | 309 } | 
| 271 return true; | 310 return true; | 
| 272 } | 311 } | 
| 273 | 312 | 
| 274 } // namespace vr_shell | 313 } // namespace vr_shell | 
| OLD | NEW |