Skip to content

Instantly share code, notes, and snippets.

@ChristianHohlfeld
Created October 4, 2018 20:22
Show Gist options
  • Save ChristianHohlfeld/bdf2b75f31d246f30d1539ce41208e8b to your computer and use it in GitHub Desktop.
Save ChristianHohlfeld/bdf2b75f31d246f30d1539ce41208e8b to your computer and use it in GitHub Desktop.
Physics.cpp
//
// Physics.cpp
// UDPTEST
//
// Created by Christian Hohlfeld on 22.09.18.
//
#include "Physics.h"
#include <cocos2d.h>
using namespace cocos2d;
Physics::Physics() : fixedTimestepAccumulator_(0)
{
b2Vec2 gravity(0, -9.8); //normal earth gravity, 9.8 m/s/s straight down!
world = new b2World(gravity);
world->SetAutoClearForces(false);
}
void Physics::tick(const float dt)
{
static const float FIXED_TIMESTEP = 1.0f / 60.0f;
static const int MAX_STEPS = 5;
static const int velocityIterations = 8;
static const int positionIterations = 1;
fixedTimestepAccumulator_ += dt;
int nSteps = static_cast<int>(floor(fixedTimestepAccumulator_/FIXED_TIMESTEP));
if (nSteps > 0) {
fixedTimestepAccumulator_ -= nSteps*FIXED_TIMESTEP;
}
assert("Invalid time accumulator state." && fixedTimestepAccumulator_ < FIXED_TIMESTEP + FLT_EPSILON);
if (nSteps > MAX_STEPS) {
nSteps = MAX_STEPS;
}
for (int i = 0; i < nSteps; ++i) {
if (i == nSteps - 1) {
renderFullStep();
}
world->Step(FIXED_TIMESTEP, velocityIterations, positionIterations);
}
world->ClearForces();
renderPartStep(fixedTimestepAccumulator_/FIXED_TIMESTEP);
}
void Physics::renderFullStep(){
for (b2Body *body = world->GetBodyList(); body; body = body->GetNext()) {
if (body->GetType() != b2_staticBody) {
CCNode *node = (CCNode *)body->GetUserData();
if (node != NULL) {
const b2Vec2 &bodyPos = body->GetPosition();
node->setPosition(CCPoint(bodyPos.x * PTM, bodyPos.y * PTM));
node->setRotation(-1 * CC_RADIANS_TO_DEGREES(body->GetAngle()));
}
}
}
}
void Physics::renderPartStep(const float alpha){
const float reminder = 1.0f - alpha;
for (b2Body *body = world->GetBodyList(); body; body = body->GetNext()) {
if (body->GetType() != b2_staticBody) {
Node *node = (Node *)body->GetUserData();
if (node != nullptr) {
const Point &prevPos = node->getPosition();
const b2Vec2 &bodyPos = body->GetPosition();
const Point renderPos((bodyPos.x * alpha + prevPos.x/PTM * reminder) * PTM,
(bodyPos.y * alpha + prevPos.y/PTM * reminder) * PTM);
node->setPosition(renderPos);
const float prevAngle = node->getRotation();
const float bodyAngle = -1 * CC_RADIANS_TO_DEGREES(body->GetAngle());
const float renderAngle = bodyAngle * alpha + prevAngle * reminder;
node->setRotation(renderAngle);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment