DrawScenarioSimChar.cpp
#include "DrawScenarioSimChar.h"
#include "sim/BaseControllerMACE.h"
#include "render/DrawUtil.h"
#include "render/DrawObj.h"
#include "render/DrawWorld.h"
#include "render/DrawSimCharacter.h"
#include "render/DrawPerturb.h"
#include "render/DrawGround.h"
const double gLinkWidth = 0.05f;
const tVector gLineColor = tVector(0, 0, 0, 1);
const tVector gFillTint = tVector(1, 1, 1, 1);
const tVector gVisOffset = tVector(0, 0, 0.5, 0); // offset for visualization elements
const int gTracerBufferSize = 200;
const double gTracerSamplePeriod = 0.033;
const std::string gOutputCharFile = "output/char_state.txt";
cDrawScenarioSimChar::cDrawScenarioSimChar(cCamera& cam)
: cDrawScenarioSimInteractive(cam)
{
mDrawInfo = false;
mDrawPoliInfo = false;
mEnableTrace = false;
mDrawFeatures = false;
mDrawPolicyPlots = false;
mCamDelta = cam.GetPosition() - cam.GetFocus();
}
cDrawScenarioSimChar::~cDrawScenarioSimChar()
{
}
void cDrawScenarioSimChar::Init()
{
cDrawScenarioSimInteractive::Init();
BuildScene();
mScene->ParseArgs(mArgParser);
mScene->Init();
mEnableTrace = false;
InitTracer();
}
void cDrawScenarioSimChar::ParseArgs(const cArgParser& parser)
{
cDrawScenarioSimInteractive::ParseArgs(parser);
mArgParser = parser;
}
void cDrawScenarioSimChar::Reset()
{
mScene->Reset();
mTracer.Reset();
cDrawScenarioSimInteractive::Reset();
}
void cDrawScenarioSimChar::Clear()
{
cDrawScenarioSimInteractive::Clear();
mScene->Clear();
mTracer.Clear();
}
void cDrawScenarioSimChar::Update(double time_elapsed)
{
cDrawScenarioSimInteractive::Update(time_elapsed);
mScene->Update(time_elapsed);
if (mEnableTrace)
{
UpdateTracer(time_elapsed);
}
UpdateCamera();
}
void cDrawScenarioSimChar::UpdateTracer(double time_elapsed)
{
auto ctrl = mScene->GetCharacter()->GetController();
const std::shared_ptr<cBaseControllerMACE> mace_ctrl = std::dynamic_pointer_cast<cBaseControllerMACE>(ctrl);
bool is_mace_ctrl = (mace_ctrl != nullptr);
if (is_mace_ctrl)
{
int action_id = ctrl->GetCurrActionID();
int trace_handle = mTraceHandles[0];
mTracer.SetTraceColIdx(trace_handle, action_id);
}
mTracer.Update(time_elapsed);
}
void cDrawScenarioSimChar::Keyboard(unsigned char key, int x, int y)
{
cDrawScenarioSimInteractive::Keyboard(key, x, y);
switch (key)
{
case 'c':
ToggleCamTrackMode(eCamTrackModeStill);
break;
case 'f':
mDrawInfo = !mDrawInfo;
break;
case 'g':
mDrawFeatures = !mDrawFeatures;
break;
case 'h':
mDrawPolicyPlots = !mDrawPolicyPlots;
break;
case 'p':
mDrawPoliInfo = !mDrawPoliInfo;
break;
case 's':
OutputCharState(GetOutputCharFile());
break;
case 'x':
SpawnProjectile();
break;
case 'y':
ToggleTrace();
break;
case 'z':
SpawnBigProjectile();
break;
default:
break;
}
}
void cDrawScenarioSimChar::MouseClick(int button, int state, double x, double y)
{
cDrawScenarioSimInteractive::MouseClick(button, state, x, y);
}
void cDrawScenarioSimChar::MouseMove(double x, double y)
{
cDrawScenarioSimInteractive::MouseMove(x, y);
}
void cDrawScenarioSimChar::Reshape(int w, int h)
{
}
std::string cDrawScenarioSimChar::GetName() const
{
return mScene->GetName();
}
void cDrawScenarioSimChar::BuildScene()
{
mScene = std::shared_ptr<cScenarioSimChar>(new cScenarioSimChar());
}
tVector cDrawScenarioSimChar::GetCamTrackPos() const
{
const auto& character = mScene->GetCharacter();
return character->CalcCOM();
}
tVector cDrawScenarioSimChar::GetCamStillPos() const
{
const auto& character = mScene->GetCharacter();
tVector char_pos = character->CalcCOM();
double cam_w = mCam.GetWidth();
double cam_h = mCam.GetHeight();
const auto& ground = mScene->GetGround();
const int num_samples = 16;
double ground_samples[num_samples] = { 0 };
const double pad = std::min(0.5, 0.5 * cam_w);
double avg_h = 0;
double min_x = char_pos[0];
double max_x = char_pos[0] + cam_w;
int num_valid_samples = 0;
for (int i = 0; i < num_samples; ++i)
{
tVector pos = char_pos;
pos[0] = static_cast<double>(i) / (num_samples - 1) * (max_x - min_x) + min_x;
bool valid_sample = true;
double ground_h = ground->SampleHeight(pos, valid_sample);
if (valid_sample)
{
ground_samples[i] = ground_h;
avg_h += ground_h;
++num_valid_samples;
}
}
avg_h /= num_valid_samples;
std::sort(ground_samples, &(ground_samples[num_samples - 1]));
double med_h = ground_samples[num_samples / 2];
double min_h = ground_samples[0];
tVector track_pos = char_pos;
double target_h = avg_h;
//double target_h = min_h;
//double y_pad = -0.2;
double y_pad = -0.4;
track_pos[1] = target_h + y_pad + 0.5 * cam_h;
return track_pos;
}
void cDrawScenarioSimChar::InitTracer()
{
mTraceHandles.clear();
mTracer.Init(gTracerBufferSize, gTracerSamplePeriod);
tVectorArr tracer_cols;
tracer_cols.push_back(tVector(0, 0, 1, 0.5));
tracer_cols.push_back(tVector(1, 0, 0, 0.5));
tracer_cols.push_back(tVector(0, 0.5, 0, 0.5));
tracer_cols.push_back(tVector(0.75, 0, 0.75, 0.5));
tracer_cols.push_back(tVector(0, 0.5, 0.5, 0.5));
tracer_cols.push_back(tVector(0, 0, 0, 0.5));
int handle = AddCharTrace(mScene->GetCharacter(), tracer_cols);
mTraceHandles.push_back(handle);
}
int cDrawScenarioSimChar::AddCharTrace(const std::shared_ptr<cSimCharacter>& character,
const tVectorArr& cols)
{
cCharTracer::tParams params;
params.mChar = character;
params.mColors = cols;
params.mType = cCharTracer::eTraceCOM;
for (int i = 0; i < character->GetNumBodyParts(); ++i)
{
if (character->IsValidBodyPart(i)
&& character->IsEndEffector(i))
{
params.mContactList.push_back(i);
}
}
int handle = mTracer.AddTrace(params);
return handle;
}
void cDrawScenarioSimChar::ToggleTrace()
{
mTracer.Reset();
mEnableTrace = !mEnableTrace;
}
void cDrawScenarioSimChar::DrawScene()
{
DrawGrid();
DrawGroundMainScene();
DrawCharacterMainScene();
DrawObjsMainScene();
DrawPerturbs();
if (mDrawInfo)
{
DrawInfo();
}
if (mDrawPoliInfo)
{
DrawPoliInfo();
}
if (mEnableTrace)
{
DrawTrace();
}
if (mDrawFeatures)
{
DrawFeatures();
}
if (mDrawPolicyPlots)
{
DrawPolicyPlots();
}
}
void cDrawScenarioSimChar::DrawGrid() const
{
const double spacing = 0.10f;
const double big_spacing = spacing * 5.f;
tVector origin = mCam.GetFocus();
origin += tVector(0, 0, -1, 0);
tVector size = tVector(mCam.GetWidth(), mCam.GetHeight(), 0, 0);
cDrawUtil::SetColor(tVector(188 / 255.f, 219 / 255.f, 242 / 255.f, 1.f));
cDrawUtil::DrawGrid2D(origin, size, spacing, big_spacing);
}
void cDrawScenarioSimChar::DrawGroundMainScene()
{
DrawGround();
}
void cDrawScenarioSimChar::DrawCharacterMainScene()
{
DrawCharacter();
}
void cDrawScenarioSimChar::DrawObjsMainScene()
{
DrawObjs();
}
void cDrawScenarioSimChar::DrawGround() const
{
const auto& ground = mScene->GetGround();
tVector focus = mCam.GetFocus();
double cam_w = mCam.GetWidth();
double cam_h = mCam.GetHeight();
tVector ground_col = GetGroundColor();
tVector bound_min = focus - tVector(cam_w, cam_h, 0, 0) * 0.5;
tVector bound_max = focus + tVector(cam_w, cam_h, 0, 0) * 0.5;
cDrawGround::Draw2D(ground.get(), ground_col, bound_min, bound_max);
}
void cDrawScenarioSimChar::DrawCharacter() const
{
const auto& character = mScene->GetCharacter();
bool enable_draw_shape = true;
cDrawSimCharacter::Draw(*(character.get()), gFillTint, GetLineColor(), enable_draw_shape);
}
void cDrawScenarioSimChar::DrawTrace() const
{
glPushMatrix();
cDrawUtil::Translate(GetVisOffset());
mTracer.Draw();
glPopMatrix();
}
void cDrawScenarioSimChar::DrawObjs() const
{
const tVector col = tVector(0.5, 0.5, 0.5, 1);
const auto& obj_entries = mScene->GetObjs();
for (size_t i = 0; i < obj_entries.size(); ++i)
{
const cScenarioSimChar::tObjEntry& entry = obj_entries[i];
const auto& obj = entry.mObj;
cDrawUtil::SetColor(tVector(col[0], col[1], col[2], col[3]));
cDrawObj::Draw(obj.get(), cDrawUtil::eDrawSolid);
tVector line_col = GetLineColor();
if (line_col[3] > 0)
{
cDrawUtil::SetColor(line_col);
cDrawObj::Draw(obj.get(), cDrawUtil::eDrawWire);
}
}
}
tVector cDrawScenarioSimChar::GetVisOffset() const
{
return gVisOffset;
}
tVector cDrawScenarioSimChar::GetLineColor() const
{
return gLineColor;
}
tVector cDrawScenarioSimChar::GetGroundColor() const
{
return tVector(151 / 255.0, 151 / 255.0, 151 / 255.0, 1.0);
}
void cDrawScenarioSimChar::DrawInfo() const
{
DrawCoM();
DrawTorque();
DrawCtrlInfo();
}
void cDrawScenarioSimChar::DrawCoM() const
{
const tVector col = tVector(0, 1, 0, 0.5);
const double marker_size = 0.1;
const double vel_scale = 0.1;
const auto& character = mScene->GetCharacter();
cDrawSimCharacter::DrawCoM(*(character.get()), marker_size, vel_scale, col, GetVisOffset());
}
void cDrawScenarioSimChar::DrawTorque() const
{
const auto& character = mScene->GetCharacter();
cDrawSimCharacter::DrawTorque(*(character.get()), GetVisOffset());
}
void cDrawScenarioSimChar::DrawCtrlInfo() const
{
const auto& character = mScene->GetCharacter();
cDrawSimCharacter::DrawCtrlInfo(character->GetController().get(), GetVisOffset());
}
void cDrawScenarioSimChar::DrawPoliInfo() const
{
const auto& character = mScene->GetCharacter();
cDrawSimCharacter::DrawPoliInfo(character->GetController().get(), mCam);
}
void cDrawScenarioSimChar::DrawFeatures() const
{
const double marker_size = 0.05;
const double vel_scale = 0.025;
const tVector pos_col = tVector(1, 0, 0, 0.5);
const tVector vel_col = tVector(0, 0.75, 0, 0.5);
const tVector terrain_col = tVector(0, 0, 1, 0.5);
const auto& character = mScene->GetCharacter();
const auto& ground = mScene->GetGround();
cDrawSimCharacter::DrawCharFeatures(*(character.get()), *ground.get(),
marker_size, vel_scale, pos_col, vel_col, GetVisOffset());
cDrawSimCharacter::DrawTerainFeatures(*(character.get()), marker_size, terrain_col, GetVisOffset());
}
void cDrawScenarioSimChar::DrawPolicyPlots() const
{
const auto& character = mScene->GetCharacter();
cDrawSimCharacter::DrawPolicyPlots(character->GetController().get(), mCam);
}
void cDrawScenarioSimChar::DrawPerturbs() const
{
const auto& world = mScene->GetWorld();
cDrawWorld::DrawPerturbs(*world.get());
}
std::string cDrawScenarioSimChar::BuildTextInfoStr() const
{
const auto& character = mScene->GetCharacter();
tVector com = character->CalcCOM();
tVector com_vel = character->CalcCOMVel();
char buffer[128];
#ifdef _WIN32
sprintf_s(buffer, "Position: (%.2f, %.2f)\nVelocity: (%.2f, %.2f)\n", com[0], com[1], com_vel[0], com_vel[1]);
#else
sprintf(buffer, "Position: (%.2f, %.2f)\nVelocity: (%.2f, %.2f)\n", com[0], com[1], com_vel[0], com_vel[1]);
#endif
std::string str(buffer);
return str;
}
void cDrawScenarioSimChar::Shutdown()
{
mScene->Shutdown();
}
const std::shared_ptr<cScenarioSimChar>& cDrawScenarioSimChar::GetScene() const
{
return mScene;
}
std::string cDrawScenarioSimChar::GetOutputCharFile() const
{
return gOutputCharFile;
}
void cDrawScenarioSimChar::OutputCharState(const std::string& out_file) const
{
mScene->OutputCharState(out_file);
}
void cDrawScenarioSimChar::SpawnProjectile()
{
mScene->SpawnProjectile();
}
void cDrawScenarioSimChar::SpawnBigProjectile()
{
mScene->SpawnBigProjectile();
}