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:
2013-05-06 12:58:57 -07:00
parent cfa1f35088
commit 8be1aff1ba
11 changed files with 118 additions and 22 deletions

View File

@@ -104,6 +104,11 @@ void KRAudioManager::initAudio()
}
}
unordered_map<std::string, KRAudioSample *> &KRAudioManager::getSounds()
{
return m_sounds;
}
bool KRAudioManager::getEnableAudio()
{
return m_enable_audio;

View File

@@ -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);

View File

@@ -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);

View File

@@ -72,6 +72,8 @@ public:
long getAbsoluteTimeMilliseconds();
std::vector<KRResource *> getResources();
private:
KRBundleManager *m_pBundleManager;
KRSceneManager *m_pSceneManager;

View File

@@ -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);

View File

@@ -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;

View File

@@ -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];

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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();

View File

@@ -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;
};