Point4D & Matrix4x4 is not mutable.

Delete a lot of not used methods.
Shared ptr corrected mistakes.
master
Vectozavr 2021-09-14 17:47:53 +07:00
parent bb4cf148c4
commit 17a307c45e
43 changed files with 270 additions and 907 deletions

View File

@ -14,19 +14,19 @@ add_executable(shooter
Client.h
Server.cpp
Server.h
Weapon.cpp
Weapon.h
Ak47.cpp
Ak47.h
Shotgun.cpp
Shotgun.h
Gun.cpp
Gun.h
weapon/Weapon.cpp
weapon/Weapon.h
weapon/Ak47.cpp
weapon/Ak47.h
weapon/Shotgun.cpp
weapon/Shotgun.h
weapon/Gun.cpp
weapon/Gun.h
Bonus.cpp
Bonus.h
Gold_Ak47.h
Rifle.cpp
Rifle.h
weapon/Gold_Ak47.h
weapon/Rifle.cpp
weapon/Rifle.h
# 3d engine:
engine/utils/Time.h
engine/utils/Time.cpp
@ -52,8 +52,6 @@ add_executable(shooter
engine/Engine.cpp
engine/Plane.h
engine/Plane.cpp
engine/CameraController.h
engine/CameraController.cpp
engine/animation/Animatable.h
engine/animation/Animation.h
engine/animation/Interpolation.h

View File

@ -12,6 +12,32 @@ void Client::updatePacket() {
_socket.send(packet, _socket.serverId());
}
void Client::spawnPlayer(sf::Uint16 id) {
std::string name = "Player_" + std::to_string(id);
_players.insert({ id, std::make_shared<Player>() });
(*_world).addMesh(_players[id], name);
_players[id]->setVisible(true);
_players[id]->setAcceleration(Point4D{0, 0, 0});
// add head and other stuff:
_world->loadObj(name + "_head", "../obj/cube.obj", "",Point4D{0.7, 0.7, 0.7});
(*_world)[name + "_head"]->translate(Point4D{0, 2, 0});
(*_world)[name + "_head"]->setCollider(false);
_players[id]->attach((*_world)[name + "_head"]);
_world->loadObj(name + "_eye1", "../obj/cube.obj", "",Point4D{0.2, 0.2, 0.05});
(*_world)[name + "_eye1"]->translate(Point4D{0.3, 2.1, 0.7});
(*_world)[name + "_eye1"]->setCollider(false);
(*_world)[name + "_eye1"]->setColor({147, 159, 255});
(*_world)[name + "_head"]->attach((*_world)[name + "_eye1"]);
_world->loadObj(name + "_eye2", "../obj/cube.obj", "",Point4D{0.2, 0.2, 0.05});
(*_world)[name + "_eye2"]->translate(Point4D{-0.3, 2.1, 0.7});
(*_world)[name + "_eye2"]->setCollider(false);
(*_world)[name + "_eye2"]->setColor({147, 159, 255});
(*_world)[name + "_head"]->attach((*_world)[name + "_eye2"]);
}
void Client::processInit(sf::Packet& packet) {
sf::Uint16 targetId;
double buf[4];
@ -19,29 +45,7 @@ void Client::processInit(sf::Packet& packet) {
while (packet >> targetId >> buf[0] >> buf[1] >> buf[2] >> buf[3])
{
if(targetId != _socket.ownId()) {
std::string name = "Player_" + std::to_string(targetId);
_players.insert({ targetId, std::make_shared<Player>() });
(*_world).addMesh(_players[targetId], name);
_players[targetId]->setVisible(true);
_players[targetId]->setAcceleration(Point4D{0, 0, 0});
// add head and other stuff:
_world->loadObj(name + "_head", "../obj/cube.obj", "",Point4D{0.7, 0.7, 0.7});
(*_world)[name + "_head"]->translate(Point4D{0, 2, 0});
(*_world)[name + "_head"]->setCollider(false);
_players[targetId]->attach((*_world)[name + "_head"]);
_world->loadObj(name + "_eye1", "../obj/cube.obj", "",Point4D{0.2, 0.2, 0.05});
(*_world)[name + "_eye1"]->translate(Point4D{0.3, 2.1, 0.7});
(*_world)[name + "_eye1"]->setCollider(false);
(*_world)[name + "_eye1"]->setColor({147, 159, 255});
(*_world)[name + "_head"]->attach((*_world)[name + "_eye1"]);
_world->loadObj(name + "_eye2", "../obj/cube.obj", "",Point4D{0.2, 0.2, 0.05});
(*_world)[name + "_eye2"]->translate(Point4D{-0.3, 2.1, 0.7});
(*_world)[name + "_eye2"]->setCollider(false);
(*_world)[name + "_eye2"]->setColor({147, 159, 255});
(*_world)[name + "_head"]->attach((*_world)[name + "_eye2"]);
spawnPlayer(targetId);
_players[targetId]->translateToPoint(Point4D{ buf[0], buf[1], buf[2]});
_players[targetId]->setHealth(buf[3]);
@ -59,7 +63,7 @@ void Client::processUpdate(sf::Packet& packet) {
_players[targetId]->translateToPoint(Point4D{buf[0], buf[1], buf[2]});
_players[targetId]->setHealth(buf[3]);
_players[targetId]->rotateToAngle(Point4D{0, buf[4], 0});
//(*_world)[name + "_head"]->rotateToAngle({buf[5], 2*buf[4], 0});
(*_world)[name + "_head"]->rotate(Matrix4x4::RotationY(buf[4]) * Point4D{1, 0, 0},
buf[5] - _players[targetId]->headAngle());
_players[targetId]->setHeadAngle(buf[5]);
@ -74,29 +78,7 @@ void Client::processNewClient(sf::Packet& packet) {
packet >> targetId;
std::string name = "Player_" + std::to_string(targetId);
_players.insert({ targetId, std::make_shared<Player>() });
_world->addMesh(_players[targetId], name);
_players[targetId]->setVisible(true);
_players[targetId]->setAcceleration(Point4D{0, 0, 0});
// add head and other stuff:
_world->loadObj(name + "_head", "../obj/cube.obj","",Point4D{0.7, 0.7, 0.7});
(*_world)[name + "_head"]->translate(Point4D{0, 2, 0});
(*_world)[name + "_head"]->setCollider(false);
_players[targetId]->attach((*_world)[name + "_head"]);
_world->loadObj(name + "_eye1", "../obj/cube.obj","",Point4D{0.2, 0.2, 0.05});
(*_world)[name + "_eye1"]->translate(Point4D{0.3, 2.1, 0.7});
(*_world)[name + "_eye1"]->setCollider(false);
(*_world)[name + "_eye1"]->setColor({147, 159, 255});
(*_world)[name + "_head"]->attach((*_world)[name + "_eye1"]);
_world->loadObj(name + "_eye2", "../obj/cube.obj", "",Point4D{0.2, 0.2, 0.05});
(*_world)[name + "_eye2"]->translate(Point4D{-0.3, 2.1, 0.7});
(*_world)[name + "_eye2"]->setCollider(false);
(*_world)[name + "_eye2"]->setColor({147, 159, 255});
(*_world)[name + "_head"]->attach((*_world)[name + "_eye2"]);
spawnPlayer(targetId);
}
void Client::processDisconnect(sf::Uint16 targetId) {
@ -204,7 +186,7 @@ void Client::addTrace(const Point4D& from, const Point4D& to) {
_socket.send(packet, _socket.serverId());
}
void Client::deleteTrace(const std::shared_ptr<World> &world, const std::string &traceName) {
void Client::deleteTrace(std::shared_ptr<World> world, const std::string &traceName) {
world->removeMesh(traceName);
}
@ -214,4 +196,3 @@ void Client::takeBonus(const std::string& bonusName) {
packet << MsgType::RemoveBonus << bonusName;
_socket.send(packet, _socket.serverId());
}

View File

@ -18,6 +18,8 @@ private:
std::map<sf::Uint16, std::shared_ptr<Player>> _players{};
int fireTraces = 0;
void spawnPlayer(sf::Uint16 id);
public:
Client(std::shared_ptr<Player> player, std::shared_ptr<World> world) : _player(std::move(player)), _world(std::move(world)) {};
@ -38,7 +40,7 @@ public:
void addTrace(const Point4D& from, const Point4D& to);
void deleteTrace(const std::shared_ptr<World> &world, const std::string& traceName);
void deleteTrace(std::shared_ptr<World> world, const std::string& traceName);
};

View File

@ -9,8 +9,9 @@
void Player::update() {
// friction
if(inCollision())
p_velocity -= p_velocity*Time::deltaTime()*2;
p_velocity = p_velocity - p_velocity*Time::deltaTime()*2;
if(isInSlowMo) {
if(_ability > 0)
@ -159,7 +160,6 @@ void Player::update() {
if ((position() - rayToFloor.first).abs() < 2) {
int soundNum = round((double) rand() / RAND_MAX * 5) + 1;
walkSound.setBuffer(*ResourceManager::loadSoundBuffer("../sound/stonestep" + std::to_string(soundNum) + ".ogg"));
//walkSound.setVolume(30);
walkSound.play();
}
}
@ -276,7 +276,7 @@ void Player::playKill() {
killSound.play();
}
void Player::collisionWithObject(const std::string &objName, const std::shared_ptr<Mesh> &obj) {
void Player::collisionWithObject(const std::string &objName, std::shared_ptr<Mesh> obj) {
if(objName.find("Bonus_gun") != std::string::npos)
addWeapon(std::make_shared<Gun>());
@ -304,7 +304,7 @@ void Player::collisionWithObject(const std::string &objName, const std::shared_p
}
}
void Player::addWeapon(const std::shared_ptr<Weapon> &weapon) {
void Player::addWeapon(std::shared_ptr<Weapon> weapon) {
changeWeaponSound.play();
if(!_weapons.empty()) {

View File

@ -11,11 +11,11 @@
#include "Mesh.h"
#include "Camera.h"
#include "World.h"
#include "Ak47.h"
#include "Shotgun.h"
#include "Gun.h"
#include "Gold_Ak47.h"
#include "Rifle.h"
#include "weapon/Ak47.h"
#include "weapon/Shotgun.h"
#include "weapon/Gun.h"
#include "weapon/Gold_Ak47.h"
#include "weapon/Rifle.h"
class Player : public Mesh{
private:
@ -53,7 +53,7 @@ private:
sf::Sound unSlowMoSound;
sf::Sound fullHealthSound;
sf::Sound fullAbilitySound;
std::string _name = "im";
std::vector<std::shared_ptr<Weapon>> _weapons;
@ -75,16 +75,16 @@ public:
void update();
void attachCamera(std::shared_ptr<Camera>& camera, std::shared_ptr<Screen> screen) {
_camera = camera;
void attachCamera(std::shared_ptr<Camera> camera, std::shared_ptr<Screen> screen) {
_camera = std::move(camera);
_screen = std::move(screen);
camera->translateToPoint(position() + Point4D{0, 1.8, 0});
this->attach(camera);
_camera->translateToPoint(position() + Point4D{0, 1.8, 0});
this->attach(_camera);
}
void attachWorld(const std::shared_ptr<World>& world, const Point4D& pos = Point4D{0, 30, 0}) {
_world = world;
void attachWorld(std::shared_ptr<World> world, const Point4D& pos = Point4D{0, 30, 0}) {
_world = std::move(world);
translate(pos);
@ -98,7 +98,7 @@ public:
fullHealthSound.setBuffer(*ResourceManager::loadSoundBuffer("../sound/fullHealth.ogg"));
fullAbilitySound.setBuffer(*ResourceManager::loadSoundBuffer("../sound/fullAbility.ogg"));
setCollisionCallBack([this](const std::string& objName, const std::shared_ptr<Mesh>& obj) {collisionWithObject(objName, obj);});
setCollisionCallBack([this](const std::string& objName, std::shared_ptr<Mesh> obj) {collisionWithObject(objName, std::move(obj));});
}
void setHealth(double h) {
@ -151,9 +151,9 @@ public:
void playDeath();
void playKill();
void collisionWithObject(const std::string& objName, const std::shared_ptr<Mesh>& obj);
void collisionWithObject(const std::string& objName, std::shared_ptr<Mesh> obj);
void addWeapon(const std::shared_ptr<Weapon>& weapon);
void addWeapon(std::shared_ptr<Weapon> weapon);
void initWeapons();
};

View File

@ -23,7 +23,7 @@ std::vector<Triangle> &Camera::project(Mesh& mesh, Screen::ViewMode mode) {
std::vector<Triangle> clippedTriangles, tempBuffer;
for(auto& t : mesh.triangles()) {
double dot = t.norm().dot((mesh.position() + t[0] - p_position).normalize());
double dot = t.norm().dot((mesh.position() + t[0] - p_position).normalized());
if(dot > 0)
continue;
@ -63,9 +63,9 @@ std::vector<Triangle> &Camera::project(Mesh& mesh, Screen::ViewMode mode) {
// and transform it's coordinate to screen space (in pixels):
clippedTriangle *= SP;
clippedTriangle[0] /= clippedTriangle[0].w();
clippedTriangle[1] /= clippedTriangle[1].w();
clippedTriangle[2] /= clippedTriangle[2].w();
clippedTriangle[0] = clippedTriangle[0] / clippedTriangle[0].w();
clippedTriangle[1] = clippedTriangle[1] / clippedTriangle[1].w();
clippedTriangle[2] = clippedTriangle[2] / clippedTriangle[2].w();
triangles.emplace_back(clippedTriangle);
}
@ -112,12 +112,8 @@ std::vector<Triangle> &Camera::sorted() {
std::sort(v_z1.begin(), v_z1.end());
std::sort(v_z2.begin(), v_z2.end());
double a = 1;
double b = 1;
double c = 1;
double z1 = (a*v_z1[0] + b*v_z1[1] + c*v_z1[2]);
double z2 = (a*v_z2[0] + b*v_z2[1] + c*v_z2[2]);
double z1 = v_z1[0] + v_z1[1] + v_z1[2];
double z2 = v_z2[0] + v_z2[1] + v_z2[2];
return z1 > z2;
});
@ -138,6 +134,9 @@ void Camera::rotateX(double rx) {
p_left = Matrix4x4::RotationX(rx) * p_left;
p_up = Matrix4x4::RotationX(rx) * p_up;
p_lookAt = Matrix4x4::RotationX(rx) * p_lookAt;
for(auto attached : v_attached)
attached->rotateRelativePoint(position(), Point4D{rx, 0, 0});
}
void Camera::rotateY(double ry) {
@ -145,6 +144,9 @@ void Camera::rotateY(double ry) {
p_left = Matrix4x4::RotationY(ry) * p_left;
p_up = Matrix4x4::RotationY(ry) * p_up;
p_lookAt = Matrix4x4::RotationY(ry) * p_lookAt;
for(auto attached : v_attached)
attached->rotateRelativePoint(position(), Point4D{0, ry, 0});
}
void Camera::rotateZ(double rz) {
@ -152,22 +154,15 @@ void Camera::rotateZ(double rz) {
p_left = Matrix4x4::RotationZ(rz) * p_left;
p_up = Matrix4x4::RotationZ(rz) * p_up;
p_lookAt = Matrix4x4::RotationZ(rz) * p_lookAt;
}
void Camera::rotate(double rx, double ry, double rz) {
rotateX(rx);
rotateY(ry);
rotateZ(rz);
if(v_attached.empty())
return;
for(auto& attached : v_attached)
attached->rotateRelativePoint(position(), Point4D{rx, ry, rz});
for(auto attached : v_attached)
attached->rotateRelativePoint(position(), Point4D{0, 0, rz});
}
void Camera::rotate(const Point4D& r) {
rotate(r.x(), r.y(), r.z());
rotateX(r.x());
rotateY(r.y());
rotateZ(r.z());
}
@ -176,9 +171,7 @@ void Camera::rotate(const Point4D& v, double rv) {
p_up = Matrix4x4::Rotation(v, rv) * p_up;
p_lookAt = Matrix4x4::Rotation(v, rv) * p_lookAt;
if(v_attached.empty())
return;
for(auto& attached : v_attached)
for(auto attached : v_attached)
attached->rotateRelativePoint(position(), v, rv);
}
@ -187,9 +180,7 @@ void Camera::rotateLeft(double rl) {
rotate(p_left, rl);
if(v_attached.empty())
return;
for(auto& attached : v_attached)
for(auto attached : v_attached)
attached->rotateRelativePoint(position(), p_left, rl);
}
@ -197,9 +188,7 @@ void Camera::rotateUp(double ru) {
p_angleLeftUpLookAt = Point4D{p_angleLeftUpLookAt.x(), p_angleLeftUpLookAt.y() + ru, p_angleLeftUpLookAt.z()};
rotate(p_up, ru);
if(v_attached.empty())
return;
for(auto& attached : v_attached)
for(auto attached : v_attached)
attached->rotateRelativePoint(position(), p_up, ru);
}
@ -207,32 +196,24 @@ void Camera::rotateLookAt(double rlAt) {
p_angleLeftUpLookAt = Point4D{p_angleLeftUpLookAt.x(), p_angleLeftUpLookAt.y(), p_angleLeftUpLookAt.z() + rlAt};
rotate(p_lookAt, rlAt);
if(v_attached.empty())
return;
for(auto& attached : v_attached)
for(auto attached : v_attached)
attached->rotateRelativePoint(position(), p_lookAt, rlAt);
}
void Camera::rotateRelativePoint(const Point4D &s, double rx, double ry, double rz) {
p_angle += Point4D{rx, ry, rz};
void Camera::rotateRelativePoint(const Point4D &s, const Point4D &r) {
p_angle = p_angle + r;
// Translate XYZ by vector r1
Point4D r1 = p_position - s;
// In translated coordinate system we rotate camera and position
Point4D r2 = Matrix4x4::Rotation(rx, ry, rz)*r1;
rotate(rx, ry, rz);
Point4D r2 = Matrix4x4::Rotation(r)*r1;
rotate(r);
// After rotation we translate XYZ by vector -r2 and recalculate position
p_position = s + r2;
if(v_attached.empty())
return;
for(auto& attached : v_attached)
attached->rotateRelativePoint(s, Point4D{rx, ry, rz});
}
void Camera::rotateRelativePoint(const Point4D &s, const Point4D &r) {
rotateRelativePoint(s, r.x(), r.y(), r.z());
for(auto attached : v_attached)
attached->rotateRelativePoint(s, r);
}
void Camera::rotateRelativePoint(const Point4D &s, const Point4D &v, double r) {
@ -245,9 +226,7 @@ void Camera::rotateRelativePoint(const Point4D &s, const Point4D &v, double r) {
// After rotation we translate XYZ by vector -r2 and recalculate position
p_position = s + r2;
if(v_attached.empty())
return;
for(auto& attached : v_attached)
for(auto attached : v_attached)
attached->rotateRelativePoint(s, v, r);
}

View File

@ -61,23 +61,17 @@ public:
[[nodiscard]] Point4D lookAt() const { return p_lookAt; }
void translate(const Point4D& dv) override {
p_position += dv;
p_position = p_position + dv;
if(v_attached.empty())
return;
for(const auto& attached : v_attached)
for(auto attached : v_attached)
attached->translate(dv);
}
void translate(double dx, double dy, double dz) {
translate(Point4D{dx, dy, dz});
}
void translateToPoint(const Point4D& point);
void rotateX(double rx);
void rotateY(double ry);
void rotateZ(double rz);
void rotate(double rx, double ry, double rz);
void rotate(const Point4D& r) override;
void rotate(const Point4D& v, double rv) override;
@ -86,8 +80,6 @@ public:
void rotateUp(double ru);
void rotateLookAt(double rlAt);
// Rotate mesh around XYZ by (rx, ry, rz) radians relative val 'point4D'
void rotateRelativePoint(const Point4D& s, double rl, double ru, double rlAt);
// Rotate mesh around XYZ by (r.x, r.y, r.z) radians relative val 'point4D'
void rotateRelativePoint(const Point4D& s, const Point4D& r) override;
// Rotate mesh around normalised vector 'v' by 'r' radians relative val 'point4D'

View File

@ -1,38 +0,0 @@
//
// Created by Иван Ильин on 23.01.2021.
//
#include "CameraController.h"
#include <utility>
CameraController::CameraController(std::shared_ptr<Camera> camera, std::shared_ptr<Screen> screen) : camera(std::move(camera)), screen(std::move(screen)) {
}
void CameraController::update() {
// Left and right
if (Screen::isKeyPressed(sf::Keyboard::A))
camera->translate(camera->left()*Time::deltaTime()*5.0);
if (Screen::isKeyPressed(sf::Keyboard::D))
camera->translate(-camera->left()*Time::deltaTime()*5.0);
// Forward and backward
if (Screen::isKeyPressed(sf::Keyboard::W))
camera->translate(camera->lookAt()*Time::deltaTime()*5.0);
if (Screen::isKeyPressed(sf::Keyboard::S))
camera->translate(-camera->lookAt()*Time::deltaTime()*5.0);
if (Screen::isKeyPressed(sf::Keyboard::LShift))
camera->translate(0.0, -Time::deltaTime()*5.0, 0);
if (Screen::isKeyPressed(sf::Keyboard::Space))
camera->translate(0.0, Time::deltaTime()*5.0, 0);
// Mouse movement
Point4D disp = screen->getMouseDisplacement();
camera->rotateY(-disp.x()/1000.0);
camera->rotateLeft(disp.y()/1000.0);
}

View File

@ -1,21 +0,0 @@
//
// Created by Иван Ильин on 23.01.2021.
//
#ifndef ENGINE_CAMERACONTROLLER_H
#define ENGINE_CAMERACONTROLLER_H
#include "Camera.h"
#include "Screen.h"
class CameraController {
private:
std::shared_ptr<Camera> camera;
std::shared_ptr<Screen> screen;
public:
CameraController(std::shared_ptr<Camera> camera, std::shared_ptr<Screen> screen);
void update();
};
#endif //INC_3DZAVR_CAMERACONTROLLER_H

View File

@ -97,8 +97,6 @@ void Engine::create(int screenWidth, int screenHeight, const std::string &name,
void Engine::exit() {
if(screen->isOpen()) {
screen->close();
if(screen->isRender())
screen->setRender(false);
}
ResourceManager::unloadAllResources();
Log::log("Engine::exit(): exit engine (" + std::to_string(screen->width()) + " x " + std::to_string(screen->height()) + ") with name '" + screen->title() + "'.");

View File

@ -9,7 +9,6 @@
#include "World.h"
#include "Camera.h"
#include "utils/Log.h"
#include "CameraController.h"
class Engine {
protected:

View File

@ -49,47 +49,10 @@ Mesh Mesh::Obj(const std::string& filename) {
return Mesh(filename);
}
Mesh Mesh::Cube(double size) {
Mesh cube{};
cube.tris = {
{ Point4D{0.0, 0.0, 0.0, 1.0}, Point4D{0.0, 1.0, 0.0, 1.0}, Point4D{1.0, 1.0, 0.0, 1.0} },
{ Point4D{0.0, 0.0, 0.0, 1.0}, Point4D{1.0, 1.0, 0.0, 1.0}, Point4D{1.0, 0.0, 0.0, 1.0} },
{ Point4D{1.0, 0.0, 0.0, 1.0}, Point4D{1.0, 1.0, 0.0, 1.0}, Point4D{1.0, 1.0, 1.0, 1.0} },
{ Point4D{1.0, 0.0, 0.0, 1.0}, Point4D{1.0, 1.0, 1.0, 1.0}, Point4D{1.0, 0.0, 1.0, 1.0} },
{ Point4D{1.0, 0.0, 1.0, 1.0}, Point4D{1.0, 1.0, 1.0, 1.0}, Point4D{0.0, 1.0, 1.0, 1.0} },
{ Point4D{1.0, 0.0, 1.0, 1.0}, Point4D{0.0, 1.0, 1.0, 1.0}, Point4D{0.0, 0.0, 1.0, 1.0} },
{ Point4D{0.0, 0.0, 1.0, 1.0}, Point4D{0.0, 1.0, 1.0, 1.0}, Point4D{0.0, 1.0, 0.0, 1.0} },
{ Point4D{0.0, 0.0, 1.0, 1.0}, Point4D{0.0, 1.0, 0.0, 1.0}, Point4D{0.0, 0.0, 0.0, 1.0} },
{ Point4D{0.0, 1.0, 0.0, 1.0}, Point4D{0.0, 1.0, 1.0, 1.0}, Point4D{1.0, 1.0, 1.0, 1.0} },
{ Point4D{0.0, 1.0, 0.0, 1.0}, Point4D{1.0, 1.0, 1.0, 1.0}, Point4D{1.0, 1.0, 0.0, 1.0} },
{ Point4D{1.0, 0.0, 1.0, 1.0}, Point4D{0.0, 0.0, 1.0, 1.0}, Point4D{0.0, 0.0, 0.0, 1.0} },
{ Point4D{1.0, 0.0, 1.0, 1.0}, Point4D{0.0, 0.0, 0.0, 1.0}, Point4D{1.0, 0.0, 0.0, 1.0} },
};
return cube *= Matrix4x4::Scale(size, size, size);
}
void Mesh::translate(double dx, double dy, double dz) {
p_position += Point4D(dx, dy, dz);
if(v_attached.empty())
return;
for(auto attached : v_attached)
attached->translate(Point4D{dx, dy, dz});
}
void Mesh::rotate(double rx, double ry, double rz) {
p_angle += Point4D{rx, ry, rz};
*this *= Matrix4x4::Rotation(rx, ry, rz);
}
void Mesh::rotate(const Point4D &r) {
p_angle += r;
p_angle = p_angle + r;
*this *= Matrix4x4::Rotation(r);
if(v_attached.empty())
return;
for(auto attached : v_attached)
attached->rotateRelativePoint(position(), r);
}
@ -97,22 +60,21 @@ void Mesh::rotate(const Point4D &r) {
void Mesh::rotate(const Point4D &v, double r) {
*this *= Matrix4x4::Rotation(v, r);
if(v_attached.empty())
return;
for(auto attached : v_attached)
attached->rotateRelativePoint(position(), v, r);
}
void Mesh::scale(double sx, double sy, double sz) {
*this *= Matrix4x4::Scale(sx, sy, sz);
}
void Mesh::scale(const Point4D &s) {
*this *= Matrix4x4::Scale(s.x(), s.y(), s.z());
*this *= Matrix4x4::Scale(s);
// TODO: scale attached objects
}
void Mesh::translate(const Point4D &t) {
translate(t.x(), t.y(), t.z());
p_position = p_position + t;
for(auto attached : v_attached)
attached->translate(t);
}
Mesh &Mesh::operator=(const Mesh &mesh) {
@ -122,15 +84,15 @@ Mesh &Mesh::operator=(const Mesh &mesh) {
return *this;
}
void Mesh::rotateRelativePoint(const Point4D &s, double rx, double ry, double rz) {
p_angle += Point4D{rx, ry, rz};
void Mesh::rotateRelativePoint(const Point4D &s, const Point4D &r) {
p_angle = p_angle + r;
// Translate XYZ by vector r1
Point4D r1 = p_position - s;
*this *= Matrix4x4::Translation(r1);
// In translated coordinate system we rotate mesh and position
Matrix4x4 rotationMatrix = Matrix4x4::Rotation(rx, ry, rz);
Matrix4x4 rotationMatrix = Matrix4x4::Rotation(r);
Point4D r2 = rotationMatrix*r1;
*this *= rotationMatrix;
@ -141,12 +103,7 @@ void Mesh::rotateRelativePoint(const Point4D &s, double rx, double ry, double rz
if(v_attached.empty())
return;
for(auto attached : v_attached)
attached->rotateRelativePoint(s, Point4D{rx, ry, rz});
}
void Mesh::rotateRelativePoint(const Point4D &s, const Point4D &r) {
p_angle += r;
rotateRelativePoint(s, r.x(), r.y(), r.z());
attached->rotateRelativePoint(s, r);
}
void Mesh::rotateRelativePoint(const Point4D &s, const Point4D &v, double r) {
@ -163,8 +120,6 @@ void Mesh::rotateRelativePoint(const Point4D &s, const Point4D &v, double r) {
*this *= Matrix4x4::Translation(-r2);
p_position = s + r2;
if(v_attached.empty())
return;
for(auto attached : v_attached)
attached->rotateRelativePoint(s, v, r);
}

View File

@ -13,6 +13,11 @@
#include "Object.h"
class Mesh : public Object, public Animatable, public RigidBody {
private:
// Operations with Matrix4x4
[[nodiscard]] Mesh operator*(const Matrix4x4& matrix4X4) const;
Mesh& operator*=(const Matrix4x4& matrix4X4);
protected:
std::vector<Triangle> tris;
@ -20,11 +25,7 @@ protected:
sf::Color c_color = sf::Color(255, 245, 194);
// Operations with Matrix4x4
[[nodiscard]] Mesh operator*(const Matrix4x4& matrix4X4) const;
Mesh& operator*=(const Matrix4x4& matrix4X4);
std::function<void(const std::string&, const std::shared_ptr<Mesh>&)> _collisionCallBack;
std::function<void(const std::string&, std::shared_ptr<Mesh>)> _collisionCallBack;
public:
Mesh() = default;
@ -41,21 +42,16 @@ public:
void setTriangles(const std::vector<Triangle>& t) override { tris = t; }
// Translate mesh
void translate(double dx, double dy, double dz);
void translate(const Point4D& t) override;
void translateToPoint(const Point4D& point);
// Rotate mesh around XYZ axes
void rotate(double rx, double ry, double rz);
void rotate(const Point4D& r) override;
// Rotate mesh around normalised vector 'v' by 'r' radians
void rotate(const Point4D& v, double r) override;
// Rotate mesh around XYZ by (rx, ry, rz) radians relative val 'point4D'
void rotateRelativePoint(const Point4D& point4D, double rx, double ry, double rz);
// Rotate mesh around XYZ by (r.x, r.y, r.z) radians relative val 'point4D'
void rotateRelativePoint(const Point4D& point4D, const Point4D& r) override;
// Rotate mesh around normalised vector 'v' by 'r' radians relative val 'point4D'
void rotateRelativePoint(const Point4D& point4D, const Point4D& v, double r) override;
void scale(double sx, double sy, double sz);
void scale(const Point4D& s);
void rotateToAngle(const Point4D& v) { rotate(v - p_angle); }
@ -66,18 +62,16 @@ public:
[[nodiscard]] sf::Color color() const override { return c_color; }
void setColor(sf::Color c) override;
Mesh static Cube(double size = 1.0);
Mesh static Obj(const std::string& filename);
Mesh static LineTo(const Point4D& from, const Point4D& to, double line_width = 0.1, sf::Color color = {150, 150, 150, 255});
void setVisible(bool visibility) { _visible = visibility; }
[[nodiscard]] bool isVisible() const { return _visible; }
std::vector<std::shared_ptr<Mesh>> static LoadObjects(const std::string& filename, const std::string &materials = "", const Point4D& scale = Point4D{1, 1, 1});
[[nodiscard]] const std::function<void(const std::string&, const std::shared_ptr<Mesh>&)>& collisionCallBack() const { return _collisionCallBack; }
void setCollisionCallBack(const std::function<void(const std::string&, const std::shared_ptr<Mesh>&)>& f) { _collisionCallBack = f; }
[[nodiscard]] const std::function<void(const std::string&, std::shared_ptr<Mesh>)>& collisionCallBack() const { return _collisionCallBack; }
void setCollisionCallBack(const std::function<void(const std::string&, std::shared_ptr<Mesh>)>& f) { _collisionCallBack = f; }
};

View File

@ -27,8 +27,8 @@ public:
[[nodiscard]] Point4D position() const { return p_position; }
[[nodiscard]] Point4D angle() const { return p_angle; }
void attach(const std::shared_ptr<Object>& object) {
v_attached.push_back(object);
void attach(std::shared_ptr<Object> object) {
v_attached.push_back(std::move(object));
}
};

View File

@ -33,23 +33,18 @@ std::pair<Point4D, double> Plane::intersection(const Point4D &start, const Point
}
int Plane::clip(Triangle &tri, Triangle &additional_tri) {
n.normalize();
n = n.normalized();
Point4D insidePoints[3]; int inside = 0;
Point4D outsidePoints[3]; int outside = 0;
Point4D insideTextures[3]; int insideT = 0;
Point4D outsideTextures[3]; int outsideT = 0;
double distances[3] = {distance(tri[0]), distance(tri[1]), distance(tri[2])};
for(int i = 0; i < 3; i++) {
if (distances[i] >= 0) {
insidePoints[inside++] = tri[i];
insideTextures[insideT++] = tri.t[i];
} else {
outsidePoints[outside++] = tri[i];
outsideTextures[outsideT++] = tri.t[i];
}
}
@ -62,13 +57,10 @@ int Plane::clip(Triangle &tri, Triangle &additional_tri) {
std::pair<Point4D, double> intersect1 = intersection(insidePoints[0], outsidePoints[0]);
std::pair<Point4D, double> intersect2 = intersection(insidePoints[0], outsidePoints[1]);
tri[0] = insidePoints[0];
tri.t[0] = insideTextures[0];
tri[1] = intersect1.first;
tri.t[1] = insideTextures[0] + (outsideTextures[0] - insideTextures[0]) * intersect1.second;
tri[2] = intersect2.first;
tri.t[2] = insideTextures[0] + (outsideTextures[1] - insideTextures[0]) * intersect2.second;
tri.clip = Triangle::Cropped;
@ -80,22 +72,16 @@ int Plane::clip(Triangle &tri, Triangle &additional_tri) {
std::pair<Point4D, double> intersect2 = intersection(insidePoints[1], outsidePoints[0]);
tri[0] = insidePoints[0];
tri.t[0] = insideTextures[0];
tri[1] = intersect1.first;
tri.t[1] = insideTextures[0] + (outsideTextures[0] - insideTextures[0])*intersect1.second;
tri[2] = insidePoints[1];
tri.t[2] = insideTextures[1];
additional_tri[0] = intersect1.first;
additional_tri.t[0] = insideTextures[0] + (outsideTextures[0] - insideTextures[0])*intersect1.second;
additional_tri[1] = intersect2.first;
additional_tri.t[1] = insideTextures[1] + (outsideTextures[0] - insideTextures[1])*intersect2.second;
additional_tri[2] = insidePoints[1];
additional_tri.t[2] = insideTextures[1];
tri.clip = Triangle::Doubled;
additional_tri.clip = Triangle::Doubled;

View File

@ -34,19 +34,6 @@ void Screen::display() {
std::string title = name + " (" + std::to_string(Time::fps()) + " fps)";
window.setTitle(title);
if(renderVideo || makeScreenShoot)
{
sf::Texture copyTexture;
copyTexture.create(window.getSize().x, window.getSize().y);
copyTexture.update(window);
if(makeScreenShoot)
copyTexture.copyToImage().saveToFile("../img/screen.png");
else
copyTexture.copyToImage().saveToFile("../film/png/" + std::to_string(frame++) + ".png");
makeScreenShoot = false;
}
window.display();
}
@ -54,19 +41,6 @@ void Screen::clear() {
window.clear(background);
}
void Screen::line(const Point4D& p1, const Point4D& p2, sf::Color color)
{
if (!window.isOpen())
return;
sf::Vertex line[] =
{
sf::Vertex(sf::Vector2f(p1.x(), p1.y()), color),
sf::Vertex(sf::Vector2f(p2.x(), p2.y()), color)
};
window.draw(line, 2, sf::Lines);
}
void Screen::triangle(const Triangle& triangle)
{
if(vm == Frame || vm == Borders || vm == Xray || vm == Clipped || vm == Transparency || vm == Normals) {
@ -193,13 +167,3 @@ void Screen::debugText(const std::string& text) {
window.draw(t);
}
void Screen::setRender(bool r) {
if(renderVideo && !r) {
std::string c = "ffmpeg -stats -r 60 -i ../film/png/%d.png -vcodec libx264 -crf 1 -pix_fmt yuv420p -frames " + std::to_string(frame) + " ../film/mp4/" + std::to_string(scene) + "_" + name + ".mp4";
popen(c.c_str(), "w");
frame = 0;
scene++;
}
renderVideo = r;
}

View File

@ -38,11 +38,9 @@ private:
std::string font = "../engine/fonts/Roboto-Thin.ttf";
bool renderVideo = false; // performance heavy. I use this to make sequence of .jpg files of screen and then convert this to .mp4 file
int frame = 0;
int scene = 0; // the number of scene
bool makeScreenShoot = false;
public:
sf::RenderWindow window;
@ -51,7 +49,6 @@ public:
void display();
void clear();
void line(const Point4D& p1, const Point4D& p2, sf::Color color = {0, 0, 0});
void triangle(const Triangle& triangle );
void title(const std::string& title);
@ -81,11 +78,6 @@ public:
void keyboardControl();
void debugText(const std::string& text);
void setRender(bool r);
bool isRender() const { return renderVideo; }
void makeScreen() { makeScreenShoot = true; }
};

View File

@ -33,7 +33,7 @@ Point4D Triangle::norm() const {
Point4D v1 = p[1] - p[0];
Point4D v2 = p[2] - p[0];
return v1.cross3D(v2).normalize();
return v1.cross3D(v2).normalized();
}
Point4D Triangle::operator[](int i) const {

View File

@ -20,8 +20,7 @@ public:
};
ClipMode clip = None;
sf::Color color;
Point4D p[3]; // points in space
Point4D t[3]; // texture coordinates
Point4D p[3];
Triangle ();
Triangle (const Triangle& triangle);

View File

@ -10,7 +10,7 @@
using namespace std;
void World::addMesh(const std::shared_ptr<Mesh>& mesh, const string &name) {
void World::addMesh(std::shared_ptr<Mesh> mesh, const string &name) {
_objects.emplace(name, mesh);
Log::log("World::addMesh(): inserted mesh '" + name + "' with " + std::to_string(_objects[name]->triangles().size()) + " tris.");

View File

@ -20,7 +20,7 @@ public:
[[nodiscard]] std::map<std::string, std::shared_ptr<Mesh>>& objects() { return _objects; }
void addMesh(const std::shared_ptr<Mesh>& mesh, const std::string& name = "");
void addMesh(std::shared_ptr<Mesh> mesh, const std::string& name = "");
void removeMesh(const std::string& name);
void removeMeshInstantly(const std::string& name);
void garbageCollector();

View File

@ -14,7 +14,7 @@ void Window::addButton(int x, int y, int w, int h, std::function<void()> click,
buttons.back().init();
}
void Window::update(const std::shared_ptr<Screen>& screen) {
void Window::update(std::shared_ptr<Screen> screen) {
screen->title(s_name);
screen->window.draw(back);

View File

@ -34,7 +34,7 @@ public:
void setBackgroundTexture(const std::string& texture, double sx = 1, double sy = 1, int w = 1920, int h = 1080);
void update(const std::shared_ptr<Screen>& screen);
void update(std::shared_ptr<Screen> screen);
};

View File

@ -15,7 +15,7 @@ Point4D RigidBody::_findFurthestPoint(const Point4D& direction) {
for(auto& tri : triangles()){
for(auto point : tri.p){
point += position();
point = point + position();
double distance = point.dot(direction);
if(distance > maxDistance) {
@ -27,7 +27,7 @@ Point4D RigidBody::_findFurthestPoint(const Point4D& direction) {
return maxPoint;
}
Point4D RigidBody::_support(const std::shared_ptr<RigidBody>& obj, const Point4D& direction) {
Point4D RigidBody::_support(std::shared_ptr<RigidBody> obj, const Point4D& direction) {
Point4D p1 = _findFurthestPoint(direction);
Point4D p2 = obj->_findFurthestPoint(-direction);
@ -132,10 +132,10 @@ bool RigidBody::_tetrahedron(Simplex &points, Point4D &direction) {
return true;
}
std::pair<bool, Simplex> RigidBody::checkGJKCollision(const std::shared_ptr<RigidBody>& obj) {
std::pair<bool, Simplex> RigidBody::checkGJKCollision(std::shared_ptr<RigidBody> obj) {
// Get initial support point in any direction
Point4D support = _support(obj, Point4D::unit_x());
Point4D support = _support(obj, Point4D{1, 0, 0});
// Simplex is an array of points, max count is 4
Simplex points;
@ -146,7 +146,7 @@ std::pair<bool, Simplex> RigidBody::checkGJKCollision(const std::shared_ptr<Rigi
int iterations = 0;
while (true && iterations < 50) {
while (iterations < 50) {
support = _support(obj, direction);
if (support.dot(direction) <= 0)
@ -166,7 +166,7 @@ std::pair<bool, Simplex> RigidBody::checkGJKCollision(const std::shared_ptr<Rigi
return std::make_pair(false, points); // no collision
}
CollisionPoint RigidBody::EPA(const Simplex& simplex, const std::shared_ptr<RigidBody>& obj) {
CollisionPoint RigidBody::EPA(const Simplex& simplex, std::shared_ptr<RigidBody> obj) {
std::vector<Point4D> polytope(simplex.begin(), simplex.end());
std::vector<size_t> faces = {
@ -185,7 +185,7 @@ CollisionPoint RigidBody::EPA(const Simplex& simplex, const std::shared_ptr<Rigi
int iterations = 0;
while ((minDistance == INFINITY) && (iterations < 50)) {
minNormal = normals[minFace];
minNormal = Point4D{normals[minFace].x(), normals[minFace].y(), normals[minFace].z()};
minDistance = normals[minFace].w();
Point4D support = _support(obj, minNormal);
@ -243,15 +243,15 @@ CollisionPoint RigidBody::EPA(const Simplex& simplex, const std::shared_ptr<Rigi
}
iterations++;
}
CollisionPoint points;
CollisionPoint point;
points.normal = minNormal;
points.depth = minDistance + 0.0001;
points.hasCollision = minDistance < INFINITY;
point.normal = minNormal;
point.depth = minDistance + 0.0001;
point.hasCollision = minDistance < INFINITY;
_collisionNormal = minNormal;
return points;
return point;
}
std::pair<std::vector<Point4D>, size_t> RigidBody::GetFaceNormals(const std::vector<Point4D>& polytope, const std::vector<size_t>& faces) {
@ -264,11 +264,11 @@ std::pair<std::vector<Point4D>, size_t> RigidBody::GetFaceNormals(const std::vec
Point4D b = polytope[faces[i + 1]];
Point4D c = polytope[faces[i + 2]];
Point4D normal = (b - a).cross3D(c - a).normalize();
Point4D normal = (b - a).cross3D(c - a).normalized();
double distance = normal.dot(a);
if (distance < 0) {
normal *= -1;
normal = -normal;
distance *= -1;
}
@ -303,10 +303,7 @@ void RigidBody::AddIfUniqueEdge(std::vector<std::pair<size_t, size_t>>& edges, c
void RigidBody::updatePhysicsState() {
translate(p_velocity * Time::deltaTime());
p_velocity += p_acceleration * Time::deltaTime();
rotate(p_angularVelocity * Time::deltaTime());
p_angularVelocity += p_angularAcceleration * Time::deltaTime();
p_velocity = p_velocity + p_acceleration * Time::deltaTime();
}
void RigidBody::setVelocity(const Point4D& velocity) {
@ -314,17 +311,9 @@ void RigidBody::setVelocity(const Point4D& velocity) {
}
void RigidBody::addVelocity(const Point4D &velocity) {
p_velocity += velocity;
}
void RigidBody::setAngularVelocity(const Point4D& angularVelocity) {
p_angularVelocity = angularVelocity;
p_velocity = p_velocity + velocity;
}
void RigidBody::setAcceleration(const Point4D& acceleration) {
p_acceleration = acceleration;
}
void RigidBody::setAngularAcceleration(const Point4D& angularAcceleration) {
p_angularAcceleration = angularAcceleration;
}

View File

@ -24,11 +24,6 @@ protected:
Point4D p_velocity;
Point4D p_acceleration;
Point4D p_angularVelocity;
Point4D p_angularAcceleration;
double _mass = 1.0;
bool _collision = false;
bool _isCollider = true;
@ -36,7 +31,7 @@ protected:
Point4D _collisionNormal;
Point4D _findFurthestPoint(const Point4D& direction);
Point4D _support(const std::shared_ptr<RigidBody>& obj, const Point4D& direction);
Point4D _support(std::shared_ptr<RigidBody> obj, const Point4D& direction);
static bool _nextSimplex(Simplex& points, Point4D& direction);
static bool _line(Simplex& points, Point4D& direction);
@ -50,13 +45,12 @@ public:
RigidBody() = default;
virtual ~RigidBody() = default;
std::pair<bool, Simplex> checkGJKCollision(const std::shared_ptr<RigidBody>& obj);
CollisionPoint EPA(const Simplex& simplex, const std::shared_ptr<RigidBody>& obj);
std::pair<bool, Simplex> checkGJKCollision(std::shared_ptr<RigidBody> obj);
CollisionPoint EPA(const Simplex& simplex, std::shared_ptr<RigidBody> obj);
[[nodiscard]] bool isCollision() const { return _collision; }
[[nodiscard]] bool inCollision() const {return _inCollision; }
[[nodiscard]] bool isCollider() const {return _isCollider; }
[[nodiscard]] Point4D collisionNormal() const {return _collisionNormal; }
void setInCollision(bool c) { _inCollision = c; }
void setCollisionNormal(const Point4D& c) { _collisionNormal = c; }
void setCollision(bool c) { _collision= c; }
@ -71,17 +65,10 @@ public:
void updatePhysicsState();
void setVelocity(const Point4D& velocity);
void setAngularVelocity(const Point4D& angularVelocity);
void addVelocity(const Point4D& velocity);
void setAcceleration(const Point4D& acceleration);
void setAngularAcceleration(const Point4D& angularAcceleration);
[[nodiscard]] Point4D velocity() const { return p_velocity; }
[[nodiscard]] double mass() const { return _mass; }
void setMass(double val) { _mass = val; }
};

View File

@ -5,7 +5,7 @@
#include "Solver.h"
#include "utils/Log.h"
void Solver::solveCollision(const std::shared_ptr<RigidBody>& obj1, const std::shared_ptr<RigidBody>& obj2, const CollisionPoint& collision) {
void Solver::solveCollision(std::shared_ptr<RigidBody> obj1, std::shared_ptr<RigidBody> obj2, const CollisionPoint& collision) {
if(!collision.hasCollision)
return;

View File

@ -9,7 +9,7 @@
class Solver {
public:
static void solveCollision(const std::shared_ptr<RigidBody>& obj1, const std::shared_ptr<RigidBody>& obj2, const CollisionPoint& collision);
static void solveCollision(std::shared_ptr<RigidBody> obj1, std::shared_ptr<RigidBody> obj2, const CollisionPoint& collision);
};

View File

@ -6,252 +6,62 @@
#include <cassert>
#include <cmath>
[[nodiscard]] const std::array<double, 4>& Matrix4x4::operator[] (int i) const {
return _arr_matrix[i];
}
std::array<double, 4> &Matrix4x4::operator[](int i) {
return _arr_matrix[i];
}
[[nodiscard]] Matrix4x4 Matrix4x4::operator-() const {
Matrix4x4 result(*this);
for(int i = 0; i < 4; i++)
for(int j = 0; j < 4; j++)
result[i][j] = -_arr_matrix[i][j];
return result;
}
[[nodiscard]] Matrix4x4 Matrix4x4::operator+() const {
return Matrix4x4(*this);
}
bool Matrix4x4::operator==(const Matrix4x4 &matrix4X4) const {
for(int i = 0; i < 4; i++)
for(int j = 0; j < 4; j++)
if(_arr_matrix[i][j] != matrix4X4[i][j])
return false;
return true;
}
bool Matrix4x4::operator!=(const Matrix4x4 &matrix4X4) const {
return !(*this==matrix4X4);
}
Matrix4x4 Matrix4x4::operator+(const Matrix4x4 &matrix4X4) const {
return Matrix4x4(*this) += matrix4X4;
}
Matrix4x4 Matrix4x4::operator-(const Matrix4x4 &matrix4X4) const {
return Matrix4x4(*this) -= matrix4X4;
}
Matrix4x4 Matrix4x4::operator*(const Matrix4x4 &matrix4X4) const {
return Matrix4x4(*this) *= matrix4X4;
}
Matrix4x4 Matrix4x4::operator/(const Matrix4x4 &matrix4X4) const {
return Matrix4x4(*this) /= matrix4X4;
}
Matrix4x4 &Matrix4x4::operator+=(const Matrix4x4 &matrix4X4) {
for(int i = 0; i < 4; i++)
for(int j = 0; j < 4; j++)
_arr_matrix[i][j] += matrix4X4[i][j];
return *this;
}
Matrix4x4 &Matrix4x4::operator-=(const Matrix4x4 &matrix4X4) {
(*this) += -matrix4X4;
return *this;
}
Matrix4x4 &Matrix4x4::operator*=(const Matrix4x4 &matrix4X4) {
Matrix4x4 copy(*this);
this->setZero();
Matrix4x4 result = Matrix4x4::Zero();
for(int i = 0; i < 4; i++)
for(int j = 0; j < 4; j++)
for(int k = 0; k < 4; k++)
_arr_matrix[i][j] += copy[i][k] * matrix4X4[k][j];
return *this;
}
Matrix4x4 &Matrix4x4::operator/=(const Matrix4x4 &matrix4X4) {
for(int i = 0; i < 4; i++)
for(int j = 0; j < 4; j++) {
assert(matrix4X4[i][j] != 0);
_arr_matrix[i][j] /= matrix4X4[i][j];
}
return *this;
}
Matrix4x4 Matrix4x4::operator+(double number) const {
return Matrix4x4(*this) += number;
}
Matrix4x4 Matrix4x4::operator-(double number) const {
return *this+(-number);
}
Matrix4x4 Matrix4x4::operator*(double number) const {
return Matrix4x4(*this) *= number;
}
Matrix4x4 Matrix4x4::operator/(double number) const {
assert(number != 0);
return *this*(1.0/number);
}
Matrix4x4 &Matrix4x4::operator+=(double number) {
for(int i = 0; i < 4; i++)
for(int j = 0; j < 4; j++)
_arr_matrix[i][j] += number;
return *this;
}
Matrix4x4 &Matrix4x4::operator-=(double number) {
return (*this) += -number;
}
Matrix4x4 &Matrix4x4::operator*=(double number) {
for(int i = 0; i < 4; i++)
for(int j = 0; j < 4; j++)
_arr_matrix[i][j] *= number;
return *this;
}
Matrix4x4 &Matrix4x4::operator/=(double number) {
return (*this) *= 1.0/number;
result._arr[i][j] += _arr[i][k] * matrix4X4._arr[k][j];
return result;
}
Point4D Matrix4x4::operator*(const Point4D &point4D) const {
return Point4D(
_arr_matrix[0][0] * point4D.x() + _arr_matrix[0][1] * point4D.y() + _arr_matrix[0][2] * point4D.z() + _arr_matrix[0][3] * point4D.w(),
_arr_matrix[1][0] * point4D.x() + _arr_matrix[1][1] * point4D.y() + _arr_matrix[1][2] * point4D.z() + _arr_matrix[1][3] * point4D.w(),
_arr_matrix[2][0] * point4D.x() + _arr_matrix[2][1] * point4D.y() + _arr_matrix[2][2] * point4D.z() + _arr_matrix[2][3] * point4D.w(),
_arr_matrix[3][0] * point4D.x() + _arr_matrix[3][1] * point4D.y() + _arr_matrix[3][2] * point4D.z() + _arr_matrix[3][3] * point4D.w()
_arr[0][0] * point4D.x() + _arr[0][1] * point4D.y() + _arr[0][2] * point4D.z() + _arr[0][3] * point4D.w(),
_arr[1][0] * point4D.x() + _arr[1][1] * point4D.y() + _arr[1][2] * point4D.z() + _arr[1][3] * point4D.w(),
_arr[2][0] * point4D.x() + _arr[2][1] * point4D.y() + _arr[2][2] * point4D.z() + _arr[2][3] * point4D.w(),
_arr[3][0] * point4D.x() + _arr[3][1] * point4D.y() + _arr[3][2] * point4D.z() + _arr[3][3] * point4D.w()
);
}
double Matrix4x4::det3D() {
return _arr_matrix[0][0] * (_arr_matrix[1][1] * _arr_matrix[2][2] - _arr_matrix[1][2] * _arr_matrix[2][1]) -
_arr_matrix[0][1] * (_arr_matrix[1][0] * _arr_matrix[2][2] - _arr_matrix[1][2] * _arr_matrix[2][0]) +
_arr_matrix[0][2] * (_arr_matrix[1][0] * _arr_matrix[2][1] - _arr_matrix[2][0] * _arr_matrix[1][1]);
}
Matrix4x4 Matrix4x4::Identity() {
Matrix4x4 result;
Matrix4x4 Matrix4x4::inv3D() {
double det = det3D();
assert(det != 0);
Matrix4x4 result{};
result[3][3] = 1.0;
result[0][0] = _arr_matrix[1][1] * _arr_matrix[2][2] - _arr_matrix[2][1] * _arr_matrix[1][2];
result[1][0] = _arr_matrix[0][1] * _arr_matrix[2][2] - _arr_matrix[2][1] * _arr_matrix[0][2];
result[2][0] = _arr_matrix[0][1] * _arr_matrix[1][2] - _arr_matrix[1][1] * _arr_matrix[0][2];
result[0][1] = _arr_matrix[1][0] * _arr_matrix[2][2] - _arr_matrix[2][0] * _arr_matrix[1][2];
result[1][1] = _arr_matrix[0][0] * _arr_matrix[2][2] - _arr_matrix[2][0] * _arr_matrix[0][2];
result[2][1] = _arr_matrix[0][0] * _arr_matrix[1][2] - _arr_matrix[1][0] * _arr_matrix[0][2];
result[0][2] = _arr_matrix[1][0] * _arr_matrix[2][1] - _arr_matrix[2][0] * _arr_matrix[1][1];
result[1][2] = _arr_matrix[0][0] * _arr_matrix[2][1] - _arr_matrix[2][0] * _arr_matrix[0][1];
result[2][2] = _arr_matrix[0][0] * _arr_matrix[1][1] - _arr_matrix[1][0] * _arr_matrix[0][1];
return result /= det;
}
Matrix4x4 &Matrix4x4::transpose() {
Matrix4x4 result{};
for(int i = 0; i < 4; i++)
for(int j = 0; j < 4; j++)
result[i][j] = _arr_matrix[j][i];
*this = result;
return *this;
}
Matrix4x4 &Matrix4x4::setIdentity() {
for(int i = 0; i < 4; i++)
for(int j = 0; j < 4; j++)
if(i == j)
_arr_matrix[j][i] = 1.0;
result._arr[j][i] = 1.0;
else
_arr_matrix[j][i] = 0.0;
return *this;
}
result._arr[j][i] = 0.0;
Matrix4x4 &Matrix4x4::setOnes() {
setConstants(1.0);
return *this;
}
Matrix4x4 &Matrix4x4::setZero() {
setConstants(0.0);
return *this;
}
Matrix4x4 &Matrix4x4::setConstants(double value) {
for(int i = 0; i < 4; i++)
for(int j = 0; j < 4; j++)
_arr_matrix[j][i] = value;
return *this;
}
const std::array<std::array<double, 4>, 4> &Matrix4x4::data() const {
return _arr_matrix;
}
std::array<std::array<double, 4>, 4> &Matrix4x4::data() {
return _arr_matrix;
}
Matrix4x4 Matrix4x4::Identity() {
return Matrix4x4().setIdentity();
}
Matrix4x4 Matrix4x4::Zero() {
return Matrix4x4();
return result;
}
Matrix4x4 Matrix4x4::Constant(double value) {
return Matrix4x4().setConstants(value);
Matrix4x4 result;
for(int i = 0; i < 4; i++)
for(int j = 0; j < 4; j++)
result._arr[j][i] = value;
return result;
}
Matrix4x4 Matrix4x4::Scale(double sx, double sy, double sz) {
Matrix4x4 Matrix4x4::Zero() {
return Matrix4x4::Constant(0);
}
Matrix4x4 Matrix4x4::Scale(const Point4D& factor) {
Matrix4x4 s{};
s[0][0] = sx;
s[1][1] = sy;
s[2][2] = sz;
s[3][3] = 1;
s._arr[0][0] = factor.x();
s._arr[1][1] = factor.y();
s._arr[2][2] = factor.z();
s._arr[3][3] = 1;
return s;
}
Matrix4x4 Matrix4x4::Translation(double dx, double dy, double dz) {
Matrix4x4 t{};
/*
* ( 1 0 0 dx )(x) (x + dx)
* ( 0 1 0 dy )(y) = (y + dy)
* ( 0 0 1 dz )(z) (z + dz)
* ( 0 0 0 1 )(1) ( 1 )
*/
t[0][0] = 1.0;
t[1][1] = 1.0;
t[2][2] = 1.0;
t[3][3] = 1.0;
t[0][3] = dx;
t[1][3] = dy;
t[2][3] = dz;
return t;
}
Matrix4x4 Matrix4x4::Translation(const Point4D& v) {
Matrix4x4 t{};
/*
@ -261,28 +71,28 @@ Matrix4x4 Matrix4x4::Translation(const Point4D& v) {
* ( 0 0 0 1 )(1) ( 1 )
*/
t[0][0] = 1.0;
t[1][1] = 1.0;
t[2][2] = 1.0;
t[3][3] = 1.0;
t._arr[0][0] = 1.0;
t._arr[1][1] = 1.0;
t._arr[2][2] = 1.0;
t._arr[3][3] = 1.0;
t[0][3] = v.x();
t[1][3] = v.y();
t[2][3] = v.z();
t._arr[0][3] = v.x();
t._arr[1][3] = v.y();
t._arr[2][3] = v.z();
return t;
}
Matrix4x4 Matrix4x4::RotationX(double rx) {
Matrix4x4 Rx{};
Rx[0][0] = 1.0;
Rx._arr[0][0] = 1.0;
Rx[1][1] = cos(rx);
Rx[1][2] = -sin(rx);
Rx[2][1] = sin(rx);
Rx[2][2] = cos(rx);
Rx._arr[1][1] = cos(rx);
Rx._arr[1][2] = -sin(rx);
Rx._arr[2][1] = sin(rx);
Rx._arr[2][2] = cos(rx);
Rx[3][3] = 1.0;
Rx._arr[3][3] = 1.0;
return Rx;
}
@ -290,14 +100,14 @@ Matrix4x4 Matrix4x4::RotationX(double rx) {
Matrix4x4 Matrix4x4::RotationY(double ry) {
Matrix4x4 Ry{};
Ry[1][1] = 1.0;
Ry._arr[1][1] = 1.0;
Ry[0][0] = cos(ry);
Ry[0][2] = sin(ry);
Ry[2][0] = -sin(ry);
Ry[2][2] = cos(ry);
Ry._arr[0][0] = cos(ry);
Ry._arr[0][2] = sin(ry);
Ry._arr[2][0] = -sin(ry);
Ry._arr[2][2] = cos(ry);
Ry[3][3] = 1.0;
Ry._arr[3][3] = 1.0;
return Ry;
}
@ -305,39 +115,39 @@ Matrix4x4 Matrix4x4::RotationY(double ry) {
Matrix4x4 Matrix4x4::RotationZ(double rz) {
Matrix4x4 Rz{};
Rz[2][2] = 1.0;
Rz._arr[2][2] = 1.0;
Rz[0][0] = cos(rz);
Rz[0][1] = -sin(rz);
Rz[1][0] = sin(rz);
Rz[1][1] = cos(rz);
Rz._arr[0][0] = cos(rz);
Rz._arr[0][1] = -sin(rz);
Rz._arr[1][0] = sin(rz);
Rz._arr[1][1] = cos(rz);
Rz[3][3] = 1.0;
Rz._arr[3][3] = 1.0;
return Rz;
}
Matrix4x4 Matrix4x4::Rotation(double rx, double ry, double rz) {
return RotationX(rx) * RotationY(ry) * RotationZ(rz);
Matrix4x4 Matrix4x4::Rotation(const Point4D& r) {
return RotationX(r.x()) * RotationY(r.y()) * RotationZ(r.z());
}
Matrix4x4 Matrix4x4::Rotation(Point4D v, double rv) {
Matrix4x4 Rv{};
v.normalize();
v = v.normalized();
Rv[0][0] = cos(rv) + (1.0 - cos(rv))*v.x()*v.x();
Rv[0][1] = (1.0 - cos(rv))*v.x()*v.y() - sin(rv)*v.z();
Rv[0][2] = (1.0 - cos(rv))*v.x()*v.z() + sin(rv)*v.y();
Rv._arr[0][0] = cos(rv) + (1.0 - cos(rv))*v.x()*v.x();
Rv._arr[0][1] = (1.0 - cos(rv))*v.x()*v.y() - sin(rv)*v.z();
Rv._arr[0][2] = (1.0 - cos(rv))*v.x()*v.z() + sin(rv)*v.y();
Rv[1][0] = (1.0 - cos(rv))*v.x()*v.y() + sin(rv)*v.z();
Rv[1][1] = cos(rv) + (1.0 - cos(rv))*v.y()*v.y();
Rv[1][2] = (1.0 - cos(rv))*v.y()*v.z() - sin(rv)*v.x();
Rv._arr[1][0] = (1.0 - cos(rv))*v.x()*v.y() + sin(rv)*v.z();
Rv._arr[1][1] = cos(rv) + (1.0 - cos(rv))*v.y()*v.y();
Rv._arr[1][2] = (1.0 - cos(rv))*v.y()*v.z() - sin(rv)*v.x();
Rv[2][0] = (1.0 - cos(rv))*v.z()*v.x() - sin(rv)*v.y();
Rv[2][1] = (1.0 - cos(rv))*v.z()*v.y() + sin(rv)*v.x();
Rv[2][2] = cos(rv) + (1.0 - cos(rv))*v.z()*v.z();
Rv._arr[2][0] = (1.0 - cos(rv))*v.z()*v.x() - sin(rv)*v.y();
Rv._arr[2][1] = (1.0 - cos(rv))*v.z()*v.y() + sin(rv)*v.x();
Rv._arr[2][2] = cos(rv) + (1.0 - cos(rv))*v.z()*v.z();
Rv[3][3] = 1.0;
Rv._arr[3][3] = 1.0;
return Rv;
}
@ -347,11 +157,11 @@ Matrix4x4 Matrix4x4::Rotation(Point4D v, double rv) {
Matrix4x4 Matrix4x4::Projection(double fov, double aspect, double ZNear, double ZFar) {
Matrix4x4 p{};
p[0][0] = 1.0/(tan(M_PI*fov*0.5/180.0)*aspect);
p[1][1] = 1.0/tan(M_PI*fov*0.5/180.0);
p[2][2] = ZFar/(ZFar - ZNear);
p[2][3] = -ZFar*ZNear/(ZFar - ZNear);
p[3][2] = 1.0;
p._arr[0][0] = 1.0/(tan(M_PI*fov*0.5/180.0)*aspect);
p._arr[1][1] = 1.0/tan(M_PI*fov*0.5/180.0);
p._arr[2][2] = ZFar/(ZFar - ZNear);
p._arr[2][3] = -ZFar*ZNear/(ZFar - ZNear);
p._arr[3][2] = 1.0;
return p;
}
@ -359,72 +169,37 @@ Matrix4x4 Matrix4x4::Projection(double fov, double aspect, double ZNear, double
Matrix4x4 Matrix4x4::ScreenSpace(int width, int height) {
Matrix4x4 s{};
s[0][0] = -0.5*width;
s[1][1] = -0.5*height;
s[2][2] = 1.0;
s._arr[0][0] = -0.5*width;
s._arr[1][1] = -0.5*height;
s._arr[2][2] = 1.0;
s[0][3] = 0.5*width;
s[1][3] = 0.5*height;
s._arr[0][3] = 0.5*width;
s._arr[1][3] = 0.5*height;
s[3][3] = 1.0;
s._arr[3][3] = 1.0;
return s;
}
Matrix4x4 Matrix4x4::View(const Point4D &left, const Point4D &up, const Point4D &lookAt, const Point4D &eye) {
Matrix4x4 V{};
Matrix4x4 V = Zero();
V.setZero();
V._arr[0][0] = left[0];
V._arr[0][1] = left[1];
V._arr[0][2] = left[2];
V._arr[0][3] = -eye.dot(left);
V[0][0] = left[0];
V[0][1] = left[1];
V[0][2] = left[2];
V[0][3] = -eye.dot(left);
V._arr[1][0] = up[0];
V._arr[1][1] = up[1];
V._arr[1][2] = up[2];
V._arr[1][3] = -eye.dot(up);
V[1][0] = up[0];
V[1][1] = up[1];
V[1][2] = up[2];
V[1][3] = -eye.dot(up);
V._arr[2][0] = lookAt[0];
V._arr[2][1] = lookAt[1];
V._arr[2][2] = lookAt[2];
V._arr[2][3] = -eye.dot(lookAt);
V[2][0] = lookAt[0];
V[2][1] = lookAt[1];
V[2][2] = lookAt[2];
V[2][3] = -eye.dot(lookAt);
V[3][3] = 1.0;
V._arr[3][3] = 1.0;
return V;
}
Matrix4x4 Matrix4x4::ViewInverse(const Point4D &left, const Point4D &up, const Point4D &lookAt, const Point4D &eye) {
Matrix4x4 inv{};
inv.setZero();
inv[0][0] = left[0];
inv[1][0] = left[1];
inv[2][0] = left[2];
inv[0][3] = eye[0];
inv[0][1] = up[0];
inv[1][1] = up[1];
inv[2][1] = up[2];
inv[1][3] = eye[1];
inv[0][2] = lookAt[0];
inv[1][2] = lookAt[1];
inv[2][2] = lookAt[2];
inv[2][3] = eye[2];
inv[3][3] = 1.0;
return inv;
}
Matrix4x4 Matrix4x4::Rotation(const Point4D &v) {
return RotationX(v.x())*RotationY(v.y())*RotationZ(v.z());
}
Matrix4x4 Matrix4x4::Scale(const Point4D &s) {
return Matrix4x4::Scale(s.x(), s.y(), s.z());
}

View File

@ -10,76 +10,28 @@
class Matrix4x4 {
private:
std::array<std::array<double, 4>, 4> _arr_matrix{};
std::array<std::array<double, 4>, 4> _arr{};
public:
Matrix4x4 () = default;
Matrix4x4& operator=(const Matrix4x4& matrix4X4) = default;
[[nodiscard]] const std::array<double, 4>& operator[] (int i) const;
[[nodiscard]] std::array<double, 4>& operator[] (int i);
[[nodiscard]] Matrix4x4 operator-() const;
[[nodiscard]] Matrix4x4 operator+() const;
// Boolean operations
bool operator==(const Matrix4x4& matrix4X4) const;
bool operator!=(const Matrix4x4& matrix4X4) const;
// Operations with Matrix4x4
[[nodiscard]] Matrix4x4 operator+(const Matrix4x4& matrix4X4) const;
[[nodiscard]] Matrix4x4 operator-(const Matrix4x4& matrix4X4) const;
[[nodiscard]] Matrix4x4 operator*(const Matrix4x4& matrix4X4) const;
[[nodiscard]] Matrix4x4 operator/(const Matrix4x4& matrix4X4) const;
Matrix4x4& operator+=(const Matrix4x4& matrix4X4);
Matrix4x4& operator-=(const Matrix4x4& matrix4X4);
Matrix4x4& operator*=(const Matrix4x4& matrix4X4);
Matrix4x4& operator/=(const Matrix4x4& matrix4X4);
// Operations with numbers
[[nodiscard]] Matrix4x4 operator+(double number) const;
[[nodiscard]] Matrix4x4 operator-(double number) const;
[[nodiscard]] Matrix4x4 operator*(double number) const;
[[nodiscard]] Matrix4x4 operator/(double number) const;
Matrix4x4& operator+=(double number);
Matrix4x4& operator-=(double number);
Matrix4x4& operator*=(double number);
Matrix4x4& operator/=(double number);
// Operations with Point4D
[[nodiscard]] Point4D operator*(const Point4D& point4D) const;
// Other useful methods
[[nodiscard]] double det3D();
[[nodiscard]] Matrix4x4 inv3D();
Matrix4x4& transpose();
Matrix4x4& setIdentity();
Matrix4x4& setOnes();
Matrix4x4& setZero();
Matrix4x4& setConstants(double value);
[[nodiscard]] const std::array<std::array<double, 4>, 4> & data() const;
[[nodiscard]] std::array<std::array<double, 4>, 4> & data();
// Any useful matrix
// Any useful matrix (static methods)
Matrix4x4 static Identity();
Matrix4x4 static Zero();
Matrix4x4 static Constant (double value);
Matrix4x4 static Scale(double sx, double sy, double sz);
Matrix4x4 static Scale(const Point4D& s);
Matrix4x4 static Translation(double dx, double dy, double dz);
Matrix4x4 static Scale(const Point4D& factor);
Matrix4x4 static Translation(const Point4D& v);
Matrix4x4 static Rotation(const Point4D& r);
Matrix4x4 static RotationX (double rx);
Matrix4x4 static RotationY (double ry);
Matrix4x4 static RotationZ (double rz);
Matrix4x4 static Rotation (double rx, double ry, double rz);
Matrix4x4 static Rotation (Point4D v, double rv);
Matrix4x4 static View(const Point4D& left, const Point4D& up, const Point4D& lookAt, const Point4D& eye);
Matrix4x4 static ViewInverse(const Point4D& left, const Point4D& up, const Point4D& lookAt, const Point4D& eye);
Matrix4x4 static Projection (double fov = 90.0, double aspect = 1.0, double ZNear = 1.0, double ZFar = 10.0);
Matrix4x4 static ScreenSpace (int width, int height);
};

View File

@ -19,32 +19,14 @@ Point4D::Point4D(const Point4D &point4D) {
_arr_point[3] = point4D.w();
}
Point4D &Point4D::operator=(const Point4D &point4D) {
if (&point4D != this)
{
_arr_point[0] = point4D.x();
_arr_point[1] = point4D.y();
_arr_point[2] = point4D.z();
_arr_point[3] = point4D.w();
}
return *this;
}
[[nodiscard]] double Point4D::operator[] (int i) const {
return _arr_point[i];
}
[[nodiscard]] double& Point4D::operator[] (int i) {
return _arr_point[i];
}
[[nodiscard]] Point4D Point4D::operator-() const {
return Point4D(-x(), -y(), -z(), -w());
}
[[nodiscard]] Point4D Point4D::operator+() const {
return Point4D(*this);
}
// Boolean operations
bool Point4D::operator==(const Point4D& point4D) const
{
return this == &point4D || (*this - point4D).sqrAbs() < 0.0000000001;
@ -55,98 +37,31 @@ bool Point4D::operator!=(const Point4D& point4D) const
}
// Operations with Point4D
Point4D Point4D::operator+(const Point4D& point4D) const
{
return Point4D(*this) += point4D;
Point4D Point4D::operator+(const Point4D& point4D) const {
return Point4D(x()+point4D.x(), y()+point4D.y(), z()+point4D.z(), w()+point4D.w());
}
Point4D Point4D::operator-(const Point4D& point4D) const
{
return Point4D(*this) -= point4D;
}
Point4D Point4D::operator*(const Point4D& point4D) const
{
return Point4D(*this) *= point4D;
}
Point4D Point4D::operator/(const Point4D& point4D) const
{
return Point4D(*this) /= point4D;
Point4D Point4D::operator-(const Point4D& point4D) const {
return Point4D(*this) + -point4D;
}
Point4D& Point4D::operator+=(const Point4D& point4D)
{
_arr_point[0] += point4D.x();
_arr_point[1] += point4D.y();
_arr_point[2] += point4D.z();
_arr_point[3] += point4D.w();
return *this;
}
Point4D& Point4D::operator-=(const Point4D& point4D)
{
(*this) += -point4D;
return *this;
}
Point4D& Point4D::operator*=(const Point4D& point4D) {
_arr_point[0] *= point4D.x();
_arr_point[1] *= point4D.y();
_arr_point[2] *= point4D.z();
_arr_point[3] *= point4D.w();
return *this;
}
Point4D& Point4D::operator/=(const Point4D& point4D) {
_arr_point[0] /= point4D.x();
_arr_point[1] /= point4D.y();
_arr_point[2] /= point4D.z();
_arr_point[3] /= point4D.w();
return *this;
}
double Point4D::dot(const Point4D& point4D) const
{
return point4D.x() * x() + point4D.y() * y() + point4D.z() * z() + point4D.w() * w();
}
[[nodiscard]] Point4D Point4D::cross3D(const Point4D& point4D) const {
Point4D cross{y() * point4D.z() - point4D.y() * z(),
z() * point4D.x() - point4D.z() * x(),
x() * point4D.y() - point4D.x() * y()};
return cross;
return Point4D {y() * point4D.z() - point4D.y() * z(),
z() * point4D.x() - point4D.z() * x(),
x() * point4D.y() - point4D.x() * y()};
}
// Operations with numbers
Point4D Point4D::operator+(double number) const {
return Point4D(*this) += number;
Point4D Point4D::operator*(double number) const {
return Point4D(x()*number, y()*number, z()*number, w()*number);
}
Point4D Point4D::operator-(double number) const {
return Point4D(*this) -= number;
}
Point4D Point4D::operator*(double number) const
{
return Point4D(*this) *= number;
}
Point4D Point4D::operator/(double number) const
{
return Point4D(*this) /= number;
}
Point4D& Point4D::operator+=(double number) {
_arr_point[0] += number;
_arr_point[1] += number;
_arr_point[2] += number;
_arr_point[3] += number;
return *this;
}
Point4D& Point4D::operator-=(double number) {
return *this += -number;
}
Point4D& Point4D::operator*=(double number)
{
_arr_point[0] *= number;
_arr_point[1] *= number;
_arr_point[2] *= number;
_arr_point[3] *= number;
return *this;
}
Point4D& Point4D::operator/=(double number)
{
return *this *= 1.0/number;
Point4D Point4D::operator/(double number) const {
if(number != 0)
return Point4D(*this)*(1.0/number);
else
return Point4D();
}
// Other useful methods
@ -154,22 +69,10 @@ double Point4D::sqrAbs() const
{
return x()*x() + y()*y() + z()*z() + w()*w();
}
double Point4D::abs() const
{
double Point4D::abs() const {
return sqrt(sqrAbs());
}
Point4D& Point4D::normalize()
{
double length = this->abs();
_arr_point[0] /= length;
_arr_point[1] /= length;
_arr_point[2] /= length;
_arr_point[3] /= length;
return *this;
}
Point4D Point4D::normalized() const {
Point4D res(*this);
return res.normalize();
return Point4D(*this)/abs();
}

View File

@ -15,18 +15,15 @@ public:
Point4D () = default;
Point4D (const Point4D& point4D);
explicit Point4D (double x, double y = 0.0, double z = 0.0, double w = 0.0);
Point4D& operator=(const Point4D& point4D);
[[nodiscard]] double x() const{ return _arr_point[0]; }
[[nodiscard]] double y() const{ return _arr_point[1]; }
[[nodiscard]] double z() const{ return _arr_point[2]; }
[[nodiscard]] double w() const{ return _arr_point[3]; }
[[nodiscard]] double x() const { return _arr_point[0]; }
[[nodiscard]] double y() const { return _arr_point[1]; }
[[nodiscard]] double z() const { return _arr_point[2]; }
[[nodiscard]] double w() const { return _arr_point[3]; }
[[nodiscard]] double operator[] (int i) const;
[[nodiscard]] double& operator[] (int i);
[[nodiscard]] Point4D operator-() const;
[[nodiscard]] Point4D operator+() const;
// Boolean operations
bool operator==(const Point4D& point4D) const;
@ -35,38 +32,18 @@ public:
// Operations with Point4D
[[nodiscard]] Point4D operator+(const Point4D& point4D) const;
[[nodiscard]] Point4D operator-(const Point4D& point4D) const;
[[nodiscard]] Point4D operator*(const Point4D& point4D) const;
[[nodiscard]] Point4D operator/(const Point4D& point4D) const;
Point4D& operator+=(const Point4D& point4D);
Point4D& operator-=(const Point4D& point4D);
Point4D& operator*=(const Point4D& point4D);
Point4D& operator/=(const Point4D& point4D);
[[nodiscard]] double dot(const Point4D& point4D) const; // Returns dot product
[[nodiscard]] Point4D cross3D(const Point4D& point4D) const; // Returns cross product
// Operations with numbers
[[nodiscard]] Point4D operator+(double number) const;
[[nodiscard]] Point4D operator-(double number) const;
[[nodiscard]] Point4D operator*(double number) const;
[[nodiscard]] Point4D operator/(double number) const;
Point4D& operator+=(double number);
Point4D& operator-=(double number);
Point4D& operator*=(double number);
Point4D& operator/=(double number);
// Other useful methods
[[nodiscard]] double sqrAbs() const; // Returns squared vector length
[[nodiscard]] double abs() const; // Returns vector length
Point4D& normalize(); // Normalize vector and returns
[[nodiscard]] Point4D normalized() const; // Returns normalized vector without changing
static Point4D unit_x() {return Point4D{1, 0, 0, 0}; }
static Point4D unit_y() {return Point4D{0, 1, 0, 0}; }
static Point4D unit_z() {return Point4D{0, 0, 1, 0}; }
};
#endif //INC_3DZAVR_POINT4D_H

View File

@ -16,7 +16,7 @@ using namespace std;
// Read server/client settings and start both.
// If client doesn't connect to the localhost - server doesn't start.
void InitNetwork(const shared_ptr<Server>& server, const shared_ptr<Client>& client)
void InitNetwork(shared_ptr<Server> server, shared_ptr<Client> client)
{
std::string clientIp;
sf::Uint16 clientPort;

View File

View File

@ -23,7 +23,7 @@ Shotgun::Shotgun(int ammo, const std::string& weaponName) : Weapon(weaponName, "
}
std::map<std::string, double>
Shotgun::processFire(const std::shared_ptr<World> &world, const std::shared_ptr<Camera> &camera) {
Shotgun::processFire(std::shared_ptr<World> world, std::shared_ptr<Camera> camera) {
std::map<std::string, double> damagedPlayers;
for(int i = 0; i < 15; i++) {

View File

@ -10,7 +10,7 @@
class Shotgun : public Weapon {
public:
explicit Shotgun(int ammo = 15, const std::string& weaponName = "shotgun");
std::map<std::string, double> processFire(const std::shared_ptr<World>& world, const std::shared_ptr<Camera>& camera) override;
std::map<std::string, double> processFire(std::shared_ptr<World> world, std::shared_ptr<Camera> camera) override;
};

View File

@ -25,7 +25,7 @@ Weapon::Weapon(const std::string& weaponName, const std::string& objFileName, co
noAmmoSound.setBuffer(*ResourceManager::loadSoundBuffer("../sound/weapons/no_ammo.ogg"));
}
std::map<std::string, double> Weapon::fire(const std::shared_ptr<World>& world, const std::shared_ptr<Camera>& camera) {
std::map<std::string, double> Weapon::fire(std::shared_ptr<World> world, std::shared_ptr<Camera> camera) {
if(_clipAmmo == 0) {
reload();
if(_clipAmmo == 0)
@ -60,13 +60,13 @@ void Weapon::reload() {
_lastReloadTime = Time::time();
}
void Weapon::addToWorld(const shared_ptr<World> &world) {
void Weapon::addToWorld(shared_ptr<World> world) {
for(auto& obj : _objects) {
world->addMesh(obj.second, obj.first);
}
}
void Weapon::removeFromWorld(const shared_ptr<World> &world) {
void Weapon::removeFromWorld(shared_ptr<World> world) {
for(auto& obj : _objects) {
world->removeMeshInstantly(obj.first);
}
@ -89,7 +89,7 @@ void Weapon::translate(const Point4D &point4D) {
mesh.second->translate(point4D);
}
void Weapon::deleteTrace(const shared_ptr<World> &world, const std::string& traceName) {
void Weapon::deleteTrace(shared_ptr<World> world, const std::string& traceName) {
world->removeMesh(traceName);
}
@ -98,7 +98,7 @@ void Weapon::rotateRelativePoint(const Point4D &point4D, const Point4D &v, doubl
mesh.second->rotateRelativePoint(point4D, v, val);
}
std::map<std::string, double> Weapon::processFire(const shared_ptr<World> &world, const shared_ptr<Camera> &camera) {
std::map<std::string, double> Weapon::processFire(shared_ptr<World> world, shared_ptr<Camera> camera) {
std::map<std::string, double> damagedPlayers;
//generate random vector

View File

@ -37,7 +37,7 @@ protected:
sf::Sound reloadSound;
sf::Sound noAmmoSound;
static void deleteTrace(const std::shared_ptr<World> &world, const std::string& traceName);
static void deleteTrace(std::shared_ptr<World> world, const std::string& traceName);
int fireTraces = 0;
@ -46,11 +46,11 @@ protected:
public:
Weapon(const std::string& weaponName, const std::string& objFileName, const std::string& matFileName, const Point4D& scale, const Point4D& translate, const Point4D& rotate);
std::map<std::string, double> fire(const std::shared_ptr<World>& world, const std::shared_ptr<Camera>& camera);
std::map<std::string, double> fire(std::shared_ptr<World> world, std::shared_ptr<Camera> camera);
void reload();
void addToWorld(const std::shared_ptr<World>& world);
void removeFromWorld(const std::shared_ptr<World>& world);
void addToWorld(std::shared_ptr<World> world);
void removeFromWorld(std::shared_ptr<World> world);
void attachToPlayer(Mesh& player);
@ -69,7 +69,7 @@ public:
void addAmmo(int ammoAdd) { _stockAmmo += ammoAdd; }
virtual std::map<std::string, double> processFire(const std::shared_ptr<World>& world, const std::shared_ptr<Camera>& camera);
virtual std::map<std::string, double> processFire(std::shared_ptr<World> world, std::shared_ptr<Camera> camera);
[[nodiscard]] int initialPack() const {return _initialPack; }
};