예제 #1
0
        public void Render()
        {
            Material mat = material;

            mat.SetTexture("_MainTex", m_Icon);
            mat.SetPass(0);

            for (int i = 0; i < m_RenderChunks.Count; ++i)
            {
                RenderChunk renderChunk = m_RenderChunks[i];

                if (renderChunk.isDirty)
                {
                    renderChunk.mesh.vertices = renderChunk.vertices.ToArray();
                    renderChunk.mesh.colors32 = renderChunk.colors.ToArray();
                    renderChunk.mesh.uv       = renderChunk.uvs.ToArray();

                    renderChunk.mesh.SetIndices(renderChunk.indices.ToArray(), MeshTopology.Triangles, 0);

                    renderChunk.isDirty = false;
                }

                Graphics.DrawMeshNow(renderChunk.mesh, Handles.matrix);
            }
        }
        public void AddPoint(Rect rect, Color color)
        {
            RenderChunk renderChunk = GetRenderChunk();

            int baseIndex = renderChunk.vertices.Count;

            renderChunk.vertices.Add(new Vector3(rect.xMin, rect.yMin, 0.0f));
            renderChunk.vertices.Add(new Vector3(rect.xMax, rect.yMin, 0.0f));
            renderChunk.vertices.Add(new Vector3(rect.xMax, rect.yMax, 0.0f));
            renderChunk.vertices.Add(new Vector3(rect.xMin, rect.yMax, 0.0f));

            renderChunk.colors.Add(color);
            renderChunk.colors.Add(color);
            renderChunk.colors.Add(color);
            renderChunk.colors.Add(color);

            renderChunk.uvs.Add(new Vector2(0.0f, 0.0f));
            renderChunk.uvs.Add(new Vector2(1.0f, 0.0f));
            renderChunk.uvs.Add(new Vector2(1.0f, 1.0f));
            renderChunk.uvs.Add(new Vector2(0.0f, 1.0f));

            renderChunk.indices.Add(baseIndex);
            renderChunk.indices.Add(baseIndex + 1);
            renderChunk.indices.Add(baseIndex + 2);

            renderChunk.indices.Add(baseIndex);
            renderChunk.indices.Add(baseIndex + 2);
            renderChunk.indices.Add(baseIndex + 3);

            renderChunk.isDirty = true;
        }
        public static void CopyDataPerIndex(this Mesh mesh, RenderChunk chunk)
        {
            if (mesh == null)
            {
                Debug.Log("CopyDataPerIndex method need some data, mesh == null..");
                return;
            }

            int[] triangles = mesh.triangles;

            chunk.indices = new int[triangles.Length];
            Array.Copy(triangles, chunk.indices, chunk.indices.Length);

            chunk.edges = new float[triangles.Length];
            int topologyLength = mesh.GetTopologyCount(0);

            for (int i = 0; i < triangles.Length; i += topologyLength)
            {
                for (int j = 0; j < topologyLength; j++)
                {
                    chunk.edges[i + j] =
                        (
                            chunk.dataPerVertex[chunk.indices[i + j]].position -
                            chunk.dataPerVertex[chunk.indices[i + (j + 1) % topologyLength]].position
                        ).sqrMagnitude;
                }
            }

            chunk.indexCounts = new uint[mesh.subMeshCount];
            for (int i = 0; i < chunk.indexCounts.Length; i++)
            {
                chunk.indexCounts[i] = mesh.GetIndexStart(i) + mesh.GetIndexCount(i);
            }
        }
        public void Render()
        {
            Material mat = material;

            mat.SetTexture("_MainTex", m_Icon);
            mat.SetPass(0);

            for (int i = 0; i < m_RenderChunks.Count; ++i)
            {
                RenderChunk renderChunk = m_RenderChunks[i];

                if (renderChunk.isDirty)
                {
                    renderChunk.mesh.vertices = renderChunk.vertices.ToArray();
                    renderChunk.mesh.colors32 = renderChunk.colors.ToArray();
                    renderChunk.mesh.uv       = renderChunk.uvs.ToArray();

                    renderChunk.mesh.SetIndices(renderChunk.indices.ToArray(), MeshTopology.Triangles, 0);

                    renderChunk.isDirty = false;
                }

                // Previous camera may still be active when calling DrawMeshNow.
                Camera.SetupCurrent(null);

                Graphics.DrawMeshNow(renderChunk.mesh, Handles.matrix);
            }
        }
        public static float GetArea(this RenderChunk chunk, int vtxIdx1, int vtxIdx2, int vtxIdx3)
        {
            Vector3 vec12 = (Vector3)(chunk.dataPerVertex[vtxIdx2].position - chunk.dataPerVertex[vtxIdx1].position),
                    vec13 = (Vector3)(chunk.dataPerVertex[vtxIdx3].position - chunk.dataPerVertex[vtxIdx1].position);

            return(Vector3.Cross(vec12, vec13).magnitude * 0.5f);
        }
