Beispiel #1
0
        /// <summary>
        /// メッシュデータから頂点/法線/接線をワールド座標変換して返す
        /// </summary>
        /// <param name="meshData"></param>
        /// <param name="boneList"></param>
        /// <param name="wposList"></param>
        /// <param name="wnorList"></param>
        /// <param name="wtanList"></param>
        /// <returns></returns>
        public static bool CalcMeshWorldPositionNormalTangent(
            MeshData meshData, List <Transform> boneList,
            out List <Vector3> wposList, out List <Vector3> wnorList, out List <Vector3> wtanList
            )
        {
            wposList = new List <Vector3>();
            wnorList = new List <Vector3>();
            wtanList = new List <Vector3>();

            if (meshData == null || boneList == null)
            {
                return(false);
            }

            if (meshData.isSkinning == false)
            {
                // 通常メッシュ
                Transform t = boneList[0];
                for (int i = 0; i < meshData.VertexCount; i++)
                {
                    // 頂点スキニング
                    var     vw   = meshData.vertexWeightList[i];
                    Vector3 wpos = t.TransformPoint(vw.localPos);
                    Vector3 wnor = t.TransformDirection(vw.localNor);
                    Vector3 wtan = t.TransformDirection(vw.localTan);

                    wposList.Add(wpos);
                    wnorList.Add(wnor);
                    wtanList.Add(wtan);
                }
            }
            else
            {
                // スキンメッシュ
                float[] weights    = new float[4];
                int[]   boneIndexs = new int[4];
                for (int i = 0; i < meshData.VertexCount; i++)
                {
                    Vector3 wpos = Vector3.zero;
                    Vector3 wnor = Vector3.zero;
                    Vector3 wtan = Vector3.zero;

                    // 頂点スキニング
                    uint pack   = meshData.vertexInfoList[i];
                    int  wcnt   = DataUtility.Unpack4_28Hi(pack);
                    int  sindex = DataUtility.Unpack4_28Low(pack);
                    for (int j = 0; j < wcnt; j++)
                    {
                        var vw = meshData.vertexWeightList[sindex + j];

                        Transform t = boneList[vw.parentIndex];
                        wpos += t.TransformPoint(vw.localPos) * vw.weight;
                        wnor += t.TransformDirection(vw.localNor) * vw.weight;
                        wtan += t.TransformDirection(vw.localTan) * vw.weight;
                    }
                    wposList.Add(wpos);
                    wnorList.Add(wnor);
                    wtanList.Add(wtan);
                }
            }

            return(true);
        }
Beispiel #2
0
        /// <summary>
        /// メッシュデータ作成
        /// </summary>
        void CreateMeshData(MagicaBoneSpring scr)
        {
            // 共有データオブジェクト作成
            string   dataname = "BoneSpringMeshData_" + scr.name;
            MeshData mdata    = ShareDataObject.CreateShareData <MeshData>(dataname);

            // トランスフォームリスト作成
            var transformList = scr.GetTransformList();

            if (transformList.Count == 0)
            {
                return;
            }

            // 頂点作成
            List <Vector3> wposList = new List <Vector3>();
            List <Vector3> lposList = new List <Vector3>();
            List <Vector3> lnorList = new List <Vector3>();
            List <Vector3> ltanList = new List <Vector3>();
            Transform      myt      = scr.transform;

            for (int i = 0; i < transformList.Count; i++)
            {
                var t = transformList[i];

                // 頂点追加
                var pos  = t.position;
                var lpos = myt.InverseTransformDirection(pos - myt.position);
                var lnor = myt.InverseTransformDirection(t.forward);
                var ltan = myt.InverseTransformDirection(t.up);
                wposList.Add(pos);
                lposList.Add(lpos);
                lnorList.Add(lnor);
                ltanList.Add(ltan);
            }
            var vertexInfoList   = new List <uint>();
            var vertexWeightList = new List <MeshData.VertexWeight>();

            for (int i = 0; i < lposList.Count; i++)
            {
                // 1ウエイトで追加
                uint vinfo = DataUtility.Pack4_28(1, i);
                vertexInfoList.Add(vinfo);
                var vw = new MeshData.VertexWeight();
                vw.parentIndex = i;
                vw.weight      = 1.0f;
                vw.localPos    = lposList[i];
                vw.localNor    = lnorList[i];
                vw.localTan    = ltanList[i];
            }
            mdata.vertexInfoList   = vertexInfoList.ToArray();
            mdata.vertexWeightList = vertexWeightList.ToArray();
            mdata.vertexCount      = lposList.Count;

            // ライン作成
            HashSet <uint> lineSet = new HashSet <uint>();

            // 構造ライン
            for (int i = 0; i < transformList.Count; i++)
            {
                var t  = transformList[i];
                var pt = t.parent;
                if (pt != null && transformList.Contains(pt))
                {
                    int  v0   = i;
                    int  v1   = transformList.IndexOf(pt);
                    uint pair = DataUtility.PackPair(v0, v1);
                    lineSet.Add(pair);
                }
            }

            // ライン格納
            List <int> lineList = new List <int>();

            foreach (var pair in lineSet)
            {
                int v0, v1;
                DataUtility.UnpackPair(pair, out v0, out v1);
                lineList.Add(v0);
                lineList.Add(v1);
            }
            mdata.lineList  = lineList.ToArray();
            mdata.lineCount = lineList.Count / 2;

            serializedObject.FindProperty("meshData").objectReferenceValue = mdata;
            serializedObject.ApplyModifiedProperties();

            // 使用トランスフォームシリアライズ
            var property    = serializedObject.FindProperty("useTransformList");
            var propertyPos = serializedObject.FindProperty("useTransformPositionList");
            var propertyRot = serializedObject.FindProperty("useTransformRotationList");
            var propertyScl = serializedObject.FindProperty("useTransformScaleList");

            property.arraySize    = transformList.Count;
            propertyPos.arraySize = transformList.Count;
            propertyRot.arraySize = transformList.Count;
            propertyScl.arraySize = transformList.Count;
            for (int i = 0; i < transformList.Count; i++)
            {
                property.GetArrayElementAtIndex(i).objectReferenceValue = transformList[i];
                propertyPos.GetArrayElementAtIndex(i).vector3Value      = transformList[i].localPosition;
                propertyRot.GetArrayElementAtIndex(i).quaternionValue   = transformList[i].localRotation;
                propertyScl.GetArrayElementAtIndex(i).vector3Value      = transformList[i].localScale;
            }
            serializedObject.ApplyModifiedProperties();

            // データ検証とハッシュ
            mdata.CreateVerifyData();
            serializedObject.ApplyModifiedProperties();

            EditorUtility.SetDirty(mdata);
        }
