فهرست منبع

Add Z-up and handedness options to OBJ export

JSandusky 10 سال پیش
والد
کامیت
83d0f9a23c

+ 3 - 3
Source/Urho3D/AngelScript/GraphicsAPI.cpp

@@ -1905,15 +1905,15 @@ static void RegisterOctree(asIScriptEngine* engine)
     engine->RegisterGlobalFunction("Octree@+ get_octree()", asFUNCTION(GetOctree), asCALL_CDECL);
 }
 
-bool ObjWriteDrawablesToOBJ(CScriptArray* drawablesArray, File* file, bool writeLightmapUV)
+bool ObjWriteDrawablesToOBJ(CScriptArray* drawablesArray, File* file, bool asZUp, bool asRightHanded, bool writeLightmapUV)
 {
     PODVector<Drawable*> drawables = ArrayToPODVector<Drawable*>(drawablesArray);
-    return WriteDrawablesToOBJ(drawables, file, writeLightmapUV);
+    return WriteDrawablesToOBJ(drawables, file, asZUp, asRightHanded, writeLightmapUV);
 }
 
 static void RegisterOBJExport(asIScriptEngine* engine)
 {
-    engine->RegisterGlobalFunction("bool WriteDrawablesToOBJ(Array<Drawable@>@, File@+, bool = false)", asFUNCTION(ObjWriteDrawablesToOBJ), asCALL_CDECL);
+    engine->RegisterGlobalFunction("bool WriteDrawablesToOBJ(Array<Drawable@>@, File@+, bool, bool, bool = false)", asFUNCTION(ObjWriteDrawablesToOBJ), asCALL_CDECL);
 }
 
 void RegisterGraphicsAPI(asIScriptEngine* engine)

+ 21 - 1
Source/Urho3D/Graphics/Drawable.cpp

@@ -444,7 +444,7 @@ void Drawable::RemoveFromOctree()
     }
 }
 
-bool WriteDrawablesToOBJ(PODVector<Drawable*> drawables, File* outputFile, bool writeLightmapUV)
+bool WriteDrawablesToOBJ(PODVector<Drawable*> drawables, File* outputFile, bool asZUp, bool asRightHanded, bool writeLightmapUV)
 {
     // Must track indices independently to deal with potential mismatching of drawables vertex attributes (ie. one with UV, another without, then another with)
     // Using long because 65,535 isn't enough as OBJ indices do not reset the count with each new object
@@ -508,6 +508,16 @@ bool WriteDrawablesToOBJ(PODVector<Drawable*> drawables, File* outputFile, bool
                 {
                     Vector3 vertexPosition = *((const Vector3*)(&vertexData[(vertexStart + j) * elementSize + positionOffset]));
                     vertexPosition = transMat * vertexPosition;
+
+                    // Convert coordinates as requested
+                    if (asRightHanded)
+                        vertexPosition.x_ *= -1;
+                    if (asZUp)
+                    {
+                        float yVal = vertexPosition.y_;
+                        vertexPosition.y_ = vertexPosition.z_;
+                        vertexPosition.z_ = yVal;
+                    }
                     outputFile->WriteLine("v " + String(vertexPosition));
                 }
 
@@ -519,6 +529,16 @@ bool WriteDrawablesToOBJ(PODVector<Drawable*> drawables, File* outputFile, bool
                         Vector3 vertexNormal = *((const Vector3*)(&vertexData[(vertexStart + j) * elementSize + positionOffset]));
                         vertexNormal = transMat * vertexNormal;
                         vertexNormal.Normalize();
+
+                        if (asRightHanded)
+                            vertexNormal.x_ *= -1;
+                        if (asZUp)
+                        {
+                            float yVal = vertexNormal.y_;
+                            vertexNormal.y_ = vertexNormal.z_;
+                            vertexNormal.z_ = yVal;
+                        }
+
                         outputFile->WriteLine("vn " + String(vertexNormal));
                     }
                 }

+ 1 - 1
Source/Urho3D/Graphics/Drawable.h

@@ -389,6 +389,6 @@ inline bool CompareDrawables(Drawable* lhs, Drawable* rhs)
     return lhs->GetSortValue() < rhs->GetSortValue();
 }
 
-URHO3D_API bool WriteDrawablesToOBJ(PODVector<Drawable*> drawables, File* outputFile, bool writeLightmapUV = false);
+URHO3D_API bool WriteDrawablesToOBJ(PODVector<Drawable*> drawables, File* outputFile, bool asZUp, bool asRightHanded, bool writeLightmapUV = false);
 
 }

+ 17 - 2
bin/Data/Scripts/Editor/EditorExport.as

@@ -1,4 +1,7 @@
 