예제 #6
0
        private RenderChunk GetRenderChunk()
        {
            RenderChunk renderChunk = null;

            if (m_RenderChunks.Count > 0)
            {
                while (m_RenderChunkIndex < m_RenderChunks.Count)
                {
                    renderChunk = m_RenderChunks[m_RenderChunkIndex];
                    // Dynamically create new render chunks when needed.
                    if ((renderChunk.vertices.Count + 4) > kMaxVertices)
                    {
                        m_RenderChunkIndex++;
                        renderChunk = null;
                        continue;
                    }

                    break;
                }

                if (renderChunk == null)
                {
                    renderChunk = CreateRenderChunk();
                }
            }
            else
            {
                renderChunk = CreateRenderChunk();
            }

            return(renderChunk);
        }
        public void AddPoint(Rect rect, Color color)
        {
            RenderChunk renderChunk = this.GetRenderChunk();
            int         count       = renderChunk.vertices.Count;

            renderChunk.vertices.Add(new Vector3(rect.xMin, rect.yMin, 0f));
            renderChunk.vertices.Add(new Vector3(rect.xMax, rect.yMin, 0f));
            renderChunk.vertices.Add(new Vector3(rect.xMax, rect.yMax, 0f));
            renderChunk.vertices.Add(new Vector3(rect.xMin, rect.yMax, 0f));
            renderChunk.colors.Add(color);
            renderChunk.colors.Add(color);
            renderChunk.colors.Add(color);
            renderChunk.colors.Add(color);
            renderChunk.uvs.Add(new Vector2(0f, 0f));
            renderChunk.uvs.Add(new Vector2(1f, 0f));
            renderChunk.uvs.Add(new Vector2(1f, 1f));
            renderChunk.uvs.Add(new Vector2(0f, 1f));
            renderChunk.indices.Add(count);
            renderChunk.indices.Add(count + 1);
            renderChunk.indices.Add(count + 2);
            renderChunk.indices.Add(count);
            renderChunk.indices.Add(count + 2);
            renderChunk.indices.Add(count + 3);
            renderChunk.isDirty = true;
        }
예제 #8
0
 //Chunks in this queue have been altered by the player, and are currently within the render radius.
 //Only queue if not already in queue
 private void FlagRenderChunkForPriorityUpdate(RenderChunk renderChunkToUpdate)
 {
     if (!renderChunkPriorityUpdateQueue.Contains(renderChunkToUpdate))
     {
         renderChunkPriorityUpdateQueue.Enqueue(renderChunkToUpdate);
     }
 }
예제 #9
0
        public void OverrideData()
        {
            long time = DateTime.Now.Ticks;

            try
            {
                RenderChunk chunk = targetAs;

                Mesh mesh = chunk.builtInRenderer.sharedMesh;

                mesh.RecalculateNormals();

                EditorUtility.DisplayProgressBar(addTitle, "Get Bone Data", 0.0f);
                chunk.SetBoneData(chunk.builtInRenderer);

                EditorUtility.DisplayProgressBar(overrideTitle, "Get Index Data", 0.25f);
                chunk.SetIndices(mesh);

                EditorUtility.DisplayProgressBar(overrideTitle, "Get Mesh Data", 0.5f);
                chunk.SetMeshData(mesh);
            }
            catch (Exception e)
            {
                Debug.LogError(e);
            }
            finally
            {
                float measuredTime = (float)((DateTime.Now.Ticks - time) / TimeSpan.TicksPerMillisecond) / 1000;
                Debug.Log("Measured time : " + measuredTime);
            }

            EditorUtility.ClearProgressBar();
        }
        public static void SetMeshData(this RenderChunk chunk, Mesh mesh)
        {
            if (mesh == null)
            {
                Debug.Log("SetMeshData method need some data, mesh == null..");
                return;
            }

            int b1Cnt = 0, b2Cnt = 0, b3Cnt = 0, b4Cnt = 0;

            {
                chunk.vertexCount = mesh.vertexCount;
            }

            {
                MeshDataInfo[] meshData = new MeshDataInfo[mesh.vertexCount];

                Vector3[]    vertices          = mesh.vertices;
                Vector3[]    normals           = mesh.normals;
                Vector2[]    uv                = mesh.uv;
                BoneWeight[] sourceBoneWeights = mesh.boneWeights;

                // This code very long time
                for (int i = 0; i < meshData.Length; i++)
                {
                    meshData[i] =
                        new MeshDataInfo()
                    {
                        position = vertices[i],
                        normal   = normals[i],
                        uv       = uv[i],
                        weight   = new Vector4(sourceBoneWeights[i].weight0, sourceBoneWeights[i].weight1, sourceBoneWeights[i].weight2, sourceBoneWeights[i].weight3),
                        index    = new Integer4(sourceBoneWeights[i].boneIndex0, sourceBoneWeights[i].boneIndex1, sourceBoneWeights[i].boneIndex2, sourceBoneWeights[i].boneIndex3)
                    };

                    if (meshData[i].weight.y == 0)
                    {
                        b1Cnt++;
                    }
                    else if (meshData[i].weight.z == 0)
                    {
                        b2Cnt++;
                    }
                    else if (meshData[i].weight.w == 0)
                    {
                        b3Cnt++;
                    }
                    else
                    {
                        b4Cnt++;
                    }
                }

                chunk.boneVertexCount = new Integer4(b1Cnt, b2Cnt, b3Cnt, b4Cnt);
                chunk.meshData        = meshData;
            }
        }
