Added IciclePyramidBananas example

This commit is contained in:
David
2024-04-10 15:02:22 -04:00
parent aa3623095b
commit d1e2261ea7
13 changed files with 3920 additions and 69 deletions
@@ -8,6 +8,10 @@
#include "helpers/c/cStructGltfHelper.h"
void search_for_objects_node() {
}
BuildObjectMap::BuildObjectMap(DkrAssetsSettings &settings, BuildInfo &info) : _settings(settings), _info(info) {
_preload_c_context();
@@ -23,8 +27,14 @@ BuildObjectMap::BuildObjectMap(DkrAssetsSettings &settings, BuildInfo &info) : _
GltfFile gltf(gltfPath);
int objectsNodeIndex;
DebugHelper::assert_(gltf.search_for_node_by_name("objects", objectsNodeIndex),
"(BuildObjectMap::BuildObjectMap) .glTF file does not contain a node named \"objects\"!");
GltfFileNode *objectsNode = gltf.get_node(objectsNodeIndex);
// _calculate_size() also fills the `_objectIdToStructCache` map.
size_t dataSize = _calculate_size(gltf);
size_t dataSize = _calculate_size(objectsNode);
size_t outSize = DataHelper::align8(dataSize + sizeof(LevelObjectMapHeader));
@@ -36,11 +46,15 @@ BuildObjectMap::BuildObjectMap(DkrAssetsSettings &settings, BuildInfo &info) : _
objectMap->header.fileSize = dataSize;
uint8_t *bytes = &objectMap->entriesData[0];
int numberOfNodes = gltf.get_node_count();
int numberOfChildNodes = objectsNode->get_child_count();
// Node 0 is the root node, so we want to start at node 1.
for(int i = 1; i < numberOfNodes; i++) {
std::string objectBuildId = gltf.get_node_extra<std::string>(i, "id", "");
for(int i = 0; i < numberOfChildNodes; i++) {
GltfFileNode *objNode = objectsNode->get_child_node_by_index(i);
std::string objectBuildId = objNode->get_extra<std::string>("id", "");
DebugHelper::assert_(!objectBuildId.empty(), "(BuildObjectMap::BuildObjectMap) Node", i,
" does not have id defined!");
int id = _transTable->get_index_of_elem_in_array<std::string>("/table", objectBuildId);
@@ -64,12 +78,12 @@ BuildObjectMap::BuildObjectMap(DkrAssetsSettings &settings, BuildInfo &info) : _
entryCommon = _c_context.get_struct("LevelObjectEntryCommon");
}
_set_obj_position(gltf, bytes, entryCommon, i);
_set_obj_position(objNode, bytes, entryCommon, i);
if(entryCommon != entryStruct) {
for(size_t entry = 0; entry < entryStruct->entry_count(); entry++) {
CStructEntry *structMember = entryStruct->get_entry(entry);
CStructGltfHelper::put_gltf_node_extra_into_struct_entry(_settings, structMember, gltf, i, bytes);
CStructGltfHelper::put_gltf_node_extra_into_struct_entry(_settings, structMember, objNode, bytes);
}
}
@@ -92,13 +106,13 @@ BuildObjectMap::~BuildObjectMap() {
}
void BuildObjectMap::_set_obj_position(GltfFile &gltf, uint8_t *bytes, CStruct *entryCommon, int nodeIndex) {
void BuildObjectMap::_set_obj_position(GltfFileNode *objNode, uint8_t *bytes, CStruct *entryCommon, int nodeIndex) {
CStructEntry *memberX = entryCommon->get_entry(2);
CStructEntry *memberY = entryCommon->get_entry(3);
CStructEntry *memberZ = entryCommon->get_entry(4);
double scaledX, scaledY, scaledZ;
gltf.get_node_position(nodeIndex, scaledX, scaledY, scaledZ);
objNode->get_position(scaledX, scaledY, scaledZ);
int xPos = _settings.adjust_from_model_scale(scaledX);
int yPos = _settings.adjust_from_model_scale(scaledY);
@@ -109,18 +123,17 @@ void BuildObjectMap::_set_obj_position(GltfFile &gltf, uint8_t *bytes, CStruct *
memberZ->set_integer_to_data(bytes, zPos);
}
size_t BuildObjectMap::_calculate_size(GltfFile &gltf) {
size_t BuildObjectMap::_calculate_size(GltfFileNode *objectsNode) {
size_t out = 0;
int numberOfNodes = gltf.get_node_count();
int numberOfChildNodes = objectsNode->get_child_count();
// Node 0 is the root node, so we want to start at node 1.
for(int i = 1; i < numberOfNodes; i++) {
std::string objectBuildId = gltf.get_node_extra<std::string>(i, "id", "");
for(int i = 0; i < numberOfChildNodes; i++) {
GltfFileNode *objNode = objectsNode->get_child_node_by_index(i);
std::string objectBuildId = objNode->get_extra<std::string>("id", "");
DebugHelper::assert_(!objectBuildId.empty(), "(BuildObjectMap::_calculate_size) id was not defined in node ", i);
DebugHelper::assert_(!objectBuildId.empty(),
"(BuildObjectMap::_calculate_size) id was not defined in node: ", objNode->get_name());
// First check if we have already calcuated the size of this object build id.
if(_objectIdStructSizeCache.find(objectBuildId) != _objectIdStructSizeCache.end()) {
@@ -30,8 +30,8 @@ private:
JsonFile *_transTable;
JsonFile *_objBehaviorToEntryTable;
void _set_obj_position(GltfFile &gltf, uint8_t *bytes, CStruct *entryCommon, int nodeIndex);
void _set_obj_position(GltfFileNode *objNode, uint8_t *bytes, CStruct *entryCommon, int nodeIndex);
size_t _calculate_size(GltfFile &gltf);
size_t _calculate_size(GltfFileNode *objectsNode);
void _preload_c_context();
};
@@ -302,9 +302,10 @@ void CStructGltfHelper::put_struct_entry_into_gltf_node_extra(DkrAssetsSettings
}
}
void CStructGltfHelper::put_gltf_node_extra_into_struct_entry(DkrAssetsSettings &settings, CStructEntry *structMember, GltfFile &gltfFile, int gltfNode, uint8_t *bytes) {
void CStructGltfHelper::put_gltf_node_extra_into_struct_entry(DkrAssetsSettings &settings, CStructEntry *structMember, GltfFileNode *objNode, uint8_t *bytes) {
CStructEntry::InternalType internalType = structMember->get_internal_type();
StructHintType hintType = StructHintType::NO_HINT;
if(structMember->has_hint()) {
hintType = hintTypes[structMember->get_hint_type()];
}
@@ -315,17 +316,17 @@ void CStructGltfHelper::put_gltf_node_extra_into_struct_entry(DkrAssetsSettings
int value = 0;
switch(hintType) {
case StructHintType::NO_HINT:
value = gltfFile.get_node_extra<int>(gltfNode, structMember->name, 0);
value = objNode->get_extra<int>(structMember->name, 0);
break;
case StructHintType::ENUM:
{
std::string enumValue = gltfFile.get_node_extra<std::string>(gltfNode, structMember->name, "");
std::string enumValue = objNode->get_extra<std::string>(structMember->name, "");
value = get_value_from_hint_enum(structMember, enumValue);
break;
}
case StructHintType::ASSET_ID:
{
std::string buildId = gltfFile.get_node_extra<std::string>(gltfNode, structMember->name, "");
std::string buildId = objNode->get_extra<std::string>(structMember->name, "");
if(buildId.empty()) {
value = -1;
} else {
@@ -335,19 +336,19 @@ void CStructGltfHelper::put_gltf_node_extra_into_struct_entry(DkrAssetsSettings
}
case StructHintType::ANGLE:
{
double angle = gltfFile.get_node_extra<double>(gltfNode, structMember->name, 0.0);
double angle = objNode->get_extra<double>(structMember->name, 0.0);
value = get_value_from_hint_angle(structMember, angle);
break;
}
case StructHintType::SCALE:
{
double scale = gltfFile.get_node_extra<double>(gltfNode, structMember->name, 0.0);
double scale = objNode->get_extra<double>(structMember->name, 0.0);
value = get_value_from_hint_scale(structMember, scale);
break;
}
case StructHintType::OBJECT:
{
std::string buildId = gltfFile.get_node_extra<std::string>(gltfNode, structMember->name, "");
std::string buildId = objNode->get_extra<std::string>(structMember->name, "");
if(buildId.empty()) {
value = -1;
} else {
@@ -357,7 +358,7 @@ void CStructGltfHelper::put_gltf_node_extra_into_struct_entry(DkrAssetsSettings
}
case StructHintType::TIME:
{
double timeSeconds = gltfFile.get_node_extra<double>(gltfNode, structMember->name, -1.0);
double timeSeconds = objNode->get_extra<double>(structMember->name, -1.0);
if(timeSeconds == -1.0) {
value = -1;
break;
@@ -374,7 +375,7 @@ void CStructGltfHelper::put_gltf_node_extra_into_struct_entry(DkrAssetsSettings
}
case CStructEntry::InternalType::ARRAY_INTEGER:
{
tinygltf::Value::Array arrayOfValues = gltfFile.get_node_extra<tinygltf::Value::Array>(gltfNode, structMember->name, {});
tinygltf::Value::Array arrayOfValues = objNode->get_extra<tinygltf::Value::Array>(structMember->name, {});
std::vector<int64_t> values;
for(tinygltf::Value &val : arrayOfValues) {
switch(hintType) {
@@ -11,6 +11,5 @@ public:
int gltfNode, uint8_t *bytes);
// gltf node extra -> struct entry
static void put_gltf_node_extra_into_struct_entry(DkrAssetsSettings &settings, CStructEntry *structMember, GltfFile &gltfFile,
int gltfNode, uint8_t *bytes);
static void put_gltf_node_extra_into_struct_entry(DkrAssetsSettings &settings, CStructEntry *structMember, GltfFileNode *objNode, uint8_t *bytes);
};
@@ -5,6 +5,30 @@
#define TINYGLTF_USE_CPP14
#include "libs/tiny_gltf.h"
GltfFileNode::GltfFileNode(GltfFile *file, tinygltf::Node *node) : _file(file), _node(node) {
}
GltfFileNode::~GltfFileNode(){
}
size_t GltfFileNode::get_child_count() {
return _node->children.size();
}
GltfFileNode *GltfFileNode::get_child_node_by_index(int nodeIndex) {
return _file->get_node(_node->children[nodeIndex]);
}
void GltfFileNode::get_position(double &outX, double &outY, double &outZ) {
outX = _node->translation[0];
outY = _node->translation[1];
outZ = _node->translation[2];
}
std::string GltfFileNode::get_name() {
return _node->name;
}
GltfFile::GltfFile(const fs::path &filepath) {
std::string err;
std::string warn;
@@ -24,20 +48,44 @@ GltfFile::GltfFile(const fs::path &filepath) {
}
GltfFile::~GltfFile() {
// Free node cache memory.
for (auto &pair : _nodeCache) {
if(pair.second == nullptr) {
continue;
}
delete pair.second;
}
}
int GltfFile::get_node_count() {
size_t GltfFile::get_node_count() {
return _model.nodes.size();
}
std::string GltfFile::get_node_name(int node) {
return _model.nodes[node].name;
GltfFileNode *GltfFile::get_node(int nodeIndex) {
DebugHelper::assert_(nodeIndex < (int)_model.nodes.size(),
"(GltfFile::get_node) Node index ", nodeIndex, " is out of range!");
tinygltf::Node *tinygltfNode = &_model.nodes[nodeIndex];
if(_nodeCache.find(tinygltfNode) == _nodeCache.end()) {
_nodeCache[tinygltfNode] = new GltfFileNode(this, tinygltfNode);
}
return _nodeCache[tinygltfNode];
}
void GltfFile::get_node_position(int node, double &x, double &y, double &z) {
x = _model.nodes[node].translation[0];
y = _model.nodes[node].translation[1];
z = _model.nodes[node].translation[2];
bool GltfFile::search_for_node_by_name(const std::string nodeName, int &outIndex) {
size_t numNodes = get_node_count();
for(size_t i = 0; i < numNodes; i++) {
if(_model.nodes[i].name == nodeName) {
outIndex = i;
return true;
}
}
// No node with the name was found.
outIndex = -1;
return false;
}
WriteableGltfFile::WriteableGltfFile(std::string rootName) {
@@ -5,39 +5,56 @@
#include <string>
#include "libs/tiny_gltf.h"
class GltfFile;
// Represents a node in the gltf file.
class GltfFileNode {
public:
GltfFileNode(GltfFile *file, tinygltf::Node *node);
~GltfFileNode();
size_t get_child_count();
GltfFileNode *get_child_node_by_index(int nodeIndex);
void get_position(double &outX, double &outY, double &outZ);
std::string get_name();
template <typename T>
T get_extra(std::string key, T defaultValue) {
if(!_node->extras.IsObject()) {
// This node does not have any extras, just return the default value.
return defaultValue;
}
if(!_node->extras.Has(key)) {
// Return default value if the key is not in the map.
return defaultValue;
}
tinygltf::Value val = _node->extras.Get(key);
return val.Get<T>();
}
private:
GltfFile *_file;
tinygltf::Node *_node;
};
// Read-Only .gltf file
class GltfFile {
public:
GltfFile(const fs::path &filepath);
~GltfFile();
// Node stuff
int get_node_count();
std::string get_node_name(int node);
void get_node_position(int node, double &x, double &y, double &z);
template <typename T>
T get_node_extra(int node, std::string key, T defaultValue) {
tinygltf::Node &gltfNode = _model.nodes[node];
if(!gltfNode.extras.IsObject()) {
// This node does not have any extras, just return the default value.
return defaultValue;
}
if(!gltfNode.extras.Has(key)) {
// Return default value if the key is not in the map.
return defaultValue;
}
tinygltf::Value val = gltfNode.extras.Get(key);
return val.Get<T>();
}
size_t get_node_count();
GltfFileNode *get_node(int nodeIndex);
bool search_for_node_by_name(const std::string nodeName, int &outIndex);
private:
tinygltf::Model _model;
tinygltf::TinyGLTF _tinygltf;
std::unordered_map<tinygltf::Node *, GltfFileNode *> _nodeCache;
};
// Write-Only .gltf file