Beispiel #1
0
        /**
         * Returns the first normal, tangent, and bitangent for this face, using the first triangle available for tangent and bitangent.
         * Does not rely on mesh.msh for normal or uv information - uses mesh.vertices & mesh.uv.
         */
        public static void NormalTangentBitangent(Vector3[] vertices, Vector2[] uv, qe_Triangle tri, out Vector3 normal, out Vector3 tangent, out Vector3 bitangent)
        {
            normal = qe_Math.Normal(vertices[tri.x], vertices[tri.y], vertices[tri.z]);

            Vector3 tan1 = Vector3.zero;
            Vector3 tan2 = Vector3.zero;
            Vector4 tan  = new Vector4(0f, 0f, 0f, 1f);

            long i1 = tri.x;
            long i2 = tri.y;
            long i3 = tri.z;

            Vector3 v1 = vertices[i1];
            Vector3 v2 = vertices[i2];
            Vector3 v3 = vertices[i3];

            Vector2 w1 = uv[i1];
            Vector2 w2 = uv[i2];
            Vector2 w3 = uv[i3];

            float x1 = v2.x - v1.x;
            float x2 = v3.x - v1.x;
            float y1 = v2.y - v1.y;
            float y2 = v3.y - v1.y;
            float z1 = v2.z - v1.z;
            float z2 = v3.z - v1.z;

            float s1 = w2.x - w1.x;
            float s2 = w3.x - w1.x;
            float t1 = w2.y - w1.y;
            float t2 = w3.y - w1.y;

            float r = 1.0f / (s1 * t2 - s2 * t1);

            Vector3 sdir = new Vector3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r);
            Vector3 tdir = new Vector3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r);

            tan1 += sdir;
            tan2 += tdir;

            Vector3 n = normal;

            Vector3.OrthoNormalize(ref n, ref tan1);

            tan.x = tan1.x;
            tan.y = tan1.y;
            tan.z = tan1.z;

            tan.w = (Vector3.Dot(Vector3.Cross(n, tan1), tan2) < 0.0f) ? -1.0f : 1.0f;

            tangent   = ((Vector3)tan) * tan.w;
            bitangent = Vector3.Cross(normal, tangent);
        }
Beispiel #2
0
        /**
         * Get an array of qe_Triangle from this mesh.
         */
        public qe_Triangle[] GetFaces()
        {
            int[] tris = cloneMesh.triangles;

            qe_Triangle[] t     = new qe_Triangle[tris.Length / 3];
            int           index = 0;

            for (int i = 0; i < tris.Length; i += 3)
            {
                t[index++] = new qe_Triangle(tris[i], tris[i + 1], tris[i + 2]);
            }

            return(t);
        }
Beispiel #3
0
        void OnMouseUp(Event e)
        {
            if (!e.shift)
            {
                Undo.RecordObject(selection, "Clear Selection");
                selection.Clear();
            }

            switch (elementMode)
            {
            case ElementMode.Vertex:
            {
                int index = -1;

                if (qe_Editor_Utility.VertexRaycast(e.mousePosition, CLICK_RECT, selection, out index))
                {
                    List <int> sel     = selection.userIndices;
                    int        indexOf = sel.IndexOf(index);

                    if (indexOf < 0)
                    {
                        sel.Add(index);
                    }
                    else
                    {
                        sel.RemoveAt(indexOf);
                    }

                    selection.SetIndices(sel);

                    break;
                }
                else
                {
                    goto default;
                }
            }

            case ElementMode.Edge:
            {
                qe_Edge edge;

                if (qe_Editor_Utility.EdgeRaycast(e.mousePosition, selection, out edge))
                {
                    List <qe_Edge> sel   = selection.edges.Distinct().ToList();
                    int            index = sel.IndexOf(edge);

                    if (index > -1)
                    {
                        sel.RemoveAt(index);
                    }
                    else
                    {
                        sel.Add(edge);
                    }

                    selection.SetEdges(sel);
                }
                else
                {
                    goto case ElementMode.Face;
                }

                break;
            }

            case ElementMode.Face:
            default:
            {
                qe_RaycastHit hit;

                if (qe_Editor_Utility.MeshRaycast(HandleUtility.GUIPointToWorldRay(e.mousePosition), selection.mesh, out hit))
                {
                    List <qe_Triangle> sel = selection.faces;
                    qe_Triangle        tri = selection.mesh.faces[hit.FaceIndex];

                    int index = sel.IndexOf(tri);

                    if (index > -1)
                    {
                        sel.RemoveAt(index);
                    }
                    else
                    {
                        sel.Add(tri);
                    }

                    selection.SetFaces(sel);
                }

                break;
            }
            }

            ResetHandles();
            CacheIndicesForGraphics();
            UpdateGraphics();
        }
Beispiel #4
0
        void UpdateElementHover(Vector2 mousePosition)
        {
            hovering.mode = elementMode;
            int  hash     = hovering.hashCode;
            bool wasValid = hovering.valid;

            hovering.valid = false;

            switch (elementMode)
            {
            case ElementMode.Vertex:
            {
                int tri = -1;

                if (qe_Editor_Utility.VertexRaycast(mousePosition, CLICK_RECT, selection, out tri))
                {
                    hovering.valid       = true;
                    hovering.hashCode    = tri.GetHashCode();
                    hovering.vertices[0] = selection.verticesInWorldSpace[tri];
                }
            }
            break;

            case ElementMode.Face:
            {
                qe_RaycastHit hit;

                if (qe_Editor_Utility.MeshRaycast(HandleUtility.GUIPointToWorldRay(mousePosition), selection.mesh, out hit))
                {
                    qe_Triangle face = selection.mesh.faces[hit.FaceIndex];
                    hovering.valid = true;

                    if (hash != face.GetHashCode())
                    {
                        hovering.hashCode = face.GetHashCode();

                        hovering.vertices[0] = selection.verticesInWorldSpace[face.x];
                        hovering.vertices[1] = selection.verticesInWorldSpace[face.y];
                        hovering.vertices[2] = selection.verticesInWorldSpace[face.z];
                                                        #if !UNITY_5
                        hovering.vertices[3] = selection.verticesInWorldSpace[face.z];
                                                        #endif
                    }
                }
            }
            break;

            case ElementMode.Edge:
            {
                qe_Edge edge;

                if (qe_Editor_Utility.EdgeRaycast(mousePosition, selection, out edge))
                {
                    hovering.valid = true;

                    if (hash != edge.GetHashCode())
                    {
                        hovering.hashCode = edge.GetHashCode();

                        hovering.vertices[0] = selection.verticesInWorldSpace[edge.x];
                        hovering.vertices[1] = selection.verticesInWorldSpace[edge.y];
                    }
                }
            }
            break;
            }

            if (hash != hovering.hashCode || hovering.valid != wasValid)
            {
                SceneView.RepaintAll();
            }
        }
Beispiel #5
0
 public static Vector3 Normal(this qe_Mesh mesh, qe_Triangle tri)
 {
     return(Normal(mesh.vertices[tri.x], mesh.vertices[tri.y], mesh.vertices[tri.z]));
 }