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

A place to show off your latest screenshots and for people to comment on them. Only start a new thread here if you have some nice images to show off!
User avatar
Beauty
OGRE Community Helper
OGRE Community Helper
Posts: 767
Joined: Wed Oct 10, 2007 2:36 pm
Location: Germany
x 39

Re: MOC - Minimal Ogre Collision - Demo1.0 Beta [Demo+Src+Video]

Post by Beauty »

VileMK3 wrote:

Code: Select all

m_CameraNode->getPosition()
Aware, in some (many?) cases you need the WorldPosition and WorldOrientation of a SceneNode.

I work with collision detection by Newton and when I update the objects in Newton world, I have to set the world parameters.
In my application the Newton objects follow the Ogre SceneNodes. So Ogre determines where the collision objects should be set. (In oposite of the case with use of physically calculation, where the Ogre SceneNodes will be moved by Newton.)

With MOC I suppose it can be the same.
If the SceneNode is attached to the RootSceneNode, then the world parameters are the same, but if there is an other parent SceneNode, that can be totally different.
Help to add information to the wiki. Also tiny edits will let it grow ... :idea:
Add your country to your profile ... it's interesting to know from where of the world you are.
User avatar
xabila
Goblin
Posts: 225
Joined: Mon Jun 05, 2006 9:40 am
Location: rennes [FR]

Re: MOC - Minimal Ogre Collision - Demo1.0 Beta [Demo+Src+Video]

Post by xabila »

VileMK3 wrote: I keep ending up in an infinite loop, I believe I've seen that questrion before, any idea why this occurs?
I' ve got the same problem, but only with the terrainSceneManager...
With the default sceneManager it's allright...

Have you try to stop the application with the debugger to see what is looping ?
User avatar
VileMK3
Halfling
Posts: 70
Joined: Fri Nov 28, 2008 8:49 pm
Location: Flanders, Belgium

Re: MOC - Minimal Ogre Collision - Demo1.0 Beta [Demo+Src+Video]

Post by VileMK3 »

I checkt while debugging and the program runs through CollidesWithEntity() and when there's no collision it returns false like it should so the program returns to capturing mouse and keyboard input, does another collidesWithEntity() but this time it doesn't do anything anymore after it returns false, and the capture() method of my inputhandler isn't called anymore which normally happens every frame. It just seems to get stuck at RayCastFromPoint. (also the second time my distToDest variable is 0,0,0)
User avatar
Nauk
Gnoll
Posts: 653
Joined: Thu May 11, 2006 9:12 pm
Location: Bavaria
x 36

Re: MOC - Minimal Ogre Collision - Demo1.0 Beta [Demo+Src+Video]

Post by Nauk »

Ok I finally came around to try with and without Querymasks set, I just cannot reproduce the bug, works both for me as intended.
User avatar
VileMK3
Halfling
Posts: 70
Joined: Fri Nov 28, 2008 8:49 pm
Location: Flanders, Belgium

Re: MOC - Minimal Ogre Collision - Demo1.0 Beta [Demo+Src+Video]

Post by VileMK3 »

Finally got it to work, just added an if() statement in which I check if the position has changed, if it hasn't than I don't check for collision.
User avatar
Nauk
Gnoll
Posts: 653
Joined: Thu May 11, 2006 9:12 pm
Location: Bavaria
x 36

Re: MOC - Minimal Ogre Collision - Demo1.0 Beta [Demo+Src+Video]

Post by Nauk »

That is good news, I am happy the problem is solved, hopefully that works for Xabila too :)
therealwoge
Gnoblar
Posts: 14
Joined: Fri Jan 09, 2009 5:11 am

Re: MOC - Minimal Ogre Collision - Demo1.0 Beta [Demo+Src+Video]

Post by therealwoge »

Hey there. I am very new to Ogre and thus new to MOC. I am currently using Code::Blocks as my IDE but I am having a hard time building and running the demo that was with the download. I am unsure if I am doing something wrong. I have tried the various different versions available opening up the .sln file each time and hitting build and run but I get 15 or so errors.

Is there a light weight tutorial to follow to allow me to understand how to get things going with the collision in MOC?

Thanks D
User avatar
Nauk
Gnoll
Posts: 653
Joined: Thu May 11, 2006 9:12 pm
Location: Bavaria
x 36

Re: MOC - Minimal Ogre Collision - Demo1.0 Beta [Demo+Src+Video]

Post by Nauk »

It should work out of the box with Ogre, but there are problems with the sample code and C::B / MinGW it seems, we are looking into it right now. If you don't need cross platform support and want to run it on windows only, I suggest using VC++ Express, free and works.

About the usage, if you open the SampleApp.cpp and look at the Startup() and Update() methods you can pretty much see the usage for collision and if you check the mousePressed() method you will see there is a pickEntity() method called, this should pretty much explain everything. Very simple to use really, if you have detail questions, please don't hesitate to ask again and more :)
therealwoge
Gnoblar
Posts: 14
Joined: Fri Jan 09, 2009 5:11 am

Re: MOC - Minimal Ogre Collision - Demo1.0 Beta [Demo+Src+Video]

Post by therealwoge »

Hey there I have had a fair bit or trouble trying to get MOC working with my basic interior geometry. I have included both the CollisionTools Header and Source files to my app and have finally been able to get the whole thing to build without an error. When I run the application from the release folder there is no Collision detection present. I am seriously in need of help from somebody. Please find the code below for the 4 files in my app. Sorry about the length, but I really need help.If someone could point out where I am going wrongand make suggestions this would really really help, as I am a novice programmer.

CollisionTools.h

Code: Select all

#pragma once
#ifndef COLLISIONTOOLS_H
#define COLLISIONTOOLS_H

#pragma warning (disable : 4530)

#include <Ogre.h>
#include <OIS\OISMouse.h>

// comment if you dont use ETM as terrainmanager
/*#define ETM_TERRAIN

#ifdef ETM_TERRAIN
#include "ETTerrainInfo.h"
#endif
*/

using namespace Ogre;

namespace MOC {

class CollisionTools {
public:
	Ogre::RaySceneQuery *mRaySceneQuery;
	Ogre::RaySceneQuery *mTSMRaySceneQuery;
	
	SceneManager *mSceneMgr;
	
#ifdef ETM_TERRAIN	
	const ET::TerrainInfo* mTerrainInfo;
	CollisionTools(Ogre::SceneManager *sceneMgr, const ET::TerrainInfo* terrainInfo);
#endif

	CollisionTools(Ogre::SceneManager *sceneMgr);
	~CollisionTools();			

