/// <summary> /// 平面衝突判定 /// </summary> /// <param name="nextpos"></param> /// <param name="radius"></param> /// <param name="cindex"></param> float PlaneColliderDetection(ref float3 nextpos, float radius, int cindex) { // 平面姿勢 var cpos = nextPosList[cindex]; var crot = nextRotList[cindex]; // 平面法線 float3 n = math.mul(crot, math.up()); // パーティクル半径分オフセット cpos += n * radius; // c = 平面位置 // n = 平面方向 // 平面衝突判定と押し出し // 平面との距離を返す(押し出しの場合は0.0) return(MathUtility.IntersectPointPlaneDist(cpos, n, nextpos, out nextpos)); }
//===================================================================================== /// <summary> /// 球衝突判定 /// </summary> /// <param name="nextpos"></param> /// <param name="pos"></param> /// <param name="radius"></param> /// <param name="cindex"></param> /// <param name="friction"></param> /// <returns></returns> float SphereColliderDetection(ref float3 nextpos, float3 basepos, float radius, int cindex) { var cpos = nextPosList[cindex]; var cradius = radiusList[cindex]; // スケール var tindex = transformIndexList[cindex]; var cscl = boneSclList[tindex]; cradius *= math.abs(cscl.x); // X軸のみを見る // 移動前のコライダーに対するローカル位置から移動後コライダーの押し出し平面を求める float3 c = 0, n = 0, v = 0; //if (keep) //{ // // 形状キープ // // 物理OFFの基本状態から拘束を決定 // var cbasepos = basePosList[cindex]; // v = basepos - cbasepos; // var iq = math.inverse(baseRotList[cindex]); // var lv = math.mul(iq, v); // v = math.mul(nextRotList[cindex], lv); //} //else { var coldpos = posList[cindex]; v = nextpos - coldpos; } n = math.normalize(v); c = cpos + n * (cradius.x + radius); // c = 平面位置 // n = 平面方向 // 平面衝突判定と押し出し return(MathUtility.IntersectPointPlaneDist(c, n, nextpos, out nextpos)); }
/// <summary> /// カプセル衝突判定 /// </summary> /// <param name="nextpos"></param> /// <param name="pos"></param> /// <param name="radius"></param> /// <param name="cindex"></param> /// <param name="dir"></param> /// <param name="friction"></param> /// <returns></returns> float CapsuleColliderDetection(ref float3 nextpos, float3 basepos, float radius, int cindex, float3 dir) { var cpos = nextPosList[cindex]; var crot = nextRotList[cindex]; // x = 長さ(片側) // y = 始点半径 // z = 終点半径 //var lpos = localPosList[cindex]; var cradius = radiusList[cindex]; // スケール var tindex = transformIndexList[cindex]; var cscl = boneSclList[tindex]; float scl = math.dot(math.abs(cscl), dir); // dirの軸のスケールを使用する cradius *= scl; float3 c = 0, n = 0; //if (keep) //{ // // 形状キープ // // 物理OFFの基本状態から拘束を決定 // var cbasepos = basePosList[cindex]; // var cbaserot = baseRotList[cindex]; // // カプセル始点と終点 // float3 l = math.mul(cbaserot, dir * cradius.x); // float3 spos = cbasepos - l; // float3 epos = cbasepos + l; // float sr = cradius.y; // float er = cradius.z; // // 移動前のコライダー位置から押し出し平面を割り出す // float t = MathUtility.ClosestPtPointSegmentRatio(basepos, spos, epos); // float r = math.lerp(sr, er, t); // float3 d = math.lerp(spos, epos, t); // float3 v = basepos - d; // // 移動前コライダーのローカルベクトル // var iq = math.inverse(cbaserot); // float3 lv = math.mul(iq, v); // // 移動後コライダーに変換 // l = math.mul(crot, dir * cradius.x); // spos = cpos - l; // epos = cpos + l; // d = math.lerp(spos, epos, t); // v = math.mul(crot, lv); // n = math.normalize(v); // c = d + n * (r + radius); //} //else { var coldpos = posList[cindex]; var coldrot = rotList[cindex]; // カプセル始点と終点 float3 l = math.mul(coldrot, dir * cradius.x); float3 spos = coldpos - l; float3 epos = coldpos + l; float sr = cradius.y; float er = cradius.z; // 移動前のコライダー位置から押し出し平面を割り出す float t = MathUtility.ClosestPtPointSegmentRatio(nextpos, spos, epos); float r = math.lerp(sr, er, t); float3 d = math.lerp(spos, epos, t); float3 v = nextpos - d; // 移動前コライダーのローカルベクトル var iq = math.inverse(coldrot); float3 lv = math.mul(iq, v); // 移動後コライダーに変換 l = math.mul(crot, dir * cradius.x); spos = cpos - l; epos = cpos + l; d = math.lerp(spos, epos, t); v = math.mul(crot, lv); n = math.normalize(v); c = d + n * (r + radius); } // c = 平面位置 // n = 平面方向 // 平面衝突判定と押し出し return(MathUtility.IntersectPointPlaneDist(c, n, nextpos, out nextpos)); }