Tress FX hair asset type.
Inheritance: UnityEngine.ScriptableObject
 public static void CreateHairData(this TressFXHair ext)
 {
     ext.m_NumTotalHairVertices          = 16;
     ext.m_NumTotalHairStrands           = 1;
     ext.m_NumOfVerticesPerStrand        = 16;
     ext.m_NumGuideHairVertices          = 16;
     ext.m_NumGuideHairStrands           = 1;
     ext.m_NumFollowHairsPerOneGuideHair = 0;
     ext.m_pHairStrandType = new int[1] {
         0
     };
     ext.m_pRefVectors = new Vector4[16];
     for (int i = 0; i < 16; ++i)
     {
         ext.m_pRefVectors[i] = new Vector4(1, 0, 0, 0);
     }
     ext.m_pGlobalRotations = new Vector4[16];
     for (int i = 0; i < 16; ++i)
     {
         ext.m_pGlobalRotations[i] = new Vector4(0, 0, 0, 1);
     }
     ext.m_pLocalRotations = new Vector4[16];//没用
     for (int i = 0; i < 16; ++i)
     {
         ext.m_pLocalRotations[i] = new Vector4(0, 0, 0, 1);
     }
     ext.m_pVertices = new Vector4[16];
     for (int i = 0; i < 16; ++i)
     {
         ext.m_pVertices[i] = new Vector4(0, -i, 0, 1);
     }
     ext.m_pVertices[0] = new Vector4(0, 0, 0, 0);
     ext.m_pVertices[1] = new Vector4(0, -1, 0, 0);
     ext.m_pTangents    = new Vector4[16];
     for (int i = 0; i < 16; ++i)
     {
         ext.m_pTangents[i] = new Vector4(0, -1, 0, 0);
     }
     ext.m_pThicknessCoeffs = new float[16];
     for (int i = 0; i < 16; ++i)
     {
         ext.m_pThicknessCoeffs[i] = 1;
     }
     ext.m_pFollowRootOffset = new Vector4[1];
     ext.m_pRestLengths      = new float[16];
     for (int i = 0; i < 16; ++i)
     {
         ext.m_pRestLengths[i] = 1;
     }
     ext.hairPartConfig            = new HairPartConfig[1];
     ext.hairPartConfig[0].Damping = 0.5f;
     ext.hairPartConfig[0].GlobalShapeMatchingEffectiveRange = 0.5f;
     ext.hairPartConfig[0].StiffnessForGlobalShapeMatching   = 0.5f;
     ext.hairPartConfig[0].StiffnessForLocalShapeMatching    = 0.5f;
     ext.m_bSphere         = new TressFXBoundingSphere();
     ext.m_TriangleIndices = new int[3];
     ext.m_LineIndices     = new int[16];
     ext.m_TexCoords       = new Vector4[16];
 }
        public static void CreateTestHair()
        {
            TressFXHair newHairData = ScriptableObjectUtility.CreateAsset <TressFXHair>("TestHair");

            newHairData.CreateHairData();
            EditorUtility.SetDirty(newHairData);
            AssetDatabase.SaveAssets();
        }
