Page 5 of 8

Re: MOC - Minimal Ogre Collision 1.0 - [Update 03.May.2009]

Posted: Sun May 03, 2009 11:12 pm
by jacmoe
deadvirus wrote:If you think it would be useful, I could post it here.
Aye, please do! :)
You won't believe how many times people have been asking how to do that..

Re: MOC - Minimal Ogre Collision 1.0 - [Update 03.May.2009]

Posted: Sun May 03, 2009 11:20 pm
by Nauk
Sure post it :) - talking about indices I am thinking of adding a caching functionality to MOC, especially for non-animated meshes or entities that share the same mesh. It should be somewhat faster not to build the index and vertex arrays everytime you make a check new for each and every mesh.

Re: MOC - Minimal Ogre Collision 1.0 - [Update 03.May.2009]

Posted: Sun May 03, 2009 11:41 pm
by deadvirus
Here it is! I'm not sure if it's the right way to do it, or if it has any kind of problems, so if you see anything that could be better, please tell me :)

I will post the entire functions, but the changes to the ones included in MOC, are not much.

This one gets the mesh information:

Code: Select all

void CollisionTools::GetMeshInformation(const Ogre::MeshPtr mesh,
                                size_t &vertex_count,
                                Ogre::Vector3* &vertices,
                                size_t &index_count,
                                Ogre::uint32* &indices,
      		        unsigned short* &indexToSubMesh,
                                const Ogre::Vector3 &position,
                                const Ogre::Quaternion &orient,
                                const Ogre::Vector3 &scale)
{
    bool added_shared = false;
    size_t current_offset = 0;
    size_t shared_offset = 0;
    size_t next_offset = 0;
    size_t index_offset = 0;
    size_t indexSMesh_offset = 0;

    vertex_count = index_count = 0;

    // Calculate how many vertices and indices we're going to need
    for (unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i)
    {
        Ogre::SubMesh* submesh = mesh->getSubMesh( i );

        // We only need to add the shared vertices once
        if(submesh->useSharedVertices)
        {
            if( !added_shared )
            {
                vertex_count += mesh->sharedVertexData->vertexCount;
                added_shared = true;
            }
        }
        else
        {
            vertex_count += submesh->vertexData->vertexCount;
        }

        // Add the indices
        index_count += submesh->indexData->indexCount;
    }


    // Allocate space for the vertices and indices
    vertices = new Ogre::Vector3[vertex_count];
    indices = new Ogre::uint32[index_count];
    indexToSubMesh = new unsigned short[index_count];

    added_shared = false;

    // Run through the submeshes again, adding the data into the arrays
    for ( unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i)
    {
        Ogre::SubMesh* submesh = mesh->getSubMesh(i);

        Ogre::VertexData* vertex_data = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData;

        //set this submesh number to its indices
        for(size_t indexAddC = indexSMesh_offset; 
        indexAddC < indexSMesh_offset + submesh->indexData->indexCount; indexAddC++)
        {
	     indexToSubMesh[indexAddC] = i;
        }

        indexSMesh_offset += submesh->indexData->indexCount;

        if((!submesh->useSharedVertices)||(submesh->useSharedVertices && !added_shared))
        {
            if(submesh->useSharedVertices)
            {
                added_shared = true;
                shared_offset = current_offset;
            }

            const Ogre::VertexElement* posElem =
                vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);

            Ogre::HardwareVertexBufferSharedPtr vbuf =
                vertex_data->vertexBufferBinding->getBuffer(posElem->getSource());

            unsigned char* vertex =
                static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));

            // There is _no_ baseVertexPointerToElement() which takes an Ogre::Ogre::Real or a double
            //  as second argument. So make it float, to avoid trouble when Ogre::Ogre::Real will
            //  be comiled/typedefed as double:
            //      Ogre::Ogre::Real* pOgre::Real;
            float* pReal;

            for( size_t j = 0; j < vertex_data->vertexCount; ++j, vertex += vbuf->getVertexSize())
            {
                posElem->baseVertexPointerToElement(vertex, &pReal);

                Ogre::Vector3 pt(pReal[0], pReal[1], pReal[2]);

                vertices[current_offset + j] = (orient * (pt * scale)) + position;
            }

            vbuf->unlock();
            next_offset += vertex_data->vertexCount;
        }


        Ogre::IndexData* index_data = submesh->indexData;
        size_t numTris = index_data->indexCount / 3;
        Ogre::HardwareIndexBufferSharedPtr ibuf = index_data->indexBuffer;

        bool use32bitindexes = (ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT);

        Ogre::uint32*  pLong = static_cast<Ogre::uint32*>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
        unsigned short* pShort = reinterpret_cast<unsigned short*>(pLong);


        size_t offset = (submesh->useSharedVertices)? shared_offset : current_offset;

        if ( use32bitindexes )
        {
            for ( size_t k = 0; k < numTris*3; ++k)
            {
                indices[index_offset++] = pLong[k] + static_cast<Ogre::uint32>(offset);
            }
        }
        else
        {
            for ( size_t k = 0; k < numTris*3; ++k)
            {
                indices[index_offset++] = static_cast<Ogre::uint32>(pShort[k]) +
                    static_cast<Ogre::uint32>(offset);
            }
        }

        ibuf->unlock();
        current_offset = next_offset;
    }
}
The raycast function:

Code: Select all

