robot.mesh, moves, but doesn't walk ? Topic is solved

Problems building or running the engine, queries about how to use features etc.
Post Reply
reb_cabin
Gnoblar
Posts: 12
Joined: Thu Jul 05, 2018 4:19 pm

robot.mesh, moves, but doesn't walk ?

Post by reb_cabin »

Ogre Version: :1.11.1:
Operating System: :Pop! OS (Ubuntu derivative):
Render System: :OpenGL 3+:

I modified the ninja tutorial (light, camera, and shadows) https://goo.gl/Lr7d4X to present the robot walking from the animation tutorial https://goo.gl/vRmqbW. This works with no surprises other than that the "Walk" animation for the robot doesn't seem to be properly triggered. The robot slides across the floor, but its legs don't move. I've seen a movie with the robot animation going https://goo.gl/2Z7qX1 so I figured there is something wrong with my program.

I thought I might inspect the "robot.mesh" file https://goo.gl/anrFgU, first to get a list of all the animations in it so I might try one of the others, and second to see if I could find a clue to the problem. That thought led me down a rabbit hole.

Amongst several other viewers and Blender plugins that all seem moribund for several years or didn't yield to a half-hour's attempt to build, I found DisplaySweet's Ogre-v2-mesh-viewer https://goo.gl/ExyJ34, which requires Qt5 (a download of 67 GB [sic]), and Ogre-v2. Which leads me to the first question:

Can Ogre-v2-1 and Ogre-1.11.1 coexist on the same machine?

That's a question at the bottom of the rabbit hole. At the top is the question:

Is there a quicker way to troubleshoot this app, and what might it be?

Fortunately, my app is short and I can paste it all, here.

Code: Select all

#include <exception>
#include <iostream>

#include <Ogre.h>
#include <OgreApplicationContext.h>
#include <OgreInput.h>
#include <OgreRTShaderSystem.h>
#include <OgreApplicationContext.h>
//#include <OgreWindowEventUtilities.h> // ?
//#include <OgreFrameListener.h> // ?
#include <OgreCameraMan.h>
#include <OgreWindowEventUtilities.h>

using namespace Ogre;
using namespace OgreBites;

class TheApp :
        public ApplicationContext,
        public WindowEventListener,
        public InputListener
{
public:
    std::deque<Vector3> mWaypoints;

    SceneManager * mSceneMgr;
    SceneNode * mCamNode;
    Real mDistance;
    Real mWalkSpeed;
    Vector3 mDirection;
    Vector3 mDestination;
    AnimationState * mAnimationState;
    Entity * mRobotEntity;
    SceneNode * mRobotNode;

    TheApp();
    virtual ~TheApp();

    void setup();

    void frameRendered(const Ogre::FrameEvent& evt);
    bool keyPressed(const KeyboardEvent& evt);
    bool nextLocation();

    void mkBaseAndRoot();
    void mkCamAndViewport();

    void mkLights() const;
    void mkAmbientLight() const;
    void mkSpotLight() const;
    void mkDirectionalLight() const;
    void mkPointLight() const;

    void mkGroundPlane() const;
    void mkGroundMarkers() const;
    void mkKnot(Real x_, Real y_, Real z_) const;
};


TheApp::TheApp(): ApplicationContext("OgreTutorialApp"),
                                            mSceneMgr(0),
                                            mCamNode(0),
                                            mDistance(0),
                                            mWalkSpeed(70.0),
                                            mDirection(Vector3::ZERO),
                                            mDestination(Vector3::ZERO),
                                            mAnimationState(0),
                                            mRobotEntity(0),
                                            mRobotNode(0) {}


TheApp::~TheApp() {}


void TheApp::setup()
{   mkBaseAndRoot();
    mkCamAndViewport();

    mkGroundMarkers();
    mkGroundPlane();
    mkLights();

    mRobotEntity = mSceneMgr->createEntity("robot.mesh");
    mRobotEntity->setCastShadows(true);

    mRobotNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(0, 0, 25.0));
    mRobotNode->attachObject(mRobotEntity);

    mWaypoints.emplace_back(550.0, 0, 50.0);
    mWaypoints.emplace_back(-100.0, 0, -200.0);
    mWaypoints.emplace_back(0, 0, 25.0);

    mAnimationState = mRobotEntity->getAnimationState("Idle");
    mAnimationState->setLoop(true);
    mAnimationState->setEnabled(true);
}

void TheApp::mkGroundMarkers() const {
    mkKnot(0.0, -10.0, -25.0);
    mkKnot(550.0, -10.0, 50.0);
    mkKnot(-100.0, -10.0, -200.0);
}

