collision, ApplicationObject with BSP

A place for users of OGRE to discuss ideas and experiences of utilitising OGRE in their games / demos / applications.
anjay
Gnoblar
Posts: 9
Joined: Thu Mar 17, 2005 3:29 pm
Location: Vilnius, Lithuania

collision, ApplicationObject with BSP

Post by anjay »

I'm using ApplicationRefference. a problem occured when I try to move manually (with arrow keys) a robot which is object derived from ApplicationObject. it does not collide with BSP world (it crosses through the wall). I want it to react to collision with the BSP like CollideCamera does or simply to stop when it reached the wall. how can I achieve this? thank you for your answer.
User avatar
luis
Greenskin
Posts: 122
Joined: Tue Mar 02, 2004 3:33 pm
Location: Spain / Argentina
x 7

Post by luis »

would be better if you post your code :-)

but, did you put this line ?

mMyRobot->setDynamicsEnabled(true);

are you moving it with setLinearVelocity or any other ApplicationObject's function?
anjay
Gnoblar
Posts: 9
Joined: Thu Mar 17, 2005 3:29 pm
Location: Vilnius, Lithuania

Post by anjay »

I have the main Game class, which inherits from ExampleRefAppApplication. here I create a robot. code is:

Code: Select all

...
ApplicationObject *zMyRobot;
...

void Game::createWorld(void) {
	mWorld = new World(mSceneMgr, World::WT_REFAPP_BSP);
}

void Game::createScene(void) {
	mWorld->setGravity(Vector3(0, 0, -60));
	mWorld->getSceneManager()->setWorldGeometry("ogretestmap.bsp");
	zMyRobot = (ApplicationObject*)mWorld->createRobot("manorobotas", 10, 40, 10);
	zMyRobot->setPosition(-100, 0, 0);
	zMyRobot->pitch(Degree(90));
	zMyRobot->setDynamicsEnabled(true);
}

void Game::createFrameListener(void) {

	mFrameListener= new GameListener(mWindow, mCamera, zMyRobot);
	mRoot->addFrameListener(mFrameListener);
}
another class GameListener which inherits from ExampleRefAppApplicationListener has method frameEnded() where I do moving. code is:

Code: Select all

bool GameListener::frameEnded(const FrameEvent& evt) {

	if (evt.timeSinceLastFrame == 0) {
		mMoveScale = 0.5;
		mRotScale = 0.1;
	} else { 
		mMoveScale = 50.0 * evt.timeSinceLastFrame;
		mRotScale = Degree(36 * evt.timeSinceLastFrame);
	}
	
	mRotX = 0;
	mRotY = 0;
	mTranslateVector = Vector3::ZERO;

	mInputDevice->capture();

	if (mInputDevice->isKeyDown(Ogre::KC_UP)) {
		mTranslateVector.x = mMoveScale;
	}

	if (mInputDevice->isKeyDown(Ogre::KC_DOWN)) {
		mTranslateVector.x = -mMoveScale;
	}

	if (mInputDevice->isKeyDown(Ogre::KC_RIGHT)) {
		zfMyRobot->yaw(-mRotScale);
	}

	if (mInputDevice->isKeyDown(Ogre::KC_LEFT)) {
		zfMyRobot->yaw(mRotScale);
	}

	if (mInputDevice->isKeyDown(Ogre::KC_ESCAPE)) {
		return false;
	}

	if (!processMouse())
		return false;

	zfMyRobot->translate(mTranslateVector);

	World::getSingleton().simulationStep(evt.timeSinceLastFrame);

	updateStats();
	return true;

}
I created method createRobot() in Application Refference class AppRefWorld. code is:

Code: Select all

OgreRefApp::Robot* World::createRobot(const String& name, 
    Real width, Real height, Real depth,
    const Vector3& pos, const Quaternion& orientation)
{
        OgreRefApp::Robot* robot = new OgreRefApp::Robot(name, width,  height, depth);
        robot->setPosition(pos);
        robot->setOrientation(orientation);

        mObjects[name] = robot;

        return robot;
}
construction of robot is:

Code: Select all

Robot::Robot(const String& name, Real width, Real height, Real depth) : ApplicationObject(name)
{
        mDimensions.x = width;
        mDimensions.y = height;
        mDimensions.z = depth;
        setUp(name);
}

void Robot::setUp(const String& name)
{
        // Create visual presence
        SceneManager* sm = World::getSingleton().getSceneManager();
        mEntity = sm->createEntity(name, "Robot.mesh");
        mSceneNode = sm->getRootSceneNode()->createChildSceneNode(name);

	mSceneNode->scale(mDimensions.x / 33.3f, mDimensions.y / 150.f, mDimensions.z / 33.3f);

        mSceneNode->attachObject(mEntity);
        // Add reverse reference
        mEntity->setUserObject(this);

        // Create mass body
        mOdeBody = new dBody(World::getSingleton().getOdeWorld()->id());
        // Set reverse reference
        mOdeBody->setData(this);
        // Set mass 
        setMassBox(100.0, mDimensions);
		
        this->setBounceParameters(0.0, 0.0);
        this->setSoftness(0.0f);
        this->setFriction(Math::POS_INFINITY);

        dBox* odeBox = new dBox(0, mDimensions.x, mDimensions.y, mDimensions.z);
        mCollisionProxies.push_back(odeBox);
        updateCollisionProxies();

}
it is all. after running this code, there are no collisions between robot and BSP world.
then I found, that CollideCamera has method _notifyCollided(), so i put this into my robot class:

Code: Select all

void Robot::_notifyCollided(SceneQuery::WorldFragment* wf, const CollisionInfo& info) 
{
        this->translateWorldSpace(info.normal * info.penetrationDepth);

}
now I have collisions with BSP, but I do not like them, they are very chaotic. the robot behaves like that boxes in BspCollision Demo when the ball hits them. how can I achieve that robot's and BSP collisions would be like CollideCamera's and BSP?
User avatar
luis
Greenskin
Posts: 122
Joined: Tue Mar 02, 2004 3:33 pm
Location: Spain / Argentina
x 7

Post by luis »

you are using Ode to simulate physics so, you shouldn't move your objects (unless it is the first time to put them in the world) calling "setposition",
use setLinearVelocity or any other ApplicationObject's function and Ode will move them for you.
example:

Code: Select all

......
if (mInputDevice->isKeyDown(Ogre::KC_DOWN)) {
      mTranslateVector.x = -mMoveScale;
   } 

 zfMyRobot->setLinearVelocity(mTranslateVector);
.....
then, your object's collision will be like collide camera :-)[/code]