UV算出ロジックの穴
はじめに
特定のオブジェクト表面上の点(World-Space)の位置を中心に、ブラシで色を塗るためにUVを算出するロジックを作っています。
これができると何が嬉しいのかというと、UnityのOnCollision系イベントメソッドで衝突した点に対して、ペイント処理を施すことが出来るようになります(Raycastを駆使する必要がなくなります)。 OnCollision系のイベントメソッド内でなくても、特定の点さえ取ってこれればペイント処理が可能です。
真面目にTexturePaint更新しはじめて、以前公開していたUV算出で色々とバグ的なものを見つけ始めました。 今回はロジックに穴があったので埋めましたよというお話。
UV算出については
ここを参照して下さい。
また、以前にもUV算出でバグを見つけたので、その時の記事も貼っておきます。
ロジックの穴
UV算出の手順は
- 点$p$が三角形が構成する平面空間に属するか調べる
- 点$p$が三角形内部に属するか調べる
- 点$p$のUV座標を面積による補間を用いて調べる
という手順でした。 実はこのままだと穴があって、2つ目の手順の「内部に属するか」というのが境界を含まないため、三角形の辺上に点$p$が存在する場合UVを返してくれません。 これでは都合が悪いので、境界についても同様に調べる必要があります。
修正
具体的には、2番目の条件に以下のコードのExistPointOnTriangleEdgeメソッドを含めます
/// <summary> /// 点pが辺(v1,v2)上に存在するかどうかを調査する /// </summary> /// <param name="p">調査点</param> /// <param name="v1">辺をなす頂点</param> /// <param name="v2">辺をなす頂点</param> /// <returns>点pが辺上に存在しているかどうか</returns> public static bool ExistPointOnEdge(Vector3 p, Vector3 v1, Vector3 v2) { return 1 - TOLERANCE < Vector3.Dot(v2 - p, v2 - v1); } /// <summary> /// 点pが与えられた3点がなす三角形の辺上に存在するかを調査する /// </summary> /// <param name="p">調査点p</param> /// <param name="t1">三角形をなす頂点</param> /// <param name="t2">三角形をなす頂点</param> /// <param name="t3">三角形をなす頂点</param> /// <returns>点pが三角形の辺城に存在するかどうか</returns> public static bool ExistPointOnTriangleEdge(Vector3 p, Vector3 t1, Vector3 t2, Vector3 t3) { if(ExistPointOnEdge(p, t1, t2) || ExistPointOnEdge(p, t2, t3) || ExistPointOnEdge(p, t3, t1)) return true; return false; }
UV算出もかなりいい感じになってきました。