From 60223a358b691c2769c362597c49e124b045209c Mon Sep 17 00:00:00 2001 From: victorfisac Date: Wed, 23 Mar 2016 15:50:41 +0100 Subject: [PATCH] Physac redesign (3/3) Finally, physics update is handled in main thread using steps to get accuracy in collisions detection instead of moving it to a new thread. Examples are finished as simple and clear as I could. Finally, physac module is MORE simpler than in the first version, calculation everything by the same way for both types of physic objects. I tryed to add rotated physics a couple of times but I didn't get anything good to get a base to improve it. Maybe for the next version... No bugs or strange behaviours found during testing. --- examples/physics_basic_rigidbody.c | 9 +++-- examples/physics_basic_rigidbody.png | Bin 18144 -> 15294 bytes examples/physics_forces.c | 40 +++++++++++++++++----- examples/physics_forces.png | Bin 0 -> 17935 bytes src/physac.c | 49 ++++++++++++++------------- src/physac.h | 6 ++-- src/raylib.h | 4 +-- 7 files changed, 68 insertions(+), 40 deletions(-) create mode 100644 examples/physics_forces.png diff --git a/examples/physics_basic_rigidbody.c b/examples/physics_basic_rigidbody.c index f0edba723..917813ad8 100644 --- a/examples/physics_basic_rigidbody.c +++ b/examples/physics_basic_rigidbody.c @@ -65,7 +65,7 @@ int main() if (IsKeyDown('A')) rectangle->rigidbody.velocity.x = -MOVE_VELOCITY; else if (IsKeyDown('D')) rectangle->rigidbody.velocity.x = MOVE_VELOCITY; - // Check player 2 movement inputs + // Check square movement inputs if (IsKeyDown(KEY_UP) && square->rigidbody.isGrounded) square->rigidbody.velocity.y = JUMP_VELOCITY; if (IsKeyDown(KEY_LEFT)) square->rigidbody.velocity.x = -MOVE_VELOCITY; else if (IsKeyDown(KEY_RIGHT)) square->rigidbody.velocity.x = MOVE_VELOCITY; @@ -80,17 +80,20 @@ int main() ClearBackground(RAYWHITE); - // Convert transform values to rectangle data type variable - DrawRectangleRec(TransformToRectangle(floor->transform), DARKGRAY); + // Draw floor, roof and walls rectangles + DrawRectangleRec(TransformToRectangle(floor->transform), DARKGRAY); // Convert transform values to rectangle data type variable DrawRectangleRec(TransformToRectangle(leftWall->transform), DARKGRAY); DrawRectangleRec(TransformToRectangle(rightWall->transform), DARKGRAY); DrawRectangleRec(TransformToRectangle(roof->transform), DARKGRAY); + // Draw middle platform rectangle DrawRectangleRec(TransformToRectangle(platform->transform), DARKGRAY); + // Draw physic objects DrawRectangleRec(TransformToRectangle(rectangle->transform), RED); DrawRectangleRec(TransformToRectangle(square->transform), BLUE); + // Draw collider lines if debug is enabled if (isDebug) { DrawRectangleLines(floor->collider.bounds.x, floor->collider.bounds.y, floor->collider.bounds.width, floor->collider.bounds.height, GREEN); diff --git a/examples/physics_basic_rigidbody.png b/examples/physics_basic_rigidbody.png index 3d691637be9444f660fa21ac5ecd0371d8eb7f7c..52f265acf9a73ee1fcc41cdcc545fa841ce59354 100644 GIT binary patch literal 15294 zcmeAS@N?(olHy`uVBq!ia0y~yU{+vYU_8XZ1{4ubUVDOp!MfGc#WAEJE}4gelKR^Gp|3~5$djgf8r~-lCK7K8{f6I@~{0W*u`G* zoo`!(#?%tTYxi`0JdzEYoCXU)zBUjthD$8KM6k%v!m0 zd+iHF_qU%aO>)5!J#7pdA>~CF_Cga_nu3ZfV}-*i8wGcZH(l9!KkN8sho_Gh&XRM#&2?Cr#qIQIu0={k z8>UX*amP8c)*#^NgN#b2`vMXmw-;hBj)CQL2{*|5iPLU)%-yJ9(&YI5fnwPc=DV?1 zQ}W;J{GEU69p9|FMPW6( zruByp&A;}Pf9KO{2`iUngr4i0HhqGGT-H<7rB4kO*0`_zG~-T&2Ibq8g)&!jZc4+IiNQ(k9&YXqY-$VnOLp{^{PyfE&1$_Ka5n$S zteqhFILrMm}a=AJGfQvCKM8r zZdk3@bFIdNzpss2k2dr%tM1ul@=h6|kS5a<7 z*X@F;do}bvXKXc_98{dS)lF>r&KJri%zM+OhWz%FUAQ##htTX?PhbSRdMSJU$u#jL zyCz=|bcWk~(pWg&khN7< z+?fk)IJ9MO@O-lsSj?G?+>+P;an>%J6)z~P-hnbAUWB>7We#q_x3Sm`brE}t z2``4rV6Nra4~dPdI6Vo<@xTU7k~A(SfLmzT8fOqOU_t%K{2#c!EN<9TN7SNMgejh9$swND=f3k-Sk^ zpdu&(7|t7e@i-xZtvW(Kc2|jsCC=CokYu`e@nW;p8c?#D{0X~nfK>#+WJR!5OZ${P z>I6`iV>A>-LjhL2kEVsuv@n_$kedOcIbt+NjOK{Z9DzPSJX$V{mJ6fh!f3fLS}tH4 zlNc=>M@z@i(s8tO94#G3aOv2PYO)5nqQIc#fV=SWiyaC^EI-b_k>*{EIxr0yg5Lz0 zPplw+{Q>ON1X58sMzR2k`9j#SmM3lk30*K?AuMXEZZFRsoF8 z34)g;P%tMrBr=1};zVF>Y*qwUFTEX@)eCQqgzx6&U!eEZqxy8qZ$nbP)m3;6h=b{L@pP&E$ literal 18144 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 zru)transform.position.x + rectangles[i]->transform.scale.x/2, rectangles[i]->transform.position.y + rectangles[i]->transform.scale.y/2 }, mousePosition, FORCE_RADIUS)) { Vector2 direction = { rectangles[i]->transform.position.x + rectangles[i]->transform.scale.x/2 - mousePosition.x, rectangles[i]->transform.position.y + rectangles[i]->transform.scale.y/2 - mousePosition.y }; float angle = atan2l(direction.y, direction.x); - DrawLineV((Vector2){ rectangles[i]->transform.position.x + rectangles[i]->transform.scale.x/2, rectangles[i]->transform.position.y + rectangles[i]->transform.scale.y/2 }, - (Vector2){ rectangles[i]->transform.position.x + rectangles[i]->transform.scale.x/2 + (cos(angle)*LINE_LENGTH), rectangles[i]->transform.position.y + rectangles[i]->transform.scale.y/2 + (sin(angle)*LINE_LENGTH) }, BLACK); + // Calculate arrow start and end positions + Vector2 startPosition = { rectangles[i]->transform.position.x + rectangles[i]->transform.scale.x/2, rectangles[i]->transform.position.y + rectangles[i]->transform.scale.y/2 }; + Vector2 endPosition = { rectangles[i]->transform.position.x + rectangles[i]->transform.scale.x/2 + (cos(angle)*LINE_LENGTH), rectangles[i]->transform.position.y + rectangles[i]->transform.scale.y/2 + (sin(angle)*LINE_LENGTH) }; + + // Draw arrow line + DrawLineV(startPosition, endPosition, BLACK); + + // Draw arrow triangle + DrawTriangleLines((Vector2){ endPosition.x - cos(angle + 90*DEG2RAD)*LINE_LENGTH/TRIANGLE_LENGTH, endPosition.y - sin(angle + 90*DEG2RAD)*LINE_LENGTH/TRIANGLE_LENGTH }, + (Vector2){ endPosition.x + cos(angle + 90*DEG2RAD)*LINE_LENGTH/TRIANGLE_LENGTH, endPosition.y + sin(angle + 90*DEG2RAD)*LINE_LENGTH/TRIANGLE_LENGTH }, + (Vector2){ endPosition.x + cos(angle)*LINE_LENGTH/TRIANGLE_LENGTH*2, endPosition.y + sin(angle)*LINE_LENGTH/TRIANGLE_LENGTH*2 }, BLACK); } } @@ -131,14 +144,23 @@ int main() // Draw force radius DrawCircleLines(mousePosition.x, mousePosition.y, FORCE_RADIUS, BLACK); - // Draw direction line + // Draw direction lines if (CheckCollisionPointCircle((Vector2){ circles[i]->transform.position.x, circles[i]->transform.position.y }, mousePosition, FORCE_RADIUS)) { Vector2 direction = { circles[i]->transform.position.x - mousePosition.x, circles[i]->transform.position.y - mousePosition.y }; float angle = atan2l(direction.y, direction.x); - DrawLineV((Vector2){ circles[i]->transform.position.x, circles[i]->transform.position.y }, - (Vector2){ circles[i]->transform.position.x + (cos(angle)*LINE_LENGTH), circles[i]->transform.position.y + (sin(angle)*LINE_LENGTH) }, BLACK); + // Calculate arrow start and end positions + Vector2 startPosition = { circles[i]->transform.position.x, circles[i]->transform.position.y }; + Vector2 endPosition = { circles[i]->transform.position.x + (cos(angle)*LINE_LENGTH), circles[i]->transform.position.y + (sin(angle)*LINE_LENGTH) }; + + // Draw arrow line + DrawLineV(startPosition, endPosition, BLACK); + + // Draw arrow triangle + DrawTriangleLines((Vector2){ endPosition.x - cos(angle + 90*DEG2RAD)*LINE_LENGTH/TRIANGLE_LENGTH, endPosition.y - sin(angle + 90*DEG2RAD)*LINE_LENGTH/TRIANGLE_LENGTH }, + (Vector2){ endPosition.x + cos(angle + 90*DEG2RAD)*LINE_LENGTH/TRIANGLE_LENGTH, endPosition.y + sin(angle + 90*DEG2RAD)*LINE_LENGTH/TRIANGLE_LENGTH }, + (Vector2){ endPosition.x + cos(angle)*LINE_LENGTH/TRIANGLE_LENGTH*2, endPosition.y + sin(angle)*LINE_LENGTH/TRIANGLE_LENGTH*2 }, BLACK); } } diff --git a/examples/physics_forces.png b/examples/physics_forces.png new file mode 100644 index 0000000000000000000000000000000000000000..832bdbd9ecf79940c404362ba94916ac59f31022 GIT binary patch literal 17935 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 Q(Frigidbody.enabled) physicObjects[i]->rigidbody.isGrounded = false; - } + for (int i = 0; i < physicObjectsCount; i++) physicObjects[i]->rigidbody.isGrounded = false; for (int steps = 0; steps < PHYSICS_STEPS; steps++) { @@ -537,26 +534,32 @@ void ApplyForceAtPosition(Vector2 position, float force, float radius) { for(int i = 0; i < physicObjectsCount; i++) { - // Calculate direction and distance between force and physic object pposition - Vector2 distance = (Vector2){ physicObjects[i]->transform.position.x - position.x, physicObjects[i]->transform.position.y - position.y }; + if(physicObjects[i]->rigidbody.enabled) + { + // Calculate direction and distance between force and physic object pposition + Vector2 distance = (Vector2){ physicObjects[i]->transform.position.x - position.x, physicObjects[i]->transform.position.y - position.y }; - if(physicObjects[i]->collider.type == COLLIDER_RECTANGLE) - { - distance.x += physicObjects[i]->transform.scale.x/2; - distance.y += physicObjects[i]->transform.scale.y/2; - } - - float distanceLength = Vector2Length(distance); - - // Check if physic object is in force range - if(distanceLength <= radius) - { - // Normalize force direction - distance.x /= distanceLength; - distance.y /= -distanceLength; + if(physicObjects[i]->collider.type == COLLIDER_RECTANGLE) + { + distance.x += physicObjects[i]->transform.scale.x/2; + distance.y += physicObjects[i]->transform.scale.y/2; + } - // Apply force to the physic object - ApplyForce(physicObjects[i], (Vector2){ distance.x*force, distance.y*force }); + float distanceLength = Vector2Length(distance); + + // Check if physic object is in force range + if(distanceLength <= radius) + { + // Normalize force direction + distance.x /= distanceLength; + distance.y /= -distanceLength; + + // Calculate final force + Vector2 finalForce = { distance.x*force, distance.y*force }; + + // Apply force to the physic object + ApplyForce(physicObjects[i], finalForce); + } } } } diff --git a/src/physac.h b/src/physac.h index c70dbbe21..37544686b 100644 --- a/src/physac.h +++ b/src/physac.h @@ -2,7 +2,7 @@ * * [physac] raylib physics module - Basic functions to apply physics to 2D objects * -* Copyright (c) 2015 Victor Fisac and Ramon Santamaria +* Copyright (c) 2016 Victor Fisac and Ramon Santamaria * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. @@ -44,8 +44,8 @@ typedef enum { COLLIDER_CIRCLE, COLLIDER_RECTANGLE } ColliderType; typedef struct Transform { Vector2 position; - float rotation; - Vector2 scale; + float rotation; // Radians (not used) + Vector2 scale; // Just for rectangle physic objects, for circle physic objects use collider radius and keep scale as { 0, 0 } } Transform; typedef struct Rigidbody { diff --git a/src/raylib.h b/src/raylib.h index a87b58da3..1782fef39 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -498,8 +498,8 @@ typedef enum { COLLIDER_CIRCLE, COLLIDER_RECTANGLE } ColliderType; typedef struct Transform { Vector2 position; - float rotation; - Vector2 scale; + float rotation; // Radians (not used) + Vector2 scale; // Just for rectangle physic objects, for circle physic objects use collider radius and keep scale as { 0, 0 } } Transform; typedef struct Rigidbody {