forked from firka/flutter
[Impeller Scene] Add offline mesh importer (flutter/engine#37981)
This commit is contained in:
@@ -1648,6 +1648,13 @@ FILE: ../../../flutter/impeller/scene/camera.cc
|
||||
FILE: ../../../flutter/impeller/scene/camera.h
|
||||
FILE: ../../../flutter/impeller/scene/geometry.cc
|
||||
FILE: ../../../flutter/impeller/scene/geometry.h
|
||||
FILE: ../../../flutter/impeller/scene/importer/importer.h
|
||||
FILE: ../../../flutter/impeller/scene/importer/importer_gltf.cc
|
||||
FILE: ../../../flutter/impeller/scene/importer/importer_main.cc
|
||||
FILE: ../../../flutter/impeller/scene/importer/mesh.fbs
|
||||
FILE: ../../../flutter/impeller/scene/importer/switches.cc
|
||||
FILE: ../../../flutter/impeller/scene/importer/switches.h
|
||||
FILE: ../../../flutter/impeller/scene/importer/types.h
|
||||
FILE: ../../../flutter/impeller/scene/material.cc
|
||||
FILE: ../../../flutter/impeller/scene/material.h
|
||||
FILE: ../../../flutter/impeller/scene/scene.cc
|
||||
|
||||
@@ -5,6 +5,24 @@
|
||||
import("//flutter/impeller/tools/impeller.gni")
|
||||
import("//flutter/shell/version/version.gni")
|
||||
|
||||
impeller_component("utilities") {
|
||||
# Current versions of libcxx have deprecated some of the UTF-16 string
|
||||
# conversion APIs.
|
||||
defines = [ "_LIBCPP_DISABLE_DEPRECATION_WARNINGS" ]
|
||||
|
||||
sources = [
|
||||
"utilities.cc",
|
||||
"utilities.h",
|
||||
]
|
||||
|
||||
public_deps = [
|
||||
"../base",
|
||||
"../geometry",
|
||||
"../runtime_stage",
|
||||
"//flutter/fml",
|
||||
]
|
||||
}
|
||||
|
||||
impeller_component("compiler_lib") {
|
||||
include_dirs = [ "//third_party/vulkan-deps/spirv-cross/src/" ]
|
||||
|
||||
@@ -34,11 +52,10 @@ impeller_component("compiler_lib") {
|
||||
"switches.h",
|
||||
"types.cc",
|
||||
"types.h",
|
||||
"utilities.cc",
|
||||
"utilities.h",
|
||||
]
|
||||
|
||||
public_deps = [
|
||||
":utilities",
|
||||
"../base",
|
||||
"../geometry",
|
||||
"../runtime_stage",
|
||||
|
||||
@@ -33,6 +33,11 @@ impeller_shaders("shader_fixtures") {
|
||||
}
|
||||
}
|
||||
|
||||
scene_importer("geometry_fixtures") {
|
||||
geometry = [ "flutter_logo.glb" ]
|
||||
type = "gltf"
|
||||
}
|
||||
|
||||
impellerc("runtime_stages") {
|
||||
shaders = [
|
||||
"ink_sparkle.frag",
|
||||
@@ -88,6 +93,7 @@ group("fixtures") {
|
||||
|
||||
public_deps = [
|
||||
":file_fixtures",
|
||||
":geometry_fixtures",
|
||||
":shader_fixtures",
|
||||
]
|
||||
}
|
||||
|
||||
BIN
engine/src/flutter/impeller/fixtures/flutter_logo.glb
Normal file
BIN
engine/src/flutter/impeller/fixtures/flutter_logo.glb
Normal file
Binary file not shown.
93
engine/src/flutter/impeller/scene/importer/BUILD.gn
Normal file
93
engine/src/flutter/impeller/scene/importer/BUILD.gn
Normal file
@@ -0,0 +1,93 @@
|
||||
# Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
import("//flutter/impeller/tools/impeller.gni")
|
||||
import("//flutter/shell/version/version.gni")
|
||||
import("//third_party/flatbuffers/flatbuffers.gni")
|
||||
|
||||
config("runtime_stage_config") {
|
||||
configs = [ "//flutter/impeller:impeller_public_config" ]
|
||||
include_dirs = [ "$root_gen_dir/flutter" ]
|
||||
}
|
||||
|
||||
flatbuffers("importer_flatbuffers") {
|
||||
flatbuffers = [ "mesh.fbs" ]
|
||||
public_configs = [ ":runtime_stage_config" ]
|
||||
public_deps = [ "//third_party/flatbuffers" ]
|
||||
}
|
||||
|
||||
impeller_component("importer_lib") {
|
||||
# Current versions of libcxx have deprecated some of the UTF-16 string
|
||||
# conversion APIs.
|
||||
defines = [ "_LIBCPP_DISABLE_DEPRECATION_WARNINGS" ]
|
||||
|
||||
sources = [
|
||||
"importer.h",
|
||||
"importer_gltf.cc",
|
||||
"switches.cc",
|
||||
"switches.h",
|
||||
"types.h",
|
||||
]
|
||||
|
||||
public_deps = [
|
||||
":importer_flatbuffers",
|
||||
"../../base",
|
||||
"../../compiler:utilities",
|
||||
"../../geometry",
|
||||
"//flutter/fml",
|
||||
|
||||
# All third_party deps must be reflected below in the scene_importer_license
|
||||
# target.
|
||||
# TODO(bdero): Fix tinygltf compilation warnings.
|
||||
#"//third_party/tinygltf",
|
||||
]
|
||||
}
|
||||
|
||||
generated_file("scene_importer_license") {
|
||||
source_path = rebase_path(".", "//flutter")
|
||||
git_url = "https://github.com/flutter/engine/tree/$engine_version"
|
||||
outputs = [ "$target_gen_dir/LICENSE.scene_importer.md" ]
|
||||
contents = [
|
||||
"# scene_importer",
|
||||
"",
|
||||
"This tool is used by the Flutter SDK to import 3D geometry.",
|
||||
"",
|
||||
"Source code for this tool: [flutter/engine/$source_path]($git_url/$source_path).",
|
||||
"",
|
||||
"## Licenses",
|
||||
"",
|
||||
"### scene_importer",
|
||||
"",
|
||||
read_file("//flutter/sky/packages/sky_engine/LICENSE", "string"),
|
||||
"",
|
||||
|
||||
# These licenses are ignored by the main license checker, since they are not
|
||||
# shipped to end-application binaries and only shipped as part of developer
|
||||
# tooling in scene_importer. Add them here.
|
||||
"## Additional open source licenses",
|
||||
"",
|
||||
"### tinygltf",
|
||||
"",
|
||||
read_file("//third_party/tinygltf/LICENSE", "string"),
|
||||
]
|
||||
}
|
||||
|
||||
group("importer") {
|
||||
deps = [
|
||||
":scene_importer",
|
||||
":scene_importer_license",
|
||||
]
|
||||
}
|
||||
|
||||
impeller_component("scene_importer") {
|
||||
target_type = "executable"
|
||||
|
||||
sources = [ "importer_main.cc" ]
|
||||
|
||||
deps = [ ":importer_lib" ]
|
||||
|
||||
metadata = {
|
||||
entitlement_file_path = [ "scene_importer" ]
|
||||
}
|
||||
}
|
||||
19
engine/src/flutter/impeller/scene/importer/importer.h
Normal file
19
engine/src/flutter/impeller/scene/importer/importer.h
Normal file
@@ -0,0 +1,19 @@
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <array>
|
||||
#include <memory>
|
||||
|
||||
#include "flutter/fml/mapping.h"
|
||||
#include "impeller/scene/importer/mesh_flatbuffers.h"
|
||||
|
||||
namespace impeller {
|
||||
namespace scene {
|
||||
namespace importer {
|
||||
|
||||
bool ParseGLTF(const fml::Mapping& source_mapping, fb::MeshT& out_mesh);
|
||||
|
||||
}
|
||||
} // namespace scene
|
||||
} // namespace impeller
|
||||
24
engine/src/flutter/impeller/scene/importer/importer_gltf.cc
Normal file
24
engine/src/flutter/impeller/scene/importer/importer_gltf.cc
Normal file
@@ -0,0 +1,24 @@
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <array>
|
||||
#include <memory>
|
||||
|
||||
#include "impeller/scene/importer/importer.h"
|
||||
|
||||
#include "flutter/fml/mapping.h"
|
||||
|
||||
namespace impeller {
|
||||
namespace scene {
|
||||
namespace importer {
|
||||
|
||||
bool ParseGLTF(const fml::Mapping& source_mapping, fb::MeshT& out_mesh) {
|
||||
// TODO(bdero): Parse source_mapping and populare out_mesh with just the first
|
||||
// mesh in the GLTF.
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace importer
|
||||
} // namespace scene
|
||||
} // namespace impeller
|
||||
108
engine/src/flutter/impeller/scene/importer/importer_main.cc
Normal file
108
engine/src/flutter/impeller/scene/importer/importer_main.cc
Normal file
@@ -0,0 +1,108 @@
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <filesystem>
|
||||
#include <memory>
|
||||
|
||||
#include "flutter/fml/backtrace.h"
|
||||
#include "flutter/fml/command_line.h"
|
||||
#include "flutter/fml/file.h"
|
||||
#include "flutter/fml/macros.h"
|
||||
#include "flutter/fml/mapping.h"
|
||||
#include "impeller/base/strings.h"
|
||||
#include "impeller/compiler/utilities.h"
|
||||
#include "impeller/scene/importer/importer.h"
|
||||
#include "impeller/scene/importer/switches.h"
|
||||
#include "impeller/scene/importer/types.h"
|
||||
|
||||
#include "third_party/flatbuffers/include/flatbuffers/flatbuffer_builder.h"
|
||||
|
||||
namespace impeller {
|
||||
namespace scene {
|
||||
namespace importer {
|
||||
|
||||
// Sets the file access mode of the file at path 'p' to 0644.
|
||||
static bool SetPermissiveAccess(const std::filesystem::path& p) {
|
||||
auto permissions =
|
||||
std::filesystem::perms::owner_read | std::filesystem::perms::owner_write |
|
||||
std::filesystem::perms::group_read | std::filesystem::perms::others_read;
|
||||
std::error_code error;
|
||||
std::filesystem::permissions(p, permissions, error);
|
||||
if (error) {
|
||||
std::cerr << "Failed to set access on file '" << p
|
||||
<< "': " << error.message() << std::endl;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Main(const fml::CommandLine& command_line) {
|
||||
fml::InstallCrashHandler();
|
||||
if (command_line.HasOption("help")) {
|
||||
Switches::PrintHelp(std::cout);
|
||||
return true;
|
||||
}
|
||||
|
||||
Switches switches(command_line);
|
||||
if (!switches.AreValid(std::cerr)) {
|
||||
std::cerr << "Invalid flags specified." << std::endl;
|
||||
Switches::PrintHelp(std::cerr);
|
||||
return false;
|
||||
}
|
||||
|
||||
auto source_file_mapping =
|
||||
fml::FileMapping::CreateReadOnly(switches.source_file_name);
|
||||
if (!source_file_mapping) {
|
||||
std::cerr << "Could not open input file." << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
fb::MeshT mesh;
|
||||
bool success = false;
|
||||
switch (switches.input_type) {
|
||||
case SourceType::kGLTF:
|
||||
success = ParseGLTF(*source_file_mapping, mesh);
|
||||
break;
|
||||
case SourceType::kUnknown:
|
||||
std::cerr << "Unknown input type." << std::endl;
|
||||
return false;
|
||||
}
|
||||
if (!success) {
|
||||
std::cerr << "Failed to parse input file." << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
flatbuffers::FlatBufferBuilder builder;
|
||||
builder.Finish(fb::Mesh::Pack(builder, &mesh));
|
||||
|
||||
auto output_file_name = std::filesystem::absolute(
|
||||
std::filesystem::current_path() / switches.output_file_name);
|
||||
fml::NonOwnedMapping mapping(builder.GetCurrentBufferPointer(),
|
||||
builder.GetSize());
|
||||
if (!fml::WriteAtomically(*switches.working_directory,
|
||||
compiler::Utf8FromPath(output_file_name).c_str(),
|
||||
mapping)) {
|
||||
std::cerr << "Could not write file to " << switches.output_file_name
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Tools that consume the geometry data expect the access mode to be 0644.
|
||||
if (!SetPermissiveAccess(output_file_name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace importer
|
||||
} // namespace scene
|
||||
} // namespace impeller
|
||||
|
||||
int main(int argc, char const* argv[]) {
|
||||
return impeller::scene::importer::Main(
|
||||
fml::CommandLineFromPlatformOrArgcArgv(argc, argv))
|
||||
? EXIT_SUCCESS
|
||||
: EXIT_FAILURE;
|
||||
}
|
||||
37
engine/src/flutter/impeller/scene/importer/mesh.fbs
Normal file
37
engine/src/flutter/impeller/scene/importer/mesh.fbs
Normal file
@@ -0,0 +1,37 @@
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
namespace impeller.fb;
|
||||
|
||||
struct Vec2 {
|
||||
x: float;
|
||||
y: float;
|
||||
}
|
||||
|
||||
struct Vec3 {
|
||||
x: float;
|
||||
y: float;
|
||||
z: float;
|
||||
}
|
||||
|
||||
struct Color {
|
||||
r: float;
|
||||
g: float;
|
||||
b: float;
|
||||
}
|
||||
|
||||
struct Vertex {
|
||||
position: Vec3;
|
||||
normal: Vec3;
|
||||
tangent: Vec3;
|
||||
texture_coords: Vec2;
|
||||
}
|
||||
|
||||
table Mesh {
|
||||
vertices: [Vertex];
|
||||
indices: [uint16];
|
||||
}
|
||||
|
||||
root_type Mesh;
|
||||
file_identifier "IPME";
|
||||
96
engine/src/flutter/impeller/scene/importer/switches.cc
Normal file
96
engine/src/flutter/impeller/scene/importer/switches.cc
Normal file
@@ -0,0 +1,96 @@
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "impeller/scene/importer/switches.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <filesystem>
|
||||
#include <map>
|
||||
|
||||
#include "flutter/fml/file.h"
|
||||
#include "impeller/compiler/utilities.h"
|
||||
#include "impeller/scene/importer/types.h"
|
||||
|
||||
namespace impeller {
|
||||
namespace scene {
|
||||
namespace importer {
|
||||
|
||||
static const std::map<std::string, SourceType> kKnownSourceTypes = {
|
||||
{"gltf", SourceType::kGLTF},
|
||||
};
|
||||
|
||||
void Switches::PrintHelp(std::ostream& stream) {
|
||||
stream << std::endl;
|
||||
stream << "Scene Importer is an offline 3D geometry file parser."
|
||||
<< std::endl;
|
||||
stream << "---------------------------------------------------------------"
|
||||
<< std::endl;
|
||||
stream << "Valid Argument are:" << std::endl;
|
||||
stream << "--input=<source_file>" << std::endl;
|
||||
stream << "[optional] --input-kind={";
|
||||
for (const auto& source_type : kKnownSourceTypes) {
|
||||
stream << source_type.first << ", ";
|
||||
}
|
||||
stream << "} (default: gltf)" << std::endl;
|
||||
stream << "--output=<output_file>" << std::endl;
|
||||
}
|
||||
|
||||
Switches::Switches() = default;
|
||||
|
||||
Switches::~Switches() = default;
|
||||
|
||||
static SourceType SourceTypeFromCommandLine(
|
||||
const fml::CommandLine& command_line) {
|
||||
auto source_type_option =
|
||||
command_line.GetOptionValueWithDefault("input-type", "gltf");
|
||||
auto source_type_search = kKnownSourceTypes.find(source_type_option);
|
||||
if (source_type_search == kKnownSourceTypes.end()) {
|
||||
return SourceType::kUnknown;
|
||||
}
|
||||
return source_type_search->second;
|
||||
}
|
||||
|
||||
Switches::Switches(const fml::CommandLine& command_line)
|
||||
: working_directory(std::make_shared<fml::UniqueFD>(fml::OpenDirectory(
|
||||
compiler::Utf8FromPath(std::filesystem::current_path()).c_str(),
|
||||
false, // create if necessary,
|
||||
fml::FilePermission::kRead))),
|
||||
source_file_name(command_line.GetOptionValueWithDefault("input", "")),
|
||||
input_type(SourceTypeFromCommandLine(command_line)),
|
||||
output_file_name(command_line.GetOptionValueWithDefault("output", "")) {
|
||||
if (!working_directory || !working_directory->is_valid()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool Switches::AreValid(std::ostream& explain) const {
|
||||
bool valid = true;
|
||||
|
||||
if (input_type == SourceType::kUnknown) {
|
||||
explain << "Unknown input type." << std::endl;
|
||||
valid = false;
|
||||
}
|
||||
|
||||
if (!working_directory || !working_directory->is_valid()) {
|
||||
explain << "Could not figure out working directory." << std::endl;
|
||||
valid = false;
|
||||
}
|
||||
|
||||
if (source_file_name.empty()) {
|
||||
explain << "Input file name was empty." << std::endl;
|
||||
valid = false;
|
||||
}
|
||||
|
||||
if (output_file_name.empty()) {
|
||||
explain << "Target output file name was empty." << std::endl;
|
||||
valid = false;
|
||||
}
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
} // namespace importer
|
||||
} // namespace scene
|
||||
} // namespace impeller
|
||||
38
engine/src/flutter/impeller/scene/importer/switches.h
Normal file
38
engine/src/flutter/impeller/scene/importer/switches.h
Normal file
@@ -0,0 +1,38 @@
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
|
||||
#include "flutter/fml/command_line.h"
|
||||
#include "flutter/fml/macros.h"
|
||||
#include "flutter/fml/unique_fd.h"
|
||||
#include "impeller/scene/importer/types.h"
|
||||
|
||||
namespace impeller {
|
||||
namespace scene {
|
||||
namespace importer {
|
||||
|
||||
struct Switches {
|
||||
std::shared_ptr<fml::UniqueFD> working_directory;
|
||||
std::string source_file_name;
|
||||
SourceType input_type;
|
||||
std::string output_file_name;
|
||||
|
||||
Switches();
|
||||
|
||||
~Switches();
|
||||
|
||||
explicit Switches(const fml::CommandLine& command_line);
|
||||
|
||||
bool AreValid(std::ostream& explain) const;
|
||||
|
||||
static void PrintHelp(std::ostream& stream);
|
||||
};
|
||||
|
||||
} // namespace importer
|
||||
} // namespace scene
|
||||
} // namespace impeller
|
||||
18
engine/src/flutter/impeller/scene/importer/types.h
Normal file
18
engine/src/flutter/impeller/scene/importer/types.h
Normal file
@@ -0,0 +1,18 @@
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace impeller {
|
||||
namespace scene {
|
||||
namespace importer {
|
||||
|
||||
enum class SourceType {
|
||||
kUnknown,
|
||||
kGLTF,
|
||||
};
|
||||
|
||||
} // namespace importer
|
||||
} // namespace scene
|
||||
} // namespace impeller
|
||||
@@ -24,6 +24,11 @@ declare_args() {
|
||||
# If it is non-empty, it should be the absolute path to impellerc.
|
||||
impeller_use_prebuilt_impellerc = ""
|
||||
|
||||
# Whether to use a prebuilt scene_importer.
|
||||
# If this is the empty string, scene_importer will be built.
|
||||
# If it is non-empty, it should be the absolute path to scene_importer.
|
||||
impeller_use_prebuilt_scene_importer = ""
|
||||
|
||||
# If enabled, all OpenGL calls will be traced. Because additional trace
|
||||
# overhead may be substantial, this is not enabled by default.
|
||||
impeller_trace_all_gl_calls = false
|
||||
@@ -613,3 +618,47 @@ template("impeller_shaders") {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Dispatches to the build or prebuilt scene_importer depending on the value of
|
||||
# the impeller_use_prebuilt_scene_importer argument. Forwards all variables to
|
||||
# compiled_action_foreach or action_foreach as appropriate.
|
||||
template("_scene_importer") {
|
||||
if (impeller_use_prebuilt_scene_importer == "") {
|
||||
compiled_action_foreach(target_name) {
|
||||
forward_variables_from(invoker, "*")
|
||||
tool = "//flutter/impeller/scene/importer:scene_importer"
|
||||
}
|
||||
} else {
|
||||
action_foreach(target_name) {
|
||||
forward_variables_from(invoker, "*", [ "args" ])
|
||||
script = "//build/gn_run_binary.py"
|
||||
scene_importer_path =
|
||||
rebase_path(impeller_use_prebuilt_scene_importer, root_build_dir)
|
||||
args = [ scene_importer_path ] + invoker.args
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template("scene_importer") {
|
||||
assert(defined(invoker.geometry), "Geometry input files must be specified.")
|
||||
assert(defined(invoker.type),
|
||||
"The type of geometry to be parsed (gltf, etc..).")
|
||||
|
||||
_scene_importer(target_name) {
|
||||
sources = invoker.geometry
|
||||
generated_dir = "$target_gen_dir"
|
||||
|
||||
input_type = invoker.type
|
||||
args = [
|
||||
"--input={{source}}",
|
||||
"--input-type=$input_type",
|
||||
]
|
||||
|
||||
output = "$generated_dir/{{source_file_part}}.ipmesh"
|
||||
output_path = rebase_path(output, root_build_dir)
|
||||
|
||||
args += [ "--output=$output_path" ]
|
||||
|
||||
outputs = [ output ]
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user