// Constructor Method:
    public MiniGameMoveToTarget1D()
    {
        //DebugBot.DebugFunctionCall("MiniGameMoveToTarget1D; Constructor();", debugFunctionCalls);
        ownPosX[0] = 0f;
        targetPosX[0] = 0f;
        ownVelX[0] = 0f;
        targetVelX[0] = 0f;
        targetDirX[0] = 0f;

        fitDotProduct[0] = 0f;
        fitTimeToTarget[0] = 1f;
        fitDistanceToTarget[0] = 0f;
        fitReachTarget[0] = 0f;
        collision = false;

        // Brain Inputs!:
        inputChannelsList = new List<BrainInputChannel>();
        BrainInputChannel BIC_ownPosX = new BrainInputChannel(ref ownPosX, false, "ownPosX");
        inputChannelsList.Add (BIC_ownPosX); // 0
        BrainInputChannel BIC_targetPosX = new BrainInputChannel(ref targetPosX, false, "targetPosX");
        inputChannelsList.Add (BIC_targetPosX); // 1
        BrainInputChannel BIC_ownVelX = new BrainInputChannel(ref ownVelX, false, "ownVelX");
        inputChannelsList.Add (BIC_ownVelX); // 2
        BrainInputChannel BIC_targetVelX = new BrainInputChannel(ref targetVelX, false, "targetVelX");
        inputChannelsList.Add (BIC_targetVelX); // 3
        BrainInputChannel BIC_targetDirX = new BrainInputChannel(ref targetDirX, false, "targetDirX");
        inputChannelsList.Add (BIC_targetDirX); // 4
        // Brain Outputs!:

        outputChannelsList = new List<BrainOutputChannel>();
        BrainOutputChannel BOC_ownVelX = new BrainOutputChannel(ref ownVelX, false, "ownVelX");
        outputChannelsList.Add (BOC_ownVelX); // 0

        fitnessComponentList = new List<FitnessComponent>();
        FitnessComponent FC_dotProduct = new FitnessComponent(ref fitDotProduct, false, true, 1f, 1f, "Dot Product To Target", true);
        fitnessComponentList.Add (FC_dotProduct); // 0
        FitnessComponent FC_timeToTarget = new FitnessComponent(ref fitTimeToTarget, false, false, 1f, 1f, "Time To Target", true);
        fitnessComponentList.Add (FC_timeToTarget); // 1
        FitnessComponent FC_distanceToTarget = new FitnessComponent(ref fitDistanceToTarget, false, false, 1f, 1f, "Distance To Target", true);
        fitnessComponentList.Add (FC_distanceToTarget); // 2
        FitnessComponent FC_reachTarget = new FitnessComponent(ref fitReachTarget, false, true, 1f, 1f, "Reaches Target", false);
        fitnessComponentList.Add (FC_reachTarget); // 3

        Reset();
    }
Exemplo n.º 2
0
    // Constructor!!
    public MiniGamePhysXWorm()
    {
        piecesBuilt = false;  // This refers to if the pieces have all their components and are ready for Simulation, not simply instantiated empty GO's
        gameInitialized = false;  // Reset() is Initialization
        gameTicked = false;  // Has the game been ticked on its current TimeStep
        gameUpdatedFromPhysX = false;  // Did the game just get updated from PhysX Simulation?
        gameCurrentTimeStep = 0;  // Should only be able to increment this if the above are true (which means it went through gameLoop for this timeStep)

        sa_x = new float[numberOfSegments];
        sa_y = new float[numberOfSegments];
        sa_z = new float[numberOfSegments];
        targetPosX = new float[1];
        targetPosY = new float[1];
        targetPosZ = new float[1];
        targetDirX = new float[1];
        targetDirY = new float[1];
        targetDirZ = new float[1];
        targetDirX[0] = 0f;
        targetDirY[0] = 0f;
        targetDirZ[0] = 0f;

        armTotalLength[0] = 2.0f;
        GOwormSegments = new GameObject[numberOfSegments];
        wormSegmentArray_PosX = new float[numberOfSegments][];
        wormSegmentArray_PosY = new float[numberOfSegments][];
        wormSegmentArray_PosZ = new float[numberOfSegments][];
        wormSegmentArray_Angle = new float[numberOfSegments][];;
        wormSegmentArray_MotorTarget = new float[numberOfSegments][];;
        wormSegmentArray_Length = new float[numberOfSegments][];;

        //GOtargetSphere = new GameObject("GOtargetSphere");
        //GOtargetSphere.transform.localScale = new Vector3(targetRadius, targetRadius, targetRadius);

        for(int i = 0; i < numberOfSegments; i++) {
            //string name = "GOwormSegment" + i.ToString();
            //GOwormSegments[i] = new GameObject(name);
            //GOwormSegments[i].transform.localPosition = new Vector3(0f, 0f, 0f); // RE-EVALUATE!!!
            wormSegmentArray_PosX[i] = new float[1];
            wormSegmentArray_PosY[i] = new float[1];
            wormSegmentArray_PosZ[i] = new float[1];
            wormSegmentArray_Angle[i] = new float[1];
            wormSegmentArray_MotorTarget[i] = new float[1];
            wormSegmentArray_Length[i] = new float[1];
            // Calculate surface areas for each face:
            wormSegmentArray_Length[i][0] = armTotalLength[0]/(float)numberOfSegments;
            //GOwormSegments[i].transform.localScale = new Vector3(wormSegmentArray_Length[i][0], wormSegmentThickness, wormSegmentThickness*2f);
            //sa_x[i] = GOwormSegments[i].transform.localScale.y * GOwormSegments[i].transform.localScale.z;
            //sa_y[i] = GOwormSegments[i].transform.localScale.x * GOwormSegments[i].transform.localScale.z;
            //sa_z[i] = GOwormSegments[i].transform.localScale.x * GOwormSegments[i].transform.localScale.y;
        }

        fitDistFromOrigin[0] = 0f;
        fitEnergySpent[0] = 0f;
        fitDistToTarget[0] = 0f;
        fitTimeToTarget[0] = 0f;

        // Brain Inputs!:
        inputChannelsList = new List<BrainInputChannel>();
        BrainInputChannel BIC_targetDirX = new BrainInputChannel(ref targetDirX, false, "TargetDir X");
        inputChannelsList.Add (BIC_targetDirX);
        BrainInputChannel BIC_targetDirY = new BrainInputChannel(ref targetDirY, false, "TargetDir Y");
        inputChannelsList.Add (BIC_targetDirY);
        BrainInputChannel BIC_targetDirZ = new BrainInputChannel(ref targetDirZ, false, "TargetDir Z");
        inputChannelsList.Add (BIC_targetDirZ);
        // Brain Outputs!:
        outputChannelsList = new List<BrainOutputChannel>();

        for(int bc = 0; bc < numberOfSegments; bc++) {
            string inputChannelName = "Worm Segment " + bc.ToString() + " Angle";
            BrainInputChannel BIC_wormSegmentAngle = new BrainInputChannel(ref wormSegmentArray_Angle[bc], false, inputChannelName);
            inputChannelsList.Add (BIC_wormSegmentAngle);

            string outputChannelName = "Worm Segment " + bc.ToString() + " Motor Target";
            BrainOutputChannel BOC_wormSegmentAngleVel = new BrainOutputChannel(ref wormSegmentArray_MotorTarget[bc], false, outputChannelName);
            outputChannelsList.Add (BOC_wormSegmentAngleVel);
        }

        fitnessComponentList = new List<FitnessComponent>();
        FitnessComponent FC_distFromOrigin = new FitnessComponent(ref fitDistFromOrigin, true, true, 1f, 1f, "Distance From Origin", true);
        fitnessComponentList.Add (FC_distFromOrigin); // 0
        FitnessComponent FC_energySpent = new FitnessComponent(ref fitEnergySpent, true, false, 1f, 1f, "Energy Spent", true);
        fitnessComponentList.Add (FC_energySpent); // 1
        FitnessComponent FC_distToTarget = new FitnessComponent(ref fitDistToTarget, true, false, 1f, 1f, "Distance To Target", false);
        fitnessComponentList.Add (FC_distToTarget); // 2
        FitnessComponent FC_timeToTarget = new FitnessComponent(ref fitTimeToTarget, true, false, 1f, 1f, "Time To Target", true);
        fitnessComponentList.Add (FC_timeToTarget); // 3

        //Reset();
    }
