private void UpdateLayerNetwork()
 {
     for (int layerIndex = 1; layerIndex < m_layerTransforms.Length; layerIndex++)
     {
         NeuralNetworkValueContainer valueContainer = m_layerTransforms[layerIndex].GetComponent <NeuralNetworkValueContainer>();
         if (valueContainer == null)
         {
             valueContainer = m_layerTransforms[layerIndex].gameObject.AddComponent <NeuralNetworkValueContainer>();
         }
         float[] values = new float[m_nodeTransforms[layerIndex].Length];
         for (int nodeIndex = 0; nodeIndex < m_nodeTransforms[layerIndex].Length; nodeIndex++)
         {
             values[nodeIndex] = m_network.GetBias(layerIndex, nodeIndex);
         }
         valueContainer.m_valuesBias = values;
     }
 }
 private void UpdateWeightIndices()
 {
     m_weightIndex++;
     if (m_weightIndex >= m_weightTransforms[m_layerIndex][m_nodeIndex].Length)
     {
         m_weightIndex = 0;
         m_nodeIndex++;
         if (m_nodeIndex >= m_weightTransforms[m_layerIndex].Length)
         {
             m_nodeIndex = 0;
             m_layerIndex++;
             if (m_layerIndex >= m_weightTransforms.Length - 1)
             {
                 m_layerIndex           = 0;
                 m_currentNodeContainer = m_nodeTransforms[m_layerIndex][m_nodeIndex].GetComponent <NeuralNetworkValueContainer>(); // because of the return, the current container of node 0 would never be reached
                 return;
             }
         }
         m_currentNodeContainer = m_nodeTransforms[m_layerIndex][m_nodeIndex].GetComponent <NeuralNetworkValueContainer>();
     }
 }
    public void UpdateActivisionsNetwork(float[] input)
    {
        if (!m_visualize || m_isDestroyed)
        {
            return;
        }

        MyMatrix[] activisions = m_network.GetActivisions(input);

        // set actual colors
        Color color;

        for (int layerIndex = 0; layerIndex < m_layerCount; layerIndex++)
        {
            NeuralNetworkValueContainer valueContainerLayer = m_layerTransforms[layerIndex].GetComponent <NeuralNetworkValueContainer>();
            if (valueContainerLayer == null)
            {
                valueContainerLayer = m_layerTransforms[layerIndex].gameObject.AddComponent <NeuralNetworkValueContainer>();
            }
            float[] values = new float[m_nodeTransforms[layerIndex].Length];


            int nodeCount = m_network.m_layerLengths[layerIndex];
            for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++)
            {
                Transform activision = m_activisionTransforms[layerIndex][nodeIndex];

                float value = activisions[layerIndex].m_data[nodeIndex][0];

                float mappedValue = 0;
                if (layerIndex == 0)
                {
                    mappedValue = Utility.MapValuePercent(0f, 1f, value);
                }
                else
                {
                    mappedValue = Utility.MapValuePercent(0f, 1f, value);
                }

                if (mappedValue > 0.5f)
                {
                    color = Color.Lerp(m_manager.GetColorBiasAverage(), m_manager.GetColorBiasMax(), (mappedValue - 0.5f) * 2f);
                }
                else
                {
                    color = Color.Lerp(m_manager.GetColorBiasMin(), m_manager.GetColorBiasAverage(), mappedValue * 2f);
                }

                Renderer renderer         = activision.GetComponent <Renderer>();
                MaterialPropertyBlock mpb = new MaterialPropertyBlock();
                mpb.SetColor("_Color", color);
                renderer.material.EnableKeyword("_EMISSION");
                mpb.SetColor("_EmissionColor", color);
                renderer.SetPropertyBlock(mpb);

                NeuralNetworkValueContainer valueContainerNode = activision.GetComponent <NeuralNetworkValueContainer>();
                if (valueContainerNode == null)
                {
                    valueContainerNode = activision.gameObject.AddComponent <NeuralNetworkValueContainer>();
                }
                valueContainerNode.m_value = value;
                values[nodeIndex]          = value;

                // set the color of activisions and biases in the input layer
                if (layerIndex == 0 || !m_showBiases)
                {
                    Transform bias = m_nodeTransforms[layerIndex][nodeIndex];

                    renderer = bias.GetComponent <Renderer>();
                    mpb      = new MaterialPropertyBlock();
                    mpb.SetColor("_Color", color);
                    renderer.material.EnableKeyword("_EMISSION");
                    mpb.SetColor("_EmissionColor", color);
                    renderer.SetPropertyBlock(mpb);
                }
            }

            valueContainerLayer.m_valuesActivision = values;
        }
    }
    private void UpdateBiasesNetwork()
    {
        if (!m_showBiases)
        {
            return;
        }

        float[] minValues = new float[m_layerCount];
        float[] maxValues = new float[m_layerCount];
        //float minValueBias = float.MaxValue;
        //float maxValueBias = float.MinValue;
        // get min / max value
        for (int layerIndex = 1; layerIndex < m_layerCount; layerIndex++)
        {
            minValues[layerIndex] = float.MaxValue;
            maxValues[layerIndex] = float.MinValue;
            int nodeCount = m_network.m_layerLengths[layerIndex];
            for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++)
            {
                float value = m_network.GetBias(layerIndex, nodeIndex);
                minValues[layerIndex] = Mathf.Min(value, minValues[layerIndex]);
                maxValues[layerIndex] = Mathf.Max(value, maxValues[layerIndex]);

                NeuralNetworkValueContainer valueContainer = m_nodeTransforms[layerIndex][nodeIndex].GetComponent <NeuralNetworkValueContainer>();
                if (valueContainer == null)
                {
                    valueContainer = m_nodeTransforms[layerIndex][nodeIndex].gameObject.AddComponent <NeuralNetworkValueContainer>();
                }
                valueContainer.m_value = value;
            }
        }
        // set actual colors
        Color color;

        for (int layerIndex = 1; layerIndex < m_layerCount; layerIndex++)
        {
            int nodeCount = m_network.m_layerLengths[layerIndex];
            for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++)
            {
                Transform node = m_nodeTransforms[layerIndex][nodeIndex];

                float value       = m_network.GetBias(layerIndex, nodeIndex);
                float mappedValue = Utility.MapValuePercent(minValues[layerIndex], maxValues[layerIndex], value);
                if (mappedValue > 0.5f)
                {
                    color = Color.Lerp(m_manager.GetColorBiasAverage(), m_manager.GetColorBiasMax(), (mappedValue - 0.5f) * 2f);
                }
                else
                {
                    color = Color.Lerp(m_manager.GetColorBiasMin(), m_manager.GetColorBiasAverage(), mappedValue * 2f);
                }

                Renderer renderer         = node.GetComponent <Renderer>();
                MaterialPropertyBlock mpb = new MaterialPropertyBlock();
                mpb.SetColor("_Color", color);
                renderer.material.EnableKeyword("_EMISSION");
                mpb.SetColor("_EmissionColor", color);
                renderer.SetPropertyBlock(mpb);
            }
        }
    }
    private void CreateObjects()
    {
        // create layer objects
        m_layerTransforms = new Transform[m_layerCount];
        for (int layerIndex = 0; layerIndex < m_layerCount; layerIndex++)
        {
            GameObject layerObject = Instantiate(m_manager.GetLayerPrefab(), m_parentTransform);
            layerObject.name              = "Layer_" + layerIndex;
            layerObject.layer             = Statics.s_neuralNetworkLayer;
            m_layerTransforms[layerIndex] = layerObject.transform;
        }

        // create node and activision objects
        m_nodeTransforms       = new Transform[m_layerCount][];
        m_activisionTransforms = new Transform[m_layerCount][];
        //m_totalNodeCount = 0;
        for (int layerIndex = 0; layerIndex < m_layerCount; layerIndex++)
        {
            int nodeCount = m_network.m_layerLengths[layerIndex];
            //m_totalNodeCount += nodeCount;
            Transform[] nodesThisLayer       = new Transform[nodeCount];
            Transform[] activisionsThisLayer = new Transform[nodeCount];
            for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++)
            {
                GameObject node = Instantiate(m_manager.GetNodePrefabHemisphere(), m_layerTransforms[layerIndex]);
                node.name  = "Node_" + layerIndex + "_" + nodeIndex;
                node.layer = Statics.s_neuralNetworkLayer;
                node.transform.Rotate(node.transform.right, -90f);
                nodesThisLayer[nodeIndex] = node.transform;

                if (layerIndex < m_layerCount - 1)
                {
                    NeuralNetworkValueContainer container = node.GetComponent <NeuralNetworkValueContainer>();
                    container.m_valuesWeight = new float[m_network.m_layerLengths[layerIndex + 1]];
                    if (layerIndex == 0 && nodeIndex == 0)
                    {
                        m_currentNodeContainer = container;
                    }
                }

                GameObject activision = Instantiate(m_manager.GetNodePrefabHemisphere(), m_layerTransforms[layerIndex]);
                activision.name  = "Activison_" + layerIndex + "_" + nodeIndex;
                activision.layer = Statics.s_neuralNetworkLayer;
                activision.transform.Rotate(activision.transform.right, 90f);
                activisionsThisLayer[nodeIndex] = activision.transform;
            }

            m_nodeTransforms[layerIndex]       = nodesThisLayer;
            m_activisionTransforms[layerIndex] = activisionsThisLayer;
        }

        // create weight objects
        m_weightTransforms = new Transform[m_layerCount][][];
        for (int layerIndex = 0; layerIndex < m_layerCount - 1; layerIndex++)
        {
            int           nodeCountThisLayer = m_network.m_layerLengths[layerIndex];
            int           nodeCountNextLayer = m_network.m_layerLengths[layerIndex + 1];
            Transform[][] nodesThisLayer     = new Transform[nodeCountThisLayer][];
            for (int nodeIndex = 0; nodeIndex < nodeCountThisLayer; nodeIndex++)
            {
                Transform[] weightTransforms = new Transform[nodeCountNextLayer];
                for (int weightIndex = 0; weightIndex < nodeCountNextLayer; weightIndex++)
                {
                    GameObject weight = Instantiate(m_manager.GetWeightPrefab(), m_nodeTransforms[layerIndex][nodeIndex], true);
                    weight.name  = "Weight_" + layerIndex + "_" + nodeIndex + "_" + weightIndex;
                    weight.layer = Statics.s_neuralNetworkLayer;
                    weightTransforms[weightIndex] = weight.transform;
                }
                nodesThisLayer[nodeIndex] = weightTransforms;
            }
            m_weightTransforms[layerIndex] = nodesThisLayer;
        }
    }