Beispiel #1
0
        public static void ReadMesh(string path, string filename, string texturepath)
        {
            if (File.Exists(path + "/" + filename))
            {
                const Assimp.PostProcessSteps flags = (
                    //        Assimp.PostProcessSteps.MakeLeftHanded |

                    Assimp.PostProcessSteps.OptimizeMeshes |
                    Assimp.PostProcessSteps.OptimizeGraph |
                    Assimp.PostProcessSteps.RemoveRedundantMaterials |
                    Assimp.PostProcessSteps.SortByPrimitiveType |
                    Assimp.PostProcessSteps.SplitLargeMeshes |
                    Assimp.PostProcessSteps.Triangulate |
                    Assimp.PostProcessSteps.CalculateTangentSpace |
                    Assimp.PostProcessSteps.GenerateUVCoords |
                    Assimp.PostProcessSteps.GenerateSmoothNormals |
                    Assimp.PostProcessSteps.RemoveComponent |
                    Assimp.PostProcessSteps.JoinIdenticalVertices
                    );

                var config = Assimp.aiCreatePropertyStore();

                Assimp.aiSetImportPropertyFloat(config, Assimp.AI_CONFIG_PP_CT_MAX_SMOOTHING_ANGLE, 60.0f);

                // IntPtr scene = Assimp.aiImportFile(path + "/" + filename, (uint)flags);
                var scene = Assimp.aiImportFileWithProperties(path + "/" + filename, (uint)flags, config);
                Assimp.aiReleasePropertyStore(config);
                if (scene == null)
                {
                    Debug.LogWarning("failed to read file: " + path + "/" + filename);
                    return;
                }
                else
                {
                    var nm = Path.GetFileNameWithoutExtension(filename);

                    var importingAssetsDir = "Assets/Prefabs/" + nm + "/";

                    if (_SaveAssets)
                    {
                        if (!Directory.Exists(importingAssetsDir))
                        {
                            Directory.CreateDirectory(importingAssetsDir);
                        }
                        AssetDatabase.Refresh();
                    }

                    var objectRoot    = new GameObject(nm);
                    var meshContainer = new GameObject(nm + "_Mesh");
                    meshContainer.transform.parent = objectRoot.transform;

                    var materials = new List <Material>();
                    var meshList  = new List <AssimpMesh>();

                    for (var i = 0; i < Assimp.aiScene_GetNumMaterials(scene); i++)
                    {
                        var matName = Assimp.aiMaterial_GetName(scene, i);
                        matName = nm + "_mat" + i;

                        //  string fname = Path.GetFileNameWithoutExtension(Assimp.aiMaterial_GetTexture(scene, i, (int)Assimp.TextureType.Diffuse));
                        var file_name = Path.GetFileName(Assimp.aiMaterial_GetTexture(scene, i, (int)Assimp.TextureType.Diffuse));
                        Debug.Log("texture " + file_name + "Material :" + matName);

                        var ambient  = Assimp.aiMaterial_GetAmbient(scene, i);
                        var diffuse  = Assimp.aiMaterial_GetDiffuse(scene, i);
                        var specular = Assimp.aiMaterial_GetSpecular(scene, i);
                        var emissive = Assimp.aiMaterial_GetEmissive(scene, i);

                        var mat = new Material(Shader.Find("Diffuse"))
                        {
                            name = matName
                        };

                        var textureName = path + "/" + file_name;

                        var tex = Utils.LoadTex(textureName);

                        //Texture2D tex = Resources.Load(texturename) as Texture2D;
                        //Texture2D tex = (Texture2D)AssetDatabase.LoadAssetAtPath(texturename, typeof(Texture2D));
                        if (tex != null)
                        {
                            Debug.Log("LOAD (" + textureName + ") texture");
                            mat.SetTexture("_MainTex", tex);
                        }
                        else
                        {
                            Debug.LogError("Fail LOAD (" + textureName + ") error");
                        }

                        if (_SaveAssets)
                        {
                            var materialAssetPath = AssetDatabase.GenerateUniqueAssetPath(importingAssetsDir + mat.name + ".asset");
                            AssetDatabase.CreateAsset(mat, materialAssetPath);
                        }
                        materials.Add(mat);
                    }

                    AssetDatabase.Refresh();

                    if (Assimp.aiScene_HasMeshes(scene))
                    {
                        for (var i = 0; i < Assimp.aiScene_GetNumMeshes(scene); i++)
                        {
                            var name = "Mesh_";
                            name += i.ToString();

                            var hasNormals  = Assimp.aiMesh_HasNormals(scene, i);
                            var hasTexCoord = Assimp.aiMesh_HasTextureCoords(scene, i, 0);
                            var hasFaces    = Assimp.aiMesh_HasFaces(scene, i);

                            var mesh = new AssimpMesh(meshContainer, objectRoot, name);
                            mesh.SetMaterial(materials[Assimp.aiMesh_GetMaterialIndex(scene, i)]);
                            meshList.Add(mesh);

                            for (var v = 0; v < Assimp.aiMesh_GetNumVertices(scene, i); v++)
                            {
                                var vertex = Assimp.aiMesh_Vertex(scene, i, v);
                                var n      = Assimp.aiMesh_Normal(scene, i, v);
                                var x      = Assimp.aiMesh_TextureCoordX(scene, i, v, 0);
                                var y      = Assimp.aiMesh_TextureCoordY(scene, i, v, 0);

                                var binormalf     = Assimp.aiMesh_Bitangent(scene, i, v);
                                var tangentf      = Assimp.aiMesh_Tangent(scene, i, v);
                                var outputTangent = new Vector4(tangentf.x, tangentf.y, tangentf.z, 0.0F);

                                var dp = Vector3.Dot(Vector3.Cross(n, tangentf), binormalf);
                                if (dp > 0.0F)
                                {
                                    outputTangent.w = 1.0F;
                                }
                                else
                                {
                                    outputTangent.w = -1.0F;
                                }

                                mesh.AddVertex(vertex, n, new Vector2(x, y), outputTangent);
                                //mesh.addVertex(vertex, new Vector3(1 * -n.x, n.y, n.z), new Vector2(x, y), outputTangent);
                            }

                            for (var f = 0; f < Assimp.aiMesh_GetNumFaces(scene, i); f++)
                            {
                                var a = Assimp.aiMesh_Indice(scene, i, f, 0);
                                var b = Assimp.aiMesh_Indice(scene, i, f, 1);
                                var c = Assimp.aiMesh_Indice(scene, i, f, 2);
                                mesh.AddFace(a, b, c);
                            }

                            //**********
                            mesh.Build();
                            if (_SaveAssets)
                            {
                                var meshAssetPath = AssetDatabase.GenerateUniqueAssetPath(importingAssetsDir + mesh._Name + ".asset");
                                AssetDatabase.CreateAsset(mesh._Geometry, meshAssetPath);
                            }

                            mesh.Dispose();
                        }
                    }

                    if (_SaveAssets)
                    {
                        var prefabPath = AssetDatabase.GenerateUniqueAssetPath(importingAssetsDir + filename + ".prefab");
                        var prefab     = PrefabUtility.CreateEmptyPrefab(prefabPath);
                        PrefabUtility.ReplacePrefab(objectRoot, prefab, ReplacePrefabOptions.ConnectToPrefab);
                        AssetDatabase.Refresh();
                    }

                    meshList.Clear();
                }
                Assimp.aiReleaseImport(scene);
                Debug.LogWarning(path + "/" + filename + " Imported ;) ");
            }
        }
        private static void ReadMesh(string path, string filename, string texturepath)
        {
            string importingAssetsDir;

            if (File.Exists(path + "/" + filename))
            {
                var flags = (
                    //  Assimp.PostProcessSteps.MakeLeftHanded |
                    Assimp.PostProcessSteps.Triangulate |
                    Assimp.PostProcessSteps.CalculateTangentSpace |
                    Assimp.PostProcessSteps.GenerateUVCoords |
                    Assimp.PostProcessSteps.GenerateSmoothNormals |
                    Assimp.PostProcessSteps.RemoveComponent |
                    Assimp.PostProcessSteps.JoinIdenticalVertices
                    );

                var config = Assimp.aiCreatePropertyStore();

                Assimp.aiSetImportPropertyFloat(config, Assimp.AI_CONFIG_PP_CT_MAX_SMOOTHING_ANGLE, 60.0f);
                Assimp.aiSetImportPropertyInteger(config, Assimp.AI_CONFIG_PP_LBW_MAX_WEIGHTS, 4);
                // IntPtr scene = Assimp.aiImportFile(path + "/" + filename, (uint)flags);
                var scene = Assimp.aiImportFileWithProperties(path + "/" + filename, (uint)flags, config);
                Assimp.aiReleasePropertyStore(config);
                if (scene == null)
                {
                    Debug.LogWarning("failed to read file: " + path + "/" + filename);
                    return;
                }
                else
                {
                    var nm = Path.GetFileNameWithoutExtension(filename);
                    importingAssetsDir = "Assets/Prefabs/" + nm + "/";
                    if (_SaveAssets)
                    {
                        if (!Directory.Exists(importingAssetsDir))
                        {
                            Directory.CreateDirectory(importingAssetsDir);
                        }
                        AssetDatabase.Refresh();
                    }
                    var objectRoot    = new GameObject(nm);
                    var meshContainer = new GameObject(nm + "_Mesh");
                    meshContainer.transform.parent = objectRoot.transform;

                    //  List<CombineInstance> combineInstances = new List<CombineInstance>();
                    var materials = new List <Material>();
                    var meshList  = new List <AssimpMesh>();

                    for (var i = 0; i < Assimp.aiScene_GetNumMaterials(scene); i++)
                    {
                        var matName = Assimp.aiMaterial_GetName(scene, i);
                        matName = nm + "_mat" + i;

                        //  string fname = Path.GetFileNameWithoutExtension(Assimp.aiMaterial_GetTexture(scene, i, (int)Assimp.TextureType.Diffuse));
                        var fname = Path.GetFileName(Assimp.aiMaterial_GetTexture(scene, i, (int)Assimp.TextureType.Diffuse));
                        Debug.Log("texture " + fname + "Material :" + matName);

                        var ambient  = Assimp.aiMaterial_GetAmbient(scene, i);
                        var diffuse  = Assimp.aiMaterial_GetDiffuse(scene, i);
                        var specular = Assimp.aiMaterial_GetSpecular(scene, i);
                        var emissive = Assimp.aiMaterial_GetEmissive(scene, i);

                        var mat = new Material(Shader.Find("Diffuse"));
                        mat.name = matName;

                        var texturename = path + "/" + fname;

                        var tex = Utils.LoadTex(texturename);

                        if (tex != null)
                        {
                            var p = AssetDatabase.GetAssetPath(tex);
                            ConfigureForAtlas(p);
                            Debug.Log("LOAD (" + texturename + ") texture");
                            mat.SetTexture("_MainTex", tex);
                        }
                        else
                        {
                            Debug.LogError("Fail LOAD (" + texturename + ") error");
                        }
                        materials.Add(mat);
                    }
                    AssetDatabase.Refresh();
                    if (Assimp.aiScene_GetRootNode(scene) != null)
                    {
                        objectRoot.transform.position = Assimp.aiNode_GetPosition(Assimp.aiScene_GetRootNode(scene));

                        //assimp quaternion is w,x,y,z and unity x,y,z,w bu int this lib i fix this for unity
                        var assQuad = Assimp.aiNode_GetRotation(Assimp.aiScene_GetRootNode(scene));
                        objectRoot.transform.rotation = assQuad;

                        var skeleton = new GameObject("Skeleton");
                        skeleton.transform.parent = objectRoot.transform;
                        ProcessNodes(scene, Assimp.aiScene_GetRootNode(scene), ref _list_joints);

                        for (var i = 0; i < _list_joints.Count; i++)
                        {
                            var joint = _list_joints[i];
                            //Transform bone = GameObject.CreatePrimitive(PrimitiveType.Sphere).transform;
                            var bone = new GameObject(joint._Name).transform;
                            //   DebugBone debug = (DebugBone)bone.gameObject.AddComponent(typeof(DebugBone));

                            bone.name   = joint._Name;
                            bone.parent = skeleton.transform;

                            if (GetBoneByName(joint._ParentName) != null)
                            {
                                var index = FindBoneByName(joint._ParentName);
                                bone.parent = joint._Parent._Transform;
                            }
                            bone.localPosition = joint._Position;
                            bone.localRotation = joint._Orientation;

                            joint._Transform = bone;
                        }
                    }
                    if (Assimp.aiScene_HasMeshes(scene))
                    {
                        for (var i = 0; i < Assimp.aiScene_GetNumMeshes(scene); i++)
                        {
                            var name = "Mesh_";
                            name += i.ToString();

                            var hasNormals  = Assimp.aiMesh_HasNormals(scene, i);
                            var hasTexCoord = Assimp.aiMesh_HasTextureCoords(scene, i, 0);
                            var hasFaces    = Assimp.aiMesh_HasFaces(scene, i);

                            var mesh = new AssimpMesh(meshContainer, objectRoot, name);
                            mesh.Setmaterial(materials[Assimp.aiMesh_GetMaterialIndex(scene, i)]);
                            meshList.Add(mesh);

                            for (var v = 0; v < Assimp.aiMesh_GetNumVertices(scene, i); v++)
                            {
                                var vertex = Assimp.aiMesh_Vertex(scene, i, v);
                                var n      = Assimp.aiMesh_Normal(scene, i, v);
                                var x      = Assimp.aiMesh_TextureCoordX(scene, i, v, 0);
                                var y      = Assimp.aiMesh_TextureCoordY(scene, i, v, 0);

                                var binormalf = Assimp.aiMesh_Bitangent(scene, i, v);
                                var tangentf  = Assimp.aiMesh_Tangent(scene, i, v);

                                var outputTangent = new Vector4(tangentf.x, tangentf.y, tangentf.z, 0.0F);

                                var dp = Vector3.Dot(Vector3.Cross(n, tangentf), binormalf);
                                if (dp > 0.0F)
                                {
                                    outputTangent.w = 1.0F;
                                }
                                else
                                {
                                    outputTangent.w = -1.0F;
                                }
                                mesh.AddVertex(vertex, n, outputTangent, new Vector2(x, y));
                            }

                            for (var f = 0; f < Assimp.aiMesh_GetNumFaces(scene, i); f++)
                            {
                                var a = Assimp.aiMesh_Indice(scene, i, f, 0);
                                var b = Assimp.aiMesh_Indice(scene, i, f, 1);
                                var c = Assimp.aiMesh_Indice(scene, i, f, 2);
                                mesh.AddFace(a, b, c);
                            }

                            //****
                            var numBone = Assimp.aiMesh_GetNumBones(scene, i);

                            for (var b = 0; b < numBone; b++)
                            {
                                var bname  = Assimp.aiMesh_GetBoneName(scene, i, b);
                                var joint  = GetBoneByName(bname);
                                var boneId = FindBoneByName(bname);

                                var numWeights = Assimp.aiMesh_GetNumBoneWeights(scene, i, b);
                                for (var w = 0; w < numWeights; w++)
                                {
                                    var weight   = Assimp.aiMesh_GetBoneWeight(scene, i, b, w);
                                    var vertexId = Assimp.aiMesh_GetBoneVertexId(scene, i, b, w);
                                    mesh.AddBone(vertexId, boneId, weight);
                                }
                            }

                            for (var j = 0; j < _list_joints.Count; j++)
                            {
                                var joint = _list_joints[j];
                                mesh.AddJoint(joint);
                            }

                            //**********
                            mesh.BuilSkin();
                            mesh.Build();
                            mesh.Dispose();
                        }
                    }

                    var m = CombineInstance(objectRoot, meshContainer, importingAssetsDir);

                    //create key frames
                    if (Assimp.aiScene_HasAnimation(scene))
                    {
                        var anim = (Animation)objectRoot.AddComponent(typeof(Animation));

                        var numAnimation = Assimp.aiScene_GetNumAnimations(scene);

                        Debug.Log("count animation  :" + numAnimation);

                        for (var a = 0; a < numAnimation; a++)
                        {
                            var clip  = new AnimationClip();
                            var anima = Assimp.aiAnim_GetName(scene, a);
                            clip.name     = nm + "_" + anima + "_" + a;
                            clip.legacy   = true;
                            clip.wrapMode = WrapMode.Loop;

                            var tinks = (float)Assimp.aiAnim_GetTicksPerSecond(scene, a);
                            if (tinks <= 1f)
                            {
                                tinks = 1f;
                            }
                            var fps = tinks;
                            clip.frameRate = tinks;

                            Debug.Log("animation fps :" + fps);

                            var numchannels = Assimp.aiAnim_GetNumChannels(scene, a);
                            for (var i = 0; i < numchannels; i++)
                            {
                                var name  = Assimp.aiAnim_GetChannelName(scene, a, i);
                                var joint = GetBoneByName(name);

                                //  Debug.Log(String.Format("anim channel {0} bone name {1}  poskeys {2}  rotkeys{2}", i, name, Assimp.aiAnim_GetNumPositionKeys(scene, 0, i), Assimp.aiAnim_GetNumRotationKeys(scene, 0, i)));

                                //public static bool ignoreRotations = true;
                                // public static bool ignorePositions = true;
                                // public static bool ignoreScalling = true;

                                if (!_IgnoreScalling)
                                {
                                    if (Assimp.aiAnim_GetNumScalingKeys(scene, a, i) != 0)
                                    {
                                        var scaleXcurve = new AnimationCurve();
                                        var scaleYcurve = new AnimationCurve();
                                        var scaleZcurve = new AnimationCurve();

                                        for (var j = 0; j < Assimp.aiAnim_GetNumScalingKeys(scene, a, i); j++)
                                        {
                                            var time  = (float)Assimp.aiAnim_GetScalingFrame(scene, a, i, j);/// fps;
                                            var scale = Assimp.aiAnim_GetScalingKey(scene, a, i, j);
                                            //    time = (float)j;
                                            scaleXcurve.AddKey(time, scale.x);
                                            scaleYcurve.AddKey(time, scale.y);
                                            scaleZcurve.AddKey(time, scale.z);
                                        }
                                        clip.SetCurve("Skeleton/" + joint._Path, typeof(Transform), "m_LocalScale.x", scaleXcurve);
                                        clip.SetCurve("Skeleton/" + joint._Path, typeof(Transform), "m_LocalScale.y", scaleYcurve);
                                        clip.SetCurve("Skeleton/" + joint._Path, typeof(Transform), "m_LocalScale.z", scaleZcurve);
                                    }
                                }

                                if (!_IgnorePositions)
                                {
                                    if (Assimp.aiAnim_GetNumPositionKeys(scene, a, i) != 0)
                                    {
                                        var posXcurve = new AnimationCurve();
                                        var posYcurve = new AnimationCurve();
                                        var posZcurve = new AnimationCurve();

                                        for (var j = 0; j < Assimp.aiAnim_GetNumPositionKeys(scene, a, i); j++)
                                        {
                                            var time = (float)Assimp.aiAnim_GetPositionFrame(scene, a, i, j);// / fps;
                                            var pos  = Assimp.aiAnim_GetPositionKey(scene, a, i, j);
                                            //    time = (float)j;
                                            posXcurve.AddKey(time, pos.x);
                                            posYcurve.AddKey(time, pos.y);
                                            posZcurve.AddKey(time, pos.z);
                                        }

                                        clip.SetCurve("Skeleton/" + joint._Path, typeof(Transform), "localPosition.x", posXcurve);
                                        clip.SetCurve("Skeleton/" + joint._Path, typeof(Transform), "localPosition.y", posYcurve);
                                        clip.SetCurve("Skeleton/" + joint._Path, typeof(Transform), "localPosition.z", posZcurve);
                                    }
                                }

                                if (!_IgnoreRotations)
                                {
                                    if (Assimp.aiAnim_GetNumRotationKeys(scene, a, i) != 0)
                                    {
                                        var rotXcurve = new AnimationCurve();
                                        var rotYcurve = new AnimationCurve();
                                        var rotZcurve = new AnimationCurve();
                                        var rotWcurve = new AnimationCurve();

                                        for (var j = 0; j < Assimp.aiAnim_GetNumRotationKeys(scene, a, i); j++)
                                        {
                                            var time = (float)Assimp.aiAnim_GetRotationFrame(scene, a, i, j);// / fps;

                                            var rotation = Assimp.aiAnim_GetRotationKey(scene, a, i, j);
                                            //    time = (float)j;
                                            rotXcurve.AddKey(time, rotation.x);
                                            rotYcurve.AddKey(time, rotation.y);
                                            rotZcurve.AddKey(time, rotation.z);
                                            rotWcurve.AddKey(time, rotation.w);
                                        }

                                        clip.SetCurve("Skeleton/" + joint._Path, typeof(Transform), "localRotation.x", rotXcurve);
                                        clip.SetCurve("Skeleton/" + joint._Path, typeof(Transform), "localRotation.y", rotYcurve);
                                        clip.SetCurve("Skeleton/" + joint._Path, typeof(Transform), "localRotation.z", rotZcurve);
                                        clip.SetCurve("Skeleton/" + joint._Path, typeof(Transform), "localRotation.w", rotWcurve);
                                    }
                                }
                            }

                            clip.EnsureQuaternionContinuity();
                            anim.AddClip(clip, clip.name);
                            anim.clip = clip;

                            var clipAssetPath = AssetDatabase.GenerateUniqueAssetPath(importingAssetsDir + clip.name + ".asset");
                            AssetDatabase.CreateAsset(clip, clipAssetPath);
                        }
                    }

                    if (_SaveAssets)
                    {
                        var prefabPath = AssetDatabase.GenerateUniqueAssetPath(importingAssetsDir + filename + ".prefab");
                        var prefab     = PrefabUtility.CreateEmptyPrefab(prefabPath);
                        PrefabUtility.ReplacePrefab(objectRoot, prefab, ReplacePrefabOptions.ConnectToPrefab);
                        AssetDatabase.Refresh();
                    }

                    meshList.Clear();
                }

                _list_joints.Clear();

                Assimp.aiReleaseImport(scene);
                Debug.LogWarning(path + "/" + filename + " Imported ;) ");
            }
        }