Beispiel #1
0
    private static void readMesh(string path, string filename, string texturepath)
    {
        string importingAssetsDir;

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

            IntPtr 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);
            IntPtr scene = Assimp.aiImportFileWithProperties(path + "/" + filename, (uint)flags, config);
            Assimp.aiReleasePropertyStore(config);
            if (scene == null)
            {
                Debug.LogWarning("failed to read file: " + path + "/" + filename);
                return;
            }
            else
            {
                string nm = Path.GetFileNameWithoutExtension(filename);


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

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


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



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



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

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

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

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

                    string texturename = path + "/" + fname;

                    Texture2D tex = null;
                    if (File.Exists(texturename))
                    {
                        tex = (Texture2D)AssetDatabase.LoadAssetAtPath(texturename, typeof(Texture2D));
                    }
                    else
                    if (File.Exists(texturename + ".PNG"))
                    {
                        tex = (Texture2D)AssetDatabase.LoadAssetAtPath(texturename + ".PNG", typeof(Texture2D));
                    }
                    else
                    if (File.Exists(texturename + ".JPG"))
                    {
                        tex = (Texture2D)AssetDatabase.LoadAssetAtPath(texturename + ".JPG", typeof(Texture2D));
                    }
                    else
                    if (File.Exists(texturename + ".BMP"))
                    {
                        tex = (Texture2D)AssetDatabase.LoadAssetAtPath(texturename + ".BMP", typeof(Texture2D));
                    }
                    else
                    if (File.Exists(texturename + ".TGA"))
                    {
                        tex = (Texture2D)AssetDatabase.LoadAssetAtPath(texturename + ".TGA", typeof(Texture2D));
                    }
                    else
                    if (File.Exists(texturename + ".DDS"))
                    {
                        tex = (Texture2D)AssetDatabase.LoadAssetAtPath(texturename + ".DDS", typeof(Texture2D));
                    }

                    if (tex != null)
                    {
                        string 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
                    Quaternion assQuad = Assimp.aiNode_GetRotation(Assimp.aiScene_GetRootNode(scene));
                    ObjectRoot.transform.rotation = assQuad;


                    GameObject skeleton = new GameObject("Skeleton");
                    skeleton.transform.parent = ObjectRoot.transform;
                    processNodes(scene, Assimp.aiScene_GetRootNode(scene), ref listJoints);

                    for (int i = 0; i < listJoints.Count; i++)
                    {
                        AssimpJoint joint = listJoints[i];
                        //Transform bone = GameObject.CreatePrimitive(PrimitiveType.Sphere).transform;
                        Transform 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)
                        {
                            int 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 (int i = 0; i < Assimp.aiScene_GetNumMeshes(scene); i++)
                    {
                        string name = "Mesh_";
                        name += i.ToString();


                        bool HasNormals  = Assimp.aiMesh_HasNormals(scene, i);
                        bool HasTexCoord = Assimp.aiMesh_HasTextureCoords(scene, i, 0);
                        bool HasFaces    = Assimp.aiMesh_HasFaces(scene, i);


                        AssimpMesh mesh = new AssimpMesh(meshContainer, ObjectRoot, name);
                        mesh.setmaterial(materials[Assimp.aiMesh_GetMaterialIndex(scene, i)]);
                        MeshList.Add(mesh);



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

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

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

                            float 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 (int f = 0; f < Assimp.aiMesh_GetNumFaces(scene, i); f++)
                        {
                            int a = Assimp.aiMesh_Indice(scene, i, f, 0);
                            int b = Assimp.aiMesh_Indice(scene, i, f, 1);
                            int c = Assimp.aiMesh_Indice(scene, i, f, 2);
                            mesh.addFace(a, b, c);
                        }



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


                        for (int b = 0; b < numBone; b++)
                        {
                            string      bname  = Assimp.aiMesh_GetBoneName(scene, i, b);
                            AssimpJoint joint  = getBoneByName(bname);
                            int         boneID = findBoneByName(bname);


                            int numWeights = Assimp.aiMesh_GetNumBoneWeights(scene, i, b);
                            for (int w = 0; w < numWeights; w++)
                            {
                                float Weight   = Assimp.aiMesh_GetBoneWeight(scene, i, b, w);
                                int   VertexId = Assimp.aiMesh_GetBoneVertexId(scene, i, b, w);
                                mesh.addBone(VertexId, boneID, Weight);
                            }
                        }

                        for (int j = 0; j < listJoints.Count; j++)
                        {
                            AssimpJoint joint = listJoints[j];
                            mesh.addJoint(joint);
                        }

                        //**********


                        mesh.BuilSkin();
                        mesh.build();
                        mesh.dispose();
                    }
                }

                Mesh m = CombineInstance(ObjectRoot, meshContainer, importingAssetsDir);



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

                    int numAnimation = Assimp.aiScene_GetNumAnimations(scene);

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


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

                        clip.wrapMode = WrapMode.Loop;

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


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



                        int numchannels = Assimp.aiAnim_GetNumChannels(scene, a);
                        for (int i = 0; i < numchannels; i++)
                        {
                            string      name  = Assimp.aiAnim_GetChannelName(scene, a, i);
                            AssimpJoint 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)
                                {
                                    AnimationCurve scaleXcurve = new AnimationCurve();
                                    AnimationCurve scaleYcurve = new AnimationCurve();
                                    AnimationCurve scaleZcurve = new AnimationCurve();

                                    for (int j = 0; j < Assimp.aiAnim_GetNumScalingKeys(scene, a, i); j++)
                                    {
                                        float   time  = (float)Assimp.aiAnim_GetScalingFrame(scene, a, i, j);/// fps;
                                        Vector3 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)
                                {
                                    AnimationCurve posXcurve = new AnimationCurve();
                                    AnimationCurve posYcurve = new AnimationCurve();
                                    AnimationCurve posZcurve = new AnimationCurve();


                                    for (int j = 0; j < Assimp.aiAnim_GetNumPositionKeys(scene, a, i); j++)
                                    {
                                        float   time = (float)Assimp.aiAnim_GetPositionFrame(scene, a, i, j);// / fps;
                                        Vector3 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)
                                {
                                    AnimationCurve rotXcurve = new AnimationCurve();
                                    AnimationCurve rotYcurve = new AnimationCurve();
                                    AnimationCurve rotZcurve = new AnimationCurve();
                                    AnimationCurve rotWcurve = new AnimationCurve();

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

                                        Quaternion 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;

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


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

                MeshList.Clear();
            }

            listJoints.Clear();

            Assimp.aiReleaseImport(scene);
            Debug.LogWarning(path + "/" + filename + " Imported ;) ");
        }
    }
Beispiel #2
0
    public static void readMesh(string path, string filename, string texturepath)
    {
        string importingAssetsDir;

        if (File.Exists(path + "/" + filename))
        {
            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);

            IntPtr config = Assimp.aiCreatePropertyStore();

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

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


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

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


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


                List <Material>   materials = new List <Material>();
                List <AssimpMesh> MeshList  = new List <AssimpMesh>();


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

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

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

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

                    string texturename = path + "/" + fname;

                    Texture2D tex = null;
                    if (File.Exists(texturename))
                    {
                        tex = (Texture2D)AssetDatabase.LoadAssetAtPath(texturename, typeof(Texture2D));
                    }
                    else
                    if (File.Exists(texturename + ".PNG"))
                    {
                        tex = (Texture2D)AssetDatabase.LoadAssetAtPath(texturename + ".PNG", typeof(Texture2D));
                    }
                    else
                    if (File.Exists(texturename + ".JPG"))
                    {
                        tex = (Texture2D)AssetDatabase.LoadAssetAtPath(texturename + ".JPG", typeof(Texture2D));
                    }
                    else
                    if (File.Exists(texturename + ".BMP"))
                    {
                        tex = (Texture2D)AssetDatabase.LoadAssetAtPath(texturename + ".BMP", typeof(Texture2D));
                    }
                    else
                    if (File.Exists(texturename + ".TGA"))
                    {
                        tex = (Texture2D)AssetDatabase.LoadAssetAtPath(texturename + ".TGA", typeof(Texture2D));
                    }
                    else
                    if (File.Exists(texturename + ".DDS"))
                    {
                        tex = (Texture2D)AssetDatabase.LoadAssetAtPath(texturename + ".DDS", typeof(Texture2D));
                    }



                    //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)
                    {
                        string materialAssetPath = AssetDatabase.GenerateUniqueAssetPath(importingAssetsDir + mat.name + ".asset");
                        AssetDatabase.CreateAsset(mat, materialAssetPath);
                    }
                    materials.Add(mat);
                }

                AssetDatabase.Refresh();



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


                        bool HasNormals  = Assimp.aiMesh_HasNormals(scene, i);
                        bool HasTexCoord = Assimp.aiMesh_HasTextureCoords(scene, i, 0);
                        bool HasFaces    = Assimp.aiMesh_HasFaces(scene, i);


                        AssimpMesh mesh = new AssimpMesh(meshContainer, ObjectRoot, name);
                        mesh.setmaterial(materials[Assimp.aiMesh_GetMaterialIndex(scene, i)]);
                        MeshList.Add(mesh);



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


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

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

                            float 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 (int f = 0; f < Assimp.aiMesh_GetNumFaces(scene, i); f++)
                        {
                            int a = Assimp.aiMesh_Indice(scene, i, f, 0);
                            int b = Assimp.aiMesh_Indice(scene, i, f, 1);
                            int c = Assimp.aiMesh_Indice(scene, i, f, 2);
                            mesh.addFace(a, b, c);
                        }



                        //**********



                        mesh.build();


                        if (saveAssets)
                        {
                            string meshAssetPath = AssetDatabase.GenerateUniqueAssetPath(importingAssetsDir + mesh.name + ".asset");
                            AssetDatabase.CreateAsset(mesh.geometry, meshAssetPath);
                        }

                        mesh.dispose();
                    }
                }



                if (saveAssets)
                {
                    string 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 ;) ");
        }
    }