コード例 #1
0
void CollisionDetection::createConvexHull( Entity *entity, bool enemy )
{
    size_t vertex_count;
	size_t index_count;
	Ogre::Vector3 *vertices;
	unsigned long *indices;

    GetMeshInformation(   entity->getMesh(), vertex_count, vertices, index_count, indices,
                          Vector3( 0.0, 0.0, 0.0 ),//entity->getParentNode()->getPosition(),
                          Ogre::Quaternion::IDENTITY, //entity->getParentNode()->getOrientation()
                          Ogre::Vector3(1,1,1));//entity->getParentNode()->_getDerivedScale() );//Ogre::Vector3(1,1,1));

    dFloat *vertexCloud = new dFloat[vertex_count*3];
    for( int i = 0; i < vertex_count; i++ )
    {
        vertexCloud[i*3] = vertices[i].x;
        vertexCloud[i*3+1] = vertices[i].y;
        vertexCloud[i*3+2] = vertices[i].z;
    }
    shapeID++;
    NewtonCollision *newCol = NewtonCreateConvexHull (newtonWorld, vertex_count, vertexCloud, 12, 0.0, shapeID, NULL);
    if(enemy)
    {
        enemyEnt = newCol;
    }
    else
    {
        NewtonBody* rigidBodyBox = NewtonCreateBody (newtonWorld, newCol);
        //PROBLEM with the line as this comand should work, but terminates the app;Possibly a c++ issue
        //NewtonReleaseCollision( newtonWorld, enemyCol);
        collisionsMap.insert(pair<Entity*,NewtonCollision*>(entity,newCol));
        bodysMap.insert(pair<Entity*,NewtonBody*>(entity,rigidBodyBox));
    }
}
コード例 #2
0
ファイル: SceneObject.cpp プロジェクト: LiberatorUSA/GUCEF
	void SceneObject::updateData()
	{
		clear();

		Ogre::Entity* entity = getSceneManager()->getEntity(mEntityName);
		if (entity != nullptr && !mMaterialName.empty())
		{
			mVertexCount = 0;
			mIndexCount = 0;
			GetMeshInformation(entity->getMesh(), mVertexCount, mVertices, mIndexCount, mIndices, mTextureCoords, Ogre::Vector3::ZERO, Ogre::Quaternion::IDENTITY, Ogre::Vector3::UNIT_SCALE, mMaterialName);

			Ogre::MaterialPtr material = (Ogre::MaterialPtr)Ogre::MaterialManager::getSingleton().getByName(mMaterialName);
			if (!material.isNull())
			{
				mTextureUnit = material->getTechnique(0)->getPass(0)->getTextureUnitState("gui");
				if (mTextureUnit)
				{
					mTextureUnit->setTextureName(mTextureName);
					mUScale = mTextureUnit->getTextureUScale();
					mVScale = mTextureUnit->getTextureVScale();
				}
			}
		}
	}
コード例 #3
0
ファイル: CollisionTools.cpp プロジェクト: aerique/okra
bool CollisionTools::raycast(const Ogre::Ray &ray, Ogre::Vector3 &result,Ogre::MovableObject* &target,float &closest_distance, 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 or
        // ManualObject.
        if ((query_result[qr_idx].movable != NULL) &&
            (query_result[qr_idx].movable->isVisible()) &&
            ((query_result[qr_idx].movable->getMovableType().compare("Entity") == 0) ||
             (query_result[qr_idx].movable->getMovableType().compare("ManualObject") == 0)))
        {
            // get the entity to check
            Ogre::MovableObject *pmovable =
               static_cast<Ogre::MovableObject*>(query_result[qr_idx].movable);

            Ogre::MeshPtr mesh_ptr;

            if (query_result[qr_idx].movable->getMovableType().compare("Entity") == 0)
            {
                mesh_ptr = ((Ogre::Entity*)pmovable)->getMesh();
            }
            else
            {
                // XXX: Does "Mesh" get replaced so we can get away with not
                // XXX: deleting it for now?
                mesh_ptr = ((Ogre::ManualObject*)pmovable)->convertToMesh("Mesh", "General");
            }

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

            // get the mesh information
            GetMeshInformation(mesh_ptr, vertex_count, vertices, index_count, indices, pmovable->getParentNode()->_getDerivedPosition(), pmovable->getParentNode()->_getDerivedOrientation(), pmovable->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;
                    }
                }
            }

            // 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 = pmovable;
                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);
    }
}
コード例 #4
0
ファイル: OgreMeshRay.cpp プロジェクト: netzz/minemonics
/***************************************************************************//*!
 * @brief Raycast from a point in to the scene.
 * @param[in] point		Point to analyse
 * @param[in] normal		Direction
 * @param[out] result	Result ( ONLY if return TRUE )
 * @return TRUE if somethings found => {result} NOT EMPTY
 */
bool OgreMeshRay::raycastFromPoint(const Ogre::Vector3& point,
		const Ogre::Vector3& normal, Ogre::Vector3& result,
		std::string entityName) {
	// create the ray to test
	Ogre::Ray ray(point, normal);

	if (!m_raySceneQuery)
		return false;

	// create a query object
	m_raySceneQuery->setRay(ray);

	// execute the query, returns a vector of hits
	if (m_raySceneQuery->execute().size() <= 0) {
		// raycast did not hit an objects bounding box
		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;
	Ogre::Vector3 closest_result;
	Ogre::RaySceneQueryResult& query_result = m_raySceneQuery->getLastResults();
	for (size_t qr_idx = 0, size = query_result.size(); qr_idx < 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) {
			if (entityName != ""
					&& query_result[qr_idx].movable->getName() != entityName) {
				std::cout << query_result[qr_idx].movable->getName()
						<< "is not " << entityName << std::endl;
				continue;
			}
			std::cout << query_result[qr_idx].movable->getName() << "is truly "
					<< entityName << std::endl;
			const std::string& movableType =
					query_result[qr_idx].movable->getMovableType();
			// mesh data to retrieve
			size_t vertex_count;
			size_t index_count;
			Ogre::Vector3* vertices;
			unsigned long* indices;

			if (movableType == "ManualObject") {
				// get the entity to check
				Ogre::ManualObject* pentity =
						static_cast<Ogre::ManualObject*>(query_result[qr_idx].movable);
				// get the mesh information
				GetMeshInformation(pentity, vertex_count, vertices, index_count,
						indices,
						pentity->getParentNode()->_getDerivedPosition(),
						pentity->getParentNode()->_getDerivedOrientation(),
						pentity->getParentNode()->_getDerivedScale());
			} else if (movableType == "Entity") {
				// get the entity to check
				Ogre::Entity *pentity =
						static_cast<Ogre::Entity*>(query_result[qr_idx].movable);
				// get the mesh information
				GetMeshInformation(pentity, vertex_count, vertices, index_count,
						indices,
						pentity->getParentNode()->_getDerivedPosition(),
						pentity->getParentNode()->_getDerivedOrientation(),
						pentity->getParentNode()->_getDerivedScale());
			} else {
				continue;
			}

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

	// return the result
	if (closest_distance >= 0.0f) {
		// raycast success
		result = closest_result;
		return true;
	}
	// raycast failed
	return false;
}
コード例 #5
0
	bool CollisionTools::raycast(const Ogre::Ray &ray, Ogre::Vector3 &result,Ogre::MovableObject* &target,float &closest_distance, 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();

#if 0
		for (size_t qr_idx = 0; qr_idx < query_result.size(); qr_idx++)
		{
			const Ogre::RaySceneQueryResultEntry& result = query_result[qr_idx];
			Ogre::Real distance = result.distance;
			Ogre::MovableObject* movable = static_cast<Ogre::MovableObject*>(result.movable);
			Ogre::SceneQuery::WorldFragment* worldFragment = result.worldFragment;

			if (movable)
			{
				const Ogre::String& type = movable->getMovableType();
				const Ogre::String& name = movable->getName();
				const Ogre::String& parentName = movable->getParentNode()->getName();
				Ogre::uint32 flag = movable->getQueryFlags();  

				if (type.compare("Entity") == 0)
				{
					Ogre::Entity* ent =  (Ogre::Entity*)movable;
				}

				std::ostrstream oss;
				oss<<"name:"<<name<<" distance:"<< distance <<" type:"<<type<<" flag:"<<flag<<" parent:"<<parentName<<std::endl;
				OutputDebugString(oss.str() );
			}
		}

#endif

		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);

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

				// 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;
						}
					}
				}

				// 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);
				}
			}
		}

		// return the result
		if (closest_distance >= 0.0f)
		{
			// raycast success
			result = closest_result;
			return (true);
		}
		else
		{
			// raycast failed
			return (false);
		}
	}
コード例 #6
0
void CollisionDetection::addStaticTreeCollisionMesh( Entity *entity, string name)
{
    bool meshCreated = false;
    NewtonCollision *treeCollision;

    std::stringstream out;
    out << name;

    string fileString = ConstManager::getString("cmesh_file_path");
    fileString += out.str();
    fileString.append(".cmesh");
    cout << fileString<<endl;
    char *fileName = (char*) fileString.c_str();

    if( !gernerateMeshes )
    {
        FILE* meshFile;
        meshFile = fopen(fileName,"r");
        if (meshFile!=NULL)
        {
            treeCollision = NewtonCreateCollisionFromSerialization (newtonWorld, myDeserializeCollisionCallbackFunction, meshFile);
            fclose (meshFile);
            meshCreated = true;
        }
        else
        {
            cout << "Colision detection could not read file.\nAttempting to create mesh from scratch" << endl;
        }
    }

    if( !meshCreated )
    {
        treeCollision = NewtonCreateTreeCollision (newtonWorld, 0);
        NewtonTreeCollisionBeginBuild(treeCollision);

        size_t vertex_count;
        size_t index_count;
        Ogre::Vector3 *vertices;
        unsigned long *indices;

        GetMeshInformation(   entity->getMesh(), vertex_count, vertices, index_count, indices,
                              entity->getParentNode()->getPosition(),
                              entity->getParentNode()->getOrientation(),
                              entity->getParentNode()->_getDerivedScale());

    /*                               Ogre::Vector3(),
                                  Ogre::Quaternion::IDENTITY,
                                  Ogre::Vector3(1,1,1)); */
        dFloat vArray[9];
        int i0, i1, i2;
        for (int i = 0; i < static_cast<int>(index_count); i += 3)
        {
            i0 = indices[i];
            i1 = indices[i+1];
            i2 = indices[i+2];

            vArray[0] = vertices[i0].x;
            vArray[1] = vertices[i0].y;
            vArray[2] = vertices[i0].z;

            vArray[3] = vertices[i1].x;
            vArray[4] = vertices[i1].y;
            vArray[5] = vertices[i1].z;

            vArray[6] = vertices[i2].x;
            vArray[7] = vertices[i2].y;
            vArray[8] = vertices[i2].z;

             NewtonTreeCollisionAddFace(treeCollision, 3, vArray,
                        sizeof(dFloat)*3, i);
        }

        NewtonTreeCollisionEndBuild(treeCollision, 1);

        FILE* meshFile;
        meshFile = fopen(fileName,"w");
        if (meshFile!=NULL)
        {
            NewtonCollisionSerialize(newtonWorld, treeCollision, mySerializeCollisionCallbackFunction, meshFile);
            fclose (meshFile);
        }
        else
        {
            cout << "Colision detection could not write cmesh file." << endl;
        }
    }

    NewtonBody* rigidTree = NewtonCreateBody (newtonWorld, treeCollision);
    NewtonReleaseCollision (newtonWorld, treeCollision);

    NewtonBodySetMatrix (rigidTree, &idmatrix[0]);

    dFloat boxP0[3];
    dFloat boxP1[3];

    //possibly need this if we rely on newton
    //NewtonCollisionCalculateAABB (treeCollision, &idmatrix[0], &boxP0[0], &boxP1[0]);

    collisionsMap.insert(pair<Entity*,NewtonCollision*>(entity,treeCollision));
    bodysMap.insert(pair<Entity*,NewtonBody*>(entity,rigidTree));
}
コード例 #7
0
ファイル: UtilityFunctions.cpp プロジェクト: LiMuBei/ovise
Ogre::Entity* RaycastToPolygon( const Ogre::Real& x, const Ogre::Real& y,
	Ogre::RaySceneQuery* Query, Ogre::Camera* Camera )
{
	Ogre::Ray MouseRay = Camera->getCameraToViewportRay( x, y );
	Query->setRay( MouseRay );
	Query->setSortByDistance( true );

	Ogre::RaySceneQueryResult& QueryResult = Query->execute();

	if( QueryResult.size() == 0 )
	{
		return NULL;
	}

	// 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 ClosestDistance = -1.0f;
	Ogre::Entity* ClosestResult;

	for( size_t QRIndex = 0; QRIndex < QueryResult.size(); QRIndex++ ) 
	{ 
		// stop checking if we have found a raycast hit that is closer 
		// than all remaining entities 
		if( ( ClosestDistance >= 0.0f ) && 
			( ClosestDistance < QueryResult[QRIndex].distance ) )
			break; 
		
		// only check this result if its a hit against an entity 
		if( ( QueryResult[QRIndex].movable != NULL ) && 
			( QueryResult[QRIndex].movable->getMovableType().compare("Entity") == 0 ) &&
			QueryResult[QRIndex].movable->getName() != OVISE_SelectionBoxName ) 
		{ 
			// get the entity to check 
			Ogre::Entity* PEntity = static_cast<Ogre::Entity*>(QueryResult[QRIndex].movable);
			
			// mesh data to retrieve
			size_t VertexCount; 
			size_t IndexCount; 
			Ogre::Vector3* Vertices; 
			unsigned long* Indices;  
			
			// get the mesh information 
			GetMeshInformation( PEntity->getMesh(), 
				VertexCount, 
				Vertices, 
				IndexCount, 
				Indices, 
				PEntity->getParentSceneNode()->_getDerivedPosition(),
				PEntity->getParentSceneNode()->_getDerivedOrientation(), 
				PEntity->getParentSceneNode()->_getDerivedScale() );

			// test for hitting individual triangles on the mesh 
			bool NewClosestFound = false;
			if( IndexCount == 0 ) // no triangles, e.g. pointcloud
			{
				NewClosestFound = true;
				ClosestDistance = QueryResult[QRIndex].distance;
			}
			else
			{
				for( int i = 0; i < static_cast<int>(IndexCount); i += 3 ) 
				{ 
					// check for a hit against this triangle 
					std::pair<bool, Ogre::Real> Hit = 
						Ogre::Math::intersects( MouseRay, 
						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( ( ClosestDistance < 0.0f ) || 
							( Hit.second < ClosestDistance ) ) 
						{ 
							// this is the closest so far, save it off 
							ClosestDistance = Hit.second; 
							NewClosestFound = 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( NewClosestFound ) 
				ClosestResult = PEntity;
		}  
	}

	if( ClosestDistance < 0.0f ) 
	{
		// raycast failed 
		ClosestResult = NULL;
	}

	return ClosestResult;
}