Exemple #1
0
        static bool TryAttachEdgeToList(IndexVector segment, LinkedLoop <int> toList)
        {
            var first = toList.first.value;

            if (first == segment.From)
            {
                toList.AddFirst(segment.To);
                return(true);
            }
            if (first == segment.To)
            {
                toList.AddFirst(segment.From);
                return(true);
            }

            var last = toList.last.value;

            if (last == segment.From)
            {
                toList.AddLast(segment.To);
                return(true);
            }
            if (last == segment.To)
            {
                toList.AddLast(segment.From);
                return(true);
            }

            return(false);
        }
Exemple #2
0
        public LinkedList <LinkedLoop <int> > GetEdgeLoopsByIndex()
        {
            var lists = new LinkedList <LinkedLoop <int> >();

            // join by common indexes
            var capEdgesLoop = new LinkedLoop <IndexVector>(CapEdges);

            while (capEdgesLoop.size != 0)
            {
                var newList = new LinkedLoop <int>();
                lists.AddLast(newList);

                IndexVector edge = capEdgesLoop.first.value;
                capEdgesLoop.first.Remove();

                newList.AddLast(edge.From);
                newList.AddLast(edge.To);

                var current = capEdgesLoop.first;

                int counter = capEdgesLoop.size;
                while (counter != 0)
                {
                    --counter;
                    var next = current.next;

                    if (TryAttachEdgeToList(current.value, newList))
                    {
                        current.Remove();
                        counter = capEdgesLoop.size;
                    }

                    current = next;
                }
            }

            return(lists);
        }
Exemple #3
0
        /// <summary>
        /// Optimize mesh: deleting all vertices that present in mesh but not present in mesh's triangle list
        /// </summary>
        public void DeleteUnusedVertices()
        {
            DeleteEmptySubmeshes();

            bool[] used = new bool[_meshData.Vertices.Count];

            int newVertexCount = 0;

            for (var i = 0; i < _meshData.SubMeshes.Length; ++i)
            {
                var subMesh = _meshData.SubMeshes[i];
                for (var j = 0; j < subMesh.Length; ++j)
                {
                    int vIndex = subMesh[j];
                    if (!used[vIndex])
                    {
                        ++newVertexCount;
                    }
                    used[vIndex] = true;
                }
            }

            var oldToNewShift = new int[_meshData.Vertices.Count];

            newVertexCount = 0;
            for (int i = 0; i < used.Length; ++i)
            {
                if (!used[i])
                {
                    continue;
                }

                _meshData.Vertices[newVertexCount] = _meshData.Vertices[i];
                oldToNewShift[i] = newVertexCount;

                ++newVertexCount;
            }

            if (_meshData.NormalsExists)
            {
                DeleteUnusedItem(used, _meshData.Normals);
            }

            if (_meshData.ColorsExists)
            {
                DeleteUnusedItem(used, _meshData.Colors);
            }
            if (_meshData.Colors32Exists)
            {
                DeleteUnusedItem(used, _meshData.Colors32);
            }

            if (_meshData.UVExists)
            {
                DeleteUnusedItem(used, _meshData.UV);
            }
            if (_meshData.UV2Exists)
            {
                DeleteUnusedItem(used, _meshData.UV2);
            }
            if (_meshData.UV3Exists)
            {
                DeleteUnusedItem(used, _meshData.UV3);
            }
            if (_meshData.UV4Exists)
            {
                DeleteUnusedItem(used, _meshData.UV4);
            }

            if (_meshData.TangentsExists)
            {
                DeleteUnusedItem(used, _meshData.Tangents);
            }

            if (_meshData.BoneWeightsExists)
            {
                DeleteUnusedItem(used, _meshData.BoneWeights);
            }

            // shift sub meshes
            for (int smi = 0; smi < _meshData.SubMeshes.Length; ++smi)
            {
                var subMesh = _meshData.SubMeshes[smi];
                for (int vertIndex = 0; vertIndex < subMesh.Length; ++vertIndex)
                {
                    subMesh[vertIndex] = oldToNewShift[subMesh[vertIndex]];
                }
            }

            // shift crossSegments
            for (int i = 0; i < CapEdges.Count; i++)
            {
                var segment = CapEdges[i];

                CapEdges[i] = new IndexVector(oldToNewShift[segment.From], oldToNewShift[segment.To]);
            }

            // truncate
            _meshData.Vertices.RemoveRange(newVertexCount, _meshData.Vertices.Count - newVertexCount);
            if (_meshData.NormalsExists)
            {
                _meshData.Normals.RemoveRange(newVertexCount, _meshData.Normals.Count - newVertexCount);
            }

            if (_meshData.ColorsExists)
            {
                _meshData.Colors.RemoveRange(newVertexCount, _meshData.Colors.Count - newVertexCount);
            }
            if (_meshData.Colors32Exists)
            {
                _meshData.Colors32.RemoveRange(newVertexCount, _meshData.Colors32.Count - newVertexCount);
            }

            if (_meshData.UVExists)
            {
                _meshData.UV.RemoveRange(newVertexCount, _meshData.UV.Count - newVertexCount);
            }
            if (_meshData.UV2Exists)
            {
                _meshData.UV2.RemoveRange(newVertexCount, _meshData.UV2.Count - newVertexCount);
            }
            if (_meshData.UV3Exists)
            {
                _meshData.UV3.RemoveRange(newVertexCount, _meshData.UV3.Count - newVertexCount);
            }
            if (_meshData.UV4Exists)
            {
                _meshData.UV4.RemoveRange(newVertexCount, _meshData.UV4.Count - newVertexCount);
            }

            if (_meshData.TangentsExists)
            {
                _meshData.Tangents.RemoveRange(newVertexCount, _meshData.Tangents.Count - newVertexCount);
            }

            if (_meshData.BoneWeightsExists)
            {
                _meshData.BoneWeights.RemoveRange(newVertexCount, _meshData.BoneWeights.Count - newVertexCount);
            }
        }
