This commit is contained in:
IXtreme 2025-08-15 22:19:30 -04:00
parent 0db35dc0b2
commit 4f206dfa99
4 changed files with 560 additions and 298 deletions

View file

@ -6,3 +6,27 @@ Size=400,400
Pos=158,170
Size=316,183
[Window][peak]
Pos=60,60
Size=344,200
[Window][0]
Pos=245,24
Size=436,96
[Window][1]
Pos=54,171
Size=68,54
[Window][2]
Pos=243,100
Size=68,54
[Window][3]
Pos=60,60
Size=68,54
[Window][4]
Pos=60,60
Size=68,54

View file

@ -7,7 +7,9 @@
#include <cmath>
#include <cstdio>
#include <iostream>
#include <optional>
#include <ostream>
#include <vector>
#define IMGUI_DEFINE_MATH_OPERATORS
#include "imgui.h"
#include "imgui_stdlib.h"
@ -27,294 +29,446 @@ extern "C" {
}
class RayWindow {
public:
bool Open = false;
public:
bool Open = false;
RenderTexture ViewTexture;
RenderTexture ViewTexture;
virtual void Setup() = 0;
virtual void Shutdown() = 0;
virtual void Show() = 0;
virtual void Update() = 0;
virtual void Setup() = 0;
virtual void Shutdown() = 0;
virtual void Show() = 0;
virtual void Update() = 0;
bool Focused = false;
bool Focused = false;
Rectangle ContentRect = {0};
Rectangle ContentRect = {0};
};
class RayWindowExample {
public:
RenderTexture ViewTexture;
bool Open = true;
bool Focused = false;
bool Resized = false;
ImVec2 PastSize;
RayWindowExample() {
ViewTexture = LoadRenderTexture(GetScreenWidth(), GetScreenWidth());
// ViewTexture = LoadRenderTexture(256, 256);
printf("window w,h: %d, %d \n", ViewTexture.texture.width, ViewTexture.texture.height);
PastSize = ImVec2{256, 256};
Resized = false;
}
~RayWindowExample() {
UnloadRenderTexture(ViewTexture);
}
void Show() {
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
ImGui::SetNextWindowSize(ImVec2(256, 275), ImGuiCond_FirstUseEver);
if (ImGui::Begin("Raylib in ImGUI", &Open, ImGuiWindowFlags_NoScrollbar)) {
Focused = ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows);
ImVec2 DaZone = ImGui::GetContentRegionAvail();
rlImGuiImageRenderTexture(&ViewTexture);
// rlImGuiImage(&ViewTexture.texture);
if (PastSize != DaZone) {
Resized = true;
} else {
Resized = false;
}
PastSize = DaZone;
}
ImGui::End();
ImGui::PopStyleVar();
}
void Update() {
if (!Open) {
return;
}
if (Resized) {
UnloadRenderTexture(ViewTexture);
ViewTexture = LoadRenderTexture(PastSize.x, PastSize.y);
}
public:
RenderTexture ViewTexture;
bool Open = true;
bool Focused = false;
bool Resized = false;
ImVec2 PastSize;
RayWindowExample() {
ViewTexture = LoadRenderTexture(GetScreenWidth(), GetScreenWidth());
// ViewTexture = LoadRenderTexture(256, 256);
printf("window w,h: %d, %d \n", ViewTexture.texture.width, ViewTexture.texture.height);
PastSize = ImVec2{256, 256};
Resized = false;
}
~RayWindowExample() {
UnloadRenderTexture(ViewTexture);
}
void Show() {
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
ImGui::SetNextWindowSize(ImVec2(256, 275), ImGuiCond_FirstUseEver);
if (ImGui::Begin("Raylib in ImGUI", &Open, ImGuiWindowFlags_NoScrollbar)) {
Focused = ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows);
ImVec2 DaZone = ImGui::GetContentRegionAvail();
rlImGuiImageRenderTexture(&ViewTexture);
// rlImGuiImage(&ViewTexture.texture);
if (PastSize != DaZone) {
Resized = true;
} else {
Resized = false;
}
PastSize = DaZone;
}
ImGui::End();
ImGui::PopStyleVar();
}
void Update() {
if (!Open) {
return;
}
if (Resized) {
UnloadRenderTexture(ViewTexture);
ViewTexture = LoadRenderTexture(PastSize.x, PastSize.y);
}
BeginTextureMode(ViewTexture);
ClearBackground(SKYBLUE);
DrawCircle(0, 0, 35, RED);
// DrawPixel(0,0, BLUE);
// DrawRectangleLines(0,0,PastSize.x,PastSize.y, RED);
Rectangle rec = Rectangle{0, 0, PastSize.x, PastSize.y};
// DrawRectangleLinesEx(rec, 2, RED);
EndTextureMode();
}
BeginTextureMode(ViewTexture);
ClearBackground(SKYBLUE);
DrawCircle(0, 0, 35, RED);
// DrawPixel(0,0, BLUE);
// DrawRectangleLines(0,0,PastSize.x,PastSize.y, RED);
Rectangle rec = Rectangle{0, 0, PastSize.x, PastSize.y};
// DrawRectangleLinesEx(rec, 2, RED);
EndTextureMode();
}
};
std::ostream &operator<<(std::ostream &os, const Vector3 &obj) {
os << "x: " << obj.x << " y: " << obj.y << " z: " << obj.z;
return os;
std::ostream& operator<<(std::ostream& os, const Vector3& obj) {
os << "x: " << obj.x << " y: " << obj.y << " z: " << obj.z;
return os;
}
std::ostream &operator<<(std::ostream &os, const Vector2 &obj) {
os << "x: " << obj.x << " y: " << obj.y;
return os;
std::ostream& operator<<(std::ostream& os, const Vector2& obj) {
os << "x: " << obj.x << " y: " << obj.y;
return os;
}
struct Player : Collider {
raylib::Camera3D cam;
struct Player {
raylib::Camera3D cam;
rl::Vector3 accel;
rl::Vector3 velocity;
rl::Vector3 pos;
rl::Vector3 accel;
rl::Vector3 velocity;
rl::Vector3 pos;
rl::Vector3 rotEul;
Player() : cam((Vector3){0, 0, 0}) {
//
}
RecPrism hitBox;
Player() : cam((Vector3) {0, 0, 0}), hitBox(0, rl::Vector3(20, 20, 20)) {
hitBox.movable = true;
cam.SetFovy(70);
}
rl::Vector3 GetVelocity() const {
return velocity;
}
void SetVelocity(rl::Vector3 in) {
velocity = in;
hitBox.SetVelocity(in);
}
rl::Vector3 GetPos() const {
return pos;
}
void SetPos(rl::Vector3 in) {
pos = in;
hitBox.SetPos(in);
}
bool CanMove() const {
return hitBox.CanMove();
}
rl::Vector3 FindFurthestPoint(rl::Vector3 dir) const {
return hitBox.FindFurthestPoint(dir);
}
rl::Quaternion Rotation() {
return QuaternionFromEuler(rotEul.z, rotEul.y, rotEul.x);
}
void KeyControl() {
rl::Vector3 forward = Vector3RotateByQuaternion((Vector3) {0, 0, -1}, Rotation());
void KeyControl() {
rl::Vector3 forward = Vector3RotateByQuaternion((Vector3) {0, 0, -1}, Rotation());
rl::Vector3 up = (Vector3) {0, 1, 0};
rl::Vector3 left = Vector3RotateByAxisAngle(forward, up, M_PI_2);
if (IsKeyDown(KEY_W)) {
//accel += forward * 5;
accel += rl::Vector3(forward.x, 0, forward.z).Normalize() * 5;
}
if (IsKeyDown(KEY_S)) {
//accel += -forward * 5;
accel += -rl::Vector3(forward.x, 0, forward.z).Normalize() * 5;
}
if (IsKeyDown(KEY_A)) {
//accel += left * 5;
accel += rl::Vector3(left.x, 0, left.z) * 5;
}
if (IsKeyDown(KEY_D)) {
//accel += -left * 5;
accel += -rl::Vector3(left.x, 0, left.z) * 5;
}
rl::Vector3 left = Vector3RotateByAxisAngle(forward, up, M_PI_2);
if(IsKeyDown(KEY_SPACE)) {
accel += up * 5.0f;
if (IsCursorHidden()) {
if (IsKeyDown(KEY_W)) {
// accel += forward * 5;
accel += rl::Vector3(forward.x, 0, forward.z).Normalize() * 5;
}
if (IsKeyDown(KEY_S)) {
// accel += -forward * 5;
accel += -rl::Vector3(forward.x, 0, forward.z).Normalize() * 5;
}
if (IsKeyDown(KEY_A)) {
// accel += left * 5;
accel += rl::Vector3(left.x, 0, left.z) * 5;
}
if (IsKeyDown(KEY_D)) {
// accel += -left * 5;
accel += -rl::Vector3(left.x, 0, left.z) * 5;
}
if (IsKeyDown(KEY_SPACE)) {
accel += up * 5.0f;
}
if (IsKeyDown(KEY_LEFT_SHIFT)) {
accel -= up * 5;
}
if (IsKeyDown(KEY_J)) {
if (velocity.y < 15) {
velocity.y = 15;
};
}
if (IsKeyDown(KEY_H)) {
velocity = 0;
}
// target = Vector3RotateByAxisAngle(target, (Vector3){0, 1, 0}, -GetMouseDelta().x * 0.02 *
// DEG2RAD); target = Vector3RotateByAxisAngle(target, (Vector3){1, 0, 0}, GetMouseDelta().y *
// 0.1 * DEG2RAD);
rotEul.z -= GetMouseDelta().y * 0.02 * DEG2RAD;
rotEul.y -= GetMouseDelta().x * 0.02 * DEG2RAD;
}
if(IsKeyDown(KEY_LEFT_SHIFT)) {
accel -= up * 5;
}
if(IsKeyDown(KEY_H)) {
velocity = 0;
}
//target = Vector3RotateByAxisAngle(target, (Vector3){0, 1, 0}, -GetMouseDelta().x * 0.02 * DEG2RAD);
//target = Vector3RotateByAxisAngle(target, (Vector3){1, 0, 0}, GetMouseDelta().y * 0.1 * DEG2RAD);
rotEul.z -= GetMouseDelta().y * 0.02 * DEG2RAD;
rotEul.y -= GetMouseDelta().x * 0.02 * DEG2RAD;
// rotation = QuaternionMultiply(rotation, QuaternionFromAxisAngle((Vector3) {1,0,0} , -GetMouseDelta().y * 0.02 * DEG2RAD));
// rotation = QuaternionNormalize(rotation);
// cam.SetTarget(pos + Vector3RotateByQuaternion((Vector3) {0, 0, -1}, rotation));
// rotation = QuaternionMultiply(rotation, QuaternionFromAxisAngle((Vector3) {1,0,0} ,
// -GetMouseDelta().y * 0.02 * DEG2RAD)); rotation = QuaternionNormalize(rotation);
// cam.SetTarget(pos + Vector3RotateByQuaternion((Vector3) {0, 0, -1}, rotation));
// forward = Vector3RotateByQuaternion((Vector3) {0, 0, -1}, rotation);
// up = Vector3RotateByQuaternion((Vector3) {0, 1, 0}, rotation);
// left = Vector3RotateByAxisAngle(forward, cam.GetUp(), M_PI_2);
// left = Vector3RotateByAxisAngle(forward, cam.GetUp(), M_PI_2);
// rotation = QuaternionMultiply(rotation, QuaternionFromAxisAngle((Vector3) {0,1,0}, -GetMouseDelta().x * 0.02 * DEG2RAD));
// rotation = QuaternionNormalize(rotation);
// cam.SetTarget(pos + Vector3RotateByQuaternion((Vector3) {0, 0, -1}, rotation));
// rotation = QuaternionMultiply(rotation, QuaternionFromAxisAngle((Vector3) {0,1,0}, -GetMouseDelta().x
// * 0.02 * DEG2RAD)); rotation = QuaternionNormalize(rotation);
// cam.SetTarget(pos + Vector3RotateByQuaternion((Vector3) {0, 0, -1}, rotation));
//zero roll
// zero roll
// std::cout << GetMouseDelta() << std::endl;
}
// std::cout << GetMouseDelta() << std::endl;
}
void UpdatePhysics() {
velocity += accel * GetFrameTime() * 0.5f;
pos += velocity * GetFrameTime();
velocity += accel * GetFrameTime() * 0.5f;
accel = Vector3Zero();
cam.SetPosition(pos);
cam.SetTarget(pos + Vector3RotateByQuaternion((Vector3) {0, 0, -1}, Rotation()));
}
void UpdatePhysics() {
velocity += accel * GetFrameTime() * 0.5f;
pos += velocity * GetFrameTime();
velocity += accel * GetFrameTime() * 0.5f;
accel = Vector3Zero();
cam.SetPosition(pos);
cam.SetTarget(pos + Vector3RotateByQuaternion((Vector3) {0, 0, -1}, Rotation()));
hitBox.pos = pos;
}
};
int main(int argc, char *argv[]) {
// Initialization
//--------------------------------------------------------------------------------------
int screenWidth = 800;
int screenHeight = 800;
// SetConfigFlags(FLAG_MSAA_4X_HINT | FLAG_WINDOW_RESIZABLE);
// SetConfigFlags(FLAG_MSAA_4X_HINT | FLAG_VSYNC_HINT | FLAG_WINDOW_RESIZABLE);
// SetConfigFlags(FLAG_MSAA_4X_HINT | FLAG_WINDOW_RESIZABLE);
raylib::Window window(screenWidth, screenHeight, "shooter",
FLAG_MSAA_4X_HINT | FLAG_WINDOW_RESIZABLE);
window.SetTargetFPS(244);
rlImGuiSetup(true);
DisableCursor();
ImGui::GetStyle().AntiAliasedLinesUseTex = false;
// SetWindowState(FLAG_WINDOW_UNDECORATED);
TestC();
TestCPPFunc();
raylib::RenderTexture outputTexture(screenWidth, screenHeight);
bool run = true;
bool showIMgui = false;
bool showDemoWindow = true;
Player user;
user.pos = rl::Vector3 {0, 0, 200};
RecPrism peak(Vector3Zero(), (Vector3) {50, 50, 50} );
RecPrism peakduo((Vector3) {45, 0, 0} , (Vector3) {50, 50, 50} );
while (!window.ShouldClose()) // Detect window close button or ESC key, or a quit from the menu
{
if (IsWindowResized()) {
outputTexture = raylib::RenderTexture(window.GetWidth(), window.GetHeight());
}
// user.cam.Update((Vector3){
// (IsKeyDown(KEY_W) || IsKeyDown(KEY_UP))*0.1f - // Move forward-backward
// (IsKeyDown(KEY_S) || IsKeyDown(KEY_DOWN))*0.1f,
// (IsKeyDown(KEY_D) || IsKeyDown(KEY_RIGHT))*0.1f - // Move right-left
// (IsKeyDown(KEY_A) || IsKeyDown(KEY_LEFT))*0.1f,
// 0.0f // Move up-down
// },
// (Vector3){
// GetMouseDelta().x*0.05f, // Rotation: yaw
// GetMouseDelta().y*0.05f, // Rotation: pitch
// 0.0f // Rotation: roll
// },
// GetMouseWheelMove()*2.0f); // Move to target (zoom)
user.KeyControl();
user.UpdatePhysics();
if (IsKeyDown(KEY_Q)) {
//std::cout << "PrevRot: " << peak.rotation.ToString() << std::endl;
peak.rotation = QuaternionMultiply(peak.rotation, QuaternionFromAxisAngle((Vector3) {0, 1, 0}, 0.01));
//std::cout << "NewRot: " << n.ToString() << std::endl;
std::optional<Collider *> GetSelectedCollider(std::vector<Collider *> list, Collider *user, Ray wr) {
// std::cout << GetMousePosition() << std::endl;
ColRay checkray = ColRay(wr.position, wr.direction);
// std::cout << wr.position << " dir: " << wr.direction << std::endl;
float closest_dist = FLT_MAX;
Collider *selected_object = NULL;
for (auto obj : list) {
if (obj != user) {
auto res = GJK(*obj, checkray);
if (res) {
float dist = (obj->GetPos() - checkray.origin).Length();
if (dist < closest_dist) {
closest_dist = dist;
selected_object = obj;
}
}
}
}
if(IsKeyDown(KEY_L)) {
peak.pos.x += 0.1;
}
if(IsKeyDown(KEY_J)) {
peak.pos.x -= 0.1;
}
if(IsKeyDown(KEY_I)) {
peak.pos.z -= 0.1;
}
if(IsKeyDown(KEY_K)) {
peak.pos.z += 0.1;
}
outputTexture.BeginMode();
ClearBackground(BLACK);
user.cam.BeginMode();
DrawSphere((Vector3){0, 0, -300}, 20, RED);
auto opt = GJK(peak, peakduo);
if (opt) {
peakduo.Draw(RED);
peak.Draw(RED);
auto vec = EPA(opt.value(), peak, peakduo);
//DrawRay(Ray{peakduo.pos, vec}, BLUE);
peakduo.pos += vec;
} else {
peakduo.Draw();
peak.Draw();
}
user.cam.EndMode();
outputTexture.EndMode();
window.BeginDrawing();
DrawTexturePro(outputTexture.texture,
(Rectangle){0, 0, static_cast<float>(outputTexture.texture.width),
static_cast<float>(-outputTexture.texture.height)},
(Rectangle){0, 0, static_cast<float>(window.GetWidth()),
static_cast<float>(window.GetHeight())},
(Vector2){0, 0}, 0, WHITE);
window.EndDrawing();
//----------------------------------------------------------------------------------
}
rlImGuiShutdown();
// De-Initialization
//--------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------
return 0;
if (selected_object == NULL) {
return std::optional<Collider *>();
}
return selected_object;
}
int main(int argc, char *argv[]) {
// Initialization
//--------------------------------------------------------------------------------------
int screenWidth = 800;
int screenHeight = 800;
// SetConfigFlags(FLAG_MSAA_4X_HINT | FLAG_WINDOW_RESIZABLE);
// SetConfigFlags(FLAG_MSAA_4X_HINT | FLAG_VSYNC_HINT | FLAG_WINDOW_RESIZABLE);
// SetConfigFlags(FLAG_MSAA_4X_HINT | FLAG_WINDOW_RESIZABLE);
raylib::Window window(screenWidth, screenHeight, "shooter", FLAG_MSAA_4X_HINT | FLAG_WINDOW_RESIZABLE);
window.SetTargetFPS(244);
rlImGuiSetup(true);
DisableCursor();
ImGui::GetStyle().AntiAliasedLinesUseTex = false;
// SetWindowState(FLAG_WINDOW_UNDECORATED);
TestC();
TestCPPFunc();
raylib::RenderTexture outputTexture(screenWidth, screenHeight);
bool run = true;
bool showIMgui = false;
bool showDemoWindow = true;
Player user;
user.pos = rl::Vector3{0, 100, 0};
RecPrism peak(Vector3Zero(), (Vector3) {50, 50, 50});
std::vector<Collider *> PhysObjs;
std::vector<Collider *> OpenConfigs;
PhysObjs.push_back(&user);
PhysObjs.push_back(&peak);
while (!window.ShouldClose()) // Detect window close button or ESC key, or a quit from the menu
{
if (IsWindowResized()) {
outputTexture = raylib::RenderTexture(window.GetWidth(), window.GetHeight());
}
// user.cam.Update((Vector3){
// (IsKeyDown(KEY_W) || IsKeyDown(KEY_UP))*0.1f - // Move forward-backward
// (IsKeyDown(KEY_S) || IsKeyDown(KEY_DOWN))*0.1f,
// (IsKeyDown(KEY_D) || IsKeyDown(KEY_RIGHT))*0.1f - // Move right-left
// (IsKeyDown(KEY_A) || IsKeyDown(KEY_LEFT))*0.1f,
// 0.0f // Move up-down
// },
// (Vector3){
// GetMouseDelta().x*0.05f, // Rotation: yaw
// GetMouseDelta().y*0.05f, // Rotation: pitch
// 0.0f // Rotation: roll
// },
// GetMouseWheelMove()*2.0f); // Move to target (zoom)
user.KeyControl();
user.accel.y -= 9.8;
user.UpdatePhysics();
for (size_t i = 0; i < PhysObjs.size(); i++) {
for (size_t j = i; j < PhysObjs.size(); j++) {
auto collide = GJK(*PhysObjs[i], *PhysObjs[j]);
if (collide) {
Collider *ObjA = PhysObjs[i];
Collider *ObjB = PhysObjs[j];
auto response = EPA(collide.value(), *PhysObjs[i], *PhysObjs[j]);
if (PhysObjs[i]->CanMove() && PhysObjs[j]->CanMove()) { // untested
auto halfresp = response / 2;
PhysObjs[i]->SetPos(PhysObjs[i]->GetPos() - halfresp);
auto dot = ObjA->GetVelocity().DotProduct((-halfresp).Normalize());
dot = dot > 0 ? 0 : dot;
ObjA->SetVelocity(ObjA->GetVelocity() -
((-halfresp).Normalize() * dot));
PhysObjs[j]->SetPos(PhysObjs[j]->GetPos() + halfresp);
auto dot2 = ObjB->GetVelocity().DotProduct(halfresp.Normalize());
dot2 = dot2 > 0 ? 0 : dot2;
ObjB->SetVelocity(ObjB->GetVelocity() - ((halfresp).Normalize() * dot));
} else if (PhysObjs[j]->CanMove()) {
PhysObjs[j]->SetPos(PhysObjs[j]->GetPos() + response);
auto velo = ObjB->GetVelocity();
auto dot = velo.DotProduct(response.Normalize());
dot = dot > 0 ? 0 : dot;
velo = velo - (response.Normalize() * dot * 1);
ObjB->SetVelocity(velo);
} else if (PhysObjs[i]->CanMove()) {
PhysObjs[i]->SetPos(PhysObjs[i]->GetPos() + (-response));
auto velo = ObjA->GetVelocity();
auto dot = velo.DotProduct((-response).Normalize());
dot = dot > 0 ? 0 : dot;
velo = velo - ((-response).Normalize() * dot * 1);
ObjA->SetVelocity(velo);
}
}
}
}
if (IsKeyDown(KEY_LEFT_SHIFT)) {
if (IsCursorHidden()) {
EnableCursor();
}
} else {
DisableCursor();
}
if (IsKeyDown(KEY_Q)) {
// std::cout << "PrevRot: " << peak.rotation.ToString() << std::endl;
peak.rotation =
QuaternionMultiply(peak.rotation, QuaternionFromAxisAngle((Vector3) {0, 1, 0}, 0.01));
// std::cout << "NewRot: " << n.ToString() << std::endl;
}
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) {
Ray wr = GetScreenToWorldRay(GetMousePosition(), user.cam);
auto out = GetSelectedCollider(PhysObjs, &user, wr);
bool contains = false;
for (auto obj : OpenConfigs) {
contains = contains || (obj == out);
}
if (!contains && out) {
// print("Here\n");
OpenConfigs.push_back(out.value());
}
}
// if(IsKeyDown(KEY_L)) {
// peak.pos.x += 0.1;
// }
// if(IsKeyDown(KEY_J)) {
// peak.pos.x -= 0.1;
// }
// if(IsKeyDown(KEY_I)) {
// peak.pos.z -= 0.1;
// }
// if(IsKeyDown(KEY_K)) {
// peak.pos.z += 0.1;
// }
outputTexture.BeginMode();
ClearBackground(BLACK);
user.cam.BeginMode();
DrawSphere((Vector3) {0, 0, -300}, 20, RED);
// auto opt = GJK(peak, peakduo);
// if (opt) {
// //peakduo.Draw(RED);
// peak.Draw(RED);
// auto vec = EPA(opt.value(), peak, peakduo);
// //DrawRay(Ray{peakduo.pos, vec}, BLUE);
// peakduo.pos += vec;
// } else {
// peakduo.Draw();
// peak.Draw();
// }
peak.Draw(BLUE);
user.cam.EndMode();
rlImGuiBegin();
for (size_t i = 0; i < OpenConfigs.size(); i++) {
if (ImGui::Begin(std::to_string(i).c_str())) {
auto pos = OpenConfigs[i]->GetPos();
ImGui::InputFloat3("pos", &pos.x);
OpenConfigs[i]->SetPos(pos);
auto sizeable = dynamic_cast<RecPrism*>(OpenConfigs[i]);
if (sizeable) {
ImGui::InputFloat3("size", &sizeable->size.x);
}
ImGui::End();
}
}
rlImGuiEnd();
outputTexture.EndMode();
window.BeginDrawing();
DrawTexturePro(
outputTexture.texture,
(Rectangle) {0, 0, static_cast<float>(outputTexture.texture.width),
static_cast<float>(-outputTexture.texture.height)},
(Rectangle) {0, 0, static_cast<float>(window.GetWidth()), static_cast<float>(window.GetHeight())},
(Vector2) {0, 0}, 0, WHITE);
window.EndDrawing();
//----------------------------------------------------------------------------------
}
rlImGuiShutdown();
// De-Initialization
//--------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------
return 0;
}

View file

@ -25,8 +25,26 @@ PointCloud::PointCloud(const std::vector<rl::Vector3>& in) : Points(in) {
RecPrism::RecPrism(rl::Vector3 v1, rl::Vector3 v2) : model(GenMeshCube(v2.x, v2.y, v2.z)) {
pos = v1;
velocity = 0;
size = v2;
rotation = QuaternionIdentity();
movable = false;
}
rl::Vector3 RecPrism::GetPos() const {
return pos;
}
void RecPrism::SetPos(rl::Vector3 in) {
pos = in;
}
rl::Vector3 RecPrism::GetVelocity() const {
return velocity;
}
void RecPrism::SetVelocity(rl::Vector3 in) {
velocity = in;
}
void RecPrism::Draw(rl::Color color) {
@ -55,6 +73,40 @@ void RecPrism::Draw(rl::Color color) {
}
}
bool RecPrism::CanMove() const {
return movable;
}
Collider::~Collider() {}
ColRay::ColRay(rl::Vector3 pos, rl::Vector3 dir) : origin(pos), direction(dir.Normalize()) {}
bool ColRay::CanMove() const {
return false;
}
void ColRay::SetPos(rl::Vector3 in) {}
rl::Vector3 ColRay::GetPos() const {
return origin;
}
void ColRay::SetVelocity(rl::Vector3 in) {}
rl::Vector3 ColRay::GetVelocity() const {
return 0;
}
rl::Vector3 ColRay::FindFurthestPoint(rl::Vector3 dir) const {
if (SameDirection(dir, direction)) {
return origin + (direction*100000);
} else {
return origin;
}
}
rl::Vector3 RecPrism::FindFurthestPoint(rl::Vector3 dir) const {
// Get Verts
if (size == Vector3Zero()) {
@ -290,9 +342,9 @@ rl::Vector3 Triangle::Normal() {
std::array<Edge, 3> Triangle::Edges() {
std::array<Edge, 3> out;
out[0] = Edge(a,b);
out[1] = Edge(b,c);
out[2] = Edge(c,a);
out[0] = Edge(a, b);
out[1] = Edge(b, c);
out[2] = Edge(c, a);
return out;
}
std::ostream& operator<<(std::ostream& out, const rl::Vector3& p) {
@ -306,8 +358,10 @@ std::ostream& operator<<(std::ostream& out, const Triangle& p) {
}
bool operator<(const rl::Vector3& a, const rl::Vector3& b) {
if (a.x != b.x) return a.x < b.x;
if (a.y != b.y) return a.y < b.y;
if (a.x != b.x)
return a.x < b.x;
if (a.y != b.y)
return a.y < b.y;
return a.z < b.z;
}
@ -326,41 +380,42 @@ Edge::Edge() {
y = 0;
}
bool Edge::operator<(const Edge& b) const { //TODO: better
if(x != b.x) return x < b.x;
bool Edge::operator<(const Edge& b) const { // TODO: better
if (x != b.x)
return x < b.x;
return y < b.y;
}
bool Triangle::operator<(const Triangle& b) const { //TODO: better
if(this->a != b.a) return this->a < b.a;
if(this->b != b.b) return this->b < b.b;
bool Triangle::operator<(const Triangle& b) const { // TODO: better
if (this->a != b.a)
return this->a < b.a;
if (this->b != b.b)
return this->b < b.b;
return this->c < b.c;
}
float Pointtoplane(Triangle t, rl::Vector3 p){
//std::cout << "calcing dist between" << p << " and " << t << " norm: " << t.Normal() << std::endl;
//return abs((p-t.a).Project(t.Normal()).Length());
return fabs((p-t.a).Project(t.Normal()).Length());
float Pointtoplane(Triangle t, rl::Vector3 p) {
// std::cout << "calcing dist between" << p << " and " << t << " norm: " << t.Normal() << std::endl;
// return abs((p-t.a).Project(t.Normal()).Length());
return fabs((p - t.a).Project(t.Normal()).Length());
}
Polytope::Polytope(Simplex S) {
faces.insert(Triangle(S[0],S[1],S[2]));
faces.insert(Triangle(S[0],S[3],S[1]));
faces.insert(Triangle(S[0],S[2],S[3]));
faces.insert(Triangle(S[1],S[3],S[2]));
faces.insert(Triangle(S[0], S[1], S[2]));
faces.insert(Triangle(S[0], S[3], S[1]));
faces.insert(Triangle(S[0], S[2], S[3]));
faces.insert(Triangle(S[1], S[3], S[2]));
}
void Polytope::Extend(rl::Vector3 p) {
std::set<Edge> edges;
std::queue<Triangle> rem;
for (auto face : faces) {
if (SameDirection(face.Normal(), p)) {
rem.push(face);
for (auto edge : face.Edges()) {
if(edges.contains(edge)) {
if (edges.contains(edge)) {
edges.erase(edge);
} else {
@ -379,55 +434,46 @@ void Polytope::Extend(rl::Vector3 p) {
for (auto edge : edges) {
auto adding = Triangle(edge.x, edge.y, p);
faces.insert(adding);
std::cout << "adding: " << adding << "count: " << i << std::endl;
// std::cout << "adding: " << adding << "count: " << i << std::endl;
i++;
}
}
rl::Vector3 EPA(Simplex S, const Collider& a, const Collider& b) {
Polytope p(S);
std::cout << "BEGIN" << std::endl;
// std::cout << "BEGIN" << std::endl;
while (true) {
// Find closest face
float dist = FLT_MAX;
Triangle nearest(0,0,0);
Triangle nearest(0, 0, 0);
for (auto face : p.faces) {
auto temp = Pointtoplane(face, 0);
std::cout << "dist: " << temp << " " << face << std::endl;
if ( temp < dist) {
// std::cout << "dist: " << temp << " " << face << std::endl;
if (temp < dist) {
dist = temp;
nearest = face;
//DrawTriangle3D(nearest.a, nearest.b, nearest.c, WHITE);
// DrawTriangle3D(nearest.a, nearest.b, nearest.c, WHITE);
}
}
auto normal = nearest.Normal();
//DrawLine3D(rl::Vector3(0), normal*1000, GREEN);
// DrawLine3D(rl::Vector3(0), normal*1000, GREEN);
auto supportPoint = Support(a, b, normal);
//std::cout << "dist to farthest hull" << supportPoint.Dotproduct(normal) - dist << std::endl;
if (abs(supportPoint.DotProduct(normal) - dist) < 0.1) { // if distance between face and point on face is same
//return supportPoint.Project(normal);
//DrawTriangle3D(nearest.a, nearest.b, nearest.c, GREEN);
std::cout << "END" << std::endl;
// std::cout << "dist to farthest hull" << supportPoint.Dotproduct(normal) - dist << std::endl;
if (abs(supportPoint.DotProduct(normal) - dist) <
0.1) { // if distance between face and point on face is same
// return supportPoint.Project(normal);
// DrawTriangle3D(nearest.a, nearest.b, nearest.c, GREEN);
// std::cout << "END" << std::endl;
return normal * Pointtoplane(nearest, 0);
} else {
//extend
std::cout << "extending" << std::endl;
// extend
// std::cout << "extending" << std::endl;
p.Extend(supportPoint);
}
}
}

View file

@ -31,6 +31,33 @@ struct PointCloud {
struct Collider {
virtual rl::Vector3 FindFurthestPoint(rl::Vector3 dir) const = 0;
virtual bool CanMove() const = 0;
virtual void SetPos(rl::Vector3 in) = 0;
virtual rl::Vector3 GetPos() const = 0;
virtual void SetVelocity(rl::Vector3 in) = 0;
virtual rl::Vector3 GetVelocity() const = 0;
virtual ~Collider() = 0;
};
struct ColRay : Collider {
rl::Vector3 origin;
rl::Vector3 direction;
ColRay(rl::Vector3 pos, rl::Vector3 dir);
bool CanMove() const;
void SetPos(rl::Vector3 in);
rl::Vector3 GetPos() const;
rl::Vector3 FindFurthestPoint(rl::Vector3 dir) const;
rl::Vector3 GetVelocity() const;
void SetVelocity(rl::Vector3 in);
};
struct RecPrism : Collider {
@ -38,12 +65,23 @@ struct RecPrism : Collider {
rl::Vector3 size;
rl::Quaternion rotation;
rl::Model model;
rl::Vector3 velocity;
bool movable;
void Draw(rl::Color color = BLUE);
RecPrism(rl::Vector3 v1, rl::Vector3 v2);
bool CanMove() const;
void SetPos(rl::Vector3 in);
rl::Vector3 GetPos() const;
rl::Vector3 FindFurthestPoint(rl::Vector3 dir) const;
rl::Vector3 GetVelocity() const;
void SetVelocity(rl::Vector3 in);
};
rl::Vector3 Support(const Collider& a, const Collider& b, rl::Vector3 dir);