Browse Source

Issue #652 - Imported model normals seem to always be on the convex side of the model

Created a config file to set the fixInfacingNormals flag off when importing a model. Default behaviour leaves the flag on.
raheelx 9 years ago
parent
commit
fd0743f4c8

+ 167 - 0
Source/Atomic/Resource/ImportConfig.cpp

@@ -0,0 +1,167 @@
+//
+// Copyright (c) 2014-2015, THUNDERBEAST GAMES LLC All rights reserved
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#include "../Core/Context.h"
+#include "../IO/Log.h"
+#include "../IO/File.h"
+#include "../IO/FileSystem.h"
+#include "JSONFile.h"
+#include "../Graphics/GraphicsDefs.h"
+#include "ImportConfig.h"
+
+namespace Atomic
+{
+
+VariantMap ImportConfig::importConfig_;
+String ImportConfig::importConfigFilename_;
+
+bool ImportConfig::GetBoolValue(const JSONValue& jvalue, bool defaultValue)
+{
+    bool value = defaultValue;
+
+    if (jvalue.IsBool())
+        value = jvalue.GetBool();
+
+    return value;
+}
+
+bool ImportConfig::LoadFromJSON(const String& json)
+{
+    importConfig_.Clear();
+
+    JSONValue jroot;
+
+    if (!JSONFile::ParseJSON(json, jroot))
+    {
+        LOGERRORF("ImportConfig::LoadFromJSON - Unable to parse config file JSON: %s", importConfigFilename_.CString());
+        return false;
+    }
+
+    if (!jroot.IsObject())
+        return false;
+
+    if (!LoadDesktopConfig(jroot))
+        return false;
+
+    return true;
+}
+
+bool ImportConfig::LoadFromFile(Context *context, const String& filename)
+{
+
+    FileSystem* fileSystem = context->GetSubsystem<FileSystem>();
+
+    if (!fileSystem->FileExists(filename))
+        return false;
+
+    importConfigFilename_ = filename;
+
+    SharedPtr<File> file(new File(context));
+
+    if (!file->Open(filename))
+    {
+        LOGERRORF("ImportConfig::LoadFromFile - Unable to open config file %s", filename.CString());
+        return false;
+    }
+
+    String json;
+    file->ReadText(json);
+
+    return LoadFromJSON(json);
+}
+
+void ImportConfig::ApplyConfig(VariantMap& settings, bool overwrite)
+{
+    VariantMap::ConstIterator itr = importConfig_.Begin();
+    if (overwrite)
+    {
+        while (itr != importConfig_.End())
+        {
+            settings[itr->first_] = itr->second_;
+            itr++;
+        }
+    }
+    else
+    {
+        while (itr != importConfig_.End())
+        {
+            settings.InsertNew(itr->first_, itr->second_);
+            itr++;
+        }
+    }
+
+}
+
+bool ImportConfig::LoadAIFlagsDefaultConfig(const JSONValue& jflags)
+{
+    if (!jflags.IsObject())
+        return false;
+
+    for (JSONObject::ConstIterator i = jflags.Begin(); i != jflags.End(); ++i)
+    {
+        String key = i->first_;
+        const JSONValue& jvalue = i->second_;
+
+        if (key == "convertToLeftHanded")
+            importConfig_["aiProcess_ConvertToLeftHanded"] = GetBoolValue(jvalue, true);
+        else if (key == "joinIdenticalVertices")
+            importConfig_["aiProcess_JoinIdenticalVertices"] = GetBoolValue(jvalue, true);
+        else if (key == "triangulate")
+            importConfig_["aiProcess_Triangulate"] = GetBoolValue(jvalue, true);
+        else if (key == "genSmoothNormals")
+            importConfig_["aiProcess_GenSmoothNormals"] = GetBoolValue(jvalue, true);
+        else if (key == "limitBoneWeights")
+            importConfig_["aiProcess_LimitBoneWeights"] = GetBoolValue(jvalue, true);
+        else if (key == "improveCacheLocality")
+            importConfig_["aiProcess_ImproveCacheLocality"] = GetBoolValue(jvalue, true);
+        else if (key == "fixInFacingNormals")
+            importConfig_["aiProcess_FixInfacingNormals"] = GetBoolValue(jvalue, true);
+        else if (key == "fixInfacingNormals")
+            importConfig_["aiProcess_FixInfacingNormals"] = GetBoolValue(jvalue, true);
+        else if (key == "findInvalidData")
+            importConfig_["aiProcess_FindInvalidData"] = GetBoolValue(jvalue, true);
+        else if (key == "genUVCoords")
+            importConfig_["aiProcess_GenUVCoords"] = GetBoolValue(jvalue, true);
+        else if (key == "findInstances")
+            importConfig_["aiProcess_FindInstances"] = GetBoolValue(jvalue, true);
+        else if (key == "optimizeMeshes")
+            importConfig_["aiProcess_OptimizeMeshes"] = GetBoolValue(jvalue, true);
+    }
+
+    return true;
+}
+
+bool ImportConfig::LoadDesktopConfig(JSONValue root)
+{
+    const JSONValue& jdesktop = root["desktop"];
+
+    if (!jdesktop.IsObject())
+        return false;
+
+    const JSONValue& jflags = jdesktop["aiFlagsDefault"];
+    if (jflags.IsObject())
+        LoadAIFlagsDefaultConfig(jflags);
+ 
+    return true;
+}
+
+}

