/** CSci-4611 Assignment 3: Earthquake */ #include "earth.h" #include "config.h" #include // for M_PI constant #define _USE_MATH_DEFINES #include Earth::Earth() { } Earth::~Earth() { } float lerp(float x, float y, float a) { return x + a * (y - x); } void Earth::Init(const std::vector &search_path) { // init shader program shader_.Init(); // init texture: you can change to a lower-res texture here if needed earth_tex_.InitFromFile(Platform::FindFile("earth-2k.png", search_path)); // init geometry std::vector tex; // TODO: This is where you need to set the vertices and indiceds for earth_mesh_. for (int i = 0; i < nslices + 1; i++) { for (int j = 0; j < nstacks + 1; j++) { Point3 sphere_point = Point3(LatLongToSphere(lerp(-M_PI / 2, M_PI / 2, j * 1.0 / nstacks), lerp(-M_PI, M_PI, i * 1.0 / nslices))); Point3 plane_point = Point3(lerp(-M_PI, M_PI, i * 1.0 / nslices), lerp(-M_PI / 2, M_PI / 2, j * 1.0 / nstacks), 0); vertices_.push_back(plane_point); sphVertices_.push_back(sphere_point); normals_.push_back(Vector3(0,0,1)); sphNormals_.push_back(sphere_point - Point3(0,0,0)); tex_.push_back(Point2(i * 1.0 / nslices, 1 - j * 1.0 / nstacks)); } } //Lower triangles for (int i = 0; i < nslices; i++) { for (int j = 0; j < nstacks; j++) { indices_.push_back(0 + j + (nstacks + 1) * i); indices_.push_back(nstacks + 1 + j + (nstacks + 1) * i); indices_.push_back(1 + j + (nstacks + 1) * i); } } //Upper triangles for (int i = 0; i < nslices; i++) { for (int j = 0; j < nstacks; j++) { indices_.push_back(1 + j + (nstacks + 1) * i); indices_.push_back(nstacks + 1 + j + (nstacks + 1) * i); indices_.push_back(nstacks + 2 + j + (nstacks + 1) * i); } } earth_mesh_.SetVertices(vertices_); earth_mesh_.SetIndices(indices_); earth_mesh_.SetTexCoords(0, tex_); earth_mesh_.SetNormals(normals_); } void Earth::set_globe_mode(bool globe_mode) { if (globe_mode) { earth_mesh_.SetVertices(sphVertices_); earth_mesh_.SetIndices(indices_); earth_mesh_.SetTexCoords(0, tex_); earth_mesh_.SetNormals(sphNormals_); } else { earth_mesh_.SetVertices(vertices_); earth_mesh_.SetIndices(indices_); earth_mesh_.SetTexCoords(0, tex_); earth_mesh_.SetNormals(normals_); } earth_mesh_.UpdateGPUMemory(); } void Earth::Draw(const Matrix4 &model_matrix, const Matrix4 &view_matrix, const Matrix4 &proj_matrix) { // Define a really bright white light. Lighting is a property of the "shader" DefaultShader::LightProperties light; light.position = Point3(10,10,10); light.ambient_intensity = Color(1,1,1); light.diffuse_intensity = Color(1,1,1); light.specular_intensity = Color(1,1,1); shader_.SetLight(0, light); // Adust the material properties, material is a property of the thing // (e.g., a mesh) that we draw with the shader. The reflectance properties // affect the lighting. The surface texture is the key for getting the // image of the earth to show up. DefaultShader::MaterialProperties mat; mat.ambient_reflectance = Color(0.5, 0.5, 0.5); mat.diffuse_reflectance = Color(0.75, 0.75, 0.75); mat.specular_reflectance = Color(0.75, 0.75, 0.75); mat.surface_texture = earth_tex_; // Draw the earth mesh using these settings if (earth_mesh_.num_triangles() > 0) { shader_.Draw(model_matrix, view_matrix, proj_matrix, &earth_mesh_, mat); } } Point3 Earth::LatLongToSphere(double latitude, double longitude) const { // TODO: We recommend filling in this function to put all your // lat,long --> sphere calculations in one place. float x = cos(latitude) * sin(longitude); float y = sin(latitude); float z = cos(latitude) * cos(longitude); return Point3(x, y, z); } Point3 Earth::LatLongToPlane(double latitude, double longitude) const { // TODO: We recommend filling in this function to put all your // lat,long --> plane calculations in one place. // return Point3(latitude,longitude,0); return Point3(GfxMath::ToRadians(longitude), GfxMath::ToRadians(latitude), 0); } void Earth::DrawDebugInfo(const Matrix4 &model_matrix, const Matrix4 &view_matrix, const Matrix4 &proj_matrix) { // This draws a cylinder for each line segment on each edge of each triangle in your mesh. // So it will be very slow if you have a large mesh, but it's quite useful when you are // debugging your mesh code, especially if you start with a small mesh. for (int t=0; t indices_ = earth_mesh_.read_triangle_indices_data(t); std::vector loop; loop.push_back(earth_mesh_.read_vertex_data(indices_[0])); loop.push_back(earth_mesh_.read_vertex_data(indices_[1])); loop.push_back(earth_mesh_.read_vertex_data(indices_[2])); quick_shapes_.DrawLines(model_matrix, view_matrix, proj_matrix, Color(1,1,0), loop, QuickShapes::LinesType::LINE_LOOP, 0.005f); } }