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

Side by Side Diff: chrome/browser/android/vr_shell/gltf_parser.cc

Issue 2852533004: Implementing Binary glTF reader for the VR controller model (Closed)
Patch Set: Avoiding auto Created 3 years, 7 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 unified diff | Download patch
OLDNEW
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/bind.h" 7 #include "base/bind.h"
8 #include "base/bind_helpers.h" 8 #include "base/bind_helpers.h"
9 #include "base/callback_helpers.h" 9 #include "base/callback_helpers.h"
10 #include "base/files/file_util.h" 10 #include "base/files/file_util.h"
11 #include "base/json/json_file_value_serializer.h" 11 #include "base/json/json_file_value_serializer.h"
12 #include "base/json/json_string_value_serializer.h"
12 #include "base/logging.h" 13 #include "base/logging.h"
13 #include "base/memory/ptr_util.h" 14 #include "base/memory/ptr_util.h"
15 #include "base/strings/string_util.h"
16 #include "base/sys_byteorder.h"
14 #include "net/base/data_url.h" 17 #include "net/base/data_url.h"
15 #include "net/base/filename_util.h" 18 #include "net/base/filename_util.h"
16 #include "url/gurl.h" 19 #include "url/gurl.h"
17 20
18 namespace vr_shell { 21 namespace vr_shell {
19 22
23 namespace {
24 constexpr const char kFailedtoReadBinaryGltfMsg[] =
25 "Failed to read binary glTF: ";
26 constexpr const char kGltfMagic[] = "glTF";
27 constexpr const char kBinaryGltfBufferName[] = "binary_glTF";
28 constexpr uint32_t kJsonGltfFormat = 0;
29 constexpr size_t kVersionStart = 4;
30 constexpr size_t kLengthStart = 8;
31 constexpr size_t kContentLengthStart = 12;
32 constexpr size_t kContentFormatStart = 16;
33 constexpr size_t kContentStart = 20;
34
35 inline uint32_t GetLE32(const char* data) {
36 return base::ByteSwapToLE32(*reinterpret_cast<const uint32_t*>(data));
37 }
38
39 } // namespace
40
20 GltfParser::GltfParser() {} 41 GltfParser::GltfParser() {}
21 42
22 GltfParser::~GltfParser() = default; 43 GltfParser::~GltfParser() = default;
23 44
24 std::unique_ptr<gltf::Asset> GltfParser::Parse( 45 std::unique_ptr<gltf::Asset> GltfParser::Parse(
25 const base::DictionaryValue& dict, 46 const base::DictionaryValue& dict,
26 std::vector<std::unique_ptr<gltf::Buffer>>* buffers, 47 std::vector<std::unique_ptr<gltf::Buffer>>* buffers,
27 const base::FilePath& path) { 48 const base::FilePath& path) {
49 DCHECK(buffers && buffers->size() <= 1);
28 path_ = path; 50 path_ = path;
29 asset_ = base::MakeUnique<gltf::Asset>(); 51 asset_ = base::MakeUnique<gltf::Asset>();
30 52
31 base::ScopedClosureRunner runner( 53 base::ScopedClosureRunner runner(
32 base::Bind(&GltfParser::Clear, base::Unretained(this))); 54 base::Bind(&GltfParser::Clear, base::Unretained(this)));
33 55
34 if (!ParseInternal(dict, buffers)) 56 if (!ParseInternal(dict, buffers))
35 return nullptr; 57 return nullptr;
36 58
37 return std::move(asset_); 59 return std::move(asset_);
38 } 60 }
39 61
40 std::unique_ptr<gltf::Asset> GltfParser::Parse( 62 std::unique_ptr<gltf::Asset> GltfParser::Parse(
41 const base::FilePath& gltf_path, 63 const base::FilePath& gltf_path,
42 std::vector<std::unique_ptr<gltf::Buffer>>* buffers) { 64 std::vector<std::unique_ptr<gltf::Buffer>>* buffers) {
65 DCHECK(buffers && buffers->size() <= 1);
43 JSONFileValueDeserializer json_deserializer(gltf_path); 66 JSONFileValueDeserializer json_deserializer(gltf_path);
44 int error_code; 67 int error_code;
45 std::string error_msg; 68 std::string error_msg;
46 auto asset_value = json_deserializer.Deserialize(&error_code, &error_msg); 69 auto asset_value = json_deserializer.Deserialize(&error_code, &error_msg);
47 if (!asset_value) 70 if (!asset_value)
48 return nullptr; 71 return nullptr;
49 base::DictionaryValue* asset; 72 base::DictionaryValue* asset;
50 if (!asset_value->GetAsDictionary(&asset)) 73 if (!asset_value->GetAsDictionary(&asset))
51 return nullptr; 74 return nullptr;
52 return Parse(*asset, buffers, gltf_path); 75 return Parse(*asset, buffers, gltf_path);
(...skipping 29 matching lines...) Expand all
82 return false; 105 return false;
83 asset_->SetMainScene(asset_->GetScene(scene_it->second)); 106 asset_->SetMainScene(asset_->GetScene(scene_it->second));
84 } 107 }
85 108
86 return true; 109 return true;
87 } 110 }
88 111
89 bool GltfParser::SetBuffers( 112 bool GltfParser::SetBuffers(
90 const base::DictionaryValue& dict, 113 const base::DictionaryValue& dict,
91 std::vector<std::unique_ptr<gltf::Buffer>>* buffers) { 114 std::vector<std::unique_ptr<gltf::Buffer>>* buffers) {
92 buffers->clear(); 115 size_t buffer_count = 0;
93 for (base::DictionaryValue::Iterator it(dict); !it.IsAtEnd(); it.Advance()) { 116 for (base::DictionaryValue::Iterator it(dict); !it.IsAtEnd(); it.Advance()) {
94 const base::DictionaryValue* buffer_dict; 117 const base::DictionaryValue* buffer_dict;
95 if (!it.value().GetAsDictionary(&buffer_dict)) 118 if (!it.value().GetAsDictionary(&buffer_dict))
96 return false; 119 return false;
97 120
121 if (it.key() == kBinaryGltfBufferName) {
122 if (buffers->size() == buffer_count)
123 return false;
124 buffer_ids_[it.key()] = 0;
125 continue;
126 }
127
98 std::string uri_str; 128 std::string uri_str;
99 if (!buffer_dict->GetString("uri", &uri_str)) 129 if (!buffer_dict->GetString("uri", &uri_str))
100 return false; 130 return false;
101 auto buffer = ProcessUri(uri_str); 131 auto buffer = ProcessUri(uri_str);
102 if (!buffer) 132 if (!buffer)
103 return false; 133 return false;
104 134
105 int byte_length; 135 int byte_length;
106 if (buffer_dict->GetInteger("byteLength", &byte_length) && 136 if (buffer_dict->GetInteger("byteLength", &byte_length) &&
107 static_cast<int>(buffer->length()) != byte_length) 137 static_cast<int>(buffer->length()) != byte_length)
108 return false; 138 return false;
109 139
110 buffer_ids_[it.key()] = buffers->size(); 140 buffer_ids_[it.key()] = buffers->size();
111 buffers->push_back(std::move(buffer)); 141 buffers->push_back(std::move(buffer));
142 ++buffer_count;
112 } 143 }
113 return true; 144 return true;
114 } 145 }
115 146
116 std::unique_ptr<gltf::Buffer> GltfParser::ProcessUri( 147 std::unique_ptr<gltf::Buffer> GltfParser::ProcessUri(
117 const std::string& uri_str) { 148 const std::string& uri_str) {
118 auto uri = path_.empty() ? GURL(uri_str) 149 auto uri = path_.empty() ? GURL(uri_str)
119 : net::FilePathToFileURL(path_).Resolve(uri_str); 150 : net::FilePathToFileURL(path_).Resolve(uri_str);
120 if (!uri.is_valid()) 151 if (!uri.is_valid())
121 return nullptr; 152 return nullptr;
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
326 asset_.reset(); 357 asset_.reset();
327 path_.clear(); 358 path_.clear();
328 buffer_ids_.clear(); 359 buffer_ids_.clear();
329 buffer_view_ids_.clear(); 360 buffer_view_ids_.clear();
330 accessor_ids_.clear(); 361 accessor_ids_.clear();
331 node_ids_.clear(); 362 node_ids_.clear();
332 mesh_ids_.clear(); 363 mesh_ids_.clear();
333 scene_ids_.clear(); 364 scene_ids_.clear();
334 } 365 }
335 366
367 std::unique_ptr<gltf::Asset> BinaryGltfParser::Parse(
368 base::StringPiece glb_content,
369 std::vector<std::unique_ptr<gltf::Buffer>>* buffers,
370 const base::FilePath& path) {
371 DCHECK(buffers && buffers->empty());
372 if (glb_content.length() < kContentStart) {
373 DLOG(ERROR) << kFailedtoReadBinaryGltfMsg << "Incomplete data";
374 return nullptr;
375 }
376 if (!glb_content.starts_with(kGltfMagic)) {
377 DLOG(ERROR) << kFailedtoReadBinaryGltfMsg << "Unknown magic number";
378 return nullptr;
379 }
380 if (GetLE32(glb_content.data() + kVersionStart) != 1) {
381 DLOG(ERROR) << kFailedtoReadBinaryGltfMsg << "Unsupported version";
382 return nullptr;
383 }
384 if (GetLE32(glb_content.data() + kLengthStart) != glb_content.length()) {
385 DLOG(ERROR) << kFailedtoReadBinaryGltfMsg << "Incorrect file size";
386 return nullptr;
387 }
388 uint32_t content_length = GetLE32(glb_content.data() + kContentLengthStart);
389 if (kContentStart + content_length > glb_content.length()) {
390 DLOG(ERROR) << kFailedtoReadBinaryGltfMsg << "Invalid content length";
391 return nullptr;
392 }
393 if (GetLE32(glb_content.data() + kContentFormatStart) != kJsonGltfFormat) {
394 DLOG(ERROR) << kFailedtoReadBinaryGltfMsg << "Unsupported glTF format";
395 return nullptr;
396 }
397
398 base::StringPiece gltf_content =
399 glb_content.substr(kContentStart, content_length);
400 int error_code;
401 std::string error_msg;
402 JSONStringValueDeserializer json_deserializer(gltf_content);
403 std::unique_ptr<base::Value> gltf_value =
404 json_deserializer.Deserialize(&error_code, &error_msg);
405 if (!gltf_value) {
406 DLOG(ERROR) << kFailedtoReadBinaryGltfMsg
407 << "Content not a valid JSON - Error " << error_code << " - "
408 << error_msg;
409 return nullptr;
410 }
411 base::DictionaryValue* gltf_dict;
412 if (!gltf_value->GetAsDictionary(&gltf_dict)) {
413 DLOG(ERROR) << kFailedtoReadBinaryGltfMsg << "Content is not a JSON object";
414 return nullptr;
415 }
416
417 auto glb_buffer = base::MakeUnique<gltf::Buffer>(
418 glb_content.substr(kContentStart + content_length));
419 buffers->push_back(std::move(glb_buffer));
420 GltfParser gltf_parser;
421 std::unique_ptr<gltf::Asset> gltf_asset =
422 gltf_parser.Parse(*gltf_dict, buffers);
423 if (!gltf_asset) {
424 DLOG(ERROR) << kFailedtoReadBinaryGltfMsg << "Content is not a valid glTF";
425 buffers->clear();
426 return nullptr;
427 }
428 return gltf_asset;
429 }
430
336 } // namespace vr_shell 431 } // namespace vr_shell
OLDNEW
« 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