Example #1
0
	void DefaultZone::_checkNodeAgainstPortals(PCZSceneNode * pczsn, Portal * ignorePortal)
	{
		if (pczsn == mEnclosureNode ||
			pczsn->allowedToVisit() == false)
		{
			// don't do any checking of enclosure node versus portals
			return;
		}

		PCZone * connectedZone;
        for ( PortalList::iterator it = mPortals.begin(); it != mPortals.end(); ++it )
        {
			Portal * p = *it;
			//Check if the portal intersects the node
			if (p != ignorePortal &&
				p->intersects(pczsn) != Portal::NO_INTERSECT)
			{
				// node is touching this portal
				connectedZone = p->getTargetZone();
				// add zone to the nodes visiting zone list unless it is the home zone of the node
				if (connectedZone != pczsn->getHomeZone() &&
					!pczsn->isVisitingZone(connectedZone))
				{
					pczsn->addZoneToVisitingZonesMap(connectedZone);
					// tell the connected zone that the node is visiting it
					connectedZone->_addNode(pczsn);
					//recurse into the connected zone
					connectedZone->_checkNodeAgainstPortals(pczsn, p->getTargetPortal());
				}
			}
        }
	}
Example #2
0
void World::shootPortal(int button) {
  //Shooting
  Vector3f cameraDir = Math::toDirection(scene->camera.rotation);

  //Find the closest intersection
  Entity closestWall;
  float intersection = INT_MAX;
  for (unsigned int i = 0; i < scene->walls.size(); i++) {
    Entity wall = scene->walls[i];
    Ray bullet = Ray(scene->camera.position, cameraDir);
    float tNear, tFar;
    if (bullet.collides(wall, &tNear, &tFar)) {
      if (wall.texture.handle == TextureLoader::getTexture("wall.png").handle) {
        if (tNear < intersection) {
          closestWall = wall;
          intersection = tNear;
        }
      }
    }
  }

  BoxCollider wall(closestWall.position, closestWall.scale);
  Vector3f ipos = scene->camera.position + (cameraDir * intersection);
  Portal portal;
  portal.placeOnWall(wall, ipos);

  if (button == 1) {
    portal.texture = TextureLoader::getTexture("blueportal.png");
    scene->bluePortal = portal;
  } else {
    portal.texture = TextureLoader::getTexture("orangeportal.png");
    scene->orangePortal = portal;
  }
}
Example #3
0
void handleCamera(Camera * camera)
{
	vec3 oldCameraPos = camera->getPosition();

	vec3 move(glfwGetKey('D')-glfwGetKey('A'),0,glfwGetKey('S')-glfwGetKey('W'));
	move *= 0.1f;
	camera->move(move);

	vec3 newCameraPos = camera->getPosition();

	vec2 lookVec(	glfwGetKey(GLFW_KEY_LEFT)-glfwGetKey(GLFW_KEY_RIGHT),
					glfwGetKey(GLFW_KEY_UP)-glfwGetKey(GLFW_KEY_DOWN));
	camera->rotateY(lookVec.x * 2.0);

	// Handle portaling :)
	Module * currentModule = camera->getOwnerModule();
	std::vector<Portal*> portals = currentModule->getPortals();

	for(u32 i=0; i<portals.size(); ++i)
	{
		Portal * portal = portals[i];

		if( intersectLinePortal(oldCameraPos, newCameraPos, *portal) )
		{
			camera->getOwnerModule()->removeGameObject(camera);
			portal->getTargetPortal()->getOwnerModule()->addGameObject(camera);

			camera->setTransform(portal->getInvViewMatrix(camera));
		}
	}
}
Example #4
0
void Portal::transportBall(Ball &ball, Portal &portal)
{
	int nextX = portal.getXPos();
	int nextY = portal.getYPos();
	ball.setXPos(nextX);
	ball.setYPos(nextY);
}
	// delete a portal instance by pointer
	void PCZSceneManager::destroyPortal(Portal * p)
	{
		// remove the portal from it's target portal
		Portal * targetPortal = p->getTargetPortal();
		if (targetPortal)
		{
			targetPortal->setTargetPortal(0); // the targetPortal will still have targetZone value, but targetPortal will be invalid
		}
		// remove the Portal from it's home zone
		PCZone * homeZone = p->getCurrentHomeZone();
		if (homeZone)
		{
			// inform zone of portal change. Do here since PCZone is abstract 
			homeZone->setPortalsUpdated(true);   
			homeZone->_removePortal(p);
		}

		// remove the portal from the master portal list
		PortalList::iterator it = std::find( mPortals.begin(), mPortals.end(), p );
		if (it != mPortals.end())
		{
			mPortals.erase(it);
		}
		// delete the portal instance
		OGRE_DELETE p;
	}
	// Create a portal instance
	Portal* PCZSceneManager::createPortal(const String& name, PortalBase::PORTAL_TYPE type)
	{
		Portal* newPortal = OGRE_NEW Portal(name, type);
		newPortal->_notifyCreator(Root::getSingleton().getMovableObjectFactory("Portal"));
		newPortal->_notifyManager(this);
		mPortals.push_front(newPortal);
		return newPortal;
	}