Esempio n. 3
0
        public override void OnInspectorGUI()
        {
            // Get the tressfx hair instance
            TressFXHair target = (TressFXHair)this.target;

            EditorGUILayout.LabelField("Hair Stats");
            EditorGUILayout.LabelField("-----------------------------------");
            EditorGUILayout.LabelField("Total Vertices: ", target.m_NumTotalHairVertices + "");
            EditorGUILayout.LabelField("Total Strands: ", target.m_NumTotalHairStrands + "");
            EditorGUILayout.LabelField("Guidance Vertices: ", target.m_NumGuideHairVertices + "");
            EditorGUILayout.LabelField("Guidance Strands: ", target.m_NumGuideHairStrands + "");
            EditorGUILayout.LabelField("Maximum Verts / strand: ", target.m_NumOfVerticesPerStrand + "");
            EditorGUILayout.LabelField("Follow strands per strand: ", target.m_NumFollowHairsPerOneGuideHair + "");

            for (int i = 0; i < target.hairPartConfig.Length; i++)
            {
                EditorGUILayout.LabelField("");
                EditorGUILayout.LabelField("Hair section " + i);
                EditorGUILayout.LabelField("-----------------------------------");
                target.hairPartConfig[i].Damping = EditorGUILayout.FloatField("Damping", target.hairPartConfig[i].Damping);
                target.hairPartConfig[i].StiffnessForLocalShapeMatching    = EditorGUILayout.FloatField("LSM stiffness", target.hairPartConfig[i].StiffnessForLocalShapeMatching);
                target.hairPartConfig[i].StiffnessForGlobalShapeMatching   = EditorGUILayout.FloatField("GSM stiffness", target.hairPartConfig[i].StiffnessForGlobalShapeMatching);
                target.hairPartConfig[i].GlobalShapeMatchingEffectiveRange = EditorGUILayout.FloatField("GSM effective range", target.hairPartConfig[i].GlobalShapeMatchingEffectiveRange);
            }

            // Save hair data
            if (GUILayout.Button("Save"))
            {
                EditorUtility.SetDirty(target);
                AssetDatabase.SaveAssets();
            }

            /*
             * // Load new hair data TFXB
             * if (GUILayout.Button("Load new Hairdata (TFXB)"))
             * {
             *      // Load new hair file
             *      string hairfilePath = EditorUtility.OpenFilePanel ("Open TressFX Hair data", "", "tfxb");
             *      target.LoadHairData (Hair.Import(HairFormat.TFXB, hairfilePath));
             *
             *      // Save
             *      EditorUtility.SetDirty(target);
             *      AssetDatabase.SaveAssets();
             * }
             *
             * // Load new hair data ASE
             * if (GUILayout.Button("Load new Hairdata (ASE)"))
             * {
             *      // Load new hair file
             *      string hairfilePath = EditorUtility.OpenFilePanel ("Open TressFX Hair data", "", "ase");
             *      target.LoadHairData (Hair.Import(HairFormat.ASE, hairfilePath));
             *
             *      // Save
             *      EditorUtility.SetDirty(target);
             *      AssetDatabase.SaveAssets();
             * }
             */
        }
Esempio n. 4
0
        public static void CreateAssetTFXB()
        {
            string hairfilePath = EditorUtility.OpenFilePanel("Open TressFX Hair data", "", "tfxb");
            string hairfileName = System.IO.Path.GetFileNameWithoutExtension(hairfilePath);

            // Create new hair asset
            TressFXHair newHairData = ScriptableObjectUtility.CreateAsset <TressFXHair> (hairfileName);

            // Open hair data
            Hair hair = Hair.Import(HairFormat.TFXB, hairfilePath, TressFXEditorWindow.GetImportSettings());

            hair.CreateUVs();
            newHairData.LoadHairData(hair);

            EditorUtility.SetDirty(newHairData);
            AssetDatabase.SaveAssets();
        }
        public override void OnInspectorGUI()
        {
            // Get the tressfx hair instance
            TressFXHair target = (TressFXHair)this.target;

            EditorGUILayout.LabelField("Hair Stats");
            EditorGUILayout.LabelField("-----------------------------------");
            EditorGUILayout.LabelField("Total Vertices: ", target.m_NumTotalHairVertices + "");
            EditorGUILayout.LabelField("Total Strands: ", target.m_NumTotalHairStrands + "");
            EditorGUILayout.LabelField("Guidance Vertices: ", target.m_NumGuideHairVertices + "");
            EditorGUILayout.LabelField("Guidance Strands: ", target.m_NumGuideHairStrands + "");
            EditorGUILayout.LabelField("Maximum Verts / strand: ", target.m_NumOfVerticesPerStrand + "");
            EditorGUILayout.LabelField("Follow strands per strand: ", target.m_NumFollowHairsPerOneGuideHair + "");

            for (int i = 0; i < target.hairPartConfig.Length; i++)
            {
                EditorGUILayout.LabelField("");
                EditorGUILayout.LabelField("Hair section " + i);
                EditorGUILayout.LabelField("-----------------------------------");
                target.hairPartConfig[i].Damping = EditorGUILayout.FloatField("Damping", target.hairPartConfig[i].Damping);
                target.hairPartConfig[i].StiffnessForLocalShapeMatching    = EditorGUILayout.FloatField("LSM stiffness", target.hairPartConfig[i].StiffnessForLocalShapeMatching);
                target.hairPartConfig[i].StiffnessForGlobalShapeMatching   = EditorGUILayout.FloatField("GSM stiffness", target.hairPartConfig[i].StiffnessForGlobalShapeMatching);
                target.hairPartConfig[i].GlobalShapeMatchingEffectiveRange = EditorGUILayout.FloatField("GSM effective range", target.hairPartConfig[i].GlobalShapeMatchingEffectiveRange);
            }

            // Merge
            EditorGUILayout.LabelField("Drag tressfx hair here to merge");
            TressFXHair mergeHair = (TressFXHair)EditorGUILayout.ObjectField(null, typeof(TressFXHair), false);

            if (mergeHair != null)
            {
                target.MergeIntoThis(mergeHair);
            }

            // Save hair data
            if (GUILayout.Button("Save"))
            {
                EditorUtility.SetDirty(target);
                AssetDatabase.SaveAssets();
            }
        }
