Пример #1
0
 private void AdjustEdgeHandleColor(Vector3 handlePos, Vector3 slideDir1, Vector3 slideDir2, Matrix4x4 transform, float alphaFactor)
 {
     bool flag;
     Vector3 inPoint = transform.MultiplyPoint(handlePos);
     Vector3 normalized = transform.MultiplyVector(slideDir1).normalized;
     Vector3 rhs = transform.MultiplyVector(slideDir2).normalized;
     if (Camera.current.isOrthoGraphic)
     {
         flag = (Vector3.Dot(-Camera.current.transform.forward, normalized) < 0f) && (Vector3.Dot(-Camera.current.transform.forward, rhs) < 0f);
     }
     else
     {
         Plane plane = new Plane(normalized, inPoint);
         Plane plane2 = new Plane(rhs, inPoint);
         flag = !plane.GetSide(Camera.current.transform.position) && !plane2.GetSide(Camera.current.transform.position);
     }
     if (flag)
     {
         alphaFactor *= 0.2f;
     }
     if (alphaFactor < 1f)
     {
         Handles.color = new Color(Handles.color.r, Handles.color.g, Handles.color.b, Handles.color.a * alphaFactor);
     }
 }
Пример #2
0
    // Handle map in the leaf level, so no care face level
    //ArrayList findVisibleFaces(ArrayList visibleLeafs) {
    //    if (visibleLeafs == null) {
    //        throw new ArgumentException();
    //    }
    //    bool[] alreadyVisibleFaces = new bool[_faces.Length];
    //    ArrayList visibleFaces = new ArrayList();
    //    foreach(int i in visibleLeafs) {
    //        BSPTreeLeaf lf = _leafs[i];
    //        for(int j=lf.leafface; j<lf.leafface+lf.n_leaffaces; j++) {
    //            int faceIndex = _leaffaces[j];
    //            if(!alreadyVisibleFaces[faceIndex]) {
    //                alreadyVisibleFaces[faceIndex] = true;
    //                visibleFaces.Add(faceIndex);
    //            }
    //        }
    //    }
    //    return visibleFaces;
    //}

    // Handle map in the leaf level, so no care face level
    //ArrayList backfaceCulling(Camera cam, ArrayList visibleFaces) {
    //    ArrayList visible = new ArrayList ();
    //    foreach (int i in visibleFaces) {
    //        BSPFileParser.Face f = _faces[i];
    //        Vector3 normal = Right2Left(new Vector3(f.normal[0], f.normal[1], f.normal[2]));
    //        if(Vector3.Dot(cam.transform.forward, normal) < BACKCULLINGFACTOR) {
    //            visible.Add(i);
    //        }
    //    }
    //    return visible;
    //}

    int findLeafIndex(Vector3 position)
    {
        if (position == null)
        {
            throw new ArgumentException();
        }

        int index = 0;

        while (index >= 0)
        {
            BSPFileParser.BSPTreeNode node  = _nodes[index];
            UnityEngine.Plane         plane = planes[node.plane];
            if (plane.GetSide(position))
            {
                index = node.children[0];
            }
            else
            {
                index = node.children[1];
            }
        }
        // When index < 0, meaning this is a BSP Leaf Index
        // convert into correct leaf index: -index-1
        return(-index - 1);
    }
Пример #3
0
 internal bool Internal_RaycastRef(Ray ray, ref UIHotSpot.Hit hit)
 {
     float single;
     Vector2 vector2 = new Vector2();
     if (this.radius == 0f)
     {
         return false;
     }
     Plane plane = new Plane(UIHotSpot.forward, this.center);
     if (!plane.Raycast(ray, out single))
     {
         hit = new UIHotSpot.Hit();
         return false;
     }
     hit.point = ray.GetPoint(single);
     hit.normal = (!plane.GetSide(ray.origin) ? UIHotSpot.backward : UIHotSpot.forward);
     vector2.x = hit.point.x - this.center.x;
     vector2.y = hit.point.y - this.center.y;
     float single1 = vector2.x * vector2.x + vector2.y * vector2.y;
     if (single1 >= this.radius * this.radius)
     {
         return false;
     }
     hit.distance = Mathf.Sqrt(single1);
     return true;
 }
Пример #4
0
    public static CausticDecalPolygon ClipPolygon(CausticDecalPolygon polygon, Plane plane)
    {
        bool[] positive = new bool[9];
        int positiveCount = 0;

        for(int i = 0; i < polygon.vertices.Count; i++) {
            positive[i] = !plane.GetSide( polygon.vertices[i] );
            if(positive[i]) positiveCount++;
        }

        if(positiveCount == 0) return null; // полностью за плоскостью
        if(positiveCount == polygon.vertices.Count) return polygon; // полностью перед плоскостью

        CausticDecalPolygon tempPolygon = new CausticDecalPolygon();

        for(int i = 0; i < polygon.vertices.Count; i++) {
            int next = i + 1;
             next %= polygon.vertices.Count;

            if( positive[i] ) {
                tempPolygon.vertices.Add( polygon.vertices[i] );
            }

            if( positive[i] != positive[next] ) {
                Vector3 v1 = polygon.vertices[next];
                Vector3 v2 = polygon.vertices[i];

                Vector3 v = LineCast(plane, v1, v2);
                tempPolygon.vertices.Add( v );
            }
        }

        return tempPolygon;
    }
Пример #5
0
	void OnGUI()
	{
		Vector3 position = transform.position + Offset;
		Plane plane = new Plane( Camera.main.transform.forward, Camera.main.transform.position );

		//If the object is behind the camera, then don't draw it
		if( plane.GetSide( position ) == false )
		{
			return;
		}

		//Calculate the 2D position of the position where the icon should be drawn
		Vector3 viewportPoint = Camera.main.WorldToViewportPoint( position );

		//The viewportPoint coordinates are between 0 and 1, so we have to convert them into screen space here
		Vector2 drawPosition = new Vector2(	viewportPoint.x * Screen.width, Screen.height * ( 1 - viewportPoint.y ) );

		float clampBorder = 12;

		//Clamp the position to the edge of the screen in case the icon would be drawn outside the screen
		drawPosition.x = Mathf.Clamp( drawPosition.x, clampBorder, Screen.width - clampBorder );
		drawPosition.y = Mathf.Clamp( drawPosition.y, clampBorder, Screen.height - clampBorder );

		GUI.color = Color;
		GUI.DrawTexture( new Rect( drawPosition.x - Icon.width * 0.5f, drawPosition.y - Icon.height * 0.5f, Icon.width, Icon.height ), Icon );
	}
Пример #6
0
    public static bool IsHandInBag(Vector3 pos_)
    {
        // The player is supposed to stand up while playing.

        Vector3 forward = Vector3.zero;

        if (Mathf.Abs(Vector3.Dot(Vector3.up, _head.forward)) < _tolerance)
        {
            Debug.LogWarning("Chosen forward = cam.forward");
            forward = _head.forward;
        }
        else if (Mathf.Abs(Vector3.Dot(Vector3.up, _head.up)) < _tolerance)
        {
            Debug.LogWarning("Chosen forward = cam.up");
            forward = _head.up;
        }
        else
        {
            Debug.LogWarning("Chosen forward = mix");

            // Is that ok... ?
            forward = (_head.forward + _head.up).normalized;
        }

        Plane pl = new Plane(forward, _head.position - forward * 0.15f);
        if (!pl.GetSide(pos_))
        {
            Debug.LogWarning("Point on negative side");

            if (pos_.y < _head.position.y)
            {
                Debug.LogWarning("Point lower than head");

                if (_head.position.y - pos_.y < Hub.playerHeight * 0.45f)
                {
                    Debug.LogWarning("Point higher than waist");

                    Vector3 headPosFromTop = _head.position;
                    headPosFromTop.y = 0f;

                    Vector3 handPosFromTop = pos_;
                    handPosFromTop.y = 0f;

                    if ((headPosFromTop - handPosFromTop).magnitude < 0.55f)
                    {
                        Debug.LogWarning("Point within tube");

                        return true;
                    }
                }
            }
        }
        else
        {
            Debug.LogWarning("Point on positive side");
        }

        return false;
    }
Пример #7
0
	static public int GetSide(IntPtr l) {
		try{
			UnityEngine.Plane self=(UnityEngine.Plane)checkSelf(l);
			UnityEngine.Vector3 a1;
			checkType(l,2,out a1);
			System.Boolean ret=self.GetSide(a1);
			pushValue(l,ret);
			return 1;
		}
		catch(Exception e) {
			LuaDLL.luaL_error(l, e.ToString());
			return 0;
		}
	}
Пример #8
0
    void GizmosDrawCameraInsideLeaf(Camera cam)
    {
        Color tc = Gizmos.color;

        Color[] cs         = new Color[] { Color.gray, Color.yellow, Color.magenta, Color.red }; // from light to dark
        int     colorIndex = 0;

        Vector3 position = cam.transform.position;

        // Camera
        Gizmos.DrawCube(position, new Vector3(200, 200, 200));
        int index = 0;

        while (index >= 0)
        {
            Gizmos.color = cs[colorIndex++ % cs.Length];
            BSPFileParser.BSPTreeNode node  = _nodes[index];
            UnityEngine.Plane         plane = planes[node.plane];
            Bounds b = new Bounds();
            b.SetMinMax(new Vector3(node.mins[0], node.mins[1], node.mins[2]),
                        new Vector3(node.maxs[0], node.maxs[1], node.maxs[2]));
            b = Right2Left(b);
            // Draw Sub-Space(BSP Tree Node bounding box)
            Gizmos.DrawWireCube(b.center, b.size);
            // Draw Split-Plane
            GizmosDrawPlane(GetOnePointOnPlane(plane), plane.normal, 5000.0f);
            if (plane.GetSide(position))
            {
                index = node.children[0];
                //Debug.Log("Front");
            }
            else
            {
                index = node.children[1];
                //Debug.Log("Back");
            }
        }

        // Draw BSP Tree Leaf bounding box
        BSPFileParser.BSPTreeLeaf lf = _leafs[-index - 1];
        Bounds temp = new Bounds();

        temp.SetMinMax(new Vector3(lf.mins[0], lf.mins[1], lf.mins[2]),
                       new Vector3(lf.maxs[0], lf.maxs[1], lf.maxs[2]));
        temp         = Right2Left(temp);
        Gizmos.color = Color.white;
        Gizmos.DrawWireCube(temp.center, temp.size);

        Gizmos.color = tc;
    }
Пример #9
0
 public bool IsPointInside(Mesh aMesh, Vector3 aLocalPoint)
 {
     var verts = aMesh.vertices;
     var tris = aMesh.triangles;
     int triangleCount = tris.Length / 3;
     for (int i = 0; i < triangleCount; i++)
     {
         var V1 = verts[tris[i * 3]];
         var V2 = verts[tris[i * 3 + 1]];
         var V3 = verts[tris[i * 3 + 2]];
         var P = new Plane(V1, V2, V3);
         if (P.GetSide(aLocalPoint))
             return false;
     }
     return true;
 }
