예제 #1
0
    /// <summary>
    /// Step the machine.
    /// Set machine speed to zero and use this method for interactive use.
    /// It's framerate independent.
    /// </summary>
    /// <param name='speed'>
    /// Speed in degrees per second.
    /// </param>
    public void Step(float speed)
    {
        step += Time.deltaTime * speed * (Reverse ? -1.0f : 1.0f);
        //FIXME: individual gear rotated > 360 reset at 0: not through step: if powered gear is smaller than other gear in same machine: larger gear gets out of sync as it has not completed its turn yet.
        PoweredGear.SetRotation(step);
        PoweredGear._currentSpeed = speed;

        // Avoiding recursion through use of a queue instead of the internal stack which is slow and limited.
        //gearUpdateQueue.Clear();
        gearUpdateQueue.Enqueue(PoweredGear);
        while (gearUpdateQueue.Count > 0)
        {
            GFGear parent = gearUpdateQueue.Dequeue();
            if (parent != null)
            {
                for (int i = 0; i < parent.childrenAsArray.Length; i++)
                {
                    GFGear child = parent.childrenAsArray[i];
                    child._currentSpeed = parent.currentSpeed * child.speedMultiplier;
                    child.SetRotation(parent.angle * child.speedMultiplier);
                    gearUpdateQueue.Enqueue(child);
                }
            }
        }
    }
예제 #2
0
    private void CloneTowardsMousePos(GFGear gear, Vector2 mousePos)
    {
        Vector3 mousewpos = GetMouseInWorldCoords(MeshUtils.CalcYAlignedCenterPlane(gear.gameObject), mousePos);
        Vector3 direction = mousewpos - gear.gameObject.transform.position;

        direction.Normalize();

        CloneGear(gear, direction);
    }
예제 #3
0
    private void CloneGear(GFGear gear, Vector3 direction)
    {
        GameObject newGearGO = gear.Clone(direction);

        // Mark new gear as dirty
        UnityEditor.EditorUtility.SetDirty(newGearGO);
        // Set focus on new gear
        Selection.activeGameObject = newGearGO;
    }
예제 #4
0
    void OnEnable()
    {
        gearGenObject         = (GFGearGen)this.target;
        lastGearGenObjectMesh = gearGenObject.gameObject.GetComponent <MeshFilter>().sharedMesh;

        gearGen      = new SerializedObject(this.target);
        gearGenProps = new Dictionary <string, SerializedProperty>();
        AddGearGenProperty("numberOfTeeth");
        AddGearGenProperty("radius");
        AddGearGenProperty("innerRadius");
        AddGearGenProperty("innerMinVertexDistance");
        AddGearGenProperty("thickness");
        AddGearGenProperty("fillCenter");
        AddGearGenProperty("fillOutside");
        AddGearGenProperty("is3d");
        AddGearGenProperty("alignTeethWithParent");
        AddGearGenProperty("alignRadiusWithParent");
        AddGearGenProperty("twistAngle");
        AddGearGenProperty("twistOutside");
        AddGearGenProperty("innerTeeth");
        AddGearGenProperty("tipLength");
        AddGearGenProperty("tipSize");
        AddGearGenProperty("valleySize");
        AddGearGenProperty("valleyAngleOffset");
        AddGearGenProperty("tipAngleOffset");
        AddGearGenProperty("skew");
        AddGearGenProperty("showNormals");
        AddGearGenProperty("splitVerticesAngle");

        AddGearGenProperty("generateTextureCoordinates");
        AddGearGenProperty("uvTiling");
        AddGearGenProperty("uvOffset");

        GFGear c = (GFGear)gearGenObject.gameObject.GetComponent(typeof(GFGear));

        if (c != null)
        {
            gear      = new SerializedObject(c);
            gearProps = new Dictionary <string, SerializedProperty>();
            AddGearProperty("numberOfTeeth");
        }
        else
        {
            gear = null;
        }

        //		innerTeethInitialState = gearGenObject.innerTeeth;
        //Persist();

        Undo.undoRedoPerformed = UndoCallback;
    }
예제 #5
0
    /// <summary>
    /// Gets the gears driven by currentGear.
    /// </summary>
    /// <returns>
    /// The gears.
    /// </returns>
    /// <param name='currentGear'>
    /// Current gear.
    /// </param>
    public GFGear[] GetGears(GFGear currentGear)
    {
        List <GFGear> go = new List <GFGear>();

        for (int i = 0; i < this.transform.childCount; i++)
        {
            GFGear foundGear = this.transform.GetChild(i).gameObject.GetComponent <GFGear>();
            if (foundGear != null && (currentGear == null || !foundGear.gameObject.Equals(currentGear.gameObject)))
            {
                go.Add(foundGear);
            }
        }
        return(go.ToArray());
    }
예제 #6
0
    void AddGears()
    {
        if (numberOfInstances < 1)
        {
            numberOfInstances = 1;
        }

        if (numberOfInstances > 1)
        {
            GFGear gear = null;

            int     seqLen = 0;
            int     repeat = 0;
            int     n      = 0;
            Vector3 dir;
            for (int i = 0; i < numberOfInstances - 1; i += seqLen)
            {
                if (repeat == 1)
                {
                    repeat = 0;
                    seqLen++;
                }
                else
                {
                    repeat++;
                }

                for (int g = 0; g < seqLen; g++)
                {
                    if (instances.Count == numberOfInstances - 1)
                    {
                        i = 0;
                        break;
                    }
                    gear = instances.Count > 0 ? instances[instances.Count - 1] : gearToTest;

                    dir = Quaternion.AngleAxis(90f * n, Vector3.back) * Vector3.right;
                    GFGear newGear = gear.Clone(dir).GetComponent <GFGear>();
                    instances.Add(newGear);
                }
                n++;
                if (n >= 4)
                {
                    n = 0;
                }
            }

            machine.RecalculateGears();
        }
    }
예제 #7
0
파일: GFGear.cs 프로젝트: zhiqich/EECS494
    /// <summary>
    /// Clone a gear and place the duplicate version aligned.
    /// </summary>
    /// <param name="direction">Direction at which to align it to</param>
    /// <returns>The cloned gear as gameobject</returns>
    public GameObject Clone(Vector3 direction)
    {
        GFGear    gear    = this;
        GFGearGen gearGen = (GFGearGen)this.gameObject.GetComponent(typeof(GFGearGen));
        float     d;

        if (gearGen != null)
        {
            d = gearGen.radius + (gearGen.radius - gearGen.tipLength);
        }
        else
        {
            d = (gear.GetRadius() * 2.1f) - gear.toothSize;
        }

        GameObject newGearGO = (GameObject)Instantiate(gear.gameObject);

        newGearGO.transform.parent = gear.gameObject.transform.parent;
        GFGear newGear = newGearGO.GetComponent(typeof(GFGear)) as GFGear;

        newGear.DrivenBy        = gear;
        newGear.AutoSetDrivenBy = false;

        GFGearGen newGearGen = newGear.GetComponent <GFGearGen>();

        if (newGearGen != null)
        {
            newGearGen.alignTeethWithParent  = true;
            newGearGen.alignRadiusWithParent = true;
        }

        newGearGO.transform.position = gear.transform.position + (direction.normalized * d);

        // Get number that is not followed by any other number
        string re   = @"(\d+)(?!.*\d)";
        Match  m    = Regex.Match(gear.gameObject.name, re);
        int    nmbr = 1;

        // Add one to the last number (if exists)
        if (m != null && m.Value != null && m.Value != "" && gear.DrivenBy != null)
        {
            nmbr = int.Parse(m.Value) + 1;
        }
        // Rename object to sequentially numbered object
        newGearGO.name = Regex.Replace(gear.gameObject.name, re, "").Trim() + " " + nmbr.ToString();

        newGearGen.Align(gearGen);

        return(newGearGO);
    }
