1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-11-07 03:12:36 +01:00

Implement visible goals for locating characters

This commit is contained in:
Daniel Evans 2015-01-23 17:18:16 +00:00
parent 6890572542
commit 1961661d14
8 changed files with 143 additions and 5 deletions

View File

@ -30,6 +30,23 @@ class ScriptMachine;
#include <queue>
#include <random>
/**
* Information about "Goal" locations so they can be rendered
* (this doesn't really belong here).
*/
struct AreaIndicatorInfo
{
enum AreaIndicatorType
{
Cylinder
};
AreaIndicatorType type;
glm::vec3 position;
glm::vec3 radius;
};
/**
* @brief Handles all data relating to object instances and other "worldly" state.
*/
@ -258,12 +275,20 @@ public:
void disableAIPaths(AIGraphNode::NodeType type, const glm::vec3& min, const glm::vec3& max);
void enableAIPaths(AIGraphNode::NodeType type, const glm::vec3& min, const glm::vec3& max);
void drawAreaIndicator(AreaIndicatorInfo::AreaIndicatorType type, glm::vec3 position, glm::vec3 radius);
const std::vector<AreaIndicatorInfo>& getAreaIndicators() const { return areaIndicators; }
void clearTickData();
private:
/**
* @brief Used by objects to delete themselves during updates.
*/
std::queue<GameObject*> deletionQueue;
std::vector<AreaIndicatorInfo> areaIndicators;
};
#endif

View File

@ -15,6 +15,8 @@ class ModelFrame;
class GameWorld;
class GameObject;
class AreaIndicatorInfo;
/// @todo migrate to some other way of rendering each object type.
class CharacterObject;
class VehicleObject;
@ -147,6 +149,7 @@ public:
Renderer::ShaderProgram* worldProg;
Renderer::ShaderProgram* skyProg;
Renderer::ShaderProgram* waterProg;
Renderer::ShaderProgram* particleProg;
GLuint particleProgram;
@ -159,6 +162,9 @@ public:
DrawBuffer skyDbuff;
GeometryBuffer skyGbuff;
DrawBuffer cylinderBuffer;
GeometryBuffer cylinderGeometry;
/**
* Renders the world using the parameters of the passed Camera.
* Note: The camera's near and far planes are overriden by weather effects.
@ -219,6 +225,9 @@ public:
void renderGeometry(Model*, size_t geom, const glm::mat4& modelMatrix, float opacity, GameObject* = nullptr);
/** Renders the area indicator */
void renderAreaIndicator(const AreaIndicatorInfo* info);
/** method for rendering AI debug information */
void renderPaths();

View File