Пример #10
0
    int findLeafIndex(Vector3 position)
    {
        if (position == null)
        {
            throw new ArgumentException();
        }

        int index = 0;

        while (index >= 0)
        {
            BSPFileParser.BSPTreeNode node  = _nodes[index];
            UnityEngine.Plane         plane = planes[node.plane];
            if (plane.GetSide(position))
            {
                index = node.children[0];
            }
            else
            {
                index = node.children[1];
            }
        }
        return(-index - 1);
    }
Пример #11
0
        static void DrawRotateGUI()
        {
            Handles.color = Color.white;

            ShapeGUI.NameNextHandle("RotateHandle");

            EditorGUI.BeginChangeCheck();

            Vector3 topCenterWorld = transform.TransformPoint( topCenter );
            Vector3 rotateHandle = topCenterWorld + transform.up * HandleUtility.GetHandleSize(topCenterWorld) *.5f;
            rotateHandle = ShapeGUI.VectorHandle( rotateHandle );
            Handles.DrawLine( rotateHandle, transform.TransformPoint( topCenter ) );

            Plane plane = new Plane( transform.forward, transform.position );
            Ray ray = new Ray( rotateHandle, plane.GetSide(rotateHandle) ? -transform.forward : transform.forward );
            float d = 0;
            plane.Raycast( ray, out d );

            rotateHandle = ray.GetPoint(d);

            Vector3 rotateVector = (rotateHandle - transform.position).normalized;

            float angle = Vector3.Angle( rotateVector, Vector3.up );
            float snappedAngle = Mathf.Round( angle / 15 ) * 15;

            Vector3 snappedVector = Vector2.up.Rotate( snappedAngle );

            if( Event.current.type == EventType.Used )
            {
                isRotating = EditorGUI.EndChangeCheck();
            }

            if( GUI.changed )
            {
                Quaternion newRotation = Quaternion.LookRotation( transform.forward, Event.current.shift ? snappedVector : rotateVector );

                if( transform.rotation != newRotation )
                {

                    Transform[] parents = new Transform[ shapes.Length ];
                    for( int i = 0; i < shapes.Length; i++)
                    {
                        Shape shape = shapes[i];
                        parents[i] = shape.transform.parent;
                        Undo.SetTransformParent( shape.transform, transform, "Rotate Shapes" );
                    }

                    Undo.RecordObject( transform, "Rotate Shapes" );
                    transform.rotation = newRotation;

                    for( int i = 0; i < shapes.Length; i++)
                    {
                        Shape shape = shapes[i];
                        Undo.SetTransformParent( shape.transform, parents[i], "Rotate Shapes" );
                    }

                }

                GUI.changed = false;
            }
        }
Пример #12
0
        /// <summary>
        /// Cut the specified victim, blade_plane and capMaterial.
        /// </summary>
        /// <param name="victim">Victim.</param>
        /// <param name="blade_plane">Blade plane.</param>
        /// <param name="capMaterial">Cap material.</param>
        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();
            left_side.ClearAll();
            right_side.ClearAll();

            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.GetIndices(sub);

                left_side.subIndices.Add(new List<int>());
                right_side.subIndices.Add(new List<int>());

                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
                            left_side.AddTriangle(p1,p2,p3,sub);
                        }else{
                            right_side.AddTriangle(p1,p2,p3,sub);
                        }

                    }else{ // cut the triangle

                        Cut_this_Face(sub, sides, p1, p2, p3);
                    }
                }
            }

            Material[] mats = victim.GetComponent<MeshRenderer>().sharedMaterials;

            if(mats[mats.Length-1].name != capMaterial.name){ // add cap indices

                left_side.subIndices.Add(new List<int>());
                right_side.subIndices.Add(new List<int>());

                Material[] newMats = new Material[mats.Length+1];
                mats.CopyTo(newMats, 0);
                newMats[mats.Length] = capMaterial;
                mats = newMats;
            }

            // cap the opennings
            Capping();

            // Left Mesh

            Mesh left_HalfMesh = new Mesh();
            left_HalfMesh.name =  "Split Mesh Left";
            left_HalfMesh.vertices  = left_side.vertices.ToArray();
            left_HalfMesh.triangles = left_side.triangles.ToArray();
            left_HalfMesh.normals   = left_side.normals.ToArray();
            left_HalfMesh.uv        = left_side.uvs.ToArray();

            left_HalfMesh.subMeshCount = left_side.subIndices.Count;
            for(int i=0; i<left_side.subIndices.Count; i++)
                left_HalfMesh.SetIndices(left_side.subIndices[i].ToArray(), MeshTopology.Triangles, i);

            // Right Mesh

            Mesh right_HalfMesh = new Mesh();
            right_HalfMesh.name = "Split Mesh Right";
            right_HalfMesh.vertices  = right_side.vertices.ToArray();
            right_HalfMesh.triangles = right_side.triangles.ToArray();
            right_HalfMesh.normals   = right_side.normals.ToArray();
            right_HalfMesh.uv        = right_side.uvs.ToArray();

            right_HalfMesh.subMeshCount = right_side.subIndices.Count;
            for(int i=0; i<right_side.subIndices.Count; i++)
                right_HalfMesh.SetIndices(right_side.subIndices[i].ToArray(), MeshTopology.Triangles, i);

            // 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.transform.localScale = victim.transform.localScale;
            rightSideObj.GetComponent<MeshFilter>().mesh = right_HalfMesh;

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

            return new GameObject[]{ leftSideObj, rightSideObj };
        }
Пример #13
0
    private void Split(Plane worldPlane, Vector3 lineStart, Vector3 lineEnd, int casts)
    {
        if (!splitting)
            return;

        // Sometimes there is null here
        // Too lazy to find real reason right now
        if (transform == null)
            return;

        float distance = worldPlane.GetDistanceToPoint(transform.position);

        Plane plane = new Plane();
        Vector3 newNormal = transform.InverseTransformDirection(worldPlane.normal);
        //Vector3 newNormal = Quaternion.Inverse(transform.rotation) * worldPlane.normal;
        plane.SetNormalAndPosition(newNormal, newNormal * -distance);

        posNormals.Add(-newNormal);
        negNormals.Add(newNormal);
        posNormals.AddRange(mesh.normals);
        negNormals.AddRange(mesh.normals);

        for (int i = 0; i < triangles.Length; i += 3)
        {
            int i1 = triangles[i];//index 1, 2 and 3 of vertices
            int i2 = triangles[i + 1];
            int i3 = triangles[i + 2];
            bool side1 = plane.GetSide(vertices[i1]);
            bool side2 = plane.GetSide(vertices[i2]);
            bool side3 = plane.GetSide(vertices[i3]);

            if (side1 == true && side2 == true && side3 == true)
            {
                posTriangles.Add(i1 + 1); //first index is reserved for interior face middle vertex so every index is incremented by 1
                posTriangles.Add(i2 + 1);
                posTriangles.Add(i3 + 1);
            }
            else if (side1 == false && side2 == false && side3 == false)
            {
                negTriangles.Add(i1 + 1);
                negTriangles.Add(i2 + 1);
                negTriangles.Add(i3 + 1);
            }
            else
            {
                //find odd boolean value(expression found using karnaugh map)
                bool odd = (!side1 && !side2) || (!side1 && !side3) || (!side2 && !side3);

                //find vertex with odd boolean value
                int vertex1, vertex2;
                if (side1 == odd)
                {
                    vertex1 = findNewVertex(i1, i2, plane);
                    vertex2 = findNewVertex(i1, i3, plane);
                    if (side1 == true)
                    {                                          //               i1 /\                  Positive Side
                        posTriangles.Add(i1 + 1);              //                 /  \
                        posTriangles.Add(vertex1 + 1);         //         vertex1/____\vertex2
                        posTriangles.Add(vertex2 + 1);         //               /   _-'\
                                                               //            i2/_.-'____\i3            Negative Side
                        negTriangles.Add(i2 + 1);
                        negTriangles.Add(i3 + 1);
                        negTriangles.Add(vertex2 + 1);

                        negTriangles.Add(i2 + 1);
                        negTriangles.Add(vertex2 + 1);
                        negTriangles.Add(vertex1 + 1);
                    }
                    else
                    {                                           //               i1 /\                  Negative Side
                        negTriangles.Add(i1 + 1);               //                 /  \
                        negTriangles.Add(vertex1 + 1);          //         vertex1/____\vertex2
                        negTriangles.Add(vertex2 + 1);          //               /   _-'\
                                                                //            i2/_.-'____\i3            Positive Side
                        posTriangles.Add(i2 + 1);
                        posTriangles.Add(i3 + 1);
                        posTriangles.Add(vertex2 + 1);

                        posTriangles.Add(i2 + 1);
                        posTriangles.Add(vertex2 + 1);
                        posTriangles.Add(vertex1 + 1);
                    }
                }
                else if (side2 == odd)
                {
                    vertex1 = findNewVertex(i2, i3, plane);
                    vertex2 = findNewVertex(i2, i1, plane);
                    if (side2 == true)
                    {                                           //               i2 /\                  Positive Side
                        posTriangles.Add(i2 + 1);               //                 /  \
                        posTriangles.Add(vertex1 + 1);          //         vertex1/____\vertex2
                        posTriangles.Add(vertex2 + 1);          //               /   _-'\
                                                                //            i3/_.-'____\i1            Negative Side
                        negTriangles.Add(i3 + 1);
                        negTriangles.Add(i1 + 1);
                        negTriangles.Add(vertex2 + 1);

                        negTriangles.Add(i3 + 1);
                        negTriangles.Add(vertex2 + 1);
                        negTriangles.Add(vertex1 + 1);
                    }
                    else
                    {                                           //               i2 /\                  Negative Side
                        negTriangles.Add(i2 + 1);               //                 /  \
                        negTriangles.Add(vertex1 + 1);          //         vertex1/____\vertex2
                        negTriangles.Add(vertex2 + 1);          //               /   _-'\
                                                                //            i3/_.-'____\i1            Positive Side
                        posTriangles.Add(i3 + 1);
                        posTriangles.Add(i1 + 1);
                        posTriangles.Add(vertex2 + 1);

                        posTriangles.Add(i3 + 1);
                        posTriangles.Add(vertex2 + 1);
                        posTriangles.Add(vertex1 + 1);
                    }
                }
                else
                {
                    vertex1 = findNewVertex(i3, i1, plane);
                    vertex2 = findNewVertex(i3, i2, plane);
                    if (side3 == true)
                    {                                           //               i3 /\                  Positive Side
                        posTriangles.Add(i3 + 1);               //                 /  \
                        posTriangles.Add(vertex1 + 1);          //         vertex1/____\vertex2
                        posTriangles.Add(vertex2 + 1);          //               /   _-'\
                                                                //            i1/_.-'____\i2            Negative Side
                        negTriangles.Add(i1 + 1);
                        negTriangles.Add(i2 + 1);
                        negTriangles.Add(vertex2 + 1);

                        negTriangles.Add(i1 + 1);
                        negTriangles.Add(vertex2 + 1);
                        negTriangles.Add(vertex1 + 1);
                    }
                    else
                    {                                           //               i3 /\                  Negative Side
                        negTriangles.Add(i3 + 1);               //                 /  \
                        negTriangles.Add(vertex1 + 1);          //         vertex1/____\vertex2
                        negTriangles.Add(vertex2 + 1);          //               /   _-'\
                                                                //            i1/_.-'____\i2            Positive Side
                        posTriangles.Add(i1 + 1);
                        posTriangles.Add(i2 + 1);
                        posTriangles.Add(vertex2 + 1);

                        posTriangles.Add(i1 + 1);
                        posTriangles.Add(vertex2 + 1);
                        posTriangles.Add(vertex1 + 1);
                    }
                }

                if (odd == true)
                {
                    //add inner triangles
                    posInnerTriangles.Add(vertex1 + 2);
                    posInnerTriangles.Add(0);
                    posInnerTriangles.Add(vertex2 + 2);

                    negInnerTriangles.Add(vertex1 + 2);
                    negInnerTriangles.Add(vertex2 + 2);
                    negInnerTriangles.Add(0);
                }
                else
                {
                    negInnerTriangles.Add(vertex1 + 2);
                    negInnerTriangles.Add(0);
                    negInnerTriangles.Add(vertex2 + 2);

                    posInnerTriangles.Add(vertex1 + 2);
                    posInnerTriangles.Add(vertex2 + 2);
                    posInnerTriangles.Add(0);
                }

                /*if (odd == true)
                {
                    //add inner triangles
                    posTriangles.Add(vertex1 + 1);
                    posTriangles.Add(0);
                    posTriangles.Add(vertex2 + 1);

                    negTriangles.Add(vertex1 + 1);
                    negTriangles.Add(vertex2 + 1);
                    negTriangles.Add(0);
                }
                else
                {
                    negTriangles.Add(vertex1 + 1);
                    negTriangles.Add(0);
                    negTriangles.Add(vertex2 + 1);

                    posTriangles.Add(vertex1 + 1);
                    posTriangles.Add(vertex2 + 1);
                    posTriangles.Add(0);
                }*/
            }
        }
        //now average all seam vertices to find center of inner face
        float x = 0;
        float y = 0;
        float z = 0;
        int n = seamVertices.Count;
        for (int j = 0; j < n; j++)
        {
            Vector3 current = seamVertices[j];
            x += current.x;
            y += current.y;
            z += current.z;
        }
        Vector3 center = new Vector3(x / n, y / n, z / n);

        var newVertices = new List<Vector3>();
        newVertices.Add(center); // at index 0
        newVertices.AddRange(vertices); // index 1 to vertices.length
        newVertices.AddRange(seamVertices); // then add the new seam vertices
        Vector3[] doneVertices = newVertices.ToArray();
        Vector2[] uvs = uv.ToArray();

        if (posTriangles.Count != 0 && negTriangles.Count != 0)//dont bother creating a gameobject if there are no triangles
        {
            Vector3 force = plane.normal * 50f;
            CreateNewSplit(doneVertices, posTriangles.ToArray(), posInnerTriangles.ToArray(), uvs, posNormals.ToArray(), force);
            CreateNewSplit(doneVertices, negTriangles.ToArray(), negInnerTriangles.ToArray(), uvs, negNormals.ToArray(), -force);
            if (OnSplit != null)
                OnSplit();
        }
        else
        {
            return;
        }

        splitting = false;
        PlaneGenerator.OnGeneration -= Split;
        Destroy(gameObject);
    }