예제 #8
0
    /// <summary>
    /// Rotates g1 and g2 with point of collission of front facing center planes as pivot point.
    /// Calculates scalar products to determine if normals are in opposite direction of eachother and returns false if that's the case.
    /// </summary>
    /// <param name='g1'>
    /// Gear 1
    /// </param>
    /// <param name='g2'>
    /// Gear 2
    /// </param>
    /// <returns>True if normals align after rotation around point of collision of planes.</returns>
    private bool Opposing(GFGear g1, GFGear g2)
    {
        if (AutoReverseOnReversedOrientation)
        {
            Vector3 c1 = g1.transform.position;
            Vector3 c2 = g2.transform.position;


            // Calculate planes through center
            Plane p1 = g1.gameObject.CalcYAlignedCenterPlane(Space.World);
            Plane p2 = g2.gameObject.CalcYAlignedCenterPlane(Space.World);

            // Calculate g1.center --> point of nearest collision of the two planes (c1) --> g2.center
            //Vector3 point = Vector3.zero;
            //Vector3 direction = Vector3.zero;
            //MathUtils.PlanePlaneIntersection(out point, out direction, p1, p2, c1, c2);

            // If parallel planes ? skip pivot rotation
//			if (direction != Vector3.zero)
//			{
            // Calculate triangle: Center (c1) -> Center translated by normal -> Plane intersection point (point)
            Plane t1 = new Plane(c1, c1 + p1.normal, c2);
            // Calculate triangle: Center (c2) -> Center translated by normal -> Plane intersection point (point)
            Plane t2 = new Plane(c2, c2 + p2.normal, c1);

            /*
             * Debug.DrawLine(c1, c1+p1.normal, Color.green, 3, false);
             * Debug.DrawLine(c1+p1.normal, c2, Color.green, 3, false);
             * Debug.DrawLine(c2, c1, Color.green, 3, false);
             * Debug.DrawLine(c1, c1+t1.normal, Color.blue, 3, false);
             *
             * Debug.DrawLine(c2, c2+p2.normal, Color.magenta, 3, false);
             * Debug.DrawLine(c2+p2.normal, c1, Color.magenta, 3, false);
             * Debug.DrawLine(c1, c2, Color.magenta, 3, false);
             * Debug.DrawLine(c2, c2+t2.normal, Color.cyan, 3, false);
             */
            // Calculate normals of those triangles: directions must be opposite
            return(t1.normal == t2.normal);

            /*
             * }
             * else
             * {
             *      // Parallel planes but facing the same sides: return true
             *      return p1.normal == p2.normal;
             * }*/
        }

        return(false);
    }
예제 #9
0
 // Update is called once per frame
 void Update()
 {
     if (Input.GetMouseButtonDown(0))
     {
         Ray        ray = Camera.main.ScreenPointToRay(Input.mousePosition);
         RaycastHit hit;
         if (Physics.Raycast(ray, out hit))
         {
             GFGear gear = hit.transform.GetComponent <GFGear>();
             if (gear != null)
             {
                 gear.SetSpeed(gearSpeed);
             }
         }
     }
 }
예제 #10
0
    static public void DrawAlignmentHelpers(this GFGear gear1)
    {
        if (gear1.AutoAlign)
        {
#if UNITY_EDITOR
            Color c = Color.green;
            c.a           = 0.2f;
            Handles.color = c;
            Handles.DrawSolidDisc(gear1.transform.position, gear1.gameObject.CalcYAlignedCenterPlane().normal, gear1.radius - (gear1.innerTeeth ? 0f : gear1.tipLength));
            c.a           = 1f;
            Handles.color = c;
            Vector3 startP = Vector3.zero;
            Vector3 endP   = Vector3.zero;
            for (int i = 0; i < gear1.numberOfTeeth; i++)
            {
                float angleRad = ((2 * Mathf.PI) / gear1.numberOfTeeth) * i;
                endP.x = Mathf.Cos(angleRad);
                endP.y = Mathf.Sin(angleRad);
                endP.z = 0f;

                startP = endP * (gear1.radius - gear1.tipLength);
                endP   = endP * gear1.radius;

                startP = gear1.transform.TransformPoint(startP);
                endP   = gear1.transform.TransformPoint(endP);

                Handles.DrawAAPolyLine(10f, new Vector3[] { startP, endP });
            }

            /*
             * Quaternion q = new Quaternion();
             * Vector3 v = gear1.DrivenBy.transform.position - gear1.transform.position;
             * if (v != Vector3.zero)
             * {
             *  q = Quaternion.LookRotation(v);
             *  Handles.DrawLine(gear1.transform.position, gear1.DrivenBy.transform.position);
             *  Vector3 conePos = gear1.transform.position + ((gear1.DrivenBy.transform.position - gear1.transform.position) / 2.0f);
             *  Handles.ConeCap(0, conePos, q, HandleUtility.GetHandleSize(conePos) / 4.0f);
             * }
             */
#endif
        }
    }
예제 #11
0
 static public void DrawPoweredBy(this GFGear gear1)
 {
     if (gear1.DrivenBy != null)
     {
                     #if UNITY_EDITOR
         Handles.color = Color.yellow;
         Quaternion q = new Quaternion();
         Vector3    v = gear1.DrivenBy.transform.position - gear1.transform.position;
         if (v != Vector3.zero)
         {
             q = Quaternion.LookRotation(v);
             Handles.DrawLine(gear1.transform.position, gear1.DrivenBy.transform.position);
             Vector3 conePos = gear1.transform.position + ((gear1.DrivenBy.transform.position - gear1.transform.position) / 2.0f);
             Handles.ConeHandleCap(0, conePos, q, HandleUtility.GetHandleSize(conePos) / 4.0f, EventType.Repaint);
         }
                     #else
         Debug.DrawLine(gear1.transform.position, gear1.DrivenBy.transform.position, Color.yellow, 3, false);
                     #endif
     }
 }
