// パーティクルごと
            public void Execute(int index)
            {
                var flag = flagList[index];

                if (flag.IsValid() == false)
                {
                    return;
                }

                // チームデータ
                int teamId   = teamIdList[index];
                var teamData = teamDataList[teamId];

                // ここからは更新がある場合のみ実行
                if (teamData.IsUpdate() == false)
                {
                    return;
                }

                // 速度更新(m/s)
                if (flag.IsFixed() == false)
                {
                    // 移動パーティクルのみ
                    var nextPos = nextPosList[index];
                    var nextRot = nextRotList[index];
                    nextRot = math.normalize(nextRot); // 回転蓄積で精度が落ちていくので正規化しておく

                    float3 velocity = 0;

                    // posListには移動影響を考慮した最終座標が入っている
                    var pos = posList[index];

                    // 速度更新(m/s)
                    velocity  = (nextPos - pos) / updateDeltaTime;
                    velocity *= teamData.velocityWeight; // 安定化用の速度ウエイト

                    // 摩擦による速度減衰
                    float friction = frictionList[index];
                    //friction *= teamData.friction; // チームごとの摩擦係数
                    velocity *= math.pow(1.0f - math.saturate(friction), updatePower);

                    // 実際の移動速度(localPosに格納)
                    var realVelocity = (nextPos - oldPosList[index]) / updateDeltaTime;
                    var depth        = depthList[index];
                    var maxVelocity  = teamMaxVelocityList[teamId].Evaluate(depth);
                    realVelocity        = MathUtility.ClampVector(realVelocity, 0.0f, maxVelocity); // 最大速度は考慮する
                    localPosList[index] = realVelocity;

                    // 書き戻し
                    velocityList[index] = velocity;

                    oldPosList[index] = nextPos;
                    oldRotList[index] = nextRot;
                }
            }
            // ボーン
            //[Unity.Collections.ReadOnly]
            //public NativeArray<quaternion> boneRotList;

            // パーティクルごと
            public void Execute(int index)
            {
                var flag = flagList[index];

                if (flag.IsValid() == false)
                {
                    return;
                }

                // チームデータ
                int teamId   = teamIdList[index];
                var teamData = teamDataList[teamId];

                // ここからは更新がある場合のみ実行(グローバルチームは除く)
                if (teamId != 0 && teamData.IsUpdate() == false)
                {
                    return;
                }

                var        oldpos  = oldPosList[index];
                var        oldrot  = oldRotList[index];
                float3     nextPos = oldpos;
                quaternion nextRot = oldrot;

                //if (flag.IsCollider())
                //{
                //    // コライダー
                //    // todo:こっちのほうがよい?
                //    nextPos = basePosList[index];
                //    nextRot = baseRotList[index];
                //}
                if (flag.IsFixed())
                {
                    // キネマティックパーティクル
                    // nextPos/nextRotが前回の姿勢
                    var oldNextPos = nextPosList[index];
                    var oldNextRot = nextRotList[index];

                    // OldPos/Rot から BasePos/Rot に step で補間して現在姿勢とする
#if true
                    // 高フレームレートで位置がスキップされてしまう問題の対処(1.8.3)
                    float stime    = teamData.startTime + updateDeltaTime * teamData.runCount;
                    float oldtime  = teamData.oldTime;
                    float interval = teamData.time - oldtime;
                    float step     = math.saturate((stime - oldtime) / interval);
#else
                    float stime   = teamData.startTime + updateDeltaTime * teamData.runCount;
                    float oldtime = teamData.time - teamData.addTime;
                    float step    = math.saturate((stime - oldtime) / teamData.addTime);
#endif
                    nextPos = math.lerp(oldpos, basePosList[index], step);
                    nextRot = math.slerp(oldrot, baseRotList[index], step);

                    // 前回の姿勢をoldpos/rotとしてposList/rotListに格納する
                    if (flag.IsCollider() && teamId == 0)
                    {
                        // グローバルコライダー
                        // 移動量と回転量に制限をかける(1.7.5)
                        // 制限をかけないと高速移動/回転時に遠く離れたパーティクルが押し出されてしまう問題が発生する。
                        oldpos = MathUtility.ClampDistance(nextPos, oldNextPos, Define.Compute.GlobalColliderMaxMoveDistance);
                        oldrot = MathUtility.ClampAngle(nextRot, oldNextRot, math.radians(Define.Compute.GlobalColliderMaxRotationAngle));
                    }
                    else
                    {
                        oldpos = oldNextPos;
                        oldrot = oldNextRot;
                    }

                    // debug
                    //nextPos = basePosList[index];
                    //nextRot = baseRotList[index];
                }
                else
                {
                    // 動的パーティクル
                    var depth       = depthList[index];
                    var maxVelocity = teamMaxVelocityList[teamId].Evaluate(depth);
                    var drag        = teamDragList[teamId].Evaluate(depth);
                    var gravity     = teamGravityList[teamId].Evaluate(depth);
                    var mass        = teamMassList[teamId].Evaluate(depth);
                    var velocity    = velocityList[index];

                    // チームスケール倍率
                    maxVelocity *= teamData.scaleRatio;

                    // massは主に伸縮を中心に調整されるので、フォース適用時は少し調整する
                    mass = (mass - 1.0f) * teamData.forceMassInfluence + 1.0f;

                    // 安定化用の速度ウエイト
                    velocity *= teamData.velocityWeight;

                    // 最大速度
                    velocity = MathUtility.ClampVector(velocity, 0.0f, maxVelocity);

                    // 空気抵抗(90ups基準)
                    // 重力に影響させたくないので先に計算する(※通常はforce適用後に行うのが一般的)
                    velocity *= math.pow(1.0f - drag, updatePower);

                    // フォース
                    // フォースは空気抵抗を無視して加算する
                    float3 force = 0;

                    // 重力
                    // 重力は質量に関係なく一定
#if false
                    // 方向減衰
                    if (teamData.IsFlag(PhysicsManagerTeamData.Flag_DirectionalDamping) && teamData.directionalDampingBoneIndex >= 0)
                    {
                        float3 dampDir = math.mul(boneRotList[teamData.directionalDampingBoneIndex], teamData.directionalDampingLocalDir);
                        var    dot     = math.dot(dampDir, new float3(0, -1, 0)) * 0.5f + 0.5f; // 1.0(0) - 0.5(90) - 0.0(180)
                        var    damp    = teamDirectionalDampingList[teamId].Evaluate(dot);
                        gravity *= damp;
                    }
#endif

                    // (最後に質量で割るためここでは質量をかける)
                    force.y += gravity * mass;

                    // 外部フォース
                    if (loopIndex == 0)
                    {
                        switch (teamData.forceMode)
                        {
                        case PhysicsManagerTeamData.ForceMode.VelocityAdd:
                            force += teamData.impactForce;
                            break;

                        case PhysicsManagerTeamData.ForceMode.VelocityAddWithoutMass:
                            force += teamData.impactForce * mass;
                            break;

                        case PhysicsManagerTeamData.ForceMode.VelocityChange:
                            force   += teamData.impactForce;
                            velocity = 0;
                            break;

                        case PhysicsManagerTeamData.ForceMode.VelocityChangeWithoutMass:
                            force   += teamData.impactForce * mass;
                            velocity = 0;
                            break;
                        }

                        // 外力
                        force += teamData.externalForce;
                    }

                    // 外力チームスケール倍率
                    force *= teamData.scaleRatio;

                    // 速度計算(質量で割る)
                    velocity += (force / mass) * updateDeltaTime;

                    // 速度を理想位置に反映させる
                    nextPos = oldpos + velocity * updateDeltaTime;
                }

                // 予定座標更新 ==============================================================
                // 摩擦減衰
                var friction = frictionList[index];
                friction            = friction * Define.Compute.FrictionDampingRate;
                frictionList[index] = friction;
                //frictionList[index] = 0;

                // 移動前の姿勢
                posList[index] = oldpos;
                rotList[index] = oldrot;

                // 予測位置
                nextPosList[index] = nextPos;
                nextRotList[index] = nextRot;

                // コリジョン用
                //velocityList[index] = nextPos;
            }
            // パーティクルごと
            public void Execute(int index)
            {
                // 初期化コピー
                var nextpos = nextPosList[index];

                outNextPosList[index] = nextpos;

                // 頂点フラグ
                var flag = flagList[index];

                if (flag.IsValid() == false || flag.IsFixed())
                {
                    return;
                }

                // チーム
                var team = teamDataList[teamIdList[index]];

                if (team.IsActive() == false || team.clampDistanceGroupIndex < 0)
                {
                    return;
                }

                // 更新確認
                if (team.IsUpdate() == false)
                {
                    return;
                }

                int pstart = team.particleChunk.startIndex;
                int vindex = index - pstart;

                // クロスごとの拘束データ
                var gdata = groupList[team.clampDistanceGroupIndex];

                if (gdata.active == 0)
                {
                    return;
                }

                // 参照データ情報
                var refdata = refDataList[gdata.refChunk.startIndex + vindex];

                if (refdata.count > 0)
                {
                    int dataIndex          = gdata.dataChunk.startIndex + refdata.startIndex;
                    ClampDistanceData data = clampDistanceList[dataIndex];
                    if (data.IsValid() == false)
                    {
                        return;
                    }

                    // ターゲット
                    int    pindex2  = pstart + data.targetVertexIndex;
                    float3 nextpos2 = nextPosList[pindex2];

                    // 現在のベクトル
                    float3 v = nextpos - nextpos2;

                    // 本来の長さ
                    float length = math.distance(basePosList[index], basePosList[pindex2]);

                    // ベクトル長クランプ
                    //v = MathUtility.ClampVector(v, data.length * gdata.minRatio, data.length * gdata.maxRatio);
                    v = MathUtility.ClampVector(v, length * gdata.minRatio, length * gdata.maxRatio);

                    // 位置
                    var opos = nextpos;
                    nextpos = nextpos2 + v;

                    // 書き出し
                    outNextPosList[index] = nextpos;

                    // 速度影響
                    var av = (nextpos - opos) * (1.0f - gdata.velocityInfluence);
                    posList[index] = posList[index] + av;
                }
            }
