summaryrefslogtreecommitdiffstats
path: root/dev/a3-earthquake/earth.cc
blob: e2c87da0b73e4baa2d71b97c8991e4a2bddef81e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/** CSci-4611 Assignment 3:  Earthquake
 */

#include "earth.h"
#include "config.h"

#include <vector>

// for M_PI constant
#define _USE_MATH_DEFINES
#include <math.h>


Earth::Earth() {
}

Earth::~Earth() {
}

float lerp(float x, float y, float a) {
    return x + a * (y - x);
}

void Earth::Init(const std::vector<std::string> &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<Point2> 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<earth_mesh_.num_triangles(); t++) {
        std::vector<unsigned int> indices_ = earth_mesh_.read_triangle_indices_data(t);
        std::vector<Point3> 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);
    }
}