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:
parent
6890572542
commit
1961661d14
@ -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
|
||||
|
@ -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();
|
||||
|
||||
|
@ -57,6 +57,9 @@ public:
|
||||
GLuint getVBOName() const
|
||||
{ return vbo; }
|
||||
|
||||
GLsizei getCount() const
|
||||
{ return num; }
|
||||
|
||||
/**
|
||||
* Uploads Vertex Buffer data from an STL vector
|
||||
*
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
@ -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(),
|
||||
|
@ -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);
|
||||
})";
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user