Example #4
0
            // ルートラインごと
            public void Execute(int rootIndex)
            {
                // チーム
                int teamIndex = rootTeamList[rootIndex];

                if (teamIndex == 0)
                {
                    return;
                }
                var team = teamDataList[teamIndex];

                if (team.IsActive() == false || team.clampRotationGroupIndex < 0)
                {
                    return;
                }

                // 更新確認
                if (team.IsUpdate() == false)
                {
                    return;
                }

                // グループデータ
                var gdata = groupList[team.clampRotationGroupIndex];

                if (gdata.active == 0)
                {
                    return;
                }

                // データ
                var rootInfo  = rootInfoList[rootIndex];
                int dataIndex = rootInfo.startIndex + gdata.dataChunk.startIndex;
                int dataCount = rootInfo.dataLength;
                int pstart    = team.particleChunk.startIndex;

                // (1)現在の親からのベクトル長を保持する
                for (int i = 0; i < dataCount; i++)
                {
                    var data   = dataList[dataIndex + i];
                    int pindex = data.parentVertexIndex;
                    if (pindex < 0)
                    {
                        continue;
                    }

                    var index = data.vertexIndex;
                    index  += pstart;
                    pindex += pstart;

                    var npos = nextPosList[index];
                    var ppos = nextPosList[pindex];

                    // 現在ベクトル長
                    float vlen = math.distance(npos, ppos);

                    lengthBuffer[dataIndex + i] = vlen;
                }


                // (2)回転角度制限
                for (int i = 0; i < dataCount; i++)
                {
                    var data   = dataList[dataIndex + i];
                    int pindex = data.parentVertexIndex;
                    if (pindex < 0)
                    {
                        continue;
                    }

                    var index = data.vertexIndex;

                    index  += pstart;
                    pindex += pstart;

                    var flag = flagList[index];
                    if (flag.IsValid() == false)
                    {
                        continue;
                    }

                    var npos = nextPosList[index];
                    var nrot = nextRotList[index];
                    var opos = npos;

                    var ppos = nextPosList[pindex];
                    var prot = nextRotList[pindex];

                    float depth = depthList[index];
                    //float stiffness = gdata.stiffness.Evaluate(depth);


                    // 本来のローカルpos/rotを算出する
                    //var bpos = basePosList[index];
                    //var brot = baseRotList[index];
                    //var pbpos = basePosList[pindex];
                    //var pbrot = baseRotList[pindex];
                    //float3 bv = math.normalize(bpos - pbpos);
                    //var ipbrot = math.inverse(pbrot);
                    //float3 localPos = math.mul(ipbrot, bv);
                    //quaternion localRot = math.mul(ipbrot, brot);


                    // 本来の方向ベクトル
                    //float3 tv = math.mul(prot, localPos);
                    //float3 tv = math.mul(prot, data.localPos); // v1.7.0
                    float3 tv = math.mul(prot, data.localPos * team.scaleDirection); // マイナススケール対応(v1.7.6)

                    // ベクトル長
                    float vlen = math.distance(npos, ppos);   // 最新の距離(※これは伸びる場合があるが、一番安定している)
                    float blen = lengthBuffer[dataIndex + i]; // 計算前の距離
                    vlen = math.clamp(vlen, 0.0f, blen * 1.2f);

                    // 現在ベクトル
                    float3 v = math.normalize(npos - ppos);

                    // ベクトル角度クランプ
                    float maxAngle = gdata.maxAngle.Evaluate(depth);
                    maxAngle = math.radians(maxAngle);

                    float angle = math.acos(math.dot(v, tv));

                    if (flag.IsFixed() == false)
                    {
                        if (angle > maxAngle)
                        {
                            //v = MathUtility.ClampAngle(v, tv, maxAngle);
                            MathUtility.ClampAngle(v, tv, maxAngle, out v);
                        }

                        var mv = (ppos + v * vlen) - npos;

                        // 最大速度クランプ
                        mv = MathUtility.ClampVector(mv, 0.0f, maxMoveLength);

                        // debug
                        //var ln = math.length(mv);
                        //if (ln >= maxMoveLength)
                        //    Debug.Log($"mv={ln}");

                        var fpos = npos + mv;

                        // 摩擦係数から移動率を算出
                        float friction  = frictionList[index];
                        float moveratio = math.saturate(1.0f - friction * Define.Compute.FrictionMoveRatio);

                        // 摩擦係数による移動制限(衝突しているパーティクルは動きづらい)
                        npos = math.lerp(npos, fpos, moveratio);

                        nextPosList[index] = npos;

                        // 現在ベクトル更新(v1.8.0)
                        v = math.normalize(npos - ppos);

                        // 速度影響
                        var av = (npos - opos) * (1.0f - gdata.velocityInfluence);
                        posList[index] = posList[index] + av;
                    }

                    // 回転補正
                    //nrot = math.mul(prot, localRot);
                    //nrot = math.mul(prot, data.localRot); // v1.7.0
                    nrot = math.mul(prot, new quaternion(data.localRot.value * team.quaternionScale)); // マイナススケール対応(v1.7.6)
                    var q = MathUtility.FromToRotation(tv, v);
                    nrot = math.mul(q, nrot);

                    nextRotList[index] = nrot;
                }
            }
            // パーティクルごと
            public void Execute(int index)
            {
                var flag = flagList[index];

                if (flag.IsValid() == false || flag.IsFixed())
                {
                    return;
                }

                var team = teamDataList[teamIdList[index]];

                if (team.IsActive() == false)
                {
                    return;
                }
                if (team.clampPositionGroupIndex < 0)
                {
                    return;
                }
                // 更新確認
                if (team.IsUpdate() == false)
                {
                    return;
                }

                // グループデータ
                var gdata = clampPositionGroupList[team.clampPositionGroupIndex];

                if (gdata.active == 0)
                {
                    return;
                }

                var nextpos     = nextPosList[index];
                var depth       = depthList[index];
                var limitLength = gdata.limitLength.Evaluate(depth);

                // チームスケール倍率
                limitLength *= team.scaleRatio;

                // baseposからの最大移動距離制限
                var basepos = basePosList[index];
                var v       = nextpos - basepos; // nextpos

                // 摩擦係数から移動率を算出
                var   friction  = frictionList[index];
                float moveratio = math.saturate(1.0f - friction * Define.Compute.FrictionMoveRatio);


                if (gdata.IsAxisCheck())
                {
                    // 楕円体判定
                    float3 axisRatio = gdata.axisRatio;
                    // 基準軸のワールド回転
                    quaternion rot = baseRotList[index];
                    // 基準軸のローカルベクトルへ変換
                    quaternion irot = math.inverse(rot);
                    float3     lv   = math.mul(irot, v);

                    // Boxクランプ
                    float3 axisRatio1 = axisRatio * limitLength;
                    lv = math.clamp(lv, -axisRatio1, axisRatio1);

                    // 基準軸のワールドベクトルへ変換
                    // 最終的に(v)が楕円体でクランプされた移動制限ベクトルとなる
                    v = math.mul(rot, lv);
                }

                // nextposの制限
                v = MathUtility.ClampVector(v, 0.0f, limitLength);

                // 最大速度クランプ
                v = (basepos + v) - nextpos;
                // todo: ClampPosition最大距離クランプ、これはあまり良くないかも
                //if (team.IsFlag(PhysicsManagerTeamData.Flag_IgnoreClampPositionVelocity) == false)
                //    v = MathUtility.ClampVector(v, 0.0f, maxMoveLength);

                // 移動位置
                var opos = nextpos;
                var fpos = opos + v;

                // 摩擦係数による移動制限(衝突しているパーティクルは動きづらい)
                nextpos = math.lerp(opos, fpos, moveratio);

                // test
                //nextpos = fpos;

                // 書き込み
                nextPosList[index] = nextpos;

                // 速度影響
                var av = (nextpos - opos) * (1.0f - gdata.velocityInfluence);

                posList[index] = posList[index] + av;
            }