Exemplo n.º 3
0
    public void RebuildCritterFromGenomeRecursive(bool physicsOn, bool useSegments, float variableMass, bool editor) {
        //Debug.Log("RebuildCritterFromGenomeRecursive: " + physicsOn.ToString() + ", " + useSegments.ToString() + ", " + variableMass.ToString() + ", " + editor.ToString());
        BoundingBoxMinCorner = Vector3.zero;
        BoundingBoxMaxCorner = Vector3.zero;
        // IMPROVE THIS SO IT WORKS FOR BOTH CritterConstructer AND Trainer
        if (!editor)
            masterCritterGenome.PreBuildCritter(variableMass);
        // Delete existing Segment GameObjects
        if(!useSegments || editor)
            DeleteSegments();
        // Is this the best way to clear the lists? from a memory standpoint...
        segaddonPhysicalAttributesList.Clear();
        
        segaddonJointAngleSensorList.Clear();
        segaddonContactSensorList.Clear();
        segaddonRaycastSensorList.Clear();
        segaddonCompassSensor1DList.Clear();
        segaddonCompassSensor3DList.Clear();
        segaddonPositionSensor1DList.Clear();
        segaddonPositionSensor3DList.Clear();
        segaddonRotationSensor1DList.Clear();
        segaddonRotationSensor3DList.Clear();
        segaddonVelocitySensor1DList.Clear();
        segaddonVelocitySensor3DList.Clear();
        segaddonAltimeterList.Clear();
        segaddonEarBasicList.Clear();
        segaddonGravitySensorList.Clear();
        segaddonOscillatorInputList.Clear();
        segaddonValueInputList.Clear();
        segaddonTimerInputList.Clear();

        segaddonJointMotorList.Clear();
        segaddonThrusterEffector1DList.Clear();
        segaddonThrusterEffector3DList.Clear();
        segaddonTorqueEffector1DList.Clear();
        segaddonTorqueEffector3DList.Clear();
        segaddonMouthBasicList.Clear();
        segaddonNoiseMakerBasicList.Clear();
        segaddonStickyList.Clear();
        segaddonWeaponBasicList.Clear();        

        InitializeSegmentMaterial();

        if (critterSegmentList != null) {
            critterSegmentList.Clear();
        }
        if(inputChannelsList != null) {
            inputChannelsList.Clear();
        }
        else {
            inputChannelsList = new List<BrainInputChannel>();
        }
        if (outputChannelsList != null) {
            outputChannelsList.Clear();
        }
        else {
            outputChannelsList = new List<BrainOutputChannel>();
        }
        // interpret Genome and construct critter in its bind pose
        bool isPendingChildren = true;
        int currentDepth = 0; // start with RootNode
        int maxDepth = 20;  // safeguard to prevent while loop lock
        int nextSegmentID = 0;
        float critterTotalVolume = 0f;
        List<CritterSegment> builtSegmentsList = new List<CritterSegment>();  // keep track of segments that have been built - linear in-order array 0-n segments
        List<BuildSegmentInfo> currentBuildSegmentList = new List<BuildSegmentInfo>();  // keeps track of all current-depth segment build-requests, and holds important metadata
        List<BuildSegmentInfo> nextBuildSegmentList = new List<BuildSegmentInfo>();  // used to keep track of next childSegments that need to be built

        // ***********  Will attempt to traverse the Segments to be created, keeping track of where on each graph (nodes# & segment#) the current build is on.
        BuildSegmentInfo rootSegmentBuildInfo = new BuildSegmentInfo();
        rootSegmentBuildInfo.sourceNode = masterCritterGenome.CritterNodeList[0];
        currentBuildSegmentList.Add(rootSegmentBuildInfo);  // ROOT NODE IS SPECIAL!        

        // Do a Breadth-first traversal??
        while (isPendingChildren) {
            //int numberOfChildNodes = masterCritterGenome.CritterNodeList[currentNode].attachedJointLinkList.Count;
            
            for (int i = 0; i < currentBuildSegmentList.Count; i++) {
                //Debug.Log("currentDepth: " + currentDepth.ToString() + "builtNodesQueue.Count: " + builtSegmentsList.Count.ToString() + ", pendingNodes: " + currentBuildSegmentList.Count.ToString() + ", i: " + i.ToString());
                // Iterate through pending nodes
                // Build current node --> Segment
                GameObject newGO = new GameObject("Node" + nextSegmentID.ToString());
                CritterSegment newSegment = newGO.AddComponent<CritterSegment>();
                builtSegmentsList.Add(newSegment);
                newGO.layer = LayerMask.NameToLayer("editorSegment"); ; // set segmentGO layer to editorSegment, to distinguish it from Gizmos
                
                newGO.transform.SetParent(this.gameObject.transform);
                if (useSegments) {
                    newGO.GetComponent<MeshRenderer>().material = critterSegmentMaterial;
                    newGO.GetComponent<MeshRenderer>().material.SetFloat("_DisplayTarget", 0f);
                    newGO.GetComponent<MeshRenderer>().material.SetFloat("_Selected", 0f);
                    newGO.AddComponent<BoxCollider>().isTrigger = false;                    
                    critterSegmentList.Add(newGO);  // Add to master Linear list of Segments
                }
                else {
                    newGO.SetActive(false);
                }  
  
                newSegment.InitGamePiece();  // create the mesh and some other initialization stuff
                newSegment.sourceNode = currentBuildSegmentList[i].sourceNode;
                newSegment.id = nextSegmentID;
                nextSegmentID++;
                
                if (currentBuildSegmentList[i].sourceNode.ID == 0) {  // is ROOT segment  -- Look into doing Root build BEFORE for loop to avoid the need to do this check
                    newGO.transform.position = masterCritterGenome.centerOfMassOffset;
                    newGO.transform.rotation = Quaternion.identity;
                    newSegment.scalingFactor = newSegment.sourceNode.jointLink.recursionScalingFactor;
                    newGO.transform.localScale = currentBuildSegmentList[i].sourceNode.dimensions * newSegment.scalingFactor;
                    critterTotalVolume += newGO.transform.localScale.x * newGO.transform.localScale.y * newGO.transform.localScale.z;
                    newSegment.surfaceArea = new Vector3(newGO.transform.localScale.y * newGO.transform.localScale.z * 2f, newGO.transform.localScale.x * newGO.transform.localScale.z * 2f, newGO.transform.localScale.x * newGO.transform.localScale.y * 2f);
                    
                }
                else {  // if NOT root segment, can consider parent-related stuff:
                    
                    newSegment.parentSegment = currentBuildSegmentList[i].parentSegment;
                    // Inherit Axis-Inversions from parent segment:
                    newSegment.mirrorX = newSegment.parentSegment.mirrorX;
                    newSegment.mirrorY = newSegment.parentSegment.mirrorY;
                    newSegment.mirrorZ = newSegment.parentSegment.mirrorZ;
                    // inherit scaling factor from parent -- this is later adjusted again if it is part of a recursion chain
                    newSegment.scalingFactor = newSegment.parentSegment.scalingFactor;
                    newSegment.scalingFactor *= currentBuildSegmentList[i].sourceNode.jointLink.recursionScalingFactor; // propagate scaling factor
                    // Check for if the segment currently being built is a Mirror COPY:
                    if (currentBuildSegmentList[i].isMirror) {
                        //Debug.Log("This is a MIRROR COPY segment - Wow!");
                        if(currentBuildSegmentList[i].sourceNode.jointLink.symmetryType == CritterJointLink.SymmetryType.MirrorX) {
                            // Invert the X-axis  (this will propagate down to all this segment's children
                            newSegment.mirrorX = !newSegment.mirrorX;
                        }
                        else if (currentBuildSegmentList[i].sourceNode.jointLink.symmetryType == CritterJointLink.SymmetryType.MirrorY) {
                            newSegment.mirrorY = !newSegment.mirrorY;
                        }
                        //else if (currentBuildSegmentList[i].sourceNode.jointLink.symmetryType == CritterJointLink.SymmetryType.MirrorZ) {
                        //    newSegment.mirrorZ = !newSegment.mirrorZ;
                        //}
                    }
                }
                if (physicsOn) {
                    newGO.AddComponent<Rigidbody>().isKinematic = false;
                    if(editor && currentBuildSegmentList[i].sourceNode.ID == 0)
                        newGO.GetComponent<Rigidbody>().isKinematic = true;


                    if(editor) {  // TEMPORARY!!!! if editor && physX, build critterMesh so hide segments!
                        //newGO.GetComponent<MeshRenderer>().enabled = false;
                    }
                    //newGO.GetComponent<Rigidbody>().drag = 20f;
                    //newGO.GetComponent<Rigidbody>().angularDrag = 20f;
                    // Bouncy Root:
                    //GameObject anchorGO = new GameObject("Anchor");
                    //anchorGO.transform.SetParent(this.gameObject.transform);
                    //anchorGO.AddComponent<Rigidbody>().isKinematic = true;
                    /*ConfigurableJoint configJoint = newGO.AddComponent<ConfigurableJoint>();
                    configJoint.autoConfigureConnectedAnchor = false;
                    configJoint.connectedBody = anchorGO.GetComponent<Rigidbody>();
                    configJoint.anchor = new Vector3(0f, 0f, 0f);
                    configJoint.connectedAnchor = new Vector3(0f, 0f, 0f);
                    configJoint.xMotion = ConfigurableJointMotion.Locked;
                    configJoint.yMotion = ConfigurableJointMotion.Locked;
                    configJoint.zMotion = ConfigurableJointMotion.Locked;
                    configJoint.angularXMotion = ConfigurableJointMotion.Locked;
                    configJoint.angularYMotion = ConfigurableJointMotion.Locked;
                    configJoint.angularZMotion = ConfigurableJointMotion.Locked;
                    SoftJointLimitSpring limitSpring = configJoint.linearLimitSpring;
                    limitSpring.spring = 80f;
                    limitSpring.damper = 800f;
                    configJoint.linearLimitSpring = limitSpring;
                    SoftJointLimit jointLimit = configJoint.linearLimit;
                    jointLimit.limit = 0.01f;
                    jointLimit.bounciness = 0.01f;
                    configJoint.linearLimit = jointLimit;
                    configJoint.angularXLimitSpring = limitSpring;
                    configJoint.angularYZLimitSpring = limitSpring;
                    */
                }

                // CHECK FOR RECURSION:
                if (currentBuildSegmentList[i].sourceNode.jointLink.numberOfRecursions > 0) { // if the node being considered has recursions:
                    //Debug.Log("currentNode: " + currentBuildSegmentList[i].sourceNode.ID.ToString() + "newSegmentRecursion#: " + newSegment.recursionNumber.ToString() + ", parentRecursion#: " + currentBuildSegmentList[i].parentSegment.recursionNumber.ToString());
                    if (newSegment.sourceNode == currentBuildSegmentList[i].parentSegment.sourceNode) {  // if this segment's sourceNode is the same is its parent Segment's sourceNode, then it is not the root of the recursion chain!
                        //Debug.Log("newSegment.sourceNode == currentBuildNodeParentSegmentList[i].sourceNode!");

                        // Are we at the end of a recursion chain?
                        if (currentBuildSegmentList[i].parentSegment.recursionNumber >= currentBuildSegmentList[i].sourceNode.jointLink.numberOfRecursions) {
                            //Debug.Log("recursion number greater than numRecursions! ( " + currentBuildSegmentList[i].parentSegment.recursionNumber.ToString() + " vs " + currentBuildSegmentList[i].sourceNode.jointLink.numberOfRecursions.ToString());
                            newSegment.recursionNumber = currentBuildSegmentList[i].parentSegment.recursionNumber + 1; //
                            //newSegment.scalingFactor *= currentBuildSegmentList[i].sourceNode.jointLink.recursionScalingFactor;
                        }
                        else {  // create new recursion instance!!
                            BuildSegmentInfo newSegmentInfo = new BuildSegmentInfo();
                            newSegmentInfo.sourceNode = currentBuildSegmentList[i].sourceNode;  // request a segment to be built again based on the current sourceNode
                            newSegment.recursionNumber = currentBuildSegmentList[i].parentSegment.recursionNumber + 1;
                            //newSegment.scalingFactor *= currentBuildSegmentList[i].sourceNode.jointLink.recursionScalingFactor; // propagate scaling factor
                            newSegmentInfo.parentSegment = newSegment; // parent of itself (the just-built Segment)
                            nextBuildSegmentList.Add(newSegmentInfo);
                            // If the node also has Symmetry:
                            if (newSegmentInfo.sourceNode.jointLink.symmetryType != CritterJointLink.SymmetryType.None) {
                                // the child node has some type of symmetry, so add a buildOrder for a mirrored Segment:
                                BuildSegmentInfo newSegmentInfoMirror = new BuildSegmentInfo();
                                newSegmentInfoMirror.sourceNode = currentBuildSegmentList[i].sourceNode;  // uses same sourceNode, but tags as Mirror:
                                newSegmentInfoMirror.isMirror = true;  // This segment is the COPY, not the original
                                newSegmentInfoMirror.parentSegment = newSegment;  // 
                                nextBuildSegmentList.Add(newSegmentInfoMirror);
                            }
                        }
                    }
                    else { // this is the root --- its sourceNode has recursion, and this segment is unique from its parentNode:
                        BuildSegmentInfo newSegmentInfo = new BuildSegmentInfo();
                        newSegmentInfo.sourceNode = currentBuildSegmentList[i].sourceNode;
                        newSegment.recursionNumber = 1;
                        newSegmentInfo.parentSegment = newSegment;
                        nextBuildSegmentList.Add(newSegmentInfo);
                        // If the node also has Symmetry:
                        if (newSegmentInfo.sourceNode.jointLink.symmetryType != CritterJointLink.SymmetryType.None) {
                            // the child node has some type of symmetry, so add a buildOrder for a mirrored Segment:
                            BuildSegmentInfo newSegmentInfoMirror = new BuildSegmentInfo();
                            newSegmentInfoMirror.sourceNode = currentBuildSegmentList[i].sourceNode;  // uses same sourceNode, but tags as Mirror:
                            newSegmentInfoMirror.isMirror = true;  // This segment is the COPY, not the original
                            newSegmentInfoMirror.parentSegment = newSegment;  // 
                            nextBuildSegmentList.Add(newSegmentInfoMirror);
                        }
                    }
                }

                // PositionSEGMENT GameObject!!!
                if (newSegment.id == 0) {  // if ROOT NODE:

                }
                else {
                    SetSegmentTransform(newGO);  // Properly position the SegmentGO where it should be  && scale!
                    critterTotalVolume += newGO.transform.localScale.x * newGO.transform.localScale.y * newGO.transform.localScale.z;
                    if (physicsOn) {
                        //newGO.GetComponent<Rigidbody>().isKinematic = false;
                        newGO.GetComponent<Rigidbody>().ResetInertiaTensor();
                        ConfigurableJoint configJoint = newGO.AddComponent<ConfigurableJoint>();
                        configJoint.autoConfigureConnectedAnchor = false;
                        configJoint.connectedBody = newSegment.parentSegment.gameObject.GetComponent<Rigidbody>();
                        configJoint.anchor = GetJointAnchor(newSegment);
                        configJoint.connectedAnchor = GetJointConnectedAnchor(newSegment); // <-- Might be Unnecessary
                        ConfigureJointSettings(newSegment, ref configJoint);  // UPDATE THIS TO USE segaddonJointMotorSettings!?!?
                    }
                }
                // Check boundingBox:
                //BoundingBox
                CheckBoundingBox(newGO);                

                // SEGMENT ADDONS:
                if (physicsOn) {
                    // Check for Physical Attributes:
                    List<AddonPhysicalAttributes> physicalAttributesList = masterCritterGenome.CheckForAddonPhysicalAttributes(currentBuildSegmentList[i].sourceNode.ID);
                    for(int a = 0; a < physicalAttributesList.Count; a++) {
                        SegaddonPhysicalAttributes newPhysicalAttributes = new SegaddonPhysicalAttributes(physicalAttributesList[a]);
                        newPhysicalAttributes.segmentID = newSegment.id;
                        segaddonPhysicalAttributesList.Add(newPhysicalAttributes);
                        
                        segmentPhysicMaterial.dynamicFriction = newPhysicalAttributes.dynamicFriction[0];
                        segmentPhysicMaterial.staticFriction = newPhysicalAttributes.staticFriction[0];
                        segmentPhysicMaterial.bounciness = newPhysicalAttributes.bounciness[0];
                        RigidbodyConstraints rbConstraints = newGO.GetComponent<Rigidbody>().constraints;
                        if (newPhysicalAttributes.freezePositionX[0]) {
                            rbConstraints = rbConstraints | RigidbodyConstraints.FreezePositionX;
                        }
                        if (newPhysicalAttributes.freezePositionY[0]) {
                            rbConstraints = rbConstraints | RigidbodyConstraints.FreezePositionY;
                        }
                        if (newPhysicalAttributes.freezePositionZ[0]) {
                            rbConstraints = rbConstraints | RigidbodyConstraints.FreezePositionZ;
                        }
                        if (newPhysicalAttributes.freezeRotationX[0]) {
                            rbConstraints = rbConstraints | RigidbodyConstraints.FreezeRotationX;
                        }
                        if (newPhysicalAttributes.freezeRotationY[0]) {
                            rbConstraints = rbConstraints | RigidbodyConstraints.FreezeRotationY;
                        }
                        if (newPhysicalAttributes.freezeRotationZ[0]) {
                            rbConstraints = rbConstraints | RigidbodyConstraints.FreezeRotationZ;
                        }
                        newGO.GetComponent<Rigidbody>().constraints = rbConstraints;
                        newGO.GetComponent<BoxCollider>().material = segmentPhysicMaterial;
                    }

                    #region INPUTS
                    List<AddonJointAngleSensor> jointAngleSensorList = masterCritterGenome.CheckForAddonJointAngleSensor(currentBuildSegmentList[i].sourceNode.ID);
                    for (int j = 0; j < jointAngleSensorList.Count; j++) {
                        SegaddonJointAngleSensor newJointAngleSensor = new SegaddonJointAngleSensor(jointAngleSensorList[j]);
                        newJointAngleSensor.segmentID = newSegment.id;
                        segaddonJointAngleSensorList.Add(newJointAngleSensor);
                                                
                        if (currentBuildSegmentList[i].sourceNode.jointLink.jointType == CritterJointLink.JointType.HingeX) {
                            string inputChannelName = "Segment " + newJointAngleSensor.segmentID.ToString() + " AngleX";
                            BrainInputChannel BIC_SegmentAngle = new BrainInputChannel(ref newJointAngleSensor.angleX, true, inputChannelName);
                            inputChannelsList.Add(BIC_SegmentAngle);

                            if (newJointAngleSensor.measureVel) {
                                inputChannelName = "Segment " + newJointAngleSensor.segmentID.ToString() + " AngleVelX";
                                BrainInputChannel BIC_SegmentAngleVel = new BrainInputChannel(ref newJointAngleSensor.angleVelX, true, inputChannelName);
                                inputChannelsList.Add(BIC_SegmentAngleVel);
                            }
                        }
                        else if (currentBuildSegmentList[i].sourceNode.jointLink.jointType == CritterJointLink.JointType.HingeY) {
                            string inputChannelName = "Segment " + newJointAngleSensor.segmentID.ToString() + " AngleY";
                            BrainInputChannel BIC_SegmentAngle = new BrainInputChannel(ref newJointAngleSensor.angleY, true, inputChannelName);
                            inputChannelsList.Add(BIC_SegmentAngle);

                            if (newJointAngleSensor.measureVel) {
                                inputChannelName = "Segment " + newJointAngleSensor.segmentID.ToString() + " AngleVelY";
                                BrainInputChannel BIC_SegmentAngleVel = new BrainInputChannel(ref newJointAngleSensor.angleVelY, true, inputChannelName);
                                inputChannelsList.Add(BIC_SegmentAngleVel);
                            }
                        }
                        else if (currentBuildSegmentList[i].sourceNode.jointLink.jointType == CritterJointLink.JointType.HingeZ) {
                            string inputChannelName = "Segment " + newJointAngleSensor.segmentID.ToString() + " AngleZ";
                            BrainInputChannel BIC_SegmentAngle = new BrainInputChannel(ref newJointAngleSensor.angleZ, true, inputChannelName);
                            inputChannelsList.Add(BIC_SegmentAngle);

                            if (newJointAngleSensor.measureVel) {
                                inputChannelName = "Segment " + newJointAngleSensor.segmentID.ToString() + " AngleVelZ";
                                BrainInputChannel BIC_SegmentAngleVel = new BrainInputChannel(ref newJointAngleSensor.angleVelZ, true, inputChannelName);
                                inputChannelsList.Add(BIC_SegmentAngleVel);
                            }
                        }
                        else if (currentBuildSegmentList[i].sourceNode.jointLink.jointType == CritterJointLink.JointType.DualXY) {
                            string inputChannelName = "Segment " + newJointAngleSensor.segmentID.ToString() + " AngleX";
                            BrainInputChannel BIC_SegmentAngleX = new BrainInputChannel(ref newJointAngleSensor.angleX, true, inputChannelName);
                            inputChannelsList.Add(BIC_SegmentAngleX);

                            inputChannelName = "Segment " + newJointAngleSensor.segmentID.ToString() + " AngleY";
                            BrainInputChannel BIC_SegmentAngleY = new BrainInputChannel(ref newJointAngleSensor.angleY, true, inputChannelName);
                            inputChannelsList.Add(BIC_SegmentAngleY);

                            if (newJointAngleSensor.measureVel) {
                                inputChannelName = "Segment " + newJointAngleSensor.segmentID.ToString() + " AngleVelX";
                                BrainInputChannel BIC_SegmentAngleVelX = new BrainInputChannel(ref newJointAngleSensor.angleVelX, true, inputChannelName);
                                inputChannelsList.Add(BIC_SegmentAngleVelX);

                                inputChannelName = "Segment " + newJointAngleSensor.segmentID.ToString() + " AngleVelY";
                                BrainInputChannel BIC_SegmentAngleVelY = new BrainInputChannel(ref newJointAngleSensor.angleVelY, true, inputChannelName);
                                inputChannelsList.Add(BIC_SegmentAngleVelY);
                            }
                        }
                    }
                    List<AddonContactSensor> contactSensorList = masterCritterGenome.CheckForAddonContactSensor(currentBuildSegmentList[i].sourceNode.ID);
                    for (int j = 0; j < contactSensorList.Count; j++) {
                        SegaddonContactSensor newContactSensor = new SegaddonContactSensor(contactSensorList[j]);
                        newContactSensor.segmentID = newSegment.id;
                        segaddonContactSensorList.Add(newContactSensor);
                        SegaddonCollisionDetector collisionDetector = newGO.AddComponent<SegaddonCollisionDetector>();
                        collisionDetector.referencedContactSensor = newContactSensor;

                        string inputChannelName = "Segment " + newContactSensor.segmentID.ToString() + " Contact Sensor";
                        BrainInputChannel BIC_SegmentContactInput = new BrainInputChannel(ref newContactSensor.contactStatus, true, inputChannelName);
                        inputChannelsList.Add(BIC_SegmentContactInput);
                    }
                    List<AddonRaycastSensor> raycastSensorList = masterCritterGenome.CheckForAddonRaycastSensor(currentBuildSegmentList[i].sourceNode.ID);
                    for (int j = 0; j < raycastSensorList.Count; j++) {
                        SegaddonRaycastSensor newRaycastSensor = new SegaddonRaycastSensor(raycastSensorList[j]);
                        newRaycastSensor.segmentID = newSegment.id;
                        segaddonRaycastSensorList.Add(newRaycastSensor);

                        string inputChannelName = "Segment " + newRaycastSensor.segmentID.ToString() + " Raycast Sensor(dist)";
                        BrainInputChannel BIC_SegmentRaycastInput = new BrainInputChannel(ref newRaycastSensor.distance, true, inputChannelName);
                        inputChannelsList.Add(BIC_SegmentRaycastInput);
                    }
                    List<AddonCompassSensor1D> compassSensor1DList = masterCritterGenome.CheckForAddonCompassSensor1D(currentBuildSegmentList[i].sourceNode.ID);
                    for (int j = 0; j < compassSensor1DList.Count; j++) {
                        SegaddonCompassSensor1D newCompassSensor1D = new SegaddonCompassSensor1D(compassSensor1DList[j]);
                        newCompassSensor1D.segmentID = newSegment.id;
                        segaddonCompassSensor1DList.Add(newCompassSensor1D);

                        string inputChannelName = "Segment " + newCompassSensor1D.segmentID.ToString() + " Compass1D";
                        BrainInputChannel BIC_SegmentCompass1DInput = new BrainInputChannel(ref newCompassSensor1D.dotProduct, true, inputChannelName);
                        inputChannelsList.Add(BIC_SegmentCompass1DInput);
                    }
                    List<AddonCompassSensor3D> compassSensor3DList = masterCritterGenome.CheckForAddonCompassSensor3D(currentBuildSegmentList[i].sourceNode.ID);
                    for (int j = 0; j < compassSensor3DList.Count; j++) {
                        SegaddonCompassSensor3D newCompassSensor3D = new SegaddonCompassSensor3D(compassSensor3DList[j]);
                        newCompassSensor3D.segmentID = newSegment.id;
                        segaddonCompassSensor3DList.Add(newCompassSensor3D);

                        string inputChannelName = "Segment " + newCompassSensor3D.segmentID.ToString() + " Compass3D Right";
                        BrainInputChannel BIC_SegmentCompass3DInputRight = new BrainInputChannel(ref newCompassSensor3D.dotProductRight, true, inputChannelName);
                        inputChannelsList.Add(BIC_SegmentCompass3DInputRight);

                        inputChannelName = "Segment " + newCompassSensor3D.segmentID.ToString() + " Compass3D Up";
                        BrainInputChannel BIC_SegmentCompass3DInputUp = new BrainInputChannel(ref newCompassSensor3D.dotProductUp, true, inputChannelName);
                        inputChannelsList.Add(BIC_SegmentCompass3DInputUp);

                        inputChannelName = "Segment " + newCompassSensor3D.segmentID.ToString() + " Compass3D Forward";
                        BrainInputChannel BIC_SegmentCompass3DInputForward = new BrainInputChannel(ref newCompassSensor3D.dotProductForward, true, inputChannelName);
                        inputChannelsList.Add(BIC_SegmentCompass3DInputForward);
                    }
                    List<AddonPositionSensor1D> positionSensor1DList = masterCritterGenome.CheckForAddonPositionSensor1D(currentBuildSegmentList[i].sourceNode.ID);
                    for (int j = 0; j < positionSensor1DList.Count; j++) {
                        SegaddonPositionSensor1D newPositionSensor1D = new SegaddonPositionSensor1D(positionSensor1DList[j]);
                        newPositionSensor1D.segmentID = newSegment.id;
                        segaddonPositionSensor1DList.Add(newPositionSensor1D);

                        string inputChannelName = "Segment " + newPositionSensor1D.segmentID.ToString() + " Position1D Forward";
                        BrainInputChannel BIC_SegmentPosition1DInput = new BrainInputChannel(ref newPositionSensor1D.linearDistance, true, inputChannelName);
                        inputChannelsList.Add(BIC_SegmentPosition1DInput);
                    }
                    List<AddonPositionSensor3D> positionSensor3DList = masterCritterGenome.CheckForAddonPositionSensor3D(currentBuildSegmentList[i].sourceNode.ID);
                    for (int j = 0; j < positionSensor3DList.Count; j++) {
                        SegaddonPositionSensor3D newPositionSensor3D = new SegaddonPositionSensor3D(positionSensor3DList[j]);
                        newPositionSensor3D.segmentID = newSegment.id;
                        segaddonPositionSensor3DList.Add(newPositionSensor3D);

                        string inputChannelName = "Segment " + newPositionSensor3D.segmentID.ToString() + " Position3D Right";
                        BrainInputChannel BIC_SegmentPosition3DInputRight = new BrainInputChannel(ref newPositionSensor3D.distanceRight, true, inputChannelName);
                        inputChannelsList.Add(BIC_SegmentPosition3DInputRight);

                        inputChannelName = "Segment " + newPositionSensor3D.segmentID.ToString() + " Position3D Up";
                        BrainInputChannel BIC_SegmentPosition3DInputUp = new BrainInputChannel(ref newPositionSensor3D.distanceUp, true, inputChannelName);
                        inputChannelsList.Add(BIC_SegmentPosition3DInputUp);

                        inputChannelName = "Segment " + newPositionSensor3D.segmentID.ToString() + " Position3D Forward";
                        BrainInputChannel BIC_SegmentPosition3DInputForward = new BrainInputChannel(ref newPositionSensor3D.distanceForward, true, inputChannelName);
                        inputChannelsList.Add(BIC_SegmentPosition3DInputForward);
                    }
                    List<AddonRotationSensor1D> rotationSensor1DList = masterCritterGenome.CheckForAddonRotationSensor1D(currentBuildSegmentList[i].sourceNode.ID);
                    for (int j = 0; j < rotationSensor1DList.Count; j++) {
                        SegaddonRotationSensor1D newRotationSensor1D = new SegaddonRotationSensor1D(rotationSensor1DList[j]);
                        newRotationSensor1D.segmentID = newSegment.id;
                        segaddonRotationSensor1DList.Add(newRotationSensor1D);

                        string inputChannelName = "Segment " + newRotationSensor1D.segmentID.ToString() + " Rotation1D";
                        BrainInputChannel BIC_SegmentRotation1DInput = new BrainInputChannel(ref newRotationSensor1D.rotationRate, true, inputChannelName);
                        inputChannelsList.Add(BIC_SegmentRotation1DInput);
                    }
                    List<AddonRotationSensor3D> rotationSensor3DList = masterCritterGenome.CheckForAddonRotationSensor3D(currentBuildSegmentList[i].sourceNode.ID);
                    for (int j = 0; j < rotationSensor3DList.Count; j++) {
                        SegaddonRotationSensor3D newRotationSensor3D = new SegaddonRotationSensor3D(rotationSensor3DList[j]);
                        newRotationSensor3D.segmentID = newSegment.id;
                        segaddonRotationSensor3DList.Add(newRotationSensor3D);

                        string inputChannelName = "Segment " + newRotationSensor3D.segmentID.ToString() + " Rotation3D X";
                        BrainInputChannel BIC_SegmentRotation3DInputX = new BrainInputChannel(ref newRotationSensor3D.rotationRateX, true, inputChannelName);
                        inputChannelsList.Add(BIC_SegmentRotation3DInputX);

                        inputChannelName = "Segment " + newRotationSensor3D.segmentID.ToString() + " Rotation3D Y";
                        BrainInputChannel BIC_SegmentRotation3DInputY = new BrainInputChannel(ref newRotationSensor3D.rotationRateY, true, inputChannelName);
                        inputChannelsList.Add(BIC_SegmentRotation3DInputY);

                        inputChannelName = "Segment " + newRotationSensor3D.segmentID.ToString() + " Rotation3D Z";
                        BrainInputChannel BIC_SegmentRotation3DInputZ = new BrainInputChannel(ref newRotationSensor3D.rotationRateZ, true, inputChannelName);
                        inputChannelsList.Add(BIC_SegmentRotation3DInputZ);
                    }
                    List<AddonVelocitySensor1D> velocitySensor1DList = masterCritterGenome.CheckForAddonVelocitySensor1D(currentBuildSegmentList[i].sourceNode.ID);
                    for (int j = 0; j < velocitySensor1DList.Count; j++) {
                        SegaddonVelocitySensor1D newVelocitySensor1D = new SegaddonVelocitySensor1D(velocitySensor1DList[j]);
                        newVelocitySensor1D.segmentID = newSegment.id;
                        segaddonVelocitySensor1DList.Add(newVelocitySensor1D);

                        string inputChannelName = "Segment " + newVelocitySensor1D.segmentID.ToString() + " Velocity1D";
                        BrainInputChannel BIC_SegmentVelocity1DInput = new BrainInputChannel(ref newVelocitySensor1D.componentVelocity, true, inputChannelName);
                        inputChannelsList.Add(BIC_SegmentVelocity1DInput);
                    }
                    List<AddonVelocitySensor3D> velocitySensor3DList = masterCritterGenome.CheckForAddonVelocitySensor3D(currentBuildSegmentList[i].sourceNode.ID);
                    for (int j = 0; j < velocitySensor3DList.Count; j++) {
                        SegaddonVelocitySensor3D newVelocitySensor3D = new SegaddonVelocitySensor3D(velocitySensor3DList[j]);
                        newVelocitySensor3D.segmentID = newSegment.id;
                        segaddonVelocitySensor3DList.Add(newVelocitySensor3D);

                        string inputChannelName = "Segment " + newVelocitySensor3D.segmentID.ToString() + " Velocity3D Right";
                        BrainInputChannel BIC_SegmentVelocity3DInputRight = new BrainInputChannel(ref newVelocitySensor3D.velocityRight, true, inputChannelName);
                        inputChannelsList.Add(BIC_SegmentVelocity3DInputRight);

                        inputChannelName = "Segment " + newVelocitySensor3D.segmentID.ToString() + " Velocity3D Up";
                        BrainInputChannel BIC_SegmentVelocity3DInputUp = new BrainInputChannel(ref newVelocitySensor3D.velocityUp, true, inputChannelName);
                        inputChannelsList.Add(BIC_SegmentVelocity3DInputUp);

                        inputChannelName = "Segment " + newVelocitySensor3D.segmentID.ToString() + " Velocity3D Forward";
                        BrainInputChannel BIC_SegmentVelocity3DInputForward = new BrainInputChannel(ref newVelocitySensor3D.velocityForward, true, inputChannelName);
                        inputChannelsList.Add(BIC_SegmentVelocity3DInputForward);
                    }
                    List<AddonAltimeter> altimeterList = masterCritterGenome.CheckForAddonAltimeter(currentBuildSegmentList[i].sourceNode.ID);
                    for (int j = 0; j < altimeterList.Count; j++) {
                        SegaddonAltimeter newAltimeter = new SegaddonAltimeter(altimeterList[j]);
                        newAltimeter.segmentID = newSegment.id;
                        segaddonAltimeterList.Add(newAltimeter);

                        string inputChannelName = "Segment " + newAltimeter.segmentID.ToString() + " Altimeter";
                        BrainInputChannel BIC_SegmentAltimeterInput = new BrainInputChannel(ref newAltimeter.altitude, true, inputChannelName);
                        inputChannelsList.Add(BIC_SegmentAltimeterInput);
                    }
                    List<AddonEarBasic> earBasicList = masterCritterGenome.CheckForAddonEarBasic(currentBuildSegmentList[i].sourceNode.ID);
                    for (int j = 0; j < earBasicList.Count; j++) {
                        SegaddonEarBasic newEarBasic = new SegaddonEarBasic(earBasicList[j]);
                        newEarBasic.segmentID = newSegment.id;
                        segaddonEarBasicList.Add(newEarBasic);

                        string inputChannelName = "Segment " + newEarBasic.segmentID.ToString() + " Ear Basic";
                        BrainInputChannel BIC_SegmentEarBasicInput = new BrainInputChannel(ref newEarBasic.activation, true, inputChannelName);
                        inputChannelsList.Add(BIC_SegmentEarBasicInput);
                    }
                    List<AddonGravitySensor> gravitySensorList = masterCritterGenome.CheckForAddonGravitySensor(currentBuildSegmentList[i].sourceNode.ID);
                    for (int j = 0; j < gravitySensorList.Count; j++) {
                        SegaddonGravitySensor newGravitySensor = new SegaddonGravitySensor(gravitySensorList[j]);
                        newGravitySensor.segmentID = newSegment.id;
                        segaddonGravitySensorList.Add(newGravitySensor);

                        string inputChannelName = "Segment " + newGravitySensor.segmentID.ToString() + " Gravity Sensor";
                        BrainInputChannel BIC_SegmentGravityInput = new BrainInputChannel(ref newGravitySensor.gravityDot, true, inputChannelName);
                        inputChannelsList.Add(BIC_SegmentGravityInput);
                    }
                    List<AddonOscillatorInput> oscillatorInputList = masterCritterGenome.CheckForAddonOscillatorInput(currentBuildSegmentList[i].sourceNode.ID);
                    for (int j = 0; j < oscillatorInputList.Count; j++) {
                        SegaddonOscillatorInput newOscillatorInput = new SegaddonOscillatorInput(oscillatorInputList[j]);
                        newOscillatorInput.segmentID = newSegment.id;
                        segaddonOscillatorInputList.Add(newOscillatorInput);

                        //SegaddonOscillatorInput oscillatorInput = critterBeingTested.segaddonOscillatorInputList[oscillatorInputIndex];
                        string inputChannelName = "Segment " + newOscillatorInput.segmentID.ToString() + " Oscillator Input";
                        BrainInputChannel BIC_SegmentOscillatorInput = new BrainInputChannel(ref newOscillatorInput.value, true, inputChannelName);
                        inputChannelsList.Add(BIC_SegmentOscillatorInput);
                    }
                    List<AddonValueInput> valueInputList = masterCritterGenome.CheckForAddonValueInput(currentBuildSegmentList[i].sourceNode.ID);
                    for (int j = 0; j < valueInputList.Count; j++) {
                        SegaddonValueInput newValueInput = new SegaddonValueInput(valueInputList[j]);
                        newValueInput.segmentID = newSegment.id;
                        segaddonValueInputList.Add(newValueInput);

                        string inputChannelName = "Segment " + newValueInput.segmentID.ToString() + " Value Input";
                        BrainInputChannel BIC_SegmentValueInput = new BrainInputChannel(ref newValueInput.value, true, inputChannelName);
                        inputChannelsList.Add(BIC_SegmentValueInput);
                    }
                    List<AddonTimerInput> timerInputList = masterCritterGenome.CheckForAddonTimerInput(currentBuildSegmentList[i].sourceNode.ID);
                    for (int j = 0; j < timerInputList.Count; j++) {
                        SegaddonTimerInput newTimerInput = new SegaddonTimerInput(timerInputList[j]);
                        newTimerInput.segmentID = newSegment.id;
                        segaddonTimerInputList.Add(newTimerInput);

                        string inputChannelName = "Segment " + newTimerInput.segmentID.ToString() + " Timer Input";
                        BrainInputChannel BIC_SegmentTimerInput = new BrainInputChannel(ref newTimerInput.value, true, inputChannelName);
                        inputChannelsList.Add(BIC_SegmentTimerInput);
                    }
                    #endregion

                    #region OUTPUTS:
                    List<AddonJointMotor> jointMotorList = masterCritterGenome.CheckForAddonJointMotor(currentBuildSegmentList[i].sourceNode.ID);
                    for (int j = 0; j < jointMotorList.Count; j++) {
                        SegaddonJointMotor newJointMotor = new SegaddonJointMotor(jointMotorList[j]);
                        newJointMotor.segmentID = newSegment.id;
                        segaddonJointMotorList.Add(newJointMotor);

                        //SegaddonJointMotor motor = critterBeingTested.segaddonJointMotorList[motorIndex];
                        if (currentBuildSegmentList[i].sourceNode.jointLink.jointType == CritterJointLink.JointType.HingeX) {
                            string outputChannelName = "Segment " + newJointMotor.segmentID.ToString() + " Motor Target X";
                            BrainOutputChannel BOC_SegmentAngleVel = new BrainOutputChannel(ref newJointMotor.targetAngularX, true, outputChannelName);
                            outputChannelsList.Add(BOC_SegmentAngleVel);
                        }
                        else if (currentBuildSegmentList[i].sourceNode.jointLink.jointType == CritterJointLink.JointType.HingeY) {
                            string outputChannelName = "Segment " + newJointMotor.segmentID.ToString() + " Motor Target Y";
                            BrainOutputChannel BOC_SegmentAngleVel = new BrainOutputChannel(ref newJointMotor.targetAngularY, true, outputChannelName);
                            outputChannelsList.Add(BOC_SegmentAngleVel);
                        }
                        else if (currentBuildSegmentList[i].sourceNode.jointLink.jointType == CritterJointLink.JointType.HingeZ) {
                            string outputChannelName = "Segment " + newJointMotor.segmentID.ToString() + " Motor Target Z";
                            BrainOutputChannel BOC_SegmentAngleVel = new BrainOutputChannel(ref newJointMotor.targetAngularZ, true, outputChannelName);
                            outputChannelsList.Add(BOC_SegmentAngleVel);
                        }
                        else if (currentBuildSegmentList[i].sourceNode.jointLink.jointType == CritterJointLink.JointType.DualXY) {
                            string outputChannelName = "Segment " + newJointMotor.segmentID.ToString() + " Motor Target X";
                            BrainOutputChannel BOC_SegmentAngleVelX = new BrainOutputChannel(ref newJointMotor.targetAngularX, true, outputChannelName);
                            outputChannelsList.Add(BOC_SegmentAngleVelX);

                            outputChannelName = "Segment " + newJointMotor.segmentID.ToString() + " Motor Target Y";
                            BrainOutputChannel BOC_SegmentAngleVelY = new BrainOutputChannel(ref newJointMotor.targetAngularY, true, outputChannelName);
                            outputChannelsList.Add(BOC_SegmentAngleVelY);
                        }
                    }
                    List<AddonThrusterEffector1D> thrusterEffector1DList = masterCritterGenome.CheckForAddonThrusterEffector1D(currentBuildSegmentList[i].sourceNode.ID);
                    for (int j = 0; j < thrusterEffector1DList.Count; j++) {
                        SegaddonThrusterEffector1D newThrusterEffector1D = new SegaddonThrusterEffector1D(thrusterEffector1DList[j]);
                        newThrusterEffector1D.segmentID = newSegment.id;
                        segaddonThrusterEffector1DList.Add(newThrusterEffector1D);

                        string outputChannelName = "Segment " + newThrusterEffector1D.segmentID.ToString() + " Thruster1D";
                        BrainOutputChannel BOC_SegmentThruster1D = new BrainOutputChannel(ref newThrusterEffector1D.throttle, true, outputChannelName);
                        outputChannelsList.Add(BOC_SegmentThruster1D);
                    }
                    List<AddonThrusterEffector3D> thrusterEffector3DList = masterCritterGenome.CheckForAddonThrusterEffector3D(currentBuildSegmentList[i].sourceNode.ID);
                    for (int j = 0; j < thrusterEffector3DList.Count; j++) {
                        SegaddonThrusterEffector3D newThrusterEffector3D = new SegaddonThrusterEffector3D(thrusterEffector3DList[j]);
                        newThrusterEffector3D.segmentID = newSegment.id;
                        segaddonThrusterEffector3DList.Add(newThrusterEffector3D);

                        string outputChannelName = "Segment " + newThrusterEffector3D.segmentID.ToString() + " Thruster3D X";
                        BrainOutputChannel BOC_SegmentThruster3DX = new BrainOutputChannel(ref newThrusterEffector3D.throttleX, true, outputChannelName);
                        outputChannelsList.Add(BOC_SegmentThruster3DX);

                        outputChannelName = "Segment " + newThrusterEffector3D.segmentID.ToString() + " Thruster3D Y";
                        BrainOutputChannel BOC_SegmentThruster3DY = new BrainOutputChannel(ref newThrusterEffector3D.throttleY, true, outputChannelName);
                        outputChannelsList.Add(BOC_SegmentThruster3DY);

                        outputChannelName = "Segment " + newThrusterEffector3D.segmentID.ToString() + " Thruster3D Z";
                        BrainOutputChannel BOC_SegmentThruster3DZ = new BrainOutputChannel(ref newThrusterEffector3D.throttleZ, true, outputChannelName);
                        outputChannelsList.Add(BOC_SegmentThruster3DZ);
                    }
                    List<AddonTorqueEffector1D> torqueEffector1DList = masterCritterGenome.CheckForAddonTorqueEffector1D(currentBuildSegmentList[i].sourceNode.ID);
                    for (int j = 0; j < torqueEffector1DList.Count; j++) {
                        SegaddonTorqueEffector1D newTorqueEffector1D = new SegaddonTorqueEffector1D(torqueEffector1DList[j]);
                        newTorqueEffector1D.segmentID = newSegment.id;
                        segaddonTorqueEffector1DList.Add(newTorqueEffector1D);

                        string outputChannelName = "Segment " + newTorqueEffector1D.segmentID.ToString() + " Torque1D";
                        BrainOutputChannel BOC_SegmentTorque1D = new BrainOutputChannel(ref newTorqueEffector1D.throttle, true, outputChannelName);
                        outputChannelsList.Add(BOC_SegmentTorque1D);
                    }
                    List<AddonTorqueEffector3D> torqueEffector3DList = masterCritterGenome.CheckForAddonTorqueEffector3D(currentBuildSegmentList[i].sourceNode.ID);
                    for (int j = 0; j < torqueEffector3DList.Count; j++) {
                        SegaddonTorqueEffector3D newTorqueEffector3D = new SegaddonTorqueEffector3D(torqueEffector3DList[j]);
                        newTorqueEffector3D.segmentID = newSegment.id;
                        segaddonTorqueEffector3DList.Add(newTorqueEffector3D);

                        string outputChannelName = "Segment " + newTorqueEffector3D.segmentID.ToString() + " Torque3D X";
                        BrainOutputChannel BOC_SegmentTorque3DX = new BrainOutputChannel(ref newTorqueEffector3D.throttleX, true, outputChannelName);
                        outputChannelsList.Add(BOC_SegmentTorque3DX);

                        outputChannelName = "Segment " + newTorqueEffector3D.segmentID.ToString() + " Torque3D Y";
                        BrainOutputChannel BOC_SegmentTorque3DY = new BrainOutputChannel(ref newTorqueEffector3D.throttleY, true, outputChannelName);
                        outputChannelsList.Add(BOC_SegmentTorque3DY);

                        outputChannelName = "Segment " + newTorqueEffector3D.segmentID.ToString() + " Torque3D Z";
                        BrainOutputChannel BOC_SegmentTorque3DZ = new BrainOutputChannel(ref newTorqueEffector3D.throttleZ, true, outputChannelName);
                        outputChannelsList.Add(BOC_SegmentTorque3DZ);
                    }
                    List<AddonMouthBasic> mouthBasicList = masterCritterGenome.CheckForAddonMouthBasic(currentBuildSegmentList[i].sourceNode.ID);
                    for (int j = 0; j < mouthBasicList.Count; j++) {
                        SegaddonMouthBasic newMouthBasic = new SegaddonMouthBasic(mouthBasicList[j]);
                        newMouthBasic.segmentID = newSegment.id;
                        segaddonMouthBasicList.Add(newMouthBasic);

                        SegaddonTriggerDetector triggerDetector = newGO.AddComponent<SegaddonTriggerDetector>();
                        triggerDetector.referencedMouth = newMouthBasic;
                    }
                    List<AddonNoiseMakerBasic> noiseMakerBasicList = masterCritterGenome.CheckForAddonNoiseMakerBasic(currentBuildSegmentList[i].sourceNode.ID);
                    for (int j = 0; j < noiseMakerBasicList.Count; j++) {
                        SegaddonNoiseMakerBasic newNoiseMakerBasic = new SegaddonNoiseMakerBasic(noiseMakerBasicList[j]);
                        newNoiseMakerBasic.segmentID = newSegment.id;
                        segaddonNoiseMakerBasicList.Add(newNoiseMakerBasic);

                        string outputChannelName = "Segment " + newNoiseMakerBasic.segmentID.ToString() + " NoiseMaker";
                        BrainOutputChannel BOC_SegmentNoiseMaker = new BrainOutputChannel(ref newNoiseMakerBasic.volume, true, outputChannelName);
                        outputChannelsList.Add(BOC_SegmentNoiseMaker);
                    }
                    List<AddonSticky> stickyList = masterCritterGenome.CheckForAddonSticky(currentBuildSegmentList[i].sourceNode.ID);
                    for (int j = 0; j < stickyList.Count; j++) {
                        SegaddonSticky newSticky = new SegaddonSticky(stickyList[j]);
                        newSticky.segmentID = newSegment.id;
                        segaddonStickyList.Add(newSticky);

                        string outputChannelName = "Segment " + newSticky.segmentID.ToString() + " Sticky";
                        BrainOutputChannel BOC_SegmentSticky = new BrainOutputChannel(ref newSticky.stickiness, true, outputChannelName);
                        outputChannelsList.Add(BOC_SegmentSticky);
                    }
                    List<AddonWeaponBasic> weaponBasicList = masterCritterGenome.CheckForAddonWeaponBasic(currentBuildSegmentList[i].sourceNode.ID);
                    for (int j = 0; j < weaponBasicList.Count; j++) {
                        SegaddonWeaponBasic newWeaponBasic = new SegaddonWeaponBasic(weaponBasicList[j]);
                        newWeaponBasic.segmentID = newSegment.id;
                        segaddonWeaponBasicList.Add(newWeaponBasic);

                        string outputChannelName = "Segment " + newWeaponBasic.segmentID.ToString() + " Weapon";
                        BrainOutputChannel BOC_SegmentWeapon = new BrainOutputChannel(ref newWeaponBasic.strength, true, outputChannelName);
                        outputChannelsList.Add(BOC_SegmentWeapon);
                    }                    
                    #endregion
                    
                    
                }
                
                
                // Figure out how many unique Child nodes this built node has:
                //int numberOfChildNodes = currentBuildSegmentList[i].sourceNode.attachedJointLinkList.Count; // old
                int numberOfChildNodes = currentBuildSegmentList[i].sourceNode.attachedChildNodesIdList.Count;
                //Debug.Log("numberOfChildNodes: " + numberOfChildNodes.ToString() + "currentBuildSegmentList[i].sourceNode: " + currentBuildSegmentList[i].sourceNode.ID.ToString() + ", i: " + i.ToString());
                for (int c = 0; c < numberOfChildNodes; c++) {

                    // if NO symmetry:
                    // Check if Attaching to a recursion chain && if onlyattachToTail is active:
                    int childID = currentBuildSegmentList[i].sourceNode.attachedChildNodesIdList[c];
                    //Debug.Log("%%%%% c=" + c.ToString() + ", childID: " + childID.ToString() + ", critterNodeListCount: " + masterCritterGenome.CritterNodeList.Count.ToString());
                    // if(currentBuildSegmentList[i].sourceNode.attachedJointLinkList[c].childNode.parentJointLink.onlyAttachToTailNode)  // OLD
                    if (masterCritterGenome.CritterNodeList[childID].jointLink.onlyAttachToTailNode) { 
                        if (currentBuildSegmentList[i].sourceNode.jointLink.numberOfRecursions > 0) {
                            if (newSegment.recursionNumber > newSegment.sourceNode.jointLink.numberOfRecursions) {
                                // Only build segment if it is on the end of a recursion chain:
                                BuildSegmentInfo newSegmentInfo = new BuildSegmentInfo();
                                newSegmentInfo.sourceNode = masterCritterGenome.CritterNodeList[childID];
                                newSegmentInfo.parentSegment = newSegment;
                                nextBuildSegmentList.Add(newSegmentInfo);

                                if (masterCritterGenome.CritterNodeList[childID].jointLink.symmetryType != CritterJointLink.SymmetryType.None) {
                                    // the child node has some type of symmetry, so add a buildOrder for a mirrored Segment:
                                    BuildSegmentInfo newSegmentInfoMirror = new BuildSegmentInfo();
                                    newSegmentInfoMirror.sourceNode = masterCritterGenome.CritterNodeList[childID];
                                    newSegmentInfoMirror.isMirror = true;  // This segment is the COPY, not the original
                                    newSegmentInfoMirror.parentSegment = newSegment;  // 
                                    nextBuildSegmentList.Add(newSegmentInfoMirror);
                                }
                            }
                        }
                        else {
                            // It only attaches to End nodes, but is parented to a Non-recursive segment, so proceed normally!!!
                            BuildSegmentInfo newSegmentInfo = new BuildSegmentInfo();
                            newSegmentInfo.sourceNode = masterCritterGenome.CritterNodeList[childID];
                            newSegmentInfo.parentSegment = newSegment;
                            nextBuildSegmentList.Add(newSegmentInfo);

                            if (masterCritterGenome.CritterNodeList[childID].jointLink.symmetryType != CritterJointLink.SymmetryType.None) {
                                // the child node has some type of symmetry, so add a buildOrder for a mirrored Segment:
                                BuildSegmentInfo newSegmentInfoMirror = new BuildSegmentInfo();
                                newSegmentInfoMirror.sourceNode = masterCritterGenome.CritterNodeList[childID];
                                newSegmentInfoMirror.isMirror = true;  // This segment is the COPY, not the original
                                newSegmentInfoMirror.parentSegment = newSegment;  // 
                                nextBuildSegmentList.Add(newSegmentInfoMirror);
                            }
                        }                       
                    }
                    else {  // proceed normally:
                        BuildSegmentInfo newSegmentInfo = new BuildSegmentInfo();
                        newSegmentInfo.sourceNode = masterCritterGenome.CritterNodeList[childID];
                        newSegmentInfo.parentSegment = newSegment;
                        nextBuildSegmentList.Add(newSegmentInfo);

                        if (masterCritterGenome.CritterNodeList[childID].jointLink.symmetryType != CritterJointLink.SymmetryType.None) {
                            // the child node has some type of symmetry, so add a buildOrder for a mirrored Segment:
                            BuildSegmentInfo newSegmentInfoMirror = new BuildSegmentInfo();
                            newSegmentInfoMirror.sourceNode = masterCritterGenome.CritterNodeList[childID];
                            newSegmentInfoMirror.isMirror = true;  // This segment is the COPY, not the original
                            newSegmentInfoMirror.parentSegment = newSegment;  // 
                            nextBuildSegmentList.Add(newSegmentInfoMirror);
                        }
                    }             
                }                               
            }
            // After all buildNodes have been built, and their subsequent childNodes Enqueued, copy pendingChildQueue into buildNodesQueue
            currentBuildSegmentList.Clear();
            // SWAP LISTS:
            if (nextBuildSegmentList.Count > 0) {
                for (int j = 0; j < nextBuildSegmentList.Count; j++) {
                    currentBuildSegmentList.Add(nextBuildSegmentList[j]);
                }
                nextBuildSegmentList.Clear();  // empty this list for next depth-round
            }
            else {
                isPendingChildren = false;
            }
            if (currentDepth >= maxDepth) { // SAFEGUARD!! prevents infinite loop in case I mess something up
                isPendingChildren = false;
            }
            currentDepth++;
        }

        //Debug.Log("RebuildCritterFromGenomeRecursive " + inputChannelsList.Count.ToString() + ", " + outputChannelsList.Count.ToString());
        //Debug.Log("RebuildCritterFromGenomeRecursive: COM_Offset: (" + masterCritterGenome.centerOfMassOffset.x.ToString() + ", " + masterCritterGenome.centerOfMassOffset.y.ToString() + ", " + masterCritterGenome.centerOfMassOffset.z.ToString() + "), totalVolume: " + critterTotalVolume.ToString());// + " RootPos: " + critterSegmentList[0].transform.position.ToString());
    }
