Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 20 additions & 57 deletions Addons/Fbx.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
// todo Once we drop support for 2018.3, use optional assembly definitions
using System;
#if FBX_EXPORTER

using UnityEditor;
using System.Reflection;
using System.Linq;
using UnityEditor.Formats.Fbx.Exporter;
using UnityEditor.ProBuilder;
using UnityEditor.ProBuilder.Actions;

namespace UnityEngine.ProBuilder.Addons.FBX
{
Expand All @@ -26,29 +28,7 @@ class FbxOptions
[InitializeOnLoad]
static class Fbx
{
private static Assembly FbxExporterAssembly
{
get
{
try
{
return Assembly.Load("Unity.Formats.Fbx.Editor");
}
catch (System.IO.FileNotFoundException)
{
return null;
}
}
}

static readonly Type[] k_ProBuilderTypes = new Type[]
{
typeof(BezierShape),
typeof(PolyShape),
typeof(Entity)
};

static FbxOptions m_FbxOptions = new FbxOptions() {
static FbxOptions s_FbxOptions = new FbxOptions() {
quads = true
};

Expand All @@ -59,52 +39,35 @@ static Fbx()

static void TryLoadFbxSupport()
{
if (FbxExporterAssembly == null)
{
return;
}

var modelExporter = FbxExporterAssembly.GetType("UnityEditor.Formats.Fbx.Exporter.ModelExporter");
var registerMeshCallback = modelExporter.GetMethods(BindingFlags.NonPublic | BindingFlags.Static).Where(x => x.Name == "RegisterMeshCallback").First(x => x.ContainsGenericParameters);
registerMeshCallback = registerMeshCallback.MakeGenericMethod(typeof(ProBuilderMesh));

var getMeshForComponent = FbxExporterAssembly.GetTypes()
.Where(t => t.BaseType == typeof(MulticastDelegate) && t.Name.StartsWith("GetMeshForComponent"))
.First(t => t.ContainsGenericParameters);

getMeshForComponent = getMeshForComponent.MakeGenericType(typeof(ProBuilderMesh));
var meshDelegate = Delegate.CreateDelegate(getMeshForComponent, typeof(Fbx).GetMethod("GetMeshForComponent", BindingFlags.NonPublic | BindingFlags.Static));

registerMeshCallback.Invoke(null, new object[] { meshDelegate, true });

m_FbxOptions.quads = ProBuilderSettings.Get<bool>("Export::m_FbxQuads", SettingsScope.User, true);
ModelExporter.RegisterMeshCallback<ProBuilderMesh>(GetMeshForPBComponent, true);
s_FbxOptions.quads = ProBuilderSettings.Get<bool>("Export::m_FbxQuads", SettingsScope.User, true);
}

static bool GetMeshForComponent(object exporter, ProBuilderMesh pmesh, object node)
static bool GetMeshForPBComponent(ModelExporter exporter, ProBuilderMesh pmesh, Autodesk.Fbx.FbxNode node)
{
Mesh mesh = new Mesh();
MeshUtility.Compile(pmesh, mesh, m_FbxOptions.quads ? MeshTopology.Quads : MeshTopology.Triangles);
MeshUtility.Compile(pmesh, mesh, s_FbxOptions.quads ? MeshTopology.Quads : MeshTopology.Triangles);

// using reflection to call: exporter.ExportMesh(mesh, node, pmesh.GetComponent<MeshRenderer>().sharedMaterials)
var pMeshRenderer = pmesh.GetComponent<MeshRenderer>();
var sharedMaterials = pMeshRenderer ? pMeshRenderer.sharedMaterials : null;
var exportMeshMethod = exporter.GetType().GetMethod("ExportMesh", BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(Mesh), node.GetType(), typeof(Material[]) }, null);
exportMeshMethod.Invoke(exporter, new object[] { mesh, node, sharedMaterials });

exporter.ExportMesh(mesh, node, sharedMaterials);

Object.DestroyImmediate(mesh);

// probuilder can't handle mesh assets that may be externally reloaded, just strip pb stuff for now.
foreach (var type in k_ProBuilderTypes)
//Need to have ExportOptions accessible to remove this reflection
var exporterType = exporter.GetType().GetMethods(BindingFlags.NonPublic | BindingFlags.Instance)
.First(x => x.Name == "get_ExportOptions").Invoke(exporter, null).GetType();

if(exporterType == typeof(ConvertToPrefabSettingsSerialize))
{
var component = pmesh.GetComponent(type);
if (component != null)
Object.DestroyImmediate(component);
// probuilder can't handle mesh assets that may be externally reloaded, just strip pb stuff for now.
StripProBuilderScripts.DoStrip(pmesh);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice 🥇

}

pmesh.preserveMeshAssetOnDestroy = true;
Object.DestroyImmediate(pmesh);

return true;
}
}
}

#endif
19 changes: 15 additions & 4 deletions Addons/Unity.ProBuilder.AddOns.Editor.asmdef
Original file line number Diff line number Diff line change
@@ -1,16 +1,27 @@
{
"name": "Unity.ProBuilder.AddOns.Editor",
"rootNamespace": "",
"references": [
"Unity.ProBuilder",
"Unity.ProBuilder.Editor"
"Unity.ProBuilder.Editor",
"Unity.Formats.Fbx.Editor",
"Autodesk.Fbx"
],
"optionalUnityReferences": [],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true
}
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [
{
"name": "com.unity.formats.fbx",
"expression": "4.0.0",
"define": "FBX_EXPORTER"
}
],
"noEngineReferences": false
}
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

### Bug Fixes

- [case: 1334017] Fixed errors while exporting a PBShape using FBX Exporter and cleaning export.
- [case: 1332226] Fixed issue where some Gizmos menu items would be missing in projects that have ProBuilder package installed.
- [case: 1324374] Fixed incorrect vertex/edge/face rect selection when mesh's parent is rotated and/or scaled.

Expand Down