예제 #12
0
    static void Create()
    {
        GameObject gameObject = new GameObject("Gear");
        GFGear     g          = (GFGear)gameObject.AddComponent(typeof(GFGear));
        GFGearGen  gg         = (GFGearGen)gameObject.AddComponent(typeof(GFGearGen));
        MeshFilter meshFilter = (MeshFilter)gameObject.GetComponent(typeof(MeshFilter));

        meshFilter.mesh = new Mesh();

        gg.Rebuild();

        gameObject.GetComponent <Renderer>().material = new Material(Shader.Find("Diffuse"));

        if (g.DrivenBy == null)
        {
            gg.alignTeethWithParent  = false;
            gg.alignRadiusWithParent = false;
        }

        GFGearGenEditor.Persist(gg);
    }
예제 #13
0
    /// <summary>
    /// Inverse the parent hierarchy to become children of the powered gear.
    /// </summary>
    private void RebuildHierarchy()
    {
        if (PoweredGear != null)
        {
            List <GFGear> gearsToInverse = new List <GFGear>();
            GFGear        parentToInv    = PoweredGear;
            while (parentToInv != null && !gearsToInverse.Contains(parentToInv))
            {
                gearsToInverse.Add(parentToInv);
                parentToInv = parentToInv.DrivenBy;
            }

            for (int i = gearsToInverse.Count - 1; i > 0; i--)
            {
                gearsToInverse[i].AutoSetDrivenBy = false;
                gearsToInverse[i].DrivenBy        = gearsToInverse[i - 1];
            }

            PoweredGear.AutoSetDrivenBy = false;
            PoweredGear.DrivenBy        = null;
        }
    }
예제 #14
0
    void OnEnable()
    {
        gearObject = (GFGear)this.target;

        gear = new SerializedObject(this.target);
        gearNumberOfTeeth = gear.FindProperty("numberOfTeeth");
        gearRotateX       = gear.FindProperty("rotateX");
        gearRotateY       = gear.FindProperty("rotateY");
        gearRotateZ       = gear.FindProperty("rotateZ");
        gearAutoAlign     = gear.FindProperty("AutoAlign");
        gearRadius        = gear.FindProperty("radius");
        gearTipLength     = gear.FindProperty("tipLength");
        gearInnerTeeth    = gear.FindProperty("innerTeeth");

        gearDrivenBy                   = gear.FindProperty("DrivenBy");
        gearAutoSetDrivenBy            = gear.FindProperty("AutoSetDrivenBy");
        gearReverseRotation            = gear.FindProperty("ReverseRotation");
        gearReverseRotationPlusSubtree = gear.FindProperty("ReverseRotationPlusSubtree");
        gearSyncSpeed                  = gear.FindProperty("SyncSpeed");

        GFGearGen c = (GFGearGen)gearObject.gameObject.GetComponent(typeof(GFGearGen));

        hasGFGearGen = c != null;
    }
예제 #15
0
 /// <summary>
 /// Set machine speed to match a gear speed.
 /// </summary>
 /// <param name="gear">Adapt speed to this gear.</param>
 /// <param name="gearSpeed">Desired new speed of the given gear in degrees per second.</param>
 public void SetSpeedByGear(GFGear gear, float gearSpeed)
 {
     speed = gearSpeed / gear.machineRatio;
 }
예제 #16
0
    private void RebuildTurnDirections(GFGear poweredBy, bool ccw, float speedMultiplier, float globalMultiplier = 1f)
    {
        if (!history.Contains(poweredBy))
        {
            history.Add(poweredBy);
            poweredBy.CCW             = ccw;
            poweredBy.speedMultiplier = speedMultiplier;
            poweredBy._machineRatio   = globalMultiplier;

            //if (poweredBy == null)
            //    poweredBy._machineRatio = 1f;

            foreach (GFGear g in gears)
            {
                // Iterate through gears and clean up empty children
                int i = 0;
                while (i < g.children.Count)
                {
                    if (g.children[i] == null)
                    {
                        g.children.RemoveAt(i);
                    }
                    else
                    {
                        i++;
                    }
                }

                // Find our gear in the gears collection
                if (g.DrivenBy == poweredBy)
                {
                    bool newccw = ccw;

                    if (!poweredBy.children.Contains(g))
                    {
                        poweredBy.children.Add(g);
                    }

                    // If g is to the left of the gear: turn the otherside around so we don't have to flip it manually
                    // we construct a plane through the center of the gear and determine if the center position of the other gear is on the backside of it
                    if (Opposing(g, poweredBy) || (poweredBy.gearGen != null && poweredBy.gearGen.innerTeeth) || (g.gearGen != null && g.gearGen.innerTeeth))
                    {
                        newccw = !ccw;
                    }

                    //calculate new speedMultiplier: compare g with poweredBy number of teeth (much more accurate then radius):
                    if (!g.SyncSpeed)
                    {
                        speedMultiplier = GetGearRatio(poweredBy, g);
                        //_machineRatio = poweredBy._machineRatio * g.speedMultiplier;
                    }
                    else
                    {
                        speedMultiplier = 1.0f;
                    }

                    if (poweredBy.ReverseRotationPlusSubtree)
                    {
                        g.ReverseRotation = true;
                        newccw            = !newccw;
                                                #if UNITY_EDITOR
                        // Tell the unity editor we changed something by code, so it gets saved.
                        UnityEditor.EditorUtility.SetDirty(g);
                                                #endif
                    }

                    RebuildTurnDirections(g, !newccw, speedMultiplier, globalMultiplier * speedMultiplier);

                    if (g.ReverseRotation && !g.ReverseRotationPlusSubtree)
                    {
                        g.CCW = !g.CCW;
                    }
                }
            }
        }

        /*
         * gearUpdateQueue.Clear();
         *
         * poweredBy.CCW = ccw;
         * poweredBy.speedMultiplier = speedMultiplier;
         * gearUpdateQueue.Enqueue(poweredBy);
         * history.Clear();
         * while (gearUpdateQueue.Count > 0)
         * {
         *      GFGear parent = gearUpdateQueue.Dequeue();
         *      if (parent != null){
         *              if (!history.Contains(parent))
         *              {
         *                      history.Add(parent);
         *
         *                      foreach(GFGear g in gears)
         *                      {
         *                              if (g.DrivenBy == parent)
         *                              {
         *                                      bool newccw = ccw;
         *
         *                                      if (!parent.Children.Contains(g))
         *                                              parent.Children.Add(g);
         *
         *                                      // If g is to the left of the gear: turn the otherside around so we don't have to flip it manually
         *                                      // we construct a plane through the center of the gear and determine if the center position of the other gear is on the backside of it
         *                                      if (Opposing(g, parent))
         *                                              newccw = !ccw;
         *
         *                                      //calculate new speedMultiplier: compare g with poweredBy number of teeth (much more accurate then radius):
         *                                      if (!g.SyncSpeed)
         *                                      {
         *                                        speedMultiplier = GetGearRatio(parent, g);
         *                                      }
         *
         *                                      if (g.ReverseRotationPlusSubtree)
         *                                      {
         *                                              newccw = !newccw;
         *                                              if (!g.ReverseRotation)
         *                                              {
         *                                                      g.ReverseRotation = true;
         *                                                      // Tell the unity editor we changed something by code, so it gets saved.
         *                                                      UnityEditor.EditorUtility.SetDirty(g);
         *                                              }
         *                                      }
         *
         * //							RebuildTurnDirections(g, !newccw, speedMultiplier);
         *                                      g.CCW = !newccw;
         *                                      g.speedMultiplier = speedMultiplier;
         *
         *                                      gearUpdateQueue.Enqueue(g);
         *                              }
         *                      }
         *              }
         *      }
         * }
         *
         * foreach (GFGear g in history){
         *      if (g.ReverseRotation && !g.ReverseRotationPlusSubtree)
         *      {
         *              g.CCW = !g.CCW;
         *      }
         * }*/
    }
예제 #17
0
 private float GetGearRatio(GFGear gear1, GFGear gear2)
 {
     return((float)gear1.numberOfTeeth / (float)gear2.numberOfTeeth);        //gear1.radius / gear2.radius;
 }
예제 #18
0
파일: GFGear.cs 프로젝트: zhiqich/EECS494
 public bool Intersects(GFGear otherGear)
 {
     MeshUtils.IntersectType it = MeshUtils.Intersect(MeshUtils.CalcOrientedBoundingBox(this.gameObject), MeshUtils.CalcOrientedBoundingBox(otherGear.gameObject));
     return(it == MeshUtils.IntersectType.Intersect || it == MeshUtils.IntersectType.Inside);
 }