Beispiel #3
0
 public ulong GetTetraHash()
 {
     return(DataUtility.PackQuater(vertexList[0].index, vertexList[1].index, vertexList[2].index, vertexList[3].index));
 }
        /// <summary>
        /// 頂点ウエイト情報の作成
        /// </summary>
        void CreateVertexWeightList(
            int vcnt,
            List <Vector3> vertices, List <Vector3> normals, List <Vector4> tangents,
            List <BoneWeight> boneWeights, List <Matrix4x4> bindPoses,
            out List <uint> vlist, out List <MeshData.VertexWeight> wlist
            )
        {
            vlist = new List <uint>();
            wlist = new List <MeshData.VertexWeight>();
            for (int j = 0; j < vcnt; j++)
            {
                var bw = boneWeights[j];

                int wcnt   = 0;
                int wstart = wlist.Count;

                // ローカル座標を事前計算する(バインドポーズ方式よりメモリは食うが実行が速い)
                if (bw.weight0 > 0.0f)
                {
                    wcnt++;
                    var vw = new MeshData.VertexWeight();
                    vw.weight      = bw.weight0;
                    vw.parentIndex = bw.boneIndex0;
                    vw.localPos    = bindPoses[bw.boneIndex0].MultiplyPoint(vertices[j]);
                    vw.localNor    = bindPoses[bw.boneIndex0].MultiplyVector(normals[j]).normalized;
                    vw.localTan    = bindPoses[bw.boneIndex0].MultiplyVector(tangents[j]).normalized;
                    wlist.Add(vw);
                }
                if (bw.weight1 > 0.0f)
                {
                    wcnt++;
                    var vw = new MeshData.VertexWeight();
                    vw.weight      = bw.weight1;
                    vw.parentIndex = bw.boneIndex1;
                    vw.localPos    = bindPoses[bw.boneIndex1].MultiplyPoint(vertices[j]);
                    vw.localNor    = bindPoses[bw.boneIndex1].MultiplyVector(normals[j]).normalized;
                    vw.localTan    = bindPoses[bw.boneIndex1].MultiplyVector(tangents[j]).normalized;
                    wlist.Add(vw);
                }
                if (bw.weight2 > 0.0f)
                {
                    wcnt++;
                    var vw = new MeshData.VertexWeight();
                    vw.weight      = bw.weight2;
                    vw.parentIndex = bw.boneIndex2;
                    vw.localPos    = bindPoses[bw.boneIndex2].MultiplyPoint(vertices[j]);
                    vw.localNor    = bindPoses[bw.boneIndex2].MultiplyVector(normals[j]).normalized;
                    vw.localTan    = bindPoses[bw.boneIndex2].MultiplyVector(tangents[j]).normalized;
                    wlist.Add(vw);
                }
                if (bw.weight3 > 0.0f)
                {
                    wcnt++;
                    var vw = new MeshData.VertexWeight();
                    vw.weight      = bw.weight3;
                    vw.parentIndex = bw.boneIndex3;
                    vw.localPos    = bindPoses[bw.boneIndex3].MultiplyPoint(vertices[j]);
                    vw.localNor    = bindPoses[bw.boneIndex3].MultiplyVector(normals[j]).normalized;
                    vw.localTan    = bindPoses[bw.boneIndex3].MultiplyVector(tangents[j]).normalized;
                    wlist.Add(vw);
                }

                // 頂点のウエイト情報
                uint pack = DataUtility.Pack4_28(wcnt, wstart);
                vlist.Add(pack);
            }
        }
            // 仮想メッシュ頂点ごと
            public void Execute(int vindex)
            {
                // 計算フラグクリア
                virtualVertexFlagList[vindex] = 0;


                //uint info = virtualVertexInfoList[vindex];
                // 使用頂点のみ
                //if ((info & 0xffff) == 0)
                if (virtualVertexUseList[vindex] == 0)
                {
                    return;
                }

                // このメッシュの使用をチェック
                //int mindex = DataUtility.Unpack16Hi(info);
                int mindex  = virtualVertexMeshIndexList[vindex];
                var m_minfo = virtualMeshInfoList[mindex - 1]; // (-1)するので注意!

                if (m_minfo.IsUse() == false)
                {
                    return;
                }

                var s_minfo = sharedVirtualMeshInfoList[m_minfo.sharedVirtualMeshIndex];

                int i        = vindex - m_minfo.vertexChunk.startIndex;
                int s_vindex = s_minfo.vertexChunk.startIndex + i;
                int s_wstart = s_minfo.weightChunk.startIndex;
                int m_bstart = m_minfo.boneChunk.startIndex;

                // スキニング処理(仮想メッシュはスキニングのみ)
                float3 spos = 0;
                float3 snor = 0;
                float3 stan = 0;

                uint pack   = sharedVirtualVertexInfoList[s_vindex];
                int  wcnt   = DataUtility.Unpack4_28Hi(pack);
                int  wstart = DataUtility.Unpack4_28Low(pack);

                for (int j = 0; j < wcnt; j++)
                {
                    var vw = sharedVirtualWeightList[s_wstart + wstart + j];

                    // ボーン
                    int tindex = virtualTransformIndexList[m_bstart + vw.parentIndex];
                    var tpos   = transformPosList[tindex];
                    var trot   = transformRotList[tindex];
                    var tscl   = transformSclList[tindex];

                    // ウエイト0はありえない
                    spos += (tpos + math.mul(trot, vw.localPos * tscl)) * vw.weight;

                    // 法線/接線
                    if (tscl.x < 0 || tscl.y < 0 || tscl.z < 0)
                    {
                        // マイナススケール対応
                        // 法線/接線は一旦クォータニオンに変換してフリップスケールを乗算して計算する
                        var q = quaternion.LookRotation(vw.localNor, vw.localTan);
                        q     = new quaternion(q.value * new float4(-math.sign(tscl), 1));
                        snor += math.mul(trot, math.mul(q, new float3(0, 0, 1))) * vw.weight;
                        stan += math.mul(trot, math.mul(q, new float3(0, 1, 0))) * vw.weight;
                    }
                    else
                    {
                        snor += math.mul(trot, vw.localNor) * vw.weight;
                        stan += math.mul(trot, vw.localTan) * vw.weight;
                    }
                }

                virtualPosList[vindex] = spos;
                virtualRotList[vindex] = quaternion.LookRotation(snor, stan);
            }
        /// <summary>
        /// メッシュ頂点の選択データを設定する
        /// </summary>
        /// <param name="meshData"></param>
        /// <param name="selects"></param>
        public void SetSelectionData(MeshData meshData, List <int> selects, List <MeshData> childMeshDataList)
        {
            // 選択データ初期化
            selectionList.Clear();
            if (meshData != null && meshData.ChildCount > 0)
            {
                for (int i = 0; i < meshData.ChildCount; i++)
                {
                    var dsel  = new DeformerSelection();
                    int cvcnt = meshData.childDataList[i].VertexCount;
                    for (int j = 0; j < cvcnt; j++)
                    {
                        dsel.selectData.Add(Invalid);
                        dsel.vertexHashList.Add(0); // ハッシュ0=無効
                    }

                    selectionList.Add(dsel);
                }
            }
            else
            {
                // そのまま
                var dsel  = new DeformerSelection();
                int cvcnt = selects.Count;
                for (int j = 0; j < cvcnt; j++)
                {
                    dsel.selectData.Add(Invalid);
                    dsel.vertexHashList.Add(0); // ハッシュ0=無効
                }

                selectionList.Add(dsel);
            }

            // 選択データに追加
            for (int i = 0; i < selects.Count; i++)
            {
                int data = selects[i];
                if (meshData != null && meshData.ChildCount > 0)
                {
                    // 親頂点に影響する子頂点情報
                    Dictionary <int, List <uint> > dict = meshData.GetVirtualToChildVertexDict();

                    // 親頂点に影響する子頂点に記録
                    if (dict.ContainsKey(i))
                    {
                        foreach (var pack in dict[i])
                        {
                            int cmindex = DataUtility.Unpack16Hi(pack);
                            int cvindex = DataUtility.Unpack16Low(pack);

                            selectionList[cmindex].selectData[cvindex] = data;

                            // 頂点ハッシュも記録
                            if (cmindex < childMeshDataList.Count)
                            {
                                var cmdata = childMeshDataList[cmindex];
                                if (cmdata != null && cvindex < cmdata.VertexHashCount)
                                {
                                    selectionList[cmindex].vertexHashList[cvindex] = cmdata.vertexHashList[cvindex];
                                }
                            }
                        }
                    }
                }
                else
                {
                    // そのまま
                    selectionList[0].selectData[i] = data;
                }
            }

            // データハッシュ設定
            CreateVerifyData();
        }
        //=========================================================================================
        /// <summary>
        /// 事前データ作成
        /// </summary>
        /// <param name="scr"></param>
        private void CreateData(MagicaVirtualDeformer scr)
        {
            Debug.Log("Started creating. [" + scr.name + "]");

            // 子メッシュの検証
            if (VerifyChildData(scr.Deformer) == false)
            {
                // error
                Debug.LogError("Setup failed. Invalid RenderDeformer data.");
                return;
            }

            serializedObject.FindProperty("deformer.targetObject").objectReferenceValue = scr.gameObject;

            // 新規メッシュデータ
            var meshData = ShareDataObject.CreateShareData <MeshData>("VirtualMeshData_" + scr.name);

            // 設計時スケール
            meshData.baseScale = scr.transform.lossyScale;

            // 仮想メッシュ作成
            var reductionMesh = new MagicaReductionMesh.ReductionMesh();

            //reductionMesh.WeightMode = MagicaReductionMesh.ReductionMesh.ReductionWeightMode.Average; // 平均法(v1.5.2)
            reductionMesh.WeightMode = MagicaReductionMesh.ReductionMesh.ReductionWeightMode.DistanceAverage; // 距離比重改良(v1.8.6)
            reductionMesh.MeshData.MaxWeightCount   = scr.Deformer.MaxWeightCount;
            reductionMesh.MeshData.WeightPow        = scr.Deformer.WeightPow;
            reductionMesh.MeshData.SameSurfaceAngle = scr.Deformer.SameSurfaceAngle;
            for (int i = 0; i < scr.Deformer.RenderDeformerCount; i++)
            {
                var deformer = scr.Deformer.GetRenderDeformer(i).Deformer;
                if (deformer != null)
                {
                    var sren = deformer.TargetObject.GetComponent <SkinnedMeshRenderer>();
                    List <Transform> boneList = new List <Transform>();
                    if (sren)
                    {
                        boneList = new List <Transform>(sren.bones);
                    }
                    else
                    {
                        boneList.Add(deformer.TargetObject.transform);
                    }
                    reductionMesh.AddMesh(
                        deformer.MeshData.isSkinning,
                        deformer.SharedMesh,
                        boneList,
                        deformer.SharedMesh.bindposes,
                        deformer.SharedMesh.boneWeights
                        );
                }
            }

            //reductionMesh.DebugData.DispMeshInfo("リダクション前");

            // リダクション
            reductionMesh.Reduction(
                scr.Deformer.MergeVertexDistance > 0.0f ? 0.0001f : 0.0f,
                scr.Deformer.MergeVertexDistance,
                scr.Deformer.MergeTriangleDistance,
                false
                );

            // (1)ゼロ距離リダクション
            //if (scr.Deformer.MergeVertexDistance > 0.0f)
            //    reductionMesh.ReductionZeroDistance();

            //// (2)頂点距離マージ
            //if (scr.Deformer.MergeVertexDistance > 0.0001f)
            //    reductionMesh.ReductionRadius(scr.Deformer.MergeVertexDistance);

            //// (3)トライアングル接続マージ
            //if (scr.Deformer.MergeTriangleDistance > 0.0f)
            //    reductionMesh.ReductionPolygonLink(scr.Deformer.MergeTriangleDistance);

            //// (4)未使用ボーンの削除
            //reductionMesh.ReductionBone();

            // (5)頂点の最大接続トライアングル数制限
            //reductionMesh.ReductionTriangleConnect(6);

            //reductionMesh.DebugData.DispMeshInfo("リダクション後");

            // 最終メッシュデータ取得
            var final = reductionMesh.GetFinalData(scr.gameObject.transform);

            // メッシュデータシリアライズ
            meshData.isSkinning  = final.IsSkinning;
            meshData.vertexCount = final.VertexCount;

            List <uint> vlist;
            List <MeshData.VertexWeight> wlist;

            CreateVertexWeightList(
                final.VertexCount, final.vertices, final.normals, final.tangents, final.boneWeights, final.bindPoses,
                out vlist, out wlist
                );
            meshData.vertexInfoList   = vlist.ToArray();
            meshData.vertexWeightList = wlist.ToArray();
            meshData.boneCount        = final.BoneCount;

            meshData.uvList        = final.uvs.ToArray();
            meshData.lineCount     = final.LineCount;
            meshData.lineList      = final.lines.ToArray();
            meshData.triangleCount = final.TriangleCount;
            meshData.triangleList  = final.triangles.ToArray();

            List <uint> vertexToTriangleInfoList = new List <uint>();

            for (int i = 0; i < final.VertexCount; i++)
            {
                int tcnt   = final.vertexToTriangleCountList[i];
                int tstart = final.vertexToTriangleStartList[i];
                vertexToTriangleInfoList.Add(DataUtility.Pack8_24(tcnt, tstart));
            }
            meshData.vertexToTriangleInfoList  = vertexToTriangleInfoList.ToArray();
            meshData.vertexToTriangleIndexList = final.vertexToTriangleIndexList.ToArray();

            // 子メッシュ情報
            for (int i = 0; i < final.MeshCount; i++)
            {
                var minfo     = final.meshList[i];
                var rdeformer = scr.Deformer.GetRenderDeformer(i).Deformer;
                var mdata     = new MeshData.ChildData();

                mdata.childDataHash = rdeformer.GetDataHash();
                mdata.vertexCount   = minfo.VertexCount;

                // 頂点ウエイト情報作成
                CreateVertexWeightList(
                    minfo.VertexCount, minfo.vertices, minfo.normals, minfo.tangents, minfo.boneWeights, final.vertexBindPoses,
                    out vlist, out wlist
                    );

                mdata.vertexInfoList   = vlist.ToArray();
                mdata.vertexWeightList = wlist.ToArray();

                mdata.parentIndexList = minfo.parents.ToArray();

                meshData.childDataList.Add(mdata);
            }

            // レイヤー情報
            //for (int i = 0; i < final.LayerCount; i++)
            //{
            //    var linfo = new MeshData.LayerInfo();
            //    linfo.triangleList = new List<int>(final.layerList[i].triangleList);
            //    meshData.layerInfoList.Add(linfo);
            //}

            // 検証
            meshData.CreateVerifyData();
            serializedObject.FindProperty("deformer.meshData").objectReferenceValue = meshData;

            // ボーン
            var property = serializedObject.FindProperty("deformer.boneList");

            property.arraySize = final.bones.Count;
            for (int i = 0; i < final.bones.Count; i++)
            {
                property.GetArrayElementAtIndex(i).objectReferenceValue = final.bones[i];
            }

            serializedObject.ApplyModifiedProperties();

            // デフォーマーデータの検証とハッシュ
            scr.Deformer.CreateVerifyData();
            serializedObject.ApplyModifiedProperties();

            // コアコンポーネントの検証とハッシュ
            scr.CreateVerifyData();
            serializedObject.ApplyModifiedProperties();

            EditorUtility.SetDirty(meshData);

            Debug.Log("Setup completed. [" + scr.name + "]");
        }
        private static void CollectionVertex(
            ref PhysicsManagerMeshData.RenderMeshInfo r_minfo,
            ref NativeArray <uint> sharedChildVertexInfoList,
            ref NativeArray <MeshData.VertexWeight> sharedChildVertexWeightList,
            ref NativeArray <float3> virtualPosList,
            ref NativeArray <quaternion> virtualRotList,
            ref float3 tpos,
            ref quaternion trot,
            ref float3 tscl,
            ref quaternion itrot,
            float scaleRatio,
            ref float3 scaleDirection,
            bool calcNormal,
            bool calcTangent,
            int vindex,
            int i,
            uint flag,
            ref NativeArray <float3> renderPosList,
            ref NativeArray <float3> renderNormalList,
            ref NativeArray <float4> renderTangentList
            )
        {
            // レンダーメッシュは複数の仮想メッシュに接続される場合がある
            int4   data;
            float3 sum_pos  = 0;
            float3 sum_nor  = 0;
            float3 sum_tan  = 0;
            float4 sum_tan4 = 0;

            sum_tan4.w = -1;
            int  cnt = 0;
            uint bit = PhysicsManagerMeshData.RenderVertexFlag_Use;

            for (int l = 0; l < PhysicsManagerMeshData.MaxRenderMeshLinkCount; l++)
            {
                if (r_minfo.IsLinkMesh(l))
                {
                    // data.x = 子共有メッシュの頂点スタートインデックス
                    // data.y = 子共有メッシュのウエイトスタートインデック
                    // data.z = 仮想メッシュの頂点スタートインデックス
                    // data.w = 仮想共有メッシュの頂点スタートインデックス
                    data.x = r_minfo.childMeshVertexStartIndex[l];
                    data.y = r_minfo.childMeshWeightStartIndex[l];
                    data.z = r_minfo.virtualMeshVertexStartIndex[l];
                    data.w = r_minfo.sharedVirtualMeshVertexStartIndex[l];

                    if ((flag & bit) == 0)
                    {
                        bit = bit << 1;
                        continue;
                    }

                    float3 pos = 0;
                    float3 nor = 0;
                    float3 tan = 0;

                    int sc_vindex = data.x + i;
                    int sc_wstart = data.y;
                    int m_vstart  = data.z;

                    // スキニング
                    uint pack   = sharedChildVertexInfoList[sc_vindex];
                    int  wcnt   = DataUtility.Unpack4_28Hi(pack);
                    int  wstart = DataUtility.Unpack4_28Low(pack);

                    if (calcTangent)
                    {
                        for (int j = 0; j < wcnt; j++)
                        {
                            var vw = sharedChildVertexWeightList[sc_wstart + wstart + j];

                            // ウエイト0はありえない
                            var mpos = virtualPosList[m_vstart + vw.parentIndex];
                            var mrot = virtualRotList[m_vstart + vw.parentIndex];

                            // position
                            //pos += (mpos + math.mul(mrot, vw.localPos * renderScale)) * vw.weight;
                            pos += (mpos + math.mul(mrot, vw.localPos * scaleDirection * scaleRatio)) * vw.weight;

                            // normal
                            //nor += math.mul(mrot, vw.localNor) * vw.weight;
                            nor += math.mul(mrot, vw.localNor * scaleDirection) * vw.weight;

                            // tangent
                            //tan += math.mul(mrot, vw.localTan) * vw.weight;
                            tan += math.mul(mrot, vw.localTan * scaleDirection) * vw.weight;
                        }

                        // レンダラーのローカル座標系に変換する
                        pos = math.mul(itrot, (pos - tpos)) / tscl;
                        nor = math.mul(itrot, nor);
                        tan = math.mul(itrot, tan);

                        // マイナススケール対応
                        nor *= scaleDirection;
                        tan *= scaleDirection;

                        sum_pos += pos;
                        sum_nor += nor;
                        sum_tan += tan;
                    }
                    else if (calcNormal)
                    {
                        for (int j = 0; j < wcnt; j++)
                        {
                            var vw = sharedChildVertexWeightList[sc_wstart + wstart + j];

                            // ウエイト0はありえない
                            var mpos = virtualPosList[m_vstart + vw.parentIndex];
                            var mrot = virtualRotList[m_vstart + vw.parentIndex];

                            // position
                            //pos += (mpos + math.mul(mrot, vw.localPos * renderScale)) * vw.weight;
                            pos += (mpos + math.mul(mrot, vw.localPos * scaleDirection * scaleRatio)) * vw.weight;

                            // normal
                            //nor += math.mul(mrot, vw.localNor) * vw.weight;
                            nor += math.mul(mrot, vw.localNor * scaleDirection) * vw.weight;
                        }

                        // レンダラーのローカル座標系に変換する
                        pos = math.mul(itrot, (pos - tpos)) / tscl;
                        nor = math.mul(itrot, nor);

                        // マイナススケール対応
                        nor *= scaleDirection;

                        sum_pos += pos;
                        sum_nor += nor;
                    }
                    else
                    {
                        for (int j = 0; j < wcnt; j++)
                        {
                            var vw = sharedChildVertexWeightList[sc_wstart + wstart + j];

                            // ウエイト0はありえない
                            var mpos = virtualPosList[m_vstart + vw.parentIndex];
                            var mrot = virtualRotList[m_vstart + vw.parentIndex];

                            // position
                            //pos += (mpos + math.mul(mrot, vw.localPos * renderScale)) * vw.weight;
                            pos += (mpos + math.mul(mrot, vw.localPos * scaleDirection * scaleRatio)) * vw.weight;
                        }

                        // レンダラーのローカル座標系に変換する
                        pos = math.mul(itrot, (pos - tpos)) / tscl;

                        sum_pos += pos;
                    }
                    cnt++;
                }
                bit = bit << 1;
            }
            if (cnt > 0)
            {
                renderPosList[vindex] = sum_pos / cnt;

                if (calcTangent)
                {
                    //renderPosList[vindex] = sum_pos / cnt;
                    renderNormalList[vindex]  = sum_nor / cnt;
                    sum_tan4.xyz              = sum_tan / cnt;
                    renderTangentList[vindex] = sum_tan4;
                }
                else if (calcNormal)
                {
                    //renderPosList[vindex] = sum_pos / cnt;
                    renderNormalList[vindex] = sum_nor / cnt;
                }
            }
        }
            // レンダーメッシュごと
            public void Execute(int rmindex)
            {
                var r_minfo = renderMeshInfoList[rmindex];

                if (r_minfo.InUse() == false)
                {
                    return;
                }

                // 更新の必要があるメッシュのみ実行する
                if (r_minfo.IsFlag(updateFlag) == false)
                {
                    return;
                }

                var sr_minfo = sharedRenderMeshInfoList[r_minfo.renderSharedMeshIndex];

                for (int i = 0; i < r_minfo.vertexChunk.dataLength; i++)
                {
                    int  index = r_minfo.vertexChunk.startIndex + i;
                    uint flag  = renderVertexFlagList[index];

                    // 頂点使用フラグをリセット
                    flag &= 0xffff;

                    int4 data;
                    uint bit = PhysicsManagerMeshData.RenderVertexFlag_Use;
                    for (int l = 0; l < PhysicsManagerMeshData.MaxRenderMeshLinkCount; l++)
                    {
                        if (r_minfo.IsLinkMesh(l))
                        {
                            // data.x = 子共有メッシュの頂点スタートインデックス
                            // data.y = 子共有メッシュのウエイトスタートインデック
                            // data.z = 仮想メッシュの頂点スタートインデックス
                            // data.w = 仮想共有メッシュの頂点スタートインデックス
                            data.x = r_minfo.childMeshVertexStartIndex[l];
                            data.y = r_minfo.childMeshWeightStartIndex[l];
                            data.z = r_minfo.virtualMeshVertexStartIndex[l];
                            data.w = r_minfo.sharedVirtualMeshVertexStartIndex[l];

                            int sc_wstart = data.y;
                            int m_vstart  = data.z;
                            int sc_vindex = data.x + i;

                            // ウエイト参照するすべての仮想頂点が利用頂点ならばこのレンダーメッシュ頂点を利用する
                            //int usecnt = 0;
                            //uint pack = sharedChildVertexInfoList[sc_vindex];
                            //int wcnt = DataUtility.Unpack4_28Hi(pack);
                            //int wstart = DataUtility.Unpack4_28Low(pack);
                            //for (int j = 0; j < wcnt; j++)
                            //{
                            //    // ウエイト0はありえない
                            //    var vw = sharedChildVertexWeightList[sc_wstart + wstart + j];
                            //    //if ((virtualVertexInfoList[m_vstart + vw.parentIndex] & 0xffff) > 0)
                            //    //    usecnt++;
                            //    if (virtualVertexUseList[m_vstart + vw.parentIndex] > 0)
                            //        usecnt++;
                            //}
                            //if (wcnt > 0 && wcnt == usecnt)
                            //{
                            //    // 利用する
                            //    flag |= bit;
                            //}

                            // ウエイト参照するすべての仮想頂点が利用頂点ならばこのレンダーメッシュ頂点を利用する
                            uint pack   = sharedChildVertexInfoList[sc_vindex];
                            int  wcnt   = DataUtility.Unpack4_28Hi(pack);
                            int  wstart = DataUtility.Unpack4_28Low(pack);
                            int  fixcnt = 0;
                            int  maxfix = wcnt * 75 / 100; // 許容する固定頂点数(75%まで)
                            int  j      = 0;
                            for (; j < wcnt; j++)
                            {
                                // ウエイト0はありえない
                                var vw     = sharedChildVertexWeightList[sc_wstart + wstart + j];
                                int vindex = m_vstart + vw.parentIndex;

                                // 仮想頂点が1つでも未使用ならば、この頂点は利用しない
                                if (virtualVertexUseList[vindex] == 0)
                                {
                                    break;
                                }

                                // 仮想頂点の固定数をカウント
                                if (virtualVertexFixList[vindex] > 0)
                                {
                                    fixcnt++;
                                    if (fixcnt > maxfix)
                                    {
                                        break; // 固定頂点数がしきい値を越えたので、この頂点は使用しない
                                    }
                                }
                            }
                            if (wcnt == j)
                            {
                                // 利用する
                                flag |= bit;
                            }
                        }
                        bit = bit << 1;
                    }

                    // 頂点フラグを再設定
                    renderVertexFlagList[index] = flag;

                    // 頂点セット
                    int si = r_minfo.sharedRenderMeshVertexStartIndex + i;
                    if ((flag & 0xffff0000) == 0)
                    {
                        // 未使用頂点
                        renderPosList[index]     = sharedRenderVertices[si];
                        renderNormalList[index]  = sharedRenderNormals[si];
                        renderTangentList[index] = sharedRenderTangents[si];
                    }

                    // ボーンウエイト
                    if (sr_minfo.IsSkinning())
                    {
#if UNITY_2018
                        int bwindex = r_minfo.boneWeightsChunk.startIndex + i;
                        if ((flag & 0xffff0000) == 0)
                        {
                            // 未使用頂点
                            int bwsi = sr_minfo.boneWeightsChunk.startIndex + i;
                            renderBoneWeightList[bwindex] = sharedBoneWeightList[bwsi];
                        }
                        else
                        {
                            // 使用頂点
                            int        renderBoneIndex = sr_minfo.rendererBoneIndex;
                            BoneWeight bw = new BoneWeight();
                            bw.boneIndex0 = renderBoneIndex;
                            bw.weight0    = 1;
                            renderBoneWeightList[bwindex] = bw;
                        }
#else
                        int svindex         = sr_minfo.bonePerVertexChunk.startIndex + i;
                        int wstart          = sharedBonesPerVertexStartList[svindex];
                        int windex          = r_minfo.boneWeightsChunk.startIndex + wstart;
                        int swindex         = sr_minfo.boneWeightsChunk.startIndex + wstart;
                        int renderBoneIndex = sr_minfo.rendererBoneIndex;

                        int cnt = sharedBonesPerVertexList[svindex];
                        if ((flag & 0xffff0000) == 0)
                        {
                            // 未使用頂点
                            for (int j = 0; j < cnt; j++)
                            {
                                renderBoneWeightList[windex + j] = sharedBoneWeightList[swindex + j];
                            }
                        }
                        else
                        {
                            // 使用頂点
                            for (int j = 0; j < cnt; j++)
                            {
                                BoneWeight1 bw = sharedBoneWeightList[swindex + j];
                                bw.boneIndex = renderBoneIndex;
                                renderBoneWeightList[windex + j] = bw;
                            }
                        }
#endif
                    }
                }

                // 情報書き戻し
                r_minfo.SetFlag(updateFlag, false);
                renderMeshInfoList[rmindex] = r_minfo;
            }
        public void AddLockPair(int id1, int id2)
        {
            uint pair = DataUtility.PackPair(id1, id2);

            lockPairSet.Add(pair);
        }