void TheApp::mkBaseAndRoot() {
    ApplicationContext::setup();
    addInputListener(this);

    // get a pointer to the already created root
    mSceneMgr = getRoot()->createSceneManager();

    // register our scene with the RTSS
    RTShader::ShaderGenerator* shadergen = RTShader::ShaderGenerator::getSingletonPtr();
    shadergen->addSceneManager(mSceneMgr);
}

void TheApp::mkCamAndViewport() {
    mCamNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
    Camera* cam = mSceneMgr->createCamera("myCam");

    cam->setNearClipDistance(5);
    mCamNode->attachObject(cam);

    //    The old stuff
    //    camNode->setPosition(200, 300, 400);
    //    camNode->lookAt(Vector3(0, 0, 0), Node::TransformSpace::TS_WORLD);
    mCamNode->setPosition(90.0, 280.0, 535.0);
    mCamNode->pitch(Degree(-30.0));
    mCamNode->yaw(Degree(-15.0));

    Viewport* vp = getRenderWindow()->addViewport(cam);
    vp->setBackgroundColour(ColourValue(0, 0, 0));
    cam->setAspectRatio(Real(vp->getActualWidth()) / Real(vp->getActualHeight()));
}

void TheApp::mkLights() const {
    mkAmbientLight();
    mkSpotLight();
    mkDirectionalLight();
    mkPointLight();
}

void TheApp::mkPointLight() const {
    Light* pointLight = mSceneMgr->createLight("PointLight");
    pointLight->setType(Light::LT_POINT);

    pointLight->setDiffuseColour(0.3, 0.3, 0.3);
    pointLight->setSpecularColour(0.3, 0.3, 0.3);

    SceneNode* pointLightNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
    pointLightNode->attachObject(pointLight);
    pointLightNode->setPosition(Vector3(0, 150, 250));
}

void TheApp::mkDirectionalLight() const {
    Light* directionalLight = mSceneMgr->createLight("DirectionalLight");
    directionalLight->setType(Light::LT_DIRECTIONAL);

    directionalLight->setDiffuseColour(ColourValue(0.4, 0, 0));
    directionalLight->setSpecularColour(ColourValue(0.4, 0, 0));

    SceneNode* directionalLightNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
    directionalLightNode->attachObject(directionalLight);
    directionalLightNode->setDirection(Vector3(0, -1, 1));
}

void TheApp::mkSpotLight() const {
    Light* spotLight = mSceneMgr->createLight("SpotLight");
    spotLight->setDiffuseColour(0, 0, 1.0);
    spotLight->setSpecularColour(0, 0, 1.0);
    spotLight->setType(Light::LT_SPOTLIGHT);

    SceneNode* spotLightNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
    spotLightNode->attachObject(spotLight);
    spotLightNode->setDirection(-1, -1, 0);
    spotLightNode->setPosition(Vector3(200, 200, 0));

    spotLight->setSpotlightRange(Degree(35), Degree(50));
}

void TheApp::mkAmbientLight() const {
    mSceneMgr->setAmbientLight(ColourValue(0.75, 0.75, 0.75));
    mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_MODULATIVE);
}

void TheApp::mkGroundPlane() const {
    Plane plane(Vector3::UNIT_Y, 0);
    MeshManager::getSingleton().createPlane(
            "ground",
            ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
            plane,
            1500, 1500, 20, 20,
            true,
            1, 5, 5,
            Vector3::UNIT_Z);

    Entity* groundEntity = mSceneMgr->createEntity("ground");
    mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(groundEntity);
    groundEntity->setCastShadows(false);
    groundEntity->setMaterialName("Examples/Rockwall");
}

void TheApp::mkKnot(Real x_, Real y_, Real z_) const {
    auto ent = mSceneMgr->createEntity("knot.mesh");
    auto node = mSceneMgr->getRootSceneNode()->createChildSceneNode(
            Vector3(x_, y_, z_));
    node->attachObject(ent);
    node->setScale(0.1, 0.1, 0.1);
    node->setScale(0.25, 0.25, 0.25);
}

bool TheApp::nextLocation() {
    if (mWaypoints.empty())
    {   return false;   }
    mDestination = mWaypoints.front();
    mWaypoints.pop_front();
    mDirection = mDestination - mRobotNode->getPosition();
    mDistance = mDirection.normalise();
    return true;
}


void TheApp::frameRendered(
        const Ogre::FrameEvent& evt) {
    if(mDirection == Vector3::ZERO)
    {   if (nextLocation())
        {   mAnimationState = mRobotEntity->getAnimationState("Walk");
            mAnimationState->setLoop(true);
            mAnimationState->setEnabled(true);
    }   }
    else
    {   Real move = mWalkSpeed * evt.timeSinceLastFrame;
        mDistance -= move;
        if (mDistance <= 0.0)
        {   mRobotNode->setPosition(mDestination);
            mDirection = Vector3::ZERO;
            if (nextLocation())
            {   auto src = mRobotNode->getOrientation() * Vector3::UNIT_X;
                if ((1.0 + src.dotProduct(mDirection)) < 0.0001)
                {   mRobotNode->yaw(Degree(180));   }
                else
                {   auto quat = src.getRotationTo(mDirection);
                    mRobotNode->rotate(quat);
            }  }
            else
            {   mAnimationState = mRobotEntity->getAnimationState("Idle");
                mAnimationState->setLoop(true);
                mAnimationState->setEnabled(true);
        }   }
        else
        {   mRobotNode->translate(move * mDirection);
}   }   }

