Beispiel #1
0
TEST_F(SceneQueryTest, Ray) {
    RaySceneQuery* rayQuery = mSceneMgr->createRayQuery(mCamera->getCameraToViewportRay(0.5, 0.5));
    rayQuery->setSortByDistance(true, 2);

    RaySceneQueryResult& results = rayQuery->execute();

    ASSERT_EQ("501", results[0].movable->getName());
    ASSERT_EQ("397", results[1].movable->getName());
}
Beispiel #2
0
Item*
OrbitState::pickItem(int x, int y)
{
  Vector2 pickPos = rGUIManager()->getRelativeCursorPosition(x, y);
  Ray pickRay = orbitScreen->trackBallCamera->getCamera()->getCameraToViewportRay(pickPos[0], pickPos[1]);
  
  RaySceneQuery* query = orbitScreen->sceneManager->createRayQuery(pickRay, 0xFFFFFFFF);
  query->setSortByDistance(true);
  RaySceneQueryResult& intersections = query->execute();
  Item* pickedItem = NULL;
  float pickedDistance = FLT_MAX;
  for(RaySceneQueryResult::const_iterator objectI = intersections.begin(); objectI != intersections.end(); ++objectI) {
    RaySceneQueryResultEntry entry = *objectI;

    if(entry.distance > pickedDistance) return pickedItem;

    if(entry.movable != NULL) {
      if(entry.movable->isVisible() == false) continue;
      UserDefinedObject* userObject = entry.movable->getUserObject();
      // MovableObjects and Entities aren't dynamic so we can't know if we hit one. But we know UserObjects are only attached
      // to Entities.
      if(userObject != NULL) {
        Entity* entity = static_cast<Entity*>(entry.movable);
        Item* target = dynamic_cast<Item*>(userObject);
        if(target != NULL) {
          Real distance;
          if(CollisionManager::getSingleton().isIntersecting(pickRay, entity, distance) && distance < pickedDistance) {
            pickedItem = target;
            pickedDistance = distance;
          }
        }
      }
    }
  }
  return pickedItem;
}
	void ControllerInput::PerformMouseOver(int MouseX, int MouseY, bool IsClick)
	{
		// normalise mouse coordinates to [0,1]
        float scrx = (float)MouseX / (float)OgreClient::Singleton->Viewport->getActualWidth();
        float scry = (float)MouseY / (float)OgreClient::Singleton->Viewport->getActualHeight();

        // create ray & query                      
		Ray ray = OgreClient::Singleton->Camera->getCameraToViewportRay(scrx, scry);                       
		RaySceneQuery* query = OgreClient::Singleton->SceneManager->createRayQuery(ray, 0xFFFFFFFF);
        
		// make it also find billboards and sort by distance
		query->setQueryTypeMask(0xFFFFFFFF);
        query->setSortByDistance(true);

		// execute query
        RaySceneQueryResult result = query->execute();
			
		if (result.size() > 0)
		{
			List<unsigned int>^ objectIDs = gcnew List<unsigned int>(result.size());

			// iterate hits
			for(unsigned int i=0; i<result.size();i++)
			{
				// get next hit and its type
				RaySceneQueryResultEntry entry = result.at(i);
				::Ogre::String type = entry.movable->getMovableType();
				
				// we only care for types Entity (3d model) 
				// and billboards (2d model)
				if (type.compare("Entity") == 0 || 
					type.compare("BillboardSet") == 0)
				{
					// get name as CLR string
					::Ogre::String ostr = entry.movable->getName();
					System::String^ s = StringConvert::OgreToCLR(ostr);
                
					// try parse an id out of name string
					unsigned int objectid;
					System::UInt32::TryParse(s->Substring(s->LastIndexOf('/') + 1), objectid);
                       
					if (objectid > 0)	
					{
						RoomObject^ obj = OgreClient::Singleton->Data->RoomObjects->GetItemByID(objectid);

						// don't select own avatar by clicks
						if (obj != nullptr && !obj->IsAvatar)
						{
							objectIDs->Add(objectid);	
							
							// for mouseover we just need the first hit
							if (!IsClick)
								break;
						}
					}
				}
			}

			// reset mouseover object
			if (!IsClick)
				OgreClient::Singleton->Data->RoomObjects->ResetHighlighted();

			// execute target clicker or mouseover
			if (objectIDs->Count > 0)
			{		
				ControllerUI::MouseCursor->setImage(UI_MOUSECURSOR_TARGET);

				if (IsClick)				
					OgreClient::Singleton->Data->ClickTarget(objectIDs, !IsSelfTargetDown);
				
				else
					OgreClient::Singleton->Data->RoomObjects->HighlightObject(objectIDs[0]);				
			}
			else
			{
				ControllerUI::MouseCursor->setImage(UI_DEFAULTARROW);
			}
		}

		// cleanup query
		OgreClient::Singleton->SceneManager->destroyQuery(query);
	};
void WeaponTower::update( Crawler *closestEnemy, float dist , float dt, TowerGameApp *game )
{
	if (m_type == Type_NODULE)
	{
		// nodules dont do anything
		return;
	}
	

	// don't update if out of range or no bug
	ParticleEmitter *emitter = m_psys->getEmitter( 0 );
	if ((dist > m_sensorRange) || (!closestEnemy)) 
	{
		emitter->setEnabled( false );
		return;
	}

	// turn on the juice
	emitter->setEnabled( true );	

	// aim at the bug
	Vector3 myPos = m_platform->getPosition();
	Vector3 crawlerPos = closestEnemy->getNode()->getPosition();
	Vector3 dir = crawlerPos - myPos;
	dir.y = 0.0;
	dir.normalise();

	//Radian targetHeading = Ogre::Math::ATan2( dir.x, dir.z );	
	//m_bracket->yaw( targetHeading );
	m_bracket->setDirection( dir, Ogre::Node::TS_WORLD );

	dir = crawlerPos - (myPos + Vector3( 0.0, 7.0, 0.0));
	//float adj = sqrt((dir.x * dir.x) + ( dir.z * dir.z));
	//Radian angle = Ogre::Math::ATan2( dir.y, adj );
	//m_gun->pitch( angle, Ogre::Node::TS_LOCAL);
	m_gun->setDirection( dir, Ogre::Node::TS_WORLD );

	//game->mFrameListener->mDebugText = " blarg blarg";

	// Ok.. now actually apply damage	
	if (m_timeout < 0.001)
	{		

#if 0
		Ray shooty( m_gun->getWorldPosition(),
				m_gun->getWorldOrientation().zAxis() );
		RaySceneQuery *rayQuery = m_sceneMgr ->createRayQuery( shooty );
		rayQuery->setQueryMask( MASK_CRAWLER );

		RaySceneQueryResult &result = rayQuery->execute();
		RaySceneQueryResult::iterator itr = result.begin();

		/// did we hit a crawler
		game->mFrameListener->mDebugText = String("Hit Test: ");
		if (itr != result.end() && ( itr->movable))
        {
			game->mFrameListener->mDebugText += String(" movable: ") + itr->movable->getName();

			SceneNode *node = itr->movable->getParentSceneNode();
			if (node)
			{
				game->mFrameListener->mDebugText +=  node->getName();

				// did we hit a crawler??
				for (std::vector<Crawler*>::iterator ci = game->m_crawlers.begin();
					ci != game->m_crawlers.end(); ++ci )
				{
					if ( (*ci)->getNode() == node )
					{
						// hit!
						(*ci)->m_health -= m_damage;
					}
				}
			}
		}

		 m_sceneMgr->destroyQuery(rayQuery);
#endif

		 // forget all of that nonsense... just hit the
		 // closest crawler
		 if (m_type == Type_FLAMETHROWER)
		 {
			 // TODO: should be all enemies within range
			closestEnemy->m_health -= m_damage * dt;
		 }
		 else
		 {
			 closestEnemy->m_health -= m_damage;
		 }

		// reset timeout
		m_timeout = m_reloadTime;
	}
	else
	{
		// wait to 'recharge'
		m_timeout -= dt;
	}


}