Beispiel #11
0
        /// <summary>
        /// クロスメッシュ用に頂点セレクションデータを拡張する
        /// </summary>
        /// <param name="originalSelection"></param>
        /// <param name="extendNext">無効頂点の隣接が移動/固定頂点なら拡張に変更する</param>
        /// <param name="extendWeight">移動/固定頂点に影響する子頂点に接続する無効頂点は拡張に変更する</param>
        /// <returns></returns>
        public List <int> ExtendSelection(List <int> originalSelection, bool extendNext, bool extendWeight)
        {
            var selection = new List <int>(originalSelection);

            // (1)無効頂点の隣接が移動/固定頂点なら拡張に変更する
            if (extendNext)
            {
                // ライン/トライアングル情報を分解して各頂点ごとの接続頂点をリスト化
                List <HashSet <int> > vlink = MeshUtility.GetTriangleToVertexLinkList(vertexCount, new List <int>(lineList), new List <int>(triangleList));

                // 無効頂点の隣接が移動/固定頂点なら拡張に変更する
                List <int> changeIndexList = new List <int>();
                for (int i = 0; i < vertexCount; i++)
                {
                    if (selection[i] == SelectionData.Invalid)
                    {
                        // 隣接を調べる
                        var vset = vlink[i];
                        foreach (var vindex in vset)
                        {
                            if (selection[vindex] == SelectionData.Move || selection[vindex] == SelectionData.Fixed)
                            {
                                // 拡張に変更する
                                selection[i] = SelectionData.Extend;
                            }
                        }
                    }
                }
            }

            // (2)移動/固定頂点に影響する子頂点に接続する無効頂点は拡張に変更する
            if (extendWeight)
            {
                var extendSet = new HashSet <int>();
                foreach (var cdata in childDataList)
                {
                    for (int i = 0; i < cdata.VertexCount; i++)
                    {
                        // 頂点のウエイト数とウエイト開始インデックス
                        uint pack   = cdata.vertexInfoList[i];
                        int  wcnt   = DataUtility.Unpack4_28Hi(pack);
                        int  wstart = DataUtility.Unpack4_28Low(pack);

                        bool link = false;
                        for (int j = 0; j < wcnt; j++)
                        {
                            int sindex = wstart + j;
                            var vw     = cdata.vertexWeightList[sindex];

                            // この子頂点が移動/固定頂点に接続しているか判定する
                            if (vw.weight > 0.0f && (selection[vw.parentIndex] == SelectionData.Move || selection[vw.parentIndex] == SelectionData.Fixed))
                            {
                                link = true;
                            }
                        }

                        if (link)
                        {
                            for (int j = 0; j < wcnt; j++)
                            {
                                int sindex = wstart + j;
                                var vw     = cdata.vertexWeightList[sindex];

                                // この子頂点が接続する頂点がInvalidの場合はExtendに変更する
                                if (vw.weight > 0.0f && selection[vw.parentIndex] == SelectionData.Invalid)
                                {
                                    extendSet.Add(vw.parentIndex);
                                }
                            }
                        }
                    }
                }
                foreach (var vindex in extendSet)
                {
                    selection[vindex] = SelectionData.Extend;
                }
            }

            return(selection);
        }
