public void TestBasics() { Assert.That(!string.IsNullOrEmpty(ModelExporter.GetVersionFromReadme())); // Test GetOrCreateLayer using (var fbxManager = FbxManager.Create()) { var fbxMesh = FbxMesh.Create(fbxManager, "name"); var layer0 = ModelExporter.GetOrCreateLayer(fbxMesh); Assert.That(layer0, Is.Not.Null); Assert.That(ModelExporter.GetOrCreateLayer(fbxMesh), Is.EqualTo(layer0)); var layer5 = ModelExporter.GetOrCreateLayer(fbxMesh, layer: 5); Assert.That(layer5, Is.Not.Null); Assert.That(layer5, Is.Not.EqualTo(layer0)); } // Test axis conversion: a x b in left-handed is the same as b x a // in right-handed (that's why we need to flip the winding order). var a = new Vector3(1, 0, 0); var b = new Vector3(0, 0, 1); var crossLeft = Vector3.Cross(a, b); Assert.That(ModelExporter.DefaultMaterial); // Test non-static functions. using (var fbxManager = FbxManager.Create()) { var fbxScene = FbxScene.Create(fbxManager, "scene"); var fbxNode = FbxNode.Create(fbxScene, "node"); var exporter = new ModelExporter(); // Test ExportMaterial: it exports and it re-exports bool result = exporter.ExportMaterial(ModelExporter.DefaultMaterial, fbxScene, fbxNode); Assert.IsTrue(result); var fbxMaterial = fbxNode.GetMaterial(0); Assert.That(fbxMaterial, Is.Not.Null); result = exporter.ExportMaterial(ModelExporter.DefaultMaterial, fbxScene, fbxNode); var fbxMaterial2 = fbxNode.GetMaterial(1); Assert.AreEqual(fbxMaterial, fbxMaterial2); // Test ExportTexture: it finds the same texture for the default-material (it doesn't create a new one) var fbxMaterialNew = FbxSurfaceLambert.Create(fbxScene, "lambert"); exporter.ExportTexture(ModelExporter.DefaultMaterial, "_MainTex", fbxMaterialNew, FbxSurfaceLambert.sBump); Assert.AreEqual( fbxMaterial.FindProperty(FbxSurfaceLambert.sDiffuse).GetSrcObject(), fbxMaterialNew.FindProperty(FbxSurfaceLambert.sBump).GetSrcObject() ); // Test ExportMesh: make sure we exported a mesh with welded vertices. var cube = GameObject.CreatePrimitive(PrimitiveType.Cube); var cubeNode = FbxNode.Create(fbxScene, "cube"); exporter.ExportMesh(cube.GetComponent <MeshFilter>().sharedMesh, cubeNode); Assert.That(cubeNode.GetMesh(), Is.Not.Null); Assert.That(cubeNode.GetMesh().GetControlPointsCount(), Is.EqualTo(8)); } // Test exporting a skinned-mesh. Make sure it doesn't leak (it did at one point) { var cube = GameObject.CreatePrimitive(PrimitiveType.Cube); var character = new GameObject(); var smr = character.AddComponent <SkinnedMeshRenderer>(); smr.sharedMesh = cube.GetComponent <MeshFilter>().sharedMesh; var meshCount = Object.FindObjectsOfType <Mesh>().Length; ModelExporter.ExportObject(GetRandomFbxFilePath(), character); Assert.AreEqual(meshCount, Object.FindObjectsOfType <Mesh>().Length); } // Test euler to quaternion conversion { // EulerToQuaternionZXY var v = new Vector3(50, 45, 190); var quat = ModelExporter.EulerToQuaternionZXY(v); var unityQuat = Quaternion.Euler(v); Assert.That((float)quat.X, Is.EqualTo(unityQuat.x)); Assert.That((float)quat.Y, Is.EqualTo(unityQuat.y)); Assert.That((float)quat.Z, Is.EqualTo(unityQuat.z)); Assert.That((float)quat.W, Is.EqualTo(unityQuat.w)); // EulerToQuaternionXYZ var fbxV = new FbxVector4(v.x, v.y, v.z); var xyzQuat = ModelExporter.EulerToQuaternionXYZ(fbxV); // get the vector from the quaternion FbxAMatrix m = new FbxAMatrix(); m.SetR(fbxV); var actualQuat = m.GetQ(); // since this quaternion is XYZ instead of ZXY, it should not match the quaternion // created with EulerToQuaternionZXY Assert.That(xyzQuat, Is.Not.EqualTo(quat)); Assert.That(xyzQuat, Is.EqualTo(actualQuat)); } }
public void BasicTests() { using (var manager = FbxManager.Create()) { // FbxPropertyT<FbxBool> example: VisibilityInheritance on a node var node = FbxNode.Create(manager, "node"); GenericPropertyTests <FbxPropertyBool> (node.VisibilityInheritance, node, "Visibility Inheritance", Globals.FbxVisibilityInheritanceDT); var property = node.VisibilityInheritance; property.Set(false); Assert.AreEqual(false, property.Get()); Assert.AreEqual(false, property.EvaluateValue()); Assert.AreEqual(false, property.EvaluateValue(FbxTime.FromSecondDouble(5))); Assert.AreEqual(false, property.EvaluateValue(FbxTime.FromSecondDouble(5), true)); } using (var manager = FbxManager.Create()) { // FbxPropertyT<FbxDouble> example: several of them on a Lambert shader var obj = FbxSurfaceLambert.Create(manager, "lambert"); GenericPropertyTests <FbxPropertyDouble> (obj.EmissiveFactor, obj, "EmissiveFactor", Globals.FbxDoubleDT); var property = obj.EmissiveFactor; property.Set(5.0); // bool Set<float> is not accessible here! Assert.AreEqual(5.0, property.Get()); Assert.AreEqual(5.0, property.EvaluateValue()); Assert.AreEqual(5.0, property.EvaluateValue(FbxTime.FromSecondDouble(5))); Assert.AreEqual(5.0, property.EvaluateValue(FbxTime.FromSecondDouble(5), true)); } using (var manager = FbxManager.Create()) { // FbxPropertyT<Double3> example: the LclTranslation on a node var node = FbxNode.Create(manager, "node"); GenericPropertyTests <FbxPropertyDouble3> (node.LclTranslation, node, "Lcl Translation", Globals.FbxLocalTranslationDT); var property = node.LclTranslation; property.Set(new FbxDouble3(1, 2, 3)); Assert.AreEqual(new FbxDouble3(1, 2, 3), property.Get()); Assert.AreEqual(new FbxDouble3(1, 2, 3), property.EvaluateValue()); Assert.AreEqual(new FbxDouble3(1, 2, 3), property.EvaluateValue(FbxTime.FromSecondDouble(5))); Assert.AreEqual(new FbxDouble3(1, 2, 3), property.EvaluateValue(FbxTime.FromSecondDouble(5), true)); } using (var manager = FbxManager.Create()) { // FbxPropertyT<float> example: the LeftBarnDoor on a light var light = FbxLight.Create(manager, "light"); GenericPropertyTests(light.LeftBarnDoor, light, "LeftBarnDoor", Globals.FbxFloatDT); var property = light.LeftBarnDoor; light.LeftBarnDoor.Set(5.0f); Assert.AreEqual(5.0f, light.LeftBarnDoor.Get()); Assert.AreEqual(5.0f, property.EvaluateValue()); Assert.AreEqual(5.0f, property.EvaluateValue(FbxTime.FromSecondDouble(5))); Assert.AreEqual(5.0f, property.EvaluateValue(FbxTime.FromSecondDouble(5), true)); } using (var manager = FbxManager.Create()) { // FbxPropertyT<int> example: the WorldUpType on an aim constraint var constraint = FbxConstraintAim.Create(manager, "constraint"); GenericPropertyTests(constraint.WorldUpType, constraint, "WorldUpType", Globals.FbxEnumDT); var property = constraint.WorldUpType; int value = (int)FbxConstraintAim.EWorldUp.eAimAtObjectUp; constraint.WorldUpType.Set(value); Assert.That(constraint.WorldUpType.Get(), Is.EqualTo(value)); Assert.That(property.EvaluateValue(), Is.EqualTo(value)); Assert.That(property.EvaluateValue(FbxTime.FromSecondDouble(5)), Is.EqualTo(value)); Assert.That(property.EvaluateValue(FbxTime.FromSecondDouble(5), true), Is.EqualTo(value)); } using (var manager = FbxManager.Create()) { // FbxPropertyT<FbxString> example: the description of a shader implementation var impl = FbxImplementation.Create(manager, "name"); GenericPropertyTests <FbxPropertyString> (impl.RenderAPI, impl, "RenderAPI", Globals.FbxStringDT); var property = impl.RenderAPI; property.Set("a value"); Assert.AreEqual("a value", property.Get()); // animated strings come out as empty-string Assert.AreEqual("", property.EvaluateValue()); Assert.AreEqual("", property.EvaluateValue(FbxTime.FromSecondDouble(5))); Assert.AreEqual("", property.EvaluateValue(FbxTime.FromSecondDouble(5), true)); } using (var manager = FbxManager.Create()) { // FbxPropertyT for FbxTexture enums EBlendMode and EWrapMode var tex = FbxTexture.Create(manager, "tex"); FbxPropertyTest.GenericPropertyTests(tex.CurrentTextureBlendMode, tex, "CurrentTextureBlendMode", Globals.FbxEnumDT); tex.CurrentTextureBlendMode.Set(FbxTexture.EBlendMode.eAdditive); Assert.AreEqual(FbxTexture.EBlendMode.eAdditive, tex.CurrentTextureBlendMode.Get()); Assert.AreEqual(FbxTexture.EBlendMode.eAdditive, tex.CurrentTextureBlendMode.EvaluateValue()); Assert.AreEqual(FbxTexture.EBlendMode.eAdditive, tex.CurrentTextureBlendMode.EvaluateValue(FbxTime.FromSecondDouble(5))); Assert.AreEqual(FbxTexture.EBlendMode.eAdditive, tex.CurrentTextureBlendMode.EvaluateValue(FbxTime.FromSecondDouble(5), true)); FbxPropertyTest.GenericPropertyTests(tex.WrapModeU, tex, "WrapModeU", Globals.FbxEnumDT); tex.WrapModeU.Set(FbxTexture.EWrapMode.eClamp); Assert.AreEqual(FbxTexture.EWrapMode.eClamp, tex.WrapModeU.Get()); Assert.AreEqual(FbxTexture.EWrapMode.eClamp, tex.WrapModeU.EvaluateValue()); Assert.AreEqual(FbxTexture.EWrapMode.eClamp, tex.WrapModeU.EvaluateValue(FbxTime.FromSecondDouble(5))); Assert.AreEqual(FbxTexture.EWrapMode.eClamp, tex.WrapModeU.EvaluateValue(FbxTime.FromSecondDouble(5), true)); } using (var manager = FbxManager.Create()) { // FbxPropertyT<FbxNull.ELook> var null1 = FbxNull.Create(manager, "null1"); FbxPropertyTest.GenericPropertyTests(null1.Look, null1, "Look", Globals.FbxEnumDT); null1.Look.Set(FbxNull.ELook.eCross); Assert.AreEqual(FbxNull.ELook.eCross, null1.Look.Get()); Assert.AreEqual(FbxNull.ELook.eCross, null1.Look.EvaluateValue()); Assert.AreEqual(FbxNull.ELook.eCross, null1.Look.EvaluateValue(FbxTime.FromSecondDouble(5))); Assert.AreEqual(FbxNull.ELook.eCross, null1.Look.EvaluateValue(FbxTime.FromSecondDouble(5), true)); } using (var manager = FbxManager.Create()) { // FbxPropertyT<FbxMarker.ELook> var marker1 = FbxMarker.Create(manager, "marker1"); FbxPropertyTest.GenericPropertyTests(marker1.Look, marker1, "Look", Globals.FbxEnumDT); marker1.Look.Set(FbxMarker.ELook.eCapsule); Assert.AreEqual(FbxMarker.ELook.eCapsule, marker1.Look.Get()); Assert.AreEqual(FbxMarker.ELook.eCapsule, marker1.Look.EvaluateValue()); Assert.AreEqual(FbxMarker.ELook.eCapsule, marker1.Look.EvaluateValue(FbxTime.FromSecondDouble(5))); Assert.AreEqual(FbxMarker.ELook.eCapsule, marker1.Look.EvaluateValue(FbxTime.FromSecondDouble(5), true)); } using (var manager = FbxManager.Create()) { // FbxPropertyT for FbxCamera enum EProjectionType var camera = FbxCamera.Create(manager, "camera"); FbxPropertyTest.GenericPropertyTests(camera.ProjectionType, camera, "CameraProjectionType", Globals.FbxEnumDT); camera.ProjectionType.Set(FbxCamera.EProjectionType.ePerspective); Assert.AreEqual(FbxCamera.EProjectionType.ePerspective, camera.ProjectionType.Get()); Assert.AreEqual(FbxCamera.EProjectionType.ePerspective, camera.ProjectionType.EvaluateValue()); Assert.AreEqual(FbxCamera.EProjectionType.ePerspective, camera.ProjectionType.EvaluateValue(FbxTime.FromSecondDouble(5))); Assert.AreEqual(FbxCamera.EProjectionType.ePerspective, camera.ProjectionType.EvaluateValue(FbxTime.FromSecondDouble(5), true)); } using (var manager = FbxManager.Create()) { // FbxPropertyT for FbxCamera enum EGateFit var camera = FbxCamera.Create(manager, "camera"); FbxPropertyTest.GenericPropertyTests(camera.GateFit, camera, "GateFit", Globals.FbxEnumDT); camera.GateFit.Set(FbxCamera.EGateFit.eFitHorizontal); Assert.AreEqual(FbxCamera.EGateFit.eFitHorizontal, camera.GateFit.Get()); Assert.AreEqual(FbxCamera.EGateFit.eFitHorizontal, camera.GateFit.EvaluateValue()); Assert.AreEqual(FbxCamera.EGateFit.eFitHorizontal, camera.GateFit.EvaluateValue(FbxTime.FromSecondDouble(5))); Assert.AreEqual(FbxCamera.EGateFit.eFitHorizontal, camera.GateFit.EvaluateValue(FbxTime.FromSecondDouble(5), true)); } using (var manager = FbxManager.Create()) { // FbxPropertyT<EInheritType> var node = FbxNode.Create(manager, "node"); FbxPropertyTest.GenericPropertyTests(node.InheritType, node, "InheritType", Globals.FbxEnumDT); node.InheritType.Set(FbxTransform.EInheritType.eInheritRSrs); Assert.AreEqual(FbxTransform.EInheritType.eInheritRSrs, node.InheritType.Get()); Assert.AreEqual(FbxTransform.EInheritType.eInheritRSrs, node.InheritType.EvaluateValue()); Assert.AreEqual(FbxTransform.EInheritType.eInheritRSrs, node.InheritType.EvaluateValue(FbxTime.FromSecondDouble(5))); Assert.AreEqual(FbxTransform.EInheritType.eInheritRSrs, node.InheritType.EvaluateValue(FbxTime.FromSecondDouble(5), true)); } using (var manager = FbxManager.Create()) { // FbxPropertyT for FbxLight enums var light = FbxLight.Create(manager, "light"); FbxPropertyTest.GenericPropertyTests(light.LightType, light, "LightType", Globals.FbxEnumDT); light.LightType.Set(FbxLight.EType.eSpot); Assert.AreEqual(FbxLight.EType.eSpot, light.LightType.Get()); Assert.AreEqual(FbxLight.EType.eSpot, light.LightType.EvaluateValue()); Assert.AreEqual(FbxLight.EType.eSpot, light.LightType.EvaluateValue(FbxTime.FromSecondDouble(5))); Assert.AreEqual(FbxLight.EType.eSpot, light.LightType.EvaluateValue(FbxTime.FromSecondDouble(5), true)); FbxPropertyTest.GenericPropertyTests(light.AreaLightShape, light, "AreaLightShape", Globals.FbxEnumDT); light.AreaLightShape.Set(FbxLight.EAreaLightShape.eSphere); Assert.AreEqual(FbxLight.EAreaLightShape.eSphere, light.AreaLightShape.Get()); Assert.AreEqual(FbxLight.EAreaLightShape.eSphere, light.AreaLightShape.EvaluateValue()); Assert.AreEqual(FbxLight.EAreaLightShape.eSphere, light.AreaLightShape.EvaluateValue(FbxTime.FromSecondDouble(5))); Assert.AreEqual(FbxLight.EAreaLightShape.eSphere, light.AreaLightShape.EvaluateValue(FbxTime.FromSecondDouble(5), true)); FbxPropertyTest.GenericPropertyTests(light.DecayType, light, "DecayType", Globals.FbxEnumDT); light.DecayType.Set(FbxLight.EDecayType.eCubic); Assert.AreEqual(FbxLight.EDecayType.eCubic, light.DecayType.Get()); Assert.AreEqual(FbxLight.EDecayType.eCubic, light.DecayType.EvaluateValue()); Assert.AreEqual(FbxLight.EDecayType.eCubic, light.DecayType.EvaluateValue(FbxTime.FromSecondDouble(5))); Assert.AreEqual(FbxLight.EDecayType.eCubic, light.DecayType.EvaluateValue(FbxTime.FromSecondDouble(5), true)); } using (var manager = FbxManager.Create()) { // Test all the create and destroy operations FbxProperty root, child; var obj = FbxObject.Create(manager, "obj"); Assert.IsNotNull(FbxProperty.Create(obj, Globals.FbxStringDT, "a")); Assert.IsNotNull(FbxProperty.Create(obj, Globals.FbxStringDT, "b", "label")); Assert.IsNotNull(FbxProperty.Create(obj, Globals.FbxStringDT, "c", "label", false)); bool didFind; Assert.IsNotNull(FbxProperty.Create(obj, Globals.FbxStringDT, "c", "label", true, out didFind)); Assert.IsTrue(didFind); root = FbxProperty.Create(obj, Globals.FbxCompoundDT, "root"); child = FbxProperty.Create(root, Globals.FbxStringDT, "a"); Assert.IsNotNull(child); Assert.IsNotNull(FbxProperty.Create(root, Globals.FbxStringDT, "b", "label")); Assert.IsNotNull(FbxProperty.Create(root, Globals.FbxStringDT, "c", "label", false)); Assert.IsNotNull(FbxProperty.Create(root, Globals.FbxStringDT, "c", "label", true, out didFind)); Assert.IsTrue(didFind); child.Destroy(); root.DestroyChildren(); Assert.IsNotNull(FbxProperty.Create(root, Globals.FbxStringDT, "c", "label", true, out didFind)); Assert.IsFalse(didFind); root.DestroyRecursively(); } }
public void TestEquality() { using (var manager = FbxManager.Create()) { // FbxProperty var node = FbxNode.Create(manager, "node"); var prop1 = FbxProperty.Create(node, Globals.FbxBoolDT, "bool1"); var prop2 = FbxProperty.Create(node, Globals.FbxBoolDT, "bool2"); var prop1copy = node.FindProperty("bool1"); EqualityTester <FbxProperty> .TestEquality(prop1, prop2, prop1copy); // FbxPropertyT<bool> var vis1 = node.VisibilityInheritance; var vis2 = FbxNode.Create(manager, "node2").VisibilityInheritance; var vis1copy = vis1; // TODO: node.FindProperty("Visibility Inheritance"); -- but that has a different proxy type EqualityTester <FbxPropertyBool> .TestEquality(vis1, vis2, vis1copy); // FbxPropertyT<EInheritType> var inhType1 = node.InheritType; var inhType2 = FbxNode.Create(manager, "node3").InheritType; var inhType1Copy = inhType1; // TODO: node.FindProperty("InheritType"); EqualityTester <FbxPropertyEInheritType> .TestEquality(inhType1, inhType2, inhType1Copy); // FbxPropertyT<double> var lambert = FbxSurfaceLambert.Create(manager, "lambert"); var emissiveCopy = lambert.EmissiveFactor; // TODO: lambert.FindProperty("EmissiveFactor"); EqualityTester <FbxPropertyDouble> .TestEquality(lambert.EmissiveFactor, lambert.AmbientFactor, emissiveCopy); // FbxPropertyT<FbxDouble3> var lclTranslationCopy = node.LclTranslation; // TODO: node.FindProperty("Lcl Translation"); EqualityTester <FbxPropertyDouble3> .TestEquality(node.LclTranslation, node.LclRotation, lclTranslationCopy); // FbxPropertyT<float> var light = FbxLight.Create(manager, "light"); EqualityTester <FbxPropertyFloat> .TestEquality(light.LeftBarnDoor, light.RightBarnDoor, light.LeftBarnDoor); // FbxPropertyT<int> var constraint = FbxConstraintAim.Create(manager, "constraint"); var constraint2 = FbxConstraintAim.Create(manager, "constraint2"); var worldUpTypeCopy = constraint.WorldUpType; // TODO: constraint.FindProperty("WorldUpType"); EqualityTester <FbxPropertyInt> .TestEquality(constraint.WorldUpType, constraint2.WorldUpType, worldUpTypeCopy); // FbxPropertyT<> for FbxTexture enums var tex1 = FbxTexture.Create(manager, "tex1"); var tex2 = FbxTexture.Create(manager, "tex2"); var blendCopy = tex1.CurrentTextureBlendMode; // TODO: tex1.FindProperty(...) EqualityTester <FbxPropertyEBlendMode> .TestEquality(tex1.CurrentTextureBlendMode, tex2.CurrentTextureBlendMode, blendCopy); var wrapCopy = tex1.WrapModeU; // TODO: tex1.FindProperty(...) EqualityTester <FbxPropertyEWrapMode> .TestEquality(tex1.WrapModeU, tex2.WrapModeU, wrapCopy); // FbxPropertyT<FbxNull.ELook> var null1 = FbxNull.Create(manager, "null1"); var null2 = FbxNull.Create(manager, "null2"); EqualityTester <FbxPropertyNullELook> .TestEquality(null1.Look, null2.Look, null1.Look); // FbxPropertyT<FbxMarker.ELook> var marker1 = FbxMarker.Create(manager, "marker1"); var marker2 = FbxMarker.Create(manager, "marker2"); EqualityTester <FbxPropertyMarkerELook> .TestEquality(marker1.Look, marker2.Look, marker1.Look); // FbxPropertyT<string> var impl = FbxImplementation.Create(manager, "impl"); var renderAPIcopy = impl.RenderAPI; // TODO: impl.FindProperty("RenderAPI"); EqualityTester <FbxPropertyString> .TestEquality(impl.RenderAPI, impl.RenderAPIVersion, renderAPIcopy); // FbxPropertyT<> for FbxCamera enum EProjectionType var cam1 = FbxCamera.Create(manager, "cam1"); var cam2 = FbxCamera.Create(manager, "cam2"); var projectionCopy = cam1.ProjectionType; EqualityTester <FbxPropertyEProjectionType> .TestEquality(cam1.ProjectionType, cam2.ProjectionType, projectionCopy); // FbxPropertyT<> for FbxLight enum EType var light1 = FbxLight.Create(manager, "light1"); var light2 = FbxLight.Create(manager, "light2"); var typeCopy = light1.LightType; EqualityTester <FbxPropertyELightType> .TestEquality(light1.LightType, light2.LightType, typeCopy); var lightShapeCopy = light1.AreaLightShape; EqualityTester <FbxPropertyEAreaLightShape> .TestEquality(light1.AreaLightShape, light2.AreaLightShape, lightShapeCopy); var decayCopy = light1.DecayType; EqualityTester <FbxPropertyEDecayType> .TestEquality(light1.DecayType, light2.DecayType, decayCopy); var floatCopy = light1.LeftBarnDoor; EqualityTester <FbxPropertyFloat> .TestEquality(light1.LeftBarnDoor, light2.LeftBarnDoor, floatCopy); } }
internal static FbxSurfaceMaterial CreateFbxMaterial( FbxExportGlobals G, string meshNamespace, IExportableMaterial exportableMaterial, HashSet <string> createdMaterialNames) { string materialName; if (exportableMaterial is BrushDescriptor) { // Toolkit uses this guid (in "N" format) to look up a BrushDescriptor. // See Toolkit's ModelImportSettings.GetDescriptorForStroke materialName = $"{exportableMaterial.UniqueName:N}_{meshNamespace}_{exportableMaterial.DurableName}"; } else if (exportableMaterial is DynamicExportableMaterial dem) { // Comes from {fbx,obj,gltf,...} import from {Poly, Media Library} // This is a customized version of a BrushDescriptor -- almost certainly // Pbr{Blend,Opaque}{Double,Single}Sided with maybe an added texture and // some of its params customized. // TBT will merge the material created by Unity for this FbxMaterial with // the premade material it has for the parent guid. materialName = $"{dem.Parent.m_Guid:N}_{meshNamespace}_{dem.DurableName}"; } else { Debug.LogWarning($"Unknown class {exportableMaterial.GetType().Name}"); materialName = $"{meshNamespace}_{exportableMaterial.DurableName}"; } // If only ExportFbx were a non-static class we could merge it with FbxExportGlobals materialName = ExportUtils.CreateUniqueName(materialName, createdMaterialNames); FbxSurfaceLambert material = FbxSurfaceLambert.Create(G.m_scene, materialName); material.Ambient.Set(new FbxDouble3(0, 0, 0)); material.Diffuse.Set(new FbxDouble3(1.0, 1.0, 1.0)); if (exportableMaterial.EmissiveFactor > 0) { material.EmissiveFactor.Set(exportableMaterial.EmissiveFactor); material.Emissive.Set(new FbxDouble3(1.0, 1.0, 1.0)); } if (exportableMaterial.BlendMode != ExportableMaterialBlendMode.None) { var blendMode = FbxProperty.Create(material, Globals.FbxStringDT, "BlendMode"); switch (exportableMaterial.BlendMode) { case ExportableMaterialBlendMode.AlphaMask: blendMode.SetString(new FbxString("AlphaMask")); material.TransparencyFactor.Set(0.2); break; case ExportableMaterialBlendMode.AdditiveBlend: blendMode.SetString(new FbxString("AdditiveBlend")); break; } } // Export the texture if (exportableMaterial.HasExportTexture()) { // This is not perfectly unique, but it is good enough for fbx export // better would be to use <durable>_<guid> but that's ugly, and nobody uses // the textures anyway, so... let's leave well enough alone for now. string albedoTextureName = exportableMaterial.DurableName; var fullTextureDir = Path.Combine(G.m_outputDir, kRelativeTextureDir); if (!Directory.Exists(fullTextureDir)) { if (!FileUtils.InitializeDirectoryWithUserError(fullTextureDir)) { throw new IOException("Cannot write textures"); } } string src = exportableMaterial.GetExportTextureFilename(); var textureFileName = albedoTextureName + ".png"; var textureFilePath = Path.Combine(fullTextureDir, textureFileName); FileInfo srcInfo = new FileInfo(src); if (srcInfo.Exists && !new FileInfo(textureFilePath).Exists) { srcInfo.CopyTo(textureFilePath); } FbxFileTexture texture = FbxFileTexture.Create(G.m_scene, albedoTextureName + "_texture"); texture.SetFileName(textureFilePath); texture.SetTextureUse(FbxTexture.ETextureUse.eStandard); texture.SetMappingType(FbxTexture.EMappingType.eUV); texture.SetMaterialUse(FbxFileTexture.EMaterialUse.eModelMaterial); texture.UVSet.Set(new FbxString("uv0")); material.Diffuse.ConnectSrcObject(texture); material.TransparentColor.ConnectSrcObject(texture); } else { foreach (var kvp in exportableMaterial.TextureUris) { string parameterName = kvp.Key; string textureUri = kvp.Value; if (ExportFileReference.IsHttp(textureUri)) { // fbx can't deal with http references to textures continue; } ExportFileReference fileRef = ExportFileReference.GetOrCreateSafeLocal( G.m_disambiguationContext, textureUri, exportableMaterial.UriBase, $"{meshNamespace}_{Path.GetFileName(textureUri)}"); AddTextureToMaterial(G, fileRef, material, parameterName); } } return(material); }
internal static global::System.Runtime.InteropServices.HandleRef getCPtr(FbxSurfaceLambert obj) { return((obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr); }
public void TestBasics() { Assert.That(!string.IsNullOrEmpty(ModelExporter.GetVersionFromReadme())); // Test GetOrCreateLayer using (var fbxManager = FbxManager.Create()) { var fbxMesh = FbxMesh.Create(fbxManager, "name"); var layer0 = ModelExporter.GetOrCreateLayer(fbxMesh); Assert.That(layer0, Is.Not.Null); Assert.That(ModelExporter.GetOrCreateLayer(fbxMesh), Is.EqualTo(layer0)); var layer5 = ModelExporter.GetOrCreateLayer(fbxMesh, layer: 5); Assert.That(layer5, Is.Not.Null); Assert.That(layer5, Is.Not.EqualTo(layer0)); } // Test axis conversion: a x b in left-handed is the same as b x a // in right-handed (that's why we need to flip the winding order). var a = new Vector3(1, 0, 0); var b = new Vector3(0, 0, 1); var crossLeft = Vector3.Cross(a, b); var afbx = ModelExporter.ConvertToRightHanded(a); var bfbx = ModelExporter.ConvertToRightHanded(b); Assert.AreEqual(ModelExporter.ConvertToRightHanded(crossLeft), bfbx.CrossProduct(afbx)); // Test scale conversion. Nothing complicated here... var afbxPosition = ModelExporter.ConvertToRightHanded(a, ModelExporter.UnitScaleFactor); Assert.AreEqual(100, afbxPosition.Length()); // Test rotation conversion. var q = Quaternion.Euler(new Vector3(0, 90, 0)); var fbxAngles = ModelExporter.ConvertQuaternionToXYZEuler(q); Assert.AreEqual(fbxAngles.X, 0); Assert.That(fbxAngles.Y, Is.InRange(-90.001, -89.999)); Assert.AreEqual(fbxAngles.Z, 0); Assert.That(ModelExporter.DefaultMaterial); // Test non-static functions. using (var fbxManager = FbxManager.Create()) { var fbxScene = FbxScene.Create(fbxManager, "scene"); var fbxNode = FbxNode.Create(fbxScene, "node"); var exporter = new ModelExporter(); // Test ExportMaterial: it exports and it re-exports bool result = exporter.ExportMaterial(ModelExporter.DefaultMaterial, fbxScene, fbxNode); Assert.IsTrue(result); var fbxMaterial = fbxNode.GetMaterial(0); Assert.That(fbxMaterial, Is.Not.Null); result = exporter.ExportMaterial(ModelExporter.DefaultMaterial, fbxScene, fbxNode); var fbxMaterial2 = fbxNode.GetMaterial(1); Assert.AreEqual(fbxMaterial, fbxMaterial2); // Test ExportTexture: it finds the same texture for the default-material (it doesn't create a new one) var fbxMaterialNew = FbxSurfaceLambert.Create(fbxScene, "lambert"); exporter.ExportTexture(ModelExporter.DefaultMaterial, "_MainTex", fbxMaterialNew, FbxSurfaceLambert.sBump); Assert.AreEqual( fbxMaterial.FindProperty(FbxSurfaceLambert.sDiffuse).GetSrcObject(), fbxMaterialNew.FindProperty(FbxSurfaceLambert.sBump).GetSrcObject() ); // Test ExportMesh: make sure we exported a mesh with welded vertices. var cube = GameObject.CreatePrimitive(PrimitiveType.Cube); var cubeNode = FbxNode.Create(fbxScene, "cube"); exporter.ExportMesh(cube.GetComponent <MeshFilter>().sharedMesh, cubeNode); Assert.That(cubeNode.GetMesh(), Is.Not.Null); Assert.That(cubeNode.GetMesh().GetControlPointsCount(), Is.EqualTo(8)); } // Test exporting a skinned-mesh. Make sure it doesn't leak (it did at one point) { var cube = GameObject.CreatePrimitive(PrimitiveType.Cube); var character = new GameObject(); var smr = character.AddComponent <SkinnedMeshRenderer>(); smr.sharedMesh = cube.GetComponent <MeshFilter>().sharedMesh; var meshCount = Object.FindObjectsOfType <Mesh>().Length; ModelExporter.ExportObject(GetRandomFbxFilePath(), character); Assert.AreEqual(meshCount, Object.FindObjectsOfType <Mesh>().Length); } }