+ 57 - 0
Source/Atomic/Resource/ImportConfig.h

@@ -0,0 +1,57 @@
+//
+// Copyright (c) 2014-2015, THUNDERBEAST GAMES LLC All rights reserved
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#pragma once
+
+#include "../Core/Variant.h"
+#include "JSONValue.h"
+
+namespace Atomic
+{
+
+class Context;
+
+class ImportConfig
+{
+
+public:
+
+    static bool LoadFromFile(Context* context, const String& filename);
+    static bool LoadFromJSON(const String& json);
+
+    /// Apply the configuration to a setting variant map, values that exist will not be overriden
+    static void ApplyConfig(VariantMap& settings, bool overwrite = false);
+
+    static const VariantMap& GetConfig() { return importConfig_; }
+
+private:
+
+    static bool GetBoolValue(const JSONValue& jvalue, bool defaultValue);
+
+    static bool LoadDesktopConfig(JSONValue root);
+    static bool LoadAIFlagsDefaultConfig(const JSONValue& jflags);
+
+    static VariantMap importConfig_;
+    static String importConfigFilename_;
+};
+
+}

+ 60 - 12
Source/ToolCore/Import/OpenAssetImporter.cpp

@@ -27,6 +27,7 @@
 #include <Atomic/IO/Log.h>
 #include <Atomic/IO/File.h>
 #include <Atomic/IO/FileSystem.h>
+#include <Atomic/Resource/ImportConfig.h>
 
 #include <Atomic/Resource/XMLFile.h>
 #include <Atomic/Resource/ResourceCache.h>
@@ -40,6 +41,9 @@
 #include <Atomic/Graphics/VertexBuffer.h>
 #include <Atomic/Graphics/Material.h>
 
+#include <ToolCore/Project/Project.h>
+#include <ToolCore/ToolSystem.h>
+
 #include "OpenAssetImporter.h"
 
 namespace ToolCore