예제 #11
0
    private void LoadChunk(int posX, int posZ, int offsetX, int offsetZ)
    {
        if (!GetChunk(posX + offsetX, posZ + offsetZ))
        {
            GameObject chunk = new GameObject("Chunk " + (posX + offsetX) + " " + (posZ + offsetZ));
            chunk.transform.parent   = gameObject.transform;
            chunk.transform.position = new Vector3((posX + offsetX) * _chunkSize, 0, (posZ + offsetZ) * _chunkSize);

            RenderChunk renderChunk = chunk.AddComponent <RenderChunk>();
            renderChunk.Render(posX + offsetX, posZ + offsetZ);
        }
    }
        public static unsafe float GetSimliarity(this RenderChunk chunk, int vtxIdx1, int vtxIdx2, float kernel)
        {
            int    sameIndexCount = 0;
            float *weightArray    = stackalloc float[8];

            // Find same bone index, and store weights.
            {
                Integer4 index1 = chunk.skinPerVertex[vtxIdx1].index, index2 = chunk.skinPerVertex[vtxIdx2].index;
                Vector4  weight1 = chunk.skinPerVertex[vtxIdx1].weight, weight2 = chunk.skinPerVertex[vtxIdx2].weight;

                for (int i = 0; i < 4; i++)
                {
                    if (weight1[i] > 0)
                    {
                        for (int j = 0; j < 4; j++)
                        {
                            if (weight2[j] > 0)
                            {
                                if (index1[i] == index2[j])
                                {
                                    weightArray[sameIndexCount]     = weight1[i];
                                    weightArray[sameIndexCount + 1] = weight2[j];

                                    sameIndexCount++;
                                    break;
                                }
                            }
                        }
                    }
                }
            }

            // Just calculate similarity with store weights.
            if (sameIndexCount < 2)
            {
                return(0f);
            }
            else
            {
                float similarity = 0f, diff;

                for (int i = 0; i < sameIndexCount; i++)
                {
                    for (int j = i + 1; j < sameIndexCount; j++)
                    {
                        diff        = weightArray[i] * weightArray[j + 1] - weightArray[i + 1] * weightArray[j];
                        similarity += weightArray[i] * weightArray[i + 1] * weightArray[j] * weightArray[j + 1] * Mathf.Exp(-(diff * diff) / (kernel * kernel));
                    }
                }

                return(similarity);
            }
        }
예제 #13
0
    private void InstantiateRenderChunk(int x, int y)
    {
        if (renderChunkArray [x, y] == null)
        {
            RenderChunk newRenderChunk = PullRenderChunkFromPool();
            newRenderChunk.SetChunkCoord(new Coord(x, y));

            //Don't immediately update chunk, as many chunks will be added at once as the player crosses grid lines in
            //chunk coords. Enque, then update one per frame.
            renderChunkUpdateQueue.Enqueue(newRenderChunk);
            renderChunkArray [x, y] = newRenderChunk.GetComponent <RenderChunk> () as RenderChunk;
        }
    }
 public void Clear()
 {
     for (int i = 0; i < this.m_RenderChunks.Count; i++)
     {
         RenderChunk chunk = this.m_RenderChunks[i];
         chunk.mesh.Clear();
         chunk.vertices.Clear();
         chunk.colors.Clear();
         chunk.uvs.Clear();
         chunk.indices.Clear();
         chunk.isDirty = true;
     }
 }
 private RenderChunk GetRenderChunk()
 {
     if (this.m_RenderChunks.Count > 0)
     {
         RenderChunk chunk = this.m_RenderChunks.Last <RenderChunk>();
         if ((chunk.vertices.Count + 4) > 0xfde8)
         {
             chunk = this.CreateRenderChunk();
         }
         return(chunk);
     }
     return(this.CreateRenderChunk());
 }