Example #6
0
            // ボーン
            //[ReadOnly]
            //public NativeArray<quaternion> boneRotList;

            // パーティクルごと
            public void Execute(int index)
            {
                var flag = flagList[index];

                if (flag.IsValid() == false)
                {
                    return;
                }

                // チームデータ
                int teamId   = teamIdList[index];
                var teamData = teamDataList[teamId];

                // ここからは更新がある場合のみ実行(グローバルチームは除く)
                if (teamId != 0 && teamData.IsUpdate() == false)
                {
                    return;
                }

                var        oldpos  = oldPosList[index];
                var        oldrot  = oldRotList[index];
                float3     nextPos = oldpos;
                quaternion nextRot = oldrot;

                if (flag.IsFixed())
                {
                    // キネマティックパーティクル
                    // OldPos/Rot から BasePos/Rot に step で補間して現在姿勢とする
                    float stime   = teamData.startTime + updateDeltaTime * teamData.runCount;
                    float oldtime = teamData.time - teamData.addTime;
                    float step    = math.saturate((stime - oldtime) / teamData.addTime);
                    nextPos = math.lerp(oldPosList[index], basePosList[index], step);
                    nextRot = math.slerp(oldRotList[index], baseRotList[index], step);
                }
                else
                {
                    // 動的パーティクル
                    var depth       = depthList[index];
                    var maxVelocity = teamMaxVelocityList[teamId].Evaluate(depth);
                    var drag        = teamDragList[teamId].Evaluate(depth);
                    var gravity     = teamGravityList[teamId].Evaluate(depth);
                    var mass        = teamMassList[teamId].Evaluate(depth);
                    var velocity    = velocityList[index];

                    // massは主に伸縮を中心に調整されるので、フォース適用時は少し調整する
                    mass = (mass - 1.0f) * teamData.forceMassInfluence + 1.0f;

                    // 最大速度
                    velocity = MathUtility.ClampVector(velocity, 0.0f, maxVelocity);

                    // 空気抵抗(90ups基準)
                    // 重力に影響させたくないので先に計算する(※通常はforce適用後に行うのが一般的)
                    velocity *= math.pow(1.0f - drag, updatePower);

                    // フォース
                    // フォースは空気抵抗を無視して加算する
                    float3 force = 0;

                    // 重力
                    // 重力は質量に関係なく一定
#if false
                    // 方向減衰
                    if (teamData.IsFlag(PhysicsManagerTeamData.Flag_DirectionalDamping) && teamData.directionalDampingBoneIndex >= 0)
                    {
                        float3 dampDir = math.mul(boneRotList[teamData.directionalDampingBoneIndex], teamData.directionalDampingLocalDir);
                        var    dot     = math.dot(dampDir, new float3(0, -1, 0)) * 0.5f + 0.5f; // 1.0(0) - 0.5(90) - 0.0(180)
                        var    damp    = teamDirectionalDampingList[teamId].Evaluate(dot);
                        gravity *= damp;
                    }
#endif

                    // (最後に質量で割るためここでは質量をかける)
                    force.y += gravity * mass;

                    // 外部フォース
                    if (loopIndex == 0)
                    {
                        switch (teamData.forceMode)
                        {
                        case PhysicsManagerTeamData.ForceMode.VelocityAdd:
                            force += teamData.impactForce;
                            break;

                        case PhysicsManagerTeamData.ForceMode.VelocityAddWithoutMass:
                            force += teamData.impactForce * mass;
                            break;

                        case PhysicsManagerTeamData.ForceMode.VelocityChange:
                            force   += teamData.impactForce;
                            velocity = 0;
                            break;

                        case PhysicsManagerTeamData.ForceMode.VelocityChangeWithoutMass:
                            force   += teamData.impactForce * mass;
                            velocity = 0;
                            break;
                        }

                        // 外力
                        force += teamData.externalForce;
                    }

                    // 速度計算(質量で割る)
                    velocity += (force / mass) * updateDeltaTime;

                    // 速度を理想位置に反映させる
                    nextPos = oldpos + velocity * updateDeltaTime;
                }

                // 予定座標更新 ==============================================================
                // 摩擦減衰
                var friction = frictionList[index];
                friction            = friction * Define.Compute.FrictionDampingRate;
                frictionList[index] = friction;

                // 移動前の姿勢
                posList[index] = oldpos;
                rotList[index] = oldrot;

                // 予測位置
                nextPosList[index] = nextPos;
                nextRotList[index] = nextRot;
            }
            // ルートラインごと
            public void Execute(int rootIndex)
            {
                // チーム
                int teamIndex = rootTeamList[rootIndex];

                if (teamIndex == 0)
                {
                    return;
                }
                var team = teamDataList[teamIndex];

                if (team.IsActive() == false || team.clampDistance2GroupIndex < 0)
                {
                    return;
                }

                // 更新確認
                if (team.IsUpdate() == false)
                {
                    return;
                }

                // グループデータ
                var gdata = groupList[team.clampDistance2GroupIndex];

                if (gdata.active == 0)
                {
                    return;
                }

                // データ
                var rootInfo  = rootInfoList[rootIndex];
                int dataIndex = rootInfo.startIndex + gdata.dataChunk.startIndex;
                int dataCount = rootInfo.dataLength;
                int pstart    = team.particleChunk.startIndex;

                for (int i = 0; i < dataCount; i++)
                {
                    var data   = dataList[dataIndex + i];
                    int pindex = data.parentVertexIndex;
                    if (pindex < 0)
                    {
                        continue;
                    }

                    var index = data.vertexIndex;

                    index  += pstart;
                    pindex += pstart;

                    var flag = flagList[index];
                    if (flag.IsValid() == false || flag.IsFixed())
                    {
                        continue;
                    }

                    var npos = nextPosList[index];
                    var opos = npos;

                    var ppos = nextPosList[pindex];

                    // 現在のベクトル
                    var v = npos - ppos;

                    // 長さクランプ
                    var len = data.length * team.scaleRatio;
                    v = MathUtility.ClampVector(v, len * gdata.minRatio, len * gdata.maxRatio);

                    npos = ppos + v;

                    // 格納
                    nextPosList[index] = npos;

                    // 速度影響
                    var av = (npos - opos) * (1.0f - gdata.velocityInfluence);
                    posList[index] = posList[index] + av;
                }
            }
