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_8XZ#=yWJp1k%11A}#|r;B4qMO-ou2gi@| z23&5=2_`Jqi3UE!113_Z7AqP^F<~bh)(c3yZRlCH^`d|TZzC3hvF#$?i3}y|k{}Ib ziUwB9MzdD9<8sCeF{Z_`6D}Sx!|8_YU^l33!(u(i2Hr-H6QpoEp$_7NRijQ|HkvgW z3ZUdT8Va-y1;$;i45u?9_}2-nSh0e^dd1?!%KgZu`XkOfG9``H^YqSG4AHwm#3Ow2X4GFZh*yv+51lR@@F0Y?C|vQ!dY_ex48~0v$&l; z&9z9WXv5U$JMK7V)*1vneUMSkD^G3Kp@mA>$ zx!lz->bYY8itWrUvVn>Kxdgk08B)um4j7S_10{WRlFjqNS*g}EF( z=NfvJZNOFjGVW?U@Pg-rfp<f0v$r&> z^?JbB{429|u2lGBryldvaHaD8E$8koeyUS@%0KJ5bkJ?)EuU2Po@%~WRhMC!;hyf` zR=t~0NKCq6wPMe;8WaA$HijaO1DC{qozPo2@m{0cNm(7`lUL$y`>wv?`Syd9*1u(C z6^~Box4cmdzn_t5y2B}9!D;WJ+ss?|T%)G5H!s~If42V!*e4lYl2|Ld#)|?AqCtVd zbLoiNt0=dk>vloay&8I-Gq##d4l2&v>LxaQ=L=;M=DlfCLw%fytu`& z8aw_5BPA$g z+aX~OiX=8nVW^Ya;z7BtXW1)6@sYyB_@_QV?#ia>EgwU z%~oqb$!hW^XdGcEC!DN6RRrEvEjYw!nzBco0P1p#hQeqlK#CYhyKOX6j^>Eb95I?B zpe+k%P)2)7_s~~|3;d3HR`}LXjpy|WInNi{PhR4A1nq9&yP-nfWvuM zPlNQ7Ik;Vh%{^hvYaI9ho?X5eVvBEb{cS_fKrY4sM-okEPDV3>^N5%e91@v9XK|vf z6jQSzxO(aBz^q<)8wCZxGrT8jkQ*b&t@S|=o78Z^7r6z|l|`4F%Y4y3w>SnifXW0-|F&a_R^M``*Vh`s+TFGB7YO Nc)I$ztaD0e0szh+pP&E$ literal 18144 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 VoL?tzy#Sq{;_2$=vd$@?2>=pfA}as@ diff --git a/examples/physics_forces.c b/examples/physics_forces.c index 2afd14ee3..74b40d57e 100644 --- a/examples/physics_forces.c +++ b/examples/physics_forces.c @@ -12,9 +12,12 @@ #include "raylib.h" #include "math.h" -#define FORCE_AMOUNT 5.0f -#define FORCE_RADIUS 150 -#define LINE_LENGTH 100 +#define FORCE_AMOUNT 5.0f +#define FORCE_RADIUS 150 +#define LINE_LENGTH 75 +#define TRIANGLE_LENGTH 12 + +void DrawRigidbodyCircle(PhysicObject *obj, Color color); int main() { @@ -42,6 +45,7 @@ int main() } // Create circles physic objects + // NOTE: when creating circle physic objects, transform.scale must be { 0, 0 } and object radius must be defined in collider.radius and use this value to draw the circle. PhysicObject *circles[3]; for (int i = 0; i < 3; i++) { @@ -111,14 +115,23 @@ int main() // Draw force radius DrawCircleLines(mousePosition.x, mousePosition.y, FORCE_RADIUS, BLACK); - // Draw direction line + // Draw direction lines if (CheckCollisionPointCircle((Vector2){ rectangles[i]->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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 literal 0 HcmV?d00001 diff --git a/src/physac.c b/src/physac.c index 718a06bb4..e3f956bad 100644 --- a/src/physac.c +++ b/src/physac.c @@ -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. @@ -75,10 +75,7 @@ void InitPhysics(Vector2 gravity) void UpdatePhysics() { // Reset all physic objects is grounded state - for (int i = 0; i < physicObjectsCount; i++) - { - if (physicObjects[i]->rigidbody.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 {