Exemplo n.º 4
0
    // Constructor!!
    public MiniGameRobotArm()
    {
        GOarmSegments = new GameObject[numberOfSegments];
        armSegmentArray_PosX = new float[numberOfSegments][];
        armSegmentArray_PosY = new float[numberOfSegments][];
        armSegmentArray_Angle = new float[numberOfSegments][];;
        armSegmentArray_AngleVel = new float[numberOfSegments][];;
        armSegmentArray_Length = new float[numberOfSegments][];;
        for(int i = 0; i < numberOfSegments; i++) {
            armSegmentArray_PosX[i] = new float[1];
            armSegmentArray_PosY[i] = new float[1];
            armSegmentArray_Angle[i] = new float[1];
            armSegmentArray_AngleVel[i] = new float[1];
            armSegmentArray_Length[i] = new float[1];
        }
        armTip_PosX[0] = 0f;
        armTip_PosY[0] = 0f;
        armTotalLength[0] = 1.6f;

        /*
        armSegmentA_PosX[0] = 0f;
        armSegmentA_PosY[0] = 0f;
        armSegmentA_Length[0] = 0.333334f;
        armSegmentA_Angle[0] = 0f;
        armSegmentA_AngleVel[0] = 0f;
        armSegmentB_PosX[0] = 0f;
        armSegmentB_PosY[0] = 0f;
        armSegmentB_Angle[0] = 0f;
        armSegmentB_AngleVel[0] = 0f;
        armSegmentB_Length[0] = 0.333334f;
        armSegmentC_PosX[0] = 0f;
        armSegmentC_PosY[0] = 0f;
        armSegmentC_Angle[0] = 0f;
        armSegmentC_AngleVel[0] = 0f;
        armSegmentC_Length[0] = 0.333334f;

        armTip_PosX[0] = 0f;
        armTip_PosY[0] = 0f;

        target_PosX[0] = 0f;
        target_PosY[0] = 0f;
        target_Angle[0] = 0f;
        target_Distance[0] = 0f;
        */

        fitTimeToTarget[0] = 1f;
        fitDistanceToTarget[0] = 0f;
        fitEnergySpent[0] = 0f;
        fitGapClosed[0] = 0f;
        fitTimeInTarget[0] = 0f;
        fitArmReachDistance[0] = 0f;
        fitDotProduct[0] = 0f;
        collision = false;

        // Brain Inputs!:
        inputChannelsList = new List<BrainInputChannel>();
        // Brain Outputs!:
        outputChannelsList = new List<BrainOutputChannel>();

        BrainInputChannel BIC_target_Angle = new BrainInputChannel(ref target_Angle, false, "target_Angle");
        inputChannelsList.Add (BIC_target_Angle); // 0
        BrainInputChannel BIC_target_Distance = new BrainInputChannel(ref target_Distance, false, "target_Distance");
        inputChannelsList.Add (BIC_target_Distance); // 1

        for(int bc = 0; bc < numberOfSegments; bc++) {
            string inputChannelName = "Arm Segment " + bc.ToString() + " Angle";
            BrainInputChannel BIC_armSegmentAngle = new BrainInputChannel(ref armSegmentArray_Angle[bc], false, inputChannelName);
            inputChannelsList.Add (BIC_armSegmentAngle);

            string outputChannelName = "Arm Segment " + bc.ToString() + " Angle Vel";
            BrainOutputChannel BOC_armSegmentAngleVel = new BrainOutputChannel(ref armSegmentArray_AngleVel[bc], false, outputChannelName);
            outputChannelsList.Add (BOC_armSegmentAngleVel);
        }

        //BrainInputChannel BIC_armSegmentA_Angle = new BrainInputChannel(ref armSegmentA_Angle, false, "armSegmentA_Angle");
        //inputChannelsList.Add (BIC_armSegmentA_Angle); // 0
        //BrainInputChannel BIC_armSegmentB_Angle = new BrainInputChannel(ref armSegmentB_Angle, false, "armSegmentB_Angle");
        //inputChannelsList.Add (BIC_armSegmentB_Angle); // 1
        //BrainInputChannel BIC_armSegmentC_Angle = new BrainInputChannel(ref armSegmentC_Angle, false, "armSegmentC_Angle");
        //inputChannelsList.Add (BIC_armSegmentC_Angle); // 2

        //BrainOutputChannel BOC_armSegmentA_AngleVel = new BrainOutputChannel(ref armSegmentA_AngleVel, false, "armSegmentA_AngleVel");
        //outputChannelsList.Add (BOC_armSegmentA_AngleVel); // 0
        //BrainOutputChannel BOC_armSegmentB_AngleVel = new BrainOutputChannel(ref armSegmentB_AngleVel, false, "armSegmentB_AngleVel");
        //outputChannelsList.Add (BOC_armSegmentB_AngleVel); // 1
        //BrainOutputChannel BOC_armSegmentC_AngleVel = new BrainOutputChannel(ref armSegmentC_AngleVel, false, "armSegmentC_AngleVel");
        //outputChannelsList.Add (BOC_armSegmentC_AngleVel); // 2

        fitnessComponentList = new List<FitnessComponent>();
        FitnessComponent FC_timeToTarget = new FitnessComponent(ref fitTimeToTarget, false, false, 1f, 1f, "Time To Target", true);
        fitnessComponentList.Add (FC_timeToTarget); // 0
        FitnessComponent FC_distanceToTarget = new FitnessComponent(ref fitDistanceToTarget, false, false, 1f, 1f, "Distance To Target", true);
        fitnessComponentList.Add (FC_distanceToTarget); // 1
        FitnessComponent FC_energySpent = new FitnessComponent(ref fitEnergySpent, false, false, 1f, 1f, "Energy Spent", true);
        fitnessComponentList.Add (FC_energySpent); // 2
        FitnessComponent FC_gapClosed = new FitnessComponent(ref fitGapClosed, false, true, 1f, 1f, "Gap Closed", false);
        fitnessComponentList.Add (FC_gapClosed); // 3
        FitnessComponent FC_timeInTarget = new FitnessComponent(ref fitTimeInTarget, false, true, 1f, 1f, "Time Inside Target", true);
        fitnessComponentList.Add (FC_timeInTarget); // 4
        FitnessComponent FC_armReachDistance = new FitnessComponent(ref fitArmReachDistance, false, false, 1f, 1f, "Arm Reach Distance", false);
        fitnessComponentList.Add (FC_armReachDistance); // 5
        FitnessComponent FC_dotProduct = new FitnessComponent(ref fitDotProduct, false, true, 1f, 1f, "Dot Product", false);
        fitnessComponentList.Add (FC_dotProduct); // 6

        Reset();
    }
    // Constructor!!
    public MiniGamePhysXTests()
    {
        GOtestAgentBall = new GameObject("GOtestAgentBall");
        GOtestAgentBall.transform.localPosition = new Vector3(0f, 0f, 0f);
        GOtestTargetBall = new GameObject("GOtestTargetBall");
        GOtestTargetBall.transform.localPosition = new Vector3(0f, 0f, 0f);

        ownPosX[0] = 0f;
        ownPosY[0] = 0f;
        ownPosZ[0] = 0f;
        targetPosX[0] = 0f;
        targetPosY[0] = 0f;
        targetPosZ[0] = 0f;
        ownVelX[0] = 0f;
        ownVelY[0] = 0f;
        ownVelZ[0] = 0f;
        targetVelX[0] = 0f;
        targetVelY[0] = 0f;
        targetVelZ[0] = 0f;

        fitDotProduct[0] = 0f;
        fitTimeToTarget[0] = 1f;
        fitDistanceToTarget[0] = 0f;
        fitReachTarget[0] = 0f;
        collision = false;

        // Brain Inputs!:
        inputChannelsList = new List<BrainInputChannel>();
        BrainInputChannel BIC_ownPosX = new BrainInputChannel(ref ownPosX, false, "ownPosX");
        inputChannelsList.Add (BIC_ownPosX); // 0
        BrainInputChannel BIC_ownPosY = new BrainInputChannel(ref ownPosY, false, "ownPosY");
        inputChannelsList.Add (BIC_ownPosY); // 1
        BrainInputChannel BIC_ownPosZ = new BrainInputChannel(ref ownPosZ, false, "ownPosZ");
        inputChannelsList.Add (BIC_ownPosZ); // 2
        BrainInputChannel BIC_targetPosX = new BrainInputChannel(ref targetPosX, false, "targetPosX");
        inputChannelsList.Add (BIC_targetPosX); // 3
        BrainInputChannel BIC_targetPosY = new BrainInputChannel(ref targetPosY, false, "targetPosY");
        inputChannelsList.Add (BIC_targetPosY); // 4
        BrainInputChannel BIC_targetPosZ = new BrainInputChannel(ref targetPosZ, false, "targetPosZ");
        inputChannelsList.Add (BIC_targetPosZ); // 5
        BrainInputChannel BIC_ownVelX = new BrainInputChannel(ref ownVelX, false, "ownVelX");
        inputChannelsList.Add (BIC_ownVelX); // 6
        BrainInputChannel BIC_ownVelY = new BrainInputChannel(ref ownVelY, false, "ownVelY");
        inputChannelsList.Add (BIC_ownVelY); // 7
        BrainInputChannel BIC_ownVelZ = new BrainInputChannel(ref ownVelZ, false, "ownVelZ");
        inputChannelsList.Add (BIC_ownVelZ); // 8
        BrainInputChannel BIC_targetDirX = new BrainInputChannel(ref targetDirX, false, "targetDirX");
        inputChannelsList.Add (BIC_targetDirX); // 9
        BrainInputChannel BIC_targetDirY = new BrainInputChannel(ref targetDirY, false, "targetDirY");
        inputChannelsList.Add (BIC_targetDirY); // 10
        BrainInputChannel BIC_targetDirZ = new BrainInputChannel(ref targetDirZ, false, "targetDirZ");
        inputChannelsList.Add (BIC_targetDirZ); // 11
        // Brain Outputs!:

        outputChannelsList = new List<BrainOutputChannel>();
        BrainOutputChannel BOC_ownVelX = new BrainOutputChannel(ref ownVelX, false, "ownVelX");
        outputChannelsList.Add (BOC_ownVelX); // 0
        BrainOutputChannel BOC_ownVelY = new BrainOutputChannel(ref ownVelY, false, "ownVelY");
        outputChannelsList.Add (BOC_ownVelY); // 1
        BrainOutputChannel BOC_ownVelZ = new BrainOutputChannel(ref ownVelZ, false, "ownVelZ");
        outputChannelsList.Add (BOC_ownVelZ); // 1

        fitnessComponentList = new List<FitnessComponent>();
        FitnessComponent FC_dotProduct = new FitnessComponent(ref fitDotProduct, true, true, 1f, 1f, "Dot Product To Target", true);
        fitnessComponentList.Add (FC_dotProduct); // 0
        FitnessComponent FC_timeToTarget = new FitnessComponent(ref fitTimeToTarget, true, false, 1f, 1f, "Time To Target", true);
        fitnessComponentList.Add (FC_timeToTarget); // 1
        FitnessComponent FC_distanceToTarget = new FitnessComponent(ref fitDistanceToTarget, true, false, 1f, 1f, "Distance To Target", true);
        fitnessComponentList.Add (FC_distanceToTarget); // 2
        FitnessComponent FC_reachTarget = new FitnessComponent(ref fitReachTarget, true, true, 1f, 1f, "Reaches Target", false);
        fitnessComponentList.Add (FC_reachTarget); // 3

        Reset();
    }