3Dメッシュの衝突判定
ざわーくらうと 2017/12/22(Fri) 18:41
Reputeless 2017/12/22(Fri) 20:47
ざわーくらうと 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();
}