Пример #14
0
    private void HandleCam()
    {
        //Debug.Log(deltaAimAngle_X);
        //Debug.Log(deltaAimAngle_Y);

        //Debug.DrawRay(tf.position, deltaAimPos_X, Color.red);
        //Debug.DrawRay(tf.position, deltaAimPos_Y, Color.green);
        //Debug.DrawRay(tf.position, Vector3.back * 10.0f);

        //HORIZONTAL
        Quaternion newHorRot = GetNewHorCamRot(deltaAimAngle_X);
        tf.rotation = Quaternion.Slerp(tf.rotation, newHorRot, Time.deltaTime * aimSensitivity);

        //VERTICAL
        //if (Mathf.Sign(deltaAimDirec.y) > 0.0f && Vector3.Angle(camTF.forward, Vector3.forward) < 90.0f)
        Quaternion newVertRot = GetNewVertCamRot(deltaAimAngle_Y);
        Quaternion finalVertRot = Quaternion.Slerp(camNeckTf.rotation, newVertRot, Time.deltaTime * aimSensitivity);

        //Debug.DrawRay(camNeckTf.position, finalVertRot * Vector3.forward, Color.red);

        //planes for limiting player's view rotation (currently generated every frame, this is only ideal if we change the player's orientation, like if gravity changed)
        Plane forwardPlane = new Plane(tf.forward, camNeckTf.position);
        Plane upPlane = new Plane(tf.up, camNeckTf.position);

        if (!forwardPlane.GetSide((finalVertRot * Vector3.forward) + camNeckTf.position)) {
        //LIMIT UP
            if (upPlane.GetSide((finalVertRot * Vector3.forward) + camNeckTf.position)) {
                //Debug.Log("up");
                finalVertRot = tf.rotation;
                finalVertRot *= Quaternion.LookRotation(tf.up, tf.up);

            }
        //LIMIT DOWN
            else {
                //Debug.Log("down");
                finalVertRot = tf.rotation;
                finalVertRot *= Quaternion.LookRotation(-tf.up, tf.up);
            }
        }

        //Debug.DrawRay(camNeckTf.position, upPlane.normal * 2.0f, Color.blue);

        camNeckTf.rotation = finalVertRot;
    }
Пример #15
0
    public void CutMeshToSelectionWithPlanes(Mesh mesh, GameObject meshObject, GameObject selectionArea)
    {
        meshObject.GetComponent <MeshFilter>().mesh = mesh;

        var planes = new OrderedDictionary()
        {
            { new Vector3(1, 0, 0), new Vector3(0.5f, 0, 0) },
            { new Vector3(-1, 0, 0), new Vector3(-0.5f, 0, 0) },
            { new Vector3(0, 1, 0), new Vector3(0, 0.5f, 0) },
            { new Vector3(0, -1, 0), new Vector3(0, -0.5f, 0) },
            { new Vector3(0, 0, 1), new Vector3(0, 0, 0.5f) },
            { new Vector3(0, 0, -1), new Vector3(0, 0, -0.5f) },
        };

        var meshFilter = gameObject.AddComponent <MeshFilter>();

        foreach (var n in planes.Keys)
        {
            var point = planes[n];

            var        res           = EzyCut((Vector3)point, (Vector3)n, meshObject, selectionArea, true);
            MeshFilter newMeshFilter = null;
            if (res is null)
            {
                newMeshFilter = meshObject.GetComponent <MeshFilter>();
            }
            else if (res.Length == 2)
            {
                newMeshFilter = res[0].GetComponent <MeshFilter>();
                Destroy(res[0]);
                Destroy(res[1]);
            }

            meshFilter.mesh = CutMeshToSelection(meshObject.GetComponent <MeshFilter>().mesh, (vertices) =>
            {
                var result     = new List <int>();
                var worldN     = selectionArea.transform.TransformDirection((Vector3)n);
                var worldPoint = selectionArea.transform.TransformPoint((Vector3)point);
                var plane      = new UnityEngine.Plane(worldN, worldPoint);
                for (var j = 0; j < vertices.Length; j++)
                {
                    if (!plane.GetSide(vertices[j]))
                    {
                        result.Add(j);
                    }
                }

                return(result);
            });
            if (res != null && res.Length == 2)
            {
                var listMeshFilters = new List <MeshFilter>()
                {
                    newMeshFilter, meshFilter
                };
                var combined = CombineMeshes(listMeshFilters);
                meshFilter.mesh = combined;
            }
            meshObject.GetComponent <MeshFilter>().mesh = meshFilter.mesh;
        }
        meshObject.SetActive(true);
        Destroy(meshFilter);
    }
Пример #16
0
    void Save()
    {
        model = transform.root.GetComponentInChildren<SkinnedMeshRenderer>();

        if (!Split)
            return;
        //foreach (var a in this.transform.root.GetComponentsInChildren<Rigidbody>())
        //    a.isKinematic = true;

        var r = model;
        var lcp = r.transform.localPosition;
        var lcr = r.transform.localRotation;
        var lcp2 = r.transform.root.position;
        var lcr2 = r.transform.root.rotation;
        r.transform.localPosition = Vector3.zero;
        r.transform.localRotation = Quaternion.identity;
        r.transform.root.position = Vector3.zero;
        r.transform.root.rotation = Quaternion.identity;

        plane = new Plane(transform.up, transform.position);
        var sharedMesh = new Mesh();
        r.BakeMesh(sharedMesh);
        vertices = sharedMesh.vertices;
        var Points = new Point[vertices.Length];

        var triangles = sharedMesh.triangles;
        boneWeights = r.sharedMesh.boneWeights;
        var bones = new List<Transform>(r.bones);
        foreach(var a in UpperBones)
        {
            var indexOf = bones.IndexOf(a);
            if (indexOf != -1)
                ubID.Add(indexOf);
        }
        if (ubID.Count == 0) throw new Exception("upper bone not found ");
        foreach (var a in lowerBones)
        {
            var indexOf = bones.IndexOf(a);
            if (indexOf != -1)
                lbID.Add(indexOf);
        }
        if (lbID.Count == 0) throw new Exception("lower bone not found ");

        Transform[] bt = UpperBones[0].GetComponentsInChildren<Transform>();
        for (int i = 0; i < bt.Length; i++)
        {
            var indexOf = bones.IndexOf(bt[i]);
            if (indexOf != -1)
                temp.Add(new BoneSave() { boneid = indexOf, i = i });
        }

        Dictionary<KeyValuePair<int, int>, int> dict = new Dictionary<KeyValuePair<int, int>, int>();
        for (int i = 0; i < vertices.Length; i++)
        {
            Points[i] = new Point(vertices[i]) { index = i };
            var side = plane.GetSide(vertices[i]);

            var v = vertices[i];
            v += plane.normal * -plane.GetDistanceToPoint(v);
            if (this.collider.bounds.Contains(v))
                for (int j = 0; j < 4; j++)
                {
                    var boneid = GetBone(boneWeights[i], j);
                    if (lbID.Contains(boneid) && side)
                    {
                        SetBone(ref boneWeights[i], j, ubID[0]);
                        dict[new KeyValuePair<int, int>(i, j)] = ubID[0];
                    }

                    if (ubID.Contains(boneid) && !side)
                    {
                        SetBone(ref boneWeights[i], j, lbID[0]);
                        dict[new KeyValuePair<int, int>(i, j)] = lbID[0];
                    }
                }
        }
        boneSave.Clear();
        foreach (var a in dict)
            boneSave.Add(new BoneSave() { vertex = a.Key.Key, i = a.Key.Value, boneid = a.Value });
        triangleSave.Clear();
        for (int i = 0; i < triangles.Length / 3; i++)
        {
            var index0 = i * 3;
            Point p0 = Points[triangles[index0]];
            Point p1 = Points[triangles[index0 + 1]];
            Point p2 = Points[triangles[index0 + 2]];

            var sameSide = SameSide(p0, p1) && SameSide(p0, p2) && SameSide(p1, p2);
            if (drawGizmo)
            {
                Debug.DrawLine(p0.pos, p1.pos, sameSide ? Color.blue : Color.red, 5);
                Debug.DrawLine(p1.pos, p2.pos, sameSide ? Color.blue : Color.red, 5);
                Debug.DrawLine(p2.pos, p0.pos, sameSide ? Color.blue : Color.red, 5);
            }
            if (!sameSide)
            {
                triangleSave.Add(index0);
                triangles[index0] = 0;
                triangles[index0 + 1] = 0;
                triangles[index0 + 2] = 0;
            }
        }
        //r.sharedMesh = (Mesh)Instantiate(r.sharedMesh);
        //r.sharedMesh.boneWeights = boneWeights.ToArray();
        //r.sharedMesh.triangles = triangles.ToArray();
        SetDirty();

        r.transform.localPosition = lcp;
        r.transform.localRotation = lcr;
        r.transform.root.position = lcp2;
        r.transform.root.rotation = lcr2;
    }
