Skip to content

Commit

Permalink
Support boundary checking
Browse files Browse the repository at this point in the history
  • Loading branch information
JiepengTan committed Oct 18, 2024
1 parent 57104cd commit 32628cd
Show file tree
Hide file tree
Showing 8 changed files with 150 additions and 8 deletions.
12 changes: 12 additions & 0 deletions core/extension/gdextension_spx_ext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,9 @@ static void gdextension_spx_physic_raycast(GdVec2 from,GdVec2 to,GdInt collision
static void gdextension_spx_physic_check_collision(GdVec2 from,GdVec2 to,GdInt collision_mask,GdBool collide_with_areas,GdBool collide_with_bodies,GdBool* ret_val) {
*ret_val = physicMgr->check_collision(from, to, collision_mask, collide_with_areas, collide_with_bodies);
}
static void gdextension_spx_physic_check_touched_camera_boundary(GdObj obj,GdInt board_type,GdBool* ret_val) {
*ret_val = physicMgr->check_touched_camera_boundary(obj, board_type);
}
static void gdextension_spx_platform_set_window_size(GdInt width,GdInt height) {
platformMgr->set_window_size(width, height);
}
Expand Down Expand Up @@ -248,6 +251,12 @@ static void gdextension_spx_sprite_set_scale(GdObj obj,GdVec2 scale) {
static void gdextension_spx_sprite_get_scale(GdObj obj,GdVec2* ret_val) {
*ret_val = spriteMgr->get_scale(obj);
}
static void gdextension_spx_sprite_set_render_scale(GdObj obj,GdVec2 scale) {
spriteMgr->set_render_scale(obj, scale);
}
static void gdextension_spx_sprite_get_render_scale(GdObj obj,GdVec2* ret_val) {
*ret_val = spriteMgr->get_render_scale(obj);
}
static void gdextension_spx_sprite_set_color(GdObj obj,GdColor color) {
spriteMgr->set_color(obj, color);
}
Expand Down Expand Up @@ -610,6 +619,7 @@ void gdextension_spx_setup_interface() {
REGISTER_SPX_INTERFACE_FUNC(spx_input_is_action_just_released);
REGISTER_SPX_INTERFACE_FUNC(spx_physic_raycast);
REGISTER_SPX_INTERFACE_FUNC(spx_physic_check_collision);
REGISTER_SPX_INTERFACE_FUNC(spx_physic_check_touched_camera_boundary);
REGISTER_SPX_INTERFACE_FUNC(spx_platform_set_window_size);
REGISTER_SPX_INTERFACE_FUNC(spx_platform_get_window_size);
REGISTER_SPX_INTERFACE_FUNC(spx_platform_set_window_title);
Expand Down Expand Up @@ -644,6 +654,8 @@ void gdextension_spx_setup_interface() {
REGISTER_SPX_INTERFACE_FUNC(spx_sprite_get_rotation);
REGISTER_SPX_INTERFACE_FUNC(spx_sprite_set_scale);
REGISTER_SPX_INTERFACE_FUNC(spx_sprite_get_scale);
REGISTER_SPX_INTERFACE_FUNC(spx_sprite_set_render_scale);
REGISTER_SPX_INTERFACE_FUNC(spx_sprite_get_render_scale);
REGISTER_SPX_INTERFACE_FUNC(spx_sprite_set_color);
REGISTER_SPX_INTERFACE_FUNC(spx_sprite_get_color);
REGISTER_SPX_INTERFACE_FUNC(spx_sprite_set_texture_altas);
Expand Down
3 changes: 3 additions & 0 deletions core/extension/gdextension_spx_ext.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ typedef void (*GDExtensionSpxInputIsActionJustReleased)(GdString action, GdBool*
// SpxPhysic
typedef void (*GDExtensionSpxPhysicRaycast)(GdVec2 from, GdVec2 to, GdInt collision_mask, GdObj* ret_value);
typedef void (*GDExtensionSpxPhysicCheckCollision)(GdVec2 from, GdVec2 to, GdInt collision_mask, GdBool collide_with_areas, GdBool collide_with_bodies, GdBool* ret_value);
typedef void (*GDExtensionSpxPhysicCheckTouchedCameraBoundary)(GdObj obj,GdInt board_type, GdBool* ret_value);
// SpxPlatform
typedef void (*GDExtensionSpxPlatformSetWindowSize)(GdInt width, GdInt height);
typedef void (*GDExtensionSpxPlatformGetWindowSize)(GdVec2* ret_value);
Expand Down Expand Up @@ -266,6 +267,8 @@ typedef void (*GDExtensionSpxSpriteSetRotation)(GdObj obj, GdFloat rot);
typedef void (*GDExtensionSpxSpriteGetRotation)(GdObj obj, GdFloat* ret_value);
typedef void (*GDExtensionSpxSpriteSetScale)(GdObj obj, GdVec2 scale);
typedef void (*GDExtensionSpxSpriteGetScale)(GdObj obj, GdVec2* ret_value);
typedef void (*GDExtensionSpxSpriteSetRenderScale)(GdObj obj, GdVec2 scale);
typedef void (*GDExtensionSpxSpriteGetRenderScale)(GdObj obj, GdVec2* ret_value);
typedef void (*GDExtensionSpxSpriteSetColor)(GdObj obj, GdColor color);
typedef void (*GDExtensionSpxSpriteGetColor)(GdObj obj, GdColor* ret_value);
typedef void (*GDExtensionSpxSpriteSetTextureAltas)(GdObj obj, GdString path, GdRect2 rect2);
Expand Down
85 changes: 78 additions & 7 deletions core/extension/spx_physic_mgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,20 @@

#include "spx_physic_mgr.h"

#include "spx_sprite.h"
#include "scene/resources/circle_shape_2d.h"
#include "scene/resources/world_2d.h"
#include "servers/physics_server_2d.h"
#include "servers/physics_server_3d.h"
#include "spx_sprite.h"
#include "spx_sprite_mgr.h"

#include "scene/2d/camera_2d.h"
#include "scene/2d/collision_shape_2d.h"
#include "scene/main/window.h"
#include "scene/resources/rectangle_shape_2d.h"
#include "spx_engine.h"
#include "spx_sprite_mgr.h"

#define spriteMgr SpxEngine::get_singleton()->get_sprite()

GdObj SpxPhysicMgr::raycast(GdVec2 from, GdVec2 to, GdInt collision_mask) {
auto node = (Node2D *)get_root();
Expand All @@ -43,15 +52,15 @@ GdObj SpxPhysicMgr::raycast(GdVec2 from, GdVec2 to, GdInt collision_mask) {
PhysicsDirectSpaceState2D::RayResult result;
PhysicsDirectSpaceState2D::RayParameters params;
// flip y axis
from = GdVec2{ from.x, -from.y };
to = GdVec2{ to.x, -to.y };
from = GdVec2{ from.x, -from.y };
to = GdVec2{ to.x, -to.y };
params.from = from;
params.to = to;
params.collision_mask = (uint32_t)collision_mask;
bool hit = space_state->intersect_ray(params, result);
if (hit) {
SpxSprite *collider = dynamic_cast<SpxSprite *>(result.collider);
if(collider != nullptr) {
if (collider != nullptr) {
return collider->get_gid();
}
}
Expand All @@ -65,8 +74,8 @@ GdBool SpxPhysicMgr::check_collision(GdVec2 from, GdVec2 to, GdInt collision_mas
PhysicsDirectSpaceState2D::RayParameters params;

// flip y axis
from = GdVec2{ from.x, -from.y };
to = GdVec2{ to.x, -to.y };
from = GdVec2{ from.x, -from.y };
to = GdVec2{ to.x, -to.y };
params.from = from;
params.to = to;
params.collision_mask = (uint32_t)collision_mask;
Expand All @@ -75,3 +84,65 @@ GdBool SpxPhysicMgr::check_collision(GdVec2 from, GdVec2 to, GdInt collision_mas
bool hit = space_state->intersect_ray(params, result);
return hit;
}
const GdInt BOUND_CAM_LEFT = 1 << 0;
const GdInt BOUND_CAM_TOP = 1 << 1;
const GdInt BOUND_CAM_RIGHT = 1 << 2;
const GdInt BOUND_CAM_BOTTOM = 1 << 3;
const GdInt BOUND_CAM_ALL = BOUND_CAM_LEFT | BOUND_CAM_TOP | BOUND_CAM_TOP | BOUND_CAM_BOTTOM;

GdInt SpxPhysicMgr::check_touched_camera_boundaries(GdObj obj) {
auto sprite = spriteMgr->get_sprite(obj);
if (sprite == nullptr) {
print_error("try to get property of a null sprite gid=" + itos(obj));
return false;
}
Transform2D sprite_transform = sprite->get_global_transform();

CollisionShape2D *collision_shape = sprite->get_trigger();
if (!collision_shape) {
return false;
}
Ref<Shape2D> sprite_shape = collision_shape->get_shape();
if (sprite_shape.is_null()) {
return false;
}

Camera2D *camera = get_tree()->get_root()->get_camera_2d();
if (!camera) {
return false;
}
Transform2D camera_transform = camera->get_global_transform();

Vector2 viewport_size = camera->get_viewport_rect().size;
Vector2 zoom = camera->get_zoom();
Vector2 half_size = (viewport_size * zoom) * 0.5;
Vector2 camera_position = camera_transform.get_origin();

Ref<RectangleShape2D> vertical_edge_shape;
vertical_edge_shape.instantiate();
vertical_edge_shape->set_size(Vector2(1, half_size.y));

Ref<RectangleShape2D> horizontal_edge_shape;
horizontal_edge_shape.instantiate();
horizontal_edge_shape->set_size(Vector2(half_size.x, 1));

Transform2D left_edge_transform(0, camera_position + Vector2(-half_size.x, 0));
Transform2D right_edge_transform(0, camera_position + Vector2(half_size.x, 0));
Transform2D top_edge_transform(0, camera_position + Vector2(0, -half_size.y));
Transform2D bottom_edge_transform(0, camera_position + Vector2(0, half_size.y));

bool is_colliding_left = sprite_shape->collide(sprite_transform, vertical_edge_shape, left_edge_transform);
bool is_colliding_right = sprite_shape->collide(sprite_transform, vertical_edge_shape, right_edge_transform);
bool is_colliding_top = sprite_shape->collide(sprite_transform, horizontal_edge_shape, top_edge_transform);
bool is_colliding_bottom = sprite_shape->collide(sprite_transform, horizontal_edge_shape, bottom_edge_transform);
GdInt result = 0;
result += is_colliding_top ? 1 << BOUND_CAM_TOP : 0;
result += is_colliding_right ? 1 << BOUND_CAM_RIGHT : 0;
result += is_colliding_bottom ? 1 << BOUND_CAM_BOTTOM : 0;
result += is_colliding_left ? 1 << BOUND_CAM_LEFT : 0;
return is_colliding_left || is_colliding_right || is_colliding_top || is_colliding_bottom;
}
GdBool SpxPhysicMgr::check_touched_camera_boundary(GdObj obj, GdInt board_type) {
auto result = check_touched_camera_boundaries(obj);
return (result & board_type) != 0;
}
2 changes: 2 additions & 0 deletions core/extension/spx_physic_mgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ class SpxPhysicMgr : SpxBaseMgr {
public:
GdObj raycast(GdVec2 from, GdVec2 to, GdInt collision_mask);
GdBool check_collision(GdVec2 from, GdVec2 to, GdInt collision_mask, GdBool collide_with_areas, GdBool collide_with_bodies);
GdInt check_touched_camera_boundaries(GdObj obj) ;
GdBool check_touched_camera_boundary(GdObj obj,GdInt board_type);
};

#endif // SPX_PHYSIC_MGR_H
6 changes: 6 additions & 0 deletions core/extension/spx_sprite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -481,3 +481,9 @@ GdBool SpxSprite::check_collision_with_point(GdVec2 point, GdBool is_trigger) {
}
return this_shape->get_shape()->_edit_is_selected_on_click(point, 0);
}
void SpxSprite::set_render_scale(GdVec2 scale) {
anim2d->set_scale(scale);
}
GdVec2 SpxSprite::get_render_scale() {
return anim2d->get_scale();
}
6 changes: 5 additions & 1 deletion core/extension/spx_sprite.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ class SpxSprite : public CharacterBody2D {
CollisionShape2D *trigger2d;
CollisionShape2D *collider2d;
VisibleOnScreenNotifier2D *visible_notifier;

public:
CollisionShape2D * get_trigger(){ return trigger2d;}
public:
template <typename T>
T *get_component(GdBool recursive = false);
Expand Down Expand Up @@ -155,6 +156,9 @@ class SpxSprite : public CharacterBody2D {
CollisionShape2D* get_collider(bool is_trigger = false);
GdBool check_collision(SpxSprite *other, GdBool is_src_trigger = true,GdBool is_dst_trigger = true);
GdBool check_collision_with_point(GdVec2 point, GdBool is_trigger = true);

void set_render_scale(GdVec2 scale);
GdVec2 get_render_scale();
};

template <typename T> T *SpxSprite::get_component(Node *node, GdBool recursive) {
Expand Down
12 changes: 12 additions & 0 deletions platform/web/godot_js_spx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,10 @@ void gdspx_physic_check_collision(GdVec2* from,GdVec2* to,GdInt* collision_mask,
*ret_val = physicMgr->check_collision(*from, *to, *collision_mask, *collide_with_areas, *collide_with_bodies);
}
EMSCRIPTEN_KEEPALIVE
void gdspx_physic_check_touched_camera_boundary(GdObj* obj,GdInt* board_type,GdBool* ret_val) {
*ret_val = physicMgr->check_touched_camera_boundary(*obj, *board_type);
}
EMSCRIPTEN_KEEPALIVE
void gdspx_platform_set_window_size(GdInt* width,GdInt* height) {
platformMgr->set_window_size(*width, *height);
}
Expand Down Expand Up @@ -311,6 +315,14 @@ void gdspx_sprite_get_scale(GdObj* obj,GdVec2* ret_val) {
*ret_val = spriteMgr->get_scale(*obj);
}
EMSCRIPTEN_KEEPALIVE
void gdspx_sprite_set_render_scale(GdObj* obj,GdVec2* scale) {
spriteMgr->set_render_scale(*obj, *scale);
}
EMSCRIPTEN_KEEPALIVE
void gdspx_sprite_get_render_scale(GdObj* obj,GdVec2* ret_val) {
*ret_val = spriteMgr->get_render_scale(*obj);
}
EMSCRIPTEN_KEEPALIVE
void gdspx_sprite_set_color(GdObj* obj,GdColor* color) {
spriteMgr->set_color(*obj, *color);
}
Expand Down
32 changes: 32 additions & 0 deletions platform/web/js/engine/gdspx.js
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,18 @@ function gdspx_physic_check_collision(from,to,collision_mask,collide_with_areas,
FreeGdBool(_retValue);
return _finalRetValue
}
function gdspx_physic_check_touched_camera_boundary(obj,board_type) {
_gdFuncPtr = GodotEngine.rtenv['_gdspx_physic_check_touched_camera_boundary'];
_retValue = AllocGdBool();
_arg0 = ToGdObj(obj);
_arg1 = ToGdInt(board_type);
_gdFuncPtr(_arg0, _arg1, _retValue);
FreeGdObj(_arg0);
FreeGdInt(_arg1);
_finalRetValue = ToJsBool(_retValue);
FreeGdBool(_retValue);
return _finalRetValue
}
function gdspx_platform_set_window_size(width,height) {
_gdFuncPtr = GodotEngine.rtenv['_gdspx_platform_set_window_size'];

Expand Down Expand Up @@ -605,6 +617,26 @@ function gdspx_sprite_get_scale(obj) {
FreeGdVec2(_retValue);
return _finalRetValue
}
function gdspx_sprite_set_render_scale(obj,scale) {
_gdFuncPtr = GodotEngine.rtenv['_gdspx_sprite_set_render_scale'];

_arg0 = ToGdObj(obj);
_arg1 = ToGdVec2(scale);
_gdFuncPtr(_arg0, _arg1);
FreeGdObj(_arg0);
FreeGdVec2(_arg1);

}
function gdspx_sprite_get_render_scale(obj) {
_gdFuncPtr = GodotEngine.rtenv['_gdspx_sprite_get_render_scale'];
_retValue = AllocGdVec2();
_arg0 = ToGdObj(obj);
_gdFuncPtr(_arg0, _retValue);
FreeGdObj(_arg0);
_finalRetValue = ToJsVec2(_retValue);
FreeGdVec2(_retValue);
return _finalRetValue
}
function gdspx_sprite_set_color(obj,color) {
_gdFuncPtr = GodotEngine.rtenv['_gdspx_sprite_set_color'];

Expand Down

0 comments on commit 32628cd

Please sign in to comment.