Instead of defining our cube inside actor class we can wrap that inside a Shape class.
#pragma once
#include <iostream>
#include <vector>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
struct Vertex {
Vertex() {}
Vertex(const float& x, const float& y, const float& z, const float& r, const float& g, const float& b, const float& a, const float& s, const float& t) {
Position = glm::vec3(x, y, z);
Color = glm::vec4(r, g, b, a);
TexCoords = glm::vec2(s, t);
}
glm::vec3 Position{};
glm::vec4 Color{};
glm::vec2 TexCoords{};
//float TexIndex;
static int getSize() { return sizeof(float) * 9; }
static std::vector<float> serialize(const std::vector<Vertex>& vec){
int N = vec.size() * getSize();
std::vector<float> j;
j.reserve(N);
for (Vertex v : vec) {
j.push_back(v.Position.x);
j.push_back(v.Position.y);
j.push_back(v.Position.z);
j.push_back(v.Color.x);
j.push_back(v.Color.y);
j.push_back(v.Color.z);
j.push_back(v.Color.w);
j.push_back(v.TexCoords.x);
j.push_back(v.TexCoords.y);
}
return j;
}
};
class Shape{
protected:
std::vector<Vertex> vertices{};
std::vector<unsigned int> indices{};
public:
std::vector<float> getVertices() {
auto a = Vertex::serialize(vertices);
//std::cout << "Serialize:" << std::endl;
//for(auto i : a)
// std::cout << i << " - ";
return a;
}
std::vector<unsigned int> getIndices() {
return indices;
}
};
//Cube.h
#pragma once
#include "Shape.h"
class Cube :
public Shape
{
void setCube(const float& size) {
vertices = {
Vertex(-size, -size, -size, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f),
Vertex( size, -size, -size, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f),
Vertex( size, size, -size, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f),
Vertex(-size, size, -size, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f),
Vertex(-size, -size, size, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f),
Vertex( size, -size, size, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f),
Vertex( size, size, size, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f),
Vertex(-size, size, size, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f),
Vertex(-size, size , size, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f),
Vertex(-size, size, -size, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f),
Vertex(-size, -size, -size, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f),
Vertex(-size, -size, size, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f),
Vertex( size, size, size, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f),
Vertex( size, size, -size, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f),
Vertex( size, -size, -size, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f),
Vertex( size, -size, size, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f),
Vertex(-size, -size, -size, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f),
Vertex( size, -size, -size, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f),
Vertex( size, -size, size, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f),
Vertex(-size, -size, size, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f),
Vertex(-size, size, -size, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f),
Vertex( size, size, -size, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f),
Vertex( size, size, size, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f),
Vertex(-size, size, size, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f),
};
// calculate indicies
for (int i = 0; i < 6; i++) {
int offsset = i * 4;
indices.push_back(offsset);
indices.push_back(offsset + 1);
indices.push_back(offsset + 2);
indices.push_back(offsset);
indices.push_back(offsset + 2);
indices.push_back(offsset + 3);
}
}
public:
Cube() {
setCube(100.0f);
}
Cube(const float& size) {
setCube(size);
}
};
// Cylinder
#pragma once
#include "Shape.h"
//#include <cmath>
class Cylinder :
public Shape
{
void setCylinder(const float& radius, const float& depth, const int& N) {
for (int i = 0; i <= N; i++){
//double rad = 3.14159265 * (360) / 180;
float x, y, z;
x = radius * sin(6.28319 / N * i);
z = radius * cos(6.28319 / N * i);
y = depth / 2;
vertices.push_back(Vertex(x, y, z, 1, 1, 1, 1, (float)i / N, 1));
y = -depth / 2;
vertices.push_back(Vertex(x, y, z, 1, 1, 1, 1, (float)i / N, 0));
}
// calculate indicies
for (int i = 0; i < N; i++) {
int offsset = i * 2;
indices.push_back(offsset);
indices.push_back(offsset + 1);
indices.push_back(offsset + 2);
indices.push_back(offsset + 1);
indices.push_back(offsset + 2);
indices.push_back(offsset + 3);
}
// top surface
int j = vertices.size();
vertices.push_back(Vertex(0, depth / 2, 0, 1, 1, 1, 1, 0.5f, 0.5f));
for (int i = 0; i <= N; i++) {
float x, y, z;
x = radius * sin(6.28319 / N * i);
z = radius * cos(6.28319 / N * i);
y = depth / 2;
vertices.push_back(Vertex(x, y, z, 1, 1, 1, 1, (sin(6.28319 / N * i) + 1) / 2, (cos(6.28319 / N * i) + 1) / 2));
}
for (int i = 0, offsset = j + 1; i < N-1; i++) {
indices.push_back(j);
indices.push_back(offsset);
indices.push_back(offsset + 1);
offsset++;
}
// bottom surface
j = vertices.size();
vertices.push_back(Vertex(0, -depth / 2, 0, 1, 1, 1, 1, 0.5f, 0.5f));
for (int i = 0; i <= N; i++) {
float x, y, z;
x = radius * sin(6.28319 / N * i);
z = radius * cos(6.28319 / N * i);
y = -depth / 2;
vertices.push_back(Vertex(x, y, z, 1, 1, 1, 1, (sin(6.28319 / N * i) + 1) / 2, (cos(6.28319 / N * i) + 1) / 2));
}
for (int i = 0, offsset = j + 1; i < N-1; i++) {
indices.push_back(j);
indices.push_back(offsset );
indices.push_back(offsset + 1);
offsset++;
}
//vertices.push_back(Vertex(0, -depth / 2, 0, 1, 1, 1, 1, 0.5f, 0.5f));
}
public:
Cylinder() { setCylinder(100,100,16); }
Cylinder(float radius,float depth, int N) {
setCylinder(radius, depth, 16);
}
};
Actor
#pragma once
#include <vector>
#include <iostream>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include "Shape.h"
#include "Cube.h"
#include "Cylinder.h"
class Actor {
public: // everything is public - for now -
Shape shape;
glm::vec3 location;
glm::vec3 rotation;
glm::vec3 scale;
glm::mat4 transform; // model matrix
Actor() {
location = glm::vec3(0, 0, 0);
rotation = glm::vec3(0, 0, 0);
scale = glm::vec3(1, 1, 1);
calculateTransform();
}
Actor(Shape shape) : Actor() {
this->shape = shape;
}
void setLocation(glm::vec3 location) {
this->location = location;
calculateTransform();
}
void setLocation(float x, float y, float z) {
setLocation(glm::vec3(x, y, z));
}
void setRotation(glm::vec3 rotation) {
this->rotation = rotation;
calculateTransform();
}
void setRotation(float x, float y, float z){
setRotation(glm::vec3(x, y, z));
}
void setScale(glm::vec3 scale) {
this->scale = scale;
calculateTransform();
}
void setScale(float x, float y, float z) {
setScale(glm::vec3(x, y, z));
}
glm::mat4 modelMatrix() {
return transform;
}
void calculateTransform() {
transform = glm::mat4(1.0f);
transform = glm::translate(transform, location);
transform = glm::rotate(transform, glm::radians(rotation.x), glm::vec3(1, 0, 0));
transform = glm::rotate(transform, glm::radians(rotation.y), glm::vec3(0, 1, 0));
transform = glm::rotate(transform, glm::radians(rotation.z), glm::vec3(0, 0, 1));
transform = glm::scale(transform, scale);
}
std::vector<float> getPoints() {
return shape.getVertices();
}
std::vector<unsigned int> getIndicies() {
return shape.getIndices();
}
};
Leave a Reply