Initial commit
This commit is contained in:
350
Torque/SDK/engine/gui/editor/guiGraphCtrl.cc
Normal file
350
Torque/SDK/engine/gui/editor/guiGraphCtrl.cc
Normal file
@@ -0,0 +1,350 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "console/console.h"
|
||||
#include "console/consoleTypes.h"
|
||||
#include "dgl/dgl.h"
|
||||
|
||||
#include "gui/editor/guiGraphCtrl.h"
|
||||
|
||||
IMPLEMENT_CONOBJECT(GuiGraphCtrl);
|
||||
|
||||
GuiGraphCtrl::GuiGraphCtrl()
|
||||
{
|
||||
|
||||
for(int i = 0; i < MaxPlots; i++)
|
||||
{
|
||||
mPlots[i].mAutoPlot = NULL;
|
||||
mPlots[i].mAutoPlotDelay = 0;
|
||||
mPlots[i].mGraphColor = ColorF(1.0, 1.0, 1.0);
|
||||
VECTOR_SET_ASSOCIATION(mPlots[i].mGraphData);
|
||||
mPlots[i].mGraphMax = 1;
|
||||
mPlots[i].mGraphType = Polyline;
|
||||
for(int j = 0; j < MaxDataPoints; j++)
|
||||
mPlots[i].mGraphData.push_front(0.0);
|
||||
}
|
||||
|
||||
AssertWarn(MaxPlots == 6, "Only 6 plot colors initialized. Update following code if you change MaxPlots.");
|
||||
|
||||
mPlots[0].mGraphColor = ColorF(1.0, 1.0, 1.0);
|
||||
mPlots[1].mGraphColor = ColorF(1.0, 0.0, 0.0);
|
||||
mPlots[2].mGraphColor = ColorF(0.0, 1.0, 0.0);
|
||||
mPlots[3].mGraphColor = ColorF(0.0, 0.0, 1.0);
|
||||
mPlots[4].mGraphColor = ColorF(0.0, 1.0, 1.0);
|
||||
mPlots[5].mGraphColor = ColorF(0.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
static EnumTable::Enums enumGraphTypes[] = {
|
||||
{ GuiGraphCtrl::Bar, "bar" },
|
||||
{ GuiGraphCtrl::Filled, "filled" },
|
||||
{ GuiGraphCtrl::Point, "point" },
|
||||
{ GuiGraphCtrl::Polyline , "polyline" },
|
||||
};
|
||||
|
||||
static EnumTable gGraphTypeTable( 4, &enumGraphTypes[0] );
|
||||
|
||||
bool GuiGraphCtrl::onWake()
|
||||
{
|
||||
if (! Parent::onWake())
|
||||
return false;
|
||||
setActive(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
void GuiGraphCtrl::onRender(Point2I offset, const RectI &updateRect)
|
||||
{
|
||||
if (mProfile->mBorder)
|
||||
{
|
||||
RectI rect(offset.x, offset.y, mBounds.extent.x, mBounds.extent.y);
|
||||
dglDrawRect(rect, mProfile->mBorderColor);
|
||||
}
|
||||
|
||||
glBlendFunc(GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR);
|
||||
glEnable(GL_BLEND);
|
||||
ColorF color(1.0, 1.0, 1.0, 0.5);
|
||||
dglDrawRectFill(updateRect, color);
|
||||
glDisable(GL_BLEND);
|
||||
glBlendFunc(GL_ONE, GL_ZERO);
|
||||
|
||||
for (int k = 0; k < MaxPlots; k++)
|
||||
{
|
||||
|
||||
|
||||
// Check if there is an autoplot and the proper amount of time has passed, if so add datum.
|
||||
if((mPlots[k].mAutoPlot!=NULL) &&
|
||||
(mPlots[k].mAutoPlotDelay < (Sim::getCurrentTime() - mPlots[k].mAutoPlotLastDisplay)))
|
||||
{
|
||||
mPlots[k].mAutoPlotLastDisplay = Sim::getCurrentTime();
|
||||
addDatum(k, Con::getFloatVariable(mPlots[k].mAutoPlot));
|
||||
Con::setIntVariable(mPlots[k].mAutoPlot, 0);
|
||||
}
|
||||
|
||||
// Adjust scale to max value + 5% so we can see high values
|
||||
F32 Scale = (F32(getExtent().y) / (F32(mPlots[k].mGraphMax*1.05)));
|
||||
|
||||
// Nothing to graph
|
||||
if (mPlots[k].mGraphData.size() == 0)
|
||||
continue;
|
||||
|
||||
// Bar graph
|
||||
if(mPlots[k].mGraphType == Bar)
|
||||
{
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
glColor3fv(mPlots[k].mGraphColor);
|
||||
|
||||
S32 temp1,temp2;
|
||||
temp1 = 0;
|
||||
|
||||
for (S32 sample = 0; sample < getExtent().x; sample++)
|
||||
{
|
||||
if(mPlots[k].mGraphData.size() >= getExtent().x)
|
||||
temp2 = sample;
|
||||
else
|
||||
temp2 = (S32)(((F32)getExtent().x / (F32)mPlots[k].mGraphData.size()) * (F32)sample);
|
||||
|
||||
glVertex2i(getPosition().x + temp1,
|
||||
(getPosition().y + getExtent().y) - (S32)(getDatum(k, sample) * Scale));
|
||||
|
||||
glVertex2i(getPosition().x + temp2,
|
||||
(getPosition().y + getExtent().y) - (S32)(getDatum(k, sample) * Scale));
|
||||
|
||||
glVertex2i(getPosition().x + temp2,
|
||||
getPosition().y + getExtent().y);
|
||||
|
||||
glVertex2i(getPosition().x + temp1,
|
||||
getPosition().y + getExtent().y);
|
||||
|
||||
temp1 = temp2;
|
||||
}
|
||||
|
||||
glEnd();
|
||||
}
|
||||
|
||||
// Filled graph
|
||||
else if(mPlots[k].mGraphType == Filled)
|
||||
{
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
glColor3fv(mPlots[k].mGraphColor);
|
||||
|
||||
S32 temp1,temp2;
|
||||
temp1 = 0;
|
||||
|
||||
for (S32 sample = 0; sample < (getExtent().x-1); sample++)
|
||||
{
|
||||
if(mPlots[k].mGraphData.size() >= getExtent().x)
|
||||
temp2 = sample;
|
||||
else
|
||||
temp2 = (S32)(((F32)getExtent().x / (F32)mPlots[k].mGraphData.size()) * (F32)sample);
|
||||
|
||||
glVertex2i(getPosition().x + temp1,
|
||||
(getPosition().y + getExtent().y) - (S32)(getDatum(k, sample) * Scale));
|
||||
|
||||
glVertex2i(getPosition().x + temp2,
|
||||
(getPosition().y + getExtent().y) - (S32)(getDatum(k, sample+1) * Scale));
|
||||
|
||||
glVertex2i(getPosition().x + temp2,
|
||||
getPosition().y + getExtent().y);
|
||||
|
||||
glVertex2i(getPosition().x + temp1,
|
||||
getPosition().y + getExtent().y);
|
||||
|
||||
temp1 = temp2;
|
||||
}
|
||||
|
||||
|
||||
// last point
|
||||
S32 sample = getExtent().x;
|
||||
|
||||
if(mPlots[k].mGraphData.size() >= getExtent().x)
|
||||
temp2 = sample;
|
||||
else
|
||||
temp2 = (S32)(((F32)getExtent().x / (F32)mPlots[k].mGraphData.size()) * (F32)sample);
|
||||
|
||||
glVertex2i(getPosition().x + temp1,
|
||||
(getPosition().y + getExtent().y) - (S32)(getDatum(k, sample) * Scale));
|
||||
|
||||
glVertex2i(getPosition().x + temp2,
|
||||
(getPosition().y + getExtent().y) - (S32)(getDatum(k, sample) * Scale));
|
||||
|
||||
glVertex2i(getPosition().x + temp2,
|
||||
getPosition().y + getExtent().y);
|
||||
|
||||
glVertex2i(getPosition().x + temp1,
|
||||
getPosition().y + getExtent().y);
|
||||
|
||||
glEnd();
|
||||
}
|
||||
|
||||
|
||||
// Point or Polyline graph
|
||||
else if((mPlots[k].mGraphType == Point) || (mPlots[k].mGraphType == Polyline))
|
||||
{
|
||||
if(mPlots[k].mGraphType == Point)
|
||||
glBegin(GL_POINTS);
|
||||
else
|
||||
glBegin(GL_LINE_STRIP);
|
||||
|
||||
glColor3fv(mPlots[k].mGraphColor);
|
||||
|
||||
for (S32 sample = 0; sample < getExtent().x; sample++)
|
||||
{
|
||||
S32 temp;
|
||||
if(mPlots[k].mGraphData.size() >= getExtent().x)
|
||||
temp = sample;
|
||||
else
|
||||
temp = (S32)(((F32)getExtent().x / (F32)mPlots[k].mGraphData.size()) * (F32)sample);
|
||||
|
||||
glVertex2i(getPosition().x + temp,
|
||||
(getPosition().y + getExtent().y) - (S32)(getDatum(k, sample) * Scale));
|
||||
}
|
||||
|
||||
glEnd();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void GuiGraphCtrl::addDatum(S32 plotID, F32 v)
|
||||
{
|
||||
AssertFatal(plotID > -1 && plotID < MaxPlots, "Invalid plot specified!");
|
||||
|
||||
// Add the data and trim the vector...
|
||||
mPlots[plotID].mGraphData.push_front( v );
|
||||
|
||||
if(mPlots[plotID].mGraphData.size() > MaxDataPoints)
|
||||
mPlots[plotID].mGraphData.pop_back();
|
||||
|
||||
// Keep record of maximum data value for scaling purposes.
|
||||
if(v > mPlots[plotID].mGraphMax)
|
||||
mPlots[plotID].mGraphMax = v;
|
||||
}
|
||||
|
||||
float GuiGraphCtrl::getDatum( int plotID, int sample)
|
||||
{
|
||||
AssertFatal(plotID > -1 && plotID < MaxPlots, "Invalid plot specified!");
|
||||
AssertFatal(sample > -1 && sample < MaxDataPoints, "Invalid sample specified!");
|
||||
return mPlots[plotID].mGraphData[sample];
|
||||
}
|
||||
|
||||
void GuiGraphCtrl::addAutoPlot(S32 plotID, const char *variable, S32 update)
|
||||
{
|
||||
mPlots[plotID].mAutoPlot = StringTable->insert(variable);
|
||||
mPlots[plotID].mAutoPlotDelay = update;
|
||||
Con::setIntVariable(mPlots[plotID].mAutoPlot, 0);
|
||||
}
|
||||
|
||||
void GuiGraphCtrl::removeAutoPlot(S32 plotID)
|
||||
{
|
||||
mPlots[plotID].mAutoPlot = NULL;
|
||||
}
|
||||
|
||||
void GuiGraphCtrl::setGraphType(S32 plotID, const char *graphType)
|
||||
{
|
||||
AssertFatal(plotID > -1 && plotID < MaxPlots, "Invalid plot specified!");
|
||||
if(!dStricmp(graphType,"Bar"))
|
||||
mPlots[plotID].mGraphType = Bar;
|
||||
else if(!dStricmp(graphType,"Filled"))
|
||||
mPlots[plotID].mGraphType = Filled;
|
||||
else if(!dStricmp(graphType,"Point"))
|
||||
mPlots[plotID].mGraphType = Point;
|
||||
else if(!dStricmp(graphType,"Polyline"))
|
||||
mPlots[plotID].mGraphType = Polyline;
|
||||
else AssertWarn(true, "Invalid graph type!");
|
||||
}
|
||||
|
||||
ConsoleMethod(GuiGraphCtrl, addDatum, void, 4, 4, "(int plotID, float v)"
|
||||
"Add a data point to the given plot.")
|
||||
{
|
||||
S32 plotID = dAtoi(argv[2]);
|
||||
if(plotID > object->MaxPlots)
|
||||
{
|
||||
Con::errorf("Invalid plotID.");
|
||||
return;
|
||||
}
|
||||
object->addDatum( plotID, dAtof(argv[3]));
|
||||
}
|
||||
|
||||
ConsoleMethod(GuiGraphCtrl, getDatum, F32, 4, 4, "(int plotID, int samples)"
|
||||
"Get a data point from the plot specified, samples from the start of the graph.")
|
||||
{
|
||||
S32 plotID = dAtoi(argv[2]);
|
||||
S32 samples = dAtoi(argv[3]);
|
||||
|
||||
if(plotID > object->MaxPlots)
|
||||
{
|
||||
Con::errorf("Invalid plotID.");
|
||||
return -1;
|
||||
}
|
||||
if(samples > object->MaxDataPoints)
|
||||
{
|
||||
Con::errorf("Invalid sample.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return object->getDatum(plotID, samples);
|
||||
}
|
||||
|
||||
ConsoleMethod(GuiGraphCtrl, addAutoPlot, void, 5, 5, "(int plotID, string variable, int update)"
|
||||
"Adds a data point with value variable, every update ms.")
|
||||
{
|
||||
S32 plotID = dAtoi(argv[2]);
|
||||
|
||||
if(plotID > object->MaxPlots)
|
||||
{
|
||||
Con::errorf("Invalid plotID.");
|
||||
return;
|
||||
}
|
||||
|
||||
object->addAutoPlot(plotID,argv[3],dAtoi(argv[4]));
|
||||
}
|
||||
|
||||
ConsoleMethod(GuiGraphCtrl, removeAutoPlot, void, 3, 3, "(int plotID)"
|
||||
"Stops automatic pointing over set interval.")
|
||||
{
|
||||
S32 plotID = dAtoi(argv[2]);
|
||||
|
||||
if(plotID > object->MaxPlots)
|
||||
{
|
||||
Con::errorf("Invalid plotID.");
|
||||
return;
|
||||
}
|
||||
|
||||
object->removeAutoPlot(plotID);
|
||||
}
|
||||
|
||||
ConsoleMethod(GuiGraphCtrl, setGraphType, void, 4, 4, "(int plotID, string graphType)"
|
||||
"Change GraphType of plot plotID.")
|
||||
{
|
||||
S32 plotID = dAtoi(argv[2]);
|
||||
|
||||
if(plotID > object->MaxPlots)
|
||||
{
|
||||
Con::errorf("Invalid plotID.");
|
||||
return;
|
||||
}
|
||||
|
||||
object->setGraphType(dAtoi(argv[2]), argv[3]);
|
||||
}
|
||||
|
||||
ConsoleMethod(GuiGraphCtrl, matchScale, void, 3, GuiGraphCtrl::MaxPlots+2, "(int plotID, int plotID, ...)"
|
||||
"Sets the scale of all specified plots to the maximum scale among them.")
|
||||
{
|
||||
F32 Max = 0;
|
||||
for(int i=0; i < (argc-2); i++)
|
||||
{
|
||||
if(dAtoi(argv[2+i]) > object->MaxPlots)
|
||||
{
|
||||
Con::errorf("Invalid plotID.");
|
||||
return;
|
||||
}
|
||||
if (object->mPlots[dAtoi(argv[2+i])].mGraphMax > Max)
|
||||
Max = object->mPlots[dAtoi(argv[2+i])].mGraphMax;
|
||||
}
|
||||
for(int i=0; i < (argc-2); i++)
|
||||
object->mPlots[dAtoi(argv[2+i])].mGraphMax = Max;
|
||||
}
|
||||
Reference in New Issue
Block a user