« C4D ベジエNURBSの三角形? | トップページ | C4D Python R12 テスト:ユーザデータ付きのヌルオブジェクトを生成してシーンに追加してみる。 »

C4D Python R12 テスト:utils.GeRayColliderでポリゴンとの交点が1個のはずが2個あったのは?

前回の記事の最後で、ポリゴンのポイントは交点に含まれるのか試しましたが、
その時、交点が1個のはずが、2個検出されました。

計算誤差かなぁ… なんて相変わらずアホみたいな事考えていた…

まぁ、早い話が…

今回のモデルは、こんな具合。

Geraycollider_13

ポリゴンのコーナー4つに接しています。

ヌルオブジェクトには、前回同様ユーザデータで2つのリンク。
1個目にスプライン、2個目にポリゴンを設定して、ヌルオブジェクトを選択状態で…

Geraycollider_09

スクリプトは前回のを使いまわし…
若干変更していますが…

Python
import c4d
from c4d import utils


#オブジェクトのポイントをグローバル座標へ変換
def GetGlobalPoint(obj):
    if not isinstance(obj, c4d.PointObject):return

    mg = obj.GetMg()
    pnt = obj.GetAllPoints()
    pnt_cnt = obj.GetPointCount()

    for id in xrange(pnt_cnt):
        pnt[id] = mg.__mul__(pnt[id])

    return pnt


#グローバル座標リストをオブジェクトのローカル座標へ変換
def GetLocalPoint(pnt, obj):
    if not isinstance(obj, c4d.BaseObject):return
    if type(pnt) != list:return

    mg = obj.GetMg()
    inv_mg = mg.__invert__()

    for id in xrange(len(pnt)):
        pnt[id] = inv_mg.__mul__(pnt[id])

    return pnt



def main():
    try:
        ray = op[c4d.ID_USERDATA, 1]
        if not isinstance(ray, c4d.SplineObject):return
        obj = op[c4d.ID_USERDATA, 2]
        if not isinstance(obj, c4d.PolygonObject):return
    except:return

    if ray.GetPointCount() <= 2:return #スプラインのポイントが2個以外終了
    if obj.GetPolygonCount() == 0:return #ポリゴンが1枚も無ければ終了

    #スプラインオブジェクトのポイントをローカル座標からグローバル座標へ
    pnt = GetGlobalPoint(ray)

    #グローバル座標からポリゴンオブジェクトのローカル座標へ
    pnt = GetLocalPoint(pnt, obj)

    #GeRayColliderの線分の開始位置と方向、長さを求める
    start_pos = pnt[0]
    direct = pnt[1] - pnt[0]
    length = direct.GetLength()

    #GeRayColliderの設定
    rc = utils.GeRayCollider()
    rc.Init(obj)
    rc.Intersect(start_pos, direct, length)

    #交点の数を表示
    is_cnt = rc.GetIntersectionCount()
    print is_cnt

    #交点の表示
    for id in xrange(is_cnt):
        print id, 'distance', rc.GetIntersection(id)['distance'], 'face_id', rc.GetIntersection(id)['face_id'], 'backface', rc.GetIntersection(id)['backface']

        #球体を交点に配置する
        Intersection_obj = c4d.BaseObject(c4d.Osphere)
        Intersection_obj.MakeTag(c4d.Tphong)
        Intersection_obj[c4d.PRIM_SPHERE_RAD] = obj.GetRad().GetLength() * 0.05
        Intersection_obj[c4d.ID_BASEOBJECT_USECOLOR] = c4d.ID_BASEOBJECT_USECOLOR_ALWAYS
        Intersection_obj[c4d.ID_BASEOBJECT_COLOR] = c4d.Vector(1.0, 0.0, 0.0)
        Intersection_obj.SetAbsPos(rc.GetIntersection(id)['hitpos'])
        Intersection_obj.InsertUnder(obj)


    print 'ok'



if __name__=='__main__':
    main()
    c4d.EventAdd()
6
0 distance 0.200000015259 face_id 0 backface False
1 distance 0.399999984741 face_id 1 backface False
2 distance 0.599999984741 face_id 2 backface False
3 distance 0.599999984741 face_id 2 backface False
4 distance 0.799999984741 face_id 3 backface False
5 distance 0.799999984741 face_id 3 backface False
ok

交点が6個
後半2枚のポリゴン(2番、3番)に、2個の交点が現れている…
距離も同一になっている。

Geraycollider_14

まぁ、早い話が…
utils.GeRayColliderの交点の取得方法は、ポリゴンを3角ポリゴンに分割してから算出するのだ。

今回のモデルのポリゴンのポイント順を見てみると…

Geraycollider_12

後半2枚のポイントCで交わっているポリゴンは、三角形abcと三角形cdaの2枚の三角ポリゴンと交わっている事になっているんだね。

これで、ほぼGeRayColliderを使うことができると思う。

|

« C4D ベジエNURBSの三角形? | トップページ | C4D Python R12 テスト:ユーザデータ付きのヌルオブジェクトを生成してシーンに追加してみる。 »

コメント

コメントを書く



(ウェブ上には掲載しません)




« C4D ベジエNURBSの三角形? | トップページ | C4D Python R12 テスト:ユーザデータ付きのヌルオブジェクトを生成してシーンに追加してみる。 »