Example #1
0
    // Use this for initialization
    public void CreateInitialMicrobe()
    {
        if (director == null)
        {
            director = GetComponent <CameraDirectorScript>();
        }

        GameObject container = Instantiate(microbeContainer);

        container.transform.position = Vector3.up * 5;

        GameObject mainBody = Instantiate(RandomChoice(hulls), container.transform);
        //mainBody.transform.SetParent(container.transform);

        Mesh mainBodyMesh = mainBody.GetComponent <MeshFilter>().mesh;
        // Have to create a new instance of a mesh so that the rotation doesn't
        // affect the real mesh...
        // The transform is rotated not the mesh, in reality, but this throws
        // off mesh vertices and norms for placement purposes
        Mesh newMesh = new Mesh
        {
            vertices  = mainBodyMesh.vertices,
            normals   = mainBodyMesh.normals,
            triangles = mainBodyMesh.triangles
        };

        List <Vector3> origVerts = new List <Vector3>(newMesh.vertices);

        // As the initial rotation of the body may not be (0, 0, 0) and vertices
        // and normals of the mesh are used to position components, we need to
        // rotate them
        Vector3        rot          = mainBody.transform.eulerAngles;
        Quaternion     rotation     = Quaternion.Euler(rot.x, rot.y, rot.z);
        Matrix4x4      m            = Matrix4x4.Rotate(rotation);
        int            i            = 0;
        List <Vector3> meshVertices = new List <Vector3>();

        while (i < origVerts.Count)
        {
            meshVertices.Add(m.MultiplyPoint3x4(origVerts[i]));
            i++;
        }
        newMesh.vertices = meshVertices.ToArray();
        // As the vertices have been altered, we need to recalculate the normals
        newMesh.RecalculateNormals();

        List <Vector3> meshNorms = new List <Vector3>(newMesh.normals);


        //Debug.Log("Vertices: " + meshVertices.Count);
        //Debug.Log("Normals: " + meshNorms.Count);
        //for (i = 0; i < meshVertices.Count; i++){
        //    Debug.Log(i + ": " + meshVertices[i]);
        //}

        // Seed the RNG for testing purposes
        //Random.InitState(123);
        // TESTING PURPOSES: Connect the single component to all ports on the main body
        for (i = 0; i < 5; i++)
        {
            //TODO: Get component ID from the chromosome, instead of using hard coded value
            // Try to position to first part at the port of the main body
            GameObject obj = Instantiate(components[1]);
            // Transform target = componentPorts[i];

            // Empty GO to get a transform and create a port at a random vertex
            GameObject dynamicPort = new GameObject();
            Transform  target      = dynamicPort.transform;
            Destroy(dynamicPort);

            // Get the random index for us to select the vertex
            int ind = Random.Range(0, meshVertices.Count);

            target.position = mainBody.transform.position + meshVertices[ind];
            target.rotation = Quaternion.LookRotation(meshNorms[ind]);

            //obj.transform.rotation = Quaternion.Inverse(Quaternion.LookRotation(-target.forward, target.up));
            //target.rotation *= Quaternion.Euler(target.right * 180);
            obj.transform.rotation = target.rotation;
            // The above rotation places the component the wrong way around, so
            // rotate around local y axis
            obj.transform.Rotate(Vector3.up * 180, Space.Self);

            ComponentPortScript component = obj.GetComponent <ComponentPortScript>();
            if (component != null)
            {
                // Set the position of the component to the port on the main body sub the difference between
                // its transform pos and its port pos
                obj.transform.position = target.position + (obj.transform.position - component.port.transform.position);
                obj.transform.SetParent(container.transform);
                FixedJoint joint = container.AddComponent <FixedJoint>();
                joint.connectedBody = obj.GetComponent <Rigidbody>();
            }
            else
            {
                Debug.Log("No component port script found on component \'" + obj.name + "\'");
            }

            // Remove the vertex and normal that have been used from the list of viable locations
            meshVertices.RemoveAt(ind);
            meshNorms.RemoveAt(ind);
        }

        director.SetCameraTarget(mainBody);
        BuoyancyControlScript b = container.GetComponent <BuoyancyControlScript>();

        if (b != null)
        {
            b.waterSurface = water.transform;
            b.SetRigidBody(container.GetComponent <Rigidbody>());
        }
        else
        {
            Debug.Log("BuoyancyControlCScript was null........");
        }
    }