Esempio n. 6
0
        public static void CreateAssetOBJ()
        {
            string hairfilePath = EditorUtility.OpenFilePanel("Open OBJ Hair data", "", "obj");
            string hairfileName = System.IO.Path.GetFileNameWithoutExtension(hairfilePath);

            // Create new hair asset
            TressFXHair newHairData = ScriptableObjectUtility.CreateAsset <TressFXHair>(hairfileName);

            // Open hair data
            Hair hair = Hair.Import(HairFormat.OBJ, hairfilePath, TressFXEditorWindow.GetImportSettings());

            if (TressFXEditorWindow.normalizeVertexCountActive && TressFXEditorWindow.normalizeVertexCount > 2)
            {
                hair.NormalizeStrands(TressFXEditorWindow.normalizeVertexCount);
            }

            hair = hair.PrepareSimulationParamatersAssetConverter(TressFXEditorWindow.followHairCount, TressFXEditorWindow.maxRadiusAroundGuideHair, Application.dataPath + "/" + EditorPrefs.GetString("TressFXAssetConverterPath"));
            hair.CreateUVs();

            newHairData.LoadHairData(hair);

            EditorUtility.SetDirty(newHairData);
            AssetDatabase.SaveAssets();
        }
Esempio n. 7
0
        /// <summary>
        /// Opens the hair data (tfxb) at the given path.
        /// </summary>
        /// <param name="path">Path.</param>
        public static void LoadHairData(this TressFXHair ext, Hair hair)
        {
                        #if UNITY_EDITOR
            EditorUtility.DisplayProgressBar("Importing TressFX Hair", "Loading information...", 0);
            HairSimulationData hairSimulationData = hair.hairSimulationData;

            // Load information variables
            ext.m_NumTotalHairVertices          = hairSimulationData.vertexCount;
            ext.m_NumTotalHairStrands           = hairSimulationData.strandCount;
            ext.m_NumOfVerticesPerStrand        = hairSimulationData.maxNumVerticesPerStrand;
            ext.m_NumGuideHairVertices          = hairSimulationData.guideHairVertexCount;
            ext.m_NumGuideHairStrands           = hairSimulationData.guideHairStrandCount;
            ext.m_NumFollowHairsPerOneGuideHair = hairSimulationData.followHairsPerOneGuideHair;

            // Load actual hair data
            EditorUtility.DisplayProgressBar("Importing TressFX Hair", "Loading strandtypes...", 0);
            ext.m_pHairStrandType = hairSimulationData.strandTypes.ToArray();
            EditorUtility.DisplayProgressBar("Importing TressFX Hair", "Loading reference vectors...", 0.05f);
            ext.m_pRefVectors = Vector4Import(hairSimulationData.referenceVectors.ToArray());
            EditorUtility.DisplayProgressBar("Importing TressFX Hair", "Loading global rotations...", 0.15f);
            ext.m_pGlobalRotations = QuaternionsToVector4(QuaternionImport(hairSimulationData.globalRotations.ToArray()));
            EditorUtility.DisplayProgressBar("Importing TressFX Hair", "Loading local rotations...", 0.25f);
            ext.m_pLocalRotations = QuaternionsToVector4(QuaternionImport(hairSimulationData.localRotations.ToArray()));
            EditorUtility.DisplayProgressBar("Importing TressFX Hair", "Loading vertices...", 0.35f);
            ext.m_pVertices = Vector4Import(hairSimulationData.vertices.ToArray());
            EditorUtility.DisplayProgressBar("Importing TressFX Hair", "Loading tangents...", 0.4f);
            ext.m_pTangents = Vector4Import(hairSimulationData.tangents.ToArray());
            EditorUtility.DisplayProgressBar("Importing TressFX Hair", "Loading thickness coefficients...", 0.55f);
            ext.m_pThicknessCoeffs = hairSimulationData.thicknessCoefficients.ToArray();
            EditorUtility.DisplayProgressBar("Importing TressFX Hair", "Loading follow hair root offsets...", 0.65f);
            ext.m_pFollowRootOffset = Vector4Import(hairSimulationData.followRootOffsets.ToArray());
            EditorUtility.DisplayProgressBar("Importing TressFX Hair", "Loading rest lengths...", 0.7f);
            ext.m_pRestLengths = hairSimulationData.restLength.ToArray();

            // Determine how much hair strand types are available
            List <int> strandTypes = new List <int>();
            for (int i = 0; i < ext.m_pHairStrandType.Length; i++)
            {
                if (!strandTypes.Contains(ext.m_pHairStrandType[i]))
                {
                    strandTypes.Add(ext.m_pHairStrandType[i]);
                }
            }

            if (ext.hairPartConfig == null || ext.hairPartConfig.Length != strandTypes.Count)
            {
                ext.hairPartConfig = new HairPartConfig[strandTypes.Count];
            }

            EditorUtility.DisplayProgressBar("Importing TressFX Hair", "Loading bounding sphere...", 0.75f);
            // Load bounding sphere
            ext.m_bSphere = new TressFXBoundingSphere(new Vector3(hair.boundingSphere.center.x, hair.boundingSphere.center.y, hair.boundingSphere.center.z), hair.boundingSphere.radius);

            EditorUtility.DisplayProgressBar("Importing TressFX Hair", "Loading indices...", 0.75f);

            // Read triangle indices
            ext.m_TriangleIndices = hair.triangleIndices;

            // Read line indices
            ext.m_LineIndices = hair.lineIndices;

            // Set texcoords
            ext.m_TexCoords = Vector4Import(hair.texcoords);

            EditorUtility.ClearProgressBar();

            // We are ready!
            Debug.Log("Hair loaded. Vertices loaded: " + ext.m_NumTotalHairVertices + ", Strands: " + ext.m_NumTotalHairStrands + ", Triangle Indices: " + ext.m_TriangleIndices.Length + ", Line Indices: " + ext.m_LineIndices.Length);
                        #endif
        }
