123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349 |
- using System;
- using System.Collections.Generic;
- using System.Runtime.InteropServices;
- using UnityEngine;
- namespace UTJ.FbxExporter
- {
- public class FbxExporter
- {
- public FbxExporter(FbxExporter.ExportOptions opt)
- {
- this.m_opt = opt;
- }
- ~FbxExporter()
- {
- this.Release();
- }
- public void Release()
- {
- FbxExporter.fbxeReleaseContext(this.m_ctx);
- this.m_ctx = FbxExporter.Context.Null;
- }
- public bool CreateScene(string name)
- {
- this.Release();
- if (!this.m_ctx)
- {
- this.m_ctx = FbxExporter.fbxeCreateContext(ref this.m_opt);
- }
- this.m_nodes = new Dictionary<Transform, FbxExporter.Node>();
- return FbxExporter.fbxeCreateScene(this.m_ctx, name);
- }
- public void AddNode(GameObject go)
- {
- if (go)
- {
- this.FindOrCreateNodeTree(go.GetComponent<Transform>(), new Action<Transform, FbxExporter.Node>(this.ProcessNode));
- }
- }
- public bool WriteAsync(string path, FbxExporter.Format format)
- {
- return FbxExporter.fbxeWriteAsync(this.m_ctx, path, format);
- }
- public bool IsFinished()
- {
- return FbxExporter.fbxeIsFinished(this.m_ctx);
- }
- private void ProcessNode(Transform trans, FbxExporter.Node node)
- {
- MeshRenderer component = trans.GetComponent<MeshRenderer>();
- SkinnedMeshRenderer component2 = trans.GetComponent<SkinnedMeshRenderer>();
- Terrain component3 = trans.GetComponent<Terrain>();
- if (component3)
- {
- this.AddTerrain(node, component3);
- }
- else if (component2)
- {
- this.AddSkinnedMesh(node, component2);
- }
- else if (component)
- {
- this.AddMesh(node, component);
- }
- }
- private FbxExporter.Node FindOrCreateNodeTree(Transform trans, Action<Transform, FbxExporter.Node> act)
- {
- if (!trans)
- {
- return FbxExporter.Node.Null;
- }
- if (this.m_nodes.ContainsKey(trans))
- {
- return this.m_nodes[trans];
- }
- FbxExporter.Node parent = trans.parent ? this.FindOrCreateNodeTree(trans.parent, act) : FbxExporter.fbxeGetRootNode(this.m_ctx);
- FbxExporter.Node node = FbxExporter.fbxeCreateNode(this.m_ctx, parent, trans.name);
- if (this.m_opt.transform)
- {
- FbxExporter.fbxeSetTRS(this.m_ctx, node, trans.localPosition, trans.localRotation, trans.localScale);
- }
- this.m_nodes.Add(trans, node);
- if (act != null)
- {
- act(trans, node);
- }
- return node;
- }
- private bool AddMesh(FbxExporter.Node node, Mesh mesh)
- {
- if (!mesh || mesh.vertexCount == 0)
- {
- return false;
- }
- if (!mesh.isReadable)
- {
- Debug.LogWarning("Mesh " + mesh.name + " is not readable and be ignored.");
- return false;
- }
- FbxExporter.Topology topology = FbxExporter.Topology.Triangles;
- PinnedArray<int> pinnedArray = new PinnedArray<int>(mesh.triangles, false);
- PinnedArray<Vector3> pinnedArray2 = new PinnedArray<Vector3>(mesh.vertices, false);
- PinnedArray<Vector3> pinnedArray3 = new PinnedArray<Vector3>(mesh.normals, false);
- if (pinnedArray3.Length == 0)
- {
- pinnedArray3 = null;
- }
- PinnedArray<Vector4> pinnedArray4 = new PinnedArray<Vector4>(mesh.tangents, false);
- if (pinnedArray4.Length == 0)
- {
- pinnedArray4 = null;
- }
- PinnedArray<Vector2> pinnedArray5 = new PinnedArray<Vector2>(mesh.uv, false);
- if (pinnedArray5.Length == 0)
- {
- pinnedArray5 = null;
- }
- PinnedArray<Color> pinnedArray6 = new PinnedArray<Color>(mesh.colors, false);
- if (pinnedArray6.Length == 0)
- {
- pinnedArray6 = null;
- }
- FbxExporter.fbxeAddMesh(this.m_ctx, node, pinnedArray2.Length, pinnedArray2, pinnedArray3, pinnedArray4, pinnedArray5, pinnedArray6);
- FbxExporter.fbxeAddMeshSubmesh(this.m_ctx, node, topology, pinnedArray.Length, pinnedArray, -1);
- int blendShapeCount = mesh.blendShapeCount;
- if (blendShapeCount > 0)
- {
- PinnedArray<Vector3> v = new PinnedArray<Vector3>(mesh.vertexCount);
- PinnedArray<Vector3> v2 = new PinnedArray<Vector3>(mesh.vertexCount);
- PinnedArray<Vector3> v3 = new PinnedArray<Vector3>(mesh.vertexCount);
- for (int i = 0; i < blendShapeCount; i++)
- {
- string blendShapeName = mesh.GetBlendShapeName(i);
- int blendShapeFrameCount = mesh.GetBlendShapeFrameCount(i);
- for (int j = 0; j < blendShapeFrameCount; j++)
- {
- float blendShapeFrameWeight = mesh.GetBlendShapeFrameWeight(i, j);
- mesh.GetBlendShapeFrameVertices(i, j, v, v2, v3);
- FbxExporter.fbxeAddMeshBlendShape(this.m_ctx, node, blendShapeName, blendShapeFrameWeight, v, v2, v3);
- }
- }
- }
- return true;
- }
- private bool AddMesh(FbxExporter.Node node, MeshRenderer mr)
- {
- MeshFilter component = mr.gameObject.GetComponent<MeshFilter>();
- return component && this.AddMesh(node, component.sharedMesh);
- }
- private bool AddSkinnedMesh(FbxExporter.Node node, SkinnedMeshRenderer smr)
- {
- Mesh sharedMesh = smr.sharedMesh;
- if (!this.AddMesh(node, sharedMesh))
- {
- return false;
- }
- Transform[] bones = smr.bones;
- PinnedArray<FbxExporter.Node> pinnedArray = new PinnedArray<FbxExporter.Node>(bones.Length);
- for (int i = 0; i < bones.Length; i++)
- {
- pinnedArray[i] = this.FindOrCreateNodeTree(bones[i], new Action<Transform, FbxExporter.Node>(this.ProcessNode));
- }
- PinnedArray<BoneWeight> v = new PinnedArray<BoneWeight>(sharedMesh.boneWeights, false);
- PinnedArray<Matrix4x4> v2 = new PinnedArray<Matrix4x4>(sharedMesh.bindposes, false);
- FbxExporter.fbxeAddMeshSkin(this.m_ctx, node, v, pinnedArray.Length, pinnedArray, v2);
- return true;
- }
- private bool AddTerrain(FbxExporter.Node node, Terrain terrain)
- {
- TerrainData terrainData = terrain.terrainData;
- int heightmapWidth = terrainData.heightmapWidth;
- int heightmapHeight = terrainData.heightmapHeight;
- float[,] heights = terrainData.GetHeights(0, 0, heightmapWidth, heightmapHeight);
- int size = heightmapWidth * heightmapHeight;
- int size2 = (heightmapWidth - 1) * (heightmapHeight - 1) * 2 * 3;
- PinnedArray<Vector3> pinnedArray = new PinnedArray<Vector3>(size);
- PinnedArray<Vector3> v = new PinnedArray<Vector3>(size);
- PinnedArray<Vector2> v2 = new PinnedArray<Vector2>(size);
- PinnedArray<int> pinnedArray2 = new PinnedArray<int>(size2);
- FbxExporter.fbxeGenerateTerrainMesh(heights, heightmapWidth, heightmapHeight, terrainData.size, pinnedArray, v, v2, pinnedArray2);
- FbxExporter.Topology topology = FbxExporter.Topology.Triangles;
- FbxExporter.fbxeAddMesh(this.m_ctx, node, pinnedArray.Length, pinnedArray, v, IntPtr.Zero, v2, IntPtr.Zero);
- FbxExporter.fbxeAddMeshSubmesh(this.m_ctx, node, topology, pinnedArray2.Length, pinnedArray2, -1);
- return true;
- }
- [DllImport("FbxExporterCore")]
- private static extern FbxExporter.Context fbxeCreateContext(ref FbxExporter.ExportOptions opt);
- [DllImport("FbxExporterCore")]
- private static extern void fbxeReleaseContext(FbxExporter.Context ctx);
- [DllImport("FbxExporterCore")]
- private static extern bool fbxeCreateScene(FbxExporter.Context ctx, string name);
- [DllImport("FbxExporterCore")]
- private static extern bool fbxeWriteAsync(FbxExporter.Context ctx, string path, FbxExporter.Format format);
- [DllImport("FbxExporterCore")]
- private static extern bool fbxeIsFinished(FbxExporter.Context ctx);
- [DllImport("FbxExporterCore")]
- private static extern FbxExporter.Node fbxeGetRootNode(FbxExporter.Context ctx);
- [DllImport("FbxExporterCore")]
- private static extern FbxExporter.Node fbxeFindNodeByName(FbxExporter.Context ctx, string name);
- [DllImport("FbxExporterCore")]
- private static extern FbxExporter.Node fbxeCreateNode(FbxExporter.Context ctx, FbxExporter.Node parent, string name);
- [DllImport("FbxExporterCore")]
- private static extern void fbxeSetTRS(FbxExporter.Context ctx, FbxExporter.Node node, Vector3 t, Quaternion r, Vector3 s);
- [DllImport("FbxExporterCore")]
- private static extern void fbxeAddMesh(FbxExporter.Context ctx, FbxExporter.Node node, int num_vertices, IntPtr points, IntPtr normals, IntPtr tangents, IntPtr uv, IntPtr colors);
- [DllImport("FbxExporterCore")]
- private static extern void fbxeAddMeshSubmesh(FbxExporter.Context ctx, FbxExporter.Node node, FbxExporter.Topology topology, int num_indices, IntPtr indices, int material);
- [DllImport("FbxExporterCore")]
- private static extern void fbxeAddMeshSkin(FbxExporter.Context ctx, FbxExporter.Node node, IntPtr weights, int num_bones, IntPtr bones, IntPtr bindposes);
- [DllImport("FbxExporterCore")]
- private static extern void fbxeAddMeshBlendShape(FbxExporter.Context ctx, FbxExporter.Node node, string name, float weight, IntPtr deltaPoints, IntPtr deltaNormals, IntPtr deltaTangents);
- [DllImport("FbxExporterCore")]
- private static extern void fbxeGenerateTerrainMesh(float[,] heightmap, int width, int height, Vector3 size, IntPtr dst_vertices, IntPtr dst_normals, IntPtr dst_uv, IntPtr dst_indices);
- private FbxExporter.ExportOptions m_opt = FbxExporter.ExportOptions.defaultValue;
- private FbxExporter.Context m_ctx;
- private Dictionary<Transform, FbxExporter.Node> m_nodes;
- public struct Context
- {
- public static FbxExporter.Context Null
- {
- get
- {
- FbxExporter.Context result;
- result.ptr = IntPtr.Zero;
- return result;
- }
- }
- public static implicit operator bool(FbxExporter.Context v)
- {
- return v.ptr != IntPtr.Zero;
- }
- public IntPtr ptr;
- }
- public struct Node
- {
- public static FbxExporter.Node Null
- {
- get
- {
- FbxExporter.Node result;
- result.ptr = IntPtr.Zero;
- return result;
- }
- }
- public static implicit operator bool(FbxExporter.Node v)
- {
- return v.ptr != IntPtr.Zero;
- }
- public IntPtr ptr;
- }
- public enum Format
- {
- FbxBinary,
- FbxAscii,
- FbxEncrypted,
- Obj
- }
- public enum SystemUnit
- {
- Millimeter,
- Centimeter,
- Decimeter,
- Meter,
- Kilometer
- }
- public enum Topology
- {
- Points,
- Lines,
- Triangles,
- Quads
- }
- public struct ExportOptions
- {
- public static FbxExporter.ExportOptions defaultValue
- {
- get
- {
- return new FbxExporter.ExportOptions
- {
- flip_handedness = true,
- flip_faces = true,
- quadify = true,
- quadify_full_search = false,
- quadify_threshold_angle = 20f,
- scale_factor = 1f,
- system_unit = FbxExporter.SystemUnit.Meter,
- transform = true
- };
- }
- }
- public bool flip_handedness;
- public bool flip_faces;
- public bool quadify;
- public bool quadify_full_search;
- public float quadify_threshold_angle;
- public float scale_factor;
- public FbxExporter.SystemUnit system_unit;
- public bool transform;
- }
- }
- }
|