예제 #16
0
 private void GenerateSpawn(int width, int length)
 {
     for (int x = 0; x < width; x++)
     {
         for (int z = 0; z < length; z++)
         {
             GameObject chunk = new GameObject("Chunk " + x + " " + z);
             chunk.transform.parent   = gameObject.transform;
             chunk.transform.position = new Vector3(x * _chunkSize, 0, z * _chunkSize);
             RenderChunk renderChunk = chunk.AddComponent <RenderChunk>();
             renderChunk.Render(x, z);
         }
     }
 }
        public static void SetBoneData(this RenderChunk chunk, SkinnedMeshRenderer renderer)
        {
            if (renderer == null)
            {
                Debug.Log("SetMeshData method need some data, renderer == null..");
                return;
            }

            chunk.rootBoneName         = renderer.rootBone.transform.name;
            chunk.indexedBoneNameArray = Array.ConvertAll(renderer.bones, (bone) => bone.name);

            chunk.inverseRestPoseMatrixArray = Array.ConvertAll(renderer.bones, (bone) => bone.worldToLocalMatrix);
            chunk.inverseRestPoseDQArray     = Array.ConvertAll(renderer.bones, (bone) => bone.GetWorldToLocalDQ());
        }
 private RenderChunk CreateRenderChunk()
 {
     RenderChunk item = new RenderChunk {
         mesh = new Mesh()
     };
     item.mesh.name = "ControlPointRendererMesh";
     item.mesh.hideFlags |= HideFlags.DontSave;
     item.vertices = new List<Vector3>();
     item.colors = new List<Color32>();
     item.uvs = new List<Vector2>();
     item.indices = new List<int>();
     this.m_RenderChunks.Add(item);
     return item;
 }
        private RenderChunk CreateRenderChunk()
        {
            RenderChunk item = new RenderChunk {
                mesh = new Mesh()
            };

            item.mesh.name       = "ControlPointRendererMesh";
            item.mesh.hideFlags |= HideFlags.DontSave;
            item.vertices        = new List <Vector3>();
            item.colors          = new List <Color32>();
            item.uvs             = new List <Vector2>();
            item.indices         = new List <int>();
            this.m_RenderChunks.Add(item);
            return(item);
        }
예제 #20
0
        public RenderChunk Read_RenderChunk(BinaryReader reader)
        {
            var result = new RenderChunk();

            result.Version = ReadVersion(reader, 2, 0x14119B820);

            result.VisibilityTomeData       = Read_Array(reader);
            result.VisibilityTomeIdMask     = reader.ReadUInt32();
            result.VisibilityTomeIdRangeEnd = reader.ReadUInt32();

            if (result.Version >= 2)
            {
                result.LightTransport = Read_LightTransport(reader);
            }

            return(result);
        }
        public void Clear()
        {
            for (int i = 0; i < m_RenderChunks.Count; ++i)
            {
                RenderChunk renderChunk = m_RenderChunks[i];

                renderChunk.mesh.Clear();

                renderChunk.vertices.Clear();
                renderChunk.colors.Clear();
                renderChunk.uvs.Clear();

                renderChunk.indices.Clear();

                renderChunk.isDirty = true;
            }
        }
        private RenderChunk CreateRenderChunk()
        {
            RenderChunk renderChunk = new RenderChunk();

            renderChunk.mesh            = new Mesh();
            renderChunk.mesh.name       = kControlPointRendererMeshName;
            renderChunk.mesh.hideFlags |= HideFlags.DontSave;

            renderChunk.vertices = new List <Vector3>();
            renderChunk.colors   = new List <Color32>();
            renderChunk.uvs      = new List <Vector2>();
            renderChunk.indices  = new List <int>();

            m_RenderChunks.Add(renderChunk);

            return(renderChunk);
        }
    public override void OnInspectorGUI()
    {
        DrawDefaultInspector();

        _world = (World)target;

        if (GUILayout.Button("Render Chunk"))
        {
            GameObject  chunk       = new GameObject("Chunk");
            RenderChunk renderChunk = chunk.AddComponent <RenderChunk>();
            renderChunk.Render(_world.ChunkX, _world.ChunkZ);
        }

        if (GUILayout.Button("Spawn Player"))
        {
            SpawnPlayer(true);
        }
    }
