読者です 読者をやめる 読者になる 読者になる

しゅみぷろ

プログラミングとか

UV算出ロジックの穴

C# Unity UnityTexturePaint

はじめに

特定のオブジェクト表面上の点(World-Space)の位置を中心に、ブラシで色を塗るためにUVを算出するロジックを作っています。

これができると何が嬉しいのかというと、UnityのOnCollision系イベントメソッドで衝突した点に対して、ペイント処理を施すことが出来るようになります(Raycastを駆使する必要がなくなります)。 OnCollision系のイベントメソッド内でなくても、特定の点さえ取ってこれればペイント処理が可能です。

f:id:es_program:20161010002354g:plain:w500

真面目にTexturePaint更新しはじめて、以前公開していたUV算出で色々とバグ的なものを見つけ始めました。 今回はロジックに穴があったので埋めましたよというお話。

UV算出については

esprog.hatenablog.com

esprog.hatenablog.com

ここを参照して下さい。

また、以前にもUV算出でバグを見つけたので、その時の記事も貼っておきます。

esprog.hatenablog.com

ロジックの穴

UV算出の手順は

  1. 点$p$が三角形が構成する平面空間に属するか調べる
  2. 点$p$が三角形内部に属するか調べる
  3. 点$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算出もかなりいい感じになってきました。