今回はunityを利用した數學的な話をしようと思います。
視錐臺(frustum)はカメラの見える範囲のことを指します。
視錐臺とその構成
3dの世界はカメラから覗いて映像を捉えるのですが、そこでいう視錐臺は下図の濃い黃色の部分の様に一部だけ切り抜いた範囲の事を指します。
左下がカメラになっていて、そこから視界が広がるイメージです。
そして最終的には臺形が立體になったもの(「四角錐臺」と呼びます)の形になりますが、特徴的なのがカメラから見て手前と奧が切れているところです。
手前側が「camera.nearclipplane」になり、奧側が「camera.farclipplane」となります。
その際にこの「面」の概念が必要になってきますが、unityではそれを獲得する関數が存在します。
以下になります。
public static plane geometryutility.calculatefrustumplanes(camera camera)
この関數に「camera」を渡すと、面に相當する「plane」の配列が返ってきます。
6面あるので6要素の配列になり、それぞれが各面に対応しています。
planeの構成
視錐臺としてplaneが6つ得られました。
このplaneは數學的な「平面」の事を指します。
平面には「向き」があり、それを表すのに「法線」、つまり平面に垂直なベクトルの概念が必要になってきます。
今回はまず、平面自體に著目します。
平面関連の計算として、點と平面の距離を算出できます。
(unityではplane.getdistancetopoint()で獲得できます。)
點から平面への最短距離(垂線)を測れますが、ここでポイントなのは、點が法線側がそうでないかで、得られる値もプラスもしくはマイナスが変わってきます。
基本的に法線側がプラス、そうでない方がマイナスで、unityのは少なくともそうなっています。
unityでの活用
視錐臺の內外判定については、unityではそれを補助するための関數が用意されています。
public static bool geometryutility.testplanesaabb(plane planes, bounds bounds);
引數に平面(plane)の配列と、バウンディングボックス(bounds)を求められます。
點ではなく立體で判定する形式で、非常に便利です。
肝心のplaneの配列ですが、geometryutility.calculatefrustumplanes()の結果をそのまま使うようなニュアンスが強いです。
しかし例えばゲーム的に「視界の中に入っているか?」という判定を行いたい時、near,far面は必ずしも必要とはいえず、むしろ取っ払ってしまった方が自然ですし、平面も4つで済むことが想像できます。
幸いnear,far面はplaneの配列の最後の2つなので、下のようにリサイズして4つにすると良いでしょう。
// 視錐臺平面を獲得
plane planes = geometryutility.calculatefrustumplanes( camera );
system.array.resize( ref planes, 4 ); // near,far面を排除
// 內外判定
if ( geometryutility.testplanesaabb( planes, bounds ) )
これで內外判定が効率よく行えました。 歡迎使用CSDN markdow
本markdown編輯器使用stackedit修改而來,用它寫部落格,將會帶來全新的體驗哦 markdown 是一種輕量級標記語言,它允許人們使用易讀易寫的純文字格式編寫文件,然後轉換成格式豐富的html頁面。維基百科 使用簡單的符號標識不同的標題,將某些文字標記為粗體或者斜體,建立乙個鏈結等,詳細...
歡迎毛毛與妞妞使用CSDN markdown編輯器
建立乙個自定義列表 如何建立乙個註腳 注釋也是必不可少的 katex數學公式 新的甘特圖功能,豐富你的文章 uml 圖表 flowchart流程圖 匯出與匯入 你好!這是你第一次使用markdown編輯器所展示的歡迎頁。如果你想學習如何使用markdown編輯器,可以仔細閱讀這篇文章,了解一下mar...
歡迎使用CSDN markdow1n編輯器
本markdown編輯器使用stackedit修改而來,用它寫部落格,將會帶來全新的體驗哦 markdown 是一種輕量級標記語言,它允許人們使用易讀易寫的純文字格式編寫文件,然後轉換成格式豐富的html頁面。維基百科 使用簡單的符號標識不同的標題,將某些文字標記為粗體或者斜體,建立乙個鏈結等,詳細...