예제 #24
0
 //return the next available chunk. If no chunks available, instantiate a new chunk.
 private RenderChunk PullRenderChunkFromPool()
 {
     if (renderChunkPool.Count > 0)
     {
         RenderChunk renderChunkToActivate = renderChunkPool.Pop();
         renderChunkToActivate.gameObject.SetActive(true);
         return(renderChunkToActivate);
     }
     else
     {
         GameObject newRenderChunkGO = Instantiate(renderChunkPrefab, this.transform.position, Quaternion.identity) as GameObject;
         //		newRenderChunkGO.transform.SetParent (this.transform);
         RenderChunk newRenderChunk = newRenderChunkGO.GetComponent <RenderChunk> () as RenderChunk;
         newRenderChunk.Initialise(chunkSize);
         BindRenderToFace(newRenderChunkGO);
         instantiatedChunkCount++;
         return(newRenderChunk);
     }
 }
        public static void SetIndices(this RenderChunk chunk, Mesh mesh)
        {
            if (mesh == null)
            {
                Debug.Log("SetMeshData method need some data, mesh == null..");
                return;
            }

            int[] triangles = mesh.triangles;

            chunk.indices = new int[triangles.Length];
            Array.Copy(triangles, chunk.indices, chunk.indices.Length);

            chunk.indexCounts = new uint[mesh.subMeshCount];
            for (int i = 0; i < chunk.indexCounts.Length; i++)
            {
                chunk.indexCounts[i] = mesh.GetIndexStart(i) + mesh.GetIndexCount(i);
            }
        }
예제 #26
0
        public void FillDataPerVertex()
        {
            long time = DateTime.Now.Ticks;

            try
            {
                RenderChunk chunk = targetAs;
                Mesh        mesh  = chunk.builtInRenderer.sharedMesh;

                mesh.CopyMiscellaneousData(chunk);

                EditorUtility.DisplayProgressBar(addTitle, "Get Bone Data", 0.0f);
                chunk.builtInRenderer.SetBoneData(chunk);

                if (chunk.dataPerVertex == null || chunk.skinPerVertex == null || chunk.vertexCount != mesh.vertexCount)
                {
                    if (EditorUtility.DisplayDialog(fillTitle, "override mesh.vertcies, mesh.triangles to RenderChunk.perVertex\nthis process has been long time, are sure this process?", "Yes", "No"))
                    {
                        EditorUtility.DisplayProgressBar(fillTitle, "Get Mesh Data", 0.25f);

                        mesh.CopyDataPerVertex(chunk);
                    }
                }

                if (chunk.indices == null || chunk.indices.Length != mesh.triangles.Length)
                {
                    EditorUtility.DisplayProgressBar(fillTitle, "Get Index Data", 0.5f);

                    mesh.CopyDataPerIndex(chunk);
                }
            }
            catch (Exception e)
            {
                Debug.LogError(e);
            }
            finally
            {
                float measuredTime = (float)((DateTime.Now.Ticks - time) / TimeSpan.TicksPerMillisecond) / 1000;
                Debug.Log("Measured time : " + measuredTime);
            }

            EditorUtility.ClearProgressBar();
        }
        public void Render()
        {
            Material material = ControlPointRenderer.material;

            material.SetTexture("_MainTex", this.m_Icon);
            material.SetPass(0);
            for (int i = 0; i < this.m_RenderChunks.Count; i++)
            {
                RenderChunk chunk = this.m_RenderChunks[i];
                if (chunk.isDirty)
                {
                    chunk.mesh.vertices = chunk.vertices.ToArray();
                    chunk.mesh.colors32 = chunk.colors.ToArray();
                    chunk.mesh.uv       = chunk.uvs.ToArray();
                    chunk.mesh.SetIndices(chunk.indices.ToArray(), MeshTopology.Triangles, 0);
                    chunk.isDirty = false;
                }
                Graphics.DrawMeshNow(chunk.mesh, Handles.matrix);
            }
        }
예제 #28
0
        public void AddData()
        {
            long time = DateTime.Now.Ticks;

            try
            {
                RenderChunk chunk = targetAs;

                Mesh mesh = chunk.builtInRenderer.sharedMesh;

                mesh.RecalculateNormals();

                EditorUtility.DisplayProgressBar(addTitle, "Get Bone Data", 0.0f);
                chunk.SetBoneData(chunk.builtInRenderer);

                EditorUtility.DisplayProgressBar(addTitle, "Get Index Data", 0.25f);
                chunk.SetIndices(mesh);

                EditorUtility.DisplayProgressBar(addTitle, "Get Mesh Data", 0.5f);

                if (EditorUtility.DisplayDialog(addTitle, "override mesh.vertcies, mesh.triangles to RenderChunk.MeshData\nthis process has been long time, are sure this process?", "Yes", "No"))
                {
                    chunk.SetMeshData(mesh);
                }
            }
            catch (Exception e)
            {
                Debug.LogError(e);
            }
            finally
            {
                float measuredTime = (float)((DateTime.Now.Ticks - time) / TimeSpan.TicksPerMillisecond) / 1000;
                Debug.Log("Measured time : " + measuredTime);
            }

            EditorUtility.ClearProgressBar();
        }
