//////////////////////////////
// @file
// Test - using box2D with entities
//
// Entity movement is constrained in y, z axis - Corresponding to box2D x, y
//////////////////////////////
#include <acknex.h>
#include <default.c>
#include "ackb2d.h"
#define PI 3.14159265
#define INV_PI 0.318309886
// Variables
b2World *world = NULL;
VECTOR gravity;
var phys_scale = 30;
// Box update function
void box_update()
{
// The current entity body
b2Body *box_body = NULL;
// Create a box2D representation for the entity
b2BodyDef *bodyDef = NULL;
bodyDef = b2BodyDef_Create();
b2BodyDef_SetType(bodyDef, B2_DYNAMICBODY);
b2BodyDef_SetPosition(bodyDef, vector(-my->y / phys_scale, my->z / phys_scale, 0.0));
// Body
box_body = b2World_CreateBody(world, bodyDef);
/// Box Polygon
b2PolygonShape *dynamicBox = NULL;
dynamicBox = b2PolygonShape_Create();
b2PolygonShape_SetAsBox1(dynamicBox, 8 / phys_scale, 8 / phys_scale);
// Fixture
b2FixtureDef *fixtureDef = NULL;
fixtureDef = b2FixtureDef_Create();
b2FixtureDef_SetShape(fixtureDef, dynamicBox);
b2FixtureDef_SetDensity(fixtureDef, 1.0);
b2FixtureDef_SetRestitution(fixtureDef, 0.2);
b2FixtureDef_SetFriction(fixtureDef, 0.3);
b2Body_CreateFixture(box_body, fixtureDef);
// Destroy unused objects
b2BodyDef_Destroy(bodyDef);
b2PolygonShape_Destroy(dynamicBox);
b2FixtureDef_Destroy(fixtureDef);
// Color entity
set(my, LIGHT);
vec_set(my->blue, vector(10+random(150), random(10), random(150)));
// Display shadow
set(my, SHADOW);
VECTOR position;
var angle;
while(1)
{
// Get properties from physics engine
b2Body_GetPosition(box_body, &position);
angle = b2Body_GetAngle(box_body);
// Copy changes into shape objects
vec_set(my.x, vector(0, position.x * phys_scale, position.y * phys_scale));
my->roll = 180 * angle * INV_PI;
wait(1);
}
}
// Sphere update function
void sphere_update()
{
// The current entity body
b2Body *box_body = NULL;
// Create a box2D representation for the entity
b2BodyDef *bodyDef = NULL;
bodyDef = b2BodyDef_Create();
b2BodyDef_SetType(bodyDef, B2_DYNAMICBODY);
b2BodyDef_SetPosition(bodyDef, vector(-my->y / phys_scale, my->z / phys_scale, 0.0));
// Body
box_body = b2World_CreateBody(world, bodyDef);
/// Box circle
b2CircleShape *dynamicCircle = b2CircleShape_Create();
b2CircleShape_SetRadius(dynamicCircle, 8 / phys_scale);
// Fixture
b2FixtureDef *fixtureDef = NULL;
fixtureDef = b2FixtureDef_Create();
b2FixtureDef_SetShape(fixtureDef, dynamicCircle);
b2FixtureDef_SetDensity(fixtureDef, 1.0);
b2FixtureDef_SetRestitution(fixtureDef, 0.6);
b2FixtureDef_SetFriction(fixtureDef, 0.3);
b2Body_CreateFixture(box_body, fixtureDef);
// Destroy unused objects
b2BodyDef_Destroy(bodyDef);
b2CircleShape_Destroy(dynamicCircle);
b2FixtureDef_Destroy(fixtureDef);
// Color entity
set(my, LIGHT);
vec_set(my->blue, vector(10+random(150), random(10), random(150)));
// Display shadow
set(my, SHADOW);
VECTOR position;
var angle;
while(1)
{
// Get properties from physics engine
b2Body_GetPosition(box_body, &position);
angle = b2Body_GetAngle(box_body);
// Copy changes into shape objects
vec_set(my.x, vector(0, position.x * phys_scale, position.y * phys_scale));
my->roll = 180 * angle * INV_PI;
wait(1);
}
}
//////////////////////////////
// Close engine on escape
//////////////////////////////
void esc_handler()
{
//////////////////////////////
// Destroy world
//////////////////////////////
b2World_Destroy(world);
sys_exit("");
}
// Main test
void main()
{
// Set video mode
video_mode = 4;
// limit fps to be in sync with box2D timestep
fps_max = 60;
// Randomize
random_seed(0);
// Shadow type
shadow_stencil = 2;
// Wait for graphics to be ready
// Wait for the execution of startup functions
wait(1);
// Set key handler
on_esc = esc_handler;
// load empty level
level_load(NULL);
vec_set(&gravity, vector(0.0, -10.0, 0.0));
var do_sleep = 1;
world = b2World_Create(&gravity, do_sleep);
// Set debug draw to default
ackDebugDraw *debug = ackDebugDraw_Create(phys_scale);
ackDebugDraw_SetFlags(debug, E_SHAPEBIT | E_JOINTBIT);
b2World_SetDebugDraw(world, debug);
// Create entities
ent_create("cube.mdl", vector(0, -8, 120), box_update);
ent_create("cube.mdl", vector(0, 8, 150), box_update);
ent_create("sphere.mdl", vector(0, -8, 200), sphere_update);
ent_create("sphere.mdl", vector(0, 8, 200), sphere_update);
// position camera
vec_set(camera.x, vector(-212, -3, 56));
//set(camera, ISOMETRIC);
/// Body def
b2BodyDef *groundBodyDef = NULL;
groundBodyDef = b2BodyDef_Create();
b2BodyDef_SetPosition(groundBodyDef, vector(0.0, -10.0, 0.0));
/// Body
b2Body *groundBody = b2World_CreateBody(world, groundBodyDef);
// Create ground entity
ENTITY *ground_ent = ent_create("cube.mdl", nullvector, NULL);
//set(ground_ent, LIGHT);
vec_set(ground_ent->blue, vector(0, 255, 255));
ground_ent->scale_x = 20;
ground_ent->scale_y = 40;
c_updatehull(ground_ent, 1);
ground_ent->z -= 8;
/// Ground Polygon
b2PolygonShape *groundBox = NULL;
groundBox = b2PolygonShape_Create();
b2PolygonShape_SetAsBox1(groundBox, 50.0, 10.0);
b2Body_CreateFixture2(groundBody, groundBox, 0);
var velocity_iterations = 6;
var position_iteration = 2;
var timeStep = 1.0 / 60.0;
while(1)
{
// Step in 2d world
b2World_Step(world, timeStep, velocity_iterations, position_iteration);
b2World_ClearForces(world);
wait(1);
}
}