	bool raycastFromCamera(RenderWindow* rw, Camera* camera, const OIS::MouseEvent &e, Vector3 &result, ulong &target,float &closest_distance, const uint32 queryMask = 0xFFFFFFFF);

	bool collidesWithEntity(const Vector3& fromPoint, const Vector3& toPoint, const float collisionRadius = 2.5f, const float rayHeightLevel = 0.0f, const uint32 queryMask = 0xFFFFFFFF);

	void calculateY(SceneNode *n, const bool doTerrainCheck = true, const bool doGridCheck = true, const float gridWidth = 1.0f, const uint32 queryMask = 0xFFFFFFFF);
	
	float getTSMHeightAt(const float x, const float z);

	bool raycastFromPoint(const Vector3 &point, const Vector3 &normal, Vector3 &result,ulong &target,float &closest_distance, const uint32 queryMask = 0xFFFFFFFF);

	bool raycast(const Ray &ray, Vector3 &result,ulong &target,float &closest_distance, const uint32 queryMask = 0xFFFFFFFF);
	
	void setHeightAdjust(const float heightadjust);
	float getHeightAdjust(void);

private:

	float _heightAdjust;

	void GetMeshInformation(const Ogre::MeshPtr mesh,
                                size_t &vertex_count,
                                Ogre::Vector3* &vertices,
                                size_t &index_count,
                                unsigned long* &indices,
                                const Ogre::Vector3 &position,
                                const Ogre::Quaternion &orient,
                                const Ogre::Vector3 &scale);

};

};

#endif
Dave.h

Code: Select all

#ifndef __Dave_h_
#define __Dave_h_


#include "ExampleApplication.h"
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#include "../res/resource.h"
#endif


class DaveFrameListener : public ExampleFrameListener
{
private:
   SceneManager* mSceneMgr;
public:
      DaveFrameListener(SceneManager *sceneMgr, RenderWindow* win, Camera* cam)
         : ExampleFrameListener(win, cam),
         mSceneMgr(sceneMgr)
	{
	}

	bool frameStarted(const FrameEvent& evt)
	{
		bool ret = ExampleFrameListener::frameStarted(evt);


      return ret;

	}

};



class DaveApp : public ExampleApplication
{
	public:
		DaveApp()
      {}

	~DaveApp()
	{
	}

protected:

	virtual void createCamera(void)
	{
		// creates PlayerCam
        mCamera = mSceneMgr->createCamera("PlayerCam");

        // set its position, direction
        mCamera->setPosition(Vector3(40,2,-23));
        mCamera->lookAt(Vector3(40,2,40));

        mCamera->setNearClipDistance(1);

        // creates SceneEditCam
        //mCamera = mSceneMgr->createCamera("SceneEditCam");

        // set its position, direction
        //mCamera->setPosition(Vector3(0,0,20));
        //mCamera->lookAt(Vector3(0,0,0));

        //mCamera->setNearClipDistance(1);
    }

	virtual void createViewports(void)

    {

        // Create one viewport, entire window
        Viewport* vp = mWindow->addViewport(mCamera);

        vp->setBackgroundColour(ColourValue( 0, 0, 0 ));

        //Alter the camera aspect ratio to match the viewport
        mCamera->setAspectRatio(Real(vp->getActualWidth()) / Real(vp->getActualHeight()));

    }

    virtual bool configure(void)
    {
        // Show the configuration dialog and initialise the system
        // You can skip this and use root.restoreConfig() to load configuration
        // settings if you were sure there are valid ones saved in ogre.cfg
		if(mRoot->showConfigDialog())
        {
            // If returned true, user clicked OK so initialise
            // Here we choose to let the system create a default rendering window by passing 'true'
            mWindow = mRoot->initialise(true);
			// Let's add a nice window icon
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
			HWND hwnd;
			mWindow->getCustomAttribute("WINDOW", (void*)&hwnd);
			LONG iconID   = (LONG)LoadIcon( GetModuleHandle(0), MAKEINTRESOURCE(IDI_APPICON) );
			SetClassLong( hwnd, GCL_HICON, iconID );
#endif
            return true;
        }
        else
        {
            return false;
        }
    }


	// Just override the mandatory create scene method
	virtual void createScene(void)
	{

      // Create the SkyBox
        //mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox");

        Entity *ent;
        Light *light;

        //Creates ambient light
        mSceneMgr->setAmbientLight( ColourValue( 1, 1, 1 ));

        //Creates level geometry
        Entity *ent1 = mSceneMgr->createEntity( "Level Geometry", "GameLevelGeom.mesh" );
        SceneNode *node1 = mSceneMgr->getRootSceneNode()->createChildSceneNode( "GameLevelnode" );
        node1->attachObject( ent1 );
        (Vector3( 0, 0, 0 ) );
        node1->scale(1, 1, 1 );
		
		
		//mSceneMgr->setWorldGeometry("GameLevelGeom.mesh");


        //Creates cube
        Entity *ent2 = mSceneMgr->createEntity( "PickupObjectGreen1", "PickupObjectGreen1.mesh" );
        SceneNode *node2 = mSceneMgr->getRootSceneNode()->createChildSceneNode( "PickupObjectGreen1node" );
        node2->attachObject( ent2 );
        //(Vector3( 25, 0, 25 ) );
        node2->scale(1, 1, 1 );

        //creates game_level_geom with shadows
        //mSceneMgr->setAmbientLight(ColourValue(0, 0, 0));
        //mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_ADDITIVE);
        //ent = mSceneMgr->createEntity("level", "game_level_geom.mesh");
        //ent->setCastShadows(true);
        //mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent);
        //(Vector3( 0, 5, 0 ) );

		//Creates point lights based on coordinates in plan view in Maya
        light = mSceneMgr->createLight("LightMiddle");
        light->setType(Light::LT_POINT);
        light->setPosition(Vector3(40, 2, 40));

        light = mSceneMgr->createLight("LightTopMiddle");
        light->setType(Light::LT_POINT);
        light->setPosition(Vector3(40, 2, 2));

        light = mSceneMgr->createLight("LightBottomMiddle");
        light->setType(Light::LT_POINT);
        light->setPosition(Vector3(40, 2, 78));

        light = mSceneMgr->createLight("LightRightMiddle");
        light->setType(Light::LT_POINT);
        light->setPosition(Vector3(78, 2, 40));

        light = mSceneMgr->createLight("LightLeftMiddle");
        light->setType(Light::LT_POINT);
        light->setPosition(Vector3(2, 2, 40));

        light = mSceneMgr->createLight("LightTopLeft");
        light->setType(Light::LT_POINT);
        light->setPosition(Vector3(2, 2, 2));

        light = mSceneMgr->createLight("LightTopRight");
        light->setType(Light::LT_POINT);
        light->setPosition(Vector3(78, 2, 2));

        light = mSceneMgr->createLight("LightBottomRight");
        light->setType(Light::LT_POINT);
        light->setPosition(Vector3(78, 2, 78));

        light = mSceneMgr->createLight("LightBottomLeft");
        light->setType(Light::LT_POINT);
        light->setPosition(Vector3(2, 2, 78));
		

	}