Exemple #4
0
        /// <summary>
        /// Generate new index in triangle list that resides in plane
        /// </summary>
        public int GetIndexFor(int from, int to)
        {
            var oldDir = new IndexVector(from, to);
            int result;

            if (_chashedOuterLines.TryGetValue(oldDir, out result))
            {
                return(result);
            }

            result = _meshData.Vertices.Count;
            _chashedOuterLines.Add(oldDir, result);

            float ratioIn = CalcGetRatio(from, to);


            {             // Vertex
                Vector3 vFrom = _meshData.Vertices[from];
                Vector3 vTo   = _meshData.Vertices[to];
                Vector3 vNew  = Vector3.Lerp(vFrom, vTo, ratioIn);
                _meshData.Vertices.Add(vNew);
            }

            if (_meshData.NormalsExists)
            {
                Vector3 nFrom = _meshData.Normals[from];
                Vector3 nTo   = _meshData.Normals[to];
                Vector3 nNew  = Vector3.Slerp(nFrom, nTo, ratioIn);
                _meshData.Normals.Add(nNew);
            }

            if (_meshData.ColorsExists)
            {
                Color colorFrom = _meshData.Colors[from];
                Color colorTo   = _meshData.Colors[to];
                Color colorNew  = Color.Lerp(colorFrom, colorTo, ratioIn);
                _meshData.Colors.Add(colorNew);
            }
            if (_meshData.Colors32Exists)
            {
                Color32 colorFrom = _meshData.Colors32[from];
                Color32 colorTo   = _meshData.Colors32[to];
                Color32 colorNew  = Color32.Lerp(colorFrom, colorTo, ratioIn);
                _meshData.Colors32.Add(colorNew);
            }

            if (_meshData.UVExists)
            {
                AddValue(_meshData.UV, from, to, ratioIn);
            }
            if (_meshData.UV2Exists)
            {
                AddValue(_meshData.UV2, from, to, ratioIn);
            }
            if (_meshData.UV3Exists)
            {
                AddValue(_meshData.UV3, from, to, ratioIn);
            }
            if (_meshData.UV4Exists)
            {
                AddValue(_meshData.UV4, from, to, ratioIn);
            }

            if (_meshData.TangentsExists)
            {
                Vector4 vFrom = _meshData.Tangents[from];
                Vector4 vTo   = _meshData.Tangents[to];
                Vector4 vNew  = Vector4.Lerp(vFrom, vTo, ratioIn);
                _meshData.Tangents.Add(vNew);
            }

            if (_meshData.BoneWeightsExists)
            {
                var w1 = _meshData.BoneWeights[from];
                var w2 = _meshData.BoneWeights[to];

                var   ws       = new Dictionary <int, float>();
                float ratioOut = 1 - ratioIn;

                if (w1.weight0 != 0)
                {
                    ws.Add(w1.boneIndex0, w1.weight0 * ratioIn);
                }
                if (w1.weight1 != 0)
                {
                    ws.Add(w1.boneIndex1, w1.weight1 * ratioIn);
                }
                if (w1.weight2 != 0)
                {
                    ws.Add(w1.boneIndex2, w1.weight2 * ratioIn);
                }
                if (w1.weight3 != 0)
                {
                    ws.Add(w1.boneIndex3, w1.weight3 * ratioIn);
                }

                if (w2.weight0 != 0)
                {
                    float fA;
                    ws.TryGetValue(w2.boneIndex0, out fA);
                    ws[w2.boneIndex0] = fA + w2.weight0 * ratioOut;
                }
                if (w2.weight1 != 0)
                {
                    float fA;
                    ws.TryGetValue(w2.boneIndex1, out fA);
                    ws[w2.boneIndex1] = fA + w2.weight1 * ratioOut;
                }
                if (w2.weight2 != 0)
                {
                    float fA;
                    ws.TryGetValue(w2.boneIndex2, out fA);
                    ws[w2.boneIndex2] = fA + w2.weight2 * ratioOut;
                }
                if (w2.weight3 != 0)
                {
                    float fA;
                    ws.TryGetValue(w2.boneIndex3, out fA);
                    ws[w2.boneIndex3] = fA + w2.weight3 * ratioOut;
                }

                var newBoneWeight = new BoneWeight();
                var wsArr         = ws
                                    .Where(v => v.Value != 0)
                                    .Take(4)
                                    .OrderByDescending(v => v.Value)
                                    .ToArray();
                KeyValuePair <int, float>[] wsArr4 = new KeyValuePair <int, float> [4];
                Array.Copy(wsArr, wsArr4, wsArr.Length);

                float weightSum = 0;
                weightSum += wsArr4[0].Value;
                weightSum += wsArr4[1].Value;
                weightSum += wsArr4[2].Value;
                weightSum += wsArr4[3].Value;

                float weightRatio = 1 / weightSum;

                if (wsArr.Length > 0)
                {
                    newBoneWeight.boneIndex0 = wsArr[0].Key;
                    newBoneWeight.weight0    = wsArr[0].Value * weightRatio;
                }
                if (wsArr.Length > 1)
                {
                    newBoneWeight.boneIndex1 = wsArr[1].Key;
                    newBoneWeight.weight1    = wsArr[1].Value * weightRatio;
                }
                if (wsArr.Length > 2)
                {
                    newBoneWeight.boneIndex2 = wsArr[2].Key;
                    newBoneWeight.weight2    = wsArr[2].Value * weightRatio;
                }
                if (wsArr.Length > 3)
                {
                    newBoneWeight.boneIndex3 = wsArr[3].Key;
                    newBoneWeight.weight3    = wsArr[3].Value * weightRatio;
                }

                _meshData.BoneWeights.Add(newBoneWeight);
            }

            return(result);
        }
