0

I am messing around with some code I found online, added a static property and now it doesn't compile (although there aren't any syntax errors).

Here is the important part of the code:

public:
    static SceneNode* currentNode;
    MyMotionState(const btTransform & initialPos, SceneNode * node)
    {
        currentNode = 0;
        mVisibleObj = node;
        mTransform = initialPos;
        //mCOM = btTransform::getIdentity();
    }

I got this error:

undefined reference to `MyMotionState::currentNode'

I also tried MyMotionState::currentNode, and currentNode without referring to the class itself.

I heard somewhere this is caused because of Eclipse's parser is outdated. I tried to rebuild and refresh the indexes but still I have the same errors.

Here is the full code:

#ifndef _PHYSICS_H_
#define _PHYSICS_H_

using namespace Ogre;

#include <sstream>
#include "TextRenderer.h"


class MyMotionState : public btDefaultMotionState
{
    protected:
        SceneNode * mVisibleObj;
        btTransform mTransform;
        //btTransform mCOM;

    public:
        static SceneNode* currentNode;
        MyMotionState(const btTransform & initialPos, SceneNode * node)
        {
            currentNode = 0;
            mVisibleObj = node;
            mTransform = initialPos;
            //mCOM = btTransform::getIdentity();
        }

        MyMotionState(const btTransform & initialPos)
        {
            mVisibleObj = NULL;
            mTransform = initialPos;
        }

        ~MyMotionState() {}

        void setNode(SceneNode * node)
        {
            mVisibleObj = node;
        }

        btTransform getWorldTransform() const
        {
            return  mTransform;
        }

        void getWorldTransform(btTransform & worldTrans) const
        {
            worldTrans = mTransform;
        }

        void setWorldTransform(const btTransform & worldTrans)
        {
            if (mVisibleObj == NULL)
                return;

            if (MyMotionState::currentNode != 0)
            {
                TextRenderer::getSingleton().printf("nigger", "Y: %f\ny: %f\nx: %f", MyMotionState::currentNode->getPosition().x, MyMotionState::currentNode->getPosition().y, MyMotionState::currentNode->getPosition().y);
            }

            mTransform = worldTrans;
            btTransform transform = mTransform;
            btQuaternion rot = transform.getRotation();
            btVector3 pos = transform.getOrigin();
            mVisibleObj->setOrientation(rot.w(), rot.x(), rot.y(), rot.z());
            mVisibleObj->setPosition(pos.x(), pos.y(), pos.z());
        }
};

class MyPhysics
{
    private:
        btAlignedObjectArray<btCollisionShape*> mCollisionShapes;
        btBroadphaseInterface * mBroadphase;
        btCollisionDispatcher * mDispatcher;
        btConstraintSolver * mSolver;
        btDefaultCollisionConfiguration * mColConfig;
        btDiscreteDynamicsWorld * mWorld;
        SceneNode * mRootSceneNode;

        int counter;

    public:
        MyPhysics()
        {
            counter = 1;
            mColConfig = new btDefaultCollisionConfiguration;
            mDispatcher = new btCollisionDispatcher(mColConfig);
            mBroadphase = new btDbvtBroadphase;
            mSolver = new btSequentialImpulseConstraintSolver;
            mWorld = new btDiscreteDynamicsWorld(mDispatcher, mBroadphase, mSolver, mColConfig);

            mWorld->setGravity(btVector3(0, -100000000000, 0));
            mRootSceneNode = 0;
        }

        ~MyPhysics()
        {
            for (int i = mWorld->getNumCollisionObjects() - 1; i >= 0; i--)
            {
                btCollisionObject * obj = mWorld->getCollisionObjectArray()[i];
                btRigidBody * body = btRigidBody::upcast(obj);

                if (body && body->getMotionState())
                    delete body->getMotionState();

                mWorld->removeCollisionObject(obj);

                delete obj;
            }

            delete mWorld;
            delete mSolver;
            delete mBroadphase;
            delete mDispatcher;
            delete mColConfig;
        }

        void addStaticPlane(SceneNode * node)
        {
            btCollisionShape * groundShape = new btStaticPlaneShape(btVector3(0, 1, 0), 50);
            mCollisionShapes.push_back(groundShape);
            btTransform groundTransform;
            groundTransform.setIdentity();
            groundTransform.setOrigin(btVector3(0, -50, 0));

            MyMotionState * motionState = new MyMotionState(groundTransform, node);
            btRigidBody::btRigidBodyConstructionInfo rbInfo(0, motionState, groundShape, btVector3(0, 0, 0));
            btRigidBody * body = new btRigidBody(rbInfo);

            mWorld->addRigidBody(body);
        }

        void addStaticPlane2(SceneNode * node)
        {
            btCollisionShape * groundShape = new btBoxShape(btVector3(5, 0, 5));
            mCollisionShapes.push_back(groundShape);
            btTransform groundTransform;
            groundTransform.setIdentity();
            groundTransform.setOrigin(btVector3(0, 3, 0));

            MyMotionState * motionState = new MyMotionState(groundTransform, node);
            btRigidBody::btRigidBodyConstructionInfo rbInfo(0, motionState, groundShape, btVector3(0, 0, 0));
            btRigidBody * body = new btRigidBody(rbInfo);

            mWorld->addRigidBody(body);
        }

        btRigidBody * addDynamicBox(SceneNode * node, float m = 1.0f)
        {
            btCollisionShape * colShape = new btBoxShape(btVector3(1, 1, 1));
            mCollisionShapes.push_back(colShape);
            btTransform boxTransform;
            boxTransform.setIdentity();

            btScalar mass(m);
            btVector3 localInertia(0, 0, 0);

            colShape->calculateLocalInertia(mass, localInertia);

            boxTransform.setOrigin(btVector3(node->getPosition().x, node->getPosition().y,node->getPosition().z));

            MyMotionState * motionState = new MyMotionState(boxTransform, node);
            btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, motionState, colShape, localInertia);
            btRigidBody * body = new btRigidBody(rbInfo);

            mWorld->addRigidBody(body);

            return body;
        }

        btRigidBody * addRigidBody(btTransform transform, btCollisionShape * shape, btScalar mass, SceneNode * node = NULL)
        {
            mCollisionShapes.push_back(shape);
            btVector3 localInertia(0, 0, 0);

            shape->calculateLocalInertia(mass, localInertia);
            MyMotionState * motionState = new MyMotionState(transform, node);
            btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, motionState, shape, localInertia);
            btRigidBody * body = new btRigidBody(rbInfo);

            mWorld->addRigidBody(body);

            return body;
        }

        void addCollisionShape(btCollisionShape * colShape)
        {
            mCollisionShapes.push_back(colShape);
        }

        btDiscreteDynamicsWorld * getDynamicsWorld()
        {
            return mWorld;
        }

        btCollisionWorld * getCollisionWorld()
        {
            return mWorld->getCollisionWorld();
        }

        btBroadphaseInterface * getBroadphase()
        {
            return mBroadphase;
        }

        void setRootSceneNode(SceneNode * node)
        {
            mRootSceneNode = node;
        }

        btVector3 toBullet(const Vector3 & vec) const
        {
            return btVector3(vec.x, vec.y, vec.z);
        }

        void shootBox(const Vector3 & camPosition)
        {
            if (mRootSceneNode)
            {

                std::stringstream ss;
                ss << counter++;
                SceneNode * node = mRootSceneNode->createChildSceneNode(camPosition);
                MyMotionState::currentNode = node;
                Entity * entity = Root::getSingleton().getSceneManager("nigger-manager")->createEntity("Head"+ ss.str(), "ogrehead.mesh");
                node->scale(0.2, 0.2, 0.2);
                node->attachObject(entity);
                btRigidBody * box = addDynamicBox(node);
                box->applyCentralImpulse(btVector3(10, 0, 0));
            }
        }

        static void debugBtVector3(const btVector3 & vec, const char * str = 0)
        {
            std::cout << str << " x: " << vec.x() << "; y: " << vec.y() << "; z: " << vec.z() << std::endl;
        }
};

#include "physics_debugdraw.h"
#endif
Pacha
  • 1,438
  • 3
  • 23
  • 46

2 Answers2

2

You have declared that "there is a variable called MyMotionState::currentNode", but you need to also define the variable somewhere:

SceneNode *MyMotionState::currentNode; 

in some .cpp file. This is because you may want that variable to "be somewhere specific" (in a specific .cpp file), and the compiler can't just place it at an arbitrary place - if you include "physics.h" in 11 different places, how does the compiler know where it should be? You certainly wouldn't want 11 of them... ;)

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
2

Try adding something like this to your .cpp file.

SceneNode* MyMotionState::currentNode = nullptr;
Andrey Tuganov
  • 351
  • 1
  • 8