Browse Source

Revise control scheme

master
C. J. Howard 5 years ago
parent
commit
55cac0b7af
Signed by: cjhoward GPG Key ID: 03E1FABA9C3EC195
11 changed files with 149 additions and 105 deletions
  1. +25
    -0
      src/entity/component-manager.hpp
  2. +1
    -0
      src/entity/components/terrain-patch-component.cpp
  3. +3
    -0
      src/entity/components/terrain-patch-component.hpp
  4. +11
    -50
      src/entity/systems/terrain-system.cpp
  5. +2
    -0
      src/entity/systems/terrain-system.hpp
  6. +65
    -15
      src/game.cpp
  7. +2
    -0
      src/game.hpp
  8. +8
    -0
      src/graphics/lighting-render-pass.cpp
  9. +2
    -0
      src/graphics/lighting-render-pass.hpp
  10. +5
    -1
      src/resources/entity-template-loader.cpp
  11. +25
    -39
      src/states/sandbox-state.cpp

+ 25
- 0
src/entity/component-manager.hpp View File

@ -90,6 +90,17 @@ public:
* @return Pointer to the component, or `nullptr` if the specified component was not found.
*/
ComponentBase* getComponent(EntityID entity, ComponentType type);
/**
* Returns the specified component of an entity.
*
* @param entity Specifies an entity.
* @tparam type Specifies the component type.
*
* @return Pointer to the component, or `nullptr` if the specified component was not found.
*/
template <typename T>
T* getComponent(EntityID entity);
/**
* Returns the component map of the specified entity.
@ -108,6 +119,20 @@ private:
std::list<ComponentObserver*> componentObservers;
};
template <typename T>
T* ComponentManager::getComponent(EntityID entity)
{
ComponentMap& componentMap = entityMap[entity];
auto it = componentMap.find(T::TYPE);
if (it == componentMap.end())
{
return nullptr;
}
return static_cast<T*>(it->second);
}
inline ComponentMap* ComponentManager::getComponents(EntityID entity)
{
return &entityMap[entity];

+ 1
- 0
src/entity/components/terrain-patch-component.cpp View File

@ -22,6 +22,7 @@
ComponentBase* TerrainPatchComponent::clone() const
{
TerrainPatchComponent* component = new TerrainPatchComponent();
component->subdivisions = subdivisions;
component->position = position;
return component;

+ 3
- 0
src/entity/components/terrain-patch-component.hpp View File

@ -28,6 +28,9 @@ class TerrainPatchComponent: public Component
{
public:
virtual ComponentBase* clone() const;
// Number of terrain mesh subdivisions (at LOD 0)
int subdivisions;
// Position in integer terrain coordinates
std::tuple<int, int> position;

+ 11
- 50
src/entity/systems/terrain-system.cpp View File

@ -27,8 +27,7 @@ TerrainSystem::TerrainSystem(ComponentManager* componentManager):
{
terrainCreationGroup.addGroupObserver(this);
terrainGroup.addGroupObserver(this);
patchSize = 100.0f;
patchSize = 1.0f;
}
TerrainSystem::~TerrainSystem()
@ -43,16 +42,23 @@ void TerrainSystem::update(float t, float dt)
ModelComponent* model = std::get<0>(member->components);
TerrainPatchComponent* patch = std::get<1>(member->components);
TransformComponent* transform = std::get<2>(member->components);
transform->transform.translation = Vector3(std::get<0>(patch->position), 0.0f, std::get<1>(patch->position)) * patchSize;
}
}
void TerrainSystem::setPatchSize(float size)
{
patchSize = size;
}
void TerrainSystem::memberRegistered(const TerrainCreationGroup::Member* member)
{
TerrainPatchComponent* patch = std::get<0>(member->components);
TransformComponent* transform = std::get<1>(member->components);
// Generate a subdivided plane mesh
TriangleMesh* patchMesh = generatePlane(5);
TriangleMesh* patchMesh = generatePlane(patch->subdivisions);
// Generate a model from the subdivided plane
Model* patchModel = generateModel(patchMesh);
@ -63,7 +69,7 @@ void TerrainSystem::memberRegistered(const TerrainCreationGroup::Member* member)
componentManager->addComponent(member->entity, model);
// Set scale of the transform component
transform->transform.scale = Vector3(patchSize);
transform->transform.scale = Vector3(patchSize, 1.0f, patchSize);
transform->transform.translation = Vector3(std::get<0>(patch->position), 0.0f, std::get<1>(patch->position)) * patchSize;
}
@ -137,51 +143,6 @@ TriangleMesh* TerrainSystem::generatePlane(int subdivisions)
}
return new TriangleMesh(vertices, indices);
/*
// Generate navmesh
surfaceNavmesh.create(surfaceVertices, surfaceIndices);
// Calculate vertex normals
calculateSurfaceNormals();
// Create and load VAO, VBO, and IBO
glGenVertexArrays(1, &surfaceVAO);
glBindVertexArray(surfaceVAO);
glGenBuffers(1, &surfaceVBO);
glBindBuffer(GL_ARRAY_BUFFER, surfaceVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * surfaceVertexSize * surfaceVertexCount, surfaceVertexData, GL_STATIC_DRAW);
glEnableVertexAttribArray(EMERGENT_VERTEX_POSITION);
glVertexAttribPointer(EMERGENT_VERTEX_POSITION, 3, GL_FLOAT, GL_FALSE, surfaceVertexSize * sizeof(float), (char*)0 + 0 * sizeof(float));
glEnableVertexAttribArray(EMERGENT_VERTEX_NORMAL);
glVertexAttribPointer(EMERGENT_VERTEX_NORMAL, 3, GL_FLOAT, GL_FALSE, surfaceVertexSize * sizeof(float), (char*)0 + 3 * sizeof(float));
glEnableVertexAttribArray(EMERGENT_VERTEX_TEXCOORD);
glVertexAttribPointer(EMERGENT_VERTEX_TEXCOORD, 2, GL_FLOAT, GL_FALSE, surfaceVertexSize * sizeof(float), (char*)0 + 6 * sizeof(float));
glGenBuffers(1, &surfaceIBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, surfaceIBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(std::uint32_t) * surfaceIndexCount, surfaceIndexData, GL_STATIC_DRAW);
// Setup material
//surfaceMaterial.flags = static_cast<unsigned int>(PhysicalMaterial::Flags::OBJECT);
// Setup buffers
surfaceModel.setVAO(surfaceVAO);
surfaceModel.setVBO(surfaceVBO);
surfaceModel.setIBO(surfaceIBO);
// Create model group
Model::Group* group = new Model::Group();
group->name = "default";
group->material = nullptr;//&surfaceMaterial;
group->indexOffset = 0;
group->triangleCount = surfaceTriangleCount;
// Add group to the model
surfaceModel.addGroup(group);
// Set model bounds
surfaceModel.setBounds(surfaceNavmesh.getBounds());
*/
}
Model* TerrainSystem::generateModel(TriangleMesh* mesh)
@ -335,7 +296,7 @@ Model* TerrainSystem::generateModel(TriangleMesh* mesh)
ShaderVariable<float>* roughness = material->addVariable<float>("roughness");
ShaderVariable<float>* metalness = material->addVariable<float>("metalness");
ShaderVariable<float>* opacity = material->addVariable<float>("opacity");
albedo->setValue(Vector3(0.8f));
albedo->setValue(Vector3(frand(0.0f, 1.0f), frand(0.0f, 1.0f), frand(0.0, 1.0f)));
roughness->setValue(0.5f);
metalness->setValue(0.0f);
opacity->setValue(1.0f);