@@ -73,18 +77,42 @@ OpenAssetImporter::OpenAssetImporter(Context* context) : Object(context) ,
     endTime_(-1)
 {
 
-    aiFlagsDefault_ =
-        aiProcess_ConvertToLeftHanded |
-        aiProcess_JoinIdenticalVertices |
-        aiProcess_Triangulate |
-        aiProcess_GenSmoothNormals |
-        aiProcess_LimitBoneWeights |
-        aiProcess_ImproveCacheLocality |
-        aiProcess_FixInfacingNormals |
-        aiProcess_FindInvalidData |
-        aiProcess_GenUVCoords |
-        aiProcess_FindInstances |
-        aiProcess_OptimizeMeshes;
+    ReadImportConfig();
+
+    VariantMap::ConstIterator itr = aiFlagParameters_.Begin();
+
+    aiFlagsDefault_ = 0;
+
+    while (itr != aiFlagParameters_.End())
+    {
+        if (itr->second_ == true)
+        {
+            if (itr->first_ == "aiProcess_ConvertToLeftHanded")
+                aiFlagsDefault_ = aiFlagsDefault_ | aiProcess_ConvertToLeftHanded;
+            else if (itr->first_ == "aiProcess_JoinIdenticalVertices")
+                aiFlagsDefault_ = aiFlagsDefault_ | aiProcess_JoinIdenticalVertices;
+            else if (itr->first_ == "aiProcess_Triangulate")
+                aiFlagsDefault_ = aiFlagsDefault_ | aiProcess_Triangulate;
+            else if (itr->first_ == "aiProcess_GenSmoothNormals")
+                aiFlagsDefault_ = aiFlagsDefault_ | aiProcess_GenSmoothNormals;
+            else if (itr->first_ == "aiProcess_LimitBoneWeights")
+                aiFlagsDefault_ = aiFlagsDefault_ | aiProcess_LimitBoneWeights;
+            else if (itr->first_ == "aiProcess_ImproveCacheLocality")
+                aiFlagsDefault_ = aiFlagsDefault_ | aiProcess_ImproveCacheLocality;
+            else if (itr->first_ == "aiProcess_FixInfacingNormals")
+                aiFlagsDefault_ = aiFlagsDefault_ | aiProcess_FixInfacingNormals;
+            else if (itr->first_ == "aiProcess_FindInvalidData")
+                aiFlagsDefault_ = aiFlagsDefault_ | aiProcess_FindInvalidData;
+            else if (itr->first_ == "aiProcess_GenUVCoords")
+                aiFlagsDefault_ = aiFlagsDefault_ | aiProcess_GenUVCoords;
+            else if (itr->first_ == "aiProcess_FindInstances")
+                aiFlagsDefault_ = aiFlagsDefault_ | aiProcess_FindInstances;
+            else if (itr->first_ == "aiProcess_OptimizeMeshes")
+                aiFlagsDefault_ = aiFlagsDefault_ | aiProcess_OptimizeMeshes;
+        }
+
+        itr++;
+    }
 
     // TODO:  make this an option on importer
 
@@ -860,6 +888,26 @@ void OpenAssetImporter::CollectAnimations(OutModel* model)
     /// \todo Vertex morphs are ignored for now
 }
 
+void OpenAssetImporter::ReadImportConfig()
+{
+    ToolSystem* tsystem = GetSubsystem<ToolSystem>();
+    Project* project = tsystem->GetProject();
+
+    String projectPath = project->GetProjectPath();
+
+    String filename = projectPath + "Settings/Import.json";
+
+    FileSystem* fileSystem = GetSubsystem<FileSystem>();
+    if (!fileSystem->FileExists(filename))
+        return;
+
+    if (ImportConfig::LoadFromFile(context_, filename))
+    {
+        ImportConfig::ApplyConfig(aiFlagParameters_);
+    }
+
+}
+
 void OpenAssetImporter::BuildBoneCollisionInfo(OutModel& model)
 {
     for (unsigned i = 0; i < model.meshes_.Size(); ++i)

+ 4 - 0
Source/ToolCore/Import/OpenAssetImporter.h

@@ -82,6 +82,8 @@ private:
     void BuildBoneCollisionInfo(OutModel& model);
     void CollectAnimations(OutModel* model = 0);
 
+    void ReadImportConfig();
+
     String GetMeshMaterialName(aiMesh* mesh);
     String GenerateMaterialName(aiMaterial* material);
     String GetMaterialTextureName(const String& nameIn);
@@ -140,6 +142,8 @@ private:
     float startTime_;
     float endTime_;
 
+    VariantMap aiFlagParameters_;
+
 };
 
 }