예제 #19
0
    // Use this for initialization
    void Start()
    {
        distributionObject = this.gameObject;

        vectors = new List <Vector3>();
        normals = new List <Vector3>();

        //normals = new List<Vector3>();
        gears = new List <GFGearGen>();
        if (distributionObject != null && gearEntity != null)
        {
            MeshFilter m = (MeshFilter)distributionObject.GetComponent(typeof(MeshFilter));
            if (m != null)
            {
                followNormals = followNormals && m.mesh.normals.Length == m.mesh.vertices.Length && m.mesh.normals.Length > 0;

                // Walk through faces
                for (int i = 0; i < m.mesh.triangles.Length; i += 3)
                {
                    int[] triangle = new int[] { m.mesh.triangles[i], m.mesh.triangles[i + 1], m.mesh.triangles[i + 2] };

                    // For every face, get the three vertices
                    // Get the longest distance between two vertices

                    float d01     = Vector3.Distance(m.mesh.vertices[triangle[0]], m.mesh.vertices[triangle[1]]);
                    float d12     = Vector3.Distance(m.mesh.vertices[triangle[1]], m.mesh.vertices[triangle[2]]);
                    float d20     = Vector3.Distance(m.mesh.vertices[triangle[2]], m.mesh.vertices[triangle[0]]);
                    int   idxFrom = 2;
                    int   idxTo   = 0;
//					float dist;// = d20;

                    if (d01 > d12 && d01 > d20)
                    {
                        idxFrom = 0;
                        idxTo   = 1;
//						dist = d01;
                    }
                    else
                    {
                        if (d12 > d01 && d12 > d20)
                        {
                            idxFrom = 1;
                            idxTo   = 2;
//							dist = d12;
                        }
                    }

                    // Face normal
                    Vector3 n = Vector3.zero;
                    if (followNormals)
                    {
                        Vector3 n1 = m.mesh.normals[triangle[1]];
                        Vector3 n2 = m.mesh.normals[triangle[2]];
                        Vector3 n3 = m.mesh.normals[triangle[0]];
                        n = (n1 + n2 + n3) / 3.0f;
                        n.Normalize();
                    }


                    // Get center of line segment
                    Vector3 center = Vector3.Lerp(m.mesh.vertices[triangle[idxFrom]], m.mesh.vertices[triangle[idxTo]], 0.5f);

                    // If center isn't already occupied: add vector
                    if (!vectors.Contains(center))
                    {
                        vectors.Add(center);
                        if (followNormals)
                        {
                            normals.Add(n);
                        }
                        //	normals.Add(center.normalized);
                    }
                }

                // Walk through vectors and instantiate a gear

                GFGearGen gg;
                for (int i = 0; i < vectors.Count; i++)
                {
                    Vector3    v  = /*distributionObject.transform.localToWorldMatrix * */ vectors[i];                // + m.transform.position;// m.mesh.vertices[i];
                    Quaternion lr = Quaternion.LookRotation(followNormals ? normals[i] : v.normalized);

                    if (i == 0)
                    {
                        //gearEntity.gameObject.active = false;
                        gearEntity.transform.position = v;                        //distributionObject.transform.TransformPoint(v);
                        gearEntity.transform.rotation = lr;
                        gearEntity.transform.localRotation.eulerAngles.Set(0.0f, 0.0f, 0.0f);
                        gg = gearEntity;
                    }
                    else
                    {
                        gg = (GFGearGen)Instantiate(gearEntity);                        //, /*distributionObject.transform.TransformPoint(v)*/v, Quaternion.LookRotation(v.normalized));

                        gg.transform.parent   = gearEntity.transform.parent;
                        gg.transform.position = v;
                        gg.transform.rotation = lr;

                        if (gg.gear != null)
                        {
                            GFGear prevgear = gears[i - 1].gear;
                            if (prevgear != null)
                            {
                                gg.gear.DrivenBy = prevgear;
                            }
                        }
                    }
                    gears.Add(gg);
                }

                GFGear gear = gearEntity.gear;                // (GFGear)gearEntity.gameObject.GetComponent(typeof(GFGear));
                if (gear != null)
                {
                    if (gear.machine != null)
                    {
                        gear.machine.RecalculateGears();
                    }
                }


                #region Combine meshes to reduce draw calls
                if (combineMeshes)
                {
                    //transform.position = distributionObject.transform.position;
                    //transform.rotation = distributionObject.transform.rotation;

                    List <CombineInstance> cmb = new List <CombineInstance>();
                    for (int i = 0; i < gears.Count; i++)
                    {
                        MeshFilter mf = gears[i].gameObject.GetComponent <MeshFilter>();
                        if (mf != null)
                        {
                            CombineInstance ci = new CombineInstance();
                            ci.mesh      = mf.sharedMesh;
                            ci.transform = mf.transform.localToWorldMatrix;

                            mf.gameObject.SetActive(false);
                            cmb.Add(ci);
                        }
                    }
                    MeshFilter currentMf = transform.GetComponent <MeshFilter>();
                    currentMf.SetMesh(new Mesh());
                    currentMf.sharedMesh.CombineMeshes(cmb.ToArray());

                    MeshRenderer currentMr = transform.GetComponent <MeshRenderer>();
                    if (currentMr == null)
                    {
                        currentMr = (MeshRenderer)transform.gameObject.AddComponent(typeof(MeshRenderer));
                    }
                    transform.gameObject.SetActive(true);
                }
                #endregion

                m.GetComponent <Renderer>().enabled = !hideEmitter;
            }
        }
    }
