From 3e757dbc71682972899a48651710c5d8280c3cee Mon Sep 17 00:00:00 2001 From: Kiet Tran Date: Mon, 29 Nov 2021 13:36:54 -0600 Subject: Publish A6 --- dev/a6-harold/billboards.cc | 206 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 206 insertions(+) create mode 100644 dev/a6-harold/billboards.cc (limited to 'dev/a6-harold/billboards.cc') diff --git a/dev/a6-harold/billboards.cc b/dev/a6-harold/billboards.cc new file mode 100644 index 0000000..5ec508a --- /dev/null +++ b/dev/a6-harold/billboards.cc @@ -0,0 +1,206 @@ +/** 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(); +} + -- cgit v1.2.3