Skip to content

Instantly share code, notes, and snippets.

@piranha771
Created October 18, 2016 15:58
Show Gist options
  • Save piranha771/e97c773fc050bc6387d36a080c4dd132 to your computer and use it in GitHub Desktop.
Save piranha771/e97c773fc050bc6387d36a080c4dd132 to your computer and use it in GitHub Desktop.
/**
* Author: David Asmuth
* Contact: [email protected]
* License: Public domain
*
* Converts the .fbx model
* from Blender orientation system (Z is up, Y is forward)
* to the Unity3D orientation system (Y is up, Z is forward)
*/
using System.IO;
using UnityEngine;
using UnityEditor;
public class FixFbxModelPostprocessor : AssetPostprocessor
{
public void OnPostprocessModel(GameObject obj)
{
ModelImporter importer = assetImporter as ModelImporter;
if (Path.GetExtension(importer.assetPath) == ".fbx")
{
FixObject(obj.transform);
Debug.Log("[Fix FBX] Finished for " + Path.GetFileName(importer.assetPath));
}
}
private void FixObject(Transform obj)
{
MeshFilter meshFilter = obj.GetComponent<MeshFilter>();
/*
* First we need to undo the stupid -90 dregree rotation on the X axis that Unity does
* on every game object with a mesh
*/
if(meshFilter)
{
obj.localRotation *= Quaternion.Euler(90, 0, 0);
}
/*
* Translate rotation into Unity's coordinate system
*/
Quaternion lc = obj.transform.localRotation;
obj.transform.localRotation = new Quaternion(-lc.x, lc.y, -lc.z, lc.w);
/*
* Translate position into Unity's coordinate system
*/
Vector3 currentPos = obj.transform.localPosition;
obj.transform.localPosition = new Vector3(-currentPos.x, currentPos.y, -currentPos.z);
/*
* Translate mesh into Unity's coordinate system
*/
if (meshFilter)
{
FixMesh(meshFilter.sharedMesh);
}
/*
* Repeat for all sub objects
*/
foreach (Transform child in obj)
{
FixObject(child);
}
}
private void FixMesh(Mesh mesh)
{
/*
* We fix the vertices by flipping Z axis with Y axis
* Odly enough X has to be inverted. When we store a positive X in Blender somehow it gets inverted in the *.fbx format O.o
*/
Vector3[] vertices = mesh.vertices;
for (int i = 0; i < vertices.Length; i++)
{
vertices[i] = new Vector3(-vertices[i].x, vertices[i].z, vertices[i].y);
}
mesh.vertices = vertices;
/*
* Same goes for normals
*/
Vector3[] normals = mesh.normals;
for (int i = 0; i < normals.Length; i++)
{
normals[i] = new Vector3(-normals[i].x, normals[i].z, normals[i].y);
}
mesh.normals = normals;
/*
* Vertex positions have changed, so recalc bounds
*/
mesh.RecalculateBounds();
}
}
@SleightOfCode
Copy link

SleightOfCode commented May 16, 2019

Great fix, saved us a ton of time!
We had to add handling for tangents as well to support ... something about our normal maps. Hard to describe; two directions jsut "weren't working" and the others were "weird". That's about as much detail as I can convey with human language.

Here's what we added, right after the "mesh.normals = normals" line:

` Vector4[] tangents = mesh.tangents;

	for (int i = 0; i < tangents.Length; i++) {
		tangents[i] = new Vector4(-tangents[i].x, tangents[i].z, tangents[i].y, tangents[i].w);
	}
	for (int i = 0; i < tangents.Length; i++) {
		tangents[i] = spin * tangents[i];
	}
	mesh.tangents = tangents;`

@Hamilgo
Copy link

Hamilgo commented Jun 12, 2019

Thank you! Although there is a problem compiling,: The variable 'spin' is not defined.
Where do you create it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment