Exemplo n.º 1
0
    /// <summary>
    /// Cut the specified victim
    /// </summary>
    public static GameObject[] Cut(GameObject victim, Vector3 anchorPoint, Vector3 normalDirection, Material capMaterial)
    {
        // set the blade relative to victim
        _blade = new Plane(victim.transform.InverseTransformDirection(-normalDirection),
                           victim.transform.InverseTransformPoint(anchorPoint));

        // get the victims mesh
        _victim_mesh = victim.GetComponent <MeshFilter>().mesh;

        // reset values
        _new_vertices.Clear();

        _leftSide  = new Mesh_Maker();
        _rightSide = new Mesh_Maker();


        bool[] sides = new bool[3];
        int[]  indices;
        int    p1, p2, p3;

        // go throught the submeshes
        for (int sub = 0; sub < _victim_mesh.subMeshCount; sub++)
        {
            indices = _victim_mesh.GetTriangles(sub);

            for (int i = 0; i < indices.Length; i += 3)
            {
                p1 = indices[i];
                p2 = indices[i + 1];
                p3 = indices[i + 2];

                sides[0] = _blade.GetSide(_victim_mesh.vertices[p1]);
                sides[1] = _blade.GetSide(_victim_mesh.vertices[p2]);
                sides[2] = _blade.GetSide(_victim_mesh.vertices[p3]);


                // whole triangle
                if (sides[0] == sides[1] && sides[0] == sides[2])
                {
                    if (sides[0])                     // left side

                    {
                        _leftSide.AddTriangle(
                            new Vector3[] { _victim_mesh.vertices[p1], _victim_mesh.vertices[p2], _victim_mesh.vertices[p3] },
                            new Vector3[] { _victim_mesh.normals[p1], _victim_mesh.normals[p2], _victim_mesh.normals[p3] },
                            new Vector2[] { _victim_mesh.uv[p1], _victim_mesh.uv[p2], _victim_mesh.uv[p3] },
                            new Vector4[] { _victim_mesh.tangents[p1], _victim_mesh.tangents[p2], _victim_mesh.tangents[p3] },
                            sub);
                    }
                    else
                    {
                        _rightSide.AddTriangle(
                            new Vector3[] { _victim_mesh.vertices[p1], _victim_mesh.vertices[p2], _victim_mesh.vertices[p3] },
                            new Vector3[] { _victim_mesh.normals[p1], _victim_mesh.normals[p2], _victim_mesh.normals[p3] },
                            new Vector2[] { _victim_mesh.uv[p1], _victim_mesh.uv[p2], _victim_mesh.uv[p3] },
                            new Vector4[] { _victim_mesh.tangents[p1], _victim_mesh.tangents[p2], _victim_mesh.tangents[p3] },
                            sub);
                    }
                }
                else                   // cut the triangle

                {
                    Cut_this_Face(
                        new Vector3[] { _victim_mesh.vertices[p1], _victim_mesh.vertices[p2], _victim_mesh.vertices[p3] },
                        new Vector3[] { _victim_mesh.normals[p1], _victim_mesh.normals[p2], _victim_mesh.normals[p3] },
                        new Vector2[] { _victim_mesh.uv[p1], _victim_mesh.uv[p2], _victim_mesh.uv[p3] },
                        new Vector4[] { _victim_mesh.tangents[p1], _victim_mesh.tangents[p2], _victim_mesh.tangents[p3] },
                        sub);
                }
            }
        }

        // The capping Material will be at the end
        Material[] mats = victim.GetComponent <MeshRenderer>().sharedMaterials;
        if (mats[mats.Length - 1].name != capMaterial.name)
        {
            Material[] newMats = new Material[mats.Length + 1];
            mats.CopyTo(newMats, 0);
            newMats[mats.Length] = capMaterial;
            mats = newMats;
        }
        _capMatSub = mats.Length - 1;       // for later use

        // cap the opennings
        Capping();


        // Left Mesh
        Mesh left_HalfMesh = _leftSide.GetMesh();

        left_HalfMesh.name = "Split Mesh Left";

        // Right Mesh
        Mesh right_HalfMesh = _rightSide.GetMesh();

        right_HalfMesh.name = "Split Mesh Right";

        // assign the game objects

        victim.name = "left side";
        victim.GetComponent <MeshFilter>().mesh = left_HalfMesh;

        GameObject leftSideObj = victim;

        GameObject rightSideObj = new GameObject("right side", typeof(MeshFilter), typeof(MeshRenderer));

        rightSideObj.transform.position = victim.transform.position;
        rightSideObj.transform.rotation = victim.transform.rotation;
        rightSideObj.GetComponent <MeshFilter>().mesh = right_HalfMesh;


        // assign mats
        leftSideObj.GetComponent <MeshRenderer>().materials  = mats;
        rightSideObj.GetComponent <MeshRenderer>().materials = mats;

        return(new GameObject[] { leftSideObj, rightSideObj });
    }
Exemplo n.º 2
0
    /// <summary>
    ///  I have no idea how I made this work
    /// </summary>
    private static void Cut_this_Face(
        Vector3[] vertices,
        Vector3[] normals,
        Vector2[] uvs,
        Vector4[] tangents,
        int submesh)
    {
        bool[] sides = new bool[3];
        sides[0] = _blade.GetSide(vertices[0]);         // true = left
        sides[1] = _blade.GetSide(vertices[1]);
        sides[2] = _blade.GetSide(vertices[2]);


        Vector3[] leftPoints    = new Vector3[2];
        Vector3[] leftNormals   = new Vector3[2];
        Vector2[] leftUvs       = new Vector2[2];
        Vector4[] leftTangents  = new Vector4[2];
        Vector3[] rightPoints   = new Vector3[2];
        Vector3[] rightNormals  = new Vector3[2];
        Vector2[] rightUvs      = new Vector2[2];
        Vector4[] rightTangents = new Vector4[2];

        bool didset_left  = false;
        bool didset_right = false;

        for (int i = 0; i < 3; i++)
        {
            if (sides[i])
            {
                if (!didset_left)
                {
                    didset_left = true;

                    leftPoints[0]   = vertices[i];
                    leftPoints[1]   = leftPoints[0];
                    leftUvs[0]      = uvs[i];
                    leftUvs[1]      = leftUvs[0];
                    leftNormals[0]  = normals[i];
                    leftNormals[1]  = leftNormals[0];
                    leftTangents[0] = tangents[i];
                    leftTangents[1] = leftTangents[0];
                }
                else
                {
                    leftPoints[1]   = vertices[i];
                    leftUvs[1]      = uvs[i];
                    leftNormals[1]  = normals[i];
                    leftTangents[1] = tangents[i];
                }
            }
            else
            {
                if (!didset_right)
                {
                    didset_right = true;

                    rightPoints[0]   = vertices[i];
                    rightPoints[1]   = rightPoints[0];
                    rightUvs[0]      = uvs[i];
                    rightUvs[1]      = rightUvs[0];
                    rightNormals[0]  = normals[i];
                    rightNormals[1]  = rightNormals[0];
                    rightTangents[0] = tangents[i];
                    rightTangents[1] = rightTangents[0];
                }
                else
                {
                    rightPoints[1]   = vertices[i];
                    rightUvs[1]      = uvs[i];
                    rightNormals[1]  = normals[i];
                    rightTangents[1] = tangents[i];
                }
            }
        }


        float normalizedDistance = 0.0f;
        float distance           = 0;

        _blade.Raycast(new Ray(leftPoints[0], (rightPoints[0] - leftPoints[0]).normalized), out distance);

        normalizedDistance = distance / (rightPoints[0] - leftPoints[0]).magnitude;
        Vector3 newVertex1  = Vector3.Lerp(leftPoints[0], rightPoints[0], normalizedDistance);
        Vector2 newUv1      = Vector2.Lerp(leftUvs[0], rightUvs[0], normalizedDistance);
        Vector3 newNormal1  = Vector3.Lerp(leftNormals[0], rightNormals[0], normalizedDistance);
        Vector4 newTangent1 = Vector3.Lerp(leftTangents[0], rightTangents[0], normalizedDistance);

        _new_vertices.Add(newVertex1);

        _blade.Raycast(new Ray(leftPoints[1], (rightPoints[1] - leftPoints[1]).normalized), out distance);

        normalizedDistance = distance / (rightPoints[1] - leftPoints[1]).magnitude;
        Vector3 newVertex2  = Vector3.Lerp(leftPoints[1], rightPoints[1], normalizedDistance);
        Vector2 newUv2      = Vector2.Lerp(leftUvs[1], rightUvs[1], normalizedDistance);
        Vector3 newNormal2  = Vector3.Lerp(leftNormals[1], rightNormals[1], normalizedDistance);
        Vector4 newTangent2 = Vector3.Lerp(leftTangents[1], rightTangents[1], normalizedDistance);


        _new_vertices.Add(newVertex2);


        // first triangle

        Vector3[] final_verts    = new Vector3[] { leftPoints[0], newVertex1, newVertex2 };
        Vector3[] final_norms    = new Vector3[] { leftNormals[0], newNormal1, newNormal2 };
        Vector2[] final_uvs      = new Vector2[] { leftUvs[0], newUv1, newUv2 };
        Vector4[] final_tangents = new Vector4[] { leftTangents[0], newTangent1, newTangent2 };

        if (Vector3.Dot(Vector3.Cross(final_verts[1] - final_verts[0], final_verts[2] - final_verts[0]), final_norms[0]) < 0)
        {
            FlipFace(final_verts, final_norms, final_uvs, final_tangents);
        }

        _leftSide.AddTriangle(final_verts, final_norms, final_uvs, final_tangents, submesh);

        // second triangle

        final_verts    = new Vector3[] { leftPoints[0], leftPoints[1], newVertex2 };
        final_norms    = new Vector3[] { leftNormals[0], leftNormals[1], newNormal2 };
        final_uvs      = new Vector2[] { leftUvs[0], leftUvs[1], newUv2 };
        final_tangents = new Vector4[] { leftTangents[0], leftTangents[1], newTangent2 };

        if (Vector3.Dot(Vector3.Cross(final_verts[1] - final_verts[0], final_verts[2] - final_verts[0]), final_norms[0]) < 0)
        {
            FlipFace(final_verts, final_norms, final_uvs, final_tangents);
        }

        _leftSide.AddTriangle(final_verts, final_norms, final_uvs, final_tangents, submesh);

        // third triangle

        final_verts    = new Vector3[] { rightPoints[0], newVertex1, newVertex2 };
        final_norms    = new Vector3[] { rightNormals[0], newNormal1, newNormal2 };
        final_uvs      = new Vector2[] { rightUvs[0], newUv1, newUv2 };
        final_tangents = new Vector4[] { rightTangents[0], newTangent1, newTangent2 };

        if (Vector3.Dot(Vector3.Cross(final_verts[1] - final_verts[0], final_verts[2] - final_verts[0]), final_norms[0]) < 0)
        {
            FlipFace(final_verts, final_norms, final_uvs, final_tangents);
        }

        _rightSide.AddTriangle(final_verts, final_norms, final_uvs, final_tangents, submesh);


        // fourth triangle

        final_verts    = new Vector3[] { rightPoints[0], rightPoints[1], newVertex2 };
        final_norms    = new Vector3[] { rightNormals[0], rightNormals[1], newNormal2 };
        final_uvs      = new Vector2[] { rightUvs[0], rightUvs[1], newUv2 };
        final_tangents = new Vector4[] { rightTangents[0], rightTangents[1], newTangent2 };

        if (Vector3.Dot(Vector3.Cross(final_verts[1] - final_verts[0], final_verts[2] - final_verts[0]), final_norms[0]) < 0)
        {
            FlipFace(final_verts, final_norms, final_uvs, final_tangents);
        }

        _rightSide.AddTriangle(final_verts, final_norms, final_uvs, final_tangents, submesh);
    }
Exemplo n.º 3
0
    public override IEnumerator Cut()
    {
        // Jump to main thread for running UNITY API calls
        yield return(Ninja.JumpToUnity);

        // set the blade relative to victim
        _blade = new Plane(gameObject.transform.InverseTransformDirection(-_normalDirection),
                           gameObject.transform.InverseTransformPoint(_anchorPoint));

        // get the victims mesh
        _victim_mesh = gameObject.GetComponent <MeshFilter>().mesh;

        Vector3[] victim_vertices = _victim_mesh.vertices;
        Vector3[] victim_normals  = _victim_mesh.normals;
        Vector2[] victim_uvs      = _victim_mesh.uv;
        Vector4[] victim_tangents = _victim_mesh.tangents;

        int subMeshCount = _victim_mesh.subMeshCount;

        // Jump back to background thread to do heavy processes.
        yield return(Ninja.JumpBack);

        // reset values
        _new_vertices.Clear();

        _leftSide  = new Mesh_Maker();
        _rightSide = new Mesh_Maker();

        bool[] sides = new bool[3];
        int[]  indices;
        int    p1, p2, p3;


        // go throught the submeshes
        for (int sub = 0; sub < subMeshCount; sub++)
        {
            yield return(Ninja.JumpToUnity);

            indices = _victim_mesh.GetTriangles(sub);
            yield return(Ninja.JumpBack);

            for (int i = 0; i < indices.Length; i += 3)
            {
                p1 = indices[i];
                p2 = indices[i + 1];
                p3 = indices[i + 2];

                sides[0] = _blade.GetSide(victim_vertices[p1]);
                sides[1] = _blade.GetSide(victim_vertices[p2]);
                sides[2] = _blade.GetSide(victim_vertices[p3]);

                // whole triangle
                if (sides[0] == sides[1] && sides[0] == sides[2])
                {
                    if (sides[0])
                    { // left side
                        _leftSide.AddTriangle(
                            new Vector3[] { victim_vertices[p1], victim_vertices[p2], victim_vertices[p3] },
                            new Vector3[] { victim_normals[p1], victim_normals[p2], victim_normals[p3] },
                            new Vector2[] { victim_uvs[p1], victim_uvs[p2], victim_uvs[p3] },
                            new Vector4[] { victim_tangents[p1], victim_tangents[p2], victim_tangents[p3] },
                            sub);
                    }
                    else
                    {
                        _rightSide.AddTriangle(
                            new Vector3[] { victim_vertices[p1], victim_vertices[p2], victim_vertices[p3] },
                            new Vector3[] { victim_normals[p1], victim_normals[p2], victim_normals[p3] },
                            new Vector2[] { victim_uvs[p1], victim_uvs[p2], victim_uvs[p3] },
                            new Vector4[] { victim_tangents[p1], victim_tangents[p2], victim_tangents[p3] },
                            sub);
                    }
                }
                else
                { // cut the triangle
                    Cut_this_Face(
                        new Vector3[] { victim_vertices[p1], victim_vertices[p2], victim_vertices[p3] },
                        new Vector3[] { victim_normals[p1], victim_normals[p2], victim_normals[p3] },
                        new Vector2[] { victim_uvs[p1], victim_uvs[p2], victim_uvs[p3] },
                        new Vector4[] { victim_tangents[p1], victim_tangents[p2], victim_tangents[p3] },
                        sub);
                }
            }
        }

        // Jump to main thread for running UNITY API calls
        yield return(Ninja.JumpToUnity);

        // The capping Material will be at the end
        Material[] mats = gameObject.GetComponent <MeshRenderer>().sharedMaterials;
        if (mats[mats.Length - 1].name != capMaterial.name)
        {
            Material[] newMats = new Material[mats.Length + 1];
            mats.CopyTo(newMats, 0);
            newMats[mats.Length] = capMaterial;
            mats = newMats;
        }
        _capMatSub = mats.Length - 1; // for later use

        // Left Mesh
        Mesh left_HalfMesh = _leftSide.GetMesh();

        left_HalfMesh.name = "Split Mesh Left";

        // Right Mesh
        Mesh right_HalfMesh = _rightSide.GetMesh();

        right_HalfMesh.name = "Split Mesh Right";

        // assign the game objects
        gameObject.name = "left side";
        gameObject.GetComponent <MeshFilter>().mesh = left_HalfMesh;

        GameObject leftSideObj = gameObject;

        GameObject rightSideObj = new GameObject("right side", typeof(MeshFilter), typeof(MeshRenderer));

        rightSideObj.transform.position = gameObject.transform.position;
        rightSideObj.transform.rotation = gameObject.transform.rotation;
        rightSideObj.GetComponent <MeshFilter>().mesh = right_HalfMesh;

        leftSideObj.layer  = 9;
        rightSideObj.layer = 9;

        if (gameObject.transform.parent != null)
        {
            rightSideObj.transform.parent = gameObject.transform.parent;
        }

        rightSideObj.transform.localScale = gameObject.transform.localScale;

        // assign mats
        leftSideObj.GetComponent <MeshRenderer>().materials  = mats;
        rightSideObj.GetComponent <MeshRenderer>().materials = mats;

        // Handle new colliders of left & right pieces
        HandleCollisions(leftSideObj);
        HandleCollisions(rightSideObj);

        // Sound effects preparation
        AudioSource asrc = rightSideObj.AddComponent <AudioSource>();

        asrc.spatialBlend = 1f;
        asrc.volume       = 0.4f;
        asrc.playOnAwake  = false;
        ////
        // Other Stuff
        VRTK.VRTK_InteractableObject vrtk_io = rightSideObj.AddComponent <VRTK_InteractableObject>();
        //vrtk_io.holdButtonToGrab = false;
        VRTK_FixedJointGrabAttach vrtk_fjga = rightSideObj.AddComponent <VRTK_FixedJointGrabAttach>();

        vrtk_io.isGrabbable     = true;
        vrtk_fjga.precisionGrab = true;
        /////

        Renderer right_renderer = rightSideObj.GetComponent <Renderer>();
        Renderer left_renderer  = leftSideObj.GetComponent <Renderer>();
        float    right_bounds   = right_renderer.bounds.size.x * right_renderer.bounds.size.y * right_renderer.bounds.size.z;
        float    left_bounds    = left_renderer.bounds.size.x * left_renderer.bounds.size.y * left_renderer.bounds.size.z;

        GameObject leftController = GameObject.Find("LeftController");

        if (leftController.GetComponent <AutoGrab>() != null)
        {
            Destroy(leftController.GetComponent <AutoGrab>());
        }
        if (right_bounds > left_bounds)
        {
            Debug.Log("right side auto grab");

            objectFlesh.transform.parent   = rightSideObj.transform;
            objectFlesh.transform.position = rightSideObj.transform.position;
            objectFlesh.transform.rotation = rightSideObj.transform.rotation;

            parent = rightSideObj;

            if (right_bounds < smallerAllowedRigVolume)
            {
                AddCanBeChopped();
            }
            else
            {
                leftController.GetComponent <VRTK_InteractGrab>().ForceRelease();

                /*if (rightController.GetComponent<VRTK_InteractGrab>() != null)
                 * {
                 *  GameObject grabbedObject = rightController.GetComponent<VRTK_InteractGrab>().GetGrabbedObject();
                 *  Debug.Log(grabbedObject);
                 *
                 *  if (grabbedObject != null && grabbedObject.GetComponent<VRTK_InteractableObject>() != null)
                 *  {
                 *      grabbedObject.GetComponent<VRTK_InteractableObject>().Ungrabbed();
                 *  }
                 * }*/
                AutoGrab autoGrabRight = leftController.AddComponent <AutoGrab>();
                autoGrabRight.interactTouch = autoGrabRight.GetComponent <VRTK_InteractTouch>();
                autoGrabRight.interactGrab  = autoGrabRight.GetComponent <VRTK_InteractGrab>();
                autoGrabRight.objectToGrab  = vrtk_io;

                // Create required components & set parameters on right piece, copy component values to new one.
                CanBePeeled cbc = rightSideObj.AddComponent <CanBePeeled>();
                cbc.capMaterial             = this.capMaterial;
                cbc.sliceTimeout            = this.sliceTimeout;
                cbc.colliderSkinWidth       = this.colliderSkinWidth;
                cbc.detachChildrenOnSlice   = this.detachChildrenOnSlice;
                cbc.newPieceMassMultiplier  = this.newPieceMassMultiplier;
                cbc.canBeChoppedWhileOnHand = this.canBeChoppedWhileOnHand;
                cbc._rootObject             = this._rootObject;
                cbc.choppingSoundBoard      = this.choppingSoundBoard;
                cbc.objectFlesh             = this.objectFlesh;
                cbc.initialRig = leftSideObj;
                ////
            }
            Destroy(leftSideObj.GetComponent <CanBePeeled>());
        }
        else
        {
            Debug.Log("left side auto grab");
            //objectFlesh.transform.localPosition = new Vector3(0,0,0);
            //objectFlesh.transform.SetParent(leftSideObj.transform);
            if (left_bounds < smallerAllowedRigVolume)
            {
                AddCanBeChopped();
            }
            else
            {
                leftController.GetComponent <VRTK_InteractGrab>().ForceRelease();

                /*if (rightController.GetComponent<VRTK_InteractGrab>() != null)
                 * {
                 *  GameObject grabbedObject = rightController.GetComponent<VRTK_InteractGrab>().GetGrabbedObject();
                 *  Debug.Log(grabbedObject);
                 *  if (grabbedObject != null && grabbedObject.GetComponent<VRTK_InteractableObject>() != null)
                 *  {
                 *      grabbedObject.GetComponent<VRTK_InteractableObject>().Ungrabbed(rightController.GetComponent<VRTK_InteractGrab>());
                 *
                 *  }
                 * }*/
                AutoGrab autoGrabRight = leftController.AddComponent <AutoGrab>();
                autoGrabRight.interactTouch = autoGrabRight.GetComponent <VRTK_InteractTouch>();
                autoGrabRight.interactGrab  = autoGrabRight.GetComponent <VRTK_InteractGrab>();
                autoGrabRight.objectToGrab  = leftSideObj.GetComponent <VRTK_InteractableObject>();

                objectFlesh.transform.parent   = leftSideObj.transform;
                objectFlesh.transform.position = leftSideObj.transform.position;
                objectFlesh.transform.rotation = leftSideObj.transform.rotation;

                parent = leftSideObj;
            }

            Destroy(rightSideObj.GetComponent <CanBePeeled>());
        }

        // End thread
        yield return(Ninja.JumpBack);

        yield break;
    }
Exemplo n.º 4
0
    public virtual IEnumerator Cut()
    {
        // Jump to main thread for running UNITY API calls
        yield return(Ninja.JumpToUnity);

        // set the blade relative to victim
        _blade = new Plane(gameObject.transform.InverseTransformDirection(-_normalDirection),
                           gameObject.transform.InverseTransformPoint(_anchorPoint));

        // get the victims mesh
        _victim_mesh = gameObject.GetComponent <MeshFilter>().mesh;

        Vector3[] victim_vertices = _victim_mesh.vertices;
        Vector3[] victim_normals  = _victim_mesh.normals;
        Vector2[] victim_uvs      = _victim_mesh.uv;
        Vector4[] victim_tangents = _victim_mesh.tangents;

        int subMeshCount = _victim_mesh.subMeshCount;

        // Jump back to background thread to do heavy processes.
        yield return(Ninja.JumpBack);

        // reset values
        _new_vertices.Clear();

        _leftSide  = new Mesh_Maker();
        _rightSide = new Mesh_Maker();

        bool[] sides = new bool[3];
        int[]  indices;
        int    p1, p2, p3;


        // go throught the submeshes
        for (int sub = 0; sub < subMeshCount; sub++)
        {
            yield return(Ninja.JumpToUnity);

            indices = _victim_mesh.GetTriangles(sub);
            yield return(Ninja.JumpBack);

            for (int i = 0; i < indices.Length; i += 3)
            {
                p1 = indices[i];
                p2 = indices[i + 1];
                p3 = indices[i + 2];

                sides[0] = _blade.GetSide(victim_vertices[p1]);
                sides[1] = _blade.GetSide(victim_vertices[p2]);
                sides[2] = _blade.GetSide(victim_vertices[p3]);

                // whole triangle
                if (sides[0] == sides[1] && sides[0] == sides[2])
                {
                    if (sides[0])
                    { // left side
                        _leftSide.AddTriangle(
                            new Vector3[] { victim_vertices[p1], victim_vertices[p2], victim_vertices[p3] },
                            new Vector3[] { victim_normals[p1], victim_normals[p2], victim_normals[p3] },
                            new Vector2[] { victim_uvs[p1], victim_uvs[p2], victim_uvs[p3] },
                            new Vector4[] { victim_tangents[p1], victim_tangents[p2], victim_tangents[p3] },
                            sub);
                    }
                    else
                    {
                        _rightSide.AddTriangle(
                            new Vector3[] { victim_vertices[p1], victim_vertices[p2], victim_vertices[p3] },
                            new Vector3[] { victim_normals[p1], victim_normals[p2], victim_normals[p3] },
                            new Vector2[] { victim_uvs[p1], victim_uvs[p2], victim_uvs[p3] },
                            new Vector4[] { victim_tangents[p1], victim_tangents[p2], victim_tangents[p3] },
                            sub);
                    }
                }
                else
                { // cut the triangle
                    Cut_this_Face(
                        new Vector3[] { victim_vertices[p1], victim_vertices[p2], victim_vertices[p3] },
                        new Vector3[] { victim_normals[p1], victim_normals[p2], victim_normals[p3] },
                        new Vector2[] { victim_uvs[p1], victim_uvs[p2], victim_uvs[p3] },
                        new Vector4[] { victim_tangents[p1], victim_tangents[p2], victim_tangents[p3] },
                        sub);
                }
            }
        }

        /////////////////////  Jump to main thread for running UNITY API calls
        yield return(Ninja.JumpToUnity);

        // The capping Material will be at the end
        Material[] mats = gameObject.GetComponent <MeshRenderer>().sharedMaterials;
        if (mats[mats.Length - 1].name != capMaterial.name)
        {
            Material[] newMats = new Material[mats.Length + 1];
            mats.CopyTo(newMats, 0);
            newMats[mats.Length] = capMaterial;
            mats = newMats;
        }

        _capMatSub = mats.Length - 1; // for later use
        yield return(Ninja.JumpBack);

        // cap the opennings
        Capping();

        yield return(Ninja.JumpToUnity);

        // Left Mesh
        Mesh left_HalfMesh = _leftSide.GetMesh();

        left_HalfMesh.name = "Split Mesh Left";

        // Right Mesh
        Mesh right_HalfMesh = _rightSide.GetMesh();

        right_HalfMesh.name = "Split Mesh Right";

        // assign the game objects
        gameObject.name = "left_side";
        gameObject.GetComponent <MeshFilter>().mesh = left_HalfMesh;

        GameObject leftSideObj = gameObject;

        // Clone left side's components to right side.
        GameObject rightSideObj = GameObject.Instantiate(leftSideObj);

        rightSideObj.transform.position = gameObject.transform.position;
        rightSideObj.transform.rotation = gameObject.transform.rotation;
        rightSideObj.GetComponent <MeshFilter>().mesh = right_HalfMesh;
        rightSideObj.name = "right_side";

        if (gameObject.transform.parent != null)
        {
            rightSideObj.transform.parent = gameObject.transform.parent;
        }

        rightSideObj.transform.localScale = gameObject.transform.localScale;

        // Check for fried object material assign
        if (GetComponent <FoodStatus>().GetIsFried())
        {
            mats[0] = GetComponent <CanBeFried>().friedMaterial;
        }
        //

        // assign mats
        leftSideObj.GetComponent <MeshRenderer>().materials  = mats;
        rightSideObj.GetComponent <MeshRenderer>().materials = mats;


        // Handle new colliders of left & right pieces
        HandleCollisions(leftSideObj);
        HandleCollisions(rightSideObj);

        CanBeChopped cbc = rightSideObj.GetComponent <CanBeChopped>();

        cbc.SetRootObject(_rootObject);

        // Update maximum chopping action counts
        this.maximumChopCount -= 1;
        cbc.maximumChopCount   = this.maximumChopCount;

        foreach (CanBeChopped child in this.transform.parent.GetComponentsInChildren <CanBeChopped>())
        {
            child.maximumChopCount = this.maximumChopCount;
        }

        // Finally, mark them as chopped pieces
        leftSideObj.GetComponent <FoodStatus>().SetIsChoppedPiece(true);

        SimulationController sc = GameObject.Find("Simulation Controller").GetComponent <SimulationController>();

        rightSideObj.GetComponent <FoodStatus>().OperationDone += sc.OnOperationDone;

        rightSideObj.GetComponent <FoodStatus>().SetIsChoppedPiece(true);


        ///////////////////

        // End thread
        yield return(Ninja.JumpBack);

        yield break;
    }
Exemplo n.º 5
0
    /// <summary>
    /// Yeah
    /// </summary>
    /// <param name="victim">self discribed</param>
    /// <param name="anchorPoint">blade world position</param>
    /// <param name="normalDirection">blade right direction</param>
    /// <param name="capMaterial">Meat</param>
    /// <returns></returns>
    public static GameObject[] Cut(GameObject victim, Vector3 anchorPoint, Vector3 normalDirection, Material capMaterial)
    {
        // set the blade relative to victim
        _blade = new Plane(victim.transform.InverseTransformDirection(-normalDirection),
                           victim.transform.InverseTransformPoint(anchorPoint));

        // get the victims mesh
        _victim_mesh = victim.GetComponent <MeshFilter>().mesh;

        // two new meshes
        _leftSide.Clear();
        _rightSide.Clear();
        _newVerticesCache.Clear();


        int index_1, index_2, index_3;

        var mesh_vertices = _victim_mesh.vertices;
        var mesh_normals  = _victim_mesh.normals;
        var mesh_uvs      = _victim_mesh.uv;
        var mesh_tangents = _victim_mesh.tangents;

        if (mesh_tangents != null && mesh_tangents.Length == 0)
        {
            mesh_tangents = null;
        }

        // go through the submeshes
        for (int submeshIterator = 0; submeshIterator < _victim_mesh.subMeshCount; submeshIterator++)
        {
            // Triangles
            var indices = _victim_mesh.GetTriangles(submeshIterator);

            for (int i = 0; i < indices.Length; i += 3)
            {
                index_1 = indices[i];
                index_2 = indices[i + 1];
                index_3 = indices[i + 2];

                // verts
                _triangleCache.vertices[0] = mesh_vertices[index_1];
                _triangleCache.vertices[1] = mesh_vertices[index_2];
                _triangleCache.vertices[2] = mesh_vertices[index_3];

                // normals
                _triangleCache.normals[0] = mesh_normals[index_1];
                _triangleCache.normals[1] = mesh_normals[index_2];
                _triangleCache.normals[2] = mesh_normals[index_3];

                // uvs
                _triangleCache.uvs[0] = mesh_uvs[index_1];
                _triangleCache.uvs[1] = mesh_uvs[index_2];
                _triangleCache.uvs[2] = mesh_uvs[index_3];

                // tangents
                if (mesh_tangents != null)
                {
                    _triangleCache.tangents[0] = mesh_tangents[index_1];
                    _triangleCache.tangents[1] = mesh_tangents[index_2];
                    _triangleCache.tangents[2] = mesh_tangents[index_3];
                }
                else
                {
                    _triangleCache.tangents[0] = Vector4.zero;
                    _triangleCache.tangents[1] = Vector4.zero;
                    _triangleCache.tangents[2] = Vector4.zero;
                }

                // which side are the vertices on
                _isLeftSideCache[0] = _blade.GetSide(mesh_vertices[index_1]);
                _isLeftSideCache[1] = _blade.GetSide(mesh_vertices[index_2]);
                _isLeftSideCache[2] = _blade.GetSide(mesh_vertices[index_3]);


                // whole triangle
                if (_isLeftSideCache[0] == _isLeftSideCache[1] && _isLeftSideCache[0] == _isLeftSideCache[2])
                {
                    if (_isLeftSideCache[0]) // left side
                    {
                        _leftSide.AddTriangle(_triangleCache, submeshIterator);
                    }
                    else // right side
                    {
                        _rightSide.AddTriangle(_triangleCache, submeshIterator);
                    }
                }
                else
                { // cut the triangle
                    Cut_this_Face(ref _triangleCache, submeshIterator);
                }
            }
        }

        // The capping Material will be at the end
        Material[] mats = victim.GetComponent <MeshRenderer>().sharedMaterials;
        if (mats[mats.Length - 1].name != capMaterial.name)
        {
            Material[] newMats = new Material[mats.Length + 1];
            mats.CopyTo(newMats, 0);
            newMats[mats.Length] = capMaterial;
            mats = newMats;
        }
        _capMatSub = mats.Length - 1; // for later use

        // cap the opennings
        Cap_the_Cut();


        // Left Mesh
        Mesh left_HalfMesh = _leftSide.GetMesh();

        left_HalfMesh.name = "Split Mesh Left";

        // Right Mesh
        Mesh right_HalfMesh = _rightSide.GetMesh();

        right_HalfMesh.name = "Split Mesh Right";

        // assign the game objects

        victim.name = "left side";
        victim.GetComponent <MeshFilter>().mesh = left_HalfMesh;

        GameObject leftSideObj = victim;

        GameObject rightSideObj = new GameObject("right side", typeof(MeshFilter), typeof(MeshRenderer));

        rightSideObj.transform.position = victim.transform.position;
        rightSideObj.transform.rotation = victim.transform.rotation;
        rightSideObj.GetComponent <MeshFilter>().mesh = right_HalfMesh;

        if (victim.transform.parent != null)
        {
            rightSideObj.transform.parent = victim.transform.parent;
        }

        rightSideObj.transform.localScale = victim.transform.localScale;


        // assign mats
        leftSideObj.GetComponent <MeshRenderer>().materials  = mats;
        rightSideObj.GetComponent <MeshRenderer>().materials = mats;

        return(new GameObject[] { leftSideObj, rightSideObj });
    }