bool CollisionTools::raycast(const Ogre::Ray &ray, Ogre::Vector3 &result, Ogre::Entity* &target,float &closest_distance,  unsigned short &submeshNumber, const Ogre::uint32 queryMask)
{
	target = NULL;

    // check we are initialised
    if (mRaySceneQuery != NULL)
    {
        // create a query object
        mRaySceneQuery->setRay(ray);
		mRaySceneQuery->setSortByDistance(true);
		mRaySceneQuery->setQueryMask(queryMask);
        // execute the query, returns a vector of hits
        if (mRaySceneQuery->execute().size() <= 0)
        {
            // raycast did not hit an objects bounding box
            return (false);
        }
    }
    else
    {
        //LOG_ERROR << "Cannot raycast without RaySceneQuery instance" << ENDLOG;
        return (false);
    }

    // at this point we have raycast to a series of different objects bounding boxes.
    // we need to test these different objects to see which is the first polygon hit.
    // there are some minor optimizations (distance based) that mean we wont have to
    // check all of the objects most of the time, but the worst case scenario is that
    // we need to test every triangle of every object.
    //Ogre::Ogre::Real closest_distance = -1.0f;
	closest_distance = -1.0f;
    Ogre::Vector3 closest_result;
    Ogre::RaySceneQueryResult &query_result = mRaySceneQuery->getLastResults();
    for (size_t qr_idx = 0; qr_idx < query_result.size(); qr_idx++)
    {
        // stop checking if we have found a raycast hit that is closer
        // than all remaining entities
        if ((closest_distance >= 0.0f) &&
            (closest_distance < query_result[qr_idx].distance))
        {
            break;
        }

        // only check this result if its a hit against an entity
        if ((query_result[qr_idx].movable != NULL)  &&
            (query_result[qr_idx].movable->getMovableType().compare("Entity") == 0))
        {
            // get the entity to check
			Ogre::Entity *pentity = static_cast<Ogre::Entity*>(query_result[qr_idx].movable);

            // mesh data to retrieve
            size_t vertex_count;
            size_t index_count;
            Ogre::Vector3 *vertices;
            Ogre::uint32 *indices;
			unsigned short *indexToSubmesh;

            // get the mesh information
			GetMeshInformation(((Ogre::Entity*)pentity)->getMesh(), vertex_count, vertices, index_count, indices, indexToSubmesh,
                              pentity->getParentNode()->_getDerivedPosition(),
                              pentity->getParentNode()->_getDerivedOrientation(),
                              pentity->getParentNode()->_getDerivedScale());

            // test for hitting individual triangles on the mesh
            bool new_closest_found = false;
			size_t closest_i;
            for (size_t i = 0; i < index_count; i += 3)
            {
                // check for a hit against this triangle
                std::pair<bool, Ogre::Real> hit = Ogre::Math::intersects(ray, vertices[indices[i]],
                    vertices[indices[i+1]], vertices[indices[i+2]], true, false);

                // if it was a hit check if its the closest
                if (hit.first)
                {
                    if ((closest_distance < 0.0f) ||
                        (hit.second < closest_distance))
                    {
                        // this is the closest so far, save it off
                        closest_distance = hit.second;
                        new_closest_found = true;
						closest_i = i;
                    }
                }
            }

			// free the verticies and indicies memory
            delete[] vertices;
            delete[] indices;

            // if we found a new closest raycast for this object, update the
            // closest_result before moving on to the next object.
            if (new_closest_found)
            {
				target = pentity;
                closest_result = ray.getPoint(closest_distance);

				//get the index of the submesh				
				submeshNumber =  indexToSubmesh[closest_i];
            }
        }
    }

    // return the result
    if (closest_distance >= 0.0f)
    {
        // raycast success
		result = closest_result;
        return (true);
    }
    else
    {
        // raycast failed
        return (false);
    }
}
The others just need to deal with the new param.
I think the best way is to override the other functions, so you can (should) use the "normal" functions when you don't need to know the submesh (it's faster).

Re: MOC - Minimal Ogre Collision 1.0 - [Update 03.May.2009]

Posted: Mon May 04, 2009 9:48 pm
by Nauk
Thanks for posting I will look into it and add it :)

Re: MOC - Minimal Ogre Collision 1.0 - [Update 03.May.2009]

Posted: Sun May 10, 2009 5:14 pm
by adanar
Hello again.

I noticed some strange behavior in raycast method. whenever it hits an entity, the intersects method returns a very small distance from the ray's origin, much smaller than the correct one.
I did several tests:
I printed the vertices positions which are correct (in world space)
the ray is aslo in worldspace
in the getMeshInformation call I used _getDerived* functions

I also printed the hit.second value for each hit, along with the ray.getOrigin().distance(vertices[indices]) (the first vertex in the triangle hit).
The value for hit.second (the value returned by the raycast method) was always approximately 400 times small than the distance of the ray's origin with the 1st vertex.

Do u have any idea why this could be happening?

Re: MOC - Minimal Ogre Collision 1.0 - [Update 03.May.2009]

Posted: Tue May 12, 2009 4:43 pm
by Nauk
No actually I haven't - so if I understand you right, you do get the correct entity as result, but the distance is wrong?

Re: MOC - Minimal Ogre Collision 1.0 - [Update 03.May.2009]

Posted: Fri May 15, 2009 11:37 am
by adanar
Yes. that's right.

I would think it is my mistake but as I told you, the strange thing is that on the raycast function I also calculate the distance of the ray origin to the first vertex of the 3 vertices used in the intersects method just before and THAT distance is correct (and approx. always 400 times large)

Re: MOC - Minimal Ogre Collision 1.0 - [Update 03.May.2009]

Posted: Sat May 16, 2009 2:38 pm
by deadvirus
I needed a way to find out the normal of the intersected plane, so I implemented it.
Here it is (just some minor changes on the raycast method). I sugest to keep the other raycast method, so that It doesn't need to waste time finding the normal, when you will not use it.

Code: Select all

bool CollisionTools::raycast(const Ogre::Ray &ray, Ogre::Vector3 &result, Ogre::MovableObject* &target,float &closest_distance,  Ogre::Vector3 &normal, const Ogre::uint32 queryMask)
{
	target = NULL;

    // check we are initialised
    if (mRaySceneQuery != NULL)
    {
        // create a query object
        mRaySceneQuery->setRay(ray);
		mRaySceneQuery->setSortByDistance(true);
		mRaySceneQuery->setQueryMask(queryMask);
        // execute the query, returns a vector of hits
        if (mRaySceneQuery->execute().size() <= 0)
        {
            // raycast did not hit an objects bounding box
            return (false);
        }
    }
    else
    {
        //LOG_ERROR << "Cannot raycast without RaySceneQuery instance" << ENDLOG;
        return (false);
    }

    // at this point we have raycast to a series of different objects bounding boxes.
    // we need to test these different objects to see which is the first polygon hit.
    // there are some minor optimizations (distance based) that mean we wont have to
    // check all of the objects most of the time, but the worst case scenario is that
    // we need to test every triangle of every object.
    //Ogre::Ogre::Real closest_distance = -1.0f;
	closest_distance = -1.0f;
    Ogre::Vector3 closest_result;
    Ogre::RaySceneQueryResult &query_result = mRaySceneQuery->getLastResults();
    for (size_t qr_idx = 0; qr_idx < query_result.size(); qr_idx++)
    {
        // stop checking if we have found a raycast hit that is closer
        // than all remaining entities
        if ((closest_distance >= 0.0f) &&
            (closest_distance < query_result[qr_idx].distance))
        {
            break;
        }

        // only check this result if its a hit against an entity
        if ((query_result[qr_idx].movable != NULL)  &&
            (query_result[qr_idx].movable->getMovableType().compare("Entity") == 0))
        {
            // get the entity to check
			Ogre::MovableObject *pentity = static_cast<Ogre::MovableObject*>(query_result[qr_idx].movable);

			Ogre::Vector3 pnormal;
            // mesh data to retrieve
            size_t vertex_count;
            size_t index_count;
            Ogre::Vector3 *vertices;
            Ogre::uint32 *indices;

            // get the mesh information
			GetMeshInformation(((Ogre::Entity*)pentity)->getMesh(), vertex_count, vertices, index_count, indices,
                              pentity->getParentNode()->_getDerivedPosition(),
                              pentity->getParentNode()->_getDerivedOrientation(),
                              pentity->getParentNode()->_getDerivedScale());

            // test for hitting individual triangles on the mesh
            bool new_closest_found = false;
            for (size_t i = 0; i < index_count; i += 3)
            {
                // check for a hit against this triangle
                std::pair<bool, Ogre::Real> hit = Ogre::Math::intersects(ray, vertices[indices[i]],
                    vertices[indices[i+1]], vertices[indices[i+2]], true, false);

                // if it was a hit check if its the closest
                if (hit.first)
                {
                    if ((closest_distance < 0.0f) ||
                        (hit.second < closest_distance))
                    {
                        // this is the closest so far, save it off
                        closest_distance = hit.second;
                        new_closest_found = true;

						//calculate normal
						Ogre::Vector3 vec1OnPlane = vertices[indices[i]] - vertices[indices[i+1]];
						Ogre::Vector3 vec2OnPlane = vertices[indices[i]] - vertices[indices[i+2]];
							
						pnormal = vec1OnPlane.crossProduct(vec2OnPlane);
                    }
                }
            }

			// free the verticies and indicies memory
            delete[] vertices;
            delete[] indices;

            // if we found a new closest raycast for this object, update the
            // closest_result before moving on to the next object.
            if (new_closest_found)
            {
				target = pentity;
                closest_result = ray.getPoint(closest_distance);
				normal = pnormal.normalisedCopy();
            }
        }
    }

    // return the result
    if (closest_distance >= 0.0f)
    {
        // raycast success
		result = closest_result;
        return (true);
    }
    else
    {
        // raycast failed
        return (false);
    }
}
Hope it helps someone!