예제 #29
0
        public override void OnInspectorGUI()
        {
            EditorGUI.BeginDisabledGroup(true);

            EditorGUILayout.ObjectField("Script", MonoScript.FromScriptableObject(targetAs), typeof(RenderChunk), false);
            EditorGUILayout.ObjectField("Editor Script", MonoScript.FromScriptableObject(this), typeof(RenderChunkEditor), false);

            EditorGUI.EndDisabledGroup();

            serializedObject.Update();

            EditorGUILayout.Space();

            RenderChunk chunk = targetAs;

            EditorGUILayout.PropertyField(rendererProperty);

            SkinnedMeshRenderer renderer = rendererProperty.objectReferenceValue as SkinnedMeshRenderer;

            if (renderer != null)
            {
                bool isAsset = AssetDatabase.Contains(renderer);

                if (isAsset)
                {
                    EditorGUILayout.ObjectField("Shared Mesh", renderer.sharedMesh, typeof(UnityEngine.Mesh), false);
                }
                else
                {
                    EditorGUILayout.HelpBox(string.Format("{0} not exist in AssetDatabase. Reselect renderer asset in model data.", renderer.gameObject.name), MessageType.Error);
                }
            }

            serializedObject.ApplyModifiedProperties();

            Mesh mesh = renderer != null? renderer.sharedMesh: null;

            EditorGUI.BeginDisabledGroup(mesh == null);

            EditorGUILayout.Space();

            EditorGUILayout.LabelField("Origin data");
            EditorGUI.indentLevel++;

            if (mesh != null)
            {
                EditorGUILayout.LabelField("Bones", renderer.bones != null ? renderer.bones.Length.ToString() : "null");
                EditorGUILayout.LabelField("Vertex Count", mesh.vertexCount.ToString());
                EditorGUILayout.LabelField("Index Count", mesh.triangles.Length.ToString());
                EditorGUILayout.LabelField("Bone Weight Count", mesh.boneWeights != null ? mesh.boneWeights.Length.ToString() : "null");
            }
            else
            {
                EditorGUILayout.HelpBox("Mesh is null.. please insert data above", MessageType.Error);
            }

            EditorGUI.indentLevel--;

            EditorGUI.EndDisabledGroup();

            EditorGUILayout.Space();

            EditorGUILayout.LabelField("Converted Data");
            EditorGUI.indentLevel++;

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Root Bone Name", chunk.rootBoneName != null ? chunk.rootBoneName : "null");

            EditorGUI.BeginDisabledGroup(chunk.rootBoneName == null);

            if (GUILayout.Button("Clear"))
            {
                chunk.rootBoneName = null;

                EditorUtility.SetDirty(target);
                AssetDatabase.SaveAssets();
                AssetDatabase.Refresh();
            }

            EditorGUI.EndDisabledGroup();
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Indexed Bone Name Array", chunk.indexedBoneNameArray != null ? chunk.indexedBoneNameArray.Length.ToString() : "null");

            EditorGUI.BeginDisabledGroup(chunk.indexedBoneNameArray == null);

            if (GUILayout.Button("Clear"))
            {
                chunk.indexedBoneNameArray = null;

                EditorUtility.SetDirty(target);
                AssetDatabase.SaveAssets();
                AssetDatabase.Refresh();
            }

            EditorGUI.EndDisabledGroup();
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Bones Matrix", chunk.inverseRestPoseMatrixArray != null ? chunk.inverseRestPoseMatrixArray.Length.ToString() : "null");

            EditorGUI.BeginDisabledGroup(chunk.inverseRestPoseMatrixArray == null);

            if (GUILayout.Button("Clear"))
            {
                chunk.inverseRestPoseMatrixArray = null;

                EditorUtility.SetDirty(target);
                AssetDatabase.SaveAssets();
                AssetDatabase.Refresh();
            }

            EditorGUI.EndDisabledGroup();
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Bones DQ", chunk.inverseRestPoseDQArray != null ? chunk.inverseRestPoseDQArray.Length.ToString() : "null");

            EditorGUI.BeginDisabledGroup(chunk.inverseRestPoseDQArray == null);

            if (GUILayout.Button("Clear"))
            {
                chunk.inverseRestPoseDQArray = null;

                EditorUtility.SetDirty(target);
                AssetDatabase.SaveAssets();
                AssetDatabase.Refresh();
            }

            EditorGUI.EndDisabledGroup();
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Vertex Count", chunk.meshData != null? chunk.meshData.Length.ToString(): "null");

            EditorGUI.BeginDisabledGroup(chunk.meshData == null);

            if (GUILayout.Button("Clear"))
            {
                chunk.meshData = null;

                EditorUtility.SetDirty(target);
                AssetDatabase.SaveAssets();
                AssetDatabase.Refresh();
            }

            EditorGUI.EndDisabledGroup();
            EditorGUILayout.EndHorizontal();

            EditorGUI.indentLevel++;

            EditorGUILayout.LabelField("1 bone vertex count", chunk.boneVertexCount.x.ToString());
            EditorGUILayout.LabelField("2 bone vertex count", chunk.boneVertexCount.y.ToString());
            EditorGUILayout.LabelField("3 bone vertex count", chunk.boneVertexCount.z.ToString());
            EditorGUILayout.LabelField("4 bone vertex count", chunk.boneVertexCount.w.ToString());

            EditorGUI.indentLevel--;

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Index Count", chunk.indices != null ? chunk.indices.Length.ToString() : "null");

            EditorGUI.BeginDisabledGroup(chunk.indices == null);

            if (GUILayout.Button("Clear"))
            {
                chunk.indices = null;

                EditorUtility.SetDirty(target);
                AssetDatabase.SaveAssets();
                AssetDatabase.Refresh();
            }

            EditorGUI.EndDisabledGroup();
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.LabelField("Each bone vertex count");
            EditorGUILayout.LabelField(string.Format("1: {0}. 2 : {1}. 3 : {2}. 4 : {3}", chunk.boneVertexCount.x, chunk.boneVertexCount.y, chunk.boneVertexCount.z, chunk.boneVertexCount.w));

            EditorGUI.indentLevel--;
            EditorGUILayout.Space();

            EditorGUI.BeginDisabledGroup(mesh == null);

            if (GUILayout.Button(addTitle))
            {
                AddData();

                EditorUtility.SetDirty(target);
                AssetDatabase.SaveAssets();
                AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(target));
            }

            if (GUILayout.Button(overrideTitle))
            {
                OverrideData();

                EditorUtility.SetDirty(target);
                AssetDatabase.SaveAssets();
                AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(target));
            }

            if (GUILayout.Button(fillTitle))
            {
                FillData();

                EditorUtility.SetDirty(target);
                AssetDatabase.SaveAssets();
                AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(target));
            }

            EditorGUILayout.Space();

            if (GUILayout.Button("Clear Data"))
            {
                targetAs.Clear();

                EditorUtility.SetDirty(target);
                AssetDatabase.SaveAssets();
                AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(target));
            }

            EditorGUI.EndDisabledGroup();
        }
        public static CoRProcessThreadState[] CalculateCenterOfRotation(this RenderChunk chunk, int maxThreadNumber, float similarityKernel, float similarityThreshold)
        {
            if (chunk.clusterArray == null || chunk.clusteredVertexIndexArray == null)
            {
                Debug.LogError("Must need pre-calculated Center Of Clusters");
                return(null);
            }

            CoRProcessThreadState[] processStateArray = new CoRProcessThreadState[maxThreadNumber];

            chunk.centerOfRotationPositionArray = new Vector3[chunk.vertexCount];

            System.Threading.ParameterizedThreadStart CoRProcessStart =
                (threadObj) =>
            {
                Thread thread = threadObj as Thread;
                Match  match  = Regex.Match(thread.Name, threadNameRegexPattern);

                int currentThreadNum = int.Parse(match.Groups[1].Value), maximumThreadNum = int.Parse(match.Groups[2].Value),
                    vertexLegnth = chunk.vertexCount;

                try
                {
                    for (int clusterIndex = currentThreadNum; clusterIndex < chunk.clusterArray.Length; clusterIndex += maximumThreadNum)
                    {
                        ClusterData currentCluster = chunk.clusterArray[clusterIndex];

                        for (int clusterVertexIndex = currentCluster.startIndexOfCluster; clusterVertexIndex < currentCluster.startIndexOfCluster + currentCluster.lengthOfCluster; clusterVertexIndex++)
                        {
                            int vertexIndex = chunk.clusteredVertexIndexArray[clusterVertexIndex];

                            Vector3 calculatedVertex = Vector3.zero;
                            float   sumedSimiliarity = 0f;

                            for (int clusterTriangleIndex = currentCluster.startIndexOfTriangles; clusterTriangleIndex < currentCluster.startIndexOfTriangles + currentCluster.lengthOfTriangles; clusterTriangleIndex++)
                            {
                                int triangleIndex = chunk.clusteredTriangleIndexArray[clusterTriangleIndex];

                                float similarity =
                                    chunk.GetSimliarity(
                                        vertexIndex,
                                        chunk.indices[triangleIndex * 3 + 0],
                                        chunk.indices[triangleIndex * 3 + 1],
                                        chunk.indices[triangleIndex * 3 + 2],
                                        similarityKernel
                                        );

                                if (similarity < similarityThreshold)
                                {
                                    continue;
                                }

                                float area = chunk.GetArea(
                                    chunk.indices[triangleIndex * 3 + 0],
                                    chunk.indices[triangleIndex * 3 + 1],
                                    chunk.indices[triangleIndex * 3 + 2]
                                    );

                                calculatedVertex +=
                                    (Vector3)(
                                        chunk.dataPerVertex[chunk.indices[triangleIndex * 3 + 0]].position +
                                        chunk.dataPerVertex[chunk.indices[triangleIndex * 3 + 1]].position +
                                        chunk.dataPerVertex[chunk.indices[triangleIndex * 3 + 2]].position
                                        ) / 3 *
                                    area * similarity;
                                sumedSimiliarity += area * similarity;
                            }

                            if (sumedSimiliarity > 0)
                            {
                                chunk.centerOfRotationPositionArray[vertexIndex] = calculatedVertex / sumedSimiliarity;
                            }
                            else
                            {
                                chunk.centerOfRotationPositionArray[vertexIndex] = chunk.dataPerVertex[vertexIndex].position;
                                processStateArray[currentThreadNum].emptyCount++;
                            }

                            processStateArray[currentThreadNum].processCount++;
                        }
                    }

                    processStateArray[currentThreadNum].done = true;
                }
                catch (Exception e)
                {
                    Debug.LogError(e);
                    Debug.LogError(e.Source);
                    Debug.LogError(e.Message);

                    processStateArray[currentThreadNum].fail = true;
                }
            };

            for (int i = 0; i < maxThreadNumber; i++)
            {
                Thread thread = new Thread(CoRProcessStart);
                thread.Name = String.Format(threadNameFormat, i, maxThreadNumber);
                thread.Start(thread);
            }

            return(processStateArray);
        }
        public static IEnumerator <int> CalculateCluster(this RenderChunk chunk, float weightDistanceThreshold)
        {
            bool[]     checkCalculateTriangle = new bool[chunk.indices.Length];
            List <int> triangleIndexList      = new List <int>();

            bool[]             checkCalculateVertex       = new bool[chunk.vertexCount];
            int                nextClusterID              = 0;
            List <ClusterData> clusterDataList            = new List <ClusterData>();
            List <int>         indexList                  = new List <int>();
            Queue <int>        processVertexIndexQueue    = new Queue <int>();
            int                numberOfCalculatedVertices = 0;

            for (int iterateVertexIndex = 0; iterateVertexIndex < checkCalculateVertex.Length; iterateVertexIndex++) // long
            {
                if (!checkCalculateVertex[iterateVertexIndex])
                {
                    List <int> vertexIndexList       = new List <int>();
                    List <int> tempTriangleIndexList = new List <int>();

                    vertexIndexList.Add(iterateVertexIndex);
                    checkCalculateVertex[iterateVertexIndex] = true;
                    numberOfCalculatedVertices++;

                    processVertexIndexQueue.Enqueue(iterateVertexIndex);

                    while (processVertexIndexQueue.Count > 0)
                    {
                        int processVertexIndex = processVertexIndexQueue.Dequeue(), findVertexIndex = 0;

                        for (int i = 0; i < chunk.indices.Length; i++)
                        {
                            if (chunk.indices[i] == processVertexIndex)
                            {
                                findVertexIndex = i;
                                int triangleIndex = findVertexIndex / 3;

                                if (!checkCalculateTriangle[triangleIndex])
                                {
                                    checkCalculateTriangle[triangleIndex] = true;
                                    tempTriangleIndexList.Add(triangleIndex);
                                }

                                for (int j = 0; j < 3; j++)
                                {
                                    int nextIndex = chunk.indices[triangleIndex * 3 + j];

                                    if (chunk.indices[nextIndex] != findVertexIndex && !checkCalculateVertex[nextIndex])
                                    {
                                        if (chunk.skinPerVertex[processVertexIndex].GetWeightDistance(chunk.skinPerVertex[nextIndex]) <= weightDistanceThreshold)
                                        {
                                            numberOfCalculatedVertices++;
                                            checkCalculateVertex[nextIndex] = true;
                                            vertexIndexList.Add(nextIndex);
                                            processVertexIndexQueue.Enqueue(nextIndex);
                                        }
                                    }
                                }
                            }
                        }
                    }

                    clusterDataList.Add(
                        new ClusterData()
                    {
                        clusterID = nextClusterID,

                        startIndexOfCluster = indexList.Count,
                        lengthOfCluster     = vertexIndexList.Count,

                        startIndexOfTriangles = triangleIndexList.Count,
                        lengthOfTriangles     = tempTriangleIndexList.Count
                    }
                        );
                    indexList.AddRange(vertexIndexList);
                    triangleIndexList.AddRange(tempTriangleIndexList);

                    nextClusterID++;
                    yield return(numberOfCalculatedVertices);
                }
            }

            chunk.clusterArray = clusterDataList.ToArray();
            chunk.clusteredVertexIndexArray   = indexList.ToArray();
            chunk.clusteredTriangleIndexArray = triangleIndexList.ToArray();
        }