@ -57,6 +57,9 @@ public:
GLuint getVBOName() const
{ return vbo; }
GLsizei getCount() const
{ return num; }
/**
* Uploads Vertex Buffer data from an STL vector
*

View File

@ -768,4 +768,14 @@ void GameWorld::enableAIPaths(AIGraphNode::NodeType type, const glm::vec3& min,
}
}
void GameWorld::drawAreaIndicator(AreaIndicatorInfo::AreaIndicatorType type, glm::vec3 position, glm::vec3 radius)
{
areaIndicators.push_back({type, position, radius});
}
void GameWorld::clearTickData()
{
areaIndicators.clear();
}

View File

@ -91,6 +91,14 @@ GameRenderer::GameRenderer(GameWorld* engine)
renderer->setProgramBlockBinding(worldProg, "SceneData", 1);
renderer->setProgramBlockBinding(worldProg, "ObjectData", 2);
particleProg = renderer->createShader(
GameShaders::WorldObject::VertexShader,
GameShaders::Particle::FragmentShader);
renderer->setUniformTexture(particleProg, "texture", 0);
renderer->setProgramBlockBinding(particleProg, "SceneData", 1);
renderer->setProgramBlockBinding(particleProg, "ObjectData", 2);
particleProgram = compileProgram(GameShaders::WorldObject::VertexShader,
GameShaders::Particle::FragmentShader);
@ -206,6 +214,30 @@ GameRenderer::GameRenderer(GameWorld* engine)
ssRectColour = glGetUniformLocation(ssRectProgram, "colour");
ssRectSize = glGetUniformLocation(ssRectProgram, "size");
ssRectOffset = glGetUniformLocation(ssRectProgram, "offset");
const static int cylsegments = 16;
std::vector<Model::GeometryVertex> cylverts;
for(int s = 0; s < cylsegments; ++s)
{
float theta = (2.f*glm::pi<float>()/cylsegments) * (s+0);
float gamma = (2.f*glm::pi<float>()/cylsegments) * (s+1);
glm::vec2 p0( glm::sin(theta), glm::cos(theta) );
glm::vec2 p1( glm::sin(gamma), glm::cos(gamma) );
p0 *= 0.5f;
p1 *= 0.5f;
cylverts.push_back({glm::vec3(p0, 2.f), glm::vec3(), glm::vec2(0.45f,0.6f), glm::u8vec4(255, 255, 255, 50)});
cylverts.push_back({glm::vec3(p0,-1.f), glm::vec3(), glm::vec2(0.45f,0.4f), glm::u8vec4(255, 255, 255, 150)});
cylverts.push_back({glm::vec3(p1, 2.f), glm::vec3(), glm::vec2(0.55f,0.6f), glm::u8vec4(255, 255, 255, 50)});
cylverts.push_back({glm::vec3(p0,-1.f), glm::vec3(), glm::vec2(0.45f,0.4f), glm::u8vec4(255, 255, 255, 150)});
cylverts.push_back({glm::vec3(p1,-1.f), glm::vec3(), glm::vec2(0.55f,0.4f), glm::u8vec4(255, 255, 255, 150)});
cylverts.push_back({glm::vec3(p1, 2.f), glm::vec3(), glm::vec2(0.55f,0.6f), glm::u8vec4(255, 255, 255, 50)});
}
cylinderGeometry.uploadVertices<Model::GeometryVertex>(cylverts);
cylinderBuffer.addGeometry(&cylinderGeometry);
cylinderBuffer.setFaceType(GL_TRIANGLES);
}
float mix(uint8_t a, uint8_t b, float num)
@ -318,6 +350,15 @@ void GameRenderer::renderWorld(const ViewCamera &camera, float alpha)
}
transparentDrawQueue.clear();
// Draw goal indicators
glDepthMask(GL_FALSE);
renderer->useProgram( particleProg );
for(auto& i : engine->getAreaIndicators())
{
renderAreaIndicator( &i );
}
glDepthMask(GL_TRUE);
// Draw the water.
renderer->useProgram( waterProg );
@ -858,6 +899,33 @@ void GameRenderer::renderGeometry(Model* model, size_t g, const glm::mat4& model
}
}
#define GOAL_RINGS 3
void GameRenderer::renderAreaIndicator(const AreaIndicatorInfo* info)
{
glm::mat4 m(1.f);
m = glm::translate(m, info->position);
glm::vec3 scale = info->radius + 0.15f * glm::sin(engine->gameTime * 5.f);
Renderer::DrawParameters dp;
dp.texture = engine->gameData.textures[{"cloud1",""}].texName;
dp.ambient = 1.f;
dp.colour = glm::u8vec4(50, 100, 255, 1);
dp.start = 0;
dp.count = cylinderGeometry.getCount();
dp.diffuse = 1.f;
for(int i = 0; i < GOAL_RINGS; i++)
{
glm::mat4 mt = m;
glm::vec3 final = scale * glm::pow(0.9f, i + 1.0f);
mt = glm::scale(mt, glm::vec3(final.x, final.y, 1.0f + i * 0.1f));
int reverse = (i % 2 ? 1 : -1);
mt = glm::rotate(mt, reverse * engine->gameTime * 0.5f, glm::vec3(0.f, 0.f, 1.f) );
renderer->drawArrays(mt, &cylinderBuffer, dp);
}
}
void GameRenderer::renderParticles()
{
_particles.erase( std::remove_if(_particles.begin(), _particles.end(),

View File

@ -220,12 +220,11 @@ layout(std140) uniform ObjectData {
void main()
{
vec4 c = texture2D(texture, TexCoords);
c.a = clamp(0, length(c.rgb/3.0), 1);
c.a = clamp(0, length(c.rgb/length(vec3(1,1,1))), 1);
if(c.a <= ALPHA_DISCARD_THRESHOLD) discard;
float fogZ = (gl_FragCoord.z / gl_FragCoord.w);
float fogfac = clamp( (fogStart-fogZ)/(fogEnd-fogStart), 0.0, 1.0 );
outColour = mix(ambient, colour * (vec4(0.5) + Colour * 0.5)
* (vec4(0.5) + dynamic * 0.5) * c, 1.f);
outColour = mix(ambient, c * colour * Colour, 1.f);
})";

View File

@ -9,6 +9,7 @@
#include <objects/CharacterObject.hpp>
#include <render/Model.hpp>
#include <render/GameRenderer.hpp>
#include <engine/Animator.hpp>
#include <engine/GameWorld.hpp>
#include <engine/GameWorld.hpp>
@ -224,7 +225,8 @@ bool game_player_in_area_2d_in_vehicle(const ScriptArguments& args)
auto character = static_cast<CharacterController*>(*args[0].handle);
glm::vec2 position(args[1].real, args[2].real);
glm::vec2 radius(args[3].real, args[4].real);
bool show = args[5].integer;
bool drawCylinder = args[5].integer;
if( character->getCharacter()->getCurrentVehicle() == nullptr )
{
@ -239,6 +241,12 @@ bool game_player_in_area_2d_in_vehicle(const ScriptArguments& args)
return true;
}
if( drawCylinder )
{
auto ground = args.getVM()->getWorld()->getGroundAtPosition(glm::vec3(position, 100.f));
args.getVM()->getWorld()->drawAreaIndicator(AreaIndicatorInfo::Cylinder, ground + glm::vec3(0.f, 0.f, 4.5f), glm::vec3(radius, 5.f));
}
return false;
}
@ -414,6 +422,7 @@ bool game_character_in_area_on_foot(const ScriptArguments& args)
bool game_character_stoped_in_volume_in_vehicle(const ScriptArguments& args)
{
auto controller = static_cast<CharacterController*>(*args[0].handle);
bool drawCylinder = !!args[7].integer;
if( controller && controller->getCharacter()->getCurrentVehicle() != nullptr )
{
@ -429,8 +438,13 @@ bool game_character_stoped_in_volume_in_vehicle(const ScriptArguments& args)
{
return controller->getCharacter()->getCurrentVehicle()->physVehicle->getCurrentSpeedKmHour() < 0.75f;
}
}
// Request the renderer draw a cylinder here.
if( drawCylinder )
{
args.getVM()->getWorld()->drawAreaIndicator(AreaIndicatorInfo::Cylinder, (max+min)/2.f, (max-min)/2.f);
}
}
return false;
}
@ -441,6 +455,8 @@ bool game_character_stoped_in_volume(const ScriptArguments& args)
glm::vec3 vec1(args[1].real, args[2].real, args[3].real);
glm::vec3 vec2(args[4].real, args[5].real, args[6].real);
bool drawCylinder = !!args[7].integer;
glm::vec3 min = glm::min(vec1, vec2);
glm::vec3 max = glm::max(vec1, vec2);
@ -459,6 +475,11 @@ bool game_character_stoped_in_volume(const ScriptArguments& args)
}
}
if( drawCylinder )
{
args.getVM()->getWorld()->drawAreaIndicator(AreaIndicatorInfo::Cylinder, (max+min)/2.f, (max-min)/2.f);
}
return false;
}

View File

@ -115,6 +115,9 @@ int RWGame::run()
void RWGame::tick(float dt)
{
// Clear out any per-tick state.
engine->clearTickData();
// Process the Engine's background work.
engine->_work->update();