Browse Source

Add lens tool

master
C. J. Howard 6 years ago
parent
commit
3d007b6dff
12 changed files with 291 additions and 77 deletions
  1. +1
    -1
      data
  2. +1
    -1
      lib/emergent
  3. +30
    -5
      src/application.cpp
  4. +8
    -0
      src/application.hpp
  5. +60
    -10
      src/game/tool.cpp
  6. +90
    -33
      src/game/tool.hpp
  7. +10
    -0
      src/material-loader.cpp
  8. +1
    -0
      src/materials.hpp
  9. +60
    -9
      src/render-passes.cpp
  10. +15
    -8
      src/render-passes.hpp
  11. +6
    -6
      src/states/loading-state.cpp
  12. +9
    -4
      src/states/play-state.cpp

+ 1
- 1
data

@ -1 +1 @@
Subproject commit a9efe788f89a3b1bf6381d1be2ffec4d3adc52bc
Subproject commit 4477e2f006acafe4058764a7ccd95694e0f61502

+ 1
- 1
lib/emergent

@ -1 +1 @@
Subproject commit 0fb571191709569af7e342e281721ffa8cafd736
Subproject commit 19d7fcdb76c3516702a8723b2d125ed07e6dc0c9

+ 30
- 5
src/application.cpp View File

