Raycaster Problem

Run Settings
LanguageC++
Language Version
Run Command
enum RaycastSide : Uint8 { Top = 0, Right, Bottom, Left }; typedef struct s_raycastinfo_t { bool hit; int x; int y; Uint8 texel; float angle; Vector start; Vector end; float distance; RaycastSide side; } RaycastInfo; void Application::Raycast(RaycastInfo* info, const Vector start, const Vector dir) { if (info) { memset(info, NULL, sizeof(RaycastInfo)); float angle = atan2f(dir.y, dir.x); if (angle < 0.0f) { angle += M_PI * 2.0f; } angle = fmod(angle, M_PI * 2.0f); float angTan = tanf(angle); bool isUp = (angle < 0.0f || angle > M_PI); bool isRight = (angle > ((M_PI * 2.0f) * 0.75f) || angle < ((M_PI * 2.0f) * 0.25f)); /* Horizontal Intersection */ Vector horzEnd = Vector::Empty(); float hXa = (BLOCK_SIZE / (isUp ? -angTan : angTan)); float hYa = (BLOCK_SIZE * (isUp ? -1 : 1)); horzEnd.y = int(start.y / BLOCK_SIZE) * (BLOCK_SIZE) + (isUp ? -1 : BLOCK_SIZE); horzEnd.x = start.x + (horzEnd.y - start.y) / angTan; int hMx = 0; int hMy = 0; bool hHit = false; while (true) { hMx = int(horzEnd.x) / BLOCK_SIZE; hMy = int(horzEnd.y) / BLOCK_SIZE; if (hMx < 0 || hMy < 0 || hMx >= mapWidth_ || hMy >= mapHeight_) { break; } else if (map_[(mapWidth_ * hMy) + hMx]) { hHit = true; break; } horzEnd.x += hXa; horzEnd.y += hYa; } /* Vertical Intersection */ Vector vertEnd = Vector::Empty(); float vXa = (BLOCK_SIZE * (isRight ? 1 : -1)); float vYa = (BLOCK_SIZE * (isRight ? angTan : -angTan)); vertEnd.x = int(start.x / BLOCK_SIZE) * (BLOCK_SIZE) + (isRight ? BLOCK_SIZE : -1); vertEnd.y = start.y + (vertEnd.x - start.x) * angTan; int vMx = 0; int vMy = 0; bool vHit = false; while (true) { vMx = int(vertEnd.x) / BLOCK_SIZE; vMy = int(vertEnd.y) / BLOCK_SIZE; if (vMx < 0 || vMy < 0 || vMx >= mapWidth_ || vMy >= mapHeight_) { break; } else if (map_[(mapWidth_ * vMy) + vMx]) { vHit = true; break; } vertEnd.x += vXa; vertEnd.y += vYa; } /* Setup info object */ float vertDist = start.DistanceSquared(vertEnd); float horzDist = start.DistanceSquared(horzEnd); info->start = start; info->angle = angle; if (hHit && horzDist < vertDist) { info->end = horzEnd; info->distance = sqrt(horzDist); info->side = (isUp ? RaycastSide::Bottom : RaycastSide::Top); info->x = hMx; info->y = hMy; info->texel = (hMx % BLOCK_SIZE); info->hit = true; } else if (vHit) { info->end = vertEnd; info->distance = sqrt(vertDist); info->side = (isRight ? RaycastSide::Left : RaycastSide::Right); info->x = vMx; info->y = vMy; info->texel = (vMy % BLOCK_SIZE); info->hit = true; } else { info->end = start; info->distance = 0.0f; info->side = RaycastSide::Top; info->x = INT_MAX; info->y = INT_MAX; info->texel = 0; info->hit = false; } } }
#pragma once #ifndef _INCLUDE_VECTOR_H_ #define _INCLUDE_VECTOR_H_ #include "main.h" class Vector { public: float x, y; /* =================== */ /* === Constructor === */ /* =================== */ Vector(void) : x(0), y(0) { } Vector(float x, float y) : x(x), y(y) { } Vector(const Vector& v) : x(v.x), y(v.y) { } ~Vector(void) { } static Vector Empty(void) { return Vector(); } Vector Floor(void) const { Vector v; v.x = floorf(this->x); v.y = floorf(this->y); return v; } Vector Ceil(void) const { Vector v; v.x = ceilf(this->x); v.y = ceilf(this->y); return v; } /* =========================== */ /* === Calculation Methods === */ /* =========================== */ float Distance(const Vector& rhs) const { return sqrt(DistanceSquared(rhs)); } float DistanceSquared(const Vector& rhs) const { Vector v = Subtract(rhs); return ((v.x * v.x) + (v.y * v.y)); } float Magnitude(void) const { return sqrtf((x * x) + (y * y)); } Vector Normalized(void) const { Vector v(x, y); float mag = v.Magnitude(); if (mag != 0.0f) { v.x /= mag; v.y /= mag; } return v; } Vector& Normalize(void) { Set(Normalized()); return *this; } float Dot(const Vector& rhs) const { return ((x * rhs.x) + (y * rhs.y)); } /* ====================== */ /* === Index Operator === */ /* ====================== */ float& operator[](int idx) { return (&this->x)[idx % 2]; } /* =========================== */ /* === Assignment Operator === */ /* =========================== */ Vector& Set(const Vector& rhs) { x = rhs.x; y = rhs.y; return *this; } Vector& Set(float rhs) { x = rhs; y = rhs; return *this; } Vector& Set(float rhsx, float rhsy) { x = rhsx; y = rhsy; return *this; } Vector& operator=(const Vector& rhs) { x = rhs.x; y = rhs.y; return *this; } Vector& operator=(float rhs) { x = rhs; y = rhs; return *this; } /* ========================= */ /* === Addition Operator === */ /* ========================= */ Vector Add(const Vector& rhs) const { Vector v(x + rhs.x, y + rhs.y); return v; } Vector Add(float rhs) const { Vector v(x + rhs, y + rhs); return v; } Vector operator+(const Vector& rhs) const { return Add(rhs); } Vector operator+(float rhs) const { return Add(rhs); } Vector& operator+=(const Vector& rhs) { x += rhs.x; y += rhs.y; return *this; } Vector& operator+=(float rhs) { x += rhs; y += rhs; return *this; } /* ============================ */ /* === Subtraction Operator === */ /* ============================ */ Vector Subtract(const Vector& rhs) const { Vector v(x - rhs.x, y - rhs.y); return v; } Vector Subtract(float rhs) const { Vector v(x - rhs, y - rhs); return v; } Vector operator-(const Vector& rhs) const { return Subtract(rhs); } Vector operator-(float rhs) const { return Subtract(rhs); } Vector& operator-=(const Vector& rhs) { x -= rhs.x; y -= rhs.y; return *this; } Vector& operator-=(float rhs) { x -= rhs; y -= rhs; return *this; } /* ========================= */ /* === Division Operator === */ /* ========================= */ Vector Divide(const Vector& rhs) const { Vector v(x / rhs.x, y / rhs.y); return v; } Vector Divide(float rhs) const { Vector v(x / rhs, y / rhs); return v; } Vector operator/(const Vector& rhs) const { return Divide(rhs); } Vector operator/(float rhs) const { return Divide(rhs); } Vector& operator/=(const Vector& rhs) { x /= rhs.x; y /= rhs.y; return *this; } Vector& operator/=(float rhs) { x /= rhs; y /= rhs; return *this; } /* =============================== */ /* === Multiplication Operator === */ /* =============================== */ Vector Multiply(const Vector& rhs) const { Vector v(x * rhs.x, y * rhs.y); return v; } Vector Multiply(float rhs) const { Vector v(x * rhs, y * rhs); return v; } Vector operator*(const Vector& rhs) const { return Multiply(rhs); } Vector operator*(float rhs) const { return Multiply(rhs); } Vector& operator*=(const Vector& rhs) { x *= rhs.x; y *= rhs.y; return *this; } Vector& operator*=(float rhs) { x *= rhs; y *= rhs; return *this; } /* =========================== */ /* === Comparison Operator === */ /* =========================== */ bool operator==(const Vector& rhs) const { return (fabsf(x - rhs.x) < FLT_EPSILON && fabsf(y - rhs.y) < FLT_EPSILON); } bool operator==(const float rhs) const { return (fabsf(x - rhs) < FLT_EPSILON && fabsf(y - rhs) < FLT_EPSILON); } bool operator!=(const Vector& rhs) const { return (fabsf(x - rhs.x) > FLT_EPSILON || fabsf(y - rhs.y) > FLT_EPSILON); } bool operator!=(const float rhs) const { return (fabsf(x - rhs) > FLT_EPSILON || fabsf(y - rhs) > FLT_EPSILON); } }; #endif
Editor Settings
Theme
Key bindings
Full width
Lines