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();
	}
};


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *