Commit 8db8b4a9 authored by Robert Scott James's avatar Robert Scott James

Trying to figure out where the spikey bits of my supposedly 'smooth' sphere...

Trying to figure out where the spikey bits of my supposedly 'smooth' sphere are coming from. Added basic primitive classes.
parent 1ea02492
Pipeline #136 skipped
......@@ -7,7 +7,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
add_subdirectory(glfw-3.1.2)
include_directories(glfw-3.1.2/include)
set(SOURCE_FILES main.cpp)
set(SOURCE_FILES main.cpp graphicPrimitives.cpp graphicPrimitives.h)
add_executable(worldGenerator ${SOURCE_FILES})
target_link_libraries(worldGenerator glfw ${GLFW_LIBRARIES})
\ No newline at end of file
//
// Created by Robert on 24/04/2016.
//
#include "graphicPrimitives.h"
#include <iostream>
Face::Face(Point v1,Point v2,Point v3){
vertices.push_back(v1);
vertices.push_back(v2);
vertices.push_back(v3);
/* Now to calculate the normal vector for this face from the average of it's vertices */
double tx = ( (v1.getX() + v2.getX() + v3.getX()) / 3.0);
double ty = ( (v1.getX() + v2.getX() + v3.getZ()) / 3.0);
double tz = ( (v1.getZ() + v2.getZ() + v3.getZ()) / 3.0);
normals = new Point(tx,ty,tz);
}
icoSphere::icoSphere(){
// Create the 12 Points Required First
Point p0(-1,t,0);
Point p1(1,t,0);
Point p2(-1,-t,0);
Point p3(1,-t,0);
Point p4(0,-1,t);
Point p5(0,1,t);
Point p6(0,-1,-t);
Point p7(0,1,-t);
Point p8(t,0,-1);
Point p9(t,0,1);
Point p10(-t,0,-1);
Point p11(-t,0,1);
// 5 Faces around p0
faceArray.push_back(Face(p0,p11,p5));
faceArray.push_back(Face(p0,p5,p1));
faceArray.push_back(Face(p0,p1,p7));
faceArray.push_back(Face(p0,p7,p10));
// 5 adjacent faces
faceArray.push_back(Face(p1,p5,p9));
faceArray.push_back(Face(p5,p11,p4));
faceArray.push_back(Face(p11,p10,p2));
faceArray.push_back(Face(p10,p7,p6));
faceArray.push_back(Face(p7,p1,p8));
// 5 faces around p3
faceArray.push_back(Face(p3,p9,p4));
faceArray.push_back(Face(p3,p4,p2));
faceArray.push_back(Face(p3,p2,p6));
faceArray.push_back(Face(p3,p6,p8));
faceArray.push_back(Face(p3,p8,p9));
// 5 adjacent faces
faceArray.push_back(Face(p4,p9,p5));
faceArray.push_back(Face(p2,p4,p11));
faceArray.push_back(Face(p6,p2,p10));
faceArray.push_back(Face(p8,p6,p7));
faceArray.push_back(Face(p9,p8,p1));
}
void icoSphere::draw(){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
for(int i = 0; i < faceArray.size(); i++){
faceArray[i].draw();
}
};
void icoSphere::subdivide(int recursionLevel){
std::cout << "Recursion Level: " << recursionLevel << std::endl;
if(recursionLevel == 0){
return;
} else {
while(recursionLevel != 0 ) {
// Go through each face in the icoSphere and replace it with 4 new ones. Add them to the end and it should be fine.
// First look at how many faces there are in the icosphere before we begin this needs to remain fixed else all hell will break loose if we start adding in the middle of the loop
int n_faces = faceArray.size();
for (int i = 0; i < n_faces; i++) {
// Now we need to extract the vertices from the faces this should be fairly easy.
Point v1 = faceArray[0].getV1();
Point v2 = faceArray[0].getV2();
Point v3 = faceArray[0].getV3();
// Calculate the new positions and normalise them to a unit sphere
Point a = getMidPoint(v1, v2);
Point b = getMidPoint(v2, v3);
Point c = getMidPoint(v3, v1);
// Generate the new faces using the newly calculated vertices. Clockwise from top left
Face nFace1(v1, a, c);
Face nFace2(a, v2, b);
Face nFace3(c, b, v3);
Face nFace4(c, a, b);
// Delete the old face from the beginning of the array
faceArray.erase(faceArray.begin());
// Now to add the new faces to the end of the faceArray
faceArray.push_back(nFace1);
faceArray.push_back(nFace2);
faceArray.push_back(nFace3);
faceArray.push_back(nFace4);
}
recursionLevel--;
}
// Continue recurring down until the required number of layers is complete
// Now return nothing and we are all good
return;
}
}
Point icoSphere::getMidPoint(Point a , Point b) {
// Calculate the coordinates of the midpoint between the two points
double midx = (a.getX() + b.getX())/2.0;
double midy = (a.getY() + b.getY())/2.0;
double midz = (a.getZ() + b.getZ())/2.0;
// Normalise the values so it lies on the unit sphere
double r = sqrt( midx*midx + midy*midy + midz*midz);
//double r = 1.0; // This should leave a refined icosahedron not an icosphere.
midx /= r;
midy /= r;
midz /= r;
// Generate a new Point using these values
Point midPoint(midx,midy,midz);
// Return it
return(midPoint);
}
//
// Created by Robert on 24/04/2016.
//
#ifndef WORLDGENERATOR_GRAPHICPRIMITIVES_H
#define WORLDGENERATOR_GRAPHICPRIMITIVES_H
#include<GLFW/glfw3.h>
#include <vector>
#include <array>
#include <cmath>
class Point{
public:
Point(double _x,double _y,double _z){
x = _x; y = _y; z = _z;
}
double getY() const {
return y;
}
void setY(double y) {
Point::y = y;
}
double getX() const {
return x;
}
void setX(double x) {
Point::x = x;
}
double getZ() const {
return z;
}
void setZ(double z) {
Point::z = z;
}
protected:
double x,y,z;
};
class Face{
public:
Face(Point v1,Point v2,Point v3);
Point getV1(){return(vertices[0]);};
Point getV2(){return(vertices[1]);};
Point getV3(){return(vertices[2]);};
void draw(){
glBegin(GL_TRIANGLES);
for(int i = 0; i < vertices.size(); i++){
glNormal3d(normals->getX(),normals->getY(),normals->getZ());
glVertex3d(vertices[i].getX(),vertices[i].getY(),vertices[i].getZ());
}
glEnd();
}
protected:
std::vector<Point> vertices;
Point *normals;
};
class icoSphere {
public:
icoSphere();
void draw();
void subdivide(int);
protected:
const double t = (1.0+ sqrt(5.0)) / 2.0;
std::vector<Face> faceArray;
Point getMidPoint(Point, Point);
};
#endif //WORLDGENERATOR_GRAPHICPRIMITIVES_H
#include <iostream>
#include <GLFW/glfw3.h>
#include "graphicPrimitives.h"
using namespace std;
......@@ -19,16 +20,35 @@ int main() {
/* Make the window's context current */
glfwMakeContextCurrent(window);
glClearColor (0.0, 0.0, 0.0, 0.0);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);
icoSphere sphere;
sphere.subdivide(1);
glScalef(0.5,0.5,0.5);
double lastTime = glfwGetTime();
/* Loop until the user closes the window */
while (!glfwWindowShouldClose(window)){
/* Render here */
sphere.draw();
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
/* Wait for time interval to happen */
while ( (glfwGetTime() - lastTime) > (1/30.0) ){
lastTime = glfwGetTime();
glRotatef(360/240.0f,0.0,0.1,0.0);
std::cout << "Next Frame" << std::endl;
}
}
glfwTerminate();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment