You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
114 lines
2.8 KiB
114 lines
2.8 KiB
//
|
|
// Path.cpp
|
|
// OSXGLEssentials
|
|
//
|
|
// Created by Joshua Moerman on 10/03/14.
|
|
//
|
|
//
|
|
|
|
#include "Path.h"
|
|
|
|
#include <cmath>
|
|
#include <random>
|
|
|
|
// A default thingy which makes implementing it easier. A subclass only have to
|
|
// provide new points, which will be connected (So this is not suitable for
|
|
// e.g. jumps or circles)
|
|
struct DefaultBuilder : PathBuilder {
|
|
// number of vertices in one chunk
|
|
static constexpr auto chainLength = 8;
|
|
|
|
DefaultBuilder(b2World & world_, b2Vec2 startingPoint)
|
|
: world(world_)
|
|
, previous(startingPoint)
|
|
, current(startingPoint)
|
|
{
|
|
fixture.friction = 2.0;
|
|
}
|
|
|
|
void buildUpTo(float x) override {
|
|
b2BodyDef groundBodyDef;
|
|
groundBodyDef.position = {0.0f, -10.0f};
|
|
|
|
while(current.x < x){
|
|
auto oldPreviousPoint = previous;
|
|
|
|
b2Vec2 chainPositions[chainLength];
|
|
chainPositions[0] = current;
|
|
for(int i = 1; i < chainLength; ++i){
|
|
chainPositions[i] = next;
|
|
previous = current;
|
|
current = next;
|
|
// we always generate one more, for the b2 ghost vertices
|
|
generate_next();
|
|
}
|
|
|
|
b2ChainShape chain;
|
|
chain.CreateChain(chainPositions, chainLength);
|
|
chain.SetPrevVertex(oldPreviousPoint);
|
|
chain.SetNextVertex(next);
|
|
|
|
fixture.shape = &chain;
|
|
auto groundBody = world.CreateBody(&groundBodyDef);
|
|
groundBody->CreateFixture(&fixture);
|
|
}
|
|
}
|
|
|
|
virtual void generate_next() = 0;
|
|
|
|
protected:
|
|
std::mt19937 generator{0};
|
|
std::uniform_real_distribution<float> distribution{-1.0, 1.0};
|
|
|
|
b2World & world;
|
|
|
|
b2Vec2 previous;
|
|
b2Vec2 current;
|
|
b2Vec2 next;
|
|
|
|
b2FixtureDef fixture;
|
|
};
|
|
|
|
// Creates random terrain, roughness comes with time
|
|
struct RandomBuilder : DefaultBuilder {
|
|
RandomBuilder(b2World & world_, b2Vec2 startingPoint)
|
|
: DefaultBuilder(world_, startingPoint)
|
|
{
|
|
generate_next();
|
|
}
|
|
|
|
virtual void generate_next() override {
|
|
auto t = current.x;
|
|
|
|
float m = std::sqrt(0.001f*t + 1) - 1;
|
|
if(t <= 0) m = 0;
|
|
float slope = m * distribution(generator);
|
|
|
|
auto rot = b2Rot(slope);
|
|
next = b2Mul(rot, {10, 0}) + current;
|
|
}
|
|
};
|
|
|
|
// A flat road
|
|
struct FlatBuilder : DefaultBuilder {
|
|
FlatBuilder(b2World & world_, b2Vec2 startingPoint)
|
|
: DefaultBuilder(world_, startingPoint)
|
|
{
|
|
generate_next();
|
|
}
|
|
|
|
virtual void generate_next() override {
|
|
b2Vec2 newPiece = {10, 0};
|
|
next = newPiece + current;
|
|
}
|
|
};
|
|
|
|
Path::Path(b2World & world_)
|
|
: world(world_)
|
|
, impl(new RandomBuilder(world, {-20, 0}))
|
|
{}
|
|
|
|
void Path::buildUpTo(float x){
|
|
impl->buildUpTo(x);
|
|
}
|
|
|
|
|