예제 #20
0
    void OnSceneGUI()
    {
        Rect guiArea = new Rect(10, 10, 110, 150);

        GFGear gear = (GFGear)this.target;

        if (!Application.isPlaying)
        {
            if (UnityEditor.Selection.Contains(gear.gameObject))
            {
                RecalculateGears(gear);

                GFGearGen gearGen = gear.gameObject.GetComponent <GFGearGen>();

                // Show powered by arrow
                if (gear.machine == null || (gear.machine != null && gear.machine.ShowPoweredByIndicator))
                {
                    gear.DrawPoweredBy();
                }

                if (gearGen == null && gear.AutoAlign)
                {
                    gear.DrawAlignmentHelpers();
                }

                //GUI.enabled = (gear.DrivenBy != null && (gear.machine == null || (gear.machine != null && gear.machine.ShowPoweredByIndicator)));

                //Handles.color = Color.white;
                //Handles.DrawLine(gear.transform.position, GetMouseInWorldCoords(MeshUtils.CalcYAlignedCenterPlane(gear.gameObject), Event.current.mousePosition));

                #region GUI.enabled then this is visible.
                // Note: Not drawing this part is not an option as it will destroy your focus on selected element even if it's visible as being focused.
                //if (GUI.enabled && gear.machine != null && gear.machine.ShowBox)
                //	gear.DrivenBy.gameObject.DrawBoundingBox(Color.yellow);

                // Draw unlink button
                Handles.BeginGUI();

                GUILayout.BeginArea(guiArea);

                if (!isInAddGearMode)
                {
                    if (gear.DrivenBy != null)
                    {
                        GUIContent gcontent = new GUIContent("Unlink", "Manually override linkage.\r\n- Sets \"Driven By\" to: null\n- Sets \"Auto Set Driven By\" to: false");

                        if (GUILayout.Button(gcontent))
                        {
                            gear.DrivenBy        = null;
                            gear.AutoSetDrivenBy = false;
                            UnityEditor.EditorUtility.SetDirty(gear);
                        }


                        GUI.enabled = true;

                        if (gearGen != null)
                        {
                            #region auto alignment
                            string label     = "";
                            string hint      = "";
                            bool   autoAlign = false;
                            if (gearGen.alignTeethWithParent || gearGen.alignRadiusWithParent)
                            {
                                autoAlign = false;
                                label     = "Move freely";
                                hint      = "Switch off auto-alignment.\r\n- Sets \"Align Teeth With Parent\" to: false\r\n- Sets \"Align Radius With Parent\" to: false\r\n";
                            }
                            else
                            {
                                autoAlign = true;
                                label     = "Snap to parent";
                                hint      = "Switches on auto-alignment.\r\n- Sets \"Align Teeth With Parent\" to: true\r\n- Sets \"Align Radius With Parent\" to: true\r\n";
                            }

                            GUIContent gcontent2 = new GUIContent(label, hint);

                            if (GUILayout.Button(gcontent2))
                            {
                                gearGen.alignTeethWithParent  = autoAlign;
                                gearGen.alignRadiusWithParent = autoAlign;
                                UnityEditor.EditorUtility.SetDirty(gearGen);
                            }
                            #endregion
                        }
                        else
                        {
                            #region auto alignment
                            if (gear.DrivenBy != null)
                            {
                                string label = "";
                                string hint  = "";
                                if (gear.AutoAlign)
                                {
                                    label = "Move freely";
                                    hint  = "Switch off auto-alignment.\r\n";
                                }
                                else
                                {
                                    label = "Snap to parent";
                                    hint  = "Switches on auto-alignment.\r\n";
                                }

                                GUIContent gcontent3 = new GUIContent(label, hint);

                                if (GUILayout.Button(gcontent3))
                                {
                                    gear.AutoAlign = !gear.AutoAlign;
                                    UnityEditor.EditorUtility.SetDirty(gear);
                                }
                            }
                            #endregion
                        }
                    }

                    if (gearGen != null)
                    {
                        GUIContent gnewgear = new GUIContent("Add single", "Adds a new gear that's linked\r\nto last selected gear.");//GFGearEditor.isInAddGearMode ? "Done" : "Link new gear", "Adds a new gear that's linked to selected gear.");

                        if (GUILayout.Button(gnewgear))
                        {
                            CloneGear(gear, Vector3.right);
                        }

                        GUIContent gnewgearMulti = new GUIContent("Add multiple", "Add multiple gears.\r\nClick in your scene to specify direction.\r\nRight click when finished.");

                        if (GUILayout.Button(gnewgearMulti))
                        {
                            isInAddGearMode = true;
                        }

                        GUIContent grandomgear = new GUIContent("Randomize", "Rebuilds current gear with\r\ndifferent randomized settings.");//GFGearEditor.isInAddGearMode ? "Done" : "Link new gear", "Adds a new gear that's linked to selected gear.");

                        if (GUILayout.Button(grandomgear))
                        {
                            gearGen.Randomize();
                        }
                    }
                }
                else
                {
                    GUIContent gnewgearMulti = new GUIContent("Done", "Finish adding multiple gears.\r\n");

                    if (GUILayout.Button(gnewgearMulti))
                    {
                        cancelAddGearMode = true;
                    }
                }

                GUILayout.EndArea();

                //GUI.Label(new Rect(Screen.width - 250, Screen.height - 70 - 150, 250, 100), GUI.tooltip);
                Handles.EndGUI();
                #endregion


                if (gear.machine != null && gear.machine.PoweredGear == gear)
                {
                    Handles.Label(gear.transform.position + ((gear.radius * 1.30f) * Vector3.up) + (gear.radius * Vector3.left), "Machine powered (Speed:" + gear.machine.speed.ToString() + ")");
                }
            }

            if (isInAddGearMode || cancelAddGearMode)
            {
                if (cancelAddGearMode || Event.current.type != EventType.MouseUp || (Event.current.type == EventType.MouseUp && !guiArea.Contains(Event.current.mousePosition)))
                {
                    if (Event.current.type == EventType.MouseUp || cancelAddGearMode)
                    {
                        if (Event.current.button == 0 && !cancelAddGearMode)
                        {
                            CloneTowardsMousePos(gear, Event.current.mousePosition);
                        }
                        else
                        {
                            cancelAddGearMode = false;

                            CancelAddGearMode();
                        }
                    }

                    int controlID = GUIUtility.GetControlID(FocusType.Passive);
                    if (Event.current.type == EventType.Layout)
                    {
                        HandleUtility.AddDefaultControl(controlID);
                    }
                }
            }
        }
    }