bool TheApp::keyPressed(const KeyboardEvent& evt) {
    if (evt.keysym.sym == SDLK_ESCAPE)
    {   getRoot()->queueEndRendering();   }
    return true;
}

int main(int argc, char **argv) {
    try
    {
        TheApp app;
        app.initApp();
        app.getRoot()->startRendering();
        app.closeApp();
    }
    catch (const std::exception& e)
    {
        std::cerr << "Error occurred during execution: " << e.what() << '\n';
        return 1;
    }

    return 0;
}
palsofchaos
Gnoblar
Posts: 7
Joined: Wed Feb 21, 2018 4:38 pm
x 1

Re: robot.mesh, moves, but doesn't walk ?

Post by palsofchaos »

Is nextLocation() ever true? It looks like you populate mWaypoints... but at a glance I would look into what thats returning while your robot is moving.
dermont
Bugbear
Posts: 812
Joined: Thu Dec 09, 2004 2:51 am
x 42

Re: robot.mesh, moves, but doesn't walk ?

Post by dermont »

Think you need to update the animation time.

Code: Select all

            mRobotEntity->getAnimationState("Walk")->addTime(move);
reb_cabin
Gnoblar
Posts: 12
Joined: Thu Jul 05, 2018 4:19 pm

Re: robot.mesh, moves, but doesn't walk ?

Post by reb_cabin »

palsofchaos wrote: Sun Jul 08, 2018 8:35 pm Is nextLocation() ever true? It looks like you populate mWaypoints... but at a glance I would look into what thats returning while your robot is moving.
Yeah, definitely. I stepped through in the debugger and nextLocation is called and returns true. Thanks for the suggestion!
dermont
Bugbear
Posts: 812
Joined: Thu Dec 09, 2004 2:51 am
x 42

Re: robot.mesh, moves, but doesn't walk ?

Post by dermont »

reb_cabin wrote: Sat Jul 07, 2018 10:01 pm
Can Ogre-v2-1 and Ogre-1.11.1 coexist on the same machine?
You can do a local install, add the following to your command line, or set from the GUI.

-DOGRE_FULL_RPATH:BOOL=ON
-DCMAKE_INSTALL_PREFIX:PATH=<your_install_path>

Then when build against the libs either set the paths in your CMakeLists.txt:

Code: Select all

set(CMAKE_PREFIX_PATH "/media/sdb5/Libraries/OGRE/sdk/default/lib/OGRE/cmake;${CMAKE_PREFIX_PATH}")
set(ENV{PKG_CONFIG_PATH} /media/sdb5/Libraries/OGRE/build/default/lib/pkgconfig)
set(OGRE_DIR /media/sdb5/Libraries/OGRE/build/default/lib/OGRE/cmake)
or

Code: Select all

export PKG_CONFIG_PATH /media/sdb5/Libraries/OGRE/build/default/lib/pkgconfig
cmake -DCMAKE_PREFIX_PATH=/media/sdb5/Libraries/OGRE/sdk/default/lib/OGRE/cmake -DOGRE_DIR:PATH=/media/sdb5/Libraries/OGRE/build/default/lib/OGRE/cmake  ........
reb_cabin
Gnoblar
Posts: 12
Joined: Thu Jul 05, 2018 4:19 pm

Re: robot.mesh, moves, but doesn't walk ?

Post by reb_cabin »

dermont wrote: Mon Jul 09, 2018 1:13 am Think you need to update the animation time.

Code: Select all

            mRobotEntity->getAnimationState("Walk")->addTime(move);
I added that line and it has no visible effect. I'm going to dig into the first suggestion by paroj. I bet I need to include "skeletal" animations. Thanks for the suggestion!
reb_cabin
Gnoblar
Posts: 12
Joined: Thu Jul 05, 2018 4:19 pm

Re: robot.mesh, moves, but doesn't walk ?

Post by reb_cabin »

dermont wrote: Mon Jul 09, 2018 1:33 am
reb_cabin wrote: Sat Jul 07, 2018 10:01 pm
Can Ogre-v2-1 and Ogre-1.11.1 coexist on the same machine?
You can do a local install, add the following to your command line, or set from the GUI.

...
Excellent instructions. OgreMeshy is proving difficult to build, so I will probably go down the road you suggest.
Post Reply