Skip to content

Commit

Permalink
Intersections and Collision module only uses Rectf instead of Rect.
Browse files Browse the repository at this point in the history
  • Loading branch information
Andre-LA committed Mar 23, 2023
1 parent ea32ab5 commit e3fd32a
Show file tree
Hide file tree
Showing 12 changed files with 63 additions and 69 deletions.
2 changes: 1 addition & 1 deletion bindgen/data/intersections.lua
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ local structs = ast_reader.get_structs(symbols, 'nene')
local funcs = utils.table.imerge(
ast_reader.get_functions(symbols, 'nene_Intersections'),
ast_reader.get_functions(symbols, 'nene_IntersectionRectfWithRectf'),
ast_reader.get_functions(symbols, 'nene_IntersectionSegmentWithRect'),
ast_reader.get_functions(symbols, 'nene_IntersectionSegmentWithRectf'),
ast_reader.get_functions(symbols, 'nene_IntersectionSegmentWithSegment')
)

Expand Down
10 changes: 2 additions & 8 deletions bindgen/generate.lua
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,8 @@ local neluagen = nelua.gen.new({
['nene_Animation'] = 'Animation',
['nene_Animation_Property'] = 'AnimationProperty',
['nene_Intersections'] = 'Intersections',
['nene_IntersectionRectWithRect'] = 'RectWithRect',
['nene_IntersectionRectfWithRectf'] = 'RectfWithRectf',
['nene_IntersectionSegmentWithRect'] = 'SegmentWithRect',
['nene_IntersectionSegmentWithRectf'] = 'SegmentWithRectf',
['nene_IntersectionSegmentWithSegment'] = 'SegmentWithSegment',
['nene_Collision'] = 'Collision',
['nene_Texture'] = 'Texture',
Expand Down Expand Up @@ -332,18 +331,15 @@ local Shape.Quadrilateral = ShapeQuadrilateral
bind_file('intersections', {
dependencies = {
{ modname = 'Vec2', path = 'nene.math.vec2' },
{ modname = 'Vec2i', path = 'nene.math.vec2i' },
{ modname = 'Rect', path = 'nene.math.rect' },
{ modname = 'Rectf', path = 'nene.math.rectf' },
{ modname = 'Segment', path = 'nene.math.segment' },
{ modname = 'Shape', path = 'nene.math.shape' },
},
prepend = [[
local Intersections = @record{}
]],
append = [[
local Intersections.RectfWithRectf = RectfWithRectf
local Intersections.SegmentWithRect = SegmentWithRect
local Intersections.SegmentWithRectf = SegmentWithRectf
local Intersections.SegmentWithSegment = SegmentWithSegment
]]
})
Expand All @@ -352,8 +348,6 @@ local Intersections.SegmentWithSegment = SegmentWithSegment
bind_file('collision', {
dependencies = {
{ modname = 'Vec2', path = 'nene.math.vec2' },
{ modname = 'Vec2i', path = 'nene.math.vec2i' },
{ modname = 'Rect', path = 'nene.math.rect' },
{ modname = 'Rectf', path = 'nene.math.rectf' },
{ modname = 'Segment', path = 'nene.math.segment' },
},
Expand Down
4 changes: 1 addition & 3 deletions bindings/nelua/nene/collision.nelua
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
## cinclude '"nene/collision.h"'

local Vec2 = require 'nene.math.vec2'
local Vec2i = require 'nene.math.vec2i'
local Rect = require 'nene.math.rect'
local Rectf = require 'nene.math.rectf'
local Segment = require 'nene.math.segment'

Expand All @@ -21,6 +19,6 @@ function Collision.no_collision(): Collision <cimport 'nene_Collision_no_collisi
function Collision.rectf_with_rectf(a: Rectf, b: Rectf, delta_pos: Vec2): Collision <cimport 'nene_Collision_rectf_with_rectf', nodecl> end

-- Returns the collision response between a rectangle and a segment.
function Collision.rect_with_segment(rect: Rect, segment: Segment, delta_pos: Vec2): Collision <cimport 'nene_Collision_rect_with_segment', nodecl> end
function Collision.rectf_with_segment(rect: Rectf, segment: Segment, delta_pos: Vec2): Collision <cimport 'nene_Collision_rectf_with_segment', nodecl> end

return Collision
13 changes: 5 additions & 8 deletions bindings/nelua/nene/intersections.nelua
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,8 @@
## cinclude '"nene/intersections.h"'

local Vec2 = require 'nene.math.vec2'
local Vec2i = require 'nene.math.vec2i'
local Rect = require 'nene.math.rect'
local Rectf = require 'nene.math.rectf'
local Segment = require 'nene.math.segment'
local Shape = require 'nene.math.shape'

local Intersections = @record{}

Expand All @@ -22,7 +19,7 @@ local RectfWithRectf <cimport 'nene_IntersectionRectfWithRectf', nodecl> = @reco
-- The intersected "sides" of the rectangle, the first element
-- it's the one that intersects `intersection.origin`, while the
-- second element it's the one that intersects `intersection.ending`.
local SegmentWithRect <cimport 'nene_IntersectionSegmentWithRect', nodecl> = @record{
local SegmentWithRectf <cimport 'nene_IntersectionSegmentWithRectf', nodecl> = @record{
count: uint8,
intersection: Segment,
intersected_rect_sides: [2]Segment,
Expand All @@ -41,7 +38,7 @@ local SegmentWithSegment <cimport 'nene_IntersectionSegmentWithSegment', nodecl>
function Intersections.is_intersecting_rectf_with_rectf(a: Rectf, b: Rectf): boolean <cimport 'nene_Intersections_is_intersecting_rectf_with_rectf', nodecl> end

-- Returns if a rectangle is intersecting with a point.
function Intersections.is_intersecting_rect_with_point(rect: Rect, point: Vec2i): boolean <cimport 'nene_Intersections_is_intersecting_rect_with_point', nodecl> end
function Intersections.is_intersecting_rectf_with_point(rect: Rectf, point: Vec2): boolean <cimport 'nene_Intersections_is_intersecting_rectf_with_point', nodecl> end

-- Returns "no rect with rect intersection" value.
function RectfWithRectf.no_intersection(): RectfWithRectf <cimport 'nene_IntersectionRectfWithRectf_no_intersection', nodecl> end
Expand All @@ -50,16 +47,16 @@ function RectfWithRectf.no_intersection(): RectfWithRectf <cimport 'nene_Interse
function RectfWithRectf.get_intersection(a: Rectf, b: Rectf): RectfWithRectf <cimport 'nene_IntersectionRectfWithRectf_get_intersection', nodecl> end

-- Returns "no segment with rect intersection" value.
function SegmentWithRect.no_intersection(): SegmentWithRect <cimport 'nene_IntersectionSegmentWithRect_no_intersection', nodecl> end
function SegmentWithRectf.no_intersection(): SegmentWithRectf <cimport 'nene_IntersectionSegmentWithRectf_no_intersection', nodecl> end

-- Returns the intersection data between a segment and a rectangle.
function SegmentWithRect.get_intersection(segment: Segment, rect: Rect): SegmentWithRect <cimport 'nene_IntersectionSegmentWithRect_get_intersection', nodecl> end
function SegmentWithRectf.get_intersection(segment: Segment, rect: Rectf): SegmentWithRectf <cimport 'nene_IntersectionSegmentWithRectf_get_intersection', nodecl> end

-- Returns the intersection data between two segments.
function SegmentWithSegment.get_intersection(a: Segment, b: Segment): SegmentWithSegment <cimport 'nene_IntersectionSegmentWithSegment_get_intersection', nodecl> end

local Intersections.RectfWithRectf = RectfWithRectf
local Intersections.SegmentWithRect = SegmentWithRect
local Intersections.SegmentWithRectf = SegmentWithRectf
local Intersections.SegmentWithSegment = SegmentWithSegment

return Intersections
3 changes: 3 additions & 0 deletions bindings/nelua/nene/math/shape.nelua
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ local ShapeQuadrilateral <cimport 'nene_ShapeQuadrilateral', nodecl> = @record{
sides: [4]Segment,
}

-- Returns a quadrilateral shape made from a rectanle with floating values.
function Shape.get_rectf_shape(rect: Rectf): ShapeQuadrilateral <cimport 'nene_Shape_get_rectf_shape', nodecl> end

-- Returns a quadrilateral shape made from a rectanle.
function Shape.get_rect_shape(rect: Rect): ShapeQuadrilateral <cimport 'nene_Shape_get_rect_shape', nodecl> end

Expand Down
27 changes: 14 additions & 13 deletions examples/pong.nelua
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ local string = require 'string'
local Nene = require 'nene.core'
local Color = require 'nene.color'
local Rect = require 'nene.math.rect'
local Rectf = require 'nene.math.rectf'
local Vec2 = require 'nene.math.vec2'
local Vec2i = require 'nene.math.vec2i'
local Intersections = require 'nene.intersections'
Expand Down Expand Up @@ -62,16 +63,16 @@ function Racket.init(): Racket
end

-- return the rect of the racket
function Racket:get_rect(is_player_one: boolean): Rect
function Racket:get_rectf(is_player_one: boolean): Rectf
local anchor_x = SETTINGS.screen_size.x / 2
local size = SETTINGS.racket.size

return Rect{
return Rectf{
pos = {
x = is_player_one and -anchor_x + 2 or anchor_x - size.x - 2,
y = self.pos_y,
},
=size,
size = Vec2.from_vec2i(size),
}
end

Expand Down Expand Up @@ -105,7 +106,7 @@ end
-- draw a racket
function Racket:draw(is_player_one: boolean)
local nene = Nene.instance()
Nene.render_draw_rect(self:get_rect(is_player_one), false, Color.yellow, true)
Nene.render_draw_rect(self:get_rectf(is_player_one):to_rect(), false, Color.yellow, true)
end

-- ball record
Expand All @@ -115,10 +116,10 @@ local Ball = @record{
}

-- return the ball's rect
function Ball:get_rect(): Rect
return Rect{
pos = self.pos:to_vec2i(),
size = Vec2i.one() * SETTINGS.ball.size,
function Ball:get_rectf(): Rectf
return Rectf{
pos = self.pos,
size = Vec2.one() * SETTINGS.ball.size,
}
end

Expand Down Expand Up @@ -149,11 +150,11 @@ function Ball:update(racket_1: *Racket, racket_2: *Racket, delta_time: number)
end

-- invert horizontal direction when intersecting rackets
local ball_rect = self:get_rect()
local r1_rect, r2_rect = racket_1:get_rect(true), racket_2:get_rect(false)
local ball_rect = self:get_rectf()
local r1_rect, r2_rect = racket_1:get_rectf(true), racket_2:get_rectf(false)

local r1_intersected, r2_intersected = Intersections.is_intersecting_rect_with_rect(ball_rect, r1_rect),
Intersections.is_intersecting_rect_with_rect(ball_rect, r2_rect)
local r1_intersected, r2_intersected = Intersections.is_intersecting_rectf_with_rectf(ball_rect, r1_rect),
Intersections.is_intersecting_rectf_with_rectf(ball_rect, r2_rect)

if r1_intersected or r2_intersected then
self.direction.x = -self.direction.x
Expand All @@ -162,7 +163,7 @@ function Ball:update(racket_1: *Racket, racket_2: *Racket, delta_time: number)
end

function Ball:draw()
Nene.render_draw_rect(self:get_rect(), false, Color.white, true)
Nene.render_draw_rect(self:get_rectf():to_rect(), false, Color.white, true)
end

local function update_points(pts_text: *Texture, points: integer, font: Font)
Expand Down
4 changes: 1 addition & 3 deletions include/nene/collision.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ SPDX-License-Identifier: Zlib

#include <stdbool.h>
#include "nene/math/vec2.h"
#include "nene/math/vec2i.h"
#include "nene/math/rect.h"
#include "nene/math/rectf.h"
#include "nene/math/segment.h"

Expand All @@ -28,6 +26,6 @@ nene_Collision nene_Collision_no_collision(void);
nene_Collision nene_Collision_rectf_with_rectf(nene_Rectf a, nene_Rectf b, nene_Vec2 delta_pos);

/// Returns the collision response between a rectangle and a segment.
nene_Collision nene_Collision_rect_with_segment(nene_Rect rect, nene_Segment segment, nene_Vec2 delta_pos);
nene_Collision nene_Collision_rectf_with_segment(nene_Rectf rect, nene_Segment segment, nene_Vec2 delta_pos);

#endif // NENE_COLLISIONS_H
11 changes: 5 additions & 6 deletions include/nene/intersections.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ SPDX-License-Identifier: Zlib

#include <stdbool.h>
#include "nene/math/vec2.h"
#include "nene/math/rect.h"
#include "nene/math/rectf.h"
#include "nene/math/segment.h"

Expand All @@ -21,14 +20,14 @@ typedef struct nene_IntersectionRectfWithRectf {
} nene_IntersectionRectfWithRectf;

/// Segment with rectangle intersection.
typedef struct nene_IntersectionSegmentWithRect {
typedef struct nene_IntersectionSegmentWithRectf {
uint8_t count;
nene_Segment intersection;
/// The intersected "sides" of the rectangle, the first element
/// it's the one that intersects `intersection.origin`, while the
/// second element it's the one that intersects `intersection.ending`.
nene_Segment intersected_rect_sides[2];
} nene_IntersectionSegmentWithRect;
} nene_IntersectionSegmentWithRectf;

/// Segment with segment intersection.
typedef struct nene_IntersectionSegmentWithSegment {
Expand All @@ -43,19 +42,19 @@ typedef struct nene_IntersectionSegmentWithSegment {
bool nene_Intersections_is_intersecting_rectf_with_rectf(nene_Rectf a, nene_Rectf b);

/// Returns if a rectangle is intersecting with a point.
bool nene_Intersections_is_intersecting_rect_with_point(nene_Rect rect, nene_Vec2i point);
bool nene_Intersections_is_intersecting_rectf_with_point(nene_Rectf rect, nene_Vec2 point);

/// Returns "no rect with rect intersection" value.
nene_IntersectionRectfWithRectf nene_IntersectionRectfWithRectf_no_intersection(void);

/// Returns "no segment with rect intersection" value.
nene_IntersectionSegmentWithRect nene_IntersectionSegmentWithRect_no_intersection(void);
nene_IntersectionSegmentWithRectf nene_IntersectionSegmentWithRectf_no_intersection(void);

/// Returns the intersection rectangle between two rectangles.
nene_IntersectionRectfWithRectf nene_IntersectionRectfWithRectf_get_intersection(nene_Rectf a, nene_Rectf b);

/// Returns the intersection data between a segment and a rectangle.
nene_IntersectionSegmentWithRect nene_IntersectionSegmentWithRect_get_intersection(nene_Segment segment, nene_Rect rect);
nene_IntersectionSegmentWithRectf nene_IntersectionSegmentWithRectf_get_intersection(nene_Segment segment, nene_Rectf rect);

/// Returns the intersection data between two segments.
nene_IntersectionSegmentWithSegment nene_IntersectionSegmentWithSegment_get_intersection(nene_Segment a, nene_Segment b);
Expand Down
4 changes: 4 additions & 0 deletions include/nene/math/shape.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,16 @@ SPDX-License-Identifier: Zlib

#include "nene/math/segment.h"
#include "nene/math/rect.h"
#include "nene/math/rectf.h"

/// Quadrilateral shape data strucuture, it holds four segments.
typedef struct nene_ShapeQuadrilateral {
nene_Segment sides[4];
} nene_ShapeQuadrilateral;

/// Returns a quadrilateral shape made from a rectanle with floating values.
nene_ShapeQuadrilateral nene_Shape_get_rectf_shape(nene_Rectf rect);

/// Returns a quadrilateral shape made from a rectanle.
nene_ShapeQuadrilateral nene_Shape_get_rect_shape(nene_Rect rect);

Expand Down
18 changes: 9 additions & 9 deletions src/collision.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,20 @@ SPDX-License-Identifier: Zlib
#include "nene/math/vec2.h"
#include "nene/math/vec2i.h"

static nene_Vec2 nene_impl_Collision_rect_with_segment_get_colliding_corner(nene_Rect rect, nene_Vec2 intersection_midpoint) {
const nene_Vec2i corners[4] = {
nene_Vec2i_add(rect.pos, (nene_Vec2i){ .x = rect.size.x }), // top-right
rect.pos, // top-left
nene_Vec2i_add(rect.pos, (nene_Vec2i){ .y = -rect.size.y }), // bottom-left
nene_Vec2i_add(rect.pos, (nene_Vec2i){ .x = rect.size.x, .y = -rect.size.y }), // bottom-right
static nene_Vec2 nene_impl_Collision_rect_with_segment_get_colliding_corner(nene_Rectf rect, nene_Vec2 intersection_midpoint) {
const nene_Vec2 corners[4] = {
nene_Vec2_add(rect.pos, (nene_Vec2){ .x = rect.size.x }), // top-right
rect.pos, // top-left
nene_Vec2_add(rect.pos, (nene_Vec2){ .y = -rect.size.y }), // bottom-left
nene_Vec2_add(rect.pos, (nene_Vec2){ .x = rect.size.x, .y = -rect.size.y }), // bottom-right
};

nene_Vec2 near_rect_corner = nene_Vec2_zero();
float shortest_len = HUGE_VALF;

// There are four corners, thus we iterate four times.
for (int i = 0; i < 4; ++i) {
const nene_Vec2 corner = nene_Vec2_from_vec2i(corners[i]);
const nene_Vec2 corner = corners[i];
const float len = nene_Vec2_len_sqr(nene_Vec2_sub(intersection_midpoint, corner));

if (len < shortest_len) {
Expand Down Expand Up @@ -92,8 +92,8 @@ nene_Collision nene_Collision_no_collision(void) {
};
}

nene_Collision nene_Collision_rect_with_segment(nene_Rect rect, nene_Segment segment, nene_Vec2 delta_pos) {
nene_IntersectionSegmentWithRect intersection = nene_IntersectionSegmentWithRect_get_intersection(segment, rect);
nene_Collision nene_Collision_rectf_with_segment(nene_Rectf rect, nene_Segment segment, nene_Vec2 delta_pos) {
nene_IntersectionSegmentWithRectf intersection = nene_IntersectionSegmentWithRectf_get_intersection(segment, rect);

if (intersection.count == 0) {
return nene_Collision_no_collision();
Expand Down
14 changes: 7 additions & 7 deletions src/intersections.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ bool nene_Intersections_is_intersecting_rectf_with_rectf(nene_Rectf a, nene_Rect
);
}

bool nene_Intersections_is_intersecting_rect_with_point(nene_Rect rect, nene_Vec2i point) {
bool nene_Intersections_is_intersecting_rectf_with_point(nene_Rectf rect, nene_Vec2 point) {
return point.x >= rect.pos.x && point.x <= rect.pos.x + rect.size.x &&
point.y <= rect.pos.y && point.y >= rect.pos.y - rect.size.y;
}
Expand All @@ -30,8 +30,8 @@ nene_IntersectionRectfWithRectf nene_IntersectionRectfWithRectf_no_intersection(
};
}

nene_IntersectionSegmentWithRect nene_IntersectionSegmentWithRect_no_intersection(void) {
return (nene_IntersectionSegmentWithRect){
nene_IntersectionSegmentWithRectf nene_IntersectionSegmentWithRectf_no_intersection(void) {
return (nene_IntersectionSegmentWithRectf){
.count = 0,
};
}
Expand Down Expand Up @@ -65,9 +65,9 @@ nene_IntersectionRectfWithRectf nene_IntersectionRectfWithRectf_get_intersection
};
}

nene_IntersectionSegmentWithRect nene_IntersectionSegmentWithRect_get_intersection(nene_Segment segment, nene_Rect rect) {
nene_IntersectionSegmentWithRect result = nene_IntersectionSegmentWithRect_no_intersection();
nene_ShapeQuadrilateral quad_shape = nene_Shape_get_rect_shape(rect);
nene_IntersectionSegmentWithRectf nene_IntersectionSegmentWithRectf_get_intersection(nene_Segment segment, nene_Rectf rect) {
nene_IntersectionSegmentWithRectf result = nene_IntersectionSegmentWithRectf_no_intersection();
nene_ShapeQuadrilateral quad_shape = nene_Shape_get_rectf_shape(rect);

nene_Vec2 points[2] = { nene_Vec2_zero(), nene_Vec2_zero() };

Expand All @@ -90,7 +90,7 @@ nene_IntersectionSegmentWithRect nene_IntersectionSegmentWithRect_get_intersecti
// if there's only one intersection point, then we assign to the second point to the
// intersecting "tip" (either origin or ending) of the segment.
if (result.count == 1) {
if (nene_Intersections_is_intersecting_rect_with_point(rect, nene_Vec2_to_vec2i(segment.origin))) {
if (nene_Intersections_is_intersecting_rectf_with_point(rect, segment.origin)) {
points[1] = segment.origin;
}
else {
Expand Down
Loading

0 comments on commit e3fd32a

Please sign in to comment.