Browse Source

Add sidewalk

master
C. J. Howard 6 years ago
parent
commit
2f6416c9ee
8 changed files with 146 additions and 145 deletions
  1. +1
    -1
      data
  2. +34
    -5
      src/application.cpp
  3. +13
    -2
      src/application.hpp
  4. +0
    -69
      src/game/ant.cpp
  5. +0
    -2
      src/game/pheromone-matrix.cpp
  6. +6
    -3
      src/game/tool.cpp
  7. +3
    -0
      src/game/tool.hpp
  8. +89
    -63
      src/states/game-state.cpp

+ 1
- 1
data

@ -1 +1 @@
Subproject commit f6fed6a858a3b4d71b879df0267b2881f270a18f
Subproject commit 463807e1e360d62997874f3a5b185f93c9999b50

+ 34
- 5
src/application.cpp View File

@ -705,7 +705,8 @@ bool Application::loadModels()
forcepsModel = modelLoader->load("data/models/forceps.mdl");
lensModel = modelLoader->load("data/models/lens.mdl");
brushModel = modelLoader->load("data/models/brush.mdl");
biomeFloorModel = modelLoader->load("data/models/desert-floor.mdl");
sidewalkPanelModel = modelLoader->load("data/models/sidewalk-panel.mdl");
soilModel = modelLoader->load("data/models/soil.mdl");
if (!antModel || !antHillModel || !nestModel || !forcepsModel || !lensModel || !brushModel)
{
@ -717,7 +718,21 @@ bool Application::loadModels()
antHillModelInstance.setModel(antHillModel);
antHillModelInstance.setRotation(glm::angleAxis(glm::radians(90.0f), Vector3(1, 0, 0)));
nestModelInstance.setModel(nestModel);
biomeFloorModelInstance.setModel(biomeFloorModel);
sidewalkPanelInstance.setModel(sidewalkPanelModel);
sidewalkPanelInstance1.setModel(sidewalkPanelModel);
sidewalkPanelInstance2.setModel(sidewalkPanelModel);
sidewalkPanelInstance3.setModel(sidewalkPanelModel);
sidewalkPanelInstance4.setModel(sidewalkPanelModel);
soilInstance.setModel(soilModel);
float offset = 100.5f;
sidewalkPanelInstance1.setTranslation(Vector3(-offset, 0.0f, 0.0f));
sidewalkPanelInstance2.setTranslation(Vector3(-offset * 2.0f, 0.0f, 0.0f));
sidewalkPanelInstance3.setTranslation(Vector3(offset, 0.0f, 0.0f));
sidewalkPanelInstance4.setTranslation(Vector3(offset * 2.0f, 0.0f, 0.0f));
soilInstance.setTranslation(Vector3(0.0f, -3.0f, 0.0f));
return true;
}
@ -1446,7 +1461,7 @@ bool Application::loadUI()
pauseMenu->setLineSpacing(1.0f);
pauseMenuResumeItem = pauseMenu->addItem();
pauseMenuResumeItem->setActivatedCallback(std::bind(&Application::unpauseSimulation, this));
pauseMenuResumeItem->setActivatedCallback(std::bind(&Application::closePauseMenu, this));
pauseMenuLevelsItem = pauseMenu->addItem();
pauseMenuLevelsItem->setActivatedCallback(std::bind(&Application::openMenu, this, levelsMenu));
@ -1562,6 +1577,8 @@ bool Application::loadControls()
gameControlProfile->registerControl("turn-left", &turnLeft);
gameControlProfile->registerControl("turn-right", &turnRight);
gameControlProfile->registerControl("toggle-pause", &togglePause);
gameControlProfile->registerControl("toggle-pause-menu", &togglePauseMenu);
gameControlProfile->registerControl("fast-forward", &fastForward);
cameraMoveForward.bindKey(keyboard, SDL_SCANCODE_W);
cameraMoveBack.bindKey(keyboard, SDL_SCANCODE_S);
@ -1580,6 +1597,8 @@ bool Application::loadControls()
turnLeft.bindKey(keyboard, SDL_SCANCODE_LEFT);
turnRight.bindKey(keyboard, SDL_SCANCODE_RIGHT);
togglePause.bindKey(keyboard, SDL_SCANCODE_SPACE);
togglePauseMenu.bindKey(keyboard, SDL_SCANCODE_ESCAPE);
fastForward.bindKey(keyboard, SDL_SCANCODE_F);
return true;
}
@ -2054,7 +2073,7 @@ void Application::loadLevel(std::size_t index)
currentLevel->load(*levelParams);
PhysicalMaterial* material = materialLoader->load("data/materials/debug-terrain-surface.mtl");
material->albedoOpacityMap = &pheromoneTexture;
//material->albedoOpacityMap = &pheromoneTexture;
currentLevel->terrain.getSurfaceModel()->getGroup(0)->material = material;
}
@ -2087,6 +2106,16 @@ void Application::loadLevel()
*/
void Application::pauseSimulation()
{
simulationPaused = true;
}
void Application::unpauseSimulation()
{
simulationPaused = false;
}
void Application::openPauseMenu()
{
simulationPaused = true;
@ -2102,7 +2131,7 @@ void Application::pauseSimulation()
pauseMenu->select(0);
}
void Application::unpauseSimulation()
void Application::closePauseMenu()
{
simulationPaused = false;

+ 13
- 2
src/application.hpp View File

@ -110,6 +110,9 @@ public:
void pauseSimulation();
void unpauseSimulation();
void openPauseMenu();
void closePauseMenu();
void setDisplayDebugInfo(bool display);
std::u32string getLevelName(std::size_t world, std::size_t level) const;
@ -163,7 +166,12 @@ public:
ModelInstance antModelInstance;
ModelInstance antHillModelInstance;
ModelInstance nestModelInstance;
ModelInstance biomeFloorModelInstance;
ModelInstance sidewalkPanelInstance;
ModelInstance sidewalkPanelInstance1;
ModelInstance sidewalkPanelInstance2;
ModelInstance sidewalkPanelInstance3;
ModelInstance sidewalkPanelInstance4;
ModelInstance soilInstance;
// Graphics
Renderer renderer;
@ -242,6 +250,8 @@ public:
Control turnLeft;
Control turnRight;
Control togglePause;
Control togglePauseMenu;
Control fastForward;
Arcball arcball;
// Misc
@ -376,7 +386,8 @@ public:
Model* forcepsModel;
Model* lensModel;
Model* brushModel;
Model* biomeFloorModel;
Model* sidewalkPanelModel;
Model* soilModel;
// Game variables
Biosphere biosphere;

+ 0
- 69
src/game/ant.cpp View File

@ -220,76 +220,7 @@ void Ant::update(float dt)
// Update model instance
modelInstance.setTransform(transform);
}
// Locomotion
/*
As the ant moves forward, legs in the stance phase are kept grounded via IK. If IK constraints are violated, the swinging legs are grounded
and the grounded legs begin swinging.
Two poses are loaded from the model file: midswing and touchdown.
touchdown is the pose in which all legs are at the end of their swing phases and need to be grounded
midswing is the pose in which all legs are at the highest point in their swing phases
when a grounded leg enters the swing phases, its current pose is saved as the liftoff pose, then an animation is created using the liftoff pose, midswing pose, and touchdown pose.
*/
}
/*
Vector3 Ant::forage(const Vector3& leftReceptor, const Vector3& rightReceptor)
{
float leftSignal = 0.0f;
float rightSignal = 0.0f;
// Detect pheromones with left receptor
std::list<Pheromone*> leftPheromones;
colony->getPheromoneOctree()->query(AABB(leftReceptor, leftReceptor), &leftPheromones);
for (Pheromone* pheromone: leftPheromones)
{
Vector3 difference = pheromone->getPosition() - rightReceptor;
float distanceSquared = glm::dot(difference, difference);
if (distanceSquared <= pheromone->getRadiusSquared())
{
// Calculate attenuated pheromone strength using inverse-square law
float strength = pheromone->getStrength() / ((distanceSquared == 0.0f) ? 1.0f : distanceSquared);
leftSignal += strength;
}
}
// Detect pheromones with right receptor
std::list<Pheromone*> rightPheromones;
colony->getPheromoneOctree()->query(AABB(rightReceptor, rightReceptor), &rightPheromones);
for (Pheromone* pheromone: rightPheromones)
{
Vector3 difference = pheromone->getPosition() - rightReceptor;
float distanceSquared = glm::dot(difference, difference);
if (distanceSquared <= pheromone->getRadiusSquared())
{
// Calculate attenuated pheromone strength using inverse-square law
float strength = pheromone->getStrength() / ((distanceSquared == 0.0f) ? 1.0f : distanceSquared);
rightSignal += strength;
}
}
// Add noise
const float maxNoise = 0.1f;
leftSignal += frand(0.0f, maxNoise);
rightSignal += frand(0.0f, maxNoise);
if (leftSignal + rightSignal > 0.0f)
{
const float maxPheromoneTurningAngle = 0.1f;
// Use Weber's law (Perna et al.) to calculate turning angle based on pheromone signals
float turningAngle = maxPheromoneTurningAngle * ((leftSignal - rightSignal) / (leftSignal + rightSignal));
}
return Vector3(0.0f);
}
*/
void Ant::setState(Ant::State state)
{

+ 0
- 2
src/game/pheromone-matrix.cpp View File

@ -48,9 +48,7 @@ PheromoneMatrix::PheromoneMatrix(int columns, int rows, const Vector2& boundsMin
}
diffusionKernel[0][0] = 0.0083333f; diffusionKernel[0][1] = 0.0166667f; diffusionKernel[0][2] = 0.0083333f;
diffusionKernel[1][0] = 0.0166667f; diffusionKernel[1][1] = 0.9f; diffusionKernel[1][2] = 0.0166667f;
diffusionKernel[2][0] = 0.0083333f; diffusionKernel[2][1] = 0.0166667f; diffusionKernel[2][2] = 0.0083333f;
clear();

+ 6
- 3
src/game/tool.cpp View File

@ -38,7 +38,6 @@ Forceps::Forceps(const Model* model)
// Allocate pose and initialize to bind pose
pose = new Pose(model->getSkeleton());
pose->reset();
pose->concatenate();
// Setup model instance
modelInstance.setModel(model);
@ -82,6 +81,10 @@ Forceps::Forceps(const Model* model)
suspendedAnt = nullptr;
cameraController = nullptr;
pick = Vector3(0.0f);
// Open forceps
pinchAnimation->animate(pose, 0.0f);
pose->concatenate();
}
Forceps::~Forceps()
@ -370,7 +373,7 @@ Lens::Lens(const Model* model)
spotlight.setIntensity(10000.0f);
spotlight.setAttenuation(Vector3(1, 0, 1));
spotlight.setCutoff(glm::radians(45.0f));
spotlight.setExponent(700.0f);
spotlight.setExponent(1000.0f);
spotlight.setActive(false);
unfocusedDistance = 18.0f;
@ -496,7 +499,7 @@ Brush::Brush(const Model* model)
hoverDistance = 0.5f;
// Setup timing
float descentDuration = 0.1f;
float descentDuration = 0.05f;
float ascentDuration = 0.1f;
// Allocate tweener and and setup tweens

