Exemple #1
0
    public void SetDiffuse(string path)
    {
        Material mat = null;

        if (mr != null)
        {
            mat = mr.sharedMaterials[0];
        }
        else if (smr != null)
        {
            mat = smr.sharedMaterials[0];
        }

        if (mat == null)
        {
            return;
        }

        mat.SetTexture("_Diffuse", PdxLoader.LoadDDS(path));

        diffuse = path;
    }
Exemple #2
0
    public void SetNormal(string path)
    {
        Material mat = null;

        if (mr != null)
        {
            mat = mr.sharedMaterials[0];
        }
        else if (smr != null)
        {
            mat = smr.sharedMaterials[0];
        }

        if (mat == null)
        {
            return;
        }

        mat.SetTexture("_Normal", PdxLoader.LoadDDS(path));

        normal = path;
    }
Exemple #3
0
    public void SetSpecular(string path)
    {
        Material mat = null;

        if (mr != null)
        {
            mat = mr.sharedMaterials[0];
        }
        else if (smr != null)
        {
            mat = smr.sharedMaterials[0];
        }

        if (mat == null)
        {
            return;
        }

        mat.SetTexture("_Specular", PdxLoader.LoadDDS(path));

        specular = path;
    }
Exemple #4
0
    public GameObject LoadMesh(string path)
    {
        AssimpContext context = new AssimpContext();
        Scene         scene   = context.ImportFile(path, PostProcessSteps.MakeLeftHanded | PostProcessSteps.FlipWindingOrder);

        if (!scene.HasMeshes)
        {
            return(null);
        }

        List <UnityEngine.Material> snow  = new List <UnityEngine.Material>();
        List <UnityEngine.Material> color = new List <UnityEngine.Material>();
        List <UnityEngine.Material> atlas = new List <UnityEngine.Material>();

        Dictionary <string, Transform> bonesByName = new Dictionary <string, Transform>();
        GameObject goRoot = new GameObject(Path.GetFileName(path));

        float min = 0;

        int idx = 0;

        foreach (Assimp.Mesh sceneMesh in scene.Meshes)
        {
            GameObject go = new GameObject("pShape" + idx);
            go.tag = "Shape";

            bool             skinned = false;
            UnityEngine.Mesh mesh    = new UnityEngine.Mesh();
            mesh.name = "pMeshShape" + idx;

            idx++;

            List <Vector3> vertices = new List <Vector3>();
            List <Vector3> normals  = new List <Vector3>();
            List <Vector2> uv       = new List <Vector2>();
            List <Vector2> uv2      = null;

            List <BoneWeight> boneWeights = new List <BoneWeight>();

            Transform[] bones = null;

            foreach (var sceneVertex in sceneMesh.Vertices)
            {
                vertices.Add(new Vector3(sceneVertex.X, sceneVertex.Y, sceneVertex.Z));
            }

            foreach (var sceneNormal in sceneMesh.Normals)
            {
                normals.Add(new Vector3(sceneNormal.X, sceneNormal.Y, sceneNormal.Z));
            }

            foreach (var sceneUV in sceneMesh.TextureCoordinateChannels[0])
            {
                uv.Add(new Vector2(sceneUV.X, 1f - sceneUV.Y));
            }

            if (sceneMesh.TextureCoordinateChannelCount > 1)
            {
                uv2 = new List <Vector2>();

                foreach (var sceneUV2 in sceneMesh.TextureCoordinateChannels[1])
                {
                    uv2.Add(new Vector2(sceneUV2.X, 1f - sceneUV2.Y));
                }
            }

            Transform rootBone = null;

            if (sceneMesh.HasBones)
            {
                for (int j = 0; j < sceneMesh.VertexCount; j++)
                {
                    boneWeights.Add(new BoneWeight());
                }

                skinned = true;

                bones = new Transform[sceneMesh.BoneCount];

                int boneIndex = 0;
                foreach (var sceneBone in sceneMesh.Bones)
                {
                    GameObject bone = new GameObject(sceneBone.Name);
                    bone.tag = "Bone";

                    UnityEngine.Matrix4x4 matrix = new UnityEngine.Matrix4x4();

                    matrix.SetRow(0, new Vector4(sceneBone.OffsetMatrix.A1, sceneBone.OffsetMatrix.A2, sceneBone.OffsetMatrix.A3, sceneBone.OffsetMatrix.A4));
                    matrix.SetRow(1, new Vector4(sceneBone.OffsetMatrix.B1, sceneBone.OffsetMatrix.B2, sceneBone.OffsetMatrix.B3, sceneBone.OffsetMatrix.B4));
                    matrix.SetRow(2, new Vector4(sceneBone.OffsetMatrix.C1, sceneBone.OffsetMatrix.C2, sceneBone.OffsetMatrix.C3, sceneBone.OffsetMatrix.C4));
                    matrix.SetRow(3, new Vector4(sceneBone.OffsetMatrix.D1, sceneBone.OffsetMatrix.D2, sceneBone.OffsetMatrix.D3, sceneBone.OffsetMatrix.D4));

                    bone.transform.FromMatrix(matrix.inverse);

                    bonesByName[bone.name] = bone.transform;
                    bones[boneIndex]       = bone.transform;

                    if (sceneBone.HasVertexWeights)
                    {
                        for (int i = 0; i < sceneBone.VertexWeights.Count; i++)
                        {
                            BoneWeight bw = boneWeights[sceneBone.VertexWeights[i].VertexID];
                            if (bw.boneIndex0 == 0 && bw.weight0 == 0)
                            {
                                bw.boneIndex0 = boneIndex; bw.weight0 = sceneBone.VertexWeights[i].Weight;
                            }
                            else if (bw.boneIndex1 == 0 && bw.weight1 == 0)
                            {
                                bw.boneIndex1 = boneIndex; bw.weight1 = sceneBone.VertexWeights[i].Weight;
                            }
                            else if (bw.boneIndex2 == 0 && bw.weight2 == 0)
                            {
                                bw.boneIndex2 = boneIndex; bw.weight2 = sceneBone.VertexWeights[i].Weight;
                            }
                            else if (bw.boneIndex3 == 0 && bw.weight3 == 0)
                            {
                                bw.boneIndex3 = boneIndex; bw.weight3 = sceneBone.VertexWeights[i].Weight;
                            }

                            /*if (bw.weight0 < 0.0011f) bw.weight0 = 0f;
                            *  if (bw.weight1 < 0.0011f) bw.weight1 = 0f;
                            *  if (bw.weight2 < 0.0011f) bw.weight2 = 0f;
                            *  if (bw.weight3 < 0.0011f) bw.weight3 = 0f;*/

                            boneWeights[sceneBone.VertexWeights[i].VertexID] = bw;
                        }
                    }

                    boneIndex++;
                }

                foreach (var bone in bonesByName)
                {
                    if (bone.Key.ToLower().Equals("root"))
                    {
                        rootBone = bone.Value;
                    }

                    string parent = "";

                    FindParentInHierarchy(bone.Key, scene.RootNode, out parent);

                    if (parent.Length > 0 && bonesByName.ContainsKey(parent))
                    {
                        bone.Value.SetParent(bonesByName[parent]);
                    }
                    else
                    {
                        bone.Value.SetParent(goRoot.transform);
                    }
                }
            }

            UnityEngine.Matrix4x4[] bindposes = null;

            if (bones != null)
            {
                bindposes = new UnityEngine.Matrix4x4[bones.Length];

                for (int b = 0; b < bones.Length; b++)
                {
                    bindposes[b] = bones[b].worldToLocalMatrix * go.transform.localToWorldMatrix;
                }
            }

            mesh.vertices  = vertices.ToArray();
            mesh.normals   = normals.ToArray();
            mesh.triangles = sceneMesh.GetIndices();
            mesh.uv        = uv.ToArray();

            mesh.RecalculateBounds();
            mesh.RecalculateTangents();

            if (min < mesh.bounds.max.z)
            {
                min = mesh.bounds.max.z;
            }
            //print(mesh.bounds.min.ToString());
            //print(mesh.bounds.max.ToString());

            PdxShape shape = go.AddComponent <PdxShape>();

            Assimp.Material _mat = scene.Materials[sceneMesh.MaterialIndex];

            //print(_mat.Name);

            Shader shader = Shader.Find("PDX/" + _mat.Name);
            shape.shader = _mat.Name;
            if (shader == null)
            {
                shader       = Shader.Find("PDX/PdxMeshStandard");
                shape.shader = "PdxMeshStandard";
            }

            UnityEngine.Material mat = new UnityEngine.Material(shader);
            bool collision           = false;

            switch (shape.shader)
            {
            case "Collision":
                collision = true;
                break;

            case "PdxMeshSnow":
                snow.Add(mat);
                break;

            case "PdxMeshColor":
                color.Add(mat);
                break;

            case "PdxMeshTextureAtlas":
                atlas.Add(mat);
                mat.SetTexture("_Atlas", atlasExample);
                break;
            }

            if (_mat.HasTextureDiffuse)
            {
                if (_mat.TextureDiffuse.FilePath.EndsWith(".dds"))
                {
                    string texPath = _mat.TextureDiffuse.FilePath;
                    if (texPath[1] != ':')
                    {
                        texPath = Path.GetDirectoryName(path) + Path.DirectorySeparatorChar + _mat.TextureDiffuse.FilePath;
                    }

                    if (File.Exists(texPath))
                    {
                        shape.diffuse = texPath;
                        Texture2D tex = PdxLoader.LoadDDS(texPath);
                        tex.name = Path.GetFileName(texPath);
                        mat.SetTexture("_Diffuse", tex);
                    }
                }
            }
            if (_mat.HasTextureHeight)
            {
                if (_mat.TextureHeight.FilePath.EndsWith(".dds"))
                {
                    string texPath = _mat.TextureHeight.FilePath;
                    if (texPath[1] != ':')
                    {
                        texPath = Path.GetDirectoryName(path) + Path.DirectorySeparatorChar + _mat.TextureHeight.FilePath;
                    }

                    if (File.Exists(texPath))
                    {
                        shape.normal = texPath;
                        Texture2D tex = PdxLoader.LoadDDS(texPath);
                        tex.name = Path.GetFileName(texPath);
                        mat.SetTexture("_Normal", tex);
                    }
                }
            }
            if (_mat.HasTextureSpecular)
            {
                if (_mat.TextureSpecular.FilePath.EndsWith(".dds"))
                {
                    string texPath = _mat.TextureSpecular.FilePath;
                    if (texPath[1] != ':')
                    {
                        texPath = Path.GetDirectoryName(path) + Path.DirectorySeparatorChar + _mat.TextureSpecular.FilePath;
                    }

                    if (File.Exists(texPath))
                    {
                        shape.specular = texPath;
                        Texture2D tex = PdxLoader.LoadDDS(texPath);
                        tex.name = Path.GetFileName(texPath);
                        mat.SetTexture("_Specular", tex);
                    }
                }
            }

            if (skinned)
            {
                SkinnedMeshRenderer smr = go.AddComponent <SkinnedMeshRenderer>();
                smr.bones    = bones;
                smr.rootBone = rootBone;

                mesh.bindposes   = bindposes;
                mesh.boneWeights = boneWeights.ToArray();

                smr.sharedMesh = mesh;
                if (collision)
                {
                    smr.sharedMaterial = mat;
                }
                else
                {
                    smr.sharedMaterials = new UnityEngine.Material[] { mat, highlightMaterial }
                };

                shape.smr = smr;
            }
            else
            {
                MeshFilter mf = go.AddComponent <MeshFilter>();
                mf.mesh = mesh;

                MeshRenderer mr = go.AddComponent <MeshRenderer>();
                if (collision)
                {
                    mr.sharedMaterial = mat;
                }
                else
                {
                    mr.sharedMaterials = new UnityEngine.Material[] { mat, highlightMaterial }
                };

                shape.mr = mr;
            }

            go.transform.SetParent(goRoot.transform);
        }

        #region import animation
        foreach (var a in scene.Animations)
        {
            if ((int)a.TicksPerSecond == 1)
            {
                EditorController.instance.Status("Can't load animation with custom frame rate", 1);
                break;
            }

            bool resampled = false;

            if (a.HasNodeAnimations)
            {
                PdxDataService.AnimationData adata = new PdxDataService.AnimationData();
#if UNITY_EDITOR
                print("fps: " + a.TicksPerSecond + ", duration: " + a.DurationInTicks);
#endif
                adata.fps         = 15;// (float)a.TicksPerSecond;
                adata.sampleCount = (int)a.DurationInTicks;
                adata.length      = adata.sampleCount / adata.fps;

                foreach (var nac in a.NodeAnimationChannels)
                {
                    resampled = nac.PositionKeyCount == adata.sampleCount + 1 || nac.RotationKeyCount == adata.sampleCount + 1 || nac.ScalingKeyCount == adata.sampleCount + 1;

                    if (resampled)
                    {
                        break;
                    }
                }

#if UNITY_EDITOR
                print("resampled " + resampled);
#endif

                foreach (var nac in a.NodeAnimationChannels)
                {
                    if (!bonesByName.ContainsKey(nac.NodeName))
                    {
                        continue;
                    }

                    var animation = new PdxDataService.AnimationData.Animation();
                    animation.name = nac.NodeName;

                    animation.parent = bonesByName[nac.NodeName];
                    animation.keys   = new List <PdxDataService.AnimationData.Key>();
                    for (int i = 0; i < adata.sampleCount + 1; i++)
                    {
                        animation.keys.Add(new PdxDataService.AnimationData.Key());
                    }

                    animation.keys[0].pos = animation.parent.transform.localPosition;
                    animation.keys[0].rot = animation.parent.transform.localRotation;
                    animation.keys[0].scl = animation.parent.transform.localScale;

                    //animation.sampleT = true; // or joint mistmatch error

                    if (nac.HasPositionKeys)
                    {
                        if (resampled)
                        {
                            foreach (var pk in nac.PositionKeys)
                            {
                                int i = (int)pk.Time + 1;
                                if (i >= animation.keys.Count)
                                {
                                    break;
                                }

                                animation.keys[i].pos  = new Vector3(pk.Value.X, pk.Value.Y, pk.Value.Z);
                                animation.keys[i].time = (float)pk.Time / (float)adata.fps;
                            }
                        }
                        else
                        {
                            List <VectorKey> posKeys = nac.PositionKeys;
                            if (ListVectorKey(ref posKeys, adata.sampleCount))
                            {
                                animation.sampleT = true;

                                foreach (var pk in posKeys)
                                {
                                    int i = (int)pk.Time + 1;
                                    if (i >= animation.keys.Count)
                                    {
                                        break;
                                    }

                                    animation.keys[i].pos  = new Vector3(pk.Value.X, pk.Value.Y, pk.Value.Z);
                                    animation.keys[i].time = (float)pk.Time / (float)adata.fps;
                                }
                            }
                        }
                    }

                    if (nac.HasRotationKeys)
                    {
                        if (resampled)
                        {
                            foreach (var rk in nac.RotationKeys)
                            {
                                int i = (int)rk.Time + 1;
                                if (i >= animation.keys.Count)
                                {
                                    break;
                                }

                                animation.keys[i].rot  = new UnityEngine.Quaternion(rk.Value.X, rk.Value.Y, rk.Value.Z, rk.Value.W);
                                animation.keys[i].time = (float)rk.Time / (float)adata.fps;
                            }
                        }
                        else
                        {
                            List <QuaternionKey> rotKeys = nac.RotationKeys;
                            if (ListQuaternionKey(ref rotKeys, adata.sampleCount))
                            {
                                animation.sampleQ = true;

                                foreach (var rk in rotKeys)
                                {
                                    int i = (int)rk.Time + 1;
                                    if (i >= animation.keys.Count)
                                    {
                                        break;
                                    }

                                    animation.keys[i].rot  = new UnityEngine.Quaternion(rk.Value.X, rk.Value.Y, rk.Value.Z, rk.Value.W);
                                    animation.keys[i].time = (float)rk.Time / (float)adata.fps;
                                }
                            }
                        }
                    }

                    if (nac.HasScalingKeys)
                    {
                        if (resampled)
                        {
                            foreach (var sk in nac.ScalingKeys)
                            {
                                int i = (int)sk.Time + 1;
                                if (i >= animation.keys.Count)
                                {
                                    break;
                                }

                                animation.keys[i].scl  = new Vector3(sk.Value.X, sk.Value.Y, sk.Value.Z);
                                animation.keys[i].time = (float)sk.Time / (float)adata.fps;
                            }
                        }
                        else
                        {
                            List <VectorKey> sclKeys = nac.ScalingKeys;
                            if (ListVectorKey(ref sclKeys, adata.sampleCount))
                            {
                                animation.sampleS = true;

                                foreach (var sk in sclKeys)
                                {
                                    int i = (int)sk.Time + 1;
                                    if (i >= animation.keys.Count)
                                    {
                                        break;
                                    }

                                    animation.keys[i].scl  = new Vector3(sk.Value.X, sk.Value.Y, sk.Value.Z);
                                    animation.keys[i].time = (float)sk.Time / (float)adata.fps;
                                }
                            }
                        }
                    }

                    adata.hierarchy.Add(animation);
                }

                var player = goRoot.AddComponent <PdxAnimationPlayer>();
                adata.Fix();
                player.animationData = adata;
            }
        }
        #endregion

        EditorController.instance.SceneHasSnowMaterial(snow.Count > 0 ? snow.ToArray() : null);
        EditorController.instance.SceneHasColorMaterial(color.Count > 0 ? color.ToArray() : null);
        EditorController.instance.SceneHasAtlasMaterial(atlas.Count > 0 ? atlas.ToArray() : null);

        if (!path.ToLower().EndsWith(".obj"))
        {
            goRoot.transform.Translate(0, min, 0, Space.World);
            goRoot.transform.rotation = UnityEngine.Quaternion.Euler(90, 0, 0);
        }

        context.Dispose();

        return(goRoot);
    }