/** CSci-4611 Assignment 6: Harold */ #include "billboards.h" Billboards::Billboards() { } Billboards::~Billboards() { } void Billboards::Init(ShaderProgram *stroke3d_shaderprog) { stroke3d_shaderprog_ = stroke3d_shaderprog; } /// Projects a 2D normalized screen point (e.g., the mouse position in normalized /// device coordinates) to a 3D point on a plane defined by an "origin", which can /// really be any point coincident with the plane, and the plane normal. Returns /// true if the screen point projects onto the plane and stores the result in /// plane_point. Returns false if the screen point does not project onto the plane. bool Billboards::ScreenPtHitsPlane(const Matrix4 &view_matrix, const Matrix4 &proj_matrix, const Point3 &plane_origin, const Vector3 &plane_normal, const Point2 &normalized_screen_pt, Point3 *plane_point) { Matrix4 camera_matrix = view_matrix.Inverse(); Point3 eye = camera_matrix.ColumnToPoint3(3); Point3 pt3d = GfxMath::ScreenToNearPlane(view_matrix, proj_matrix, normalized_screen_pt); Ray ray(eye, (pt3d - eye).ToUnit()); float t; return ray.IntersectPlane(plane_origin, plane_normal, &t, plane_point); } /// Checks to see if a ray starting at the eye point and passing through 2D /// normalized screen point projects onto any of the billboards in the scene. If /// so, returns the id of the closest billboard intersected. If not, returns -1. int Billboards::IntersectBillboard(const Matrix4 &view_matrix, const Matrix4 &proj_matrix, const Point2 &normalized_screen_pt) { Matrix4 camera_matrix = view_matrix.Inverse(); Point3 eye = camera_matrix.ColumnToPoint3(3); int id = -1; float best_i_time = -1.0; Point3 pt3d = GfxMath::ScreenToNearPlane(view_matrix, proj_matrix, normalized_screen_pt); Ray ray(eye, (pt3d - eye).ToUnit()); Point3 i_point; float i_time; int i_tri_id; for (int i=0; i &stroke2d, const Mesh &stroke2d_mesh, const Color &stroke_color, Ground *ground_ptr) { Matrix4 camera_matrix = view_matrix.Inverse(); Point3 eye = camera_matrix.ColumnToPoint3(3); // Create a new billboard Billboard b; b.color = stroke_color; b.transform = Matrix4(); b.mesh = stroke2d_mesh; // find the base point for the billboard ground_ptr->ScreenPtHitsGround(view_matrix, proj_matrix, stroke2d[0], &b.anchor_pt); Vector3 norm = (eye - b.anchor_pt); norm[1] = 0.0; // with 0 change in Y so the billboard does not tilt norm.Normalize(); // convert to a unit vector // project the stroke into 3D to lie on the projection plane std::vector verts; for (int i=0; i verts; for (int i=0; iUseProgram(); stroke3d_shaderprog_->SetUniform("projectionMatrix", proj_matrix); for (int i=0; iSetUniform("modelViewMatrix", modelview_matrix); stroke3d_shaderprog_->SetUniform("strokeColor", billboards_[i].color); billboards_[i].mesh.Draw(); } stroke3d_shaderprog_->StopProgram(); }