Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 123 additions & 31 deletions main.cpp
Original file line number Diff line number Diff line change
@@ -1,53 +1,145 @@
#include<math.h>
#include<iostream>

#include "engine.hpp"

static int SCR_HEIGHT = 600;
static int SCR_WIDTH = 800;

const char *cubeSource = "/cube2.obj";
const char *catSource = "/cat.obj";
const char *benchSource = "/bench.obj";

const char *vertexShaderSource = "/vertex/standart.vshader";
const char *fragmentShaderSource = "/fragment/standart.fshader";

const char *cubeSource = "/cube.obj";

class MovingBall : public Object {
private:
float MIN_VELOCITY = 0.001;

public:
Vec3 velocity;
float bounciness = 1;
float friction = 0;

void Update(float dt) override {
transform->Translate(velocity * dt);
Vec3 rotationAxis = cross(normalize(velocity), Vec3(0, -1, 0));
float angle = length(velocity) * dt / transform->GetScale().x;
Mat4 rotation = transform->GetRotation();
transform->Rotate(inverse(rotation));
transform->Rotate(angle, rotationAxis);
transform->Rotate(rotation);
velocity *= pow(1 - friction, dt);
if (length(velocity) < MIN_VELOCITY) {
velocity = Vec3(0, 0, 0);
}
}

MovingBall(Vec3 position, ShaderProgram * shaderProgram,
std::string diffuseSource, std::string specularSource = "") {
this->renderData = new RenderData();
this->renderData->model = Model::loadFromFile("/shar_152.obj"); // Model::GetSphere();
this->renderData->model->shader = shaderProgram;

auto images = std::vector<std::string>();
images.push_back(diffuseSource);
if (specularSource != "") {
images.push_back(specularSource);
}
this->renderData->material = {
4.f,
Texture(images),
};

bindRenderData(this->renderData);

Object* initModel();
this->collider = new Collider{Sphere{
Vec3(0.0),
1.0f,
}};

transform = new Transform(position, Vec3(1., 1., 1.), Mat4(1.0));
}
};

class GameManager : public Object {
public:
std::vector<MovingBall*> balls;
float minX = -7, maxX = 7, minZ = -7, maxZ = 7;

void Update(float dt) override {
for (int i = 0; i < balls.size(); ++i) {
auto ball = balls[i];
Vec3 pos = ball->transform->GetTranslation();
if (pos.x < minX) {
ball->transform->Translate((1 + ball->bounciness) * Vec3(minX - pos.x, 0, 0));
ball->velocity = Vec3(- ball->velocity.x, 0, ball->velocity.z) * ball->bounciness;
}
if (pos.x > maxX) {
ball->transform->Translate((1 + ball->bounciness) * Vec3(maxX - pos.x, 0, 0));
ball->velocity = Vec3(- ball->velocity.x, 0, ball->velocity.z) * ball->bounciness;
}
if (pos.z < minZ) {
ball->transform->Translate((1 + ball->bounciness) * Vec3(0, 0, minZ - pos.z));
ball->velocity = Vec3(ball->velocity.x, 0, - ball->velocity.z) * ball->bounciness;
}
if (pos.z > maxZ) {
ball->transform->Translate((1 + ball->bounciness) * Vec3(0, 0, maxZ - pos.z));
ball->velocity = Vec3(ball->velocity.x, 0, - ball->velocity.z) * ball->bounciness;
}
for (int j = i + 1; j < balls.size(); ++j) {
auto ball2 = balls[j];
if (ball->collider->Collide(*ball->transform, ball2->collider, *ball2->transform)) {
// collision
Vec3 pos2 = ball2->transform->GetTranslation();
Vec3 center = (pos + pos2) * 0.5f; // collision point
Vec3 speed = ball->velocity - ball2->velocity; // approach speed of 2 balls
Vec3 v = pos - center; // vector towards center of collision
float dotProduct = speed.x * v.x + speed.z * v.z;
float proj = dotProduct / length(v); // projection of speed vector on collision line
Vec3 impulseChange = normalize(v) * proj * (1 + ball->bounciness * ball2->bounciness);
ball->velocity -= impulseChange * 0.5f;
ball2->velocity += impulseChange * 0.5f;
ball->transform->Translate(v * (ball->transform->GetScale().x / length(v) - 1));
ball2->transform->Translate(v * (1 - ball2->transform->GetScale().x / length(v)));
}
}
}
}
explicit GameManager(std::vector<MovingBall*> balls) {
this->balls = balls;
}
};

MovingBall *newBall(Vec3 position, Vec3 velocity,
ShaderProgram *sp, std::string diffuseSource, std::string specularSource);

int main() {
auto engine = Engine(SCR_WIDTH, SCR_HEIGHT);
Object* testObj = initModel();
engine.AddObject<>(testObj);
engine.Run(SCR_WIDTH, SCR_HEIGHT);
}

Object* initModel() {
// build and compile our shader program ------------------------------------
Shader vShader = Shader(VertexShader, vertexShaderSource);
Shader fShader = Shader(FragmentShader, fragmentShaderSource);
ShaderProgram *shaderProgram = new ShaderProgram(vShader, fShader);

// init a model
Model * model = Model::loadFromFile(catSource);
std::vector<MovingBall*> balls;
int ballsCount = 5;

auto obj = new Object();
obj->renderData = new RenderData();
obj->renderData->model = model;
obj->renderData->model->shader = new ShaderProgram(vShader, fShader);
for (int i = 0; i < ballsCount; ++i) {
MovingBall *sphere = newBall(Vec3(i * 2 - 5, -12, -i), Vec3(3, 0, 1 + i),
shaderProgram, "/152.png", "/cat_specular.png");
balls.push_back(sphere);
engine.AddObject<>(sphere);
}

obj->transform = new Transform(glm::vec3(0.f, -3.f, -8.f), glm::vec3(.1f, .1f, .1f), glm::mat4(1.0));
obj->transform->Rotate(1.67f, glm::vec3(-1.f, 0.f, 0.f));
auto render_data = obj->renderData;
GameManager *gameManager = new GameManager(balls);

bindRenderData(render_data);
engine.AddObject(gameManager);

// Maybe this can be less clunky?
// Perhaps variadic functions?
auto images = std::vector<std::string>();
images.push_back("/Cat_diffuse.png");
images.push_back("/Cat_specular.png");
obj->renderData->material = {
4.f,
Texture(images),
};
engine.Run(SCR_WIDTH, SCR_HEIGHT);
}

return obj;
MovingBall *newBall(Vec3 position, Vec3 velocity,
ShaderProgram *sp, std::string diffuseSource, std::string specularSource) {
MovingBall* ball = new MovingBall(position, sp, diffuseSource, specularSource);
ball->velocity = velocity;
return ball;
}
Loading