Implemented KRContext::getResources
FBX Importing toolchain now detects need for vertex tangent vectors based on presence of Normal maps, and only imports them when needed. If tangent vectors are needed, but not present in the FBX file, they are calculated during the import process. Importing tangents increases the size of the vertex data and reduces the ability to share vertexes for multiple faces when using indexed triangle rendering; therefore, they are imported sparingly.
This commit is contained in:
@@ -104,6 +104,11 @@ void KRAudioManager::initAudio()
|
||||
}
|
||||
}
|
||||
|
||||
unordered_map<std::string, KRAudioSample *> &KRAudioManager::getSounds()
|
||||
{
|
||||
return m_sounds;
|
||||
}
|
||||
|
||||
bool KRAudioManager::getEnableAudio()
|
||||
{
|
||||
return m_enable_audio;
|
||||
|
||||
@@ -80,6 +80,8 @@ public:
|
||||
KRAudioManager(KRContext &context);
|
||||
virtual ~KRAudioManager();
|
||||
|
||||
unordered_map<std::string, KRAudioSample *> &getSounds();
|
||||
|
||||
void add(KRAudioSample *Sound);
|
||||
|
||||
KRAudioSample *load(const std::string &name, const std::string &extension, KRDataBlock *data);
|
||||
|
||||
@@ -131,6 +131,45 @@ KRUnknownManager *KRContext::getUnknownManager() {
|
||||
return m_pUnknownManager;
|
||||
}
|
||||
|
||||
std::vector<KRResource *> KRContext::getResources()
|
||||
{
|
||||
|
||||
std::vector<KRResource *> resources;
|
||||
|
||||
for(unordered_map<std::string, KRScene *>::iterator itr = m_pSceneManager->getScenes().begin(); itr != m_pSceneManager->getScenes().end(); itr++) {
|
||||
resources.push_back((*itr).second);
|
||||
}
|
||||
for(unordered_map<std::string, KRTexture *>::iterator itr = m_pTextureManager->getTextures().begin(); itr != m_pTextureManager->getTextures().end(); itr++) {
|
||||
resources.push_back((*itr).second);
|
||||
}
|
||||
for(unordered_map<std::string, KRMaterial *>::iterator itr = m_pMaterialManager->getMaterials().begin(); itr != m_pMaterialManager->getMaterials().end(); itr++) {
|
||||
resources.push_back((*itr).second);
|
||||
}
|
||||
for(unordered_multimap<std::string, KRMesh *>::iterator itr = m_pModelManager->getModels().begin(); itr != m_pModelManager->getModels().end(); itr++) {
|
||||
resources.push_back((*itr).second);
|
||||
}
|
||||
for(unordered_map<std::string, KRAnimation *>::iterator itr = m_pAnimationManager->getAnimations().begin(); itr != m_pAnimationManager->getAnimations().end(); itr++) {
|
||||
resources.push_back((*itr).second);
|
||||
}
|
||||
for(unordered_map<std::string, KRAnimationCurve *>::iterator itr = m_pAnimationCurveManager->getAnimationCurves().begin(); itr != m_pAnimationCurveManager->getAnimationCurves().end(); itr++) {
|
||||
resources.push_back((*itr).second);
|
||||
}
|
||||
for(unordered_map<std::string, KRAudioSample *>::iterator itr = m_pSoundManager->getSounds().begin(); itr != m_pSoundManager->getSounds().end(); itr++) {
|
||||
resources.push_back((*itr).second);
|
||||
}
|
||||
|
||||
unordered_map<std::string, unordered_map<std::string, KRUnknown *> > unknowns = m_pUnknownManager->getUnknowns();
|
||||
for(unordered_map<std::string, unordered_map<std::string, KRUnknown *> >::iterator itr = unknowns.begin(); itr != unknowns.end(); itr++) {
|
||||
for(unordered_map<std::string, KRUnknown *>::iterator itr2 = (*itr).second.begin(); itr2 != (*itr).second.end(); itr++) {
|
||||
resources.push_back((*itr2).second);
|
||||
}
|
||||
}
|
||||
|
||||
// FINDME, TODO - Not yet exporting shaders, as they are currently only being used as standard Kraken assets. In the future people may want their custom shaders to be exported.
|
||||
|
||||
return resources;
|
||||
}
|
||||
|
||||
void KRContext::loadResource(const std::string &file_name, KRDataBlock *data) {
|
||||
std::string name = KRResource::GetFileBase(file_name);
|
||||
std::string extension = KRResource::GetFileExtension(file_name);
|
||||
|
||||
@@ -72,6 +72,8 @@ public:
|
||||
|
||||
long getAbsoluteTimeMilliseconds();
|
||||
|
||||
std::vector<KRResource *> getResources();
|
||||
|
||||
private:
|
||||
KRBundleManager *m_pBundleManager;
|
||||
KRSceneManager *m_pSceneManager;
|
||||
|
||||
@@ -75,6 +75,11 @@ std::string KRMaterial::getExtension() {
|
||||
return "mtl";
|
||||
}
|
||||
|
||||
bool KRMaterial::needsVertexTangents()
|
||||
{
|
||||
return m_normalMap.size() > 0;
|
||||
}
|
||||
|
||||
bool KRMaterial::save(KRDataBlock &data) {
|
||||
std::stringstream stream;
|
||||
stream.precision(std::numeric_limits<long double>::digits10);
|
||||
|
||||
@@ -85,6 +85,8 @@ public:
|
||||
|
||||
bool bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, KRCamera *pCamera, std::vector<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&spot_lights, const std::vector<KRBone *> &bones, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass);
|
||||
|
||||
bool needsVertexTangents();
|
||||
|
||||
private:
|
||||
std::string m_name;
|
||||
|
||||
|
||||
@@ -44,6 +44,11 @@ KRMaterialManager::~KRMaterialManager() {
|
||||
}
|
||||
|
||||
|
||||
unordered_map<std::string, KRMaterial *> &KRMaterialManager::getMaterials()
|
||||
{
|
||||
return m_materials;
|
||||
}
|
||||
|
||||
void KRMaterialManager::configure(bool blend_enable, GLenum blend_src, GLenum blend_dest, bool depth_test_enable, GLenum depth_func, bool depth_write_enable) {
|
||||
if(blend_enable) {
|
||||
GLDEBUG(glEnable(GL_BLEND));
|
||||
@@ -67,21 +72,31 @@ void KRMaterialManager::configure(bool blend_enable, GLenum blend_src, GLenum bl
|
||||
}
|
||||
|
||||
|
||||
KRMaterial *KRMaterialManager::getMaterial(const char *szName) {
|
||||
std::string lowerName = szName;
|
||||
KRMaterial *KRMaterialManager::getMaterial(const std::string &name) {
|
||||
std::string lowerName = name;
|
||||
std::transform(lowerName.begin(), lowerName.end(),
|
||||
lowerName.begin(), ::tolower);
|
||||
|
||||
|
||||
unordered_map<std::string, KRMaterial *>::iterator itr = m_materials.find(lowerName);
|
||||
if(itr == m_materials.end()) {
|
||||
fprintf(stderr, "Material not found: %s\n", szName);
|
||||
fprintf(stderr, "Material not found: %s\n", name.c_str());
|
||||
// Not found
|
||||
return NULL;
|
||||
} else {
|
||||
return (*itr).second;
|
||||
}
|
||||
}
|
||||
|
||||
void KRMaterialManager::add(KRMaterial *new_material) {
|
||||
// FINDME, TODO - Potential memory leak if multiple materials with the same name are added
|
||||
std::string lowerName = new_material->getName();
|
||||
std::transform(lowerName.begin(), lowerName.end(),
|
||||
lowerName.begin(), ::tolower);
|
||||
|
||||
m_materials[lowerName] = new_material;
|
||||
}
|
||||
|
||||
bool KRMaterialManager::load(const char *szName, KRDataBlock *data) {
|
||||
KRMaterial *pMaterial = NULL;
|
||||
char szSymbol[16][256];
|
||||
|
||||
@@ -50,10 +50,14 @@ public:
|
||||
virtual ~KRMaterialManager();
|
||||
|
||||
bool load(const char *szName, KRDataBlock *data);
|
||||
KRMaterial *getMaterial(const char *szName);
|
||||
void add(KRMaterial *new_material);
|
||||
KRMaterial *getMaterial(const std::string &name);
|
||||
|
||||
void configure(bool blend_enable, GLenum blend_src, GLenum blend_dest, bool depth_test_enable, GLenum depth_func, bool depth_write_enable);
|
||||
|
||||
|
||||
unordered_map<std::string, KRMaterial *> &getMaterials();
|
||||
|
||||
private:
|
||||
unordered_map<std::string, KRMaterial *> m_materials;
|
||||
KRTextureManager *m_pTextureManager;
|
||||
|
||||
@@ -122,6 +122,15 @@ std::vector<KRResource *> KRResource::LoadFbx(KRContext &context, const std::str
|
||||
}
|
||||
}
|
||||
|
||||
// ----====---- Import Materials ----====----
|
||||
int material_count = pFbxScene->GetSrcObjectCount<FbxSurfaceMaterial>();
|
||||
printf("\nLoading materials...\n");
|
||||
for(int i=0; i < material_count; i++) {
|
||||
FbxSurfaceMaterial *material = pFbxScene->GetSrcObject<FbxSurfaceMaterial>(i);
|
||||
printf(" Material %i of %i: %s\n", i+1, material_count, material->GetName());
|
||||
LoadMaterial(context, resources, material);
|
||||
}
|
||||
|
||||
// ----====---- Import Meshes ----====----
|
||||
int mesh_count = pFbxScene->GetSrcObjectCount<FbxMesh>();
|
||||
printf("\nLoading meshes...\n");
|
||||
@@ -132,15 +141,6 @@ std::vector<KRResource *> KRResource::LoadFbx(KRContext &context, const std::str
|
||||
LoadMesh(context, resources, pGeometryConverter, mesh);
|
||||
}
|
||||
|
||||
// ----====---- Import Materials ----====----
|
||||
int material_count = pFbxScene->GetSrcObjectCount<FbxSurfaceMaterial>();
|
||||
printf("\nLoading materials...\n");
|
||||
for(int i=0; i < material_count; i++) {
|
||||
FbxSurfaceMaterial *material = pFbxScene->GetSrcObject<FbxSurfaceMaterial>(i);
|
||||
printf(" Material %i of %i: %s\n", i+1, material_count, material->GetName());
|
||||
LoadMaterial(context, resources, material);
|
||||
}
|
||||
|
||||
// ----====---- Import Textures ----====----
|
||||
int texture_count = pFbxScene->GetSrcObjectCount<FbxFileTexture>();
|
||||
|
||||
@@ -162,13 +162,8 @@ std::vector<KRResource *> KRResource::LoadFbx(KRContext &context, const std::str
|
||||
}
|
||||
}
|
||||
|
||||
for(unordered_map<std::string, KRTexture *>::iterator texture_itr = context.getTextureManager()->getTextures().begin(); texture_itr != context.getTextureManager()->getTextures().end(); texture_itr++) {
|
||||
resources.push_back((*texture_itr).second);
|
||||
}
|
||||
|
||||
for(unordered_map<std::string, KRMesh *>::iterator mesh_itr = context.getModelManager()->getModels().begin(); mesh_itr != context.getModelManager()->getModels().end(); mesh_itr++) {
|
||||
resources.push_back((*mesh_itr).second);
|
||||
}
|
||||
std::vector<KRResource *> resources2 = context.getResources();
|
||||
resources.insert(resources.begin(), resources2.begin(), resources2.end());
|
||||
|
||||
DestroySdkObjects(lSdkManager);
|
||||
|
||||
@@ -1044,6 +1039,7 @@ void LoadMaterial(KRContext &context, std::vector<KRResource *> &resources, FbxS
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
bool bFound = false;
|
||||
for(vector<KRResource *>::iterator resource_itr = resources.begin(); resource_itr != resources.end(); resource_itr++) {
|
||||
KRResource *pResource = (*resource_itr);
|
||||
@@ -1056,7 +1052,16 @@ void LoadMaterial(KRContext &context, std::vector<KRResource *> &resources, FbxS
|
||||
} else {
|
||||
resources.push_back(new_material);
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
|
||||
// Only save unique materials
|
||||
KRMaterial *found_material = context.getMaterialManager()->getMaterial(new_material->getName());
|
||||
if(found_material == NULL) {
|
||||
context.getMaterialManager()->add(new_material);
|
||||
} else {
|
||||
delete new_material;
|
||||
}
|
||||
}
|
||||
|
||||
void LoadMesh(KRContext &context, std::vector<KRResource *> &resources, FbxGeometryConverter *pGeometryConverter, KFbxMesh* pSourceMesh) {
|
||||
@@ -1162,8 +1167,18 @@ void LoadMesh(KRContext &context, std::vector<KRResource *> &resources, FbxGeome
|
||||
|
||||
int dest_vertex_id = 0;
|
||||
|
||||
bool need_tangents = false;
|
||||
|
||||
for(int iMaterial=0; iMaterial < material_count; iMaterial++) {
|
||||
KFbxSurfaceMaterial *pMaterial = pSourceMesh->GetNode()->GetMaterial(iMaterial);
|
||||
|
||||
KRMaterial *material = context.getMaterialManager()->getMaterial(pMaterial->GetName());
|
||||
if(material) {
|
||||
if(material->needsVertexTangents()) {
|
||||
need_tangents = true;
|
||||
}
|
||||
}
|
||||
|
||||
int source_vertex_id = 0;
|
||||
int mat_vertex_count = 0;
|
||||
int mat_vertex_start = dest_vertex_id;
|
||||
@@ -1294,7 +1309,7 @@ void LoadMesh(KRContext &context, std::vector<KRResource *> &resources, FbxGeome
|
||||
KRMesh *new_mesh = new KRMesh(context, pSourceMesh->GetNode()->GetName());
|
||||
std::vector<__uint16_t> vertex_indexes;
|
||||
std::vector<std::pair<int, int> > vertex_index_bases;
|
||||
new_mesh->LoadData(vertex_indexes, vertex_index_bases, vertices, uva, uvb, normals, tangents, submesh_starts, submesh_lengths, material_names, bone_names, bone_indexes, bone_weights,KRMesh::KRENGINE_MODEL_FORMAT_TRIANGLES, true, false); // FINDME, HACK! "false" set for importing tangents so that we can merge more vertices in the index buffer. This should be configurable by the end-user so if normal maps are required and no tangents are included in the model, they can be calculated
|
||||
new_mesh->LoadData(vertex_indexes, vertex_index_bases, vertices, uva, uvb, normals, tangents, submesh_starts, submesh_lengths, material_names, bone_names, bone_indexes, bone_weights,KRMesh::KRENGINE_MODEL_FORMAT_TRIANGLES, true, need_tangents);
|
||||
|
||||
context.getModelManager()->addModel(new_mesh);
|
||||
}
|
||||
|
||||
@@ -46,6 +46,11 @@ KRUnknownManager::~KRUnknownManager()
|
||||
}
|
||||
}
|
||||
|
||||
unordered_map<std::string, unordered_map<std::string, KRUnknown *> > &KRUnknownManager::getUnknowns()
|
||||
{
|
||||
return m_unknowns;
|
||||
}
|
||||
|
||||
void KRUnknownManager::add(KRUnknown *unknown)
|
||||
{
|
||||
std::string lower_name = unknown->getName();
|
||||
|
||||
@@ -51,6 +51,8 @@ public:
|
||||
|
||||
const unordered_map<std::string, KRUnknown *> &get(const std::string &extension);
|
||||
|
||||
unordered_map<std::string, unordered_map<std::string, KRUnknown *> > &getUnknowns();
|
||||
|
||||
private:
|
||||
unordered_map<std::string, unordered_map<std::string, KRUnknown *> > m_unknowns;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user