3Dメッシュの衝突判定
ざわーくらうと  2017/12/22(Fri) 18:41
OBJファイルを読み込んだ3Dメッシュ(Mesh,或いはModel)と,画面上の任意の点からの直線(Ray)との衝突判定,および衝突位置の計算をしたいと考えています.
恐らく,画面上の点で奥行方法を向くRayを定義し,MeshDataとして読み込んだメッシュの三角形を次々に読み込んで Ray::intersectsAt(const Triangle3D& triangle) を呼び出せばできるような気がしているのですが,Rayのうまい定義方法が思いつきません.

Siv3Dの仕様内で任意メッシュとの衝突判定は計算できますか?
記事編集
Reputeless  2017/12/22(Fri) 20:47
Graphics3D::ToRay(Vec2) で、画面上の任意の座標からの Ray を作成できます。

また、ModelLoader::LoadMeshDataFromOBJ() で Array<MeshData> を取得できます。
MeshData::computeBoundingBox() でバウンディングボックスが計算できるので、計算量の削減に役立つと思います。

Ray vs Mesh の衝突判定は OpenSiv3D 以降で実装予定です。
編集
ざわーくらうと  2017/12/25(Mon) 18:24
Reputelessさん,ありがとうございます.
処理時間はともかくやりたい処理は実現できましたので,該当部分のソースコードを載せておきます.

注意点として,Rayは常にウィンドウ全体を描画ウィンドウとして計算するので,Viewport内座標の点からRayを飛ばす(描画する)場合は適当なスケーリングが必要でした.


// 特徴点の3次元化
for (auto l : landmarks) {
// Rayを作成
Graphics3D::SetViewportForward(viewarea_free);
auto s = Window::Size();
Vec2 v = Vec2((l.x - viewarea_free.w / 2) / viewarea_free.h*s.y + s.x / 2,
(l.y - viewarea_free.h / 2) / viewarea_free.h*s.y + s.y / 2);
auto ray = Graphics3D::ToRay(v);

//// Rayと3Dモデルの衝突判定
MeshData md = facemesh[0];
if (ray.intersects(md.computeBoundingBox())) {
for (int i = 2; i < md.indices.size(); i++) {
auto v1 = md.vertices[md.indices[i - 2]].position;
auto v2 = md.vertices[md.indices[i - 1]].position;
auto v3 = md.vertices[md.indices[i - 0]].position;
if (ray.intersects(Triangle3D(v1, v2, v3))) {
auto p = ray.intersectsAt(Triangle3D(v1, v2, v3));
landmarks3d.push_back(p.value());
break;
}
}
}
}

// rayの描画
for (auto l : landmarks) {
// Rayを作成
Graphics3D::SetViewportForward(viewarea_free);
auto s = Window::Size();
Vec2 v = Vec2((l.x- viewarea_front.w/2)/ viewarea_front.h*s.y + s.x/2,
(l.y- viewarea_front.h/2)/ viewarea_front.h*s.y + s.y/2);
//v.draw(Palette::Red);
auto ray = Graphics3D::ToRay(v);

Line3D(Mat4x4::Rotate(rot).transform(ray.origin),
Mat4x4::Rotate(rot).transform(cam_front.farClip*ray.direction)).drawForward();
}

// 三次元特徴点の描画
Graphics3D::SetViewportForward(viewarea_free);
for (auto l : landmarks3d) {
Sphere(l, 2).asMesh().rotated(rot).drawForward();
}
編集
件名
Re: 3Dメッシュの衝突判定
名前
コメント
画像添付


投稿修正キー (投稿を修正する時に使います)
画像認証 (右画像の数字を入力) 投稿キー

- WEB PATIO -