   // Create new frame listener
	void createFrameListener(void)
	{
      mFrameListener= new DaveFrameListener(mSceneMgr, mWindow, mCamera);
		mRoot->addFrameListener(mFrameListener);
	}
};

#endif // #ifndef __Dave_h_

CollisonTools.cpp

Code: Select all

#include "CollisionTools.h"


namespace MOC {

#ifdef ETM_TERRAIN
CollisionTools::CollisionTools(Ogre::SceneManager *sceneMgr, const ET::TerrainInfo* terrainInfo)
{
	mRaySceneQuery = sceneMgr->createRayQuery(Ogre::Ray());
    if (NULL == mRaySceneQuery)
    {
      // LOG_ERROR << "Failed to create Ogre::RaySceneQuery instance" << ENDLOG;
      return;
    }
    mRaySceneQuery->setSortByDistance(true);
    
    mTSMRaySceneQuery = NULL;
    
	mTerrainInfo = terrainInfo;
	
	_heightAdjust = 0.0f;
}
#endif

CollisionTools::CollisionTools(Ogre::SceneManager *sceneMgr)
{
	mSceneMgr = sceneMgr;
	
	mRaySceneQuery = mSceneMgr->createRayQuery(Ogre::Ray());
    if (NULL == mRaySceneQuery)
    {
      // LOG_ERROR << "Failed to create Ogre::RaySceneQuery instance" << ENDLOG;
      return;
    }
    mRaySceneQuery->setSortByDistance(true);
    
    mTSMRaySceneQuery =  mSceneMgr->createRayQuery(Ogre::Ray());
    
    _heightAdjust = 0.0f;    	
}

CollisionTools::~CollisionTools()
{
	if (mRaySceneQuery != NULL)
		delete mRaySceneQuery;
		
	if (mTSMRaySceneQuery != NULL)
		delete mTSMRaySceneQuery;
}

bool CollisionTools::raycastFromCamera(RenderWindow* rw, Camera* camera, const OIS::MouseEvent &e, Vector3 &result, ulong &target,float &closest_distance, const uint32 queryMask)
{
	// Create the ray to test
	Real tx = (Real) e.state.X.abs / (Real) rw->getWidth();
	Real ty = (Real) e.state.Y.abs / (Real) rw->getHeight();
	Ray ray = camera->getCameraToViewportRay(tx, ty);

	return raycast(ray, result, target, closest_distance, queryMask);
}

bool CollisionTools::collidesWithEntity(const Vector3& fromPoint, const Vector3& toPoint, const float collisionRadius, const float rayHeightLevel, const uint32 queryMask)
{
	Vector3 fromPointAdj(fromPoint.x, fromPoint.y + rayHeightLevel, fromPoint.z);
	Vector3 toPointAdj(toPoint.x, toPoint.y + rayHeightLevel, toPoint.z);	
	Vector3 normal = toPointAdj - fromPointAdj;
	float distToDest = normal.normalise();

	Vector3 myResult(0, 0, 0);
	Ogre::Entity* myObject = NULL;
	float distToColl = 0.0f;

	if (raycastFromPoint(fromPointAdj, normal, myResult, (ulong&)myObject, distToColl, queryMask))
	{
		distToColl -= collisionRadius; 
		return (distToColl <= distToDest);
	}
	else
	{
		return false;
	}
}

float CollisionTools::getTSMHeightAt(const float x, const float z) {
	float y=0.0f;

    static Ray updateRay;
    
    updateRay.setOrigin(Vector3(x,9999,z));
    updateRay.setDirection(Vector3::NEGATIVE_UNIT_Y);
    
    mTSMRaySceneQuery->setRay(updateRay);
    RaySceneQueryResult& qryResult = mTSMRaySceneQuery->execute();
    
    RaySceneQueryResult::iterator i = qryResult.begin();
    if (i != qryResult.end() && i->worldFragment)
    {
        y=i->worldFragment->singleIntersection.y;           
    }		
	return y;
}

void CollisionTools::calculateY(SceneNode *n, const bool doTerrainCheck, const bool doGridCheck, const float gridWidth, const uint32 queryMask)
{
	Vector3 pos = n->getPosition();
	
	float x = pos.x;
	float z = pos.z;
	float y = pos.y;
	
	Vector3 myResult(0,0,0);
	Ogre::Entity *myObject=NULL;
	float distToColl = 0.0f;

	float terrY = 0, colY = 0, colY2 = 0;

	if( raycastFromPoint(Vector3(x,y,z),Vector3::NEGATIVE_UNIT_Y,myResult,(ulong&)myObject, distToColl, queryMask)){
		if (myObject != NULL) {
			colY = myResult.y;
		} else {
			colY = -99999;
		}
	}
	
	//if doGridCheck is on, repeat not to fall through small holes for example when crossing a hangbridge
	if (doGridCheck) {		
		if( raycastFromPoint(Vector3(x,y,z)+(n->getOrientation()*Vector3(0,0,gridWidth)),Vector3::NEGATIVE_UNIT_Y,myResult,(ulong&)myObject, distToColl, queryMask)){
			if (myObject != NULL) {
				colY = myResult.y;
			} else {
				colY = -99999;
			}	
		}
		if (colY<colY2) colY = colY2;
	}
	
	// set the parameter to false if you are not using ETM or TSM
	if (doTerrainCheck) {
	
#ifdef ETM_TERRAIN
		// ETM height value
		terrY = mTerrainInfo->getHeightAt(x,z);
#else	
		// TSM height value
		terrY = getTSMHeightAt(x,z);
#endif

		if(terrY < colY ) {
			n->setPosition(x,colY+_heightAdjust,z);
		} else {
			n->setPosition(x,terrY+_heightAdjust,z);
		}
	} else {
		if (!doTerrainCheck && colY == -99999) colY = y;
		n->setPosition(x,colY+_heightAdjust,z);
	}
}

// raycast from a point in to the scene.
// returns success or failure.
// on success the point is returned in the result.
bool CollisionTools::raycastFromPoint(const Vector3 &point,
                                        const Vector3 &normal,
										Vector3 &result,ulong &target,float &closest_distance,
										const uint32 queryMask)
{
    // create the ray to test
    static Ogre::Ray ray;
	ray.setOrigin(point);
	ray.setDirection(normal);

	return raycast(ray, result, target, closest_distance, queryMask);
}

bool CollisionTools::raycast(const Ray &ray, Vector3 &result,ulong &target,float &closest_distance, const 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::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;
            unsigned long *indices;

            // get the mesh information
			GetMeshInformation(pentity->getMesh(), vertex_count, vertices, index_count, indices,             
                              pentity->getParentNode()->_getDerivedPosition(),
                              pentity->getParentNode()-> _getDerivedOrientation(),
                              pentity->getParentNode()->getScale());

            // test for hitting individual triangles on the mesh
            bool new_closest_found = false;
            for (int i = 0; i < static_cast<int>(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;
                    }
                }
            }

