Merge pull request #849 from benelot/3D-NN-walkers-example

Improvements to 3DNNWalkers example
This commit is contained in:
erwincoumans
2017-06-05 13:31:07 -07:00
committed by GitHub
5 changed files with 866 additions and 451 deletions

3
.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
/bin
/build3/gmake
/build_cmake/

File diff suppressed because it is too large Load Diff

View File

@@ -208,7 +208,8 @@ struct NN3DWalkersTimeWarpBase: public CommonRigidBodyBase {
CommonRigidBodyBase(helper), CommonRigidBodyBase(helper),
mPhysicsStepsPerSecondUpdated(false), mPhysicsStepsPerSecondUpdated(false),
mFramesPerSecondUpdated(false), mFramesPerSecondUpdated(false),
mSolverIterationsUpdated(false) { mSolverIterationsUpdated(false),
mIsHeadless(false){
// main frame timer initialization // main frame timer initialization
mApplicationStart = mLoopTimer.getTimeMilliseconds(); /**!< Initialize when the application started running */ mApplicationStart = mLoopTimer.getTimeMilliseconds(); /**!< Initialize when the application started running */
@@ -519,7 +520,7 @@ struct NN3DWalkersTimeWarpBase: public CommonRigidBodyBase {
m_collisionConfiguration); m_collisionConfiguration);
} }
changeERPCFM(); // set appropriate ERP/CFM values according to the string and damper properties of the constraint changeERPCFM(); // set appropriate ERP/CFM values according to the spring and damper properties of the constraint
if (useSplitImpulse) { // If you experience strong repulsion forces in your constraints, it might help to enable the split impulse feature if (useSplitImpulse) { // If you experience strong repulsion forces in your constraints, it might help to enable the split impulse feature
m_dynamicsWorld->getSolverInfo().m_splitImpulse = 1; //enable split impulse feature m_dynamicsWorld->getSolverInfo().m_splitImpulse = 1; //enable split impulse feature
@@ -536,7 +537,7 @@ struct NN3DWalkersTimeWarpBase: public CommonRigidBodyBase {
m_dynamicsWorld->getSolverInfo().m_numIterations = gSolverIterations; // set the number of solver iterations for iteration based solvers m_dynamicsWorld->getSolverInfo().m_numIterations = gSolverIterations; // set the number of solver iterations for iteration based solvers
m_dynamicsWorld->setGravity(btVector3(0, -9.81f, 0)); // set gravity to -9.81 m_dynamicsWorld->setGravity(btVector3(0, btScalar(-9.81f), 0)); // set gravity to -9.81
} }
@@ -551,7 +552,7 @@ struct NN3DWalkersTimeWarpBase: public CommonRigidBodyBase {
void timeWarpSimulation(float deltaTime) // Override this virtual void performModelUpdate(float deltaTime) // Override this
{ {
} }
@@ -559,7 +560,7 @@ struct NN3DWalkersTimeWarpBase: public CommonRigidBodyBase {
void stepSimulation(float deltaTime){ // customly step the simulation void stepSimulation(float deltaTime){ // customly step the simulation
do{ do{
// // settings // settings
if(mPhysicsStepsPerSecondUpdated){ if(mPhysicsStepsPerSecondUpdated){
changePhysicsStepsPerSecond(gPhysicsStepsPerSecond); changePhysicsStepsPerSecond(gPhysicsStepsPerSecond);
mPhysicsStepsPerSecondUpdated = false; mPhysicsStepsPerSecondUpdated = false;
@@ -590,10 +591,10 @@ struct NN3DWalkersTimeWarpBase: public CommonRigidBodyBase {
//############# //#############
// model update - here you perform updates of your model, be it the physics model, the game or simulation state or anything not related to graphics and input // model update - here you perform updates of your model, be it the physics model, the game or simulation state or anything not related to graphics and input
timeWarpSimulation(deltaTime); performModelUpdate(deltaTime);
if(mLoopTimer.getTimeSeconds() - speedUpPrintTimeStamp > 1){ if(mLoopTimer.getTimeSeconds() - speedUpPrintTimeStamp > 1){
// on reset, we calculate the performed speed up // on reset, we calculate the performed speed up
//double speedUp = ((double)performedTime*1000.0)/((double)(mLoopTimer.getTimeMilliseconds()-performanceTimestamp)); double speedUp = ((double)performedTime*1000.0)/((double)(mLoopTimer.getTimeMilliseconds()-performanceTimestamp));
// b3Printf("Avg Effective speedup: %f",speedUp); // b3Printf("Avg Effective speedup: %f",speedUp);
performedTime = 0; performedTime = 0;
performanceTimestamp = mLoopTimer.getTimeMilliseconds(); performanceTimestamp = mLoopTimer.getTimeMilliseconds();
@@ -612,7 +613,7 @@ struct NN3DWalkersTimeWarpBase: public CommonRigidBodyBase {
mModelStart = mLoopTimer.getTimeMilliseconds(); /**!< Begin with the model update (in Milliseconds)*/ mModelStart = mLoopTimer.getTimeMilliseconds(); /**!< Begin with the model update (in Milliseconds)*/
mLastGraphicsTick = mModelStart - mGraphicsStart; /**!< Update graphics timer (in Milliseconds) */ mLastGraphicsTick = mModelStart - mGraphicsStart; /**!< Update graphics timer (in Milliseconds) */
if (gMaximumSpeed /** If maximum speed is enabled*/) { if (gMaximumSpeed) { /** If maximum speed is enabled*/
performMaxStep(); performMaxStep();
} else { /**!< This mode tries to progress as much time as it is expected from the game loop*/ } else { /**!< This mode tries to progress as much time as it is expected from the game loop*/
performSpeedStep(); performSpeedStep();
@@ -627,8 +628,8 @@ struct NN3DWalkersTimeWarpBase: public CommonRigidBodyBase {
mInputDt = mThisModelIteration - mInputClock; mInputDt = mThisModelIteration - mInputClock;
if (mInputDt >= gApplicationTick) { if (mInputDt >= gApplicationTick) {
mInputClock = mThisModelIteration; mInputClock = mThisModelIteration;
// mInputHandler.injectInput(); /**!< Inject input into handlers */ //mInputHandler.injectInput(); /**!< Inject input into handlers */
// mInputHandler.update(mInputClock); /**!< update elements that work on the current input state */ //mInputHandler.update(mInputClock); /**!< update elements that work on the current input state */
} }
mGraphicsStart = mLoopTimer.getTimeMilliseconds(); /**!< Start the graphics update */ mGraphicsStart = mLoopTimer.getTimeMilliseconds(); /**!< Start the graphics update */
@@ -752,10 +753,9 @@ struct NN3DWalkersTimeWarpBase: public CommonRigidBodyBase {
for (int i = 0; i < subSteps; i++) { /**!< Perform the number of substeps to reach the timestep*/ for (int i = 0; i < subSteps; i++) { /**!< Perform the number of substeps to reach the timestep*/
if (timeStep && m_dynamicsWorld) { if (timeStep && m_dynamicsWorld) {
// since we want to perform all proper steps, we perform no interpolated substeps int subSteps = 1; // since we want to perform all proper steps, we perform no interpolated substeps
int subSteps = 1;
m_dynamicsWorld->stepSimulation(btScalar(timeStep), m_dynamicsWorld->stepSimulation(btScalar(fixedPhysicsStepSizeSec),
btScalar(subSteps), btScalar(fixedPhysicsStepSizeSec)); btScalar(subSteps), btScalar(fixedPhysicsStepSizeSec));
} }
} }

View File

@@ -13,7 +13,11 @@ struct DataSource
float m_lastValue; float m_lastValue;
bool m_hasLastValue; bool m_hasLastValue;
DataSource() DataSource()
:m_hasLastValue(false) :m_red(0),
m_green(0),
m_blue(0),
m_lastValue(0),
m_hasLastValue(false)
{ {
} }
}; };
@@ -28,10 +32,12 @@ struct TimeSeriesInternalData
int m_height; int m_height;
float m_pixelsPerUnit; float m_pixelsPerUnit;
float m_zero; float m_center;
int m_timeTicks; int m_timeTicks;
int m_ticksPerSecond; int m_ticksPerSecond;
float m_yScale; float m_yMax;
float m_yMin;
float m_yZero;
int m_bar; int m_bar;
unsigned char m_backgroundRed; unsigned char m_backgroundRed;
@@ -50,13 +56,17 @@ struct TimeSeriesInternalData
} }
TimeSeriesInternalData(int width, int height) TimeSeriesInternalData(int width, int height)
:m_width(width), :m_canvasInterface(NULL),
m_canvasIndex(0),
m_width(width),
m_height(height), m_height(height),
m_pixelsPerUnit(-100), m_pixelsPerUnit(-100),
m_zero(height/2.0), m_center(height/2.0),
m_timeTicks(0), m_timeTicks(0),
m_ticksPerSecond(100), m_ticksPerSecond(100),
m_yScale(1), m_yMax(1),
m_yMin(0),
m_yZero(0.5f),
m_bar(0), m_bar(0),
m_backgroundRed(255), m_backgroundRed(255),
m_backgroundGreen(255), m_backgroundGreen(255),
@@ -105,13 +115,18 @@ void TimeSeriesCanvas::addDataSource(const char* dataSourceLabel, unsigned char
} }
void TimeSeriesCanvas::setupTimeSeries(float yScale, int ticksPerSecond, int startTime, bool clearCanvas) void TimeSeriesCanvas::setupTimeSeries(float yScale, int ticksPerSecond, int startTime, bool clearCanvas)
{
setupTimeSeries(-yScale, yScale, ticksPerSecond, startTime, clearCanvas);
}
void TimeSeriesCanvas::setupTimeSeries(float yMin, float yMax, int ticksPerSecond, int startTime, bool clearCanvas)
{ {
if (0==m_internalData->m_canvasInterface) if (0==m_internalData->m_canvasInterface)
return; return;
m_internalData->m_pixelsPerUnit = -(m_internalData->m_height/3.f)/yScale; m_internalData->m_pixelsPerUnit = -(m_internalData->m_height/3.f)/(0.5f*(yMax-yMin));
m_internalData->m_ticksPerSecond = ticksPerSecond; m_internalData->m_ticksPerSecond = ticksPerSecond;
m_internalData->m_yScale = yScale; m_internalData->m_yMin = yMin;
m_internalData->m_yMax = yMax;
m_internalData->m_dataSources.clear(); m_internalData->m_dataSources.clear();
if (clearCanvas) if (clearCanvas)
@@ -130,18 +145,22 @@ void TimeSeriesCanvas::setupTimeSeries(float yScale, int ticksPerSecond, int sta
} }
} }
float zeroPixelCoord = m_internalData->m_zero; float centerPixelCoord = m_internalData->m_center;
float pixelsPerUnit = m_internalData->m_pixelsPerUnit; float pixelsPerUnit = m_internalData->m_pixelsPerUnit;
float yPos = zeroPixelCoord+pixelsPerUnit*yScale; m_internalData->m_yZero = centerPixelCoord - pixelsPerUnit*0.5f*(yMax+yMin);
float yNeg = zeroPixelCoord+pixelsPerUnit*-yScale;
float yPos = centerPixelCoord+pixelsPerUnit*0.5f*(yMax-yMin);
float yNeg = centerPixelCoord+pixelsPerUnit*-0.5f*(yMax-yMin);
grapicalPrintf("0", sTimeSeriesFontData, 2,zeroPixelCoord,m_internalData->m_textColorRed,m_internalData->m_textColorGreen,m_internalData->m_textColorBlue,m_internalData->m_textColorAlpha); if(yMin < 0 && yMax > 0){
grapicalPrintf("0", sTimeSeriesFontData, 2,m_internalData->m_yZero,m_internalData->m_textColorRed,m_internalData->m_textColorGreen,m_internalData->m_textColorBlue,m_internalData->m_textColorAlpha);
}
char label[1024]; char label[1024];
sprintf(label,"%2.1f", yScale); sprintf(label,"%2.1f", yMax);
grapicalPrintf(label, sTimeSeriesFontData, 2,yPos,m_internalData->m_textColorRed,m_internalData->m_textColorGreen,m_internalData->m_textColorBlue,m_internalData->m_textColorAlpha); grapicalPrintf(label, sTimeSeriesFontData, 2,yPos,m_internalData->m_textColorRed,m_internalData->m_textColorGreen,m_internalData->m_textColorBlue,m_internalData->m_textColorAlpha);
sprintf(label,"%2.1f", -yScale); sprintf(label,"%2.1f", yMin);
grapicalPrintf(label, sTimeSeriesFontData, 2,yNeg,m_internalData->m_textColorRed,m_internalData->m_textColorGreen,m_internalData->m_textColorBlue,m_internalData->m_textColorAlpha); grapicalPrintf(label, sTimeSeriesFontData, 2,yNeg,m_internalData->m_textColorRed,m_internalData->m_textColorGreen,m_internalData->m_textColorBlue,m_internalData->m_textColorAlpha);
m_internalData->m_canvasInterface->refreshImageData(m_internalData->m_canvasIndex); m_internalData->m_canvasInterface->refreshImageData(m_internalData->m_canvasIndex);
@@ -209,7 +228,7 @@ void TimeSeriesCanvas::shift1PixelToLeft()
int resetVal = 10; int resetVal = 10;
int countdown = resetVal; int countdown = resetVal;
//shift pixture one pixel to the left //shift picture one pixel to the left
for (int j=50;j<m_internalData->m_height-48;j++) for (int j=50;j<m_internalData->m_height-48;j++)
{ {
for (int i=40;i<this->m_internalData->m_width;i++) for (int i=40;i<this->m_internalData->m_width;i++)
@@ -238,14 +257,13 @@ void TimeSeriesCanvas::shift1PixelToLeft()
} }
} }
{ {
int resetVal = 2; int resetVal = 2;
static int countdown = resetVal; static int countdown = resetVal;
if (!countdown--) if (!countdown--)
{ {
countdown=resetVal; countdown=resetVal;
m_internalData->m_canvasInterface->setPixel(m_internalData->m_canvasIndex,m_internalData->m_width-1,m_internalData->m_zero,0,0,0,255); m_internalData->m_canvasInterface->setPixel(m_internalData->m_canvasIndex,m_internalData->m_width-1,m_internalData->m_yZero,0,0,0,255);
} }
} }
@@ -255,11 +273,11 @@ void TimeSeriesCanvas::shift1PixelToLeft()
if (!countdown--) if (!countdown--)
{ {
countdown=resetVal; countdown=resetVal;
float zeroPixelCoord = m_internalData->m_zero; float centerPixelCoord = m_internalData->m_center;
float pixelsPerUnit = m_internalData->m_pixelsPerUnit; float pixelsPerUnit = m_internalData->m_pixelsPerUnit;
float yPos = zeroPixelCoord+pixelsPerUnit*m_internalData->m_yScale; float yPos = centerPixelCoord+pixelsPerUnit*0.5f*(m_internalData->m_yMax-m_internalData->m_yMin);
float yNeg = zeroPixelCoord+pixelsPerUnit*-m_internalData->m_yScale; float yNeg = centerPixelCoord+pixelsPerUnit*-0.5f*(m_internalData->m_yMax-m_internalData->m_yMin);
m_internalData->m_canvasInterface->setPixel(m_internalData->m_canvasIndex,m_internalData->m_width-1, m_internalData->m_canvasInterface->setPixel(m_internalData->m_canvasIndex,m_internalData->m_width-1,
yPos,0,0,0,255); yPos,0,0,0,255);
@@ -276,7 +294,7 @@ void TimeSeriesCanvas::shift1PixelToLeft()
char buf[1024]; char buf[1024];
float time = m_internalData->getTime(); float time = m_internalData->getTime();
sprintf(buf,"%2.0f",time); sprintf(buf,"%2.0f",time);
grapicalPrintf(buf, sTimeSeriesFontData, m_internalData->m_width-25,m_internalData->m_zero+3,0,0,0,255); grapicalPrintf(buf, sTimeSeriesFontData, m_internalData->m_width-25,m_internalData->m_center+3,0,0,0,255);
m_internalData->m_bar=m_internalData->m_ticksPerSecond; m_internalData->m_bar=m_internalData->m_ticksPerSecond;
@@ -294,7 +312,7 @@ void TimeSeriesCanvas::insertDataAtCurrentTime(float orgV, int dataSourceIndex,
btAssert(dataSourceIndex < m_internalData->m_dataSources.size()); btAssert(dataSourceIndex < m_internalData->m_dataSources.size());
float zero = m_internalData->m_zero; float zero = m_internalData->m_yZero;
float amp = m_internalData->m_pixelsPerUnit; float amp = m_internalData->m_pixelsPerUnit;
//insert some new value(s) in the right-most column //insert some new value(s) in the right-most column
{ {

View File

@@ -13,6 +13,7 @@ public:
virtual ~TimeSeriesCanvas(); virtual ~TimeSeriesCanvas();
void setupTimeSeries(float yScale, int ticksPerSecond, int startTime, bool clearCanvas=true); void setupTimeSeries(float yScale, int ticksPerSecond, int startTime, bool clearCanvas=true);
void setupTimeSeries(float yMin, float yMax, int ticksPerSecond, int startTime, bool clearCanvas=true);
void addDataSource(const char* dataSourceLabel, unsigned char red,unsigned char green,unsigned char blue); void addDataSource(const char* dataSourceLabel, unsigned char red,unsigned char green,unsigned char blue);
void insertDataAtCurrentTime(float value, int dataSourceIndex, bool connectToPrevious); void insertDataAtCurrentTime(float value, int dataSourceIndex, bool connectToPrevious);
float getCurrentTime() const; float getCurrentTime() const;