Esempio n. 8
0
        /// <summary>
        /// Merges other into this tressfx hair.
        /// </summary>
        /// <param name="other"></param>
        public void MergeIntoThis(TressFXHair other)
        {
            if (this.hairPartConfig.Length + other.hairPartConfig.Length > 4)
            {
                throw new Exception("Tressfx merge error! Hair cannot have more than 4 parts");
            }

            // Head info check
            if (this.m_NumOfVerticesPerStrand != other.m_NumOfVerticesPerStrand)
            {
                throw new Exception("Tressfx merge error! Hair vertex count per strand must match!");
            }

            /*int newPartCount = this.hairPartConfig.Length + other.hairPartConfig.Length;
             * int otherPartCount = other.hairPartConfig.Length;*/
            int thisPartCount = this.hairPartConfig.Length;

            // Create lists
            List <int>     pHairStrandType   = new List <int>(this.m_pHairStrandType);
            List <Vector4> pRefVectors       = new List <Vector4>(this.m_pRefVectors);
            List <Vector4> pGlobalRotations  = new List <Vector4>(this.m_pGlobalRotations);
            List <Vector4> pLocalRotations   = new List <Vector4>(this.m_pLocalRotations);
            List <Vector4> pVertices         = new List <Vector4>(this.m_pVertices);
            List <Vector4> pTangents         = new List <Vector4>(this.m_pTangents);
            List <float>   pThicknessCoeffs  = new List <float>(this.m_pThicknessCoeffs);
            List <Vector4> pFollowRootOffset = new List <Vector4>(this.m_pFollowRootOffset);
            List <float>   pRestLengths      = new List <float>(this.m_pRestLengths);
            List <int>     triangleIndices   = new List <int>(this.m_TriangleIndices);
            List <int>     lineIndices       = new List <int>(this.m_LineIndices);
            List <Vector4> texCoords         = new List <Vector4>(this.m_TexCoords);

            // Prepare new strand types
            List <int> tmpIntList = new List <int>();

            for (int i = 0; i < other.m_pHairStrandType.Length; i++)
            {
                tmpIntList.Add(other.m_pHairStrandType[i] + thisPartCount);
            }

            // Add up new strand types
            pHairStrandType.AddRange(tmpIntList);
            tmpIntList.Clear();

            // Prepare indices
            // TRIANGLES
            int indexOffset = this.m_pVertices.Length;

            for (int i = 0; i < other.m_TriangleIndices.Length; i++)
            {
                tmpIntList.Add(other.m_TriangleIndices[i] + indexOffset);
            }

            // Add new triangle indices
            triangleIndices.AddRange(tmpIntList);
            tmpIntList.Clear();

            // LINES
            for (int i = 0; i < other.m_LineIndices.Length; i++)
            {
                tmpIntList.Add(other.m_LineIndices[i] + indexOffset);
            }

            // Add new triangle indices
            lineIndices.AddRange(tmpIntList);
            tmpIntList.Clear();

            // Add up static stuff
            pRefVectors.AddRange(other.m_pRefVectors);
            pGlobalRotations.AddRange(other.m_pGlobalRotations);
            pLocalRotations.AddRange(other.m_pLocalRotations);
            pVertices.AddRange(other.m_pVertices);
            pTangents.AddRange(other.m_pTangents);
            pThicknessCoeffs.AddRange(other.m_pThicknessCoeffs);
            pFollowRootOffset.AddRange(other.m_pFollowRootOffset);
            pRestLengths.AddRange(other.m_pRestLengths);
            texCoords.AddRange(other.m_TexCoords);

            // Write back to this
            this.m_pHairStrandType   = pHairStrandType.ToArray();
            this.m_pRefVectors       = pRefVectors.ToArray();
            this.m_pGlobalRotations  = pGlobalRotations.ToArray();
            this.m_pLocalRotations   = pLocalRotations.ToArray();
            this.m_pVertices         = pVertices.ToArray();
            this.m_pTangents         = pTangents.ToArray();
            this.m_pThicknessCoeffs  = pThicknessCoeffs.ToArray();
            this.m_pFollowRootOffset = pFollowRootOffset.ToArray();
            this.m_pRestLengths      = pRestLengths.ToArray();
            this.m_TriangleIndices   = triangleIndices.ToArray();
            this.m_LineIndices       = lineIndices.ToArray();
            this.m_TexCoords         = texCoords.ToArray();

            // Part configs
            List <HairPartConfig> partConfigs = new List <HairPartConfig>();

            partConfigs.AddRange(this.hairPartConfig);
            partConfigs.AddRange(other.hairPartConfig);
            this.hairPartConfig = partConfigs.ToArray();

            // Recalc header
            this.m_NumTotalHairVertices = pVertices.Count;
            this.m_NumTotalHairStrands  = this.m_NumTotalHairStrands + other.m_NumTotalHairStrands;
            this.m_NumGuideHairVertices = this.m_NumGuideHairVertices + other.m_NumGuideHairVertices;
            this.m_NumGuideHairStrands  = this.m_NumGuideHairStrands + other.m_NumGuideHairStrands;

            // Bounds
            Bounds newBounds = new Bounds(this.m_bSphere.center, Vector3.one * this.m_bSphere.radius);

            newBounds.Encapsulate(new Bounds(other.m_bSphere.center, Vector3.one * this.m_bSphere.radius));

            this.m_bSphere.center = newBounds.center;
            this.m_bSphere.radius = Mathf.Max(newBounds.extents.x, newBounds.extents.y, newBounds.extents.z);
        }