Beispiel #12
0
            // レンダーメッシュごと
            public void Execute(int rmindex)
            {
                var r_minfo = renderMeshInfoList[rmindex];

                if (r_minfo.InUse() == false)
                {
                    return;
                }

                // レンダラーのローカル座標系に変換する
                int        tindex = r_minfo.transformIndex;
                var        tpos   = transformPosList[tindex];
                var        trot   = transformRotList[tindex];
                var        tscl   = transformSclList[tindex];
                quaternion itrot  = math.inverse(trot);

                int vcnt     = r_minfo.vertexChunk.dataLength;
                int r_vstart = r_minfo.vertexChunk.startIndex;

                bool calcNormal  = r_minfo.IsFlag(PhysicsManagerMeshData.Meshflag_CalcNormal);
                bool calcTangent = r_minfo.IsFlag(PhysicsManagerMeshData.Meshflag_CalcTangent);

                // 頂点ごと
                for (int i = 0; i < r_minfo.vertexChunk.dataLength; i++)
                {
                    int  vindex = r_minfo.vertexChunk.startIndex + i;
                    uint flag   = renderVertexFlagList[vindex];

                    // 使用頂点のみ
                    if ((flag & 0xffff0000) == 0)
                    {
                        continue;
                    }

                    // レンダーメッシュは複数の仮想メッシュに接続される場合がある
                    int4   data;
                    float3 sum_pos  = 0;
                    float3 sum_nor  = 0;
                    float3 sum_tan  = 0;
                    float4 sum_tan4 = 0;
                    sum_tan4.w = -1;
                    int  cnt = 0;
                    uint bit = PhysicsManagerMeshData.RenderVertexFlag_Use;
                    for (int l = 0; l < PhysicsManagerMeshData.MaxRenderMeshLinkCount; l++)
                    {
                        if (r_minfo.IsLinkMesh(l))
                        {
                            // data.x = 子共有メッシュの頂点スタートインデックス
                            // data.y = 子共有メッシュのウエイトスタートインデック
                            // data.z = 仮想メッシュの頂点スタートインデックス
                            // data.w = 仮想共有メッシュの頂点スタートインデックス
                            data.x = r_minfo.childMeshVertexStartIndex[l];
                            data.y = r_minfo.childMeshWeightStartIndex[l];
                            data.z = r_minfo.virtualMeshVertexStartIndex[l];
                            data.w = r_minfo.sharedVirtualMeshVertexStartIndex[l];

                            if ((flag & bit) == 0)
                            {
                                bit = bit << 1;
                                continue;
                            }

                            float3 pos = 0;
                            float3 nor = 0;
                            float3 tan = 0;

                            int sc_vindex = data.x + i;
                            int sc_wstart = data.y;
                            int m_vstart  = data.z;

                            // スキニング
                            uint pack   = sharedChildVertexInfoList[sc_vindex];
                            int  wcnt   = DataUtility.Unpack4_28Hi(pack);
                            int  wstart = DataUtility.Unpack4_28Low(pack);

                            if (calcTangent)
                            {
                                for (int j = 0; j < wcnt; j++)
                                {
                                    var vw = sharedChildVertexWeightList[sc_wstart + wstart + j];

                                    // ウエイト0はありえない
                                    var mpos = virtualPosList[m_vstart + vw.parentIndex];
                                    var mrot = virtualRotList[m_vstart + vw.parentIndex];

                                    // position
                                    pos += (mpos + math.mul(mrot, vw.localPos)) * vw.weight;

                                    // normal
                                    nor += math.mul(mrot, vw.localNor) * vw.weight;

                                    // tangent
                                    tan += math.mul(mrot, vw.localTan) * vw.weight;
                                }

                                // レンダラーのローカル座標系に変換する
                                pos = math.mul(itrot, (pos - tpos)) / tscl;
                                nor = math.mul(itrot, nor);
                                tan = math.mul(itrot, tan);

                                sum_pos += pos;
                                sum_nor += nor;
                                sum_tan += tan;
                            }
                            else if (calcNormal)
                            {
                                for (int j = 0; j < wcnt; j++)
                                {
                                    var vw = sharedChildVertexWeightList[sc_wstart + wstart + j];

                                    // ウエイト0はありえない
                                    var mpos = virtualPosList[m_vstart + vw.parentIndex];
                                    var mrot = virtualRotList[m_vstart + vw.parentIndex];

                                    // position
                                    pos += (mpos + math.mul(mrot, vw.localPos)) * vw.weight;

                                    // normal
                                    nor += math.mul(mrot, vw.localNor) * vw.weight;
                                }

                                // レンダラーのローカル座標系に変換する
                                pos = math.mul(itrot, (pos - tpos)) / tscl;
                                nor = math.mul(itrot, nor);

                                sum_pos += pos;
                                sum_nor += nor;
                            }
                            else
                            {
                                for (int j = 0; j < wcnt; j++)
                                {
                                    var vw = sharedChildVertexWeightList[sc_wstart + wstart + j];

                                    // ウエイト0はありえない
                                    var mpos = virtualPosList[m_vstart + vw.parentIndex];
                                    var mrot = virtualRotList[m_vstart + vw.parentIndex];

                                    // position
                                    pos += (mpos + math.mul(mrot, vw.localPos)) * vw.weight;
                                }

                                // レンダラーのローカル座標系に変換する
                                pos = math.mul(itrot, (pos - tpos)) / tscl;

                                sum_pos += pos;
                            }
                            cnt++;
                        }
                        bit = bit << 1;
                    }
                    if (cnt > 0)
                    {
                        if (calcTangent)
                        {
                            renderPosList[vindex]     = sum_pos / cnt;
                            renderNormalList[vindex]  = sum_nor / cnt;
                            sum_tan4.xyz              = sum_tan / cnt;
                            renderTangentList[vindex] = sum_tan4;
                        }
                        else if (calcNormal)
                        {
                            renderPosList[vindex]    = sum_pos / cnt;
                            renderNormalList[vindex] = sum_nor / cnt;
                        }
                        else
                        {
                            renderPosList[vindex] = sum_pos / cnt;
                        }
                    }
                }
            }