bool CEntityObject::GetLocalBounds( AABB &bounds ) { if (pStatObj) { bounds.Add(pStatObj->GetAABB()); return true; } else if (pCharacter) { bounds.Add(pCharacter->GetAABB()); return true; } else if (pLight) { bounds.Add(Vec3Constants<float>::fVec3_Zero, 0.1f); return true; } else if (pChildRenderNode) { pChildRenderNode->GetLocalBounds(bounds); return true; } return false; }
AABB Node::GetAABB() { AABB box; for (int i = 0; i < child_array_->Size(); i++) { Node * node = (Node*)child_array_->At(i); AABB tbox = node->GetAABB(); vec3 v = tbox.GetMax(); box.Add(v.x, v.y, v.z); v = tbox.GetMin(); box.Add(v.x, v.y, v.z); } vec3 v = aabb_.GetMax(); box.Add(v.x, v.y, v.z); v = aabb_.GetMin(); box.Add(v.x,v.y, v.z); mat4 t = this->GetTransform(); if (parents_) { t = parents_->GetTransform() * t; } box.SetToTransformedBox(t); return box; }
bool AABBTreeOfAABBsBuilder::ComputeGlobalBox(const udword* primitives, udword nb_prims, AABB& global_box) const { // Checkings if(!primitives || !nb_prims) return false; // Initialize global box global_box = mAABBArray[primitives[0]]; // Loop through boxes for(udword i=1;i<nb_prims;i++) { // Update global box global_box.Add(mAABBArray[primitives[i]]); } return true; }
void CVTOLVehicleManager::CalculateBounds(IEntity* pVTOLEntity, SVTOLInfo& info) { // Work out final local bounds - includes all children's bounds AABB aabb; pVTOLEntity->GetLocalBounds(aabb); const int numChildren = pVTOLEntity->GetChildCount(); AABB childAABB; for(int child = 0; child < numChildren; ++child) { if(IEntity* pChild = pVTOLEntity->GetChild(child)) { pChild->GetLocalBounds(childAABB); aabb.Add(childAABB); } } info.localBounds = aabb; }
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 } }
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; }