+bool objExportZUp_ = false;
+bool objExportRightHanded_ = true;
+
 void ExportSceneToOBJ(String fileName)
 {
     if (fileName.empty)
@@ -27,7 +30,7 @@ void ExportSceneToOBJ(String fileName)
     RemoveDebugDrawables(drawables);
 
     File@ file = File(fileName, FILE_WRITE);
-    if (WriteDrawablesToOBJ(drawables, file))
+    if (WriteDrawablesToOBJ(drawables, file, objExportZUp_, objExportRightHanded_))
     {
         MessageBox("OBJ file written to " + fileName, "Success");
         file.Close();
@@ -78,7 +81,7 @@ void ExportSelectedToOBJ(String fileName)
     if (drawables.length > 0)
     {
         File@ file = File(fileName, FILE_WRITE);
-        if (WriteDrawablesToOBJ(drawables, file))
+        if (WriteDrawablesToOBJ(drawables, file, objExportZUp_, objExportRightHanded_))
         {
             MessageBox("OBJ file written to " + fileName, "Success");
             file.Close();
@@ -107,4 +110,16 @@ void RemoveDebugDrawables(Array<Drawable@>@ drawables)
         else
             ++i;
     }
+}
+
+void HandleOBJZUpChanged(StringHash eventType, VariantMap& eventData)
+{
+    CheckBox@ checkBox = cast<CheckBox>(eventData["Element"].GetPtr());
+    objExportZUp_ = checkBox.checked;
+}
+
+void HandleOBJRightHandedChanged(StringHash eventType, VariantMap& eventData)
+{
+    CheckBox@ checkBox = cast<CheckBox>(eventData["Element"].GetPtr());
+    objExportRightHanded_ = checkBox.checked;
 }

+ 48 - 8
bin/Data/Scripts/Editor/EditorUI.as

@@ -622,15 +622,55 @@ bool PickFile()
         CreateFileSelector("Import scene", "Import", "Cancel", uiImportPath, uiAllFilters, uiImportFilter);
         SubscribeToEvent(uiFileSelector, "FileSelected", "HandleImportScene");
     }
-    else if (action == "Export scene to OBJ...")
+    else if (action == "Export scene to OBJ..." || action == "Export selected to OBJ...")
     {
-        CreateFileSelector("Export scene to OBJ", "Save", "Cancel", uiExportPath, uiExportPathFilters, uiExportFilter);
-        SubscribeToEvent(uiFileSelector, "FileSelected", "HandleExportSceneOBJ");
-    }
-    else if (action == "Export selected to OBJ...")
-    {
-        CreateFileSelector("Export selected to OBJ", "Save", "Cancel", uiExportPath, uiExportPathFilters, uiExportFilter);
-        SubscribeToEvent(uiFileSelector, "FileSelected", "HandleExportSelectedOBJ");
+        // Set these up together to share the "export settings" options
+        if (action == "Export scene to OBJ...")
+        {
+            CreateFileSelector("Export scene to OBJ", "Save", "Cancel", uiExportPath, uiExportPathFilters, uiExportFilter);
+            SubscribeToEvent(uiFileSelector, "FileSelected", "HandleExportSceneOBJ");
+        }
+        else if (action == "Export selected to OBJ...")
+        {
+            CreateFileSelector("Export selected to OBJ", "Save", "Cancel", uiExportPath, uiExportPathFilters, uiExportFilter);
+            SubscribeToEvent(uiFileSelector, "FileSelected", "HandleExportSelectedOBJ");
+        }
+        
+        Window@ window = uiFileSelector.window;
+        
+            UIElement@ optionsGroup = UIElement();
+            optionsGroup.maxHeight = 30;
+            optionsGroup.layoutMode = LM_HORIZONTAL;
+            window.defaultStyle = uiStyle;
+            window.style = AUTO_STYLE;
+            
+                CheckBox@ checkRightHanded = CheckBox();
+                checkRightHanded.checked = objExportRightHanded_;
+                checkRightHanded.defaultStyle = uiStyle;
+                checkRightHanded.style = AUTO_STYLE;
+                SubscribeToEvent(checkRightHanded, "Toggled", "HandleOBJRightHandedChanged");
+                optionsGroup.AddChild(checkRightHanded);
+                
+                    Text@ lblRightHanded = Text();
+                    lblRightHanded.defaultStyle = uiStyle;
+                    lblRightHanded.style = AUTO_STYLE;
+                    lblRightHanded.text = "  Right handed";
+                    optionsGroup.AddChild(lblRightHanded);
+                
+                CheckBox@ checkZUp = CheckBox();
+                checkZUp.checked = objExportZUp_;
+                checkZUp.defaultStyle = uiStyle;
+                checkZUp.style = AUTO_STYLE;
+                SubscribeToEvent(checkZUp, "Toggled", "HandleOBJZUpChanged");
+                optionsGroup.AddChild(checkZUp);
+                
+                    Text@ lblZUp = Text();
+                    lblZUp.defaultStyle = uiStyle;
+                    lblZUp.style = AUTO_STYLE;
+                    lblZUp.text = " Z Axis Up";
+                    optionsGroup.AddChild(lblZUp);
+                
+            window.AddChild(optionsGroup);
     }
     else if (action == "Run script...")
     {