			// 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 = (ulong)pentity;
                closest_result = ray.getPoint(closest_distance);               
            }
        }       
    }

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


// Get the mesh information for the given mesh.
// Code found on this forum link: http://www.ogre3d.org/wiki/index.php/RetrieveVertexData
void CollisionTools::GetMeshInformation(const Ogre::MeshPtr mesh,
                                size_t &vertex_count,
                                Ogre::Vector3* &vertices,
                                size_t &index_count,
                                unsigned long* &indices,
                                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;

    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 unsigned long[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;

        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::Real or a double
            //  as second argument. So make it float, to avoid trouble when Ogre::Real will
            //  be comiled/typedefed as double:
            //      Ogre::Real* pReal;
            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);

        unsigned long*  pLong = static_cast<unsigned long*>(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<unsigned long>(offset);
            }
        }
        else
        {
            for ( size_t k = 0; k < numTris*3; ++k)
            {
                indices[index_offset++] = static_cast<unsigned long>(pShort[k]) +
                    static_cast<unsigned long>(offset);
            }
        }

        ibuf->unlock();
        current_offset = next_offset;
    }
}

void CollisionTools::setHeightAdjust(const float heightadjust) {
	_heightAdjust = heightadjust;
}

float CollisionTools::getHeightAdjust(void) {
	return _heightAdjust;
}

};
Dave.cpp

Code: Select all

#include "Dave.h"

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
#endif

#ifdef __cplusplus
	extern "C" {
#endif

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
		INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
#else
		int main(int argc, char *argv[])
#endif
		{
			// Create application object
			DaveApp app;

			try {
				app.go();
			} catch( Ogre::Exception& e ) {
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
				MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
#else
				std::cerr << "An exception has occured: " <<
					e.getFullDescription().c_str() << std::endl;
#endif
			}

			return 0;
		}

#ifdef __cplusplus
	}
#endif
User avatar
Nauk
Gnoll
Posts: 653
Joined: Thu May 11, 2006 9:12 pm
Location: Bavaria
x 36

Re: MOC - Minimal Ogre Collision - Demo1.0 Beta [Demo+Src+Video]

Post by Nauk »

You are currently not doing any collision checks at all. You either need to have something like this in your framestarted method:

Code: Select all

// save the current camera position
		Vector3 oldPos = mCamNode->getPosition();

// apply the movement
		mCamNode->translate(mCamera->getOrientation() * mDirection * (mMoveSpeed * timeFactor));

// check if any movment happened
		if (oldPos != mCamNode->getPosition()) {

  // do a ground collision check
			mCollisionTools->calculateY(mCamNode);

  // check if a collision would happen with an entity
			if (mCollisionTools->collidesWithEntity(oldPos, mCamNode->getPosition(),ENTITY_MASK))
			{

    // if there was a collision discard the movement reset the camera to old position
				mCamNode->setPosition(oldPos);

			}
		}
	
or in an update method if you work without framelistener, as I said, if you look at the example app that comes with MOC it should be clear how to call it and where. In doubt I strongly recommend to work the basic ogre wiki tutorials -> http://www.ogre3d.org/wiki/index.php/Ogre_Tutorials <- to understand how a framelistener works or how you setup a basic ogre app without framelistener. No offense but seeing your code you won't get much further without that.

Additionally you need to flag all your Entities with setQueryMask(ENTITY_MASK).

Example how you define masks:

Code: Select all

enum QueryFlags
{
   WATER_MASK = 1<<7,
   ENTITY_MASK  = 1<<8,
   WALL_MASK   = 1<<9,
};
Hope that helps a bit on the way :)
User avatar
Kukanani
Halfling
Posts: 67
Joined: Thu Jun 12, 2008 11:42 pm
x 1

Re: MOC - Minimal Ogre Collision - Demo1.0 Beta [Demo+Src+Video]

Post by Kukanani »

I'm trying to use the "Grass" Ogre demo and adapt it to use MOC. Unfortunately, while building I get errors.

Here's my edited code:

Code: Select all

/*
-----------------------------------------------------------------------------
This source file is part of OGRE
    (Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2006 Torus Knot Software Ltd
Also see acknowledgements in Readme.html

You may use this sample code for anything you like, it is not covered by the
LGPL like the rest of the engine.
-----------------------------------------------------------------------------
*/

/**
    \file
        Grass.cpp
    \brief
        Specialisation of OGRE's framework application to show the
        use of the StaticGeometry class to create 'baked' instances of
		many meshes, to create effects like grass efficiently.
**/

#include "ExampleApplication.h"
#include "Ogre.h"


#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
#endif


#define KEY_PRESSED(_key,_timeDelay, _macro) \
{ \
    if (mKeyboard->isKeyDown(_key) && timeDelay <= 0) \
    { \
		timeDelay = _timeDelay; \
        _macro ; \
    } \
}

#define GRASS_HEIGHT 300
#define GRASS_WIDTH 250
#define GRASS_MESH_NAME "grassblades"
#define GRASS_MATERIAL "Examples/GrassBlades"
#define OFFSET_PARAM 999

#include "CollisionTools.h"

using namespace MOC;

Light* mLight;
SceneNode* mLightNode = 0;
AnimationState* mAnimState = 0;
ColourValue mMinLightColour(0.5, 0.1, 0.0);
ColourValue mMaxLightColour(1.0, 0.6, 0.0);
Real mMinFlareSize = 40;
Real mMaxFlareSize = 80;
StaticGeometry* mStaticGeom;