Re: MOC - Minimal Ogre Collision 1.0 - [Update 03.May.2009]

Posted: Sat May 16, 2009 11:03 pm
by Nauk
Good work deadvirus and thanks for sharing, I like it and will add it. :)

Re: MOC - Minimal Ogre Collision 1.0 - [Update 03.May.2009]

Posted: Sun May 17, 2009 12:40 am
by deadvirus
Nauk wrote:Good work deadvirus and thanks for sharing, I like it and will add it. :)
No problem! I am the one who has to say thanks for MOC :D

Re: MOC - Minimal Ogre Collision 1.0 - [Update 03.May.2009]

Posted: Sun May 17, 2009 6:17 pm
by crosswind
Hi guys,

New to ogre and MOC but I am working on my ogre project but met with 2 errors while compiling my code. I incoporated the MOC source code i downloaded with my own ogre project. Anyone can help? Error and cpp file shown below......If you guys need more info, please PM or contact me...thanks

error C2872: 'ulong' : ambiguous symbol

error C2664: 'bool MOC::CollisionTools::raycastFromCamera(Ogre::RenderWindow *,Ogre::Camera *,const Ogre::Vector2 &,Ogre::Vector3 &,Ogre::MovableObject *&,float &,const Ogre::uint32)' : cannot convert parameter 3 from 'const OIS::MouseEvent' to 'const Ogre::Vector2 &'

Code: Select all

#include "Gui.h"

Gui::Gui() :
	root(),
	sceneMgr(0),
	window(0),
	GuiSystem(0),
	ois(0),
	mouse(0), 
	exitgame(false)
{
	//mLastTime = mTimer.getMilliseconds();	
	//
	//mTimer1 = 0.0;
	//mCollision = true;
}

Gui::~Gui()
{
	delete root; 
	delete GuiSystem;
	//delete mCollisionTools;
}

bool Gui::Start()
{
	if (!InitOgre())
		return false;

	if (!InitOIS())
		return false;

	movement = 0;
	yaw = 0;
	while(!exitgame) 
	{ 
		WindowEventUtilities::messagePump(); 
		mouse->capture();
		keyboard->capture();
		root->renderOneFrame();  
		mShipNode->translate(Ogre::Vector3(0,0,movement),Ogre::SceneNode::TS_LOCAL);
		mShipNode->yaw(Degree( yaw ) );

	}

}

bool Gui::InitOgre()
{
	root = new Root; 
	root->loadPlugin("RenderSystem_GL_d"); 

	RenderSystemList *rs = root->getAvailableRenderers(); 
	if(rs&&rs->size()&&rs->at(0)->getName().compare("RenderSystem_GL"))
	{ 
		RenderSystem * r=rs->at(0); 
		root->setRenderSystem(r); 

		r->setConfigOption("Full Screen","No");  
		r->setConfigOption("Video Mode","800 x 600 @ 16-bit colour"); 
	}

	else
	{ 
		return false;
	}

	ResourceGroupManager &resources=ResourceGroupManager::getSingleton(); 
	resources.addResourceLocation("data","FileSystem"); 
	//resources.addResourceLocation("resource","FileSystem");
	resources.initialiseAllResourceGroups(); 

	window = root->initialise(true, "Simple Ogre App");
	sceneMgr = root->createSceneManager(ST_GENERIC); 
	//////added code//////////////////////////////////////////////////////
	Ogre::WindowEventUtilities::addWindowEventListener(window, this);
	// init the collision handler
	mCollisionTools = new CollisionTools(sceneMgr);
	/////////////////////////////added code///////////////////////////////
	//Create our entity
	sceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_ADDITIVE);

	mShip = sceneMgr->createEntity("ship", "tiger0.mesh");
	mShip->setCastShadows(true);
	mShipNode = sceneMgr->getRootSceneNode()->createChildSceneNode();
	mShipNode->attachObject(mShip);
	mShipNode->setPosition(Ogre::Vector3(0,-100,0));

	mFuel = sceneMgr->createEntity("fuel", "Box16.mesh");
	mFuel->setCastShadows(true);
	mFuel->setQueryFlags(ENTITY_MASK);
	mFuelNode = sceneMgr->getRootSceneNode()->createChildSceneNode();
	mFuelNode->attachObject(mFuel);
	mFuelNode->setPosition(Ogre::Vector3(0,-100,0));

	mCube = sceneMgr->createEntity("cube", "pCube1.mesh");
	mCubeNode = sceneMgr->getRootSceneNode()->createChildSceneNode(Ogre::Vector3(0,400,0));
	mCubeNode->attachObject(mCube);
	mCubeNode->scale( 100000,10000,100000 );

	cam = sceneMgr->createCamera("SimpleCamera"); 
	cam->setPosition(Ogre::Vector3(0.0f,50.0f,-400.0f)); 
	cam->lookAt(Ogre::Vector3(0.0f,0.0f,0.0f)); 
	cam->setNearClipDistance(5.0f); 
	cam->setFarClipDistance(5000.0f); 
	mShipNode->attachObject(cam);


	Viewport* v = window->addViewport(cam); 
	v->setBackgroundColour(ColourValue(0,0,0)); 

	cam->setAspectRatio(Real(v->getActualWidth())/v->getActualHeight()); 


	sceneMgr->setAmbientLight( ColourValue( 0, 0, 0 ) );
	
	light = sceneMgr->createLight("Light1");
	light->setType(Light::LT_POINT);
	light->setPosition(Ogre::Vector3(0, 100, 0));
	light->setDiffuseColour(1.0, 1.0, 1.0);
	light->setSpecularColour(1.0, 1.0, 1.0);

	light = sceneMgr->createLight("Light3");
	light->setType(Light::LT_DIRECTIONAL);
	light->setDiffuseColour(ColourValue(1, 1, 1));
	light->setSpecularColour(ColourValue(1, 1, 1));
	light->setDirection(Ogre::Vector3( 0, -1, 1 ));

	light = sceneMgr->createLight("Light2");
	light->setType(Light::LT_SPOTLIGHT);
	light->setDiffuseColour(1.0, 1.0, 1.0);
	light->setSpecularColour(1.0, 1.0, 1.0);
	light->setDirection(-1, -1, 0);
	light->setPosition(Ogre::Vector3(300, 300, 0));
	light->setSpotlightRange(Degree(35), Degree(50));


}
void Gui::Update() 
{
	float getHeightAt(float x, float z);
	Root::getSingleton().renderOneFrame();
	keyboard->capture();
	mouse->capture();

	Ogre::WindowEventUtilities::messagePump();
	
	// take time since last loop to adapt movement to system speed
	const float timeFactor = ((float)(mTimer.getMilliseconds()-mLastTime)/1000);

	mTimer1 -= timeFactor;

	// commit the camera movement (if moving and not colliding with any entity)
	if (mDirection != Ogre::Vector3::ZERO)
	{
		// save last position
		Ogre::Vector3 oldPos = mShipNode->getPosition();
		
		// commit move
		mShipNode->translate(cam->getOrientation() * mDirection * (mMoveSpeed * timeFactor));
		
		// collision on?		
		if (mCollision) {
		
			// calculate the new Y position: check vs. terrain & all objects flagged with ENTITY_MASK
			// multiple masks possible like e.g. ENTITY_MASK|MY_MASK|ETC_MASK
			// doGridCheck casts a 2nd ray, gridWidth=2.0f ogre units away from the exact camera position to 
			// avoid falling through small wholes or gaps in hangbridges for example.
			mCollisionTools->calculateY(mShipNode,true,true,2.0f,ENTITY_MASK );
			
			// check if we are colliding with anything with a collision radius of 2.5 ogre units and we 
			// set the ray origin -1.0 lower towards the ground to get smaller obstacles too
			if (mCollisionTools->collidesWithEntity(oldPos, mShipNode->getPosition(), 2.5f, -100.0f,ENTITY_MASK ))
			{
				// undo move
				mShipNode->setPosition(oldPos);
			}
		} 
		//else 
		//{
		//	// collision off -> get terrain height
		//	Ogre::Vector3 pos = mShipNode->getPosition();
		//	float y =  mShip->getHeightAt(pos.x, pos.z);
		//	mShipNode->setPosition(pos.x,y+4.5f, pos.z);
		//}
	}

	// commit the camera rotation (if rotating)
	if (mRotation != 0.0f)
	{
		mShipNode->yaw( Degree(mRotation * mRotateSpeed* 50 *timeFactor) );
		mShipNode->pitch( Degree(-mPitch * mRotateSpeed* 50 *timeFactor) );

		// normalise the camera orientation to avoid distortion of the perspective
		Quaternion q = mShipNode->getOrientation();
		q.normalise();
		mShipNode->setOrientation(q);
	}

	mLastTime = mTimer.getMilliseconds();		
    
};