+ 2
- 0
src/entity/systems/terrain-system.hpp View File

@ -42,6 +42,8 @@ public:
virtual void update(float t, float dt);
void setPatchSize(float size);
private:
virtual void memberRegistered(const TerrainCreationGroup::Member* member);
virtual void memberUnregistered(const TerrainCreationGroup::Member* member);

+ 65
- 15
src/game.cpp View File

@ -40,6 +40,7 @@
#include "entity/component-manager.hpp"
#include "entity/components/transform-component.hpp"
#include "entity/components/model-component.hpp"
#include "entity/components/terrain-patch-component.hpp"
#include "entity/entity-manager.hpp"
#include "entity/entity-template.hpp"
#include "entity/system-manager.hpp"
@ -334,6 +335,7 @@ void Game::setup()
steeringSystem = new SteeringSystem(componentManager);
locomotionSystem = new LocomotionSystem(componentManager);
terrainSystem = new TerrainSystem(componentManager);
terrainSystem->setPatchSize(500.0f);
particleSystem = new ParticleSystem(componentManager);
particleSystem->resize(1000);
particleSystem->setMaterial(smokeMaterial);
@ -412,8 +414,41 @@ void Game::setup()
//EntityID tool0 = createInstanceOf("lens");
EntityID patch0 = createInstanceOf("terrain-patch");
int highResolutionDiameter = 3;
int mediumResolutionDiameter = highResolutionDiameter + 2;
int lowResolutionDiameter = 20;
float lowResolutionRadius = static_cast<float>(lowResolutionDiameter) / 2.0f;
float mediumResolutionRadius = static_cast<float>(mediumResolutionDiameter) / 2.0f;
float highResolutionRadius = static_cast<float>(highResolutionDiameter) / 2.0f;
for (int i = 0; i < lowResolutionDiameter; ++i)
{
for (int j = 0; j < lowResolutionDiameter; ++j)
{
EntityID patch;
int x = i - lowResolutionDiameter / 2;
int z = j - lowResolutionDiameter / 2;
if (std::abs(x) < highResolutionRadius && std::abs(z) < highResolutionRadius)
{
patch = createInstanceOf("terrain-patch-high-resolution");
}
else if (std::abs(x) < mediumResolutionRadius && std::abs(z) < mediumResolutionRadius)
{
patch = createInstanceOf("terrain-patch-medium-resolution");
}
else
{
patch = createInstanceOf("terrain-patch-low-resolution");
}
setTerrainPatchPosition(patch, {x, z});
}
}
changeState(sandboxState);
}
@ -422,9 +457,6 @@ void Game::update(float t, float dt)
{
this->time = t;
// Dispatch scheduled events
eventDispatcher.update(t);
// Execute current state
if (currentState != nullptr)
{
@ -469,14 +501,14 @@ void Game::render()
renderer.render(*worldScene);
renderer.render(*uiScene);
// Swap window framebuffers
window->swapBuffers();
if (screenshotQueued)
{
screenshot();
screenshotQueued = false;
}
// Swap window framebuffers
window->swapBuffers();
}
void Game::exit()
@ -922,6 +954,11 @@ void Game::setupUI()
toolIconCameraImage->setTextureBounds(normalizeTextureBounds(hudTextureAtlas.getBounds("tool-icon-camera"), hudTextureAtlasBounds));
radialMenuImage->addChild(toolIconCameraImage);
toolIconMicrochipImage = new UIImage();
toolIconMicrochipImage->setTexture(hudSpriteSheetTexture);
toolIconMicrochipImage->setTextureBounds(normalizeTextureBounds(hudTextureAtlas.getBounds("tool-icon-microchip"), hudTextureAtlasBounds));
radialMenuImage->addChild(toolIconMicrochipImage);
toolIconTestTubeImage = new UIImage();
toolIconTestTubeImage->setTexture(hudSpriteSheetTexture);
toolIconTestTubeImage->setTextureBounds(normalizeTextureBounds(hudTextureAtlas.getBounds("tool-icon-test-tube"), hudTextureAtlasBounds));
@ -1080,7 +1117,7 @@ void Game::setupUI()
cameraGridContainer->addChild(cameraGridX0Image);
cameraGridContainer->addChild(cameraGridX1Image);
cameraGridContainer->addChild(cameraReticleImage);
cameraGridContainer->setVisible(true);
cameraGridContainer->setVisible(false);
uiRootElement->addChild(cameraGridContainer);
cameraFlashImage = new UIImage();
@ -1859,6 +1896,9 @@ void Game::resizeUI(int w, int h)
toolIconCameraImage->setDimensions(Vector2(toolIconCameraBounds.getWidth(), toolIconCameraBounds.getHeight()));
toolIconCameraImage->setAnchor(Anchor::CENTER);
Rect toolIconMicrochipBounds = hudTextureAtlas.getBounds("tool-icon-microchip");
toolIconMicrochipImage->setDimensions(Vector2(toolIconMicrochipBounds.getWidth(), toolIconMicrochipBounds.getHeight()));
toolIconMicrochipImage->setAnchor(Anchor::CENTER);
Rect toolIconTestTubeBounds = hudTextureAtlas.getBounds("tool-icon-test-tube");
toolIconTestTubeImage->setDimensions(Vector2(toolIconTestTubeBounds.getWidth(), toolIconTestTubeBounds.getHeight()));
@ -1931,7 +1971,7 @@ void Game::resizeUI(int w, int h)
toolIconLensImage,
nullptr,
toolIconForcepsImage,
nullptr,
toolIconMicrochipImage,
toolIconCameraImage,
nullptr
};
@ -2015,6 +2055,7 @@ void Game::screenshot()
// Read pixel data from framebuffer
unsigned char* pixels = new unsigned char[w * h * 3];
glReadBuffer(GL_BACK);
glReadPixels(0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, pixels);
// Get game title in current language
@ -2056,13 +2097,12 @@ void Game::screenshot()
// Play camera shutter sound
// Restore camera UI visibility
cameraGridContainer->setVisible(true);
//cameraGridContainer->setVisible(true);
fpsLabel->setVisible(true);
// Whiteout screen immediately
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
window->swapBuffers();
}
void Game::mapInput(const InputMapping& mapping)
@ -2215,7 +2255,7 @@ void Game::removeComponent(EntityID entity, ComponentType type)
void Game::setTranslation(EntityID entity, const Vector3& translation)
{
TransformComponent* component = static_cast<TransformComponent*>(componentManager->getComponent(entity, ComponentType::TRANSFORM));
TransformComponent* component = componentManager->getComponent<TransformComponent>(entity);
if (!component)
{
return;
@ -2226,7 +2266,7 @@ void Game::setTranslation(EntityID entity, const Vector3& translation)
void Game::setRotation(EntityID entity, const Quaternion& rotation)
{
TransformComponent* component = static_cast<TransformComponent*>(componentManager->getComponent(entity, ComponentType::TRANSFORM));
TransformComponent* component = componentManager->getComponent<TransformComponent>(entity);
if (!component)
{
return;
@ -2237,7 +2277,7 @@ void Game::setRotation(EntityID entity, const Quaternion& rotation)
void Game::setScale(EntityID entity, const Vector3& scale)
{
TransformComponent* component = static_cast<TransformComponent*>(componentManager->getComponent(entity, ComponentType::TRANSFORM));
TransformComponent* component = componentManager->getComponent<TransformComponent>(entity);
if (!component)
{
return;
@ -2246,6 +2286,16 @@ void Game::setScale(EntityID entity, const Vector3& scale)
component->transform.scale = scale;
}
void Game::setTerrainPatchPosition(EntityID entity, const std::tuple<int, int>& position)
{
TerrainPatchComponent* component = componentManager->getComponent<TerrainPatchComponent>(entity);
if (!component)
{
return;
}
component->position = position;
}
void Game::saveScreenshot(const std::string& filename, unsigned int width, unsigned int height, unsigned char* pixels)
{

+ 2
- 0
src/game.hpp View File

@ -172,6 +172,7 @@ public:
void setTranslation(EntityID entity, const Vector3& translation);
void setRotation(EntityID entity, const Quaternion& rotation);
void setScale(EntityID entity, const Vector3& scale);
void setTerrainPatchPosition(EntityID entity, const std::tuple<int, int>& position);
void boxSelect(float x, float y, float w, float h);
@ -283,6 +284,7 @@ public:
UIImage* toolIconForcepsImage;
UIImage* toolIconSpadeImage;
UIImage* toolIconCameraImage;
UIImage* toolIconMicrochipImage;
UIImage* toolIconTestTubeImage;
UIContainer* buttonContainer;
UIImage* playButtonBGImage;

+ 8
- 0
src/graphics/lighting-render-pass.cpp View File

@ -81,6 +81,9 @@ bool LightingRenderPass::load(const RenderContext* renderContext)
spotlightCutoffsParam.connect(shader->getInput("spotlightCutoffs"));
spotlightExponentsParam.connect(shader->getInput("spotlightExponents"));
clipNearParam.connect(shader->getInput("clipNear"));
clipFarParam.connect(shader->getInput("clipFar"));
#if defined(DEBUG)
wireframeLineWidthParam.connect(shader->getInput("wireframeLineWidth"));
#endif
@ -228,6 +231,8 @@ void LightingRenderPass::render(RenderContext* renderContext)
cameraPositionParam.setValue(cameraPosition);
shadowMapParam.setValue(shadowMap);
timeParam.setValue(time);
clipNearParam.setValue(camera.getClipNear());
clipFarParam.setValue(camera.getClipFar());
std::uint32_t permutation = 0xDEADBEEF;
bool blending = false;
@ -284,6 +289,9 @@ void LightingRenderPass::render(RenderContext* renderContext)
spotlightExponentsParam.upload();
}
clipNearParam.upload();
clipFarParam.upload();
#if defined(DEBUG)
wireframeLineWidthParam.upload();
#endif

+ 2
- 0
src/graphics/lighting-render-pass.hpp View File

@ -82,6 +82,8 @@ private:
ShaderVector3 spotlightDirectionsParam;
ShaderFloat spotlightCutoffsParam;
ShaderFloat spotlightExponentsParam;
ShaderFloat clipNearParam;
ShaderFloat clipFarParam;
#if defined(DEBUG)
ShaderFloat wireframeLineWidthParam;

+ 5
- 1
src/resources/entity-template-loader.cpp View File

@ -80,12 +80,14 @@ static ComponentBase* loadModelComponent(ResourceManager* resourceManager, const
static ComponentBase* loadTerrainPatchComponent(const std::vector<std::string>& parameters)
{
if (parameters.size() != 3)
if (parameters.size() != 4)
{
throw std::runtime_error("loadTerrainPatchComponent(): Invalid parameter count.");
}
int subdivisions;
std::tuple<int, int> position;
float size;
std::stringstream stream;
for (std::size_t i = 1; i < parameters.size(); ++i)
{
@ -93,10 +95,12 @@ static ComponentBase* loadTerrainPatchComponent(const std::vector&
if (i < parameters.size() - 1)
stream << ' ';
}
stream >> subdivisions;
stream >> std::get<0>(position);
stream >> std::get<1>(position);
TerrainPatchComponent* component = new TerrainPatchComponent();
component->subdivisions = subdivisions;
component->position = position;
return component;

+ 25
- 39
src/states/sandbox-state.cpp View File

@ -67,13 +67,13 @@ void SandboxState::enter()
game->orbitCam->setTargetAzimuth(azimuth);
game->freeCam->setTranslation(Vector3(-5, 5.0f, -5.0f));
game->cameraRig = game->freeCam;
game->mouse->setRelativeMode(true);
//game->cameraRig = game->freeCam;
//game->mouse->setRelativeMode(true);
toolIndex = 0;
game->selectTool(toolIndex);
game->currentTool->setActive(false);
//game->mouse->warp(game->window, game->w / 2, game->h / 2);
//game->currentTool->setActive(false);
game->mouse->warp(game->window, game->w / 2, game->h / 2);
zoom = 0.5f;
noPick = false;
@ -153,7 +153,7 @@ void SandboxState::execute()
zoom = std::max<float>(0.0f, std::min<float>(1.0f, zoom));
float minFocalDistance = 5.0f;
float maxFocalDistance = 70.0f;
float maxFocalDistance = 200.0f;
float logMinFocalDistance = std::log(minFocalDistance);
float logMaxFocalDistance = std::log(maxFocalDistance);
float logFocalDistance = lerp(logMinFocalDistance, logMaxFocalDistance, 1.0f - zoom);
@ -167,9 +167,9 @@ void SandboxState::execute()
float fov = std::exp(logFOV);
float minClipNear = 1.0f;
float maxClipNear = 10.0f;
float minClipFar = 80.0f;
float maxClipFar = 350.0f;
float maxClipNear = 5.0f;
float minClipFar = 100.0f;
float maxClipFar = 5000.0f;
float logMinClipNear = std::log(minClipNear);
float logMaxClipNear = std::log(maxClipNear);
float logMinClipFar = std::log(minClipFar);
@ -179,15 +179,8 @@ void SandboxState::execute()
float clipNear = std::exp(logClipNear);
float clipFar = std::exp(logClipFar);
float nearElevation = glm::radians(40.0f);
float farElevation = glm::radians(80.0f);
float logNearElevation = std::log(nearElevation);
float logFarElevation = std::log(farElevation);
float logElevation = lerp(logNearElevation, logFarElevation, 1.0f - zoom);
float elevation = std::exp(logElevation);
float minMovementSpeed = 2.5f * game->timestep;
float maxMovementSpeed = 40.0f * game->timestep;
float minMovementSpeed = 3.5f * game->timestep;
float maxMovementSpeed = 100.0f * game->timestep;
float logMinMovementSpeed = std::log(minMovementSpeed);
float logMaxMovementSpeed = std::log(maxMovementSpeed);
float logMovementSpeed = lerp(logMinMovementSpeed, logMaxMovementSpeed, 1.0f - zoom);
@ -217,12 +210,23 @@ void SandboxState::execute()
float logLabelDistance = lerp(logNearLabelDistance, logFarLabelDistance, 1.0f - zoom);
float labelDistance = std::exp(logLabelDistance);
if (game->adjustCameraControl.isActive() && !game->adjustCameraControl.wasActive())
{
savedMousePosition = game->mouse->getCurrentPosition();
game->mouse->setRelativeMode(true);
}
if (!game->radialMenuContainer->isVisible() && !menuClosed)
{
// Picking
Vector3 pick;
std::tuple<int, int> mousePosition = game->mouse->getCurrentPosition();
if (game->adjustCameraControl.isActive() || game->adjustCameraControl.wasActive())
{
mousePosition = savedMousePosition;
}
std::get<1>(mousePosition) = game->h - std::get<1>(mousePosition);
Vector4 viewport(0.0f, 0.0f, game->w, game->h);
Vector3 mouseNear = game->cameraRig->getCamera()->unproject(Vector3(std::get<0>(mousePosition), std::get<1>(mousePosition), 0.0f), viewport);
@ -250,26 +254,8 @@ void SandboxState::execute()
}
game->currentTool->update(game->timestep);
}
if (game->adjustCameraControl.isActive() || game->dragCameraControl.isActive())
{
noPick = true;
}
else
{
noPick = false;
}
if (game->adjustCameraControl.isActive() && !game->adjustCameraControl.wasActive())
{
Vector3 focalPoint = pick;
game->orbitCam->setTargetFocalPoint(focalPoint);
savedMousePosition = game->mouse->getCurrentPosition();
game->mouse->setRelativeMode(true);
}
else if (game->dragCameraControl.isActive())
if (game->dragCameraControl.isActive())
{
if (!game->dragCameraControl.wasActive())
{
@ -308,7 +294,7 @@ void SandboxState::execute()
if (!game->adjustCameraControl.isActive() && game->adjustCameraControl.wasActive())
{
game->mouse->setRelativeMode(false);
game->mouse->warp(game->window, game->w / 2, game->h / 2);
game->mouse->warp(game->window, std::get<0>(savedMousePosition), std::get<1>(savedMousePosition));
noPick = false;
}
}
@ -377,7 +363,7 @@ void SandboxState::handleEvent(const MouseMovedEvent& event)
float rotation = glm::radians(22.5f) * rotationFactor * game->timestep;
float minElevation = glm::radians(-80.0f);
float minElevation = glm::radians(4.0f);
float maxElevation = glm::radians(80.0f);
float elevation = game->orbitCam->getTargetElevation() + elevationFactor * 0.25f * game->timestep;
elevation = std::min<float>(maxElevation, std::max<float>(minElevation, elevation));

Loading…
Cancel
Save