enum QueryFlags
{
    GROUND_MASK = 1<<0,
    ROBOT_MASK = 1<<1
};

/** This class 'wibbles' the light and billboard */
class LightWibbler : public ControllerValue<Real>
{
protected:
	Light* mLight;
	Billboard* mBillboard;
	ColourValue mColourRange;
	ColourValue mHalfColour;
	Real mMinSize;
	Real mSizeRange;
	Real intensity;
public:
	LightWibbler(Light* light, Billboard* billboard, const ColourValue& minColour,
		const ColourValue& maxColour, Real minSize, Real maxSize)
	{
		mLight = light;
		mBillboard = billboard;
		mColourRange.r = (maxColour.r - minColour.r) * 0.5;
		mColourRange.g = (maxColour.g - minColour.g) * 0.5;
		mColourRange.b = (maxColour.b - minColour.b) * 0.5;
		mHalfColour = minColour + mColourRange;
		mMinSize = minSize;
		mSizeRange = maxSize - minSize;
	}

	virtual Real  getValue (void) const
	{
		return intensity;
	}

	virtual void  setValue (Real value)
	{
		intensity = value;

		ColourValue newColour;

		// Attenuate the brightness of the light
		newColour.r = mHalfColour.r + (mColourRange.r * intensity);
		newColour.g = mHalfColour.g + (mColourRange.g * intensity);
		newColour.b = mHalfColour.b + (mColourRange.b * intensity);

		mLight->setDiffuseColour(newColour);
		mBillboard->setColour(newColour);
		// set billboard size
		Real newSize = mMinSize + (intensity * mSizeRange);
		mBillboard->setDimensions(newSize, newSize);

	}
};

class GrassListener : public ExampleFrameListener
{
protected:
	SceneManager* mSceneManager;
	bool mShowBBs;
	CollisionTools* mCollisionTools;
public:
	GrassListener(RenderWindow* win, Camera* cam, SceneManager* sceneManager)
		: ExampleFrameListener(win, cam),
		mSceneManager(sceneManager), mShowBBs(false)
	{
	}


	void waveGrass(Real timeElapsed)
	{
		static Real xinc = Math::PI * 0.4;
		static Real zinc = Math::PI * 0.55;
		static Real xpos = Math::RangeRandom(-Math::PI, Math::PI);
		static Real zpos = Math::RangeRandom(-Math::PI, Math::PI);

		xpos += xinc * timeElapsed;
		zpos += zinc * timeElapsed;

		// Update vertex program parameters by binding a value to each renderable
		static Vector4 offset(0,0,0,0);

		StaticGeometry::RegionIterator rit =  mStaticGeom->getRegionIterator();
		while (rit.hasMoreElements())
		{
			StaticGeometry::Region* reg = rit.getNext();

			// a little randomness
			xpos += reg->getCentre().x * 0.001;
			zpos += reg->getCentre().z * 0.001;
			offset.x = Math::Sin(xpos) * 5;
			offset.z = Math::Sin(zpos) * 5;

			StaticGeometry::Region::LODIterator lodit = reg->getLODIterator();
			while (lodit.hasMoreElements())
			{
				StaticGeometry::LODBucket* lod = lodit.getNext();
				StaticGeometry::LODBucket::MaterialIterator matit =
					lod->getMaterialIterator();
				while (matit.hasMoreElements())
				{
					StaticGeometry::MaterialBucket* mat = matit.getNext();
					StaticGeometry::MaterialBucket::GeometryIterator geomit =
						mat->getGeometryIterator();
					while (geomit.hasMoreElements())
					{
						StaticGeometry::GeometryBucket* geom = geomit.getNext();
						geom->setCustomParameter(OFFSET_PARAM, offset);

					}
				}
			}


		}

        // init the collision handler
        mCollisionTools = new CollisionTools(mSceneManager);
        // set how far we want the camera to be above ground
        mCollisionTools->setHeightAdjust(4.5f);

        // place the camera node on the ground
        mCollisionTools->calculateY(mCamera->getParentSceneNode());

	}

	bool frameRenderingQueued(const FrameEvent& evt)
	{
		if( ExampleFrameListener::frameRenderingQueued(evt) == false )
			return false;

		static Real timeDelay = 0;
		timeDelay -= evt.timeSinceLastFrame;

		if (mAnimState)
			mAnimState->addTime(evt.timeSinceLastFrame);

		KEY_PRESSED(OIS::KC_B, 1,
			mShowBBs = !mShowBBs;
			mSceneManager->showBoundingBoxes(mShowBBs);
			)

		waveGrass(evt.timeSinceLastFrame);

		Vector3 oldPos = mCamera->getPosition();

		// commit move
		//mCamNode->translate(mCamera->getOrientation() * mDirection * (mMoveSpeed * timeFactor));

            // 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(mCamera->getParentSceneNode(),true,true,2.0f,GROUND_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, mCamera->getPosition(), 2.5f, -1.0f, GROUND_MASK))
			{
				// undo move
				mCamera->setPosition(oldPos);
			}

		return true;
	}
};



class Grass_Application : public ExampleApplication
{
public:
    Grass_Application() {}

protected:
	SceneNode *mpObjsNode; // the node wich will hold our entities

	void createGrassMesh()
	{
		// Each grass section is 3 planes at 60 degrees to each other
		// Normals point straight up to simulate correct lighting
		MeshPtr msh = MeshManager::getSingleton().createManual(GRASS_MESH_NAME,
			ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
		SubMesh* sm = msh->createSubMesh();
		sm->useSharedVertices = false;
		sm->vertexData = new VertexData();
		sm->vertexData->vertexStart = 0;
		sm->vertexData->vertexCount = 12;
		VertexDeclaration* dcl = sm->vertexData->vertexDeclaration;
		size_t offset = 0;
		dcl->addElement(0, offset, VET_FLOAT3, VES_POSITION);
		offset += VertexElement::getTypeSize(VET_FLOAT3);
		dcl->addElement(0, offset, VET_FLOAT3, VES_NORMAL);
		offset += VertexElement::getTypeSize(VET_FLOAT3);
		dcl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES);
		offset += VertexElement::getTypeSize(VET_FLOAT2);

		HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton()
			.createVertexBuffer(
				offset, 12, HardwareBuffer::HBU_STATIC_WRITE_ONLY);
		float* pReal = static_cast<float*>(vbuf->lock(HardwareBuffer::HBL_DISCARD));
		Vector3 baseVec(GRASS_WIDTH/2, 0, 0);
		Vector3 vec = baseVec;
		Quaternion rot;
		rot.FromAngleAxis(Degree(60), Vector3::UNIT_Y);
		int i;
		for (i = 0; i < 3; ++i)
		{
			// position
			*pReal++ = -vec.x;
			*pReal++ = GRASS_HEIGHT;
			*pReal++ = -vec.z;
			// normal
			*pReal++ = 0;
			*pReal++ = 1;
			*pReal++ = 0;
			// uv
			*pReal++ = 0;
			*pReal++ = 0;

			// position
			*pReal++ = vec.x;
			*pReal++ = GRASS_HEIGHT;
			*pReal++ = vec.z;
			// normal
			*pReal++ = 0;
			*pReal++ = 1;
			*pReal++ = 0;
			// uv
			*pReal++ = 1;
			*pReal++ = 0;

			// position
			*pReal++ = -vec.x;
			*pReal++ = 0;
			*pReal++ = -vec.z;
			// normal
			*pReal++ = 0;
			*pReal++ = 1;
			*pReal++ = 0;
			// uv
			*pReal++ = 0;
			*pReal++ = 1;

			// position
			*pReal++ = vec.x;
			*pReal++ = 0;
			*pReal++ = vec.z;
			// normal
			*pReal++ = 0;
			*pReal++ = 1;
			*pReal++ = 0;
			// uv
			*pReal++ = 1;
			*pReal++ = 1;

			vec = rot * vec;
		}
		vbuf->unlock();
		sm->vertexData->vertexBufferBinding->setBinding(0, vbuf);
		sm->indexData->indexCount = 6*3;
		sm->indexData->indexBuffer = HardwareBufferManager::getSingleton()
			.createIndexBuffer(HardwareIndexBuffer::IT_16BIT, 6*3,
				HardwareBuffer::HBU_STATIC_WRITE_ONLY);
		uint16* pI = static_cast<uint16*>(
			sm->indexData->indexBuffer->lock(HardwareBuffer::HBL_DISCARD));
		for (i = 0; i < 3; ++i)
		{
			int off = i*4;
			*pI++ = 0 + off;
			*pI++ = 3 + off;
			*pI++ = 1 + off;

			*pI++ = 0 + off;
			*pI++ = 2 + off;
			*pI++ = 3 + off;
		}

		sm->indexData->indexBuffer->unlock();

		sm->setMaterialName(GRASS_MATERIAL);
		msh->load();

	}

	void setupLighting()
	{
		// Set ambient light
		mSceneMgr->setAmbientLight(ColourValue::Black);
		// Point light, movable, reddish
		mLight = mSceneMgr->createLight("Light2");
		mLight->setDiffuseColour(mMinLightColour);
		mLight->setSpecularColour(1, 1, 1);
		mLight->setAttenuation(8000,1,0.0005,0);

		// Create light node
		mLightNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(
			"MovingLightNode");
		mLightNode->attachObject(mLight);
		// create billboard set
		BillboardSet* bbs = mSceneMgr->createBillboardSet("lightbbs", 1);
		bbs->setMaterialName("Examples/Flare");
		Billboard* bb = bbs->createBillboard(0,0,0,mMinLightColour);
		// attach
		mLightNode->attachObject(bbs);

		// create controller, after this is will get updated on its own
		ControllerFunctionRealPtr func = ControllerFunctionRealPtr(
			new WaveformControllerFunction(Ogre::WFT_SINE, 0.0, 0.5));
		ControllerManager& contMgr = ControllerManager::getSingleton();
		ControllerValueRealPtr val = ControllerValueRealPtr(
			new LightWibbler(mLight, bb, mMinLightColour, mMaxLightColour,
			mMinFlareSize, mMaxFlareSize));
		Controller<Real>* controller = contMgr.createController(
			contMgr.getFrameTimeSource(), val, func);

		//mLight->setPosition(Vector3(300,250,-300));
		mLightNode->setPosition(Vector3(300,250,-300));


		// Create a track for the light
		Animation* anim = mSceneMgr->createAnimation("LightTrack", 20);
		// Spline it for nice curves
		anim->setInterpolationMode(Animation::IM_SPLINE);
		// Create a track to animate the camera's node
		NodeAnimationTrack* track = anim->createNodeTrack(0, mLightNode);
		// Setup keyframes
		TransformKeyFrame* key = track->createNodeKeyFrame(0); // A startposition
		key->setTranslate(Vector3(300,550,-300));
		key = track->createNodeKeyFrame(2);//B
		key->setTranslate(Vector3(150,600,-250));
		key = track->createNodeKeyFrame(4);//C
		key->setTranslate(Vector3(-150,650,-100));
		key = track->createNodeKeyFrame(6);//D
		key->setTranslate(Vector3(-400,500,-200));
		key = track->createNodeKeyFrame(8);//E
		key->setTranslate(Vector3(-200,500,-400));
		key = track->createNodeKeyFrame(10);//F
		key->setTranslate(Vector3(-100,450,-200));
		key = track->createNodeKeyFrame(12);//G
		key->setTranslate(Vector3(-100,400,180));
		key = track->createNodeKeyFrame(14);//H
		key->setTranslate(Vector3(0,250,600));
		key = track->createNodeKeyFrame(16);//I
		key->setTranslate(Vector3(100,650,100));
		key = track->createNodeKeyFrame(18);//J
		key->setTranslate(Vector3(250,600,0));
		key = track->createNodeKeyFrame(20);//K == A
		key->setTranslate(Vector3(300,550,-300));
		// Create a new animation state to track this
		mAnimState = mSceneMgr->createAnimationState("LightTrack");
		mAnimState->setEnabled(true);
	}

	void createScene(void)
    {

		mSceneMgr->setSkyBox(true, "Examples/SpaceSkyBox");

		setupLighting();


		Plane plane;
		plane.normal = Vector3::UNIT_Y;
		plane.d = 0;
		MeshManager::getSingleton().createPlane("Myplane",
			ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane,
			14500,14500,10,10,true,1,50,50,Vector3::UNIT_Z);
		Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" );
		pPlaneEnt->setMaterialName("Examples/GrassFloor");
		pPlaneEnt->setCastShadows(false);
		pPlaneEnt->setQueryFlags(GROUND_MASK);
		mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt);

		Vector3 minV(-2000,0,-2000);
		Vector3 maxV(2000,0,2000);


		createGrassMesh();

		Entity* e = mSceneMgr->createEntity("1", GRASS_MESH_NAME);

		StaticGeometry* s = mSceneMgr->createStaticGeometry("bing");
		s->setRegionDimensions(Vector3(1000,1000,1000));
		// Set the region origin so the centre is at 0 world
		s->setOrigin(Vector3(-500, 500, -500));

		for (int x = -1950; x < 1950; x += 150)
		{
			for (int z = -1950; z < 1950; z += 150)
			{
				Vector3 pos(
					x + Math::RangeRandom(-25, 25),
					0,
					z + Math::RangeRandom(-25, 25));
				Quaternion orientation;
				orientation.FromAngleAxis(
					Degree(Math::RangeRandom(0, 359)),
					Vector3::UNIT_Y);
				Vector3 scale(
					1, Math::RangeRandom(0.85, 1.15), 1);
				s->addEntity(e, pos, orientation, scale);
			}

		}

		s->build();
		mStaticGeom = s;

		// Put an Ogre head in the middle
		MeshPtr m = MeshManager::getSingleton().load("ogrehead.mesh",
			ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
		unsigned short src, dest;
		if (!m->suggestTangentVectorBuildParams(VES_TANGENT, src, dest))
		{
			m->buildTangentVectors(VES_TANGENT, src, dest);
		}
		e = mSceneMgr->createEntity("head", "ogrehead.mesh");
		e->setMaterialName("Examples/OffsetMapping/Specular");
		SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
		headNode->attachObject(e);
		headNode->setScale(7,7,7);
		headNode->setPosition(0,200,0);
		headNode->yaw(Degree(15));
		mCamera->move(Vector3(0,350,0));
	}

    // Create new frame listener
    void createFrameListener(void)
    {
        mFrameListener= new GrassListener(mWindow, mCamera, mSceneMgr);
        mRoot->addFrameListener(mFrameListener);
    }
};

#ifdef __cplusplus
extern "C" {
#endif

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
#else
int main(int argc, char **argv)
#endif
{
    // Create application object
    Grass_Application app;

    try {
        app.go();
    } catch( Exception& e ) {
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
        MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
#else
        std::cerr << "An exception has occured: " << e.getFullDescription();
#endif
    }

    return 0;
}

#ifdef __cplusplus
}
#endif

Here's my build errors:

Code: Select all

||Info: resolving Ogre::Math::fDeg2Rad     by linking to __imp___ZN4Ogre4Math8fDeg2RadE |
||Info: resolving Ogre::Vector3::ZERO     by linking to __imp___ZN4Ogre7Vector34ZEROE |
||Info: resolving Ogre::ColourValue::Black      by linking to __imp___ZN4Ogre11ColourValue5BlackE |
||Info: resolving Ogre::Quaternion::IDENTITY      by linking to __imp___ZN4Ogre10Quaternion8IDENTITYE |
||Info: resolving Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME       by linking to __imp___ZN4Ogre20ResourceGroupManager27DEFAULT_RESOURCE_GROUP_NAMEE |
||Info: resolving Ogre::Vector3::UNIT_Y     by linking to __imp___ZN4Ogre7Vector36UNIT_YE |
||Info: resolving Ogre::Vector3::UNIT_Z     by linking to __imp___ZN4Ogre7Vector36UNIT_ZE |
||Info: resolving Ogre::StringUtil::BLANK      by linking to __imp___ZN4Ogre10StringUtil5BLANKE |
||Info: resolving Ogre::Math::PI     by linking to __imp___ZN4Ogre4Math2PIE |
||warning: auto-importing has been activated without --enable-auto-import specified on the command line.|
This should work unless it involves constant data structures referencing symbols from auto-imported DLLs...\obj\Release\src\Grass.o:Grass.cpp:(.text$_ZN13GrassListener9waveGrassEf[GrassListener::waveGrass(float)]+0x456)||undefined reference to `MOC::CollisionTools::CollisionTools(Ogre::SceneManager*)'|
..\obj\Release\src\Grass.o:Grass.cpp:(.text$_ZN13GrassListener9waveGrassEf[GrassListener::waveGrass(float)]+0x494)||undefined reference to `MOC::CollisionTools::setHeightAdjust(float)'|
..\obj\Release\src\Grass.o:Grass.cpp:(.text$_ZN13GrassListener9waveGrassEf[GrassListener::waveGrass(float)]+0x4d4)||undefined reference to `MOC::CollisionTools::calculateY(Ogre::SceneNode*, bool, bool, float, unsigned int)'|
)]+0xe7)||undefined reference to `MOC::CollisionTools::calculateY(Ogre::SceneNode*, bool, bool, float, unsigned int)'|
)]+0x11e)||undefined reference to `MOC::CollisionTools::collidesWithEntity(Ogre::Vector3 const&, Ogre::Vector3 const&, float, float, unsigned int)'|
||=== Build finished: 5 errors, 1 warnings ===|

I'm using Code::Blocks, MinGW, Vista 64-Bit. I copied the CollisionTools.h and CollisionTools.cpp to the include and src dirs to be more easily accessible, but even if I don't I still get these errors. Help would be appreciated.

Kukanani

EDIT: Yes, I have searched this.
Grammar is the greatest joy in life, don't you find?

--Aunt Josephine in The Wide Window
User avatar
Nauk
Gnoll
Posts: 653
Joined: Thu May 11, 2006 9:12 pm
Location: Bavaria
x 36

Re: MOC - Minimal Ogre Collision - Demo1.0 Beta [Demo+Src+Video]

Post by Nauk »

This version of MOC posted by kallitokaco on the MOC board works and compiles with Ogre 1.61 Codeblocks / MinGW, I just tried it: http://www.artifexterra3d.com/forum/moc ... 70/#msg170

HTH /Nauk :)
User avatar
Kukanani
Halfling
Posts: 67
Joined: Thu Jun 12, 2008 11:42 pm
x 1

Re: MOC - Minimal Ogre Collision - Demo1.0 Beta [Demo+Src+Video]

Post by Kukanani »

Sorry but this still doesn't work for me.

Same code as before, but the CollisionTools files are updated with the ones from that post on the Artifex forums.

Errors:

Code: Select all

||=== Demo_Grass, Release ===|
..\obj\Release\src\Grass.o:Grass.cpp:(.text$_ZN13GrassListener9waveGrassEf[GrassListener::waveGrass(float)]+0x456)||undefined reference to `MOC::CollisionTools::CollisionTools(Ogre::SceneManager*)'|
..\obj\Release\src\Grass.o:Grass.cpp:(.text$_ZN13GrassListener9waveGrassEf[GrassListener::waveGrass(float)]+0x494)||undefined reference to `MOC::CollisionTools::setHeightAdjust(float)'|
..\obj\Release\src\Grass.o:Grass.cpp:(.text$_ZN13GrassListener9waveGrassEf[GrassListener::waveGrass(float)]+0x4d4)||undefined reference to `MOC::CollisionTools::calculateY(Ogre::SceneNode*, bool, bool, float, unsigned int)'|
)]+0xe7)||undefined reference to `MOC::CollisionTools::calculateY(Ogre::SceneNode*, bool, bool, float, unsigned int)'|
)]+0x11e)||undefined reference to `MOC::CollisionTools::collidesWithEntity(Ogre::Vector3 const&, Ogre::Vector3 const&, float, float, unsigned int)'|
||=== Build finished: 5 errors, 0 warnings ===|
Grammar is the greatest joy in life, don't you find?

--Aunt Josephine in The Wide Window
User avatar
Kukanani
Halfling
Posts: 67
Joined: Thu Jun 12, 2008 11:42 pm
x 1

Re: MOC - Minimal Ogre Collision - Demo1.0 Beta [Demo+Src+Video]

Post by Kukanani »

Ah! I got noobed (well, I am a noob.)

Forgot to add the CollisionTools files to my project.

Thanks for the help,

Kukanani
Grammar is the greatest joy in life, don't you find?

--Aunt Josephine in The Wide Window
User avatar
Nauk
Gnoll
Posts: 653
Joined: Thu May 11, 2006 9:12 pm
Location: Bavaria
x 36

Re: MOC - Minimal Ogre Collision - Demo1.0 Beta [Demo+Src+Video]

Post by Nauk »

I just took your Grass.cpp and copied it into my MOC C::B test project and it compiled just fine, 3 warnings, no errors. I created that project with the Codeblocks Ogre wizard, so there is likely something wrong with your setup, because the code works like this. Mind you I haven't tested any functionality, I only did compile it.
User avatar
Nauk
Gnoll
Posts: 653
Joined: Thu May 11, 2006 9:12 pm
Location: Bavaria
x 36

Re: MOC - Minimal Ogre Collision - Demo1.0 Beta [Demo+Src+Video]

Post by Nauk »

Kukanani wrote:Ah! I got noobed (well, I am a noob.)

Forgot to add the CollisionTools files to my project.

Thanks for the help,

Kukanani
Problem located behind the keyboard! :) - Well good then it should work now.
teamgong
Gnoblar
Posts: 8
Joined: Wed Apr 02, 2008 7:17 am

Re: MOC - Minimal Ogre Collision - Demo1.0 Beta [Demo+Src+Video]

Post by teamgong »

very good!!!
User avatar
xadhoom
Minaton
Posts: 973
Joined: Fri Dec 28, 2007 4:35 pm
Location: Germany
x 1

Re: MOC - Minimal Ogre Collision - Demo1.0 Beta [Demo+Src+Video]

Post by xadhoom »

Hi Nauk!

Do you have a roadmap for MOC in mind?

xad
User avatar
Nauk
Gnoll
Posts: 653
Joined: Thu May 11, 2006 9:12 pm
Location: Bavaria
x 36

Re: MOC - Minimal Ogre Collision - Demo1.0 Beta [Demo+Src+Video]

Post by Nauk »

Hey Xad, not a roadmap exactly, but here is what is lined up for coming versions:

- code cosmetics to make it more portable
- billboard support and evtl other ogre objects as far as possible.
- sliding implementation (likely to be a user contribution soon)
- bsp support

Roughly in that order.

Oh and: Proper documentation + wiki entries :D
mickeyren
Greenskin
Posts: 142
Joined: Thu Dec 18, 2008 11:32 am

Re: MOC - Minimal Ogre Collision - Demo1.0 Beta [Demo+Src+Video]

Post by mickeyren »

Hi Nauk

Would you update your code to include sliding when it collides with the wall?
User avatar
Nauk
Gnoll
Posts: 653
Joined: Thu May 11, 2006 9:12 pm
Location: Bavaria
x 36

Re: MOC - Minimal Ogre Collision - Demo1.0 Beta [Demo+Src+Video]

Post by Nauk »

Hey mickey, brogaard just informed me that he is still working on it, but had to pause for a more urgent matter. I have very little time right now being busy with Artifex mainly, so if you need it fast you would have to implement it yourself, I have posted a theoretical approach that should work and not be all that hard to put into code: http://www.artifexterra3d.com/forum/moc ... -collsion/
mickeyren
Greenskin
Posts: 142
Joined: Thu Dec 18, 2008 11:32 am

Re: MOC - Minimal Ogre Collision - Demo1.0 Beta [Demo+Src+Video]

Post by mickeyren »

Hi Nauk,

ok i could try - does MOC also return the exact point of collision ?
ludollu
Kobold
Posts: 38
Joined: Tue Apr 03, 2007 10:38 am

Re: MOC - Minimal Ogre Collision - Demo1.0 Beta [Demo+Src+Video]

Post by ludollu »

Hi everyone !
I'm a MOC user.

I create a beautiful manualObject (a 3d triangle) with OT_TRIANGLE_LIST renderOperation
after that I convert it in mesh (convertToMesh).

Then I use MOC for picking.
But, the function GetMeshInformation return strange result.

Code: Select all

GetMeshInformation(entity->getMesh(), vertex_count, vertices, index_count, indices,
       entity->getParentNode()->_getDerivedPosition(),
       entity->getParentNode()->_getDerivedOrientation(),
       entity->getParentNode()->getScale());
The vertex position seem wrong.
My triangle is in a plan (with y aligned) and I have some vertex with y=1 and other with y=-1

I change the function getMeshInformation to use directly the matrix 4x4 representing the full transformation.

Code: Select all

newGetMeshInformation(entity->getMesh(), vertex_count, vertices, index_count, indices,
       entity->_getParentNodeFullTransform());
I have the same results :'(

I probably make a mistake !
So if you have a idea ...
User avatar
Nauk
Gnoll
Posts: 653
Joined: Thu May 11, 2006 9:12 pm
Location: Bavaria
x 36

Re: MOC - Minimal Ogre Collision - Demo1.0 Beta [Demo+Src+Video]

Post by Nauk »

@mickeyren: Sorry I totally missed that, yes it should, since it calculates the intersection point with the ray and the polygon hit.

@ludollu: Out of the box, I have no idea why that could be the case, but you could try and create an identical mesh in blender or whatever modeler, then apply your transformations and try the picking again on the test object to compare the difference to your manual object, might give you a better clue where things go wrong.