blob: 453d1036faafd9637440e275743b04451338ba94 [file] [log] [blame]
// Copyright 2018 The Fuchsia 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 <memory>
#include "lib/ui/scenic/cpp/commands.h"
#include "lib/ui/scenic/cpp/resources.h"
namespace scenic {
namespace mesh_utils {
std::unique_ptr<Mesh> NewMeshWithVertices(
Session* session, const std::vector<float>& vertices,
const std::vector<uint32_t>& indices) {
auto mesh = std::make_unique<Mesh>(session);
ZX_DEBUG_ASSERT(vertices.size() % 3 == 0);
const uint64_t num_vertices = vertices.size() / 3;
ZX_DEBUG_ASSERT(*std::max_element(indices.begin(), indices.end()) <
num_vertices);
// TODO(SCN-558) vertex_elements should be 3.
uint64_t vertex_elements = 5;
uint64_t vertex_size = vertex_elements * sizeof(float);
uint64_t vertex_buffer_size = num_vertices * vertex_size;
uint64_t index_buffer_size = indices.size() * sizeof(uint32_t);
// TODO(SCN-558) This whole block is a workaround and should be removed.
std::vector<float> vertices_scn_558;
vertices_scn_558.reserve(vertex_buffer_size / sizeof(float));
for (uint64_t i = 0; i < num_vertices; i++) {
const float* vertex_in = vertices.data() + i * 3;
float* vertex_out = vertices_scn_558.data() + i * vertex_elements;
vertex_out[0] = vertex_in[0];
vertex_out[1] = vertex_in[1];
vertex_out[2] = vertex_in[2];
vertex_out[3] = 0;
vertex_out[4] = 0;
}
// END TODO(SCN-558)
// Copy data to VMO and create buffers
uint64_t vmo_size = vertex_buffer_size + index_buffer_size;
zx::vmo vmo;
zx_status_t status;
status = zx::vmo::create(vmo_size, 0u, &vmo);
// TODO(SCN-558) uses vertices.data()
status = vmo.write(vertices_scn_558.data(), 0, vertex_buffer_size);
ZX_DEBUG_ASSERT(status == ZX_OK);
status = vmo.write(indices.data(), vertex_buffer_size, index_buffer_size);
ZX_DEBUG_ASSERT(status == ZX_OK);
Memory mem(session, std::move(vmo), vmo_size,
fuchsia::images::MemoryType::VK_DEVICE_MEMORY);
Buffer vertex_buffer(mem, 0, vertex_buffer_size);
Buffer index_buffer(mem, vertex_buffer_size, index_buffer_size);
auto vertex_format = NewMeshVertexFormat(
fuchsia::ui::gfx::ValueType::kVector3, fuchsia::ui::gfx::ValueType::kNone,
fuchsia::ui::gfx::ValueType::kVector2);
// Compute bounding box.
std::vector<float> bounding_box_min;
std::vector<float> bounding_box_max;
for (int i = 0; i < 3; i++) {
bounding_box_min.push_back(std::numeric_limits<float>::max());
bounding_box_max.push_back(std::numeric_limits<float>::min());
}
for (uint64_t i = 0; i < num_vertices; i++) {
const float* vertex = vertices.data() + i * 3;
bounding_box_min[0] = std::min(bounding_box_min[0], vertex[0]);
bounding_box_min[1] = std::min(bounding_box_min[1], vertex[1]);
bounding_box_min[2] = std::min(bounding_box_min[2], vertex[2]);
bounding_box_max[0] = std::max(bounding_box_max[0], vertex[0]);
bounding_box_max[1] = std::max(bounding_box_max[1], vertex[1]);
bounding_box_max[2] = std::max(bounding_box_max[2], vertex[2]);
}
// Bind buffers.
mesh->BindBuffers(index_buffer, fuchsia::ui::gfx::MeshIndexFormat::kUint32, 0,
indices.size(), vertex_buffer, std::move(vertex_format), 0,
num_vertices, bounding_box_min.data(),
bounding_box_max.data());
return mesh;
}
} // namespace mesh_utils
} // namespace scenic