Exemplo n.º 1
0
DivideData SplitObjects(const AABB &box, std::vector< std::vector<Primitive*> > &vectorList)
{
	DivideData data;
	int objectsNumber = vectorList[0].size();
	float minSAH = objectsNumber * box.GetSurfaceArea();
	std::sort(vectorList[0].begin(),vectorList[0].end(), ComparePrimitivesX);
	std::sort(vectorList[1].begin(),vectorList[1].end(), ComparePrimitivesY);
	std::sort(vectorList[2].begin(),vectorList[2].end(), ComparePrimitivesZ);

	for (int i = 0; i < 3; i++) 
	{
		AABB tempBox;
		std::vector<AABB> rightBounds;
		for (int j = objectsNumber; j > 0; j--) {
			tempBox.Include(vectorList[i][j-1]);
			rightBounds.push_back(tempBox);
		}
		tempBox.Reset();
		for (int j = 1; j < objectsNumber; j++) 
		{
			tempBox.Include(vectorList[i][j-1]);
			float sah = j * tempBox.GetSurfaceArea() + rightBounds[objectsNumber - j - 1].GetSurfaceArea() * (objectsNumber - j);
			if (sah < minSAH) 
			{
				minSAH = sah;
				data.divideAxis = i;
				data.leftObjectsNum = j;
				data.rightObjectsNum = objectsNumber - j;
				data.rightBox = rightBounds[objectsNumber - j - 1];
				data.leftBox = tempBox;	
			}
		}
		if (data.divideAxis != -1)
			data.isDivided = true;
		return data;
	}
}
Exemplo n.º 2
0
void CAreaProxy::SerializeXML( XmlNodeRef &entityNode,bool bLoading )
{
	if (m_nFlags & FLAG_NOT_SERIALIZE)
		return;

	if (bLoading)
	{
		XmlNodeRef areaNode = entityNode->findChild( "Area" );
		if (!areaNode)
			return;

		int nId=0,nGroup=0,nPriority=0;
		float fProximity = 0;
		float fHeight = 0;
		
		areaNode->getAttr( "Id",nId );
		areaNode->getAttr( "Group",nGroup );
		areaNode->getAttr( "Proximity",fProximity );
		areaNode->getAttr( "Priority",nPriority );
		m_pArea->SetID(nId);
		m_pArea->SetGroup(nGroup);
		m_pArea->SetProximity(fProximity);
		m_pArea->SetPriority(nPriority);
		const char* token(0);

		XmlNodeRef pointsNode = areaNode->findChild( "Points" );
		if (pointsNode)
		{
			for (int i = 0; i < pointsNode->getChildCount(); i++)
			{
				XmlNodeRef pntNode = pointsNode->getChild(i);
				Vec3 pos;
				if (pntNode->getAttr( "Pos",pos ))
					m_localPoints.push_back(pos);

				// Get sound obstruction 
				bool bObstructSound = 0;
				pntNode->getAttr("ObstructSound", bObstructSound);
				m_abObstructSound.push_back(bObstructSound);
			}
			m_pArea->SetAreaType( ENTITY_AREA_TYPE_SHAPE );

			areaNode->getAttr( "Height",fHeight );
			m_pArea->SetHeight(fHeight);
			// Set points.
			OnMove();
		}
		else if (areaNode->getAttr("SphereRadius",m_fRadius))
		{
			// Sphere.
			areaNode->getAttr("SphereCenter",m_vCenter);
			m_pArea->SetSphere( m_pEntity->GetWorldTM().TransformPoint(m_vCenter),m_fRadius );
		}
		else if (areaNode->getAttr("VolumeRadius",m_fRadius))
		{
			areaNode->getAttr("Gravity",m_fGravity);
			areaNode->getAttr("DontDisableInvisible", m_bDontDisableInvisible);

			AABB box;
			box.Reset();

			// Bezier Volume.
			pointsNode = areaNode->findChild( "BezierPoints" );
			if (pointsNode)
			{
				for (int i = 0; i < pointsNode->getChildCount(); i++)
				{
					XmlNodeRef pntNode = pointsNode->getChild(i);
					Vec3 pt;
					if (pntNode->getAttr( "Pos",pt))
					{
						m_bezierPoints.push_back(pt);
						box.Add( pt );
					}
				}
			}
			m_pArea->SetAreaType( ENTITY_AREA_TYPE_GRAVITYVOLUME );
			if (!m_pEntity->GetRenderProxy())
			{
				IEntityRenderProxyPtr pRenderProxy = crycomponent_cast<IEntityRenderProxyPtr>(m_pEntity->CreateProxy( ENTITY_PROXY_RENDER ));
				m_pEntity->SetFlags(m_pEntity->GetFlags() | ENTITY_FLAG_SEND_RENDER_EVENT);

				if (box.min.x > box.max.x)
					box.min = box.max = Vec3(0,0,0);
				box.min-=Vec3(m_fRadius, m_fRadius, m_fRadius);
				box.max+=Vec3(m_fRadius, m_fRadius, m_fRadius);

				Matrix34 tm = m_pEntity->GetWorldTM_Fast();

				box.SetTransformedAABB( m_pEntity->GetWorldTM_Fast().GetInverted(),box );

				pRenderProxy->SetLocalBounds(box, true);
			}

			OnEnable(m_bIsEnable);
		}
		else if (areaNode->getAttr("AreaSolidFileName",&token))
		{
			CCryFile file;

			int nAliasLen = sizeof("%level%")-1;
			const char* areaSolidFileName;
			if (strncmp(token,"%level%",nAliasLen) == 0)
				areaSolidFileName = GetIEntitySystem()->GetSystem()->GetI3DEngine()->GetLevelFilePath(token+nAliasLen);
			else
				areaSolidFileName = token;

			if( file.Open(areaSolidFileName,"rb") )
			{
				int numberOfClosedPolygon = 0;
				int numberOfOpenPolygon = 0;

				m_pArea->BeginSettingSolid(m_pEntity->GetWorldTM());

				file.ReadType(&numberOfClosedPolygon);
				file.ReadType(&numberOfOpenPolygon);

				ReadPolygonsForAreaSolid( file, numberOfClosedPolygon, true );
				ReadPolygonsForAreaSolid( file, numberOfOpenPolygon, false );

				m_pArea->EndSettingSolid();
			}
		}
		else
		{
			// Box.
			Vec3 bmin(0,0,0),bmax(0,0,0);
			areaNode->getAttr("BoxMin",bmin);
			areaNode->getAttr("BoxMax",bmax);
			m_pArea->SetBox( bmin,bmax,m_pEntity->GetWorldTM() );

			// Get sound obstruction
			XmlNodeRef const pNodeSoundData = areaNode->findChild("SoundData");
			if (pNodeSoundData)
			{
				assert(m_abObstructSound.size() == 0);

				for (int i = 0; i < pNodeSoundData->getChildCount(); ++i)
				{
					XmlNodeRef const pNodeSide = pNodeSoundData->getChild(i);

					if (pNodeSide)
					{
						bool bObstructSound = false;
						pNodeSide->getAttr("ObstructSound", bObstructSound);
						m_abObstructSound.push_back(bObstructSound);
					}
				}
			}

			OnMove();
		}

		m_pArea->ClearEntities();
		XmlNodeRef entitiesNode = areaNode->findChild( "Entities" );
		// Export Entities.
		if (entitiesNode)
		{
			for (int i = 0; i < entitiesNode->getChildCount(); i++)
			{
				XmlNodeRef entNode = entitiesNode->getChild(i);
				EntityId entityId;
				EntityGUID entityGuid;
				if(gEnv->pEntitySystem->EntitiesUseGUIDs())
				{
					if (entNode->getAttr( "Guid",entityGuid ))
						m_pArea->AddEntity( entityGuid );
				}
				else
				{
					if (entNode->getAttr( "Id",entityId ))
						m_pArea->AddEntity( entityId );
				}
			}
		}
	}
	else
	{
		// Save points.
		XmlNodeRef areaNode = entityNode->newChild( "Area" );
		areaNode->setAttr( "Id",m_pArea->GetID() );
		areaNode->setAttr( "Group",m_pArea->GetGroup() );
		areaNode->setAttr( "Proximity",m_pArea->GetProximity() );
		areaNode->setAttr( "Priority", m_pArea->GetPriority() );
		EEntityAreaType type = m_pArea->GetAreaType();
		if (type == ENTITY_AREA_TYPE_SHAPE)
		{
			XmlNodeRef pointsNode = areaNode->newChild( "Points" );
			for (unsigned int i = 0; i < m_localPoints.size(); i++)
			{
				XmlNodeRef pntNode = pointsNode->newChild("Point");
				pntNode->setAttr( "Pos",m_localPoints[i] );
				pntNode->setAttr("ObstructSound", m_abObstructSound[i]);
			}
			areaNode->setAttr( "Height",m_pArea->GetHeight() );
		}
		else if (type == ENTITY_AREA_TYPE_SPHERE)
		{
			// Box.
			areaNode->setAttr("SphereCenter",m_vCenter);
			areaNode->setAttr("SphereRadius",m_fRadius);
		}
		else if (type == ENTITY_AREA_TYPE_BOX)
		{
			// Box.
			Vec3 bmin,bmax;
			m_pArea->GetBox(bmin,bmax);
			areaNode->setAttr("BoxMin",bmin);
			areaNode->setAttr("BoxMax",bmax);

			// Set sound obstruction
			XmlNodeRef const pNodeSoundData = areaNode->newChild("SoundData");
			if (pNodeSoundData)
			{
				assert(m_abObstructSound.size() == 6);
				size_t nIndex = 0;
				tSoundObstructionIterConst const ItEnd = m_abObstructSound.end();
				for (tSoundObstructionIterConst It = m_abObstructSound.begin(); It != ItEnd ; ++It)
				{
					bool const bObstructed = (bool)(*It);
					stack_string sTemp;
					sTemp.Format("Side%d", ++nIndex);

					XmlNodeRef const pNodeSide = pNodeSoundData->newChild(sTemp.c_str());
					pNodeSide->setAttr("ObstructSound", bObstructed);
				}
			}
		}
		else if (type == ENTITY_AREA_TYPE_GRAVITYVOLUME)
		{
			areaNode->setAttr("VolumeRadius",m_fRadius);
			areaNode->setAttr("Gravity",m_fGravity);
			areaNode->setAttr("DontDisableInvisible", m_bDontDisableInvisible);
			XmlNodeRef pointsNode = areaNode->newChild( "BezierPoints" );
			for (unsigned int i = 0; i < m_bezierPoints.size(); i++)
			{
				XmlNodeRef pntNode = pointsNode->newChild("Point");
				pntNode->setAttr( "Pos",m_bezierPoints[i] );
			}
		}

#ifdef SW_ENTITY_ID_USE_GUID
		const std::vector<EntityGUID>& entGUIDs=*m_pArea->GetEntitiesGuid();
		// Export Entities.
		if (!entGUIDs.empty())
		{
			XmlNodeRef nodes = areaNode->newChild( "Entities" );
			for (uint32 i = 0; i < entGUIDs.size(); i++)
			{
				EntityGUID guid = entGUIDs[i];
				XmlNodeRef entNode = nodes->newChild( "Entity" );
				entNode->setAttr( "Guid",guid );
				entNode->setAttr( "Id",gEnv->pEntitySystem->GenerateEntityIdFromGuid(guid) );
			}
		}
#else
		const std::vector<EntityId>& entIDs=*m_pArea->GetEntities();
		// Export Entities.
		if (!entIDs.empty())
		{
			XmlNodeRef nodes = areaNode->newChild( "Entities" );
			for (uint32 i = 0; i < entIDs.size(); i++)
			{
				int entityId = entIDs[i];
				XmlNodeRef entNode = nodes->newChild( "Entity" );
				entNode->setAttr( "Id",entityId );
			}
		}
#endif
	}
}
Exemplo n.º 3
0
bool CDialogActorContext::DoLocalPlayerChecks(const float dt)
{
	// don't check this every frame, but only every .2 secs
	m_checkPlayerTimeOut-=dt;
	if (m_checkPlayerTimeOut <= 0.0f)
	{
		do // a dummy loop to use break
		{
			float awareDistance;
			float awareDistanceSq;
			float awareAngle;
			m_pSession->GetPlayerAwarenessValues(awareDistance, awareAngle);
			awareDistanceSq=awareDistance*awareDistance;

			m_checkPlayerTimeOut = PLAYER_CHECKTIME;
			const float spotAngleCos = cos_tpl(DEG2RAD(awareAngle));
	
			const CDialogSession::TActorContextMap& contextMap = m_pSession->GetAllContexts();
			if (contextMap.size() == 1 && contextMap.begin()->first == m_actorID)
			{
				m_bIsAware = true;
				break;
			}
	
			// early out, when we don't have to do any checks
			if (awareDistance <= 0.0f && awareAngle <= 0.0f)
			{
				m_bIsAware = true;
				break;
			}

			IEntity* pThisEntity = m_pSession->GetActorEntity(m_actorID);
			if (!pThisEntity)
			{
				assert (false);
				m_bIsAware = true;
				break;
			}
			IMovementController* pMC = (m_pIActor != NULL) ? m_pIActor->GetMovementController() : NULL;
			if (!pMC)
			{
				assert (false);
				m_bIsAware = true;
				break;
			}
			SMovementState moveState;
			pMC->GetMovementState(moveState);
			Vec3 viewPos = moveState.eyePosition;
			Vec3 viewDir = moveState.eyeDirection;
			viewDir.z = 0.0f;
			viewDir.NormalizeSafe();
	
			// check the player's position
			// check the player's view direction
			AABB groupBounds;
			groupBounds.Reset();

			CDialogSession::TActorContextMap::const_iterator iter = contextMap.begin();
			CDialogScript::SActorSet lookingAt = 0;
			while (iter != contextMap.end())
			{
				if (iter->first != m_actorID)
				{
					IEntity* pActorEntity = m_pSession->GetActorEntity(iter->first);
					if (pActorEntity)
					{
						Vec3 vEntityPos = pActorEntity->GetWorldPos();
						AABB worldBounds;
						pActorEntity->GetWorldBounds(worldBounds);
						groupBounds.Add(worldBounds);
						// calc if we look at it somehow
						Vec3 vEntityDir = vEntityPos - viewPos;
						vEntityDir.z = 0.0f;
						vEntityDir.NormalizeSafe();
						if (viewDir.IsUnit() && vEntityDir.IsUnit())
						{
							const float dot = clamp_tpl(viewDir.Dot(vEntityDir),-1.0f,+1.0f); // clamping should not be needed
							if (spotAngleCos <= dot)
								lookingAt.SetActor(iter->first);
							DiaLOG::Log(DiaLOG::eDebugC, "Angle to actor %d is %f deg", iter->first, RAD2DEG(acos_tpl(dot)));
						}
					}
				}
				++iter;
			}

			const float distanceSq = pThisEntity->GetWorldPos().GetSquaredDistance(groupBounds.GetCenter());
			CCamera& camera=gEnv->pSystem->GetViewCamera();
			const bool bIsInAABB  = camera.IsAABBVisible_F(groupBounds);
			const bool bIsInRange = distanceSq <= awareDistanceSq;
			const bool bIsLooking = contextMap.empty() || lookingAt.NumActors() > 0;
			m_bIsAwareLooking = awareAngle <= 0.0f || (bIsInAABB || bIsLooking);
			m_bIsAwareInRange = awareDistance <= 0.0f || bIsInRange;
			m_bIsAware = m_bIsAwareLooking && m_bIsAwareInRange;

			DiaLOG::Log(DiaLOG::eDebugB, "[DIALOG] LPC: %s awDist=%f awAng=%f AABBVis=%d IsLooking=%d InRange=%d [Distance=%f LookingActors=%d] Final=%saware", 
				m_pSession->GetDebugName(), awareDistance, awareAngle, bIsInAABB, bIsLooking, bIsInRange, sqrt_tpl(distanceSq), lookingAt.NumActors(), m_bIsAware ? "" : "not ");
		
		} while (false);
	}

	if (m_bIsAware)
	{
		m_playerAwareTimeOut = m_pSession->GetPlayerAwarenessGraceTime();
	}
	else
	{
		m_playerAwareTimeOut-= dt;
		if (m_playerAwareTimeOut <= 0)
		{
			return false;
		}
	}

	return true;
}