Esempio n. 9
0
        /// <summary>
        /// Merges other into this tressfx hair.
        /// </summary>
        /// <param name="other"></param>
        public void MergeIntoThis(TressFXHair other)
        {
            if (this.hairPartConfig.Length + other.hairPartConfig.Length > 4)
                throw new Exception("Tressfx merge error! Hair cannot have more than 4 parts");

            // Head info check
            if (this.m_NumOfVerticesPerStrand != other.m_NumOfVerticesPerStrand)
                throw new Exception("Tressfx merge error! Hair vertex count per strand must match!");

            /*int newPartCount = this.hairPartConfig.Length + other.hairPartConfig.Length;
            int otherPartCount = other.hairPartConfig.Length;*/
            int thisPartCount = this.hairPartConfig.Length;

            // Create lists
            List<int> pHairStrandType = new List<int>(this.m_pHairStrandType);
            List<Vector4> pRefVectors = new List<Vector4>(this.m_pRefVectors);
            List<Vector4> pGlobalRotations = new List<Vector4>(this.m_pGlobalRotations);
            List<Vector4> pLocalRotations = new List<Vector4>(this.m_pLocalRotations);
            List<Vector4> pVertices = new List<Vector4>(this.m_pVertices);
            List<Vector4> pTangents = new List<Vector4>(this.m_pTangents);
            List<float> pThicknessCoeffs = new List<float>(this.m_pThicknessCoeffs);
            List<Vector4> pFollowRootOffset = new List<Vector4>(this.m_pFollowRootOffset);
            List<float> pRestLengths = new List<float>(this.m_pRestLengths);
            List<int> triangleIndices = new List<int>(this.m_TriangleIndices);
            List<int> lineIndices = new List<int>(this.m_LineIndices);
            List<Vector4> texCoords = new List<Vector4>(this.m_TexCoords);

            // Prepare new strand types
            List<int> tmpIntList = new List<int>();
            for (int i = 0; i < other.m_pHairStrandType.Length; i++)
            {
                tmpIntList.Add(other.m_pHairStrandType[i] + thisPartCount);
            }

            // Add up new strand types
            pHairStrandType.AddRange(tmpIntList);
            tmpIntList.Clear();

            // Prepare indices
            // TRIANGLES
            int indexOffset = this.m_pVertices.Length;
            for (int i = 0; i < other.m_TriangleIndices.Length; i++)
            {
                tmpIntList.Add(other.m_TriangleIndices[i] + indexOffset);
            }

            // Add new triangle indices
            triangleIndices.AddRange(tmpIntList);
            tmpIntList.Clear();

            // LINES
            for (int i = 0; i < other.m_LineIndices.Length; i++)
            {
                tmpIntList.Add(other.m_LineIndices[i] + indexOffset);
            }

            // Add new triangle indices
            lineIndices.AddRange(tmpIntList);
            tmpIntList.Clear();

            // Add up static stuff
            pRefVectors.AddRange(other.m_pRefVectors);
            pGlobalRotations.AddRange(other.m_pGlobalRotations);
            pLocalRotations.AddRange(other.m_pLocalRotations);
            pVertices.AddRange(other.m_pVertices);
            pTangents.AddRange(other.m_pTangents);
            pThicknessCoeffs.AddRange(other.m_pThicknessCoeffs);
            pFollowRootOffset.AddRange(other.m_pFollowRootOffset);
            pRestLengths.AddRange(other.m_pRestLengths);
            texCoords.AddRange(other.m_TexCoords);

            // Write back to this
            this.m_pHairStrandType = pHairStrandType.ToArray();
            this.m_pRefVectors = pRefVectors.ToArray();
            this.m_pGlobalRotations = pGlobalRotations.ToArray();
            this.m_pLocalRotations = pLocalRotations.ToArray();
            this.m_pVertices = pVertices.ToArray();
            this.m_pTangents = pTangents.ToArray();
            this.m_pThicknessCoeffs = pThicknessCoeffs.ToArray();
            this.m_pFollowRootOffset = pFollowRootOffset.ToArray();
            this.m_pRestLengths = pRestLengths.ToArray();
            this.m_TriangleIndices = triangleIndices.ToArray();
            this.m_LineIndices = lineIndices.ToArray();
            this.m_TexCoords = texCoords.ToArray();

            // Part configs
            List<HairPartConfig> partConfigs = new List<HairPartConfig>();
            partConfigs.AddRange(this.hairPartConfig);
            partConfigs.AddRange(other.hairPartConfig);
            this.hairPartConfig = partConfigs.ToArray();

            // Recalc header
            this.m_NumTotalHairVertices = pVertices.Count;
            this.m_NumTotalHairStrands = this.m_NumTotalHairStrands + other.m_NumTotalHairStrands;
            this.m_NumGuideHairVertices = this.m_NumGuideHairVertices + other.m_NumGuideHairVertices;
            this.m_NumGuideHairStrands = this.m_NumGuideHairStrands + other.m_NumGuideHairStrands;

            // Bounds
            Bounds newBounds = new Bounds(this.m_bSphere.center, Vector3.one * this.m_bSphere.radius);
            newBounds.Encapsulate(new Bounds(other.m_bSphere.center, Vector3.one * this.m_bSphere.radius));

            this.m_bSphere.center = newBounds.center;
            this.m_bSphere.radius = Mathf.Max(newBounds.extents.x, newBounds.extents.y, newBounds.extents.z);
        }