Example #8
0
            // パーティクルごと
            public void Execute(int index)
            {
                // 初期化コピー
                var nextpos = nextPosList[index];

                outNextPosList[index] = nextpos;

                // 頂点フラグ
                var flag = flagList[index];

                if (flag.IsValid() == false || flag.IsFixed())
                {
                    return;
                }

                // チーム
                var team = teamDataList[teamIdList[index]];

                if (team.IsActive() == false || team.clampDistanceGroupIndex < 0)
                {
                    return;
                }

                // 更新確認
                if (team.IsUpdate() == false)
                {
                    return;
                }

                int pstart = team.particleChunk.startIndex;
                int vindex = index - pstart;

                // クロスごとの拘束データ
                var gdata = groupList[team.clampDistanceGroupIndex];

                if (gdata.active == 0)
                {
                    return;
                }

                // 参照データ情報
                var refdata = refDataList[gdata.refChunk.startIndex + vindex];

                if (refdata.count > 0)
                {
                    int dataIndex          = gdata.dataChunk.startIndex + refdata.startIndex;
                    ClampDistanceData data = clampDistanceList[dataIndex];
                    if (data.IsValid() == false)
                    {
                        return;
                    }

                    // ターゲット
                    int    pindex2  = pstart + data.targetVertexIndex;
                    float3 nextpos2 = nextPosList[pindex2];

                    // 現在のベクトル
                    float3 v = nextpos - nextpos2;

                    // 復元長さ
                    float length = data.length; // v1.7.0
                    length *= team.scaleRatio;  // チームスケール倍率
                    //if (length == 0.0f)
                    //{
                    //    // 従来データ(basePosの長さから)
                    //    length = math.distance(basePosList[index], basePosList[pindex2]);
                    //}

                    // ベクトル長クランプ
                    v = MathUtility.ClampVector(v, length * gdata.minRatio, length * gdata.maxRatio);

                    // 位置
                    var opos = nextpos;
                    nextpos = nextpos2 + v;

                    // 摩擦係数から移動率を算出
                    float friction  = frictionList[index];
                    float moveratio = math.saturate(1.0f - friction * Define.Compute.FrictionMoveRatio);
                    nextpos = math.lerp(opos, nextpos, moveratio);

                    // 書き出し
                    outNextPosList[index] = nextpos;

                    // 速度影響
                    var av = (nextpos - opos) * (1.0f - gdata.velocityInfluence);
                    posList[index] = posList[index] + av;
                }
            }