Пример #17
0
        public Vector3 PlaneAvoidance()
        {
            makeFeelers();

            Plane worldPlane = new Plane(new Vector3(0, 1, 0), 0);
            Vector3 force = Vector3.zero;
            foreach (Vector3 feeler in PlaneAvoidanceFeelers)
            {
                if (!worldPlane.GetSide(feeler))
                {
                    float distance = Math.Abs(worldPlane.GetDistanceToPoint(feeler));
                    force += worldPlane.normal * distance;
                }
            }

            if (force.magnitude > 0.0)
            {
                DrawFeelers();
            }
            return force;
        }
Пример #18
0
 private bool UpdateRectSelection()
 {
   bool flag1 = false;
   SkinnedMeshRenderer component = this.cloth.GetComponent<SkinnedMeshRenderer>();
   Vector3[] normals = this.cloth.normals;
   ClothSkinningCoefficient[] coefficients = this.cloth.coefficients;
   float x1 = Mathf.Min(this.m_SelectStartPoint.x, this.m_SelectMousePoint.x);
   float x2 = Mathf.Max(this.m_SelectStartPoint.x, this.m_SelectMousePoint.x);
   float y1 = Mathf.Min(this.m_SelectStartPoint.y, this.m_SelectMousePoint.y);
   float y2 = Mathf.Max(this.m_SelectStartPoint.y, this.m_SelectMousePoint.y);
   Ray worldRay1 = HandleUtility.GUIPointToWorldRay(new Vector2(x1, y1));
   Ray worldRay2 = HandleUtility.GUIPointToWorldRay(new Vector2(x2, y1));
   Ray worldRay3 = HandleUtility.GUIPointToWorldRay(new Vector2(x1, y2));
   Ray worldRay4 = HandleUtility.GUIPointToWorldRay(new Vector2(x2, y2));
   Plane plane1 = new Plane(worldRay2.origin + worldRay2.direction, worldRay1.origin + worldRay1.direction, worldRay1.origin);
   Plane plane2 = new Plane(worldRay3.origin + worldRay3.direction, worldRay4.origin + worldRay4.direction, worldRay4.origin);
   Plane plane3 = new Plane(worldRay1.origin + worldRay1.direction, worldRay3.origin + worldRay3.direction, worldRay3.origin);
   Plane plane4 = new Plane(worldRay4.origin + worldRay4.direction, worldRay2.origin + worldRay2.direction, worldRay2.origin);
   Quaternion rotation = component.actualRootBone.rotation;
   for (int index = 0; index < coefficients.Length; ++index)
   {
     Vector3 lastVertex = this.m_LastVertices[index];
     bool flag2 = (double) Vector3.Dot(rotation * normals[index], Camera.current.transform.forward) <= 0.0;
     bool flag3 = plane1.GetSide(lastVertex) && plane2.GetSide(lastVertex) && plane3.GetSide(lastVertex) && plane4.GetSide(lastVertex) && (this.state.ManipulateBackfaces || flag2);
     if (this.m_RectSelection[index] != flag3)
     {
       this.m_RectSelection[index] = flag3;
       flag1 = true;
     }
   }
   return flag1;
 }
Пример #19
0
    static bool Plane_GetSide__Vector3(JSVCall vc, int argc)
    {
        int len = argc;

        if (len == 1)
        {
            UnityEngine.Vector3 arg0    = (UnityEngine.Vector3)JSApi.getVector3S((int)JSApi.GetType.Arg);
            UnityEngine.Plane   argThis = (UnityEngine.Plane)vc.csObj;                JSApi.setBooleanS((int)JSApi.SetType.Rval, (System.Boolean)(argThis.GetSide(arg0)));
            JSMgr.changeJSObj(vc.jsObjID, argThis);
        }

        return(true);
    }
Пример #20
0
 /// <summary>
 /// Returns true if THIS metric fits inside the given CONTAINER mesh.
 /// </summary>
 /// <param name="this_T">Transform of this metric.</param>
 /// <param name="other_T">Transform of the given mesh.</param>
 /// <param name="container">Mesh acting as a container.</param>
 /// Implemeted using algorithm described at
 /// http://answers.unity3d.com/questions/611947/am-i-inside-a-volume-without-colliders.html
 public bool FitsAligned(Transform this_T, Transform other_T, Mesh container)
 {
     //get edges in containers reference frame
     var edges = hull != null? hull.Points.ToArray() : BoundsEdges(bounds);
     //check each triangle of container
     var c_edges   = container.vertices;
     var triangles = container.triangles;
     if(triangles.Length/3 > edges.Length)
     {
         for(int i = 0; i < edges.Length; i++)
             edges[i] = other_T.InverseTransformPoint(this_T.position+this_T.TransformDirection(edges[i]-center));
         for(int i = 0; i < triangles.Length/3; i++)
         {
             var V1 = c_edges[triangles[i*3]];
             var V2 = c_edges[triangles[i*3+1]];
             var V3 = c_edges[triangles[i*3+2]];
             var P  = new Plane(V1, V2, V3);
             foreach(Vector3 edge in edges)
             { if(!P.GetSide(edge)) return false; }
         }
     }
     else
     {
         var planes = new Plane[triangles.Length/3];
         for(int i = 0; i < triangles.Length/3; i++)
         {
             var V1 = c_edges[triangles[i*3]];
             var V2 = c_edges[triangles[i*3+1]];
             var V3 = c_edges[triangles[i*3+2]];
             planes[i] = new Plane(V1, V2, V3);
         }
         for(int i = 0; i < edges.Length; i++)
         {
             var edge = other_T.InverseTransformPoint(this_T.position+this_T.TransformDirection(edges[i]-center));
             foreach(Plane P in planes)
             { if(!P.GetSide(edge)) return false; }
         }
     }
     return true;
 }
Пример #21
0
 private bool UpdateRectSelection()
 {
     bool flag = false;
     SkinnedMeshRenderer component = this.cloth.GetComponent<SkinnedMeshRenderer>();
     Vector3[] normals = this.cloth.normals;
     ClothSkinningCoefficient[] coefficients = this.cloth.coefficients;
     float x = Mathf.Min(this.m_SelectStartPoint.x, this.m_SelectMousePoint.x);
     float num2 = Mathf.Max(this.m_SelectStartPoint.x, this.m_SelectMousePoint.x);
     float y = Mathf.Min(this.m_SelectStartPoint.y, this.m_SelectMousePoint.y);
     float num4 = Mathf.Max(this.m_SelectStartPoint.y, this.m_SelectMousePoint.y);
     Ray ray = HandleUtility.GUIPointToWorldRay(new Vector2(x, y));
     Ray ray2 = HandleUtility.GUIPointToWorldRay(new Vector2(num2, y));
     Ray ray3 = HandleUtility.GUIPointToWorldRay(new Vector2(x, num4));
     Ray ray4 = HandleUtility.GUIPointToWorldRay(new Vector2(num2, num4));
     Plane plane = new Plane(ray2.origin + ray2.direction, ray.origin + ray.direction, ray.origin);
     Plane plane2 = new Plane(ray3.origin + ray3.direction, ray4.origin + ray4.direction, ray4.origin);
     Plane plane3 = new Plane(ray.origin + ray.direction, ray3.origin + ray3.direction, ray3.origin);
     Plane plane4 = new Plane(ray4.origin + ray4.direction, ray2.origin + ray2.direction, ray2.origin);
     Quaternion rotation = component.actualRootBone.rotation;
     for (int i = 0; i < coefficients.Length; i++)
     {
         Vector3 inPt = this.m_LastVertices[i];
         bool flag2 = Vector3.Dot((Vector3) (rotation * normals[i]), Camera.current.transform.forward) <= 0f;
         bool flag3 = (((plane.GetSide(inPt) && plane2.GetSide(inPt)) && plane3.GetSide(inPt)) && plane4.GetSide(inPt)) && (this.state.ManipulateBackfaces || flag2);
         if (this.m_RectSelection[i] != flag3)
         {
             this.m_RectSelection[i] = flag3;
             flag = true;
         }
     }
     return flag;
 }
Пример #22
0
        /**
         * Slice the gameobject mesh (if any) using the Plane, which will generate
         * a maximum of 2 other Meshes.
         * This function will recalculate new UV coordinates to ensure textures are applied
         * properly.
         * Returns null if no intersection has been found or the GameObject does not contain
         * a valid mesh to cut.
         */
        public static SlicedHull Slice(Mesh sharedMesh, Plane pl, TextureRegion region, int crossIndex, bool intersectionOnly = false)
        {
            if (sharedMesh == null)
            {
                return(null);
            }

            Vector3[] verts = sharedMesh.vertices;
            Vector2[] uv    = sharedMesh.uv;
            Vector3[] norm  = sharedMesh.normals;
            Vector4[] tan   = sharedMesh.tangents;

            int submeshCount = sharedMesh.subMeshCount;

            // each submesh will be sliced and placed in its own array structure
            SlicedSubmesh[] slices = new SlicedSubmesh[submeshCount];
            // the cross section hull is common across all submeshes
            List <Vector3> crossHull = new List <Vector3>();

            // we reuse this object for all intersection tests
            IntersectionResult result = new IntersectionResult();

            // see if we would like to split the mesh using uv, normals and tangents
            bool genUV   = verts.Length == uv.Length;
            bool genNorm = verts.Length == norm.Length;
            bool genTan  = verts.Length == tan.Length;

            // iterate over all the submeshes individually. vertices and indices
            // are all shared within the submesh
            for (int submesh = 0; submesh < submeshCount; submesh++)
            {
                int[] indices      = sharedMesh.GetTriangles(submesh);
                int   indicesCount = indices.Length;

                SlicedSubmesh mesh = new SlicedSubmesh();

                // loop through all the mesh vertices, generating upper and lower hulls
                // and all intersection points
                for (int index = 0; index < indicesCount; index += 3)
                {
                    int i0 = indices[index + 0];
                    int i1 = indices[index + 1];
                    int i2 = indices[index + 2];

                    Triangle newTri = new Triangle(verts[i0], verts[i1], verts[i2]);

                    // generate UV if available
                    if (genUV)
                    {
                        newTri.SetUV(uv[i0], uv[i1], uv[i2]);
                    }

                    // generate normals if available
                    if (genNorm)
                    {
                        newTri.SetNormal(norm[i0], norm[i1], norm[i2]);
                    }

                    // generate tangents if available
                    if (genTan)
                    {
                        newTri.SetTangent(tan[i0], tan[i1], tan[i2]);
                    }

                    // slice this particular triangle with the provided
                    // plane
                    result.Clear();

                    if (newTri.Split(pl, result))
                    {
                        int upperHullCount = result.upperHullCount;
                        int lowerHullCount = result.lowerHullCount;
                        int interHullCount = result.intersectionPointCount;

                        for (int i = 0; i < upperHullCount; i++)
                        {
                            mesh.upperHull.Add(result.upperHull[i]);
                        }

                        for (int i = 0; i < lowerHullCount; i++)
                        {
                            mesh.lowerHull.Add(result.lowerHull[i]);
                        }

                        for (int i = 0; i < interHullCount; i++)
                        {
                            crossHull.Add(result.intersectionPoints[i]);
                        }
                    }
                    else if (!intersectionOnly)
                    {
                        var unityPl = new UnityEngine.Plane(pl.normal, pl.pos);
                        if (unityPl.GetSide(verts[i0]) && unityPl.GetSide(verts[i1]) && unityPl.GetSide(verts[i2]))
                        {
                            mesh.upperHull.Add(newTri);
                        }
                        else
                        {
                            mesh.lowerHull.Add(newTri);
                        }
                    }
                }

                // register into the index
                slices[submesh] = mesh;
            }

            // check if slicing actually occured
            for (int i = 0; i < slices.Length; i++)
            {
                // check if at least one of the submeshes was sliced. If so, stop checking
                // because we need to go through the generation step
                if (slices[i] != null && slices[i].isValid)
                {
                    return(CreateFrom(slices, CreateFrom(crossHull, pl.normal, region), crossIndex));
                }
            }

            // no slicing occured, just return null to signify
            return(null);
        }
Пример #23
0
	public void SliceMyMesh() {
		if (MyMesh) {
			//GameObject SlicedMesh = (GameObject) Instantiate (gameObject, transform.position, Quaternion.identity);	// off set the positions after the meshes are created, by finding out the releative bounds difference
			SlicedCustomMesh1 = (CustomMesh) gameObject.GetComponent("CustomMesh");
			//SlicedCustomMesh2 = (CustomMesh) SlicedMesh.GetComponent("CustomMesh");

			//SlicedCustomMesh2.IsSingleCube = false;

			//MyPlaneNormal = MyPlaneRotation.transform.position;
			MySlicePlane = new Plane(MyPlaneNormal, PlaneDistance);
			MySlicePlane.SetNormalAndPosition(MyPlaneNormal, new Vector3(0,0.5f,0));
			 SlicedPoints1 = new List<Vector3>();
			SlicedIndicies1 = new List<int>();
			SlicedPoints2 = new List<Vector3>();
			SlicedIndicies2 = new List<int>();
			// Where the plane intersects
			SlicedIndicies3 = new List<int>();
			SlicedIndicies4 = new List<int>();
			SlicedPoints4 = new List<Vector3>();
			//SlicedMesh.MyCustomMesh

			// Add all the indicies that intersect with the plane
			for (int i = 0; i < SlicedCustomMesh1.MyCustomMesh.Indicies.Count; i += 3) {	// for all the meshes triangles
				Vector3 Vertex1 = SlicedCustomMesh1.MyCustomMesh.Verticies[SlicedCustomMesh1.MyCustomMesh.Indicies[i]];
				Vector3 Vertex2 = SlicedCustomMesh1.MyCustomMesh.Verticies[SlicedCustomMesh1.MyCustomMesh.Indicies[i+1]];
				Vector3 Vertex3 = SlicedCustomMesh1.MyCustomMesh.Verticies[SlicedCustomMesh1.MyCustomMesh.Indicies[i+2]];
				
				if (MySlicePlane.GetSide(Vertex1+MyPlanePosition) && MySlicePlane.GetSide(Vertex2+MyPlanePosition) && MySlicePlane.GetSide(Vertex3+MyPlanePosition)) {	// if all 3 verticies are on the same side

				} else if (!MySlicePlane.GetSide(Vertex1+MyPlanePosition) && !MySlicePlane.GetSide(Vertex2+MyPlanePosition) && !MySlicePlane.GetSide(Vertex3+MyPlanePosition)) { // if they are not on same side, they are intersected by the plane

				} else {
					SlicedIndicies3.Add(SlicedCustomMesh1.MyCustomMesh.Indicies[i]);
					SlicedIndicies3.Add(SlicedCustomMesh1.MyCustomMesh.Indicies[i+1]);
					SlicedIndicies3.Add(SlicedCustomMesh1.MyCustomMesh.Indicies[i+2]);
					SlicedPoints3.Add (Vertex1);
					SlicedPoints3.Add (Vertex2);
					SlicedPoints3.Add (Vertex3);
				}
			}

			// Now create slices in these triangles
			for (int i = 0; i < SlicedIndicies3.Count; i += 3) {	// for all the meshes triangles
				Vector3 Vertex1 = SlicedCustomMesh1.MyCustomMesh.Verticies[SlicedIndicies3[i]];
				Vector3 Vertex2 = SlicedCustomMesh1.MyCustomMesh.Verticies[SlicedIndicies3[i+1]];
				Vector3 Vertex3 = SlicedCustomMesh1.MyCustomMesh.Verticies[SlicedIndicies3[i+2]];
				// from a slice through a triangle
				// we can get a maximum of 5 points
				// break down 5 points into 3 triangles
				// test this by chose random points along the triangle lines and adding them vertexes

				//RaycastHit hit1;
				Ray Ray1 = new Ray(Vertex1, Vertex1-Vertex2);
				float RayDistance1 = Vector3.Distance (Vertex1, Vertex2);
				if (MySlicePlane.Raycast(Ray1, out RayDistance1)) {
					Debug.Log(" Triangles are sliced 1" );
					DebugVector3 (SlicedCustomMesh1.MyCustomMesh.Verticies[SlicedIndicies3[i]]);
				} else  {
					Debug.Log(i + " Triangles Not Sliced Vertex 1 - ");
					Debug.Log ("    Distance: " + RayDistance1);
					DebugVector3 (Vertex1);
					DebugVector3 (Vertex1 + Ray1.direction*RayDistance1);

					if (RayDistance1 != 0) {
						SlicedIndicies4.Add (i);
						SlicedPoints4.Add (Vertex1 + Ray1.direction*RayDistance1);
						//SlicedCustomMesh1.MyCustomMesh.Verticies[SlicedIndicies3[i]] = Vertex1 + Ray1.direction*RayDistance1;
					}
				}
				Ray Ray2 = new Ray(Vertex2, Vertex2-Vertex3);
				float RayDistance2 = Vector3.Distance (Vertex1, Vertex2);
				if (MySlicePlane.Raycast(Ray2, out RayDistance2)) {
					Debug.Log(" Triangles are sliced 2" );
					SlicedCustomMesh1.MyCustomMesh.Verticies[SlicedIndicies3[i]] = Vertex2 + Ray2.direction*RayDistance2;
				} else  {
					Debug.Log(i + " Triangles Not Sliced 2 - ");
					Debug.Log ("    Distance: " + RayDistance2);
					DebugVector3 (Vertex2);
					DebugVector3 (Vertex2 + Ray2.direction*RayDistance2);
					if (RayDistance2 != 0) {
						SlicedIndicies4.Add (i+1);
						SlicedPoints4.Add (Vertex2 + Ray2.direction*RayDistance2);
						//SlicedCustomMesh1.MyCustomMesh.Verticies[SlicedIndicies3[i]] = Vertex2 + Ray2.direction*RayDistance2;
					}
				}
				Ray Ray3 = new Ray(Vertex3, Vertex3-Vertex1);
				float RayDistance3 = Vector3.Distance (Vertex3, Vertex1);
				if (MySlicePlane.Raycast(Ray3, out RayDistance3)) {
					Debug.Log(" Triangles are sliced 3" );
					DebugVector3 (Vertex2);
					SlicedCustomMesh1.MyCustomMesh.Verticies[SlicedIndicies3[i]] = Vertex3 + Ray3.direction*RayDistance3;
				} else  {
					Debug.Log(i + " Triangles a Not Sliced 3 -");
					Debug.Log ("    Distance: " + RayDistance3);
					DebugVector3 (Vertex3);
					DebugVector3 (Vertex3 + Ray3.direction*RayDistance3);
					if (RayDistance3 != 0) {
						SlicedIndicies4.Add (i+2);
						SlicedPoints4.Add (Vertex3 + Ray3.direction*RayDistance3);
						//SlicedCustomMesh1.MyCustomMesh.Verticies[SlicedIndicies3[i]] = Vertex3 + Ray3.direction*RayDistance3;
					}
				}
				//Mathf.Int
			}
			// test slice through the middle, where the plane is .5, .5 ,.5
			// Concieve a 2d plane that is the slice (sword action pewpew)
			// find all the intersecting points with the mesh
			for (int i = 0; i < SlicedCustomMesh1.MyCustomMesh.Indicies.Count; i += 3) {	// for all the meshes triangles
				//SlicedCustomMesh2.MyCustomMesh.Indicies[i] = 0;
				Vector3 Vertex1 = SlicedCustomMesh1.MyCustomMesh.Verticies[SlicedCustomMesh1.MyCustomMesh.Indicies[i]];
				Vector3 Vertex2 = SlicedCustomMesh1.MyCustomMesh.Verticies[SlicedCustomMesh1.MyCustomMesh.Indicies[i+1]];
				Vector3 Vertex3 = SlicedCustomMesh1.MyCustomMesh.Verticies[SlicedCustomMesh1.MyCustomMesh.Indicies[i+2]];
				// if our vertexes are on the positive side of the plane, add to mesh 1
				//if (Vertex1.y > 0.5f) {
				if (MySlicePlane.GetSide(Vertex1) && MySlicePlane.GetSide(Vertex2) && MySlicePlane.GetSide(Vertex3)) {	// if all 3 verticies are on the same side
					SlicedIndicies1.Add(SlicedCustomMesh1.MyCustomMesh.Indicies[i]);
					SlicedIndicies1.Add(SlicedCustomMesh1.MyCustomMesh.Indicies[i+1]);
					SlicedIndicies1.Add(SlicedCustomMesh1.MyCustomMesh.Indicies[i+2]);
				//} else {
				} else if (!MySlicePlane.GetSide(Vertex1) && !MySlicePlane.GetSide(Vertex2) && !MySlicePlane.GetSide(Vertex3)){ // if they are not on same side, they are intersected by the plane
					SlicedIndicies2.Add(SlicedCustomMesh1.MyCustomMesh.Indicies[i]);
					SlicedIndicies2.Add(SlicedCustomMesh1.MyCustomMesh.Indicies[i+1]);
					SlicedIndicies2.Add(SlicedCustomMesh1.MyCustomMesh.Indicies[i+2]);
				}
			}

			//for (int i = 0; i < 0
			// Add all the points onto 2 new meshes

			// Add the rest of the meshes points onto the 2 created ones

			// Instantiate the new objects in the points it was cut

			// test this with non moving objects for positioning
			//SlicedCustomMesh1.MyCustomMesh.Verticies = SlicedPoints1;
			if (IsSlice) {
				SlicedCustomMesh1.MyCustomMesh.Indicies.Clear ();
				//SlicedCustomMesh1.MyCustomMesh.Indicies = SlicedIndicies1;
				SlicedCustomMesh1.MyCustomMesh.Indicies = SlicedIndicies3;
				//SlicedCustomMesh2.MyCustomMesh.Indicies.Clear ();
				//SlicedCustomMesh2.MyCustomMesh.Indicies = SlicedIndicies2;

			//SlicedCustomMesh1.MyCustomMesh.Refresh(SlicedPoints1, SlicedIndicies1, SlicedCustomMesh1.MyCustomMesh.TextureCoordinates);
			//SlicedCustomMesh2.MyCustomMesh.Refresh(SlicedPoints2, SlicedIndicies2, SlicedCustomMesh2.MyCustomMesh.TextureCoordinates);

				SlicedCustomMesh1.UpdateMesh(SlicedCustomMesh1.MyCustomMesh);
				//SlicedCustomMesh2.UpdateMesh(SlicedCustomMesh2.MyCustomMesh);
			}
		}
	}