@ -591,9 +591,10 @@ bool Application::loadModels()
antHillModel = modelLoader->load("data/models/ant-hill.mdl");
nestModel = modelLoader->load("data/models/nest.mdl");
forcepsModel = modelLoader->load("data/models/forceps.mdl");
lensModel = modelLoader->load("data/models/lens.mdl");
biomeFloorModel = modelLoader->load("data/models/desert-floor.mdl");
if (!antModel || !antHillModel || !nestModel || !forcepsModel)
if (!antModel || !antHillModel || !nestModel || !forcepsModel || !lensModel)
{
return false;
}
@ -1064,10 +1065,10 @@ bool Application::loadUI()
// Create pie menu
pieMenu = new PieMenu(tweener);
pieMenu->addOption(arcNorthTexture, toolLensTexture, std::bind(&std::printf, "0 on\n"), std::bind(&std::printf, "0 off\n"));
pieMenu->addOption(arcEastTexture, toolForcepsTexture, std::bind(&std::printf, "1 on\n"), std::bind(&std::printf, "1 off\n"));
pieMenu->addOption(arcSouthTexture, toolTrowelTexture, std::bind(&std::printf, "2 on\n"), std::bind(&std::printf, "2 off\n"));
pieMenu->addOption(arcWestTexture, toolBrushTexture, std::bind(&std::printf, "3 on\n"), std::bind(&std::printf, "3 off\n"));
pieMenu->addOption(arcNorthTexture, toolLensTexture, std::bind(&Application::selectTool, this, lens), std::bind(&Application::deselectTool, this, lens));
pieMenu->addOption(arcEastTexture, toolForcepsTexture, std::bind(&Application::selectTool, this, forceps), std::bind(&Application::deselectTool, this, forceps));
pieMenu->addOption(arcSouthTexture, toolTrowelTexture, std::bind(&Application::selectTool, this, nullptr), std::bind(&Application::deselectTool, this, nullptr));
pieMenu->addOption(arcWestTexture, toolBrushTexture, std::bind(&Application::selectTool, this, forceps), std::bind(&Application::deselectTool, this, nullptr));
uiRootElement->addChild(pieMenu->getContainer());
pieMenu->resize();
pieMenu->getContainer()->setVisible(false);
@ -1403,11 +1404,16 @@ bool Application::loadGame()
colony = new Colony();
colony->setAntModel(antModel);
currentTool = nullptr;
// Create tools
forceps = new Forceps(forcepsModel);
forceps->setColony(colony);
forceps->setCameraController(surfaceCam);
lens = new Lens(lensModel);
lens->setCameraController(surfaceCam);
return true;
}
@ -1508,6 +1514,25 @@ void Application::enterLevelSelection()
changeState(levelSelectState);
}
void Application::deselectTool(Tool* tool)
{
if (tool != nullptr)
{
tool->setActive(false);
return;
}
}
void Application::selectTool(Tool* tool)
{
if (tool != nullptr)
{
tool->setActive(true);
}
currentTool = tool;
}
void Application::selectWorld(std::size_t index)
{
// Set current world and level

+ 8
- 0
src/application.hpp View File

@ -52,7 +52,9 @@ class ModelLoader;
class MaterialLoader;
class Toolbar;
class PieMenu;
class Tool;
class Forceps;
class Lens;
/**
* Encapsulates the state of the application.
@ -106,6 +108,9 @@ public:
void enterLevelSelection();
void deselectTool(Tool* tool);
void selectTool(Tool* tool);
void pauseSimulation();
@ -360,6 +365,7 @@ public:
Model* antHillModel;
Model* nestModel;
Model* forcepsModel;
Model* lensModel;
Model* biomeFloorModel;
// Game variables
@ -383,7 +389,9 @@ public:
bool cameraOverheadView;
bool cameraNestView;
int toolIndex;
Tool* currentTool;
Forceps* forceps;
Lens* lens;
bool simulationPaused;
// Debug

+ 60
- 10
src/game/tool.cpp View File

@ -5,6 +5,28 @@
#include <iostream>
#include <list>
Tool::Tool():
active(false),
pick(0.0f),
cameraController(nullptr)
{
modelInstance.setActive(active);
}
Tool::~Tool()
{}
void Tool::setActive(bool active)
{
this->active = active;
modelInstance.setActive(active);
}
void Tool::setCameraController(const SurfaceCameraController* cameraController)
{
this->cameraController = cameraController;
}
Forceps::Forceps(const Model* model)
{
// Allocate pose and initialize to bind pose
@ -229,16 +251,6 @@ void Forceps::setColony(Colony* colony)
this->colony = colony;
}
void Forceps::setCameraController(const SurfaceCameraController* cameraController)
{
this->cameraController = cameraController;
}
void Forceps::setPick(const Vector3& pick)
{
this->pick = pick;
}
void Forceps::pinch()
{
// Change state to pinching
@ -326,3 +338,41 @@ void Forceps::release()
ascentTween->reset();
ascentTween->stop();
}
Lens::Lens(const Model* model)
{
// Setup model instance
modelInstance.setModel(model);
hoverDistance = 12.0f;
}
Lens::~Lens()
{}
void Lens::update(float dt)
{
/*
// Rotate to face camera
hoverDistance = 30.0f;
Vector3 direction = glm::normalize(cameraController->getCamera()->getTranslation() - pick);
//direction = cameraController->getCamera()->getForward();
float distance = glm::distance(pick, cameraController->getCamera()->getTranslation());
Quaternion alignment = glm::angleAxis(cameraController->getAzimuth() + glm::radians(90.0f), Vector3(0, 1, 0));
Quaternion tilt = glm::rotation(Vector3(0, 1, 0), -direction);
Quaternion rotation = glm::normalize(tilt * alignment);
Vector3 translation = pick + rotation * Vector3(0, -distance + hoverDistance, 0);
modelInstance.setTranslation(translation);
modelInstance.setRotation(rotation);
*/
Quaternion alignment = glm::angleAxis(cameraController->getAzimuth() + glm::radians(90.0f), Vector3(0, 1, 0));
Quaternion rotation = glm::normalize(alignment);
Vector3 translation = pick + Vector3(0, hoverDistance, 0);
modelInstance.setTranslation(translation);
modelInstance.setRotation(rotation);
}

+ 90
- 33
src/game/tool.hpp View File