예제 #21
0
    public void RecalculateGears(GFGear g1)
    {
        GFGear prevDrivenBy = g1.DrivenBy;

        if (g1.AutoSetDrivenBy)
        {
            g1.DrivenBy = null;
        }
        foreach (GFGear otherGear in g1.otherGears)
        {
            if (!otherGear.gameObject.Equals(g1.gameObject) && ((g1.AutoSetDrivenBy && g1.Intersects(otherGear)) || !g1.AutoSetDrivenBy))
            {
                // Set initial rotation
                if (g1.machine == null || (g1.machine != null && g1.machine.PoweredGear != g1))
                {
                    if (g1.AutoSetDrivenBy && g1.DrivenBy != otherGear)
                    {
                        // If redundant / circular reference is occuring: restore previous link and abort
                        if (otherGear.DrivenBy == g1)
                        {
                            g1.DrivenBy = prevDrivenBy;
                        }
                        else
                        {
                            g1.DrivenBy = otherGear;
                        }
                    }

                    if (g1.DrivenBy != null)
                    {
                        // If gear is auto generated, we can align the teeth
                        GFGearGen gg1 = g1.GetComponent(typeof(GFGearGen)) as GFGearGen;
                        GFGearGen gg2 = g1.DrivenBy.GetComponent(typeof(GFGearGen)) as GFGearGen;
                        if (gg1 != null && gg2 != null)
                        {
                            if (gg1.alignTeethWithParent)
                            {
                                gg1.Align(gg2);
                            }
                            else
                            {
                                if (gg1.alignRadiusWithParent)
                                {
                                    gg1.AlignRadius(gg2);
                                }
                            }
                        }
                        else
                        {
                            // If gear is not auto generated, we can align the positions if autoAlign is true.
                            if (gearAutoAlign.boolValue)
                            {
                                g1.Align(g1.DrivenBy);
                            }
                        }
                    }
                }

                // Tell the unity editor we changed something by code, so it gets saved.
                UnityEditor.EditorUtility.SetDirty(g1);
                // All aligned and set: get the hell out of this loop!
                break;
            }
        }
    }