void Gui::pickEntity(const OIS::MouseEvent &arg, const Ogre::uint32 queryMask)
{
	Entity *mFuel= NULL;
	Ogre::Vector3 result = Ogre::Vector3::ZERO;
	float distToColl;


	if (mCollisionTools->raycastFromCamera(window, cam, arg, result, (ulong&)mShip, distToColl, queryMask))
	{
		SceneNode* mFuelNode = mFuel->getParentSceneNode();
		if (mFuelNode->getShowBoundingBox()) 
		{
			mFuelNode->showBoundingBox(false);
		} 
		else 
		{
			mFuelNode->showBoundingBox(true);
		}
	}


}


bool Gui::onPushButtonClicked(const CEGUI::EventArgs &e)
{
	exit(1);
}


bool Gui::InitOIS()
{
	HWND hwnd = GetActiveWindow();
	OIS::ParamList pl;

	std::ostringstream oss;
	oss << (long)hwnd;
	pl.insert(std::make_pair(std::string("WINDOW"), oss.str()));
	pl.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_FOREGROUND" )));
	pl.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_EXCLUSIVE")));
	pl.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_BACKGROUND" )));
	pl.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_NONEXCLUSIVE")));
	ois = OIS::InputManager::createInputSystem(pl);

	mouse = static_cast<OIS::Mouse*>(ois->createInputObject( OIS::OISMouse, true ));
	const OIS::MouseState &ms = mouse->getMouseState();
	mouse->setEventCallback(this);

	keyboard = static_cast<OIS::Keyboard*>(ois->createInputObject(OIS::OISKeyboard, true));
	
	keyboard->setEventCallback(this);

	ms.width = 800;
	ms.height = 600;

	return true;
}

bool Gui::keyPressed( const KeyEvent &arg )
{
	switch(arg.key)
	{
	case OIS::KC_ESCAPE:
		exit(1);
		break;
	case OIS::KC_DOWN:
		movement = -50;
		break;
	case OIS::KC_UP:
		movement = 50;
		break;
	case OIS::KC_LEFT:
		yaw = 1;
		break;
	case OIS::KC_RIGHT:
		yaw = -1;
		break;
	}

	/*if(keyboard->isKeyDown(OIS::KC_ESCAPE))
	{
		exit(1);
	}
	if(keyboard->isKeyDown(OIS::KC_UP))
	{
		movement = 100;		
	}

	if(keyboard->isKeyDown(OIS::KC_DOWN))
	{
		mShipNode->translate(Ogre::Vector3(0,0,-100));
	}*/

	return true;
}

bool Gui::keyReleased( const KeyEvent &arg )
{
	switch(arg.key)
	{
	case OIS::KC_DOWN:
		movement = 0;
		break;
	case OIS::KC_UP:
		movement = 0;
		break;
	case OIS::KC_LEFT:
		yaw = 0;
		break;
	case OIS::KC_RIGHT:
		yaw = 0;
		break;
	}
	
	return true;
}

bool Gui::mouseMoved( const OIS::MouseEvent &arg )
{

	return true;
}

bool Gui::mousePressed( const OIS::MouseEvent &arg, OIS::MouseButtonID id )
{
	return true;
}

bool Gui::mouseReleased( const OIS::MouseEvent &arg, OIS::MouseButtonID id )
{
	return true;
}

CEGUI::MouseButton Gui::MapMouseButton(OIS::MouseButtonID button)
{
	switch (button)
	{
	case OIS::MB_Left:
		return CEGUI::LeftButton;
		
	case OIS::MB_Right:
		return CEGUI::RightButton;
	}

	return CEGUI::LeftButton;
}



Re: MOC - Minimal Ogre Collision 1.0 - [Update 03.May.2009]

Posted: Sun May 17, 2009 6:28 pm
by deadvirus
crosswind wrote:Hi guys,

New to ogre and MOC but I am working on my ogre project but met with 2 errors while compiling my code. I incoporated the MOC source code i downloaded with my own ogre project. Anyone can help? Error and cpp file shown below......If you guys need more info, please PM or contact me...thanks

error C2872: 'ulong' : ambiguous symbol

error C2664: 'bool MOC::CollisionTools::raycastFromCamera(Ogre::RenderWindow *,Ogre::Camera *,const Ogre::Vector2 &,Ogre::Vector3 &,Ogre::MovableObject *&,float &,const Ogre::uint32)' : cannot convert parameter 3 from 'const OIS::MouseEvent' to 'const Ogre::Vector2 &'

Code: Select all

#include "Gui.h"

Gui::Gui() :
	root(),
	sceneMgr(0),
	window(0),
	GuiSystem(0),
	ois(0),
	mouse(0), 
	exitgame(false)
{
	//mLastTime = mTimer.getMilliseconds();	
	//
	//mTimer1 = 0.0;
	//mCollision = true;
}

Gui::~Gui()
{
	delete root; 
	delete GuiSystem;
	//delete mCollisionTools;
}

bool Gui::Start()
{
	if (!InitOgre())
		return false;

	if (!InitOIS())
		return false;

	movement = 0;
	yaw = 0;
	while(!exitgame) 
	{ 
		WindowEventUtilities::messagePump(); 
		mouse->capture();
		keyboard->capture();
		root->renderOneFrame();  
		mShipNode->translate(Ogre::Vector3(0,0,movement),Ogre::SceneNode::TS_LOCAL);
		mShipNode->yaw(Degree( yaw ) );

	}

}

bool Gui::InitOgre()
{
	root = new Root; 
	root->loadPlugin("RenderSystem_GL_d"); 

	RenderSystemList *rs = root->getAvailableRenderers(); 
	if(rs&&rs->size()&&rs->at(0)->getName().compare("RenderSystem_GL"))
	{ 
		RenderSystem * r=rs->at(0); 
		root->setRenderSystem(r); 

		r->setConfigOption("Full Screen","No");  
		r->setConfigOption("Video Mode","800 x 600 @ 16-bit colour"); 
	}

	else
	{ 
		return false;
	}

	ResourceGroupManager &resources=ResourceGroupManager::getSingleton(); 
	resources.addResourceLocation("data","FileSystem"); 
	//resources.addResourceLocation("resource","FileSystem");
	resources.initialiseAllResourceGroups(); 

	window = root->initialise(true, "Simple Ogre App");
	sceneMgr = root->createSceneManager(ST_GENERIC); 
	//////added code//////////////////////////////////////////////////////
	Ogre::WindowEventUtilities::addWindowEventListener(window, this);
	// init the collision handler
	mCollisionTools = new CollisionTools(sceneMgr);
	/////////////////////////////added code///////////////////////////////
	//Create our entity
	sceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_ADDITIVE);

	mShip = sceneMgr->createEntity("ship", "tiger0.mesh");
	mShip->setCastShadows(true);
	mShipNode = sceneMgr->getRootSceneNode()->createChildSceneNode();
	mShipNode->attachObject(mShip);
	mShipNode->setPosition(Ogre::Vector3(0,-100,0));

	mFuel = sceneMgr->createEntity("fuel", "Box16.mesh");
	mFuel->setCastShadows(true);
	mFuel->setQueryFlags(ENTITY_MASK);
	mFuelNode = sceneMgr->getRootSceneNode()->createChildSceneNode();
	mFuelNode->attachObject(mFuel);
	mFuelNode->setPosition(Ogre::Vector3(0,-100,0));

	mCube = sceneMgr->createEntity("cube", "pCube1.mesh");
	mCubeNode = sceneMgr->getRootSceneNode()->createChildSceneNode(Ogre::Vector3(0,400,0));
	mCubeNode->attachObject(mCube);
	mCubeNode->scale( 100000,10000,100000 );

	cam = sceneMgr->createCamera("SimpleCamera"); 
	cam->setPosition(Ogre::Vector3(0.0f,50.0f,-400.0f)); 
	cam->lookAt(Ogre::Vector3(0.0f,0.0f,0.0f)); 
	cam->setNearClipDistance(5.0f); 
	cam->setFarClipDistance(5000.0f); 
	mShipNode->attachObject(cam);


	Viewport* v = window->addViewport(cam); 
	v->setBackgroundColour(ColourValue(0,0,0)); 

	cam->setAspectRatio(Real(v->getActualWidth())/v->getActualHeight()); 


	sceneMgr->setAmbientLight( ColourValue( 0, 0, 0 ) );
	
	light = sceneMgr->createLight("Light1");
	light->setType(Light::LT_POINT);
	light->setPosition(Ogre::Vector3(0, 100, 0));
	light->setDiffuseColour(1.0, 1.0, 1.0);
	light->setSpecularColour(1.0, 1.0, 1.0);

	light = sceneMgr->createLight("Light3");
	light->setType(Light::LT_DIRECTIONAL);
	light->setDiffuseColour(ColourValue(1, 1, 1));
	light->setSpecularColour(ColourValue(1, 1, 1));
	light->setDirection(Ogre::Vector3( 0, -1, 1 ));

	light = sceneMgr->createLight("Light2");
	light->setType(Light::LT_SPOTLIGHT);
	light->setDiffuseColour(1.0, 1.0, 1.0);
	light->setSpecularColour(1.0, 1.0, 1.0);
	light->setDirection(-1, -1, 0);
	light->setPosition(Ogre::Vector3(300, 300, 0));
	light->setSpotlightRange(Degree(35), Degree(50));


}
void Gui::Update() 
{
	float getHeightAt(float x, float z);
	Root::getSingleton().renderOneFrame();
	keyboard->capture();
	mouse->capture();

	Ogre::WindowEventUtilities::messagePump();
	
	// take time since last loop to adapt movement to system speed
	const float timeFactor = ((float)(mTimer.getMilliseconds()-mLastTime)/1000);

	mTimer1 -= timeFactor;

	// commit the camera movement (if moving and not colliding with any entity)
	if (mDirection != Ogre::Vector3::ZERO)
	{
		// save last position
		Ogre::Vector3 oldPos = mShipNode->getPosition();
		
		// commit move
		mShipNode->translate(cam->getOrientation() * mDirection * (mMoveSpeed * timeFactor));
		
		// collision on?		
		if (mCollision) {
		
			// calculate the new Y position: check vs. terrain & all objects flagged with ENTITY_MASK
			// multiple masks possible like e.g. ENTITY_MASK|MY_MASK|ETC_MASK
			// doGridCheck casts a 2nd ray, gridWidth=2.0f ogre units away from the exact camera position to 
			// avoid falling through small wholes or gaps in hangbridges for example.
			mCollisionTools->calculateY(mShipNode,true,true,2.0f,ENTITY_MASK );
			
			// check if we are colliding with anything with a collision radius of 2.5 ogre units and we 
			// set the ray origin -1.0 lower towards the ground to get smaller obstacles too
			if (mCollisionTools->collidesWithEntity(oldPos, mShipNode->getPosition(), 2.5f, -100.0f,ENTITY_MASK ))
			{
				// undo move
				mShipNode->setPosition(oldPos);
			}
		} 
		//else 
		//{
		//	// collision off -> get terrain height
		//	Ogre::Vector3 pos = mShipNode->getPosition();
		//	float y =  mShip->getHeightAt(pos.x, pos.z);
		//	mShipNode->setPosition(pos.x,y+4.5f, pos.z);
		//}
	}

	// commit the camera rotation (if rotating)
	if (mRotation != 0.0f)
	{
		mShipNode->yaw( Degree(mRotation * mRotateSpeed* 50 *timeFactor) );
		mShipNode->pitch( Degree(-mPitch * mRotateSpeed* 50 *timeFactor) );

		// normalise the camera orientation to avoid distortion of the perspective
		Quaternion q = mShipNode->getOrientation();
		q.normalise();
		mShipNode->setOrientation(q);
	}

	mLastTime = mTimer.getMilliseconds();		
    
};

void Gui::pickEntity(const OIS::MouseEvent &arg, const Ogre::uint32 queryMask)
{
	Entity *mFuel= NULL;
	Ogre::Vector3 result = Ogre::Vector3::ZERO;
	float distToColl;


	if (mCollisionTools->raycastFromCamera(window, cam, arg, result, (ulong&)mShip, distToColl, queryMask))
	{
		SceneNode* mFuelNode = mFuel->getParentSceneNode();
		if (mFuelNode->getShowBoundingBox()) 
		{
			mFuelNode->showBoundingBox(false);
		} 
		else 
		{
			mFuelNode->showBoundingBox(true);
		}
	}


}


bool Gui::onPushButtonClicked(const CEGUI::EventArgs &e)
{
	exit(1);
}


bool Gui::InitOIS()
{
	HWND hwnd = GetActiveWindow();
	OIS::ParamList pl;

	std::ostringstream oss;
	oss << (long)hwnd;
	pl.insert(std::make_pair(std::string("WINDOW"), oss.str()));
	pl.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_FOREGROUND" )));
	pl.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_EXCLUSIVE")));
	pl.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_BACKGROUND" )));
	pl.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_NONEXCLUSIVE")));
	ois = OIS::InputManager::createInputSystem(pl);

	mouse = static_cast<OIS::Mouse*>(ois->createInputObject( OIS::OISMouse, true ));
	const OIS::MouseState &ms = mouse->getMouseState();
	mouse->setEventCallback(this);

	keyboard = static_cast<OIS::Keyboard*>(ois->createInputObject(OIS::OISKeyboard, true));
	
	keyboard->setEventCallback(this);

	ms.width = 800;
	ms.height = 600;

	return true;
}

bool Gui::keyPressed( const KeyEvent &arg )
{
	switch(arg.key)
	{
	case OIS::KC_ESCAPE:
		exit(1);
		break;
	case OIS::KC_DOWN:
		movement = -50;
		break;
	case OIS::KC_UP:
		movement = 50;
		break;
	case OIS::KC_LEFT:
		yaw = 1;
		break;
	case OIS::KC_RIGHT:
		yaw = -1;
		break;
	}

	/*if(keyboard->isKeyDown(OIS::KC_ESCAPE))
	{
		exit(1);
	}
	if(keyboard->isKeyDown(OIS::KC_UP))
	{
		movement = 100;		
	}

	if(keyboard->isKeyDown(OIS::KC_DOWN))
	{
		mShipNode->translate(Ogre::Vector3(0,0,-100));
	}*/

	return true;
}

bool Gui::keyReleased( const KeyEvent &arg )
{
	switch(arg.key)
	{
	case OIS::KC_DOWN:
		movement = 0;
		break;
	case OIS::KC_UP:
		movement = 0;
		break;
	case OIS::KC_LEFT:
		yaw = 0;
		break;
	case OIS::KC_RIGHT:
		yaw = 0;
		break;
	}
	
	return true;
}

bool Gui::mouseMoved( const OIS::MouseEvent &arg )
{

	return true;
}

bool Gui::mousePressed( const OIS::MouseEvent &arg, OIS::MouseButtonID id )
{
	return true;
}

bool Gui::mouseReleased( const OIS::MouseEvent &arg, OIS::MouseButtonID id )
{
	return true;
}

CEGUI::MouseButton Gui::MapMouseButton(OIS::MouseButtonID button)
{
	switch (button)
	{
	case OIS::MB_Left:
		return CEGUI::LeftButton;
		
	case OIS::MB_Right:
		return CEGUI::RightButton;
	}

	return CEGUI::LeftButton;
}


For the first error, try doing "Ogre::ulong" instead of just "ulong".
For the second error, you should get mouse position to a Ogre::Vector3, and then pass that Vector3 instead of passing the OIS::MouseEvent.

Re: MOC - Minimal Ogre Collision 1.0 - [Update 03.May.2009]

Posted: Sun May 17, 2009 6:30 pm
by crosswind
thanks deadvirus....that was fast....let me go try now.

Re: MOC - Minimal Ogre Collision 1.0 - [Update 03.May.2009]

Posted: Sun May 17, 2009 6:50 pm
by crosswind
For the 2nd pt....dnt quite get you....care to elaborate? and my bad...i am using the keyboard atm instead of the mouse

Re: MOC - Minimal Ogre Collision 1.0 - [Update 03.May.2009]

Posted: Sun May 17, 2009 6:53 pm
by jacmoe
What's in an OIS::arg? You need a Ogre::Vector2..
I think you'll find the answer in the MOC demo.

Re: MOC - Minimal Ogre Collision 1.0 - [Update 03.May.2009]

Posted: Sun May 17, 2009 6:56 pm
by crosswind
Hi Jacmoe,

i took the collisiontools.h and .cpp and then put into my Ogre project and edited it....yap i d/l the source code bt been staring at it for hours

Re: MOC - Minimal Ogre Collision 1.0 - [Update 03.May.2009]

Posted: Sun May 17, 2009 6:57 pm
by deadvirus
Something like:

Code: Select all

Ogre::Vector3 mousepos;
mousepos.x = arg.state.X.rel;
mousepos.y = arg.state.Y.rel;

if(mCollisionTools->raycastFromCamera(window, cam, mousepos, result, (Ogre::ulong&)mShip, distToColl, queryMask))
.....
I think that'll work...

Re: MOC - Minimal Ogre Collision 1.0 - [Update 03.May.2009]

Posted: Sun May 17, 2009 7:00 pm
by crosswind
thanks guys or the help....will try it out immediately now....=)

Re: MOC - Minimal Ogre Collision 1.0 - [Update 03.May.2009]

Posted: Sun May 17, 2009 7:11 pm
by jacmoe
Except that mousepos should be Ogre::Vector2. :wink:

Re: MOC - Minimal Ogre Collision 1.0 - [Update 03.May.2009]

Posted: Sun May 17, 2009 7:11 pm
by deadvirus
Oh, by the way, if you're using the last MOC version, you don't need to cast mShip to ulong (you can't).
jacmoe wrote:Except that mousepos should be Ogre::Vector2. :wink:
Yes! Right :)

HELP

Posted: Wed May 20, 2009 7:38 pm
by crosswind
Having tis break in my code when it compiles....Trying to implement the collision code bt breaks at the update area:
const float timeFactor = ((float)(mTimer.getMilliseconds()-mLastTime)/1000);

Call stack at the bottom

Code: Select all

#include "Gui.h"
#include <OgreVector2.h> 

using namespace Ogre;

Gui::Gui() :
	root(),
	sceneMgr(0),
	window(0),
	GuiSystem(0),
	ois(0),
	mouse(0), 
	exitgame(false)
{
	mLMouseDown = mMMouseDown = mRMouseDown = false;
	mLastTime = mTimer.getMilliseconds();	
	mTimer1 = 0.0;
	mCollision = true;
}

Gui::~Gui()
{
	delete root; 
	delete GuiSystem;
	delete mCollisionTools;
}

bool Gui::Start()
{
	if (!InitOgre())
		return false;

	if (!InitOIS())
		return false;

	movement = 0;
	yaw = 0;
	while(!exitgame) 
	{ 
		WindowEventUtilities::messagePump(); 
		mouse->capture();
		keyboard->capture();
		root->renderOneFrame();  
		mShipNode->translate(Ogre::Vector3(0,0,movement),Ogre::SceneNode::TS_LOCAL);
		mShipNode->yaw(Degree( yaw ) );
		gui->Update();
	}
}

bool Gui::InitOgre()
{
	root = new Root; 
	root->loadPlugin("RenderSystem_GL_d"); 

	RenderSystemList *rs = root->getAvailableRenderers(); 
	if(rs&&rs->size()&&rs->at(0)->getName().compare("RenderSystem_GL"))
	{ 
		RenderSystem * r=rs->at(0); 
		root->setRenderSystem(r); 

		r->setConfigOption("Full Screen","No");  
		r->setConfigOption("Video Mode","800 x 600 @ 16-bit colour"); 
	}

	else
	{ 
		return false;
	}

	ResourceGroupManager &resources=ResourceGroupManager::getSingleton(); 
	resources.addResourceLocation("data","FileSystem"); 
	resources.initialiseAllResourceGroups(); 

	window = root->initialise(true, "Simple Ogre App");
	sceneMgr = root->createSceneManager(ST_GENERIC); 

	//////added code//////////////////////////////////////////////////////
	Ogre::WindowEventUtilities::addWindowEventListener(window, this);

	// init the collision handler
	mCollisionTools = new CollisionTools(sceneMgr);

	
	/////////////////////////////added code///////////////////////////////
	//Create our entity
	sceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_ADDITIVE);

	mShip = sceneMgr->createEntity("ship", "tiger0.mesh");
	mShip->setCastShadows(true);
	mShipNode = sceneMgr->getRootSceneNode()->createChildSceneNode();
	mShipNode->attachObject(mShip);
	mShipNode->setPosition(Ogre::Vector3(0,-100,0));

	mFuel = sceneMgr->createEntity("fuel", "Box16.mesh");
	mFuel->setCastShadows(true);
	mFuel->setQueryFlags(ENTITY_MASK);
	mFuelNode = sceneMgr->getRootSceneNode()->createChildSceneNode();
	mFuelNode->attachObject(mFuel);
	mFuelNode->setPosition(Ogre::Vector3(0,-100,0));

	mCube = sceneMgr->createEntity("cube", "pCube1.mesh");
	mCubeNode = sceneMgr->getRootSceneNode()->createChildSceneNode(Ogre::Vector3(0,400,0));
	mCubeNode->attachObject(mCube);
	mCubeNode->scale( 5000,5000,5000 );

	cam = sceneMgr->createCamera("SimpleCamera"); 
	cam->setPosition(Ogre::Vector3(0.0f,50.0f,-400.0f)); 
	cam->lookAt(Ogre::Vector3(0.0f,0.0f,0.0f)); 
	cam->setNearClipDistance(5.0f); 
	cam->setFarClipDistance(5000.0f); 
	mShipNode->attachObject(cam);


	Viewport* v = window->addViewport(cam); 
	v->setBackgroundColour(ColourValue(0,0,0)); 

	cam->setAspectRatio(Real(v->getActualWidth())/v->getActualHeight()); 


	sceneMgr->setAmbientLight( ColourValue( 0, 0, 0 ) );
	
	light = sceneMgr->createLight("Light1");
	light->setType(Light::LT_POINT);
	light->setPosition(Ogre::Vector3(0, 100, 0));
	light->setDiffuseColour(1.0, 1.0, 1.0);
	light->setSpecularColour(1.0, 1.0, 1.0);

	light = sceneMgr->createLight("Light3");
	light->setType(Light::LT_DIRECTIONAL);
	light->setDiffuseColour(ColourValue(1, 1, 1));
	light->setSpecularColour(ColourValue(1, 1, 1));
	light->setDirection(Ogre::Vector3( 0, -1, 1 ));

	light = sceneMgr->createLight("Light2");
	light->setType(Light::LT_SPOTLIGHT);
	light->setDiffuseColour(1.0, 1.0, 1.0);
	light->setSpecularColour(1.0, 1.0, 1.0);
	light->setDirection(-1, -1, 0);
	light->setPosition(Ogre::Vector3(300, 300, 0));
	light->setSpotlightRange(Degree(35), Degree(50));
}

void Gui::Update() 
{
	float getHeightAt(float x, float z);
	Root::getSingleton().renderOneFrame();

	Ogre::WindowEventUtilities::messagePump();
	
	// take time since last loop to adapt movement to system speed
	const float timeFactor = ((float)(mTimer.getMilliseconds()-mLastTime)/1000);
	mTimer1 -= timeFactor;

	// commit the camera movement (if moving and not colliding with any entity)
	if (mDirection != Ogre::Vector3::ZERO)
	{
		// save last position
		Ogre::Vector3 oldPos = mShipNode->getPosition();
		
		// commit move
		mShipNode->translate(cam->getOrientation() * mDirection * (mMoveSpeed * timeFactor));
		
		// collision on?		
		if (mCollision) 
		{
			// calculate the new Y position: check vs. terrain & all objects flagged with ENTITY_MASK
			// multiple masks possible like e.g. ENTITY_MASK|MY_MASK|ETC_MASK
			// doGridCheck casts a 2nd ray, gridWidth=2.0f ogre units away from the exact camera position to 
			// avoid falling through small wholes or gaps in hangbridges for example.
			mCollisionTools->calculateY(mShipNode,true,true,2.0f,ENTITY_MASK );
			
			// check if we are colliding with anything with a collision radius of 2.5 ogre units and we 
			// set the ray origin -1.0 lower towards the ground to get smaller obstacles too
			if (mCollisionTools->collidesWithEntity(oldPos, mShipNode->getPosition(), 2.5f, -100.0f,ENTITY_MASK ))
			{
				// undo move
				mShipNode->setPosition(oldPos);
			}
		} 

	}

	// commit the camera rotation (if rotating)
	if (mRotation != 0.0f)
	{
		mShipNode->yaw( Degree(mRotation * mRotateSpeed* 50 *timeFactor) );
		mShipNode->pitch( Degree(-mPitch * mRotateSpeed* 50 *timeFactor) );

		// normalise the camera orientation to avoid distortion of the perspective
		Quaternion q = mShipNode->getOrientation();
		q.normalise();
		mShipNode->setOrientation(q);
	}
	mLastTime = mTimer.getMilliseconds();		
    
};

void Gui::pickEntity(const OIS::MouseEvent &arg, const Ogre::uint32 queryMask)
{
	Entity *tmpE = NULL;
	Ogre::Vector3 result = Ogre::Vector3::ZERO;
	float distToColl;

	mousepos.x = arg.state.X.rel;
	mousepos.y = arg.state.Y.rel;

	if (mCollisionTools->raycastFromCamera(window, cam, mousepos, result, mFuel, distToColl, queryMask))
	{
		SceneNode* mFuelNode= mFuel->getParentSceneNode();
		if (mFuelNode->getShowBoundingBox()) 
		{
			mFuelNode->showBoundingBox(false);
		} 
		else 
		{
			mFuelNode->showBoundingBox(true);
		}
	}

}

bool Gui::onPushButtonClicked(const CEGUI::EventArgs &e)
{
	exit(1);
}


bool Gui::InitOIS()
{
	HWND hwnd = GetActiveWindow();
	OIS::ParamList pl;

	std::ostringstream oss;
	oss << (long)hwnd;
	pl.insert(std::make_pair(std::string("WINDOW"), oss.str()));
	pl.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_FOREGROUND" )));
	pl.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_EXCLUSIVE")));
	pl.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_BACKGROUND" )));
	pl.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_NONEXCLUSIVE")));
	ois = OIS::InputManager::createInputSystem(pl);

	mouse = static_cast<OIS::Mouse*>(ois->createInputObject( OIS::OISMouse, true ));
	const OIS::MouseState &ms = mouse->getMouseState();
	mouse->setEventCallback(this);

	keyboard = static_cast<OIS::Keyboard*>(ois->createInputObject(OIS::OISKeyboard, true));
	
	keyboard->setEventCallback(this);

	ms.width = 800;
	ms.height = 600;

	return true;
}

bool Gui::keyPressed( const KeyEvent &arg )
{
	switch(arg.key)
	{
	case OIS::KC_ESCAPE:
		exit(1);
		break;
	case OIS::KC_DOWN:
		movement = -50;
		break;
	case OIS::KC_UP:
		movement = 50;
		break;
	case OIS::KC_LEFT:
		yaw = 1;
		break;
	case OIS::KC_RIGHT:
		yaw = -1;
		break;
	}

	/*if(keyboard->isKeyDown(OIS::KC_ESCAPE))
	{
		exit(1);
	}
	if(keyboard->isKeyDown(OIS::KC_UP))
	{
		movement = 100;		
	}

	if(keyboard->isKeyDown(OIS::KC_DOWN))
	{
		mShipNode->translate(Ogre::Vector3(0,0,-100));
	}*/

	return true;
}

bool Gui::keyReleased( const KeyEvent &arg )
{
	switch(arg.key)
	{
	case OIS::KC_DOWN:
		movement = 0;
		break;
	case OIS::KC_UP:
		movement = 0;
		break;
	case OIS::KC_LEFT:
		yaw = 0;
		break;
	case OIS::KC_RIGHT:
		yaw = 0;
		break;
	}
	
	return true;
}

bool Gui::mouseMoved( const OIS::MouseEvent &arg )
{
	return true;
}

bool Gui::mousePressed( const OIS::MouseEvent &arg, OIS::MouseButtonID id )
{
	if ( id == OIS::MB_Left )
	{
		mLMouseDown = true;
		pickEntity(arg, ENTITY_MASK);
	}
	else if ( id == OIS::MB_Middle )
	{
		mMMouseDown = true;
	}
	else if (id == OIS::MB_Right)
	{		
		mRMouseDown = true;		  
	}
	
	return true;
}

bool Gui::mouseReleased( const OIS::MouseEvent &arg, OIS::MouseButtonID id )
{	
	if ( id == OIS::MB_Left )
	{
		mLMouseDown = false;
	}
	else if ( id == OIS::MB_Middle )
	{
		mMMouseDown = false;
	}
	else if (id == OIS::MB_Right)
	{		
		mRMouseDown = false;		  
	}
	
	return true;
}

CEGUI::MouseButton Gui::MapMouseButton(OIS::MouseButtonID button)
{
	switch (button)
	{
	case OIS::MB_Left:
		return CEGUI::LeftButton;
		
	case OIS::MB_Right:
		return CEGUI::RightButton;
	}

	return CEGUI::LeftButton;
}

Image

Re: MOC - Minimal Ogre Collision 1.0 - [Update 03.May.2009]

Posted: Sat Jun 13, 2009 10:31 am
by tdev
i found some way to get StaticGeometry working, but its horribly slow (see attached sources)

EDIT: found the reason why its slow, *improving*
EDIT2: attached col2.zip is slightly faster, but still too slow to be usable :/

the collision with static geometry seems to work well, but the FPS drops from 120 normal to 20 when moving for me :(
any ideas how to speed this up? maybe store the mesh information once retrieved?

EDIT3: performance problems solved :D
the attached col3.zip caches the retrieved mesh information of static geometry, thus the FPS drop is only 1-5 FPS at ~120 :D

Re: MOC - Minimal Ogre Collision 1.0 - [Update 03.May.2009]

Posted: Sat Jun 13, 2009 3:46 pm
by Nauk
Nice work tdev :) going to include that in the next update.

Re: MOC - Minimal Ogre Collision 1.0 - [Update 03.May.2009]

Posted: Sun Jun 14, 2009 8:02 am
by compvis
Hi,

How can i track a collision event ? My goal is:
I have a missile and a bullet. After shooting the bullet to the missile, if the bullet hits the missile then how can i handle that event. I will use this event to call a function that plays a particle effect (explosion).

if i can do ?

Re: MOC - Minimal Ogre Collision 1.0 - [Update 03.May.2009]

Posted: Sun Jun 14, 2009 12:28 pm
by tdev
Nauk wrote:Nice work tdev :) going to include that in the next update.
please review the code before you integrate it. It basically caches the mesh information by allocating lots of memory that never gets freed.
So for a production quality software there should be an algorithm that determines which cached variables to free at what time.

The caching i did for static geometry could also be used for other static / non moving objects and thus speed up things a lot. (i think its clear in the code how its done)