@ -35,9 +35,77 @@ class SurfaceCameraController;
class Tool
{
public:
/**
* Creates an instance of Tool.
*/
Tool();
/**
* Destroys an instance of Tool.
*/
virtual ~Tool();
/**
* Updates the tool.
*
* @param dt Application timestep.
*/
virtual void update(float dt) = 0;
/**
* Activates or deactivates the tool.
*/
void setActive(bool active);
/**
* Sets the picking position.
*
* @param pick Picking position
*/
void setPick(const Vector3& pick);
/**
* Sets the camera.
*
* @param camera Pointer to the camera.
*/
void setCameraController(const SurfaceCameraController* cameraController);
bool isActive() const;
/**
* Returns the model instance.
*/
const ModelInstance* getModelInstance() const;
ModelInstance* getModelInstance();
protected:
ModelInstance modelInstance;
bool active;
Vector3 pick;
const SurfaceCameraController* cameraController;
};
inline bool Tool::isActive() const
{
return active;
}
inline void Tool::setPick(const Vector3& pick)
{
this->pick = pick;
}
inline const ModelInstance* Tool::getModelInstance() const
{
return &modelInstance;
}
inline ModelInstance* Tool::getModelInstance()
{
return &modelInstance;
}
/**
* The forceps tool can pick up ants and place them anywhere in the world.
@ -67,6 +135,8 @@ public:
/**
* Updates the forceps.
*
* @param dt Application timestep.
*/
virtual void update(float dt);
@ -87,20 +157,6 @@ public:
*/
void setColony(Colony* colony);
/**
* Sets the camera.
*
* @param camera Pointer to the camera.
*/
void setCameraController(const SurfaceCameraController* cameraController);
/**
* Sets the picking position.
*
* @param pick Picking position
*/
void setPick(const Vector3& pick);
/**
* Returns the current state of the forceps.
*/
@ -110,16 +166,9 @@ public:
* Returns the suspended ant, if any.
*/
Ant* getSuspendedAnt() const;
/**
* Returns the model instance.
*/
const ModelInstance* getModelInstance() const;
ModelInstance* getModelInstance();
private:
Forceps::State state;
ModelInstance modelInstance;
Pose* pose;
const Animation* pinchAnimation;
const Animation* releaseAnimation;
@ -137,8 +186,6 @@ private:
Colony* colony;
Ant* targetedAnt;
Ant* suspendedAnt;
const SurfaceCameraController* cameraController;
Vector3 pick;
};
inline Forceps::State Forceps::getState() const
@ -151,23 +198,33 @@ inline Ant* Forceps::getSuspendedAnt() const
return suspendedAnt;
}
inline const ModelInstance* Forceps::getModelInstance() const
{
return &modelInstance;
}
inline ModelInstance* Forceps::getModelInstance()
{
return &modelInstance;
}
/**
* The lens tool can be used to burn ants.
*/
class Lens: public Tool
{
public:
/**
* Creates an instance of Lens.
*
* @param model Lens model
*/
Lens(const Model* model);
/**
* Destroys an instance of Lens.
*/
~Lens();
/**
* Updates the lens.
*
* @param dt Application timestep.
*/
virtual void update(float dt);
private:
float hoverDistance;
};
/**

+ 10
- 0
src/material-loader.cpp View File

@ -135,6 +135,16 @@ PhysicalMaterial* MaterialLoader::load(const std::string& filename)
{
std::stringstream(arguments[0]) >> material->roughness;
}
else if (command == "translucent" && arguments.size() == 1)
{
int translucent = 0;
std::stringstream(arguments[0]) >> translucent;
if (translucent)
{
material->flags |= static_cast<unsigned int>(PhysicalMaterial::Flags::TRANSLUCENT);
}
}
else if (command == "albedo-opacity-map")
{
material->albedoOpacityMap = loadTexture(argumentList);

+ 1
- 0
src/materials.hpp View File

@ -55,6 +55,7 @@ public:
OBJECT = 0x01,
TERRAIN = 0x02,
SOIL = 0x04,
TRANSLUCENT = 0x08
};
PhysicalMaterial():

+ 60
- 9
src/render-passes.cpp View File

@ -44,7 +44,7 @@ void ShadowMapRenderPass::unload()
depthShader = nullptr;
}
void ShadowMapRenderPass::render(const RenderContext* renderContext)
void ShadowMapRenderPass::render(RenderContext* renderContext)
{
// Bind framebuffer and setup viewport
glBindFramebuffer(GL_FRAMEBUFFER, renderTarget->framebuffer);
@ -128,7 +128,7 @@ void ClippingRenderPass::unload()
shader = nullptr;
}
void ClippingRenderPass::render(const RenderContext* renderContext)
void ClippingRenderPass::render(RenderContext* renderContext)
{
glEnable(GL_CLIP_DISTANCE0);
glEnable(GL_STENCIL_TEST);
@ -232,7 +232,7 @@ void SoilRenderPass::unload()
horizonCTexture = nullptr;
}
void SoilRenderPass::render(const RenderContext* renderContext)
void SoilRenderPass::render(RenderContext* renderContext)
{
// Bind shader
shader->bind();
@ -400,7 +400,7 @@ void LightingRenderPass::unload()
specularCubemap = nullptr;
}
void LightingRenderPass::render(const RenderContext* renderContext)
void LightingRenderPass::render(RenderContext* renderContext)
{
/*
time += 1.0f / 60.f;
@ -787,7 +787,7 @@ void LightingRenderPass::render(const RenderContext* renderContext)
*/
const Camera& camera = *(renderContext->camera);
const std::list<RenderOperation>* operations = renderContext->queue->getOperations();
std::list<RenderOperation>* operations = renderContext->queue->getOperations();
// Enable depth testing
glEnable(GL_DEPTH_TEST);
@ -820,6 +820,9 @@ void LightingRenderPass::render(const RenderContext* renderContext)
Texture* metalnessRoughnessMap = nullptr;
Texture* normalOcclusionMap = nullptr;
// Sort operations
operations->sort(RenderOpCompare());
// Render operations
for (const RenderOperation& operation: *operations)
{
@ -992,6 +995,54 @@ bool LightingRenderPass::loadShader(const RenderOperation& operation)
return false;
}
bool LightingRenderPass::RenderOpCompare::operator()(const RenderOperation& opA, const RenderOperation& opB) const
{
// Skip render operations with unsupported materials
if (opA.material->getMaterialFormatID() != static_cast<unsigned int>(MaterialFormat::PHYSICAL))
{
return false;
}
else if (opB.material->getMaterialFormatID() != static_cast<unsigned int>(MaterialFormat::PHYSICAL))
{
return true;
}
// Cast materials
const PhysicalMaterial* materialA = static_cast<const PhysicalMaterial*>(opA.material);
const PhysicalMaterial* materialB = static_cast<const PhysicalMaterial*>(opB.material);
// Determine transparency
bool transparentA = materialA->flags & (unsigned int)PhysicalMaterial::Flags::TRANSLUCENT;
bool transparentB = materialB->flags & (unsigned int)PhysicalMaterial::Flags::TRANSLUCENT;
if (transparentA)
{
if (transparentB)
{
// A and B are both transparent, sort by depth
return (opA.depth <= opB.depth);
}
else
{
// A is transparent, B is opaque. Render B first
return false;
}
}
else
{
if (transparentB)
{
// A is opaque, B is transparent. Render A first
return true;
}
else
{
// A and B are both opaque, sort by material
return (opA.material < opB.material);
}
}
}
DebugRenderPass::DebugRenderPass()
{
modelViewProjectionParam = parameterSet.addParameter("modelViewProjectionMatrix", ShaderParameter::Type::MATRIX_4, 1);
@ -1052,7 +1103,7 @@ void DebugRenderPass::unload()
glDeleteVertexArrays(1, &aabbVAO);
}
void DebugRenderPass::render(const RenderContext* renderContext)
void DebugRenderPass::render(RenderContext* renderContext)
{
const Camera& camera = *(renderContext->camera);
@ -1148,7 +1199,7 @@ void UIRenderPass::unload()
untexturedUIShader = nullptr;
}
void UIRenderPass::render(const RenderContext* renderContext)
void UIRenderPass::render(RenderContext* renderContext)
{
const Camera& camera = *(renderContext->camera);
@ -1265,7 +1316,7 @@ void VignetteRenderPass::unload()
glDeleteTextures(1, &bayerTextureID);
}
void VignetteRenderPass::render(const RenderContext* renderContext)
void VignetteRenderPass::render(RenderContext* renderContext)
{
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
@ -1359,7 +1410,7 @@ void SkyboxRenderPass::unload()
glDeleteVertexArrays(1, &quadVAO);
}
void SkyboxRenderPass::render(const RenderContext* renderContext)
void SkyboxRenderPass::render(RenderContext* renderContext)
{
if (!cubemap)
{

+ 15
- 8
src/render-passes.hpp View File

@ -36,7 +36,7 @@ public:
virtual bool load(const RenderContext* renderContext);
virtual void unload();
virtual void render(const RenderContext* renderContext);
virtual void render(RenderContext* renderContext);
private:
ShaderParameterSet parameterSet;
@ -55,7 +55,7 @@ public:
ClippingRenderPass();
virtual bool load(const RenderContext* renderContext);
virtual void unload();
virtual void render(const RenderContext* renderContext);
virtual void render(RenderContext* renderContext);
void setClippingPlane(const Plane& plane);
@ -89,7 +89,7 @@ public:
SoilRenderPass();
virtual bool load(const RenderContext* renderContext);
virtual void unload();
virtual void render(const RenderContext* renderContext);
virtual void render(RenderContext* renderContext);
inline void setHorizonOTexture(Texture* texture) { horizonOTexture = texture; }
inline void setHorizonATexture(Texture* texture) { horizonATexture = texture; }
@ -122,12 +122,19 @@ public:
virtual bool load(const RenderContext* renderContext);
virtual void unload();
virtual void render(const RenderContext* renderContext);
virtual void render(RenderContext* renderContext);
inline void setShadowMap(GLuint shadowMap) { this->shadowMap = shadowMap; }
inline void setShadowCamera(const Camera* camera) { this->shadowCamera = camera; }
private:
class RenderOpCompare
{
public:
// Sort render opations
bool operator()(const RenderOperation& opA, const RenderOperation& opB) const;
};
bool loadShader(const RenderOperation& operation);
ShaderParameterSet parameterSet;
@ -173,7 +180,7 @@ public:
DebugRenderPass();
virtual bool load(const RenderContext* renderContext);
virtual void unload();
virtual void render(const RenderContext* renderContext);
virtual void render(RenderContext* renderContext);
//void setDrawBounds(bool enabled);
//void setDrawSkeletons(bool enabled);
@ -203,7 +210,7 @@ public:
UIRenderPass();
virtual bool load(const RenderContext* renderContext);
virtual void unload();
virtual void render(const RenderContext* renderContext);
virtual void render(RenderContext* renderContext);
private:
ShaderParameterSet parameterSet;
@ -226,7 +233,7 @@ public:
VignetteRenderPass();
virtual bool load(const RenderContext* renderContext);
virtual void unload();
virtual void render(const RenderContext* renderContext);
virtual void render(RenderContext* renderContext);
private:
ShaderParameterSet parameterSet;
@ -249,7 +256,7 @@ public:
inline void setCubemap(Texture* cubemap) { this->cubemap = cubemap; }
virtual bool load(const RenderContext* renderContext);
virtual void unload();
virtual void render(const RenderContext* renderContext);
virtual void render(RenderContext* renderContext);
private:
ShaderParameterSet parameterSet;

+ 6
- 6
src/states/loading-state.cpp View File

@ -56,8 +56,8 @@ void LoadingState::enter()
std::cout << "success" << std::endl;
}
std::cout << "Loading UI... ";
if (!application->loadUI())
std::cout << "Loading models... ";
if (!application->loadModels())
{
std::cout << "failed" << std::endl;
failure = true;
@ -67,8 +67,8 @@ void LoadingState::enter()
std::cout << "success" << std::endl;
}
std::cout << "Loading models... ";
if (!application->loadModels())
std::cout << "Loading game... ";
if (!application->loadGame())
{
std::cout << "failed" << std::endl;
failure = true;
@ -78,8 +78,8 @@ void LoadingState::enter()
std::cout << "success" << std::endl;
}
std::cout << "Loading game... ";
if (!application->loadGame())
std::cout << "Loading UI... ";
if (!application->loadUI())
{
std::cout << "failed" << std::endl;
failure = true;

+ 9
- 4
src/states/play-state.cpp View File

@ -51,6 +51,7 @@ void PlayState::enter()
// Add tools to scene
application->defaultLayer->addObject(application->forceps->getModelInstance());
application->defaultLayer->addObject(application->lens->getModelInstance());
// Add terrain to scene
application->defaultLayer->addObject(&application->currentLevel->terrainSurface);
@ -196,8 +197,11 @@ void PlayState::execute()
}
// Update tools
application->forceps->setPick(pick);
application->forceps->update(application->dt);
if (application->currentTool != nullptr)
{
application->currentTool->setPick(pick);
application->currentTool->update(application->dt);
}
// Update colony
if (!application->simulationPaused)
@ -229,6 +233,7 @@ void PlayState::exit()
application->defaultLayer->removeObject(&application->currentLevel->terrainSubsurface);
application->defaultLayer->removeObject(&application->biomeFloorModelInstance);
application->defaultLayer->removeObject(application->forceps->getModelInstance());
application->defaultLayer->removeObject(application->lens->getModelInstance());
for (std::size_t i = 0; i < application->colony->getAntCount(); ++i)
{
Ant* ant = application->colony->getAnt(i);
@ -251,7 +256,7 @@ void PlayState::exit()
void PlayState::mouseButtonPressed(int button, int x, int y)
{
if (button == 1)
if (button == 1 && application->forceps->isActive())
{
application->forceps->pinch();
}
@ -259,7 +264,7 @@ void PlayState::mouseButtonPressed(int button, int x, int y)
void PlayState::mouseButtonReleased(int button, int x, int y)
{
if (button == 1)
if (button == 1 && application->forceps->isActive())
{
application->forceps->release();
}

Loading…
Cancel
Save