Language: C++
The following example leverages the feature of adding textures to discrete faces of a shell:
#include <string>
#include "hoops_license.h"
#include "sc_store.h"
#include "sc_assemblytree.h"
#include "ginger_bread_jpg.h"
class ApplicationLogger: public SC::Store::Logger {
public:
virtual void
Message(const char* message) const
{
printf("%s\n", message);
}
};
static void
AddSquareFace(SC::Store::Mesh& mesh, uint32_t const* point_indices, uint32_t const* uv_indices)
{
mesh.face_elements.emplace_back();
SC::Store::MeshElement& face = mesh.face_elements.back();
// Add first face triangle
for (size_t i = 0; i < 3; ++i) {
face.indices.push_back(point_indices[i]);
face.indices.push_back(uv_indices[i]);
}
// Add second face triangle
for (size_t i = 0; i < 3; ++i) {
auto index = (i + 2) % 4;
face.indices.push_back(point_indices[index]);
face.indices.push_back(uv_indices[index]);
}
}
static SC::Store::MeshKey
CreateCubeMesh(SC::Store::Model& model)
{
using SC::Store::Mesh;
Mesh mesh;
mesh.flags = (Mesh::Bits)(Mesh::ClockwiseWinding | Mesh::Manifold | Mesh::FaceUVs);
SC::Store::Point points[] = {
{ 0, 0, 1 }, // 0
{ 1, 0, 1 }, // 1
{ 0, 0, 0 }, // 2
{ 1, 0, 0 }, // 3
{ 1, 1, 1 }, // 4
{ 1, 1, 0 }, // 5
{ 0, 1, 1 }, // 6
{ 0, 1, 0 }, // 7
};
SC::Store::UV uvs[] = {
{ 0, 0 }, // 0
{ 1, 0 }, // 1
{ 1, 1 }, // 2
{ 0, 1 }, // 3
};
mesh.points = points;
mesh.point_count = 8;
mesh.uvs = uvs;
mesh.uv_count = 4;
uint32_t uv_indices[] = { 0, 1, 2, 3 };
{
uint32_t point_indices[] = { 0, 1, 3, 2 };
AddSquareFace(mesh, point_indices, uv_indices);
}
{
uint32_t point_indices[] = { 6, 4, 1, 0 };
AddSquareFace(mesh, point_indices, uv_indices);
}
{
uint32_t point_indices[] = { 7, 5, 4, 6 };
AddSquareFace(mesh, point_indices, uv_indices);
}
{
uint32_t point_indices[] = { 2, 3, 5, 7 };
AddSquareFace(mesh, point_indices, uv_indices);
}
{
uint32_t point_indices[] = { 1, 4, 5, 3 };
AddSquareFace(mesh, point_indices, uv_indices);
}
{
uint32_t point_indices[] = { 6, 0, 2, 7 };
AddSquareFace(mesh, point_indices, uv_indices);
}
{
// Create a material map to color 5 of the 6 cube faces.
// The 6th face will get colored by the instance material.
SC::Store::Color colors[] = {
SC::Store::Color(1.0f, 0.0f, 0.0f, 1.0f), //
SC::Store::Color(0.0f, 1.0f, 0.0f, 1.0f), //
SC::Store::Color(0.0f, 0.0f, 1.0f, 1.0f), //
SC::Store::Color(1.0f, 0.0f, 1.0f, 1.0f), //
};
SC::Store::MaterialKeys material_keys;
for (SC::Store::Color const& color: colors) {
material_keys.push_back(model.Insert(color));
}
{
SC::Store::ImageKey image_key_jpeg =
model.Insert(ginger_bread_jpg_size, ginger_bread_jpg, SC::Store::ImageFormat::JPEG);
uint32_t const packedFlags = SC::Store::Texture::PackFlags(
SC::Store::Texture::Clamp, SC::Store::Texture::InterpolationOn,
SC::Store::Texture::MipMappingOn, SC::Store::Texture::UV, SC::Store::Texture::None);
SC::Store::Material material;
material.diffuse_textures.push_back(
SC::Store::Texture(image_key_jpeg, SC::Store::MatrixKey(), packedFlags));
material_keys.push_back(model.Insert(material));
}
mesh.mesh_face_element_material_map = model.Insert(material_keys);
}
return model.Insert(mesh);
}
int
MaterialMapSample(const std::string& model_path)
{
std::string model_name = "material_map_sample";
ApplicationLogger logger;
try {
// Open the cache.
SC::Store::Database::SetLicense(HOOPS_LICENSE);
SC::Store::Cache cache = SC::Store::Database::Open(logger);
std::string file_path_string = model_path;
file_path_string += "/";
file_path_string += model_name;
// Does the model in question exist?
if (cache.Exists(file_path_string.c_str())) {
printf("Model already exists.\n");
return 1;
}
// Create and open the model we care about.
SC::Store::Model model = cache.Open(file_path_string.c_str());
model.Include(model);
SC::Store::MeshKey mesh_key = CreateCubeMesh(model);
{
SC::Store::Matrix3d matrix = {
1, 0, 0, //
0, 1, 0, //
0, 0, 1, //
0, 0, 0, //
};
SC::Store::MatrixKey matrix_key = model.Insert(matrix);
SC::Store::Color color(
0, 0, 0,
1); // Colors the instance's face that does not have a material map applied.
SC::Store::MaterialKey material_key = model.Insert(color);
model.Instance(mesh_key, matrix_key, material_key, material_key);
}
// Prepare the model for streaming.
model.PrepareStream();
} catch (std::exception const& e) {
std::string message("Exception: ");
message.append(e.what());
message.append("\n");
logger.Message(message.c_str());
return 1;
}
return 0;
}
Also attaching the .cpp file which can be transferred to the following directory to replace the existing libsc example:
HOOPS_Communicator_2021_SP1\authoring\libsc\examples
sc_store_material_map.cpp (5.5 KB)
This is a screenshot of the resulting single-face textured cube as viewed in the Web Viewer: