void CrowdAgent::OnCrowdAgentReposition(const Vector3& newPos, const Vector3& newDirection)
{
    if (node_)
    {
        // Notify parent node of the reposition
        VariantMap& map = GetContext()->GetEventDataMap();
        map[CrowdAgentReposition::P_NODE] = GetNode();
        map[CrowdAgentReposition::P_CROWD_AGENT] = this;
        map[CrowdAgentReposition::P_POSITION] = newPos;
        map[CrowdAgentReposition::P_VELOCITY] = GetActualVelocity();
        SendEvent(E_CROWD_AGENT_REPOSITION, map);
        
        if (updateNodePosition_)
        {
            ignoreTransformChanges_ = true;
            node_->SetPosition(newPos);
            ignoreTransformChanges_ = false;
        }

        // Send a notification event if we've reached the destination
        CrowdTargetState newTargetState = GetTargetState();
        CrowdAgentState newAgentState = GetAgentState();
        if (newAgentState != previousAgentState_ || newTargetState != previousTargetState_)
        {
            VariantMap& map = GetContext()->GetEventDataMap();
            map[CrowdAgentStateChanged::P_NODE] = GetNode();
            map[CrowdAgentStateChanged::P_CROWD_AGENT] = this;
            map[CrowdAgentStateChanged::P_CROWD_TARGET_STATE] = newTargetState;
            map[CrowdAgentStateChanged::P_CROWD_AGENT_STATE] = newAgentState;
            map[CrowdAgentStateChanged::P_POSITION] = newPos;
            map[CrowdAgentStateChanged::P_VELOCITY] = GetActualVelocity();
            SendEvent(E_CROWD_AGENT_STATE_CHANGED, map);

            // Send a failure event if either state is a failed status
            if (newAgentState == CROWD_AGENT_INVALID || newTargetState == CROWD_AGENT_TARGET_FAILED)
            {
                VariantMap& map = GetContext()->GetEventDataMap();
                map[CrowdAgentFailure::P_NODE] = GetNode();
                map[CrowdAgentFailure::P_CROWD_AGENT] = this;
                map[CrowdAgentFailure::P_CROWD_TARGET_STATE] = newTargetState;
                map[CrowdAgentFailure::P_CROWD_AGENT_STATE] = newAgentState;
                map[CrowdAgentFailure::P_POSITION] = newPos;
                map[CrowdAgentFailure::P_VELOCITY] = GetActualVelocity();
                SendEvent(E_CROWD_AGENT_FAILURE, map);
            }

            // State may have been altered during the handling of the event
            previousAgentState_ = GetAgentState();
            previousTargetState_ = GetTargetState();
        }
    }
}
void CrowdAgent::DrawDebugGeometry(DebugRenderer* debug, bool depthTest)
{
    if (node_)
    {
        const Vector3 pos = GetPosition();
        const Vector3 vel = GetActualVelocity();
        const Vector3 desiredVel = GetDesiredVelocity();
        const Vector3 agentHeightVec(0, height_ * 0.5f, 0);

        debug->AddLine(pos, pos + vel, Color::GREEN, depthTest);
        debug->AddLine(pos + agentHeightVec, pos + desiredVel + agentHeightVec, Color::RED, depthTest);
        debug->AddCylinder(pos, radius_, height_, Color::GREEN, depthTest);
    }
}
Exemplo n.º 3
0
void CrowdAgent::AddAgentToCrowd()
{
    if (!crowdManager_ || !crowdManager_->crowd_ || !node_)
        return;

    PROFILE(AddAgentToCrowd);

    if (!inCrowd_)
    {
        inCrowd_ = true;
        agentCrowdId_ = crowdManager_->AddAgent(this, node_->GetPosition());
        if (agentCrowdId_ == -1)
        {
            inCrowd_ = false;
            LOGERROR("AddAgentToCrowd: Could not add agent to crowd");
            return;
        }
        crowdManager_->UpdateAgentNavigationQuality(this, navQuality_);
        crowdManager_->UpdateAgentPushiness(this, navPushiness_);
        previousAgentState_ = GetAgentState();
        previousTargetState_ = GetTargetState();

        // Agent created, but initial state is invalid and needs to be addressed
        if (previousAgentState_ == CROWD_AGENT_INVALID)
        {
            VariantMap& map = GetContext()->GetEventDataMap();
            map[CrowdAgentFailure::P_NODE] = GetNode();
            map[CrowdAgentFailure::P_CROWD_AGENT] = this;
            map[CrowdAgentFailure::P_CROWD_TARGET_STATE] = previousTargetState_;
            map[CrowdAgentFailure::P_CROWD_AGENT_STATE] = previousAgentState_;
            map[CrowdAgentFailure::P_POSITION] = GetPosition();
            map[CrowdAgentFailure::P_VELOCITY] = GetActualVelocity();
            SendEvent(E_CROWD_AGENT_FAILURE, map);

            // Reevaluate states as handling of event may have resulted in changes
            previousAgentState_ = GetAgentState();
            previousTargetState_ = GetTargetState();
        }

        // Save the initial position to prevent CrowdAgentReposition event being triggered unnecessarily
        previousPosition_ = GetPosition();
    }
}