Example #1
0
    /// <summary>
    /// Internal method, applies delta offset translation for each morph.
    /// </summary>
    /// <remarks>
    /// we may want to tally the totals once and apply it once.
    /// </remarks>>
    private void ApplyBindPoseChanges(JCTMorph morph)
    {
        float v = morph.m_value;         //range is 0->1 (used as a percent for the deltas below)

        if (morph.m_nodes != null && current_bind_poses.Length == morph.m_nodes.Length)
        {
            for (int i = 0; i < current_bind_poses.Length; i++)
            {
                current_bone_positions[i] += morph.m_offsets[i] * v;
                current_bind_poses[i][12] -= morph.m_nodes[i].x * v;                 //updating the x translation value of the matrix
                current_bind_poses[i][13] -= morph.m_nodes[i].y * v;                 //updating the y translation value of the matrix
                current_bind_poses[i][14] -= morph.m_nodes[i].z * v;                 //updating the z translation value of the matrix
            }
        }
    }
Example #2
0
        /// <summary>
        /// Creates the JCT transition on import. Passing in the Exact geometry GameObject, one at a time.
        /// </summary>
        /// <param name="destination">Destination GameObject.</param>
        /// <param name="go">GameObject with geometry.</param>
        /// <param name="geometryId">Geometry identifier.</param>
        /// <param name="asset_path">Asset path.</param>
        public static void CreateJCTTransitionOnImport(GameObject destination, GameObject go, string geometryId, string asset_path)
        {
            // Morpher morpher  = obj.transform.parent.gameObject.GetComponentInChildren (typeof (Morpher)) as Morpher;
            SkinnedMeshRenderer skinned_mesh_renderer = go.GetComponent <SkinnedMeshRenderer> ();

            // we'll skip calling handleskinnedmeshrenderer and just do what it does here but streamline it for our usage
            Transform[] bones = skinned_mesh_renderer.bones;
            // the importer passes in the path
            string assetPath = asset_path;

            string baseName = geometryId;


            //first let's look for the "new" way, which is a JCTs.json file that sits next to the .fbx file, if we can't find anything we'll fall back
            string jsonPath = assetPath.Substring(0, assetPath.LastIndexOf("/")) + "/JCTs.json";

            if (File.Exists(jsonPath))
            {
                //UnityEngine.Debug.Log ("I found a JCTs.json file: " + jsonPath + " , unpacking and using");
                JCTsPacked packed = JsonUtility.FromJson <JCTsPacked> (File.ReadAllText(jsonPath));

                Regex basePattern     = new Regex(baseName + @"\.base$");
                Regex baseNamePattern = new Regex(baseName);

                //we need to get the base first...

                string[]  baseNames   = null;
                Vector3[] baseNodes   = null;
                Vector3[] baseOffsets = null;

                bool foundBase = false;

                //convert XYZFemale_LOD0.Aged_Posture to Aged_Posture, this is for dual compatibility
                for (int i = 0; i < packed.names.Length; i++)
                {
                    int pos = packed.names[i].IndexOf('.');
                    if (pos >= 0)
                    {
                        packed.names[i] = packed.names[i].Substring(pos + 1);
                    }
                }

                //UnityEngine.Debug.Log("Packed file contains: " + packed.count + " | " + packed.names.Length + " | " + packed.jcts.Length);

                for (int i = 0; i < packed.count; i++)
                {
                    if (packed.names[i].Equals("base"))
                    {
                        //found the base

                        Stream stream = new MemoryStream(Encoding.UTF8.GetBytes(packed.jcts[i]));


                        using (StreamReader reader = new StreamReader(stream)){
                            getJCTDataFromStream(reader, out baseNames, out baseNodes, out baseOffsets);
                        }
                        foundBase = true;
                        break;
                    }
                }

                if (!foundBase)
                {
                    UnityEngine.Debug.LogWarning("Unable to locate base morph in JCT file, this means JCTs WILL NOT WORK");
                }

                if (foundBase)
                {
                    int[]           nodeMap  = calcNodeMap(bones, baseNames);
                    List <JCTMorph> jct_list = new List <JCTMorph> ();

                    //loop again and put the regular ones in

                    for (int j = 0; j < packed.count; j++)
                    {
                        //if (baseNamePattern.Match (packed.names [j]).Success) { //pre 1.5
                        Stream    stream = new MemoryStream(Encoding.UTF8.GetBytes(packed.jcts [j]));
                        string[]  morph_names;
                        Vector3[] nodes;
                        Vector3[] offsets;

                        string morph_name = Unescape(packed.names [j]);

                        using (StreamReader reader = new StreamReader(stream)) {
                            getJCTDataFromStream(reader, out morph_names, out nodes, out offsets);



                            JCTMorph morph = new JCTMorph();
                            morph.m_name  = morph_name;
                            morph.m_value = 0;

                            bool      hasNodeDelta = false;
                            Vector3[] nodeDeltas   = new Vector3[bones.Length];

                            Vector3[] nodeOffsets = new Vector3[bones.Length];
                            for (int i = 0; i < bones.Length; i++)
                            {
                                int ii = nodeMap [i];
                                nodeDeltas [i]  = nodes [ii] - baseNodes [ii];
                                nodeOffsets [i] = offsets [ii] - baseOffsets [ii];
                                if (nodeDeltas [i].sqrMagnitude > Mathf.Epsilon)
                                {
                                    hasNodeDelta = true;
                                }
                            }
                            if (hasNodeDelta)
                            {
                                morph.m_nodes   = nodeDeltas;
                                morph.m_offsets = nodeOffsets;

                                jct_list.Add(morph);
                            }
                        }
                        //}
                    }

                    if (jct_list.Count <= 0)
                    {
                        UnityEngine.Debug.LogWarning("JCT morph list is empty, morphs that affect bones will not work properly");
                    }

                    JCTMorph[] morphs = jct_list.ToArray();

                    // add the data to the jct_adapter
                    JCTTransition jct_adapter = destination.GetComponent <JCTTransition> ();
                    // if (jct_adapter == null) {
                    jct_adapter = destination.AddComponent <JCTTransition> ();
                    // added by jesse for a compelte reference to all bones - theoretically since it comes from the figure mesh
                    // jct_adapter.mesh_skeleton = skinned_mesh_renderer.bones;
                    // }

                    jct_adapter.m_morphs  = morphs;
                    jct_adapter.hideFlags = HideFlags.HideInInspector;
                    // morpher.m_duplicates = duplicates;
                    jct_adapter.CreationSetup(skinned_mesh_renderer);

                    return;
                }
            }



            //LEGACY (1.0 way)


            // need root folder

            string morphFolder = assetPath.Substring(0, assetPath.LastIndexOf("/")) + "/Morphs";


            string baseFile = morphFolder + "/" + baseName + ".base.morph";

            if (File.Exists(baseFile) == true)
            {
                string[]  baseNames;
                Vector3[] baseNodes;
                Vector3[] baseOffsets;

                // root bone position data. all bones are stored in absolute format. we need both to put them in relative positioning
                getJCTDataFromFile(baseFile, out baseNames, out baseNodes, out baseOffsets);

                int[]           nodeMap  = calcNodeMap(bones, baseNames);
                string[]        files    = Directory.GetFiles(morphFolder, baseName + ".*.morph");
                List <JCTMorph> jct_list = new List <JCTMorph> ();

                foreach (var file in files)
                {
                    if (File.Exists(file) == true)
                    {
                        string[]  morph_names;
                        Vector3[] nodes;
                        Vector3[] offsets;
                        getJCTDataFromFile(file, out morph_names, out nodes, out offsets);

                        // we parse the file name to get the morph name
                        char[]   splitter   = { '\\', '/' };
                        string[] parts      = file.Split(splitter);
                        string   morph_name = parts [parts.Length - 1];
                        char[]   splitter1  = { '.' };
                        parts      = morph_name.Split(splitter1);
                        morph_name = Unescape(parts [1]);



                        JCTMorph morph = new JCTMorph();
                        morph.m_name  = morph_name;
                        morph.m_value = 0;

                        bool      hasNodeDelta = false;
                        Vector3[] nodeDeltas   = new Vector3[bones.Length];

                        Vector3[] nodeOffsets = new Vector3[bones.Length];
                        for (int i = 0; i < bones.Length; i++)
                        {
                            int ii = nodeMap [i];
                            nodeDeltas [i]  = nodes [ii] - baseNodes [ii];
                            nodeOffsets [i] = offsets [ii] - baseOffsets [ii];
                            if (nodeDeltas [i].sqrMagnitude > Mathf.Epsilon)
                            {
                                hasNodeDelta = true;
                            }
                        }
                        if (hasNodeDelta)
                        {
                            morph.m_nodes   = nodeDeltas;
                            morph.m_offsets = nodeOffsets;

                            jct_list.Add(morph);
                        }
                    }
                    else
                    {
                        Debug.LogWarning("Missing morph file:" + file);
                    }
                }

                JCTMorph[] morphs = jct_list.ToArray();

                // add the data to the jct_adapter
                JCTTransition jct_adapter = destination.GetComponent <JCTTransition> ();
                // if (jct_adapter == null) {
                jct_adapter = destination.AddComponent <JCTTransition> ();
                // added by jesse for a compelte reference to all bones - theoretically since it comes from the figure mesh
                // jct_adapter.mesh_skeleton = skinned_mesh_renderer.bones;
                // }

                jct_adapter.m_morphs  = morphs;
                jct_adapter.hideFlags = HideFlags.HideInInspector;
                // morpher.m_duplicates = duplicates;
                jct_adapter.CreationSetup(skinned_mesh_renderer);
            }
        }