Example #2
0
    public GameObject CreateInitialMicrobe(Chromosome chromosome)
    {
        if (director == null)
        {
            director = GetComponent <CameraDirectorScript>();
        }

        //Debug.Log("Creating microbe from chromosome:");
        //Debug.Log(chromosome.ChromosomeString);

        GameObject container = Instantiate(microbeContainer);

        container.transform.position = Vector3.up * 5;

        Rigidbody contRb = container.GetComponent <Rigidbody>();

        contRb.mass = chromosome.HullMass;

        int        hullId   = chromosome.HullId % hulls.Length;
        GameObject mainBody = Instantiate(hulls[hullId], container.transform);
        //mainBody.transform.SetParent(container.transform);

        Mesh mainBodyMesh = mainBody.GetComponent <MeshFilter>().mesh;
        // Have to create a new instance of a mesh so that the rotation doesn't
        // affect the real mesh...
        // The transform is rotated not the mesh, in reality, but this throws
        // off mesh vertices and norms for placement purposes
        Mesh newMesh = new Mesh
        {
            vertices  = mainBodyMesh.vertices,
            normals   = mainBodyMesh.normals,
            triangles = mainBodyMesh.triangles
        };

        List <Vector3> origVerts = new List <Vector3>(newMesh.vertices);

        // As the initial scale may not be (1,1,1) and rotation of the body may
        // not be (0, 0, 0) we need to scale and rotate the vertex vectors

        Vector3        rot          = mainBody.transform.eulerAngles;
        Quaternion     rotation     = Quaternion.Euler(rot.x, rot.y, rot.z);
        Matrix4x4      m            = Matrix4x4.Rotate(rotation);
        int            i            = 0;
        List <Vector3> meshVertices = new List <Vector3>();

        Vector3 scale = mainBody.transform.localScale;

        scale.x *= chromosome.HullScale;
        scale.y *= chromosome.HullScale;
        scale.z *= chromosome.HullScale;
        mainBody.transform.localScale = scale;

        while (i < origVerts.Count)
        {
            Vector3 newV = origVerts[i];
            newV.x *= mainBody.transform.localScale.x;
            newV.y *= mainBody.transform.localScale.y;
            newV.z *= mainBody.transform.localScale.z;
            newV    = m.MultiplyPoint3x4(newV);
            meshVertices.Add(newV);
            i++;
        }
        newMesh.vertices = meshVertices.ToArray();
        // As the vertices have been altered, we need to recalculate the normals
        newMesh.RecalculateNormals();

        List <Vector3> meshNorms = new List <Vector3>(newMesh.normals);

        for (i = 0; i < chromosome.ComponentCount; i++)
        {
            int        componentId = chromosome.ComponentData[i].Id % components.Length;
            GameObject obj         = Instantiate(components[componentId]);

            // Empty GO to get a transform and create a port at a random vertex
            GameObject dynamicPort = new GameObject();
            Transform  target      = dynamicPort.transform;
            Destroy(dynamicPort);

            // Get the index from the chromosome for this component
            int ind = chromosome.ComponentData[i].MeshVertex % meshVertices.Count;

            // TODO: Use the rotation from the chromosome component data to rotate the component
            // TODO: Use mass and buoyancy values from chromosome
            target.position = mainBody.transform.position + meshVertices[ind];
            target.rotation = Quaternion.LookRotation(meshNorms[ind]);

            obj.transform.rotation = target.rotation;
            // The above rotation places the component the wrong way around, so
            // rotate around local y axis
            obj.transform.Rotate(Vector3.up * 180, Space.Self);

            ComponentPortScript component = obj.GetComponent <ComponentPortScript>();
            if (component != null)
            {
                Animator anim = obj.GetComponent <Animator>();

                if (anim != null)
                {
                    // use the scale value for this component to offset the component animation
                    // map the scale factor from its original range to the possible range of animation times
                    float idleStart = Map(chromosome.ComponentData[i].Scale,
                                          0,
                                          Chromosome.COMPONENT_SCALE_BITS,
                                          0,
                                          anim.GetCurrentAnimatorStateInfo(0).length);
                    anim.Play("LegMovementAnimation", 0, idleStart);
                }

                // Set the position of the component to the port on the main body sub the difference between
                // its transform pos and its port pos
                component.transform.rotation = component.port.transform.rotation;
                obj.transform.position       = target.position + (obj.transform.position - component.port.transform.position);
                obj.transform.SetParent(container.transform);
                FixedJoint joint  = container.AddComponent <FixedJoint>();
                Rigidbody  compRb = obj.GetComponent <Rigidbody>();
                joint.connectedBody = compRb;
            }
            else
            {
                Debug.Log("No component port script found on component \'" + obj.name + "\'");
            }

            // Remove the vertex and normal that have been used from the list of viable locations
            meshVertices.RemoveAt(ind);
            meshNorms.RemoveAt(ind);
        }

        director.SetCameraTarget(mainBody);
        BuoyancyControlScript b = container.GetComponent <BuoyancyControlScript>();

        if (b != null)
        {
            b.waterSurface = water.transform;
            b.SetRigidBody(container.GetComponent <Rigidbody>());
            return(container);
        }

        Debug.Log("BuoyancyControlCScript was null........");

        return(container);
    }