Exemple #5
0
        /// <summary>
        /// Generate new index in triangle list that resides in plane
        /// </summary>
        public int GetIndexFor(int from, int to)
        {
            var oldDir = new IndexVector(from, to);
            int result;

            if (_chashedOuterLines.TryGetValue(oldDir, out result))
            {
                return(result);
            }

            Vector3 v1 = _adapter.GetWorldPos(from);
            Vector3 v2 = _adapter.GetWorldPos(to);
            Vector3 enter;
            float   ratioIn = CalcGetRatio(v1, v2, out enter);

            if (Mathf.Abs((enter - v1).sqrMagnitude) <= float.Epsilon)
            {
                return(from);
            }

            if (Mathf.Abs((enter - v2).sqrMagnitude) <= float.Epsilon)
            {
                return(to);
            }

            result = _meshData.Vertices.Count;
            _chashedOuterLines.Add(oldDir, result);

            {             // Vertex
                Vector3 vFrom = _meshData.Vertices[from];
                Vector3 vTo   = _meshData.Vertices[to];
                Vector3 vNew  = Vector3.Lerp(vFrom, vTo, ratioIn);
                _meshData.Vertices.Add(vNew);
            }

            if (_meshData.NormalsExists)
            {
                Vector3 nFrom = _meshData.Normals[from];
                Vector3 nTo   = _meshData.Normals[to];
                Vector3 nNew  = Vector3.Slerp(nFrom, nTo, ratioIn);
                _meshData.Normals.Add(nNew);
            }

            if (_meshData.ColorsExists)
            {
                Color colorFrom = _meshData.Colors[from];
                Color colorTo   = _meshData.Colors[to];
                Color colorNew  = Color.Lerp(colorFrom, colorTo, ratioIn);
                _meshData.Colors.Add(colorNew);
            }
            if (_meshData.Colors32Exists)
            {
                Color32 colorFrom = _meshData.Colors32[from];
                Color32 colorTo   = _meshData.Colors32[to];
                Color32 colorNew  = Color32.Lerp(colorFrom, colorTo, ratioIn);
                _meshData.Colors32.Add(colorNew);
            }

            if (_meshData.UVExists)
            {
                AddValue(_meshData.UV, from, to, ratioIn);
            }
            if (_meshData.UV2Exists)
            {
                AddValue(_meshData.UV2, from, to, ratioIn);
            }
            if (_meshData.UV3Exists)
            {
                AddValue(_meshData.UV3, from, to, ratioIn);
            }
            if (_meshData.UV4Exists)
            {
                AddValue(_meshData.UV4, from, to, ratioIn);
            }

            if (_meshData.TangentsExists)
            {
                Vector4 vFrom = _meshData.Tangents[from];
                Vector4 vTo   = _meshData.Tangents[to];
                Vector4 vNew  = Vector4.Lerp(vFrom, vTo, ratioIn);
                _meshData.Tangents.Add(vNew);
            }

            if (_meshData.BoneWeightsExists)
            {
                var w1 = _meshData.BoneWeights[from];
                var w2 = _meshData.BoneWeights[to];

                var   ws       = new Dictionary <int, float>(8);
                float ratioOut = 1 - ratioIn;

                float tmp;
                ws.TryGetValue(w1.boneIndex0, out tmp);
                ws[w1.boneIndex0] = tmp + w1.weight0 * ratioIn;
                ws.TryGetValue(w1.boneIndex1, out tmp);
                ws[w1.boneIndex1] = tmp + w1.weight1 * ratioIn;
                ws.TryGetValue(w1.boneIndex2, out tmp);
                ws[w1.boneIndex2] = tmp + w1.weight2 * ratioIn;
                ws.TryGetValue(w1.boneIndex3, out tmp);
                ws[w1.boneIndex3] = tmp + w1.weight3 * ratioIn;

                ws.TryGetValue(w2.boneIndex0, out tmp);
                ws[w2.boneIndex0] = tmp + w2.weight0 * ratioOut;
                ws.TryGetValue(w2.boneIndex1, out tmp);
                ws[w2.boneIndex1] = tmp + w2.weight1 * ratioOut;
                ws.TryGetValue(w2.boneIndex2, out tmp);
                ws[w2.boneIndex2] = tmp + w2.weight2 * ratioOut;
                ws.TryGetValue(w2.boneIndex3, out tmp);
                ws[w2.boneIndex3] = tmp + w2.weight3 * ratioOut;

                var wsArr = ws
                            .OrderByDescending(v => v.Value)
                            .Take(4)
                            .ToArray();

                KeyValuePair <int, float>[] wsArr4 = new KeyValuePair <int, float> [4];
                Array.Copy(wsArr, wsArr4, wsArr.Length);

                float weightSum = 0;
                weightSum += wsArr4[0].Value;
                weightSum += wsArr4[1].Value;
                weightSum += wsArr4[2].Value;
                weightSum += wsArr4[3].Value;

                var   newBoneWeight = new BoneWeight();
                float weightRatio   = 1 / weightSum;

                if (wsArr.Length > 0)
                {
                    newBoneWeight.boneIndex0 = wsArr[0].Key;
                    newBoneWeight.weight0    = wsArr[0].Value * weightRatio;
                }
                if (wsArr.Length > 1)
                {
                    newBoneWeight.boneIndex1 = wsArr[1].Key;
                    newBoneWeight.weight1    = wsArr[1].Value * weightRatio;
                }
                if (wsArr.Length > 2)
                {
                    newBoneWeight.boneIndex2 = wsArr[2].Key;
                    newBoneWeight.weight2    = wsArr[2].Value * weightRatio;
                }
                if (wsArr.Length > 3)
                {
                    newBoneWeight.boneIndex3 = wsArr[3].Key;
                    newBoneWeight.weight3    = wsArr[3].Value * weightRatio;
                }

                _meshData.BoneWeights.Add(newBoneWeight);
            }

            return(result);
        }