Esempio n. 1
0
        /// <summary>
        /// Iterates over a given face.
        /// </summary>
        /// <param name="face"></param>
        /// <param name="currentVertexSelector"></param>
        /// <param name="returnCurrent">
        /// There are always 2 possible edges to follow from each vertex. So we have to
        /// keep track from which vertex did we come to the current vertex.
        ///
        /// The returnCurrent argument determines which of the two vertices is returned.
        /// true - returns the current vertex
        /// false - returns the previous vertex
        /// </param>
        /// <returns></returns>
        private IEnumerable <Vertex <T> > IterateFace(FaceHandle <Vertex <T> > face, Func <FaceHandle <Vertex <T> >, Vertex <T> > currentVertexSelector, bool returnCurrent = true)
        {
            var previous = face.Anchor;
            var current  = currentVertexSelector(face);

            return(IterateFace(current, previous, returnCurrent));
        }
Esempio n. 2
0
        /// <summary>
        /// Iterates over both sides of the face in parallel until the root is found.
        /// </summary>
        /// <remarks>
        /// Always returns the "previous" vertex!
        ///
        /// The first returned vertex is the anchor of a given face. Both iterators are then
        /// advanced so that anchor point is not returned twice. After that, both iterators
        /// alternate in returning the current follow vertex. If any of the iterators encounter
        /// the root vertex, the whole process ends.
        /// </remarks>
        /// <param name="face"></param>
        /// <returns></returns>
        private IEnumerable <Vertex <T> > IterateBothSides(FaceHandle <Vertex <T> > face)
        {
            var firstEnumerable  = IterateFirstSide(face, false);
            var secondEnumerable = IterateSecondSide(face, false);
            var firstActive      = false;

            using (var firstEnumerator = firstEnumerable.GetEnumerator())
            {
                using (var secondEnumerator = secondEnumerable.GetEnumerator())
                {
                    if (!firstEnumerator.MoveNext() || !secondEnumerator.MoveNext())
                    {
                        yield break;
                    }

                    yield return(firstEnumerator.Current);

                    if (!firstEnumerator.MoveNext() || !secondEnumerator.MoveNext())
                    {
                        yield break;
                    }

                    while (true)
                    {
                        if (firstActive)
                        {
                            yield return(firstEnumerator.Current);

                            if (!firstEnumerator.MoveNext())
                            {
                                yield break;
                            }
                        }
                        else
                        {
                            yield return(secondEnumerator.Current);

                            if (!secondEnumerator.MoveNext())
                            {
                                yield break;
                            }
                        }

                        firstActive = !firstActive;
                    }
                }
            }
        }
Esempio n. 3
0
    public override void OnHandlerDrag(PointerEventData eventData)
    {
        SCPointEventData scPointEventData = eventData as SCPointEventData;

        if (scPointEventData == null)
        {
            return;
        }

        if (currentGrabPoint == Vector3.zero)
        {
            initialGrabPoint = currentGrabPoint = scPointEventData.Position3D;
        }
        currentGrabPoint = scPointEventData.Position3D;

        float initialDist = Vector3.Dot(initialGrabPoint - oppositeCorner, diagonalDir);
        float currentDist = Vector3.Dot(currentGrabPoint - oppositeCorner, diagonalDir);
        float scaleFactor = 1 + (currentDist - initialDist) / initialDist;

        Vector3 newScale = initialScaleOnGrabStart;// * scaleFactor;

        FaceHandle facePointHandle = currentHandle as FaceHandle;

        Vector3 axisScaleFactor = Vector3.one;

        if (facePointHandle.axis == BoundingBox.AxisType.X || facePointHandle.axis == BoundingBox.AxisType.NX)
        {
            axisScaleFactor = new Vector3(scaleFactor, 1, 1);
        }
        else if (facePointHandle.axis == BoundingBox.AxisType.Y || facePointHandle.axis == BoundingBox.AxisType.NY)
        {
            axisScaleFactor = new Vector3(1, scaleFactor, 1);
        }
        else if (facePointHandle.axis == BoundingBox.AxisType.Z || facePointHandle.axis == BoundingBox.AxisType.NZ)
        {
            axisScaleFactor = new Vector3(1, 1, scaleFactor);
        }
        newScale = Vector3.Scale(initialScaleOnGrabStart, axisScaleFactor);

        boundingBox.transform.localScale = newScale;

        float distance = Vector3.Distance(initialPositionOnGrabStart, oppositeCorner);
        float coef     = (facePointHandle.axis == BoundingBox.AxisType.X || facePointHandle.axis == BoundingBox.AxisType.Y || facePointHandle.axis == BoundingBox.AxisType.Z)
            ? -1 : 1;

        boundingBox.transform.position = initialPositionOnGrabStart + coef * (boundingBox.transform.rotation * (Vector3.one - axisScaleFactor) * distance);
    }
Esempio n. 4
0
    private void UpdateMesh()
    {
        mVertices.Clear();
        mNormals.Clear();
        mUvs.Clear();
        mIndices.Clear();
        int triangle = 0;

        for (int faceIndex = 0; faceIndex < mFaces.Count; ++faceIndex)
        {
            FaceHandle face = mFaces[faceIndex];
            if (face.vertices.Count < 3)
            {
                Debug.LogWarning("Invalid face. A face needs at least 3 vertices. The mesh will exlude this face.");
                continue;
            }
            for (int vertexIndex = 0; vertexIndex < face.vertices.Count; ++vertexIndex)
            {
                Vertex vertex = face.vertices[vertexIndex];
                mVertices.Add(vertex.position);

                Vector3 AB     = face.vertices[(vertexIndex + 1) % face.vertices.Count].position - vertex.position;
                Vector3 AC     = face.vertices[(vertexIndex + 2) % face.vertices.Count].position - vertex.position;
                Vector3 normal = Vector3.Cross(AB, AC).normalized;
                mNormals.Add(normal);
            }
            for (int triangleIndex = 0; triangleIndex < face.vertices.Count - 2; ++triangleIndex)
            {
                AddTriangle(triangle, triangle + 1 + triangleIndex, triangle + 2 + triangleIndex);
            }
            triangle += face.vertices.Count;
        }
        mMesh.Clear();
        mMesh.vertices  = mVertices.ToArray();
        mMesh.normals   = mNormals.ToArray();
        mMesh.triangles = mIndices.ToArray();
        mMesh.RecalculateBounds();
        MeshFilter meshFilter = GetComponent <MeshFilter>();

        if (meshFilter != null)
        {
            meshFilter.mesh = mMesh;
        }
    }
Esempio n. 5
0
    private void Update()
    {
        ResetMesh();

        for (int ruleSetIndex = 0; ruleSetIndex < mRuleSets.Count; ++ruleSetIndex)
        {
            List <FaceHandle> facesToEdit = new List <FaceHandle>();
            for (int faceIndex = 0; faceIndex < mFaces.Count; ++faceIndex)
            {
                if (mFaces[faceIndex].name == mRuleSets[ruleSetIndex].mName)
                {
                    facesToEdit.Add(mFaces[faceIndex]);
                }
            }
            for (int faceIndex = 0; faceIndex < facesToEdit.Count; ++faceIndex)
            {
                FaceHandle currentFaceHandle = facesToEdit[faceIndex];
                for (int ruleIndex = 0; ruleIndex < mRuleSets[ruleSetIndex].mRules.Count; ++ruleIndex)
                {
                    ProceduralMeshRule rule = mRuleSets[ruleSetIndex].mRules[ruleIndex];
                    if (SparkUtilities.Cast <ProceduralMeshRuleExtrude>(rule) != null)
                    {
                        ProceduralMeshRuleExtrude extrudeRule = SparkUtilities.Cast <ProceduralMeshRuleExtrude>(rule);
                        float             length   = extrudeRule.mLength;
                        List <FaceHandle> newFaces = ExtrudeFace(currentFaceHandle, length);
                        for (int newFaceIndex = 0; newFaceIndex < newFaces.Count; ++newFaceIndex)
                        {
                            //newFaces[newFaceIndex].name = extrudeRule.mNewFaceNames;
                        }
                        currentFaceHandle = mFaces.Last();
                    }
                    else if (SparkUtilities.Cast <ProceduralMeshRuleScale>(rule) != null)
                    {
                        ProceduralMeshRuleScale scaleRule = SparkUtilities.Cast <ProceduralMeshRuleScale>(rule);
                        Vector2 scale = scaleRule.mScale;
                        ScaleFace(currentFaceHandle, scale);
                    }
                }
            }
        }

        UpdateMesh();
    }
Esempio n. 6
0
    public void ScaleFace(FaceHandle aFace, Vector2 aScale)
    {
        if (aFace.vertices.Count < 3)
        {
            Debug.LogWarning("Invalid face. A face needs at least 3 vertices. The face scaling will be skipped.");
            return;
        }

        Vector3 center = Vector3.zero;

        for (int vertexIndex = 0; vertexIndex < aFace.vertices.Count; ++vertexIndex)
        {
            center += aFace.vertices[vertexIndex].position;
        }
        center /= aFace.vertices.Count;
        for (int vertexIndex = 0; vertexIndex < aFace.vertices.Count; ++vertexIndex)
        {
            Vector3 original = aFace.vertices[vertexIndex].position;
            aFace.vertices[vertexIndex].position = center * (1.0f - aScale.x) + original * aScale.x;
        }
    }
Esempio n. 7
0
    public List <FaceHandle> ExtrudeFace(FaceHandle aFace, float aLength)
    {
        List <FaceHandle> newFaces = new List <FaceHandle>();

        if (aFace.vertices.Count < 3)
        {
            Debug.LogWarning("Invalid face. A face needs at least 3 vertices. The face extrusion will be skipped.");
            return(newFaces);
        }
        Vector3 averageNormal = Vector3.zero;

        for (int triangleIndex = 0; triangleIndex < aFace.vertices.Count - 2; ++triangleIndex)
        {
            Vector3 AB     = aFace.vertices[(triangleIndex + 1) % aFace.vertices.Count].position - aFace.vertices[triangleIndex].position;
            Vector3 AC     = aFace.vertices[(triangleIndex + 2) % aFace.vertices.Count].position - aFace.vertices[triangleIndex].position;
            Vector3 normal = Vector3.Cross(AB, AC).normalized;
            averageNormal += normal;
        }
        averageNormal.Normalize();

        Vertex[] tempVertices = new Vertex[aFace.vertices.Count];
        for (int vertexIndex = 0; vertexIndex < aFace.vertices.Count; ++vertexIndex)
        {
            tempVertices[vertexIndex] = new Vertex {
                position = aFace.vertices[vertexIndex].position + averageNormal * aLength, normal = Vector3.up, uv = Vector2.up
            };
        }
        for (int faceIndex = 0; faceIndex < aFace.vertices.Count; ++faceIndex)
        {
            int numVertices = aFace.vertices.Count;
            int i0          = faceIndex;
            int i1          = (faceIndex + 1) % numVertices;
            mFaces.Add(new FaceHandle(aFace.vertices[i0], aFace.vertices[i1], tempVertices[i1], tempVertices[i0]));
            newFaces.Add(mFaces.Last());
        }
        mFaces.Add(new FaceHandle(tempVertices));
        mFaces.Remove(aFace);
        return(newFaces);
    }
Esempio n. 8
0
 /// <summary>
 /// Starts with the "second" vertex of a given face handle.
 /// Stops after a root is find.
 /// </summary>
 /// <param name="face"></param>
 /// <param name="returnCurrent">
 /// There are always 2 possible edges to follow from each vertex. So we have to
 /// keep track from which vertex did we come to the current vertex.
 ///
 /// The returnCurrent argument determines which of the two vertices is returned.
 /// true - returns the current vertex
 /// false - returns the previous vertex
 /// </param>
 /// <returns></returns>
 private IEnumerable <Vertex <T> > IterateSecondSide(FaceHandle <Vertex <T> > face, bool returnCurrent = true)
 {
     return(IterateFace(face, x => x.SecondVertex, returnCurrent));
 }
Esempio n. 9
0
    private void ReCreateVisual()
    {
        if (boundingBox.CornerBoundingBoxRoot == null)
        {
            return;
        }

        handles = new FaceHandle[FACE_NUM];
        for (int i = 0; i < FACE_NUM; i++)
        {
            handles[i] = new FaceHandle();
        }

        CornerBoundingBoxRoot cornerBoundingBoxRoot = boundingBox.CornerBoundingBoxRoot;

        handles[0].localPosition = (cornerBoundingBoxRoot.handles[0].localPosition + cornerBoundingBoxRoot.handles[3].localPosition) * 0.5f;
        handles[1].localPosition = (cornerBoundingBoxRoot.handles[3].localPosition + cornerBoundingBoxRoot.handles[6].localPosition) * 0.5f;
        handles[2].localPosition = (cornerBoundingBoxRoot.handles[5].localPosition + cornerBoundingBoxRoot.handles[6].localPosition) * 0.5f;
        handles[3].localPosition = (cornerBoundingBoxRoot.handles[0].localPosition + cornerBoundingBoxRoot.handles[5].localPosition) * 0.5f;
        handles[4].localPosition = (cornerBoundingBoxRoot.handles[0].localPosition + cornerBoundingBoxRoot.handles[6].localPosition) * 0.5f;
        handles[5].localPosition = (cornerBoundingBoxRoot.handles[1].localPosition + cornerBoundingBoxRoot.handles[7].localPosition) * 0.5f;

        handles[0].axis = BoundingBox.AxisType.NZ;
        handles[1].axis = BoundingBox.AxisType.Y;
        handles[2].axis = BoundingBox.AxisType.Z;
        handles[3].axis = BoundingBox.AxisType.NY;
        handles[4].axis = BoundingBox.AxisType.NX;
        handles[5].axis = BoundingBox.AxisType.X;

        for (int i = 0; i < FACE_NUM; i++)
        {
            string rootName = "FacePointRoot_" + i.ToString();

            Transform existRoot = boundingBox.BoundingBoxContainer.Find(rootName);
            if (existRoot != null)
            {
                GameObject.Destroy(existRoot.gameObject);
            }

            handles[i].root = new GameObject("FacePointRoot_" + i).transform;
            handles[i].root.transform.parent        = boundingBox.BoundingBoxContainer;
            handles[i].root.transform.localPosition = handles[i].localPosition;
            handles[i].root.transform.localRotation = Quaternion.identity;

            handles[i].visual = boundingBox.facePrefab == null?GameObject.CreatePrimitive(PrimitiveType.Cube) : GameObject.Instantiate(boundingBox.facePrefab);

            handles[i].visual.name = "visuals";

            if (handles[i].visual.GetComponent <Collider>())
            {
                GameObject.Destroy(handles[i].visual.GetComponent <Collider>());
            }

            handles[i].bounds = BoundingBoxUtils.GetMaxBounds(handles[i].visual);
            float maxDim   = Mathf.Max(Mathf.Max(handles[i].bounds.size.x, handles[i].bounds.size.y), handles[i].bounds.size.z);
            float invScale = boundingBox.AxisScaleHandleSize / maxDim;

            handles[i].visual.transform.parent        = handles[i].root.transform;
            handles[i].visual.transform.localScale    = new Vector3(invScale, invScale, invScale);
            handles[i].visual.transform.localPosition = Vector3.zero;
            handles[i].visual.transform.localRotation = Quaternion.identity;

            Bounds bounds = new Bounds(handles[i].bounds.center * invScale, handles[i].bounds.size * invScale);

            BoxCollider collider = handles[i].root.gameObject.AddComponent <BoxCollider>();
            collider.size   = bounds.size;
            collider.center = bounds.center;

            handles[i].root.gameObject.AddComponent <NearInterationGrabbable>();

            var cursorBehavoir = handles[i].root.gameObject.AddComponent <CursorBehavoir>();
            cursorBehavoir.positionBehavoir = CursorBehavoir.PositionBehavoir.AnchorPosition3D;
            cursorBehavoir.visualBehavoir   = CursorBehavoir.VisualBehavoir.Scale;
        }
    }