|
|
@ -62,127 +62,3 @@ void Camera::mouseMoved(const glm::vec2 &delta) { |
|
|
|
float margin = 0.01; |
|
|
|
float margin = 0.01; |
|
|
|
theta = glm::clamp(theta, -glm::half_pi<float>() + margin, glm::half_pi<float>() - margin); |
|
|
|
theta = glm::clamp(theta, -glm::half_pi<float>() + margin, glm::half_pi<float>() - margin); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
* Vector3d Camera::toNDC(const Vector3d &pWorld) const { |
|
|
|
|
|
|
|
Matrix4d VP = getProjection() * getView(); |
|
|
|
|
|
|
|
return (VP * pWorld.homogeneous()).hnormalized(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Vector3d Camera::toWorld(const Vector3d &ndcCube) const { |
|
|
|
|
|
|
|
Matrix4d VPinv = (getProjection() * getView()).inverse(); |
|
|
|
|
|
|
|
return (VPinv * ndcCube.homogeneous()).hnormalized(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Ray Camera::rayForward(const Vector2d &screen) const { |
|
|
|
|
|
|
|
Vector2d ndc = {(screen.x() / viewport.width() * 2) - 1, (2 - (screen.y() / viewport.height()) * 2) - 1}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Vector3d a, b; |
|
|
|
|
|
|
|
a.head(2) = b.head(2) = ndc; |
|
|
|
|
|
|
|
a(2) = -1; // near
|
|
|
|
|
|
|
|
b(2) = 1; // far
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Vector3d p1 = toWorld(a); |
|
|
|
|
|
|
|
Vector3d p2 = toWorld(b); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return {p1, (p2 - p1).normalized()}; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Vector3d Camera::movePoint(const Vector3d &p, const Vector2d& pixelDelta) const { |
|
|
|
|
|
|
|
Vector3d ndcDelta = {(pixelDelta.x() / viewport.width() * 2), -(pixelDelta.y() / viewport.height()) * 2, 0}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Vector3d ndc = toNDC(p); |
|
|
|
|
|
|
|
Vector3d ndc2 = ndc + ndcDelta; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Vector3d p2 = toWorld(ndc2); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return p2 - p; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
* bool SoftBody::testRay(const Ray &ray, RayHit& rayHit) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GLfloat* gpuData; |
|
|
|
|
|
|
|
#if USE_GPU |
|
|
|
|
|
|
|
glBindBuffer(GL_SHADER_STORAGE_BUFFER, VBO); |
|
|
|
|
|
|
|
gpuData = static_cast<GLfloat*>(glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_ONLY)); |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::vector<RayHit> validResults; |
|
|
|
|
|
|
|
for (size_t triangleId = 0; triangleId < outerFaces.size(); triangleId++){ |
|
|
|
|
|
|
|
Face f = outerFaces[triangleId]; |
|
|
|
|
|
|
|
Vector3d a = vertices[f.a].p; |
|
|
|
|
|
|
|
Vector3d b = vertices[f.b].p; |
|
|
|
|
|
|
|
Vector3d c = vertices[f.c].p; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if USE_GPU |
|
|
|
|
|
|
|
a = Vector3f( |
|
|
|
|
|
|
|
gpuData[f.a * GL_VERTEX_SIZE + 0], |
|
|
|
|
|
|
|
gpuData[f.a * GL_VERTEX_SIZE + 1], |
|
|
|
|
|
|
|
gpuData[f.a * GL_VERTEX_SIZE + 2]).cast<double>(); |
|
|
|
|
|
|
|
b = Vector3f( |
|
|
|
|
|
|
|
gpuData[f.b * GL_VERTEX_SIZE + 0], |
|
|
|
|
|
|
|
gpuData[f.b * GL_VERTEX_SIZE + 1], |
|
|
|
|
|
|
|
gpuData[f.b * GL_VERTEX_SIZE + 2]).cast<double>(); |
|
|
|
|
|
|
|
c = Vector3f( |
|
|
|
|
|
|
|
gpuData[f.c * GL_VERTEX_SIZE + 0], |
|
|
|
|
|
|
|
gpuData[f.c * GL_VERTEX_SIZE + 1], |
|
|
|
|
|
|
|
gpuData[f.c * GL_VERTEX_SIZE + 2]).cast<double>(); |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Vector3d ab = b - a; |
|
|
|
|
|
|
|
Vector3d ac = c - a; |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* Line G: x = rayOrigin + r * rayDirection |
|
|
|
|
|
|
|
* Plane A: (x - a) * n = 0 |
|
|
|
|
|
|
|
* Intersection point q between G and A |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* 0 = (x - a) * n = (o + r * d - a) * n = o * n + r * d * n - a * n |
|
|
|
|
|
|
|
* <=> 0 = o * n + r * d * n - a * n |
|
|
|
|
|
|
|
* <=> r * d * n = a * n - o * n = (a - o) * n |
|
|
|
|
|
|
|
* <=> r = ((a - o) * n) / (d * n) |
|
|
|
|
|
|
|
* q = o + r * d |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* Select nearest point of triangle to q |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Vector3d n = ab.cross(ac); |
|
|
|
|
|
|
|
double r = (a - ray.origin).dot(n) / ray.direction.dot(n); |
|
|
|
|
|
|
|
Vector3d q = ray.origin + r * ray.direction; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// check if q is inside triangle
|
|
|
|
|
|
|
|
// https://math.stackexchange.com/questions/4322/check-whether-a-point-is-within-a-3d-triangle
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Vector3d qa = a - q; |
|
|
|
|
|
|
|
Vector3d qb = b - q; |
|
|
|
|
|
|
|
Vector3d qc = c - q; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
double area = ab.cross(ac).norm() / 2; |
|
|
|
|
|
|
|
double alpha = (qb).cross(qc).norm() / (2 * area); |
|
|
|
|
|
|
|
double beta = (qc).cross(qa).norm() / (2 * area); |
|
|
|
|
|
|
|
double gamma = (qa).cross(qb).norm() / (2 * area); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool isOne = std::abs(alpha + beta + gamma - 1) < 0.00001; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (alpha >= 0 && alpha <= 1 && beta >= 0 && beta <= 1 && gamma >= 0 && gamma <= 1 && isOne){ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// find vertex nearest to q
|
|
|
|
|
|
|
|
size_t vId; |
|
|
|
|
|
|
|
if (qa.norm() < qb.norm()){ |
|
|
|
|
|
|
|
if (qa.norm() < qc.norm()) |
|
|
|
|
|
|
|
vId = f.a; |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
vId = f.c; |
|
|
|
|
|
|
|
} else if (qb.norm() < qc.norm()) |
|
|
|
|
|
|
|
vId = f.b; |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
vId = f.c; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
validResults.push_back(RayHit(r, q, triangleId, vId)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|