Esempio n. 1
0
    protected override void OnStart()
    {
        EmotionSpectrum currentEmotion = ProceduralEngine.Instance.GetCurrentEmotion();
        float           expectation    = currentEmotion.Dot(new EmotionSpectrum(EmotionVector.GetCoreEmotion(CoreEmotion.Anticipation)));

        camera.RotationDampingTime = .1f + Mathf.Lerp(.4f, 0f, Mathf.Clamp01(expectation - 2f));
        camera.PositionDampingTime = .1f + Mathf.Lerp(.4f, 0f, Mathf.Clamp01(expectation - 2f));
        camera.SetNoiseParameters(Mathf.Clamp(expectation * .4f, 0f, .25f), .75f);

        Vector3 boundsAxis = mainInterestPoint.AssociatedItemBounds.size.normalized;

        List <KeyValuePair <Vector3, float> > possibleDirections = new List <KeyValuePair <Vector3, float> >();

        // Chance of following the frustum average
        possibleDirections.Add(new KeyValuePair <Vector3, float>(mainInterestAxis, .5f));

        // Chance of picking a dolly direction based on the item boundaries
        possibleDirections.Add(new KeyValuePair <Vector3, float>(mainInterestPoint.transform.right * boundsAxis.x, boundsAxis.x));
        possibleDirections.Add(new KeyValuePair <Vector3, float>(mainInterestPoint.transform.up * boundsAxis.y, boundsAxis.y));
        possibleDirections.Add(new KeyValuePair <Vector3, float>(mainInterestPoint.transform.forward * boundsAxis.z, boundsAxis.z));

        // Chance of doing a dolly in/out
        float inOutDirection = ProceduralEngine.Instance.EmotionEngine.GetStructureAtTime(ProceduralEngine.Instance.CurrentTimeNormalized) == StructureType.Decreasing ? -1f : 1f;

        possibleDirections.Add(new KeyValuePair <Vector3, float>(GetForward() * inOutDirection, .5f));

        movementDirection = ProceduralEngine.SelectRandomWeighted(possibleDirections, x => x.Value).Key.normalized;
        keepAttention     = ProceduralEngine.RandomRange(0f, 1f) > .5f; // TODO: associate this with the rotation smoothness/lag, and with emotions (e.g. sadness lags, expectation keeps)
    }
Esempio n. 2
0
    public float GetTrackAffinityInTime(float nT)
    {
        TrackData track = ProceduralEngine.Instance.EmotionEngine.GetTrackById(TrackId);

        if (track != null)
        {
            return(internalSpectrum.Dot(ProceduralEngine.Instance.EmotionEngine.EvaluateTrack(track, nT)));
        }

        return(0f);
    }
Esempio n. 3
0
    /// <summary>
    /// This heuristic is useful for two cases:
    /// - Trying to find the main interest point
    /// - Trying to evaluate different views for the same interest point (shot heuristic)
    /// </summary>
    public float EvaluateHeuristic(EmotionSpectrum currentEmotion, float normalizedTime, bool primaryInterest = false)
    {
        // If this GO is inactive just ignore this IP
        // This is useful for state machines
        if (!gameObject.activeInHierarchy)
        {
            return(0f);
        }

        float heuristic = importance;

        heuristic += emotionalImpact * currentEmotion.Dot(internalSpectrum);

        // If this is the primary interest point, we want to make sure it is
        // close to other interesting places, so biasing the importance with a heatmap is useful.
        if (primaryInterest)
        {
            // Interesting: while being on an important place is good, we must not make unimportant elements important.
            // Thus we need to be careful with this multiplier
            heuristic += .35f * ProceduralCameraDirector.Instance.GetGrid().GetAverageImportanceForPosition(transform.position);

            // This is somewhat of a hack. The correct idea is to
            // predict if this state is going to be triggered, but that is not trivial
            if (stateMachine != null)
            {
                float stateEmotionResponse = stateMachine.GetGlobalAffinityInTime(normalizedTime) + stateMachine.GetTrackAffinityInTime(normalizedTime);
                heuristic += emotionalImpact * stateEmotionResponse;

                if (stateMachine.CurrentState == EmotionStateMachineState.State.Enabled ||
                    stateMachine.CurrentState == EmotionStateMachineState.State.IntroTransition)
                {
                    heuristic *= 2f;
                }
            }
        }

        // Let's try to favor small or big objects based on general flow
        Vector3 worldScale          = transform.lossyScale * size;
        float   worldSizeNormalized = Mathf.Min(worldScale.magnitude, 200f) / 200f;
        float   smoothEnergy        = ProceduralEngine.Instance.EmotionEngine.GetSmoothEnergy(normalizedTime) / ProceduralEngine.Instance.EmotionEngine.MaxEnergy;

        // We assume smoothEnergy to be the normalized size we favor
        float sizeTargetOffset = Mathf.Abs(smoothEnergy - worldSizeNormalized) * 2f;

        heuristic = Mathf.Lerp(heuristic * 2f, heuristic, sizeTargetOffset);

        // TODO: ideas:
        // - Is it being lit right now? Or in shadow?
        //      - If it is reflective/specular, where would be a good place to look at it from?
        // - Is it moving?
        return(heuristic);
    }
Esempio n. 4
0
    public float GetGlobalAffinityInTime(float nT)
    {
        EmotionSpectrum globalEmotion = smooth ? ProceduralEngine.Instance.EmotionEngine.GetSmoothSpectrum(nT) : ProceduralEngine.Instance.EmotionEngine.GetSpectrum(nT);

        return(globalEmotion.Dot(internalSpectrum));
    }