Example #7
0
//---------------------------------------------------------------------------------------
void    Portal::Split(Plane& plane, Portal& a, Portal& b)
{
    a.CopyProps(*this);
    b.CopyProps(*this);


    if((_n == plane._n && _c == plane._c) ||
        (_n == -plane._n && _c == -plane._c) )
    {
#ifdef WINDOWS
#   pragma message("see this")
#endif
        a._vxes = _vxes;
        b._vxes = _vxes;
        return;
    }

    v3d_t  iv;
    v3d_t itxB = *_vxes.begin();
    v3d_t itxA = _vxes.back();

    f32_t    fB;
    f32_t	fA = plane.DistTo(itxA);

    FOREACH(vvector<v3d_t>, _vxes, vxI)
    {
        itxB = *vxI;
        fB   = plane.DistTo(itxB);
        if(fB > GEpsilon)
        {
            if(fA < -GEpsilon)
            {
                f32_t   t = -fA /(fB - fA);
                iv.interpolate(itxA,itxB,t);
                a._vxes << iv;
                b._vxes << iv;
            }
            a._vxes<<itxB;
        }
        else if(fB < -GEpsilon)
        {
            if(fA > GEpsilon)
            {
                f32_t t = -fA /(fB - fA);           // t of segment
                iv.interpolate(itxA,itxB,t);
                a._vxes <<iv;
                b._vxes <<iv;
            }
            b._vxes<<itxB;
        }
        else
        {
            a._vxes << itxB;
            b._vxes << itxB;
        }
        itxA = itxB;
        fA   = fB;
    }
Example #8
0
Portal* Portal::create(Stage* _stage) {
	Portal* ret = new (std::nothrow) Portal();
	if (ret &&ret->init(_stage))
	{
		ret->autorelease();
		return ret;
	}
	CC_SAFE_DELETE(ret);
	return nullptr;
}
Example #9
0
void Sector::render(Portal *portal) {
	
	if(frame == Engine::frame) return;
	frame = Engine::frame;
	
	this->portal = portal;
	Bsp::visible_sectors[Bsp::num_visible_sectors++] = this;
	
	num_visible_objects = 0;
	
	root->render();
	
	for(int i = 0; i < num_objects; i++) {
		Object *o = objects[i];
		if(o->frame == Engine::frame) continue;
		if(Engine::frustum->inside(o->pos + o->getCenter(),o->getRadius())) {
			Engine::num_triangles += o->render(Object::RENDER_OPACITY);
			visible_objects[num_visible_objects++] = o;
		}
	}
	
	for(int i = 0; i < num_portals; i++) {
		Portal *p = &Bsp::portals[portals[i]];
		if(p->frame == Engine::frame) continue;
		p->frame = Engine::frame;
		if(Engine::frustum->inside(p->center,p->radius)) {
			float dist = (Engine::camera - p->center).length();
			
			if(Engine::have_occlusion && dist > p->radius) {
				
				if(Material::old_material) Material::old_material->disable();
				
				glDisable(GL_CULL_FACE);
				glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
				glDepthMask(GL_FALSE);
				glBeginQueryARB(GL_SAMPLES_PASSED_ARB,Engine::query_id);
				p->render();
				glEndQueryARB(GL_SAMPLES_PASSED_ARB);
				glDepthMask(GL_TRUE);
				glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
				glEnable(GL_CULL_FACE);
					
				GLuint samples;
				glGetQueryObjectuivARB(Engine::query_id,GL_QUERY_RESULT_ARB,&samples);
				if(samples == 0) continue;
			}
			
			if(dist > p->radius) Engine::frustum->addPortal(Engine::camera,p->points);
			for(int j = 0; j < p->num_sectors; j++) {
				Bsp::sectors[p->sectors[j]].render(dist > p->radius ? p : NULL);
			}
			if(dist > p->radius) Engine::frustum->removePortal();
		}
	}
}
Example #10
0
    /* The following function checks if a node has left it's current home zone.
	* This is done by checking each portal in the zone.  If the node has crossed
	* the portal, then the current zone is no longer the home zone of the node.  The
	* function then recurses into the connected zones.  Once a zone is found where
	* the node does NOT cross out through a portal, that zone is the new home zone.
	NOTE: For this function to work, the node must start out in the proper zone to
	      begin with!
	*/
    PCZone* DefaultZone::updateNodeHomeZone( PCZSceneNode * pczsn, bool allowBackTouches )
    {
		// default to newHomeZone being the current home zone
		PCZone * newHomeZone = pczsn->getHomeZone();

		// Check all portals of the start zone for crossings!
		Portal* portal;
		PortalList::iterator pi, piend;
		piend = mPortals.end();
		for (pi = mPortals.begin(); pi != piend; pi++)
		{
			portal = *pi;

			Portal::PortalIntersectResult pir = portal->intersects(pczsn);
			switch (pir)
			{
			default:
			case Portal::NO_INTERSECT: // node does not intersect portal - do nothing
			case Portal::INTERSECT_NO_CROSS:// node intersects but does not cross portal - do nothing				
				break;
			case Portal::INTERSECT_BACK_NO_CROSS:// node intersects but on the back of the portal
				if (allowBackTouches)
				{
					// node is on wrong side of the portal - fix if we're allowing backside touches
					if (portal->getTargetZone() != this &&
						portal->getTargetZone() != pczsn->getHomeZone())
					{
						// set the home zone of the node to the target zone of the portal
						pczsn->setHomeZone(portal->getTargetZone());
						// continue checking for portal crossings in the new zone
						newHomeZone = portal->getTargetZone()->updateNodeHomeZone(pczsn, false);
					}
				}
				break;
			case Portal::INTERSECT_CROSS:
				// node intersects and crosses the portal - recurse into that zone as new home zone
				if (portal->getTargetZone() != this &&
					portal->getTargetZone() != pczsn->getHomeZone())
				{
					// set the home zone of the node to the target zone of the portal
					pczsn->setHomeZone(portal->getTargetZone());
					// continue checking for portal crossings in the new zone
					newHomeZone = portal->getTargetZone()->updateNodeHomeZone(pczsn, true);
				}
				break;
			}
		}

		// return the new home zone
		return newHomeZone;

    }
Example #11
0
//=================================================================================================
void Location::Save(GameWriter& f, bool)
{
	f << type;
	f << pos;
	f << name;
	f << state;
	int refid;
	if(active_quest)
	{
		if(active_quest == (Quest_Dungeon*)ACTIVE_QUEST_HOLDER)
			refid = ACTIVE_QUEST_HOLDER;
		else
			refid = active_quest->refid;
	}
	else
		refid = -1;
	f << refid;
	f << last_visit;
	f << st;
	f << outside;
	f << reset;
	f << spawn;
	f << dont_clean;
	f << seed;
	f << image;

	// portals
	Portal* p = portal;
	while(p)
	{
		f.Write1();
		p->Save(f);
		p = p->next_portal;
	}
	f.Write0();

	// events
	f << events.size();
	for(Event& e : events)
	{
		f << e.type;
		f << e.quest->refid;
	}
}
long Portal::dist(Portal &p) const
{
    //Om de är i samma grupp
    if (p.group->id == this->group->id)
    {
        //Om du ska hitta avtåndet i en cykel
        if (group->type == 1)
        {
            if (p.i() < i())
                return group->high - i() + 1 + p.i() - group->low;
            else
                return p.i() - i();
        }
        
        //Avståndet i en gren
        if (group->type == 2)
        {
            if (p.in(group) && p.i() > i())
                return p.i() - i();
            else
                return -1;
        }
        
        
    }
    else
    {
        
        //Om det finns en väg mellan de två nodernas grupper
        if (group->merge.find(p.group->id) != group->merge.end())
        {
            //Om noden har en index högre än där grenen ansluter till dens grupp
            if (portals[group->merge[p.group->id].first].i() <= p.i())
            {
                return group->high - i() + 1 + group->merge[p.group->id].second + p.i() - portals[group->merge[p.group->id].first].i();
            }
            else if (p.group->type == 1)
            {
                return group->high - i() + 1 + group->merge[p.group->id].second + p.group->high - portals[group->merge[p.group->id].first].i() + p.i() - p.group->low + 1;
            }
            
        }
        else
            return -1;
        
    }
    
    
    return -1;
}
Example #13
0
void SoundEvent::visitRoom(Room *room, double strength) {

    strength *= room->eventMultiplier(GameEventType::Sound);

    if (strength >= 0.1) {
        for (const GameObjectPtr &characterPtr : room->characters()) {
            if (excludedCharacters().contains(characterPtr)) {
                continue;
            }

            Character *character = characterPtr.cast<Character *>();
            QString message = descriptionForStrengthAndCharacterInRoom(strength, character, room);
            if (character->isPlayer()) {
                character->send(message);
            } else {
                character->invokeTrigger("onsound", message);
            }

            addAffectedCharacter(characterPtr);
        }

        for (const GameObjectPtr &portalPtr : room->portals()) {
            Portal *portal = portalPtr.cast<Portal *>();
            Room *room1 = portal->room().unsafeCast<Room *>();
            Room *room2 = portal->room2().unsafeCast<Room *>();
            Room *oppositeRoom = (room == room1 ? room2 : room1);
            if (hasBeenVisited(oppositeRoom) || !portal->canHearThrough()) {
                continue;
            }

            double propagatedStrength = strength * portal->eventMultiplier(GameEventType::Sound);
            if (propagatedStrength >= 0.1) {
                addVisit(oppositeRoom, propagatedStrength);
            }
        }
    }
}
	/* Attempt to automatically connect unconnected portals to proper target zones 
		* by looking for matching portals in other zones which are at the same location
		*/
	void PCZSceneManager::connectPortalsToTargetZonesByLocation(void)
	{
		// go through every zone to find portals
		ZoneMap::iterator i, iend;
		PCZone* zone;
		iend = mZones.end();
		bool foundMatch;
		for (i = mZones.begin(); i != iend; i++)
		{
			zone = i->second;
			// go through all the portals in the zone
			Portal* portal;
			PortalList::iterator pi, piend;
			piend = zone->mPortals.end();
			for (pi = zone->mPortals.begin(); pi != piend; pi++)
			{
				portal = *pi;
				//portal->updateDerivedValues();
				if (portal->getTargetZone() == 0)
				{
					// this is a portal without a connected zone - look for 
					// a matching portal in another zone
					PCZone* zone2;
					ZoneMap::iterator j= mZones.begin();
					foundMatch = false;
					while (!foundMatch && j != mZones.end())
					{
						zone2 = j->second;
						if (zone2 != zone) // make sure we don't look in the same zone
						{
							Portal * portal2 = zone2->findMatchingPortal(portal);
							if (portal2)
							{
								// found a match!
								Ogre::LogManager::getSingletonPtr()->logMessage("Connecting portal "+portal->getName()+" to portal "+portal2->getName());
								foundMatch = true;
								portal->setTargetZone(zone2);
								portal->setTargetPortal(portal2);
								portal2->setTargetZone(zone);
								portal2->setTargetPortal(portal);
							}
						}
						j++;
					}
					if (foundMatch == false)
					{
						// error, didn't find a matching portal!
						OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, 
							"Could not find matching portal for portal " + portal->getName(), 
							"PCZSceneManager::connectPortalsToTargetZonesByLocation");

					}
				}
			}			
		}
	}
	// delete a portal instance by pointer
	void PCZSceneManager::destroyPortal(const String & portalName)
	{
		// find the portal from the master portal list
		Portal * p;
		Portal * thePortal = 0;
		PortalList::iterator it = mPortals.begin();
		while (it != mPortals.end())
		{
			p = *it;
			if (p->getName() == portalName)
			{
				thePortal = p;
				// erase entry in the master list
				mPortals.erase(it);
				break;
			}
			it++;
		}
		if (thePortal)
		{
			// remove the portal from it's target portal
			Portal * targetPortal = thePortal->getTargetPortal();
			if (targetPortal)
			{
				targetPortal->setTargetPortal(0); // the targetPortal will still have targetZone value, but targetPortal will be invalid
			}
			// remove the Portal from it's home zone
			PCZone * homeZone = thePortal->getCurrentHomeZone();
			if (homeZone)
			{
				// inform zone of portal change 
				homeZone->setPortalsUpdated(true);   
				homeZone->_removePortal(thePortal);
			}

			// delete the portal instance
			OGRE_DELETE thePortal;
		}
	}
//Skapa den nya datastrukturen med grupper
//Varje nod besöks 1 gång O(N)
//a = noden som skall besökas, low = lägsta noden (ny index) som besökts (början på en gren)
inline Group * rec(long a, const long & low)
{
    Portal * p = &portals[a];
    
    //Om noden inte har fått en ny index
    if (p->i() == 0) {
        //Ge en ny index
        p->new_index = first++;
        
        Group * g = rec(p->exit, low);
        
        //Om vi ansluter till en cykel
        if (g->type == 1)
        {
            //Om den nuvarande noden finns i cykeln
            if (p->in(g))
            {
                //sätt nodens grupp till cykelns
                return p->group = g;
                
            }
            else
            {
                //Annars skapa en gren
                p->group->type = 2;
                p->group->merge[portals[p->exit].group->id] = make_pair(p->exit, 0);
                p->group->low = low;
                p->group->high = p->new_index;
                
                return p->group;
            }
            
            
        }
        else
        {
            //Om numret inte finns i den nuvarande grenen
            if (!p->in(g)) {
                //_(Optimering)_
                //Om du ansluter en nod i början av grenen
                if (portals[p->exit].i() == g->low)
                {
                    //Flytta upp noderna i grenens index så att de nu är över den nuvarande nodens index
                    g->add += (p->i() - g->low) + 1;
                    g->high += (p->i() - g->low) + 1;
                    
                    first = g->high + 1;
                    p->new_index -= g->add;
                    g->low = low;
                }else
                {
                    //Om den nya noden ansluter mitt på grenen skapa en ny gren.
                    p->group->type = 2;
                    //Hämta avtånde och anslutningsinformation från överliggadne gren
                    for (auto item : g->merge)
                        p->group->merge[item.first] = make_pair(item.second.first, item.second.second + g->high - portals[p->exit].i() + 1);
                    
                    p->group->merge[g->id] = make_pair(p->exit, 0);
                    p->group->low = low;
                    p->group->high = p->new_index;
                    
                    return p->group;
                }
            }
            else
            {
                //Om noden finns på grenen justera dens index
                p->new_index -= g->add;
            }
            
            return p->group = g;
            
        }
        
    }
    else
    {
        //Om noden är besökt men inte har en grupp
        if (p->group->type == 0)
        {
            //Skapa en cykel
            p->group->type = 1;
            p->group->low = p->i();
            p->group->high = first - 1;
            
            return p->group;
            
        }
        else
        {
            return p->group;
        }
    }
    
}
Example #17
0
    void DefaultZone::_findNodes( const Ray &t, 
							      PCZSceneNodeList &list, 
                                  PortalList &visitedPortals,
						 	      bool includeVisitors,
							      bool recurseThruPortals,
							      PCZSceneNode *exclude )
    {
		// if this zone has an enclosure, check against the enclosure AABB first
		if (mEnclosureNode)
		{
			std::pair<bool, Real> nsect = t.intersects(mEnclosureNode->_getWorldAABB());
			if (!nsect.first)
			{
				// AABB of zone does not intersect t, just return.
				return;
			}
		}

		// check nodes at home in this zone
	    PCZSceneNodeList::iterator it = mHomeNodeList.begin();
	    while ( it != mHomeNodeList.end() )
	    {
			PCZSceneNode * pczsn = *it;
			if ( pczsn != exclude )
			{
				// make sure node is not already in the list (might have been added in another
				// zone it was visiting)
				PCZSceneNodeList::iterator it2 = list.find(pczsn);
				if (it2 == list.end())
				{
					std::pair<bool, Real> nsect = t.intersects( pczsn -> _getWorldAABB() );
					if ( nsect.first )
					{
						list.insert( pczsn );
					}
				}
			}
		    ++it;
	    }

		if (includeVisitors)
		{
			// check visitor nodes
			PCZSceneNodeList::iterator iter = mVisitorNodeList.begin();
			while ( iter != mVisitorNodeList.end() )
			{
				PCZSceneNode * pczsn = *iter;
				if ( pczsn != exclude )
				{
					// make sure node is not already in the list (might have been added in another
					// zone it was visiting)
					PCZSceneNodeList::iterator it2 = list.find(pczsn);
					if (it2 == list.end())
					{
						std::pair<bool, Real> nsect = t.intersects( pczsn -> _getWorldAABB() );
						if ( nsect.first )
						{
							list.insert( pczsn );
						}
					}
				}
				++iter;
			}
		}

		// if asked to, recurse through portals
		if (recurseThruPortals)
		{
			PortalList::iterator pit = mPortals.begin();
			while ( pit != mPortals.end() )
			{
				Portal * portal = *pit;
				// check portal versus bounding box
				if (portal->intersects(t))
				{
					// make sure portal hasn't already been recursed through
					PortalList::iterator pit2 = std::find(visitedPortals.begin(), visitedPortals.end(), portal);
					if (pit2 == visitedPortals.end())
					{
						// save portal to the visitedPortals list
						visitedPortals.push_front(portal);
						// recurse into the connected zone 
						portal->getTargetZone()->_findNodes(t, 
															list, 
															visitedPortals,
															includeVisitors, 
															recurseThruPortals, 
															exclude);
					}
				}
				pit++;
			}
		}

	}
Example #18
0
    /*
    // Recursively walk the zones, adding all visible SceneNodes to the list of visible nodes.
    */
    void DefaultZone::findVisibleNodes(PCZCamera *camera, 
								  NodeList & visibleNodeList,
								  RenderQueue * queue,
								  VisibleObjectsBoundsInfo* visibleBounds, 
								  bool onlyShadowCasters,
								  bool displayNodes,
								  bool showBoundingBoxes)
    {

        //return immediately if nothing is in the zone.
		if (mHomeNodeList.size() == 0 &&
			mVisitorNodeList.size() == 0 &&
			mPortals.size() == 0)
            return ;

        // Else, the zone is automatically assumed to be visible since either
		// it is the camera the zone is in, or it was reached because
		// a connecting portal was deemed visible to the camera.  

		// enable sky if called to do so for this zone
		if (mHasSky)
		{
			// enable sky 
			mPCZSM->enableSky(true);
		}

		// find visible nodes at home in the zone
        bool vis;
        PCZSceneNodeList::iterator it = mHomeNodeList.begin();
        while ( it != mHomeNodeList.end() )
        {
			PCZSceneNode * pczsn = *it;
            // if the scene node is already visible, then we can skip it
            if (pczsn->getLastVisibleFrame() != mLastVisibleFrame ||
				pczsn->getLastVisibleFromCamera() != camera)
            {
				// for a scene node, check visibility using AABB
				vis = camera ->isVisible( pczsn -> _getWorldAABB() );
				if ( vis )
				{
					// add it to the list of visible nodes
					visibleNodeList.push_back( pczsn );
					// add the node to the render queue
					pczsn -> _addToRenderQueue(camera, queue, onlyShadowCasters, visibleBounds );
					// if we are displaying nodes, add the node renderable to the queue
					if ( displayNodes )
					{
						queue -> addRenderable( pczsn->getDebugRenderable() );
					}
					// if the scene manager or the node wants the bounding box shown, add it to the queue
					if (pczsn->getShowBoundingBox() || showBoundingBoxes)
					{
						pczsn->_addBoundingBoxToQueue(queue);
					}
					// flag the node as being visible this frame
					pczsn->setLastVisibleFrame(mLastVisibleFrame);
					pczsn->setLastVisibleFromCamera(camera);
				}
            }
            ++it;
        }
		// find visible visitor nodes
        it = mVisitorNodeList.begin();
        while ( it != mVisitorNodeList.end() )
        {
			PCZSceneNode * pczsn = *it;
            // if the scene node is already visible, then we can skip it
            if (pczsn->getLastVisibleFrame() != mLastVisibleFrame ||
				pczsn->getLastVisibleFromCamera() != camera)
            {
				// for a scene node, check visibility using AABB
				vis = camera ->isVisible( pczsn -> _getWorldAABB() );
				if ( vis )
				{
					// add it to the list of visible nodes
					visibleNodeList.push_back( pczsn );
					// add the node to the render queue
					pczsn->_addToRenderQueue(camera, queue, onlyShadowCasters, visibleBounds );
					// if we are displaying nodes, add the node renderable to the queue
					if ( displayNodes )
					{
						queue -> addRenderable( pczsn->getDebugRenderable() );
					}
					// if the scene manager or the node wants the bounding box shown, add it to the queue
					if (pczsn->getShowBoundingBox() || showBoundingBoxes)
					{
						pczsn->_addBoundingBoxToQueue(queue);
					}
					// flag the node as being visible this frame
					pczsn->setLastVisibleFrame(mLastVisibleFrame);
					pczsn->setLastVisibleFromCamera(camera);
				}
            }
            ++it;
        }

		// Here we merge both portal and antiportal visible to the camera into one list.
		// Then we sort them in the order from nearest to furthest from camera.
		PortalBaseList sortedPortalList;
		for (AntiPortalList::iterator iter = mAntiPortals.begin(); iter != mAntiPortals.end(); ++iter)
		{
			AntiPortal* portal = *iter;
			if (camera->isVisible(portal))
			{
				sortedPortalList.push_back(portal);
			}
		}
		for (PortalList::iterator iter = mPortals.begin(); iter != mPortals.end(); ++iter)
		{
			Portal* portal = *iter;
			if (camera->isVisible(portal))
			{
				sortedPortalList.push_back(portal);
			}
		}
		const Vector3& cameraOrigin(camera->getDerivedPosition());
		std::sort(sortedPortalList.begin(), sortedPortalList.end(),
			PortalSortDistance(cameraOrigin));

		// create a standalone frustum for anti portal use.
		// we're doing this instead of using camera because we don't need
		// to do camera frustum check again.
		PCZFrustum antiPortalFrustum;
		antiPortalFrustum.setOrigin(cameraOrigin);
		antiPortalFrustum.setProjectionType(camera->getProjectionType());

		// now we do culling check and remove hidden portals.
		// whenever we get a portal in the main loop, we can be sure that it is not
		// occluded by AntiPortal. So we do traversal right there and then.
		// This is because the portal list has been sorted.
		size_t sortedPortalListCount = sortedPortalList.size();
		for (size_t i = 0; i < sortedPortalListCount; ++i)
		{
			PortalBase* portalBase = sortedPortalList[i];
			if (!portalBase) continue; // skip removed portal.

			if (portalBase->getTypeFlags() == PortalFactory::FACTORY_TYPE_FLAG)
			{
				Portal* portal = static_cast<Portal*>(portalBase);
				// portal is visible. Add the portal as extra culling planes to camera
				int planes_added = camera->addPortalCullingPlanes(portal);
				// tell target zone it's visible this frame
				portal->getTargetZone()->setLastVisibleFrame(mLastVisibleFrame);
				portal->getTargetZone()->setLastVisibleFromCamera(camera);
				// recurse into the connected zone 
				portal->getTargetZone()->findVisibleNodes(camera,
														  visibleNodeList,
														  queue,
														  visibleBounds,
														  onlyShadowCasters,
														  displayNodes,
														  showBoundingBoxes);
				if (planes_added > 0)
				{
					// Then remove the extra culling planes added before going to the next portal in the list.
					camera->removePortalCullingPlanes(portal);
				}
			}
			else if (i < sortedPortalListCount) // skip antiportal test if it is the last item in the list.
			{
				// this is an anti portal. So we use it to test preceding portals in the list.
				AntiPortal* antiPortal = static_cast<AntiPortal*>(portalBase);
				int planes_added = antiPortalFrustum.addPortalCullingPlanes(antiPortal);

				for (size_t j = i + 1; j < sortedPortalListCount; ++j)
				{
					PortalBase* otherPortal = sortedPortalList[j];
					// Since this is an antiportal, we are doing the inverse of the test.
					// Here if the portal is fully visible in the anti portal fustrum, it means it's hidden.
					if (otherPortal && antiPortalFrustum.isFullyVisible(otherPortal))
						sortedPortalList[j] = NULL;
				}

				if (planes_added > 0)
				{
					// Then remove the extra culling planes added before going to the next portal in the list.
					antiPortalFrustum.removePortalCullingPlanes(antiPortal);
				}
			}
		}
	}
Example #19
0
bool Portal::_setBackSidePassable( void* object, const char* index, const char* data )
{
   Portal* portal = reinterpret_cast< Portal* >( object );
   portal->setSidePassable( Portal::BackSide, EngineUnmarshallData< bool >()( data ) );
   return false;
}
Example #20
0
void FunctionalPortal::createEnvironmentMap(const std::vector<Portal *> *portals){
	Portal *destPortal = (*portals)[iDestPortal];
	Vec3 portalPos = destPortal->getPos();
	Vec3 eyePos;
	vecAdd(&destPos_pcoord, &portalPos, &eyePos);

	bool oldHide = isHidden();
	setHide(true);

	GL_CHECK(glMatrixMode(GL_MODELVIEW));
	GL_CHECK(glPushMatrix());
	GL_CHECK(glMatrixMode(GL_PROJECTION));
	GL_CHECK(glPushMatrix());
	GL_CHECK(glPushAttrib(GL_VIEWPORT_BIT));

	//GL_CHECK(glBindTexture(GL_TEXTURE_2D, 0));
	tgr->bind();
	//GL_CHECK(glBindTexture(GL_TEXTURE_2D, dstDepthmap));
	//GL_CHECK(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
	//GL_TEXTURE_2D, dstDepthmap, 0));
	/*GLuint id = renderTgr->genColorTexutre();
	glFramebufferTexture2DEXT(
        GL_FRAMEBUFFER_EXT,
        GL_COLOR_ATTACHMENT0_EXT,
        GL_TEXTURE_2D,
        id,
        0);
		struct MAZErectangle viewport;
	viewport.left = 0;
	viewport.bottom = 0;
	viewport.width = width;
	viewport.height = height;
	struct Vec3 centerPos = vec2vecAdd(&eyePos, 0, 0, -10);
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		gluLookAt(eyePos.x, eyePos.y, eyePos.z, 
				centerPos.x, centerPos.y, centerPos.z,
				0, 1, 0);
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		struct MAZEmat projviewMat;
		struct MAZEmat viewportMat;

		getWindowProjMat(viewport, projviewMat, viewportMat);

		hash_set<int *> visitedEdgeSet;
		destPortal->cullDraw(&projviewMat, &viewportMat, viewport, 
							portals, visitedEdgeSet);
		
		glBindTexture(GL_TEXTURE_2D, id);
		//debug
	sf::Uint8 *pixelArray = new sf::Uint8[width*height*4];
	glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelArray); // to read from texture instead
	sf::Image temp(width, height, pixelArray);
	std::string filename = "envmap";
	//char a[2] = {'a'+i, '\0'};
	//filename.append(a);
	filename.append(".jpg");
	temp.SaveToFile(filename);
	return;*/

	glMatrixMode(GL_PROJECTION);
	GLfloat aspectRatio = 1.;
    GLfloat nearClip = 0.1f;
    GLfloat farClip = 400.0f;
    GLfloat fieldOfView = 90.0f; // Degrees

    glLoadIdentity();
    gluPerspective(fieldOfView, aspectRatio, nearClip, farClip);
	glViewport(0, 0, width, height);

	float lookVectors[24] = {
		1, 0, 0, 1,
		-1, 0, 0, 1,
		0, 1, 0, 1,
		0, -1, 0, 1,
		0, 0, 1, 1,
		0, 0, -1, 1
	};
	
	float up[24] = {
		0, -1, 0, 1,
		0, -1, 0, 1,
		0, 0, 1, 1,
		0, 0, -1, 1,
		0, -1, 0, 1,
		0, -1, 0, 1
	};

	struct MAZErectangle viewport;
	viewport.left = 0;
	viewport.bottom = 0;
	viewport.width = width;
	viewport.height = height;
	GL_CHECK(glBindTexture(GL_TEXTURE_CUBE_MAP, dstCubemap));
	struct Vec3 centerPos = vec2vecAdd(&eyePos, 
										lookVectors[direction*4], 
										lookVectors[direction*4+1], 
										lookVectors[direction*4+2]);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	GL_CHECK(gluLookAt(eyePos.x, eyePos.y, eyePos.z, 
				centerPos.x, centerPos.y, centerPos.z,
				up[direction*4], up[direction*4+1], up[direction*4+2]));
	GL_CHECK(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
	GL_TEXTURE_CUBE_MAP_POSITIVE_X+src_lookDirection, dstCubemap, 0));
	/*if(GL_FRAMEBUFFER_COMPLETE_EXT != glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT)){
		cerr << "Invalid framebuffer configuration: ERROR CODE " 
			<< glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
		exit(-1);
	}*/
	GL_CHECK(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
	struct MAZEmat projviewMat;
	struct MAZEmat viewportMat;

	getWindowProjMat(viewport, projviewMat, viewportMat);

	set<int *> visitedEdgeSet;
	cout << "here1" <<endl;
	destPortal->cullDraw(&projviewMat, &viewportMat, viewport, 
						portals, visitedEdgeSet);
		
	//GL_CHECK(glBindTexture(GL_TEXTURE_CUBE_MAP, dstCubemap));
	/*	//debug
	sf::Uint8 *pixelArray = new sf::Uint8[width*height*4];
	glGetTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X+src_lookDirection, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelArray); // to read from texture instead
	sf::Image temp(width, height, pixelArray);
	std::string filename = "envmap";
	char a[2] = {'a'+src_lookDirection, '\0'};
	filename.append(a);
	filename.append(".jpg");
	temp.SaveToFile(filename);
	delete pixelArray;*/

	glMatrixMode(GL_MODELVIEW);
	glPopMatrix();
	glMatrixMode(GL_PROJECTION);
	glPopMatrix();
	glPopAttrib();
	tgr->unbind();

	setHide(oldHide);
}
Example #21
0
bool Portal::cullDraw(struct MAZEmat *projviewMat, struct MAZEmat *viewportMat, 
					struct MAZErectangle &rec, const std::vector<Portal *> *portals, set<int *> &visitedEdgeSet){
	MAZEmat finalProjViewMat;
	multMat(projviewMat, &transformation, &finalProjViewMat);

	//TODO: implement BV for objects
	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	//glMultMatrixf(transformation.mat);
	if(!portalObj->isHidden())
		portalObj->draw(portals);
	for(int i=0; i<objs.size(); i++)
		if(!objs[i]->isHidden())
			objs[i]->draw(portals);

	glMatrixMode(GL_MODELVIEW);
	glPopMatrix();
	
	//What this portal looks like in its neighbors eye...
	int posMap[4] = {1, 0, 3, 2};

	for(int i=0; i<4; i++){
		if(neighbors[i] < 0)
			continue;

		//Have we visited this undirected edge? 
		//I know the following code seems a little hack
		//but I can't find any better way...
		Portal *port = (*portals)[neighbors[i]];
		if(visitedEdgeSet.count(port->getNeighbors()+posMap[i]) > 0 || 
			visitedEdgeSet.count(neighbors+i))
			continue;
		//int size1 = visitedEdgeSet.size();
		visitedEdgeSet.insert(neighbors+i);
		//int size2 = visitedEdgeSet.size();
		/*if(size2 == size1){
			cout << "not right" << endl;
		}*/
		//assert(visitedEdgeSet.size()<4*(*portals).size());
		//cout<<"visitedEdge " << visitedEdgeSet.size() << endl;
		struct Vec3 p[4];
		float left = MY_FLT_MAX, right = MY_FLT_MIN, top = MY_FLT_MIN, bottom = MY_FLT_MAX;
		float nearC = MY_FLT_MAX, farC = MY_FLT_MIN;
		for(int j=0; j<4; j++){
			struct Vec3 tmp;
			matMultVec3_normalize(&finalProjViewMat, &doorPoints[i][j], &tmp);
			matMultVec3_normalize(viewportMat, &tmp, p+j);
			if(p[j].x < left)
				left = p[j].x;
			if(p[j].x > right)
				right = p[j].x;

			if(p[j].y > top)
				top = p[j].y;
			if(p[j].y < bottom)
				bottom = p[j].y;

			if(p[j].z < nearC)
				nearC = p[j].z;

			if(p[j].z > farC)
				farC = p[j].z;
		}
		if(farC < 0 || nearC > 1)
			continue;

		left = left > rec.left ? left : rec.left;
		right = right < (rec.left+rec.width) ? right : rec.left+rec.width;
		bottom = bottom > rec.bottom ? bottom : rec.bottom;
		top = top < (rec.bottom + rec.height) ? top : rec.bottom+rec.height;
		MAZErectangle neighborRect;
		neighborRect.left = left;
		neighborRect.bottom = bottom;
		neighborRect.height = top-bottom;
		neighborRect.width = right-left;
		//This is necessary for edge condition
		if(neighborRect.height <= -1e-5 || neighborRect.width <= -1e-5)
			continue;
		
		//Door status switched. If it is open from this cell to its
		//neighbor, we might visit that neighbor. When we are visiting
		//the neighbor, we will close the door and would not visit this
		//cell. Is it still possible that we might loop back to visited portal?
		//If the door is open, visit it.
		//NOTE: Theorectically it's possible that a single object in a cell
		//can be rendered several times from different doors. TODO: I might add some
		//mask to handle this problem in the future. But, for this maze game,
		//this scenario seems unlikely. So ignore it for now.
		port->cullDraw(projviewMat, viewportMat, neighborRect, portals, visitedEdgeSet);
	}
	return true;
}
void Hero::update()
{
	if (mySpawnPortal)
	{
		mySpawnPortalFrameCounter++;
		if (mySpawnPortalFrameCounter == 1)
		{
			Portal* portal = new Portal();
			portal->setPosition(getPosition());
			getRoom()->addEntity(portal);
			return;
		}
		else if (mySpawnPortalFrameCounter >= 60 * 5)
		{
			mySpawnPortal = false;
		}
		else 
		{
			return;
		}
	}

	if (myIsDead)
		return;

	Entity::update();
	mFramesSinceLandPlayed++;

	if (mGravityHitTimer <= 0){
		mGravityDirection=1;
	} else {
		mGravityHitTimer--;
	}

	if (touchesDangerousTile())
	{
		die();
	}
	//checkEnemies();

	if (mSpawnPoint.x < -100 && mSpawnPoint.y < -100)
	{
		mSpawnPoint = getPosition();
	}

	float acceleration = mOnGround ? GROUND_ACCELERATION : AIR_ACCELERATION;
	
	if (Input::isHeld(Button_Left)) {
		mVelocity.x -= acceleration;
		mFacingDirection = Direction_Left;
	}

	if (Input::isHeld(Button_Right)) {
		mVelocity.x += acceleration;
		mFacingDirection = Direction_Right;
	}

	if(Input::isPressed(Button_Fire) && GameState::getInt(GameState::POWERUP_GRENADE) != 0){
		mWeaponSelected = Weapon_Gravity_Grenade;
		fireWeapon();
	}

	if(Input::isPressed(Button_ToggleWeapon) && GameState::getInt(GameState::POWERUP_GUN) != 0){
		mWeaponSelected = Weapon_Gun;
		fireWeapon();
	}

	mVelocity.x = clamp(mVelocity.x, -MAX_X_VELOCITY, MAX_X_VELOCITY);
	
	if (Input::isPressed(Button_Jump)) {
		mJumpPrepressed = true;
	}

	if (mOnGround && mJumpPrepressed) {
		Sound::playSample("data/sounds/jump.wav");
		mVelocity.y = GameState::getInt(GameState::POWERUP_HIJUMP) ? -HI_JUMP_VELOCITY : -JUMP_VELOCITY;
		mJumpHeld = true;
		mJumpPrepressed = false;
	}

	if (Input::isReleased(Button_Jump)) {
		if (mJumpHeld && mVelocity.y < 0) {
			mVelocity.y *= 0.5f;
		}

		mJumpHeld = false;
		mJumpPrepressed = false;
	}

	if (mVelocity.y >= 0) {
		mJumpHeld = false;
	}

	mMovementState = MovementState_Still;
	
	if (mOnGround) {
		if (abs(mVelocity.x) > GROUND_STOP_VELOCITY)
		{
			mMovementState = MovementState_Run;
		}
	}
	else
	{
		if (mVelocity.y < 0) {
			mMovementState = MovementState_Jump;
		} else {
			mMovementState = MovementState_Fall;
		}
	}
	
	if (mMovementState == MovementState_Still)
	{
		mVelocity.x = 0;
	}

	bool ground = moveOutOfSolidEntities();

	float2 usedVelocity(mVelocity.x, clamp(mVelocity.y, -MAX_Y_VELOCITY, MAX_Y_VELOCITY));
	unsigned int bumps = moveWithCollision(usedVelocity / Time::TicksPerSecond);
	
	if ((bumps & (Direction_Left | Direction_Right)) != 0) {
		mVelocity.x = 0;
	}

	if ((bumps & (Direction_Up | Direction_Down)) != 0) {
		mVelocity.y = 0;
	}

	float gravity = mJumpHeld ? JUMP_GRAVITY : GRAVITY;
	mVelocity.y += gravity * getGravityDirection();
	ground |= ((bumps & Direction_Down) != 0);
	if (ground && !mOnGround)
	{
		if (mFramesSinceLandPlayed > 6)
		{
			Sound::playSample("data/sounds/land.wav");
		}
		mFramesSinceLandPlayed = 0;
	}
	mOnGround = ground;

	float drag = mOnGround ? GROUND_DRAG : AIR_DRAG;
	mVelocity *= drag;

	mFrame ++;
	if (mBlinkingTicksLeft)
	{
		mBlinkingTicksLeft --;
	}
}
Example #23
0
void Camera::Update()
{
  //float dt = TheTimer::Instance()->GetDt();
  Vec3f pos;

  if (m_target)
  {
    pos = m_target->GetPos();

    // yRotAuto = 0;
#ifdef AUTO_ROTATE
    // Swing behind target
    float dir = m_target->GetDir() + 180.0f;
    float angleDiff = yRotAuto - dir;

    // Rotate to face m_dir, taking the shortest route (CW or CCW)
    if (fabs(angleDiff) < 0.1f) // TODO CONFIG
    {
      yRotAuto  = dir;
    }
    else
    {
      float ROT_SPEED = 1.0f; // TODO CONFIG
      if (yRotAuto > dir)
      {
        yRotAuto -= ROT_SPEED * dt * fabs(angleDiff);
      }
      else if (yRotAuto < dir)
      {
        yRotAuto += ROT_SPEED * dt * fabs(angleDiff);
      }
    }
#endif // AUTO_ROTATE

#ifdef PORTAL_ROTATE
    // TODO Get closest portal
    static PGameObject lastportal = 0;
    // We want to get the closest portal to the target, even if they have never intersected it.
    int pid = m_target->GetIgnorePortalId();
    if (pid > -1)
    {
      lastportal = TheGame::Instance()->GetGameObject(pid);
    }
    else
    {
      // Look for portals in this room, find closest.
      // TODO Optimise
      // just check periodically ?
      Portals portals = GetPortals();
      float bestSqDist = 999999.9f;
      for (Portals::iterator it = portals.begin(); it != portals.end(); ++it)
      {
        Portal* p = *it;
        float sqDist = (p->GetPos() - pos).SqLen();
        if (sqDist < bestSqDist)
        {
          bestSqDist = sqDist;
          lastportal = p;
        }
      } 
    }
    
    if (lastportal)
    {
      float pdist = (pos - lastportal->GetPos()).SqLen(); // sq dist from portal to player
      static const float MAX_DIST = ROConfig()->GetFloat("portal-max-dist", 200.0f); 
      static const float MAX_SQ_DIST = MAX_DIST * MAX_DIST; 
      if (pdist < MAX_SQ_DIST) 
      {
        yRotAuto = atan2(-pos.x, pos.z) * (1.0f - pdist / MAX_SQ_DIST); 

//std::cout << "SQ Dist from portal: " << pdist << " pos.z=" << pos.z << " pos.x=" << pos.x << " yRotAuto degs=" << RadToDeg(yRotAuto) << "\n";
      }
    }
#endif // PORTAL_ROTATE
  }
  else
  {
    pos = posNoTarget; 
  }
  pos += posOffset;

  float y = DegToRad(yRotAuto + yRotUser); 

  SetEyePos(Vec3f(
    pos.x + sin(y) * cos(xRot) * zDist, 
    pos.y + sin(xRot) * zDist, 
    pos.z + cos(y) * cos(xRot) * zDist));

  SetLookAtPos(pos);
}
Example #24
0
void CommandInterpreter::execute(Character *character, const QString &_command) {

    static QRegExp whitespace("\\s+");

    try {
        QString command = _command.trimmed();
        LogUtil::logCommand(character->name(), command);

        QStringList words = command.split(whitespace);
        QString commandName = words[0].toLower();
        if (commandName.isEmpty()) {
            return;
        }

        if (Util::isDirectionAbbreviation(commandName)) {
            words[0] = Util::direction(commandName);
            commandName = words[0];
        }
        if (Util::isDirection(commandName)) {
            words.prepend("go");
            m_registry->command("go")->execute(character, words.join(" "));
            return;
        } else {
            Room *currentRoom = character->currentRoom().cast<Room *>();
            bool matchedPortal = false;
            for (const GameObjectPtr &portalPtr : currentRoom->portals()) {
                Portal *portal = portalPtr.cast<Portal *>();
                QString portalName = portal->nameFromRoom(character->currentRoom());
                if (portalName == commandName) {
                    matchedPortal = true;
                } else {
                    for (const QString &portalNamePart : portalName.split(' ')) {
                        if (portalNamePart == commandName) {
                            matchedPortal = true;
                        }
                    }
                }
            }
            if (matchedPortal) {
                words.prepend("go");
                m_registry->command("go")->execute(character, words.join(" "));
                return;
            }
        }

        QStringList commands;

        if (m_registry->contains(commandName)) {
            m_registry->command(commandName)->execute(character, command);
            return;
        } else {
            for (const QString &name : m_registry->commandNames()) {
                if (name.startsWith(commandName)) {
                    commands.append(name);
                }
            }
        }

        if (character->isPlayer() && qobject_cast<Player *>(character)->isAdmin()) {
            if (commandName.startsWith("api-")) {
                if (m_registry->apiCommandsContains(commandName)) {
                    m_registry->apiCommand(commandName)->execute(character, command);
                    return;
                }
            } else {
                if (m_registry->adminCommandsContains(commandName)) {
                    m_registry->adminCommand(commandName)->execute(character, command);
                    return;
                } else {
                    for (const QString &name : m_registry->adminCommandNames()) {
                        if (name.startsWith(commandName)) {
                            commands.append(name);
                        }
                    }
                }
            }
        }

        if (commands.length() == 1) {
            commandName = commands[0];
            if (m_registry->contains(commandName)) {
                m_registry->command(commandName)->execute(character, command);
            } else if (m_registry->adminCommandsContains(commandName)) {
                m_registry->adminCommand(commandName)->execute(character, command);
            }
        } else if (commands.length() > 1) {
            character->send("Command is not unique.");
        } else {
            character->send(QString("Command \"%1\" does not exist.").arg(words[0]));
        }
    } catch (GameException &exception) {
        if (character->isPlayer()) {
            Player *player = qobject_cast<Player *>(character);
            player->send(QString("Executing the command gave an exception: ") + exception.what());
            if (!player->isAdmin()) {
                player->send("This is not good. You may want to contact a game admin about this.");
            }
        }
    } catch (...) {
        if (character->isPlayer()) {
            Player *player = qobject_cast<Player *>(character);
            player->send("Executing the command gave an unknown exception.");
            if (!player->isAdmin()) {
                player->send("This is not good. You may want to contact a game admin about this.");
            }
        }
    }
}
Example #25
0
Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh>,Ref<Shape> > &collision_map,uint32_t p_flags,Set<Ref<ImageTexture> >& image_map) {

	// children first..
	for(int i=0;i<p_node->get_child_count();i++) {


		Node *r = _fix_node(p_node->get_child(i),p_root,collision_map,p_flags,image_map);
		if (!r) {
			print_line("was erased..");
			i--; //was erased
		}
	}

	String name = p_node->get_name();

	bool isroot = p_node==p_root;


	if (!isroot && p_flags&SCENE_FLAG_REMOVE_NOIMP && _teststr(name,"noimp")) {

		memdelete(p_node);
		return NULL;
	}

	{

		List<PropertyInfo> pl;
		p_node->get_property_list(&pl);
		for(List<PropertyInfo>::Element *E=pl.front();E;E=E->next()) {

			if (E->get().type==Variant::OBJECT || E->get().type==Variant::ARRAY || E->get().type==Variant::DICTIONARY) {
				_find_resources(p_node->get(E->get().name),image_map);
			}
		}

	}




	if (p_flags&SCENE_FLAG_CREATE_BILLBOARDS && p_node->cast_to<MeshInstance>()) {

		MeshInstance *mi = p_node->cast_to<MeshInstance>();

		bool bb=false;

		if ((_teststr(name,"bb"))) {
			bb=true;
		} else if (mi->get_mesh().is_valid() && (_teststr(mi->get_mesh()->get_name(),"bb"))) {
			bb=true;

		}

		if (bb) {
			mi->set_flag(GeometryInstance::FLAG_BILLBOARD,true);
			if (mi->get_mesh().is_valid()) {

				Ref<Mesh> m = mi->get_mesh();
				for(int i=0;i<m->get_surface_count();i++) {

					Ref<FixedMaterial> fm = m->surface_get_material(i);
					if (fm.is_valid()) {
						fm->set_flag(Material::FLAG_UNSHADED,true);
						fm->set_flag(Material::FLAG_DOUBLE_SIDED,true);
						fm->set_hint(Material::HINT_NO_DEPTH_DRAW,true);
						fm->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA,true);
					}
				}
			}
		}
	}

	if (p_flags&SCENE_FLAG_REMOVE_NOIMP && p_node->cast_to<AnimationPlayer>()) {
		//remove animations referencing non-importable nodes
		AnimationPlayer *ap = p_node->cast_to<AnimationPlayer>();

		List<StringName> anims;
		ap->get_animation_list(&anims);
		for(List<StringName>::Element *E=anims.front();E;E=E->next()) {

			Ref<Animation> anim=ap->get_animation(E->get());
			ERR_CONTINUE(anim.is_null());
			for(int i=0;i<anim->get_track_count();i++) {
				NodePath path = anim->track_get_path(i);

				for(int j=0;j<path.get_name_count();j++) {
					String node = path.get_name(j);
					if (_teststr(node,"noimp")) {
						anim->remove_track(i);
						i--;
						break;
					}
				}
			}

		}
	}


	if (p_flags&SCENE_FLAG_CREATE_IMPOSTORS && p_node->cast_to<MeshInstance>()) {

		MeshInstance *mi = p_node->cast_to<MeshInstance>();

		String str;

		if ((_teststr(name,"imp"))) {
			str=name;
		} else if (mi->get_mesh().is_valid() && (_teststr(mi->get_mesh()->get_name(),"imp"))) {
			str=mi->get_mesh()->get_name();

		}


		if (p_node->get_parent() && p_node->get_parent()->cast_to<MeshInstance>()) {
			MeshInstance *mi = p_node->cast_to<MeshInstance>();
			MeshInstance *mip = p_node->get_parent()->cast_to<MeshInstance>();
			String d=str.substr(str.find("imp")+3,str.length());
			if (d!="") {
				if ((d[0]<'0' || d[0]>'9'))
					d=d.substr(1,d.length());
				if (d.length() && d[0]>='0' && d[0]<='9') {
					float dist = d.to_double();
					mi->set_flag(GeometryInstance::FLAG_BILLBOARD,true);
					mi->set_flag(GeometryInstance::FLAG_BILLBOARD_FIX_Y,true);
					mi->set_draw_range_begin(dist);
					mi->set_draw_range_end(100000);

					mip->set_draw_range_begin(0);
					mip->set_draw_range_end(dist);

					if (mi->get_mesh().is_valid()) {

						Ref<Mesh> m = mi->get_mesh();
						for(int i=0;i<m->get_surface_count();i++) {

							Ref<FixedMaterial> fm = m->surface_get_material(i);
							if (fm.is_valid()) {
								fm->set_flag(Material::FLAG_UNSHADED,true);
								fm->set_flag(Material::FLAG_DOUBLE_SIDED,true);
								fm->set_hint(Material::HINT_NO_DEPTH_DRAW,true);
								fm->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA,true);
							}
						}
					}
				}
			}
		}
	}

    if (p_flags&SCENE_FLAG_CREATE_LODS && p_node->cast_to<MeshInstance>()) {

	MeshInstance *mi = p_node->cast_to<MeshInstance>();

	String str;

	if ((_teststr(name,"lod"))) {
	    str=name;
	} else if (mi->get_mesh().is_valid() && (_teststr(mi->get_mesh()->get_name(),"lod"))) {
	    str=mi->get_mesh()->get_name();

	}


	if (p_node->get_parent() && p_node->get_parent()->cast_to<MeshInstance>()) {
	    MeshInstance *mi = p_node->cast_to<MeshInstance>();
	    MeshInstance *mip = p_node->get_parent()->cast_to<MeshInstance>();
	    String d=str.substr(str.find("lod")+3,str.length());
	    if (d!="") {
		if ((d[0]<'0' || d[0]>'9'))
		    d=d.substr(1,d.length());
		if (d.length() && d[0]>='0' && d[0]<='9') {
		    float dist = d.to_double();
		    mi->set_draw_range_begin(dist);
		    mi->set_draw_range_end(100000);

		    mip->set_draw_range_begin(0);
		    mip->set_draw_range_end(dist);

		    /*if (mi->get_mesh().is_valid()) {

			Ref<Mesh> m = mi->get_mesh();
			for(int i=0;i<m->get_surface_count();i++) {

			    Ref<FixedMaterial> fm = m->surface_get_material(i);
			    if (fm.is_valid()) {
				fm->set_flag(Material::FLAG_UNSHADED,true);
				fm->set_flag(Material::FLAG_DOUBLE_SIDED,true);
				fm->set_hint(Material::HINT_NO_DEPTH_DRAW,true);
				fm->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA,true);
			    }
			}
		    }*/
		}
	    }
	}
    }
	if (p_flags&SCENE_FLAG_CREATE_COLLISIONS && _teststr(name,"colonly") && p_node->cast_to<MeshInstance>()) {

		if (isroot)
			return p_node;

		MeshInstance *mi = p_node->cast_to<MeshInstance>();
		Node * col = mi->create_trimesh_collision_node();

		ERR_FAIL_COND_V(!col,NULL);
		col->set_name(_fixstr(name,"colonly"));
		col->cast_to<Spatial>()->set_transform(mi->get_transform());
		p_node->replace_by(col);
		memdelete(p_node);
		p_node=col;

	} else if (p_flags&SCENE_FLAG_CREATE_COLLISIONS &&_teststr(name,"col") && p_node->cast_to<MeshInstance>()) {


		MeshInstance *mi = p_node->cast_to<MeshInstance>();

		mi->set_name(_fixstr(name,"col"));
		mi->create_trimesh_collision();
	} else if (p_flags&SCENE_FLAG_CREATE_ROOMS && _teststr(name,"room") && p_node->cast_to<MeshInstance>()) {


		if (isroot)
			return p_node;

		MeshInstance *mi = p_node->cast_to<MeshInstance>();
		DVector<Face3> faces = mi->get_faces(VisualInstance::FACES_SOLID);


		BSP_Tree bsptree(faces);

		Ref<RoomBounds> area = memnew( RoomBounds );
		area->set_bounds(faces);
		area->set_geometry_hint(faces);


		Room * room = memnew( Room );
		room->set_name(_fixstr(name,"room"));
		room->set_transform(mi->get_transform());
		room->set_room(area);

		p_node->replace_by(room);
		memdelete(p_node);
		p_node=room;

	} else if (p_flags&SCENE_FLAG_CREATE_ROOMS &&_teststr(name,"room")) {

		if (isroot)
			return p_node;

		Spatial *dummy = p_node->cast_to<Spatial>();
		ERR_FAIL_COND_V(!dummy,NULL);

		Room * room = memnew( Room );
		room->set_name(_fixstr(name,"room"));
		room->set_transform(dummy->get_transform());

		p_node->replace_by(room);
		memdelete(p_node);
		p_node=room;

		room->compute_room_from_subtree();

	} else if (p_flags&SCENE_FLAG_CREATE_PORTALS &&_teststr(name,"portal") && p_node->cast_to<MeshInstance>()) {

		if (isroot)
			return p_node;

		MeshInstance *mi = p_node->cast_to<MeshInstance>();
		DVector<Face3> faces = mi->get_faces(VisualInstance::FACES_SOLID);

		ERR_FAIL_COND_V(faces.size()==0,NULL);
		//step 1 compute the plane
		Set<Vector3> points;
		Plane plane;

		Vector3 center;

		for(int i=0;i<faces.size();i++) {

			Face3 f = faces.get(i);
			Plane p = f.get_plane();
			plane.normal+=p.normal;
			plane.d+=p.d;

			for(int i=0;i<3;i++) {

				Vector3 v = f.vertex[i].snapped(0.01);
				if (!points.has(v)) {
					points.insert(v);
					center+=v;
				}
			}
		}

		plane.normal.normalize();
		plane.d/=faces.size();
		center/=points.size();

		//step 2, create points

		Transform t;
		t.basis.from_z(plane.normal);
		t.basis.transpose();
		t.origin=center;

		Vector<Point2> portal_points;

		for(Set<Vector3>::Element *E=points.front();E;E=E->next()) {

			Vector3 local = t.xform_inv(E->get());
			portal_points.push_back(Point2(local.x,local.y));
		}
		// step 3 bubbly sort points

		int swaps=0;

		do {
			swaps=0;

			for(int i=0;i<portal_points.size()-1;i++) {

				float a = portal_points[i].atan2();
				float b = portal_points[i+1].atan2();

				if (a>b) {
					SWAP( portal_points[i], portal_points[i+1] );
					swaps++;
				}

			}

		} while(swaps);


		Portal *portal = memnew( Portal );

		portal->set_shape(portal_points);
		portal->set_transform( mi->get_transform() * t);

		p_node->replace_by(portal);
		memdelete(p_node);
		p_node=portal;

	} else if (p_node->cast_to<MeshInstance>()) {

		//last attempt, maybe collision insde the mesh data

		MeshInstance *mi = p_node->cast_to<MeshInstance>();

		Ref<Mesh> mesh = mi->get_mesh();
		if (!mesh.is_null()) {

			if (p_flags&SCENE_FLAG_CREATE_COLLISIONS && _teststr(mesh->get_name(),"col")) {

				mesh->set_name( _fixstr(mesh->get_name(),"col") );
				Ref<Shape> shape;

				if (collision_map.has(mesh)) {
					shape = collision_map[mesh];

				} else {

					shape = mesh->create_trimesh_shape();
					if (!shape.is_null())
						collision_map[mesh]=shape;


				}

				if (!shape.is_null()) {
#if 0
					StaticBody* static_body = memnew( StaticBody );
					ERR_FAIL_COND_V(!static_body,NULL);
					static_body->set_name( String(mesh->get_name()) + "_col" );
					shape->set_name(static_body->get_name());
					static_body->add_shape(shape);

					mi->add_child(static_body);
					if (mi->get_owner())
						static_body->set_owner( mi->get_owner() );
#endif
				}

			}

			for(int i=0;i<mesh->get_surface_count();i++) {

				Ref<FixedMaterial> fm = mesh->surface_get_material(i);
				if (fm.is_valid()) {
					String name = fm->get_name();
					if (_teststr(name,"alpha")) {
						fm->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA,true);
						name=_fixstr(name,"alpha");
					}

					if (_teststr(name,"vcol")) {
						fm->set_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY,true);
						name=_fixstr(name,"vcol");
					}
					fm->set_name(name);
				}
			}

		}

	}




	return p_node;
}
void physics(Game *g)
{
	g->mouseThrustOn=false;

	//ball collision
	if(gameStarted){
		ball.setYVel(ball.getYVel());
		ball.setXVel(ball.getXVel());
		obstacle->setYVel(obstacle->getYVel());
		bool is_ball_hit_edge = ball.checkCollision(xres, yres);
		if (is_ball_hit_edge){
			lastPaddleHit = 'N';
		}
	}


	//paddle collision
	bool isLeftHit = paddle1.checkCollision(yres, ball);
	if (isLeftHit){
		lastPaddleHit = 'L';        
	}
	bool isRightHit = paddle2.checkCollision(yres, ball);
	if (isRightHit){
		lastPaddleHit = 'R';        
	}

	if(level == 2){
		obstacle->checkCollision(xres, yres, ball, p1);
	}


	//paddle1 movement
	paddle1.setYVel(paddle1YVel);

	//paddle2 movement
	paddle2.setYVel(paddle2YVel);

	if (level == 1 && hud->isPaused()==false){
		//SET BOMBS POSITION:         
		bomb_theta = bomb_theta + speed_theta;
		if (fabs(bomb_theta) >= 2*PI){
			bomb_theta=0;
			speed_theta *= -1;
		}
		bomb_posx=(int)(xres/2 + bomb_radius*cos(bomb_theta - PI/2) - bomb_width/2);
		bomb_posy=(int)(yres/2 + bomb_radius*sin(bomb_theta - PI/2) - bomb_height/2);

		//CHECK LEFT COLLISION WITH BOMB:
		if ((beginSmallLeftPaddle + smallLeftPaddleTime) < time(NULL)){
			paddle1.setHeight(100.0f);
			bool isBallBetweenX = (ball.getXPos() > bomb_posx) && (ball.getXPos() < (bomb_posx + bomb_width));
			bool isBallBetweenY = (ball.getYPos() > bomb_posy) && (ball.getYPos() < (bomb_posy + bomb_height));
			if (lastPaddleHit == 'L' && (isBallBetweenX && isBallBetweenY)){
				bombBegin = time(NULL);
				createSound(8);
				createSound(9);
				//set to half normal height:            
				paddle1.setHeight(60.0f);
				if (hud->getPlayer1Health()>0){
					hud->setPlayer1Health(hud->getPlayer1Health()-10*(1+random(8)));
					//GAMEOVER:
					if (hud->getPlayer1Health() <= 0){
						createSound(5);
						is_gameover = true;
						ball.setXVel(0.0f);
						ball.setYVel(0.0f);
						stopGame();
					}
				}
				beginSmallLeftPaddle = time(NULL);
			}
		}

		//CHECK RIGHT COLLISION WITH BOMB:
		if ((beginSmallRightPaddle + smallRightPaddleTime) < time(NULL)){
			paddle2.setHeight(100.0f);
			//is_bomb_visible = true;
			bool isBallBetweenX = (ball.getXPos() > bomb_posx) && (ball.getXPos() < (bomb_posx + bomb_width));
			bool isBallBetweenY = (ball.getYPos() > bomb_posy) && (ball.getYPos() < (bomb_posy + bomb_height));
			if (lastPaddleHit == 'R' && (isBallBetweenX && isBallBetweenY)){
				bombBegin = time(NULL);
				createSound(8);
				createSound(9);
				//is_bomb_visible = false;
				//set to half normal height:
				paddle2.setHeight(60.0f);
				if (hud->getPlayer2Health()>0){
					hud->setPlayer2Health(hud->getPlayer2Health()- 10*(1+random(8)));
					//GAMEOVER:
					if (hud->getPlayer2Health() <= 0){
						createSound(5);
						is_gameover = true;
						ball.setXVel(0.0f);
						ball.setYVel(0.0f);
						stopGame();
					}
				}
				beginSmallRightPaddle = time(NULL);
			}
		}
		if(ball.getXPos() >= (xres/2)){
			portal1.checkCollision(ball, portal0);
		} else {
			portal0.checkCollision(ball, portal1);
		}
	}//end if level 1 and not paused


}
void init(Game *g) {
	portal0.setPortalType(0);
	portal1.setPortalType(1);
	g->mouseThrustOn=false;
}
Example #28
0
    /** (recursive) check the given light against all portals in the zone
    * NOTE: This is the default implementation, which doesn't take advantage
    *       of any zone-specific optimizations for checking portal visibility
    */
    void DefaultZone::_checkLightAgainstPortals(PCZLight *light, 
                                                unsigned long frameCount, 
                                                PCZFrustum *portalFrustum,
                                                Portal * ignorePortal)
    {
		for ( PortalList::iterator it = mPortals.begin(); it != mPortals.end(); ++it )
		{
			Portal * p = *it;
            if (p != ignorePortal)
            {
                // calculate the direction vector from light to portal
                Vector3 lightToPortal = p->getDerivedCP() - light->getDerivedPosition();
                if (portalFrustum->isVisible(p))
                {
                    // portal is facing the light, but some light types need to
                    // check illumination radius too.
                    PCZone * targetZone = p->getTargetZone();
                    switch(light->getType())
                    {
                    case Light::LT_POINT:
                        // point lights - just check if within illumination range
                        if (lightToPortal.length() <= light->getAttenuationRange())
                        {
 							// if portal is quad portal it must be pointing towards the light 
							if ((p->getType() == Portal::PORTAL_TYPE_QUAD && lightToPortal.dotProduct(p->getDerivedDirection()) < 0.0) ||
								(p->getType() != Portal::PORTAL_TYPE_QUAD))
							{
								if (!light->affectsZone(targetZone))
								{
									light->addZoneToAffectedZonesList(targetZone);
									if (targetZone->getLastVisibleFrame() == frameCount)
									{
										light->setAffectsVisibleZone(true);
									}
									// set culling frustum from the portal
									portalFrustum->addPortalCullingPlanes(p);
									// recurse into the target zone of the portal
									p->getTargetZone()->_checkLightAgainstPortals(light, 
																				frameCount, 
																				portalFrustum,
																				p->getTargetPortal());
									// remove the planes added by this portal
									portalFrustum->removePortalCullingPlanes(p);
								}
							}
                        }
                        break;
                    case Light::LT_DIRECTIONAL:
                        // directionals have infinite range, so just make sure
                        // the direction is facing the portal
                        if (lightToPortal.dotProduct(light->getDerivedDirection()) >= 0.0)
                        {
 							// if portal is quad portal it must be pointing towards the light 
							if ((p->getType() == Portal::PORTAL_TYPE_QUAD && lightToPortal.dotProduct(p->getDerivedDirection()) < 0.0) ||
								(p->getType() != Portal::PORTAL_TYPE_QUAD))
							{
								if (!light->affectsZone(targetZone))
								{
									light->addZoneToAffectedZonesList(targetZone);
									if (targetZone->getLastVisibleFrame() == frameCount)
									{
										light->setAffectsVisibleZone(true);
									}
									// set culling frustum from the portal
									portalFrustum->addPortalCullingPlanes(p);
									// recurse into the target zone of the portal
									p->getTargetZone()->_checkLightAgainstPortals(light, 
																				frameCount, 
																				portalFrustum,
																				p->getTargetPortal());
									// remove the planes added by this portal
									portalFrustum->removePortalCullingPlanes(p);
								}
							}
                        }
                        break;
                    case Light::LT_SPOTLIGHT:
                        // spotlights - just check if within illumination range
                        // Technically, we should check if the portal is within
                        // the cone of illumination, but for now, we'll leave that
                        // as a future optimisation.
                        if (lightToPortal.length() <= light->getAttenuationRange())
                        {
 							// if portal is quad portal it must be pointing towards the light 
							if ((p->getType() == Portal::PORTAL_TYPE_QUAD && lightToPortal.dotProduct(p->getDerivedDirection()) < 0.0) ||
								(p->getType() != Portal::PORTAL_TYPE_QUAD))
							{
								if (!light->affectsZone(targetZone))
								{
									light->addZoneToAffectedZonesList(targetZone);
									if (targetZone->getLastVisibleFrame() == frameCount)
									{
										light->setAffectsVisibleZone(true);
									}
									// set culling frustum from the portal
									portalFrustum->addPortalCullingPlanes(p);
									// recurse into the target zone of the portal
									p->getTargetZone()->_checkLightAgainstPortals(light, 
																				frameCount, 
																				portalFrustum,
																				p->getTargetPortal());
									// remove the planes added by this portal
									portalFrustum->removePortalCullingPlanes(p);
								}
							}
                        }
                        break;
                    }
                }
            }
        }           
    }
void render(Game *g)
{        
	g->mouseThrustOn=false;    
	glClear(GL_COLOR_BUFFER_BIT);
	if(intro < 1) {
		char screen;
		if (selected_screen == LEFT){
			screen = 'L';
		}
		else{
			screen = 'R';
		}
		if (hud->isShowWelcome() == true){
			hud->showIntro(screen,introTexture, bgTexture1, bgTexture2);
			if (hud->getAI() == true){
				hud->selectAI();
			}
			else{
				hud->selectHuman();
			}
			return;
		}
		else if (hud->isShowHelpMenu() == true){
			hud->showHelpMenu(helpMenuTexture);
			return;
		}
		return;
	}
	else{
		renderTexture(bgTexture, xres, yres);
	}

	if (is_gameover){
		renderTexture(gameOverTexture, xres, yres);
		high_score = setHighScore(ball.getPlayer1Score(), ball.getPlayer2Score());
		//cout << "Final Score : " << high_score << "\n";
		hud->showGameOver(high_score,ball.getPlayer1Score(), ball.getPlayer2Score());
		return;
	}

	hud->showScore(ball.getPlayer1Score(), ball.getPlayer2Score());
	hud->showHealth(hud->getPlayer1Health(), hud->getPlayer2Health());
	hud->showCourtYard();

	//DRAW BOMB:
	if (level == 1){

		GLuint which_bomb_texture = bombTexture;
		if ((bombBegin + 2) > time(NULL)){
			which_bomb_texture = explodeTexture;
		}
		else{
			which_bomb_texture = bombTexture;
		}

		portal0.render(portalTexture0);
		portal1.render(portalTexture1);


		hud->renderBomb(which_bomb_texture,bomb_posx,bomb_posy,bomb_width,bomb_height);
	}

	//Draw the paddle
	glColor3f(0.0, 0.5, 0.5);
	paddle1.render();
	glColor3f(0.7, 0.5, 0.0);
	paddle2.render();
	glEnd();
	//Draw the ball
	ball.render();

	//If option 2 is selected i.e. ninja_robot.ppm is the background
	//Level 2 selected
	//Draw some obstacles to showcase a difference between level 1 and level2
	if(level == 2) {
		obstacle->render();
	}
	hud->showTimer(getTimer());
	if (hud->isPaused()){
		hud->showPaused(pausedTexture);
	}
}
Example #30
0
	/** Update the zone data for the portals in the zone
	* NOTE: All portal spatial data must be up-to-date before calling this routine.
	*/
	void DefaultZone::updatePortalsZoneData(void)
	{
		PortalList transferPortalList;
		AntiPortalList transferAntiPortalList;
		// check each portal to see if it's intersecting another portal of smaller size
		for ( PortalList::iterator it = mPortals.begin(); it != mPortals.end(); ++it )
		{
			Portal * p = *it;
			bool portalNeedUpdate = p->needUpdate();

			Real pRadius = p->getRadius();

			// First we check against portals in the SAME zone (and only if they have a 
			// target zone different from the home zone)
			// Here we check only against portals that moved and of smaller size.

			// We do not need to check portal againts previous portals 
			// since it would have been already checked.
			// Hence we start with the next portal after the current portal.
			PortalList::iterator it2 = it;
			for ( ++it2; it2 != mPortals.end(); ++it2 )
			{
				Portal * p2 = (*it2);

				// Skip portal if it doesn't need updating.
				// If both portals are not moving, then there's no need to check between them.
				if (!portalNeedUpdate && !p2->needUpdate()) continue;

				// Skip portal if it's not pointing to another zone.
				if (p2->getTargetZone() == this) continue;

				// Skip portal if it's pointing to the same target zone as this portal points to
				if (p2->getTargetZone() == p->getTargetZone()) continue;

				if (pRadius > p2->getRadius())
				{
					// Portal#1 is bigger than Portal#2, check for crossing
					if (p2->getCurrentHomeZone() != p->getTargetZone() && p2->crossedPortal(p))
					{
						// portal#2 crossed portal#1 - flag portal#2 to be moved to portal#1's target zone
						p2->setNewHomeZone(p->getTargetZone());
						transferPortalList.push_back(p2);
					}
				}
				else if (pRadius < p2->getRadius())
				{
					// Portal #2 is bigger than Portal #1, check for crossing
					if (p->getCurrentHomeZone() != p2->getTargetZone() && p->crossedPortal(p2))
					{
						// portal#1 crossed portal#2 - flag portal#1 to be moved to portal#2's target zone
						p->setNewHomeZone(p2->getTargetZone());
						transferPortalList.push_back(p);
						continue;
					}
				}
			}

			// Secondly we check againts the antiportals of this zone.
			for (AntiPortalList::iterator ait = mAntiPortals.begin(); ait != mAntiPortals.end(); ++ait)
			{
				AntiPortal* ap = (*ait);

				// Skip portal if it doesn't need updating.
				// If both portals are not moving, then there's no need to check between them.
				if (!portalNeedUpdate && !ap->needUpdate()) continue;

				// only check for crossing if AntiPortal smaller than portal.
				if (pRadius > ap->getRadius())
				{
					// Portal#1 is bigger than AntiPortal, check for crossing
					if (ap->crossedPortal(p))
					{
						// AntiPortal crossed Portal#1 - flag AntiPortal to be moved to Portal#1's target zone
						ap->setNewHomeZone(p->getTargetZone());
						transferAntiPortalList.push_back(ap);
					}
				}
			}

			// Skip portal if it doesn't need updating.
			if (!portalNeedUpdate) continue;

			// Thirdly we check against portals in the target zone (and only if that target
			// zone is different from the home zone)
			PCZone * tzone = p->getTargetZone();
			if (tzone != this)
			{
				for ( PortalList::iterator it3 = tzone->mPortals.begin(); it3 != tzone->mPortals.end(); ++it3 )
				{
					Portal * p3 = (*it3);
					// only check against bigger regular portals
					if (pRadius < p3->getRadius())
					{
						// Portal#3 is bigger than Portal#1, check for crossing
						if (p->getCurrentHomeZone() != p3->getTargetZone() && p->crossedPortal(p3))
						{
							// Portal#1 crossed Portal#3 - switch target zones for Portal#1
							p->setTargetZone(p3->getTargetZone());
							break;
						}
					}
				}
			}
		}
		// transfer any portals to new zones that have been flagged
		for ( PortalList::iterator it = transferPortalList.begin(); it != transferPortalList.end(); ++it )
		{
			Portal * p = *it;
			if (p->getNewHomeZone() != 0)
			{
				_removePortal(p);
				p->getNewHomeZone()->_addPortal(p);
				p->setNewHomeZone(0);
			}
		}
		// transfer any anti portals to new zones that have been flagged
		for (AntiPortalList::iterator it = transferAntiPortalList.begin(); it != transferAntiPortalList.end(); ++it)
		{
			AntiPortal* p = *it;
			if (p->getNewHomeZone() != 0)
			{
				_removeAntiPortal(p);
				p->getNewHomeZone()->_addAntiPortal(p);
				p->setNewHomeZone(0);
			}
		}
	}