+ 3
- 0
src/game/tool.hpp View File

@ -203,6 +203,9 @@ inline Ant* Forceps::getSuspendedAnt() const
/**
* The lens tool can be used to burn ants.
*
* @see https://taylorpetrick.com/blog/post/dispersion-opengl
* @see https://taylorpetrick.com/portfolio/webgl/lense
*/
class Lens: public Tool
{

+ 89
- 63
src/states/game-state.cpp View File

@ -79,10 +79,15 @@ void GameState::enter()
// Add terrain to scene
application->defaultLayer->addObject(&application->currentLevel->terrainSurface);
//application->defaultLayer->addObject(&application->currentLevel->terrainSurface);
//application->defaultLayer->addObject(&application->currentLevel->terrainSubsurface);
//application->defaultLayer->addObject(&application->biomeFloorModelInstance);
application->defaultLayer->addObject(&application->sidewalkPanelInstance);
application->defaultLayer->addObject(&application->sidewalkPanelInstance1);
application->defaultLayer->addObject(&application->sidewalkPanelInstance2);
application->defaultLayer->addObject(&application->sidewalkPanelInstance3);
application->defaultLayer->addObject(&application->sidewalkPanelInstance4);
application->defaultLayer->addObject(&application->soilInstance);
// Spawn ants
for (int i = 0; i < 200; ++i)
{
@ -135,7 +140,7 @@ void GameState::enter()
void GameState::execute()
{
// Pause simulation
if (application->escape.isTriggered() && !application->escape.wasTriggered())
if (application->togglePause.isTriggered() && !application->togglePause.wasTriggered())
{
if (application->simulationPaused)
{
@ -146,6 +151,18 @@ void GameState::execute()
application->pauseSimulation();
}
}
// Open pause menu
else if (application->togglePauseMenu.isTriggered() && !application->togglePauseMenu.wasTriggered())
{
if (application->activeMenu == application->pauseMenu)
{
application->closePauseMenu();
}
else
{
application->openPauseMenu();
}
}
// Navigate menu
if (application->activeMenu != nullptr)
@ -252,63 +269,9 @@ void GameState::execute()
pick = pickingRay.extrapolate(std::get<1>(result));
}
*/
static bool bla = false;
bla = !bla;
// Update pheromone texture
if (bla)
{
float cmyk[4];
float rgb[3];
const float* bufferH = application->colony->getHomingMatrix()->getActiveBuffer();
const float* bufferR = application->colony->getRecruitmentMatrix()->getActiveBuffer();
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, application->pheromonePBO);
GLubyte* data = (GLubyte*)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
GLubyte* channel = data;
std::size_t index = 0;
for (int y = 0; y < application->pheromoneTexture.getHeight(); ++y)
{
for (int x = 0; x < application->pheromoneTexture.getWidth(); ++x)
{
float concentrationH = std::min<float>(1.0f, bufferH[index]) * 0.35f;
float concentrationR = std::min<float>(1.0f, bufferR[index]) * 0.35f;
cmyk[0] = std::min<float>(1.0f, concentrationH * HOMING_PHEROMONE_COLOR[0] + concentrationR * RECRUITMENT_PHEROMONE_COLOR[0]);
cmyk[1] = std::min<float>(1.0f, concentrationH * HOMING_PHEROMONE_COLOR[1] + concentrationR * RECRUITMENT_PHEROMONE_COLOR[1]);
cmyk[2] = std::min<float>(1.0f, concentrationH * HOMING_PHEROMONE_COLOR[2] + concentrationR * RECRUITMENT_PHEROMONE_COLOR[2]);
cmyk[3] = 0.35f;
cmykToRGB(cmyk, rgb);
GLubyte b = static_cast<GLubyte>(std::min<float>(255.0f, rgb[2] * 255.0f));
GLubyte g = static_cast<GLubyte>(std::min<float>(255.0f, rgb[1] * 255.0f));
GLubyte r = static_cast<GLubyte>(std::min<float>(255.0f, rgb[0] * 255.0f));
*(channel++) = b;
*(channel++) = g;
*(channel++) = r;
*(channel++) = 255;
++index;
}
}
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
glBindTexture(GL_TEXTURE_2D, application->pheromoneTextureID);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, application->pheromoneTexture.getWidth(), application->pheromoneTexture.getHeight(), GL_BGRA, GL_UNSIGNED_BYTE, nullptr);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
}
application->colony->getHomingMatrix()->evaporate();
application->colony->getRecruitmentMatrix()->evaporate();
static int frame = 0;
if (frame++ % DIFFUSION_FRAME == 0)
{
application->colony->getHomingMatrix()->diffuse();
application->colony->getRecruitmentMatrix()->diffuse();
}
@ -360,7 +323,70 @@ void GameState::execute()
application->currentTool->update(application->dt);
}
application->colony->update(application->dt);
int iterations = application->fastForward.isTriggered() ? 10 : 1;
for (int iteration = 0; iteration < iterations; ++iteration)
{
application->colony->getHomingMatrix()->evaporate();
application->colony->getRecruitmentMatrix()->evaporate();
static int frame = 0;
if (frame++ % DIFFUSION_FRAME == 0)
{
application->colony->getHomingMatrix()->diffuse();
application->colony->getRecruitmentMatrix()->diffuse();
}
application->colony->update(application->dt);
}
static bool bla = false;
bla = !bla;
// Update pheromone texture
if (bla)
{
float cmyk[4];
float rgb[3];
const float* bufferH = application->colony->getHomingMatrix()->getActiveBuffer();
const float* bufferR = application->colony->getRecruitmentMatrix()->getActiveBuffer();
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, application->pheromonePBO);
GLubyte* data = (GLubyte*)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
GLubyte* channel = data;
std::size_t index = 0;
for (int y = 0; y < application->pheromoneTexture.getHeight(); ++y)
{
for (int x = 0; x < application->pheromoneTexture.getWidth(); ++x)
{
float concentrationH = std::min<float>(1.0f, bufferH[index]) * 0.35f;
float concentrationR = std::min<float>(1.0f, bufferR[index]) * 0.35f;
cmyk[0] = std::min<float>(1.0f, concentrationH * HOMING_PHEROMONE_COLOR[0] + concentrationR * RECRUITMENT_PHEROMONE_COLOR[0]);
cmyk[1] = std::min<float>(1.0f, concentrationH * HOMING_PHEROMONE_COLOR[1] + concentrationR * RECRUITMENT_PHEROMONE_COLOR[1]);
cmyk[2] = std::min<float>(1.0f, concentrationH * HOMING_PHEROMONE_COLOR[2] + concentrationR * RECRUITMENT_PHEROMONE_COLOR[2]);
cmyk[3] = 0.35f;
cmykToRGB(cmyk, rgb);
GLubyte b = static_cast<GLubyte>(std::min<float>(255.0f, rgb[2] * 255.0f));
GLubyte g = static_cast<GLubyte>(std::min<float>(255.0f, rgb[1] * 255.0f));
GLubyte r = static_cast<GLubyte>(std::min<float>(255.0f, rgb[0] * 255.0f));
*(channel++) = b;
*(channel++) = g;
*(channel++) = r;
*(channel++) = 255;
++index;
}
}
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
glBindTexture(GL_TEXTURE_2D, application->pheromoneTextureID);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, application->pheromoneTexture.getWidth(), application->pheromoneTexture.getHeight(), GL_BGRA, GL_UNSIGNED_BYTE, nullptr);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
}
}
}
@ -370,9 +396,9 @@ void GameState::exit()
application->mouse->removeMouseButtonObserver(this);
// Clear scene
application->defaultLayer->removeObject(&application->currentLevel->terrainSurface);
application->defaultLayer->removeObject(&application->currentLevel->terrainSubsurface);
application->defaultLayer->removeObject(&application->biomeFloorModelInstance);
//application->defaultLayer->removeObject(&application->currentLevel->terrainSurface);
//application->defaultLayer->removeObject(&application->currentLevel->terrainSubsurface);
application->defaultLayer->removeObject(&application->sidewalkPanelInstance);
application->defaultLayer->removeObject(application->forceps->getModelInstance());
application->defaultLayer->removeObject(application->lens->getModelInstance());
application->defaultLayer->removeObject(application->lens->getSpotlight());

Loading…
Cancel
Save