Пример #24
0
	public void _StrokePath() {
		Terrain ter = (Terrain) GetComponent(typeof(Terrain));
		if (ter == null) {
			Debug.LogError("No terrain component on this GameObject");
			return;
		}		
		int Px = 0;
		int Py = 0;		
		try { 
			TerrainData terData = ter.terrainData;
			int Tw = terData.heightmapWidth; //heightMapResolution in pixels
			int Th = terData.heightmapHeight;//heightMapResolution in pixels
			Vector3 Ts = terData.size; //x and z and height of terrain
			
			if (VERBOSE) Debug.Log("terrainData heightmapHeight/heightmapWidth:" + Tw + " " + Tw);
			if (VERBOSE) Debug.Log("terrainData heightMapResolution:" + terData.heightmapResolution);
			if (VERBOSE) Debug.Log("terrainData size:" + terData.size);
			
			Vector3 ls = transform.localScale; //need to remember and reset the scale because the InverseTransform does not work properly for terrains because they ignore the scale
			transform.localScale = new Vector3(1.0f,1.0f,1.0f);
			List<Vector3> controlPointsLocal = new List<Vector3>();//[controlPoints.Count];
			for (int i = 0; i < controlPoints.Count; i++){
				//don't use inverse transform point because terrain ignores rotation and scale
				controlPointsLocal.Add( controlPoints[i] - transform.position );
			}
			
			//Vector3 localBeginPosition = transform.InverseTransformPoint(beginRamp);
			//Vector3 localEndPosition = transform.InverseTransformPoint(endRamp);
			
			transform.localScale = ls;
			
//			int[] pi = terrainCordsToBitmap(terData,localBeginPosition);
//			int[] pf = terrainCordsToBitmap(terData,localEndPosition);
			
			for (int i = 0; i < controlPointsLocal.Count; i++){
				int[] p = terrainCordsToBitmap(terData,controlPointsLocal[i]);
				if (p[0] < 0 || p[1] < 0 || p[0] >= Tw || p[1] >= Th){
					Debug.LogError("The start point or the end point was out of bounds. Make sure the gizmo is over the terrain before setting the start and end points." +
						           "Note: that sometimes Unity does not update the collider after changing settings in the 'Set Resolution' dialog. Entering play mode should reset the collider.");
					return;
				}
			}

			int Sx = (int) Mathf.Floor((Tw / Ts.z) * brushSize); //the x and z are mixed up intentionally
			int Sz = (int) Mathf.Floor((Th / Ts.x) * brushSize); //the x and z are mixed up intentionally
						

			
			float[,] heightMapAll = terData.GetHeights(0, 0, Tw, Th);
			
			//calculate plane. n is plane normal, localEnd and localBegin are in plane.
			//plane uses terrain cord system, y coordinate is in terrain height units, not world units.
			for (int i = 0; i < controlPointsLocal.Count; i++){
				int[] p = terrainCordsToBitmap(terData,controlPointsLocal[i]);
				Vector3 v = controlPointsLocal[i];
				v.y = heightMapAll[p[0],p[1]];
				controlPointsLocal[i] = v;
			}
			
			calculateDistBetweenPoints(controlPointsLocal);
			calculateDistBetweenPointsInPixels(controlPointsLocal,terData);			
			float timeIncrement = (float) (brushSampleDensity) / _totalLengthPixels;
			float timeBrushWidth = (float) (brushSize) / _totalLengthPixels; //the width of the brush in parameterized t
			Debug.Log("Sample w " + Sx + " h " + Sz);
			Debug.Log("parameterized brush width " + timeBrushWidth);
			if (timeBrushWidth > .5f) timeBrushWidth = .5f;
			
			if (VERBOSE){
				for (int i = 0; i < controlPointsLocal.Count; i++){
					int[] pi = terrainCordsToBitmap(terData,controlPointsLocal[i]);
					float[] temp = bitmapCordsToTerrain(terData,pi[0],pi[1]);
					Debug.Log(i + " Local control Pos:" + controlPointsLocal[i]);
					Debug.Log(i + " pixel begin coord:" + pi[0] + " " + pi[0]);
					Debug.Log(i + " Local begin Pos Rev Transformed:" + temp[0] + " " + temp[1]);						
				}
				Debug.Log("parameterized brush width " + timeBrushWidth);
			}			
			StringBuilder sb = new StringBuilder();	
			for(float t = 0.0f; t <= 1.0f; t += timeIncrement){
				Ray psamp = parameterizedLine(t,controlPointsLocal);  //localBeginPosition + t * (v1);
				Vector3 n = Vector3.Cross(new Vector3(-psamp.direction.z, 0.0f, psamp.direction.x), psamp.direction);
				n.Normalize();
				if (spacingJitter > 0f){
					float tt = 2f*Mathf.PI*UnityEngine.Random.value;
					float u = UnityEngine.Random.value+UnityEngine.Random.value;
					float r;
					if (u > 1f) {
						r = 2f-u; 
					} else { 
						r = u;
					}
					r *= spacingJitter * brushSize;
					Vector3 randV = new Vector3(r*Mathf.Cos(tt), 0f, r*Mathf.Sin(tt));
					if (VERBOSE) Debug.Log("jittering by " + randV + " dir " + psamp.direction + " n " + n);
					Plane p = new Plane(n,psamp.origin);
					float ttt;
					Ray rr = new Ray(psamp.origin + randV,Vector3.up);
					if (p.Raycast(rr,out ttt)){
						Vector3 vv = rr.origin + rr.direction * ttt;
						psamp.origin = vv;
					}
				}

				Plane beginClipPlane;
				Plane endClipPlane;
				beginClipPlane = new Plane((controlPointsLocal[0]-controlPointsLocal[1]).normalized, controlPointsLocal[0]);
				endClipPlane = new Plane((controlPointsLocal[controlPointsLocal.Count - 1]-controlPointsLocal[controlPointsLocal.Count - 2]).normalized, controlPointsLocal[controlPointsLocal.Count - 1]);
				int[] pv = terrainCordsToBitmap(terData, psamp.origin);
				Px = pv[0] - Sx/2;
				Py = pv[1] - Sz/2; 
				 
				float[,] heightMap = new float[Sx,Sz]; //little brush size heightmap
				for (int i = 0; i < Sx; i ++){
					for (int j = 0; j <  Sz; j++){
						if (Px + i >= 0 && Py + j >=0 && Px + i < Tw && Py + j < Th) {
							heightMap[i,j] = heightMapAll[Px + i,Py + j] ;
						} else {
							heightMap[i,j] = 0;
						}
					}
				}				
				
				// build a perfect ramp that is size of brush
				float[,] erodedheightMap = (float[,]) heightMap.Clone();
				for (int Tx = 0; Tx < Sx; Tx++) {
					for (int Tz = 0; Tz < Sz; Tz++) {
						float[] My = bitmapCordsToTerrain(terData, (Px + Tx), (Py + Tz));
						//don't ramp points before begin position or after end position
						Vector3 myV = new Vector3(My[0],0f,My[1]);
						Boolean clipThisPoint = false;
						
						if (beginClipPlane.GetSide(myV) && t < timeBrushWidth/2f){
							clipThisPoint = true;
						} else if (endClipPlane.GetSide(myV) && t > 1f - timeBrushWidth/2f){
							clipThisPoint = true;
						}
						
						if (!clipThisPoint){
							//do raycast from zero straight against slope
							Plane p = new Plane(n,psamp.origin);
							Ray r = new Ray(myV,Vector3.up);
							float tt;
							if (!p.Raycast(r, out tt))continue;
//							sb.AppendFormat("n{0} psamp{1} r{2} t{3}\n",n,psamp.ToString("f5"),r,t);
							erodedheightMap[Tx,Tz] = r.origin.y + r.direction.y * tt;
//							Debug.Log("hm " + erodedheightMap[Tx,Tz] + " " +  heightMap[Tx,Tz]);
						}
					}
				}
			
				// Blend it to the terrain object
				float sampleRadius = Mathf.Min(Sz/2.0f, Sx/2.0f);
				for (int Tx = 0; Tx < Sx; Tx++) {
					for (int Ty = 0; Ty < Sz; Ty++) {
						float newHeightAtPoint = erodedheightMap[Tx, Ty];
						float oldHeightAtPoint = heightMap[Tx, Ty];
						float distanceFromCenter = Vector2.Distance(new Vector2(Tx, Ty), new Vector2(sampleRadius, sampleRadius));
						float weightAtPoint = (1.0f - distanceFromCenter / sampleRadius ) / brushSoftness;
						if (weightAtPoint < 0.0f) {
							weightAtPoint = 0.0f;
						} else if (weightAtPoint > 1.0f) {
							weightAtPoint = 1.0f;
						}
						weightAtPoint *= brushOpacity;
						float blendedHeightAtPoint = (newHeightAtPoint * weightAtPoint) + (oldHeightAtPoint * (1.0f - weightAtPoint));
						heightMap[Tx, Ty] = blendedHeightAtPoint;
					}
				}
				
				for (int i = 0; i < Sx; i ++){
					for (int j = 0; j <  Sz; j++){
						if (Px + i >= 0 && Py + j >=0 && Px + i < Tw && Py + j < Th) {
							heightMapAll[Px + i,Py + j] = heightMap[i,j];
						}
					}
				}
			}
			Debug.Log(sb);
			terData.SetHeights(0,0,heightMapAll);
			//beginRamp = endRamp;
		} catch (Exception e) {
		 	Debug.LogError("A brush error occurred: "+e);
		}			
	}
Пример #25
0
	 void Fracture(Vector3 point, Vector3 force, float iterations){
		MeshFilter thisMeshFilter = gameObject.GetComponent<MeshFilter>();

		if(instantiateOnBreak && force.magnitude >= Mathf.Max(minBreakingForce, forcePerDivision)){
			if(Network.isServer || Network.isClient) Network.Instantiate(instantiateOnBreak, transform.position, transform.rotation,0);
			else Instantiate(instantiateOnBreak, transform.position, transform.rotation);
			instantiateOnBreak=null;
		}
		while (iterations > 0){
			if(totalMaxFractures == 0 || Vector3.Min(thisMeshFilter.mesh.bounds.size, minFractureSize) != minFractureSize){
				if(destroySmallAfterTime >= 1.0f)
					Destroy(gameObject, destroySmallAfterTime);

				totalMaxFractures = 0;
				return;
			}
			totalMaxFractures--;
			iterations--;

			if(fractureAtCenter) point = thisMeshFilter.mesh.bounds.center;
			Vector3 vec = Vector3.Scale(grain,Random.insideUnitSphere).normalized;
			Vector3 sub = transform.worldToLocalMatrix.MultiplyVector(force.normalized)*(useCollisionDirection ? 1 : 0)*Vector3.Dot(transform.worldToLocalMatrix.MultiplyVector(force.normalized),vec);
			//Vector3 sub = transform.worldToLocalMatrix.MultiplyVector(force.normalized)*useCollisionDirection*Vector3.Dot(transform.worldToLocalMatrix.MultiplyVector(force.normalized),vec);
			Plane plane = new Plane(vec-sub,Vector3.Scale(Random.insideUnitSphere, thisMeshFilter.mesh.bounds.size)*randomOffset+point);
			GameObject newObject;
			if(Network.isServer || Network.isClient){
				newObject = _PublicData._PublicProperties.minePlayer.networkView.RPC("CreateCopyLocally",RPCMode.OthersBuffered,gameObject.transform);
				//newObject = Network.Instantiate(gameObject.transform, transform.position, transform.rotation,0) as GameObject;
			}
			else newObject = Instantiate(gameObject.transform, transform.position, transform.rotation) as GameObject;
			MeshFilter newObjectMeshFilter = newObject.GetComponent<MeshFilter>();
			if(avoidSelfCollision) IgnoreCollision(newObject.collider,gameObject.collider);
			
			if(rigidbody) newObject.rigidbody.velocity = rigidbody.velocity;
			Vector3[] vertsA = thisMeshFilter.mesh.vertices;
			Vector3[] vertsB = newObjectMeshFilter.mesh.vertices;
			
			Vector3 average = Vector3.zero;
			foreach(Vector3 i in vertsA) average+=i;
			
			average /= thisMeshFilter.mesh.vertexCount;
			average -= plane.GetDistanceToPoint(average)*plane.normal;

			int broken = 0;

			if(fractureToPoint){
				for(int i=0;i<thisMeshFilter.mesh.vertexCount;i++){
					if(plane.GetSide(vertsA[i])){
						vertsA[i] = average;
						broken++;
					}
					else vertsB[i] = average;
				}
			}
			else{
				for(int ii=0;ii<thisMeshFilter.mesh.vertexCount;ii++){
					if(plane.GetSide(vertsA[ii])){
						vertsA[ii] -= plane.GetDistanceToPoint(vertsA[ii])*plane.normal;
						broken++;
					}
					else vertsB[ii] -= plane.GetDistanceToPoint(vertsB[ii])*plane.normal;
				}
			}

			if(broken == 0 || broken == thisMeshFilter.mesh.vertexCount){
				totalMaxFractures++;
				iterations++;
				Destroy(newObject);
				//yield return null; //mmm
			}
			else{
				thisMeshFilter.mesh.vertices = vertsA;
				newObjectMeshFilter.mesh.vertices = vertsB;
				
				thisMeshFilter.mesh.RecalculateNormals();
				newObjectMeshFilter.mesh.RecalculateNormals();

				thisMeshFilter.mesh.RecalculateBounds();
				newObjectMeshFilter.mesh.RecalculateBounds();

				MeshCollider thisMeshCol = gameObject.GetComponent<MeshCollider>();
				if(thisMeshCol){
					thisMeshCol.sharedMesh = thisMeshFilter.mesh;
					newObject.GetComponent<MeshCollider>().sharedMesh = newObjectMeshFilter.mesh; //mmm
				}
				else{
					Destroy(collider);
					Destroy(gameObject, 1.0f);
				}
			}
			if(smartJoints){
				Joint[] jointsb = GetComponents<Joint>();
				if(jointsb.Length>0){
					for(int iii=0;iii<jointsb.Length;iii++){
						if(jointsb[iii].connectedBody!=null && plane.GetSide(transform.worldToLocalMatrix.MultiplyPoint(jointsb[iii].connectedBody.transform.position))){
							Joint[] tmpJoints = jointsb[iii].gameObject.GetComponent<ObjectDestruction>().joints;
							if(tmpJoints.Length>0){
								foreach(Joint j in tmpJoints){
									//if(j == jointsb[iii]) j=newObject.GetComponents<Joint>()[iii]; //mmm
								}
							}
							Destroy(jointsb[iii]);
						}
						else{
							Destroy(newObject.GetComponents<Joint>()[iii]);
						}
					}
				}
				if(joints!=null){
					ArrayList temp;
					for(int iiii=0;iiii<joints.Length;iiii++){
						if(joints[iiii] && plane.GetSide(transform.worldToLocalMatrix.MultiplyPoint(joints[iiii].transform.position))){
							joints[iiii].connectedBody=newObject.rigidbody;
							temp = new ArrayList(joints);
							temp.RemoveAt(iiii);
							joints = (Joint[]) temp.ToArray(typeof(Joint));
						}
						else{
							temp = new ArrayList(joints);
							temp.RemoveAt(iiii);
							newObject.GetComponent<ObjectDestruction>().joints = (Joint[]) temp.ToArray(typeof(Joint));
						}
					}
				}
			}
			else{
				if(GetComponent<Joint>()){
					Joint[] jnts = GetComponents<Joint>();
					Joint[] newjnts = GetComponents<Joint>();
					for(int i_i=0;i_i<jnts.Length;i_i++){
						Destroy(jnts[i_i]);
						Destroy(newjnts[i_i]);
					}
				}
				if(joints != null){
					foreach(Joint jnt in joints){
						Destroy(jnt);
					}
					joints=null;
				}
			}
			if(!rigidbody){
				gameObject.AddComponent<Rigidbody>();
				newObject.AddComponent<Rigidbody>();
				rigidbody.mass = totalMassIfStatic;
				newObject.rigidbody.mass = totalMassIfStatic;
			}
			gameObject.rigidbody.mass *= .5f;
			newObject.rigidbody.mass *= .5f;
			gameObject.rigidbody.centerOfMass = transform.worldToLocalMatrix.MultiplyPoint3x4(gameObject.collider.bounds.center);
			newObject.rigidbody.centerOfMass = transform.worldToLocalMatrix.MultiplyPoint3x4(newObject.collider.bounds.center);
			
			newObject.GetComponent<ObjectDestruction>().Fracture(point,force,iterations);
		
			if(destroyAllAfterTime>=1){
				Destroy(newObject.GetComponent<MeshCollider>(), destroyAllAfterTime-1);
				Destroy(gameObject.GetComponent<MeshCollider>(), destroyAllAfterTime-1);
				Destroy(newObject, destroyAllAfterTime);
				Destroy(gameObject, destroyAllAfterTime);
			}
			//yield return null;//hmmm
		}
		if(totalMaxFractures == 0 || Vector3.Min(thisMeshFilter.mesh.bounds.size,minFractureSize)!=minFractureSize){
			if(destroySmallAfterTime>=1){
				Destroy(GetComponent<MeshCollider>(), destroySmallAfterTime-1);
				Destroy(gameObject, destroySmallAfterTime);
			}
			totalMaxFractures = 0;
		}
	}
Пример #26
0
        //Calculate the plane for reflection in World Space.
        private static Plane ReflectionPlane(Vector3 viewerPos, Vector3 mirrorPos, Vector3 mirrorDir, float clipOffset)
        {
            float d = -Vector3.Dot (mirrorDir, mirrorPos) - clipOffset;
            Plane reflectionPlane = new Plane (mirrorDir, d);

            if (!reflectionPlane.GetSide (viewerPos))
            {
                // Flip the reflection plane if the camera is behide
                mirrorDir = -mirrorDir;
                d = -Vector3.Dot (mirrorDir, mirrorPos) - clipOffset;
                reflectionPlane = new Plane (mirrorDir, d);
            }

            return reflectionPlane;
        }
Пример #27
0
        /**
         * Splits a vertex in two along a plane. Returns true if the vertex can be split, false otherwise. Does not create new border
         * edges inside the tear in order to prevent non-manifold vertices emerging, so it is only suitable for realtime cloth tearing.
         * \param vertex the vertex to split.
         * \param splitPlane plane to split the vertex at.
         * \param newVertex the newly created vertex after the split operation has been performed.
         * \param vertices new mesh vertices list after the split operation.
         * \param removedEdges list of edge ids removed after splitting the vertex.
         * \param addedEdges list of edge ids added after splitting the vertex.
         * \param oldAndNewEdges a dictionary relating old and new edge ids.
         */
        public bool SplitVertex(HEVertex vertex, Plane splitPlane, out HEVertex newVertex, out Vector3[] vertices, out HashSet<int> removedEdges, out HashSet<int> addedEdges, out Dictionary<int,int> oldAndNewEdges)
        {
            // initialize return values:
            removedEdges = new HashSet<int>();
            addedEdges = new HashSet<int>();
            oldAndNewEdges = new Dictionary<int,int>();
            newVertex = null;

            // initialize face lists for each side of the split plane.
            List<HEFace> side1Faces = new List<HEFace>();
            List<HEFace> side2Faces = new List<HEFace>();
            HashSet<int> side2Edges = new HashSet<int>();

            // Get a copy of mesh vertices:
            vertices = input.vertices;

            // classify adjacent faces depending on which side of the cut plane they reside in:
            foreach(HEFace face in GetNeighbourFacesEnumerator(vertex)){

            int v1 = heEdges[face.edges[0]].startVertex;
            int v2 = heEdges[face.edges[1]].startVertex;
            int v3 = heEdges[face.edges[2]].startVertex;

            //Skip this face if it doesnt contain the splitted vertex.
            if (v1 != vertex.index && v2 != vertex.index && v3 != vertex.index) continue;

            Vector3 faceCenter = (vertices[heVertices[v1].physicalIDs[0]] +
                                  vertices[heVertices[v2].physicalIDs[0]] +
                                  vertices[heVertices[v3].physicalIDs[0]]) / 3.0f;

            if (splitPlane.GetSide(faceCenter)){
                side1Faces.Add(face);
            }else{
                side2Faces.Add(face);
                foreach(int e in face.edges)
                    side2Edges.Add(e);
            }
            }

            // If the vertex cant be split, return false.
            if (side1Faces.Count == 0 || side2Faces.Count == 0) return false;

            // create new mesh vertex and triangle buffers:
            vertices = new Vector3[input.vertexCount+1];
            Array.Copy(input.vertices,vertices,input.vertexCount);

            int[] triangles = input.triangles;

            // create a new vertex:
            newVertex = new HEVertex(input.vertexCount);
            newVertex.index = heVertices.Count;
            heVertices.Add(newVertex);

            // add the new vertex to the mesh vertices buffer:
            vertices[input.vertexCount] = vertices[vertex.physicalIDs[0]];

            // Copy uvs, colors and other mesh info.
            Vector2[] uv = null;
            Vector2[] uv2 = null;
            Vector2[] uv3 = null;
            Vector2[] uv4 = null;
            Color32[] colors = null;
            if (input.uv.Length > 0){
            uv = new Vector2[input.uv.Length+1];
            Array.Copy(input.uv,uv,input.uv.Length);
            uv[input.uv.Length] = uv[vertex.physicalIDs[0]]; //TODO: could cause copying uvs from the other side of the cut...
            }
            if (input.uv2.Length > 0){
            uv2 = new Vector2[input.uv2.Length+1];
            Array.Copy(input.uv2,uv2,input.uv2.Length);
            uv2[input.uv2.Length] = uv2[vertex.physicalIDs[0]];
            }
            if (input.uv3.Length > 0){
            uv3 = new Vector2[input.uv3.Length+1];
            Array.Copy(input.uv3,uv3,input.uv3.Length);
            uv3[input.uv3.Length] = uv3[vertex.physicalIDs[0]];
            }
            if (input.uv4.Length > 0){
            uv4 = new Vector2[input.uv4.Length+1];
            Array.Copy(input.uv4,uv4,input.uv4.Length);
            uv4[input.uv4.Length] = uv4[vertex.physicalIDs[0]];
            }
            if (input.colors32.Length > 0){
            colors = new Color32[input.colors32.Length+1];
            Array.Copy(input.colors32,colors,input.colors32.Length);
            colors[input.colors32.Length] = colors[vertex.physicalIDs[0]];
            }

            // rearrange edges at side 1:
            foreach(HEFace face in side1Faces){

            // find half edges that start or end at the split vertex:
            HEEdge edgeIn = heEdges[Array.Find<int>(face.edges,e => heEdges[e].endVertex == vertex.index)];
            HEEdge edgeOut = heEdges[Array.Find<int>(face.edges,e => heEdges[e].startVertex == vertex.index)];

            int oldInID = ObiUtils.Pair(edgeIn.startVertex,edgeIn.endVertex);
            int oldOutID = ObiUtils.Pair(edgeOut.startVertex,edgeOut.endVertex);

            if (ShouldRemoveEdge(edgeIn,side2Edges.Contains(edgeIn.pair)))
                removedEdges.Add(oldInID);

            if (ShouldRemoveEdge(edgeOut,side2Edges.Contains(edgeOut.pair)))
                removedEdges.Add(oldOutID);

            // stitch half edges to new vertex
            edgeIn.endVertex = newVertex.index;
            edgeOut.startVertex = newVertex.index;

            newVertex.halfEdgeIndex = edgeOut.index;

            int newInID = ObiUtils.Pair(edgeIn.startVertex,edgeIn.endVertex);
            int newOutID = ObiUtils.Pair(edgeOut.startVertex,edgeOut.endVertex);

            addedEdges.Add(newInID);
            addedEdges.Add(newOutID);

            if (!oldAndNewEdges.ContainsKey(newInID))
            oldAndNewEdges.Add(newInID,oldInID);
            if (!oldAndNewEdges.ContainsKey(newOutID))
            oldAndNewEdges.Add(newOutID,oldOutID);

            // update mesh triangle buffer to point at new vertex where needed:
            if (triangles[face.index*3] == vertex.physicalIDs[0]) triangles[face.index*3] = newVertex.physicalIDs[0];
            if (triangles[face.index*3+1] == vertex.physicalIDs[0]) triangles[face.index*3+1] = newVertex.physicalIDs[0];
            if (triangles[face.index*3+2] == vertex.physicalIDs[0]) triangles[face.index*3+2] = newVertex.physicalIDs[0];

            }

            // update input mesh:
            input.vertices = vertices;
            input.triangles = triangles;
            if (uv != null)
            input.uv = uv;
            if (uv2 != null)
            input.uv2 = uv2;
            if (uv3 != null)
            input.uv3 = uv3;
            if (uv4 != null)
            input.uv4 = uv4;
            if (colors != null)
            input.colors32 = colors;

            _closed = false;
            _modified = true;

            return true;
        }
Пример #28
0
		private void AdjustEdgeHandleColor(Vector3 handlePos, Vector3 slideDir1, Vector3 slideDir2, Matrix4x4 transform, float alphaFactor)
		{
			Vector3 inPoint = transform.MultiplyPoint(handlePos);
			Vector3 normalized = transform.MultiplyVector(slideDir1).normalized;
			Vector3 normalized2 = transform.MultiplyVector(slideDir2).normalized;
			bool flag;
			if (Camera.current.orthographic)
			{
				flag = (Vector3.Dot(-Camera.current.transform.forward, normalized) < 0f && Vector3.Dot(-Camera.current.transform.forward, normalized2) < 0f);
			}
			else
			{
				Plane plane = new Plane(normalized, inPoint);
				Plane plane2 = new Plane(normalized2, inPoint);
				flag = (!plane.GetSide(Camera.current.transform.position) && !plane2.GetSide(Camera.current.transform.position));
			}
			if (flag)
			{
				alphaFactor *= this.backfaceAlphaMultiplier;
			}
			if (alphaFactor < 1f)
			{
				Handles.color = new Color(Handles.color.r, Handles.color.g, Handles.color.b, Handles.color.a * alphaFactor);
			}
		}
    /// <summary>
    /// Finds the intersection points.
    /// </summary>
    /// <param name='index'>
    /// Index: the meshObject index in the meshObjects array
    /// </param>
    void FindIntersectionPoints(int index)
    {
        Plane plane = new Plane(transform.TransformDirection(Vector3.up), transform.position);
        List<Vector3> points = new List<Vector3>();

        MeshFilter meshObject = meshObjects[index].meshObject;

        Mesh mesh = meshObject.mesh;
        if(mesh == null) return;

        Vector3[] vertices = mesh.vertices;
        //Vector3[] normals = mesh.normals;
        int[] triangles = mesh.triangles;

        //loop through triangles to find intersections or points on the plane
        for(int j = 0; j < (mesh.triangles.Length); j += 3) {

            //retrieve the vertices of the triangle
            Vector3 vertex1 = meshObject.transform.TransformPoint(vertices[triangles[j + 0]]);
            Vector3 vertex2 = meshObject.transform.TransformPoint(vertices[triangles[j + 1]]);
            Vector3 vertex3 = meshObject.transform.TransformPoint(vertices[triangles[j + 2]]);

            //find if each vertice lies directly on the plane
            bool onPlane1 = Mathf.Approximately(plane.GetDistanceToPoint(vertex1), 0f);
            bool onPlane2 = Mathf.Approximately(plane.GetDistanceToPoint(vertex2), 0f);
            bool onPlane3 = Mathf.Approximately(plane.GetDistanceToPoint(vertex3), 0f);

            //find if each vertex is in front of or behind the plane
            bool inFront1 = plane.GetSide(vertex1);
            bool inFront2 = plane.GetSide(vertex2);
            bool inFront3 = plane.GetSide(vertex3);

            Vector3? firstPoint = null;

            //Special handling for if a point is directly on the planes surface
            #region Handle Points on Plane
            if(onPlane1) {
                if(inFront2 == inFront3) continue;
                firstPoint = vertex1;
            }

            if(onPlane2) {
                if(inFront1 == inFront3) continue;
                if(firstPoint != null) {
                    points.Add((Vector3)firstPoint);
                    points.Add(vertex2);
                    continue;
                } else firstPoint = vertex2;
            }

            if(onPlane3) {
                if(inFront1 == inFront2) continue;
                if(firstPoint != null) {
                    points.Add((Vector3)firstPoint);
                    points.Add(vertex3);
                    continue;
                } else firstPoint = vertex3;
            }
            #endregion

            float rayDistance;
            Ray ray = new Ray(vertex1, vertex2 - vertex1);

            //For points 1 and 2, if neither are on the planes surface, check if they are on opposite sides,
            //if so, find the intersection point on the plane.
            //If the first point was found earlier, add it and the intersection point to the list and continue.
            #region Find Intersections
            if(!onPlane1 && !onPlane2 && inFront1 != inFront2 && plane.Raycast(ray, out rayDistance)) {
                if(firstPoint != null) {
                    points.Add((Vector3)firstPoint);
                    points.Add(ray.GetPoint(rayDistance));
                    continue;
                } else firstPoint = ray.GetPoint(rayDistance);

            }

            ray = new Ray(vertex2, vertex3 - vertex2);

            if(!onPlane2 && !onPlane3 && (inFront2 != inFront3) && plane.Raycast(ray, out rayDistance)) {
                if(firstPoint != null) {
                    points.Add((Vector3)firstPoint);
                    points.Add(ray.GetPoint(rayDistance));
                    continue;
                } else firstPoint = ray.GetPoint(rayDistance);
            }

            if(firstPoint == null) continue;

            ray = new Ray(vertex3, vertex1 - vertex3);

            if(!onPlane3 && !onPlane1 && (inFront3 != inFront1) && plane.Raycast(ray, out rayDistance)) {
                points.Add((Vector3)firstPoint);
                points.Add(ray.GetPoint(rayDistance));
            }
            #endregion
        }

        //makes sure that all points are on the plane's surface, and removes points outside of the planes bounding box
        #region Cleanup Points
        for(int i = 0; i < points.Count; i += 2) {
            Vector3 p1 = ProjectPointOnPlane(plane.normal, transform.position, points[i]);
            Vector3 p2 = ProjectPointOnPlane(plane.normal, transform.position, points[i + 1]);

            bool containsP1 = GetComponent<Collider>().bounds.Contains(p1);
            bool containsP2 = GetComponent<Collider>().bounds.Contains(p2);

            if(!containsP1 && !containsP2) {
                points[i] = points[i + 1] = Vector3.zero;
                continue;
            }

            if(!containsP1 && containsP2) {
                Ray ray = new Ray(p1, p2 - p1);
                float distance;

                GetComponent<Collider>().bounds.IntersectRay(ray, out distance);

                Vector3 newP = ray.GetPoint(distance);
                points[i] = newP;
            }

            if(containsP1 && !containsP2) {
                Ray ray = new Ray(p2, p1 - p2);
                float distance;

                GetComponent<Collider>().bounds.IntersectRay(ray, out distance);

                Vector3 newP = ray.GetPoint(distance);
                points[i + 1] = newP;
                Debug.Log(distance.ToString());
            }

        }
        #endregion

        meshObjects[index].points = points;
    }