Example #1
0
    /// <summary>
    /// Align current gear with the gear specified in alignTo.
    /// </summary>
    /// <param name='alignTo'>
    /// Align to this gear.
    /// </param>
    public void Align(GFGearGen alignTo)
    {
        int desiredTeethCount = (int)Mathf.Round((alignTo.numberOfTeeth / alignTo.radius) * this.radius);

        if (this.numberOfTeeth != desiredTeethCount)
        {
            this.numberOfTeeth = desiredTeethCount;
            Rebuild();
        }

        base.Align(alignTo);
    }
Example #2
0
    /// <summary>
    /// Align radius of current gear with the gear specified in alignTo based on number of teeth.
    /// </summary>
    /// <param name='alignTo'>
    /// Align to this gear.
    /// </param>
    public void AlignRadius(GFGearGen alignTo)
    {
        float desiredRadius = (alignTo.radius / (float)alignTo.numberOfTeeth) * this.numberOfTeeth;

        if (this.radius != desiredRadius)
        {
            // First set radius to the amount of teeth related to it's radius
            this.radius = desiredRadius;
            Rebuild();
        }

        base.Align(alignTo);
    }
Example #3
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;
    }
Example #4
0
    /// <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);
    }
Example #5
0
    static private void Persist(GFGearGen gearGenObject)
    {
        Mesh newMesh = gearGenObject.GetComponent <MeshFilter>().sharedMesh;

        if (newMesh == null || !AssetDatabase.Contains(newMesh))
        {
            if (!AssetDatabase.IsValidFolder("Assets/Gear Factory/Meshes"))
            {
                AssetDatabase.CreateFolder("Assets/Gear Factory", "Meshes");
            }

            string assetName = AssetDatabase.GenerateUniqueAssetPath("Assets/Gear Factory/Meshes/" + gearGenObject.gameObject.name + ".asset");
            AssetDatabase.CreateAsset(newMesh, assetName);
            AssetDatabase.SaveAssets();
        }
    }
Example #6
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);
    }
Example #7
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;
    }
Example #8
0
 /// <summary>
 /// Aligns the position and rotation to match gear specified in alignTo.
 /// </summary>
 /// <param name='alignTo'>
 /// Align to.
 /// </param>
 public void AlignPositions(GFGearGen alignTo)
 {
     base.Align(alignTo);
 }
Example #9
0
    public void GenerateGear(GFGearGen gearGen)
    {
        this.gearGen = gearGen;
        GameObject gameObject = gearGen.gameObject;

        mesh = gameObject.GetSharedMesh();

        if (mesh != null)
        {
            mesh.Clear();

            /*
             * //speed up math by copying the mesh arrays
             * meshTriangles = mesh.triangles;
             * meshVertices = mesh.vertices;
             * meshUv = mesh.uv;
             * meshNormals = mesh.normals;
             */
            // Clean up (storing these temp lists globally and just clearing them localy prevents the GC to be all nasty on our performance.
            verticesSideA.Clear();
            verticesSideB.Clear();
            facesSideA.Clear();
            facesSideB.Clear();
            vertices.Clear();
            faces.Clear();
            normals.Clear();
            normalsA.Clear();
            normalsB.Clear();
            centersA.Clear();
            centersB.Clear();

            // Create vertices
            CreateSide(ref verticesSideA, ref facesSideA, ref normalsA, ref centersA, false, 0);
            if (gearGen.is3d)
            {
                CreateSide(ref verticesSideB, ref facesSideB, ref normalsB, ref centersB, true, verticesSideA.Count);
            }

            vertices.AddRange(verticesSideA);
            normals.AddRange(normalsA);

            if (gearGen.is3d)
            {
                vertices.AddRange(verticesSideB);
                normals.AddRange(normalsB);
            }

            // Create faces
            faces.AddRange(facesSideA);

            if (gearGen.is3d)
            {
                faces.AddRange(facesSideB);
            }

            // Optimize center vertices when inner radius > threshold
            if (gearGen.innerRadius > 0.0f)
            {
                verticesRemoved = MeshUtils.RemoveDoubles(gearGen.innerMinVertexDistance, vertices, normals, faces, centersA, centersB, facesSideA, facesSideB);
            }
            else
            {
                verticesRemoved = 0;
            }

            if (gearGen.is3d)
            {
                CreateGlue(facesSideA, centersA, facesSideB, centersB, ref vertices, ref faces, ref normals);
            }

            MeshUtils.SmoothNormals(gearGen.splitVerticesAngle, vertices, normals);

            verticesRemoved += MeshUtils.RemoveDoubles(0.001f, vertices, normals, faces);

            // Fill the mesh
            mesh.vertices  = vertices.ToArray();
            mesh.uv        = GetUVs(mesh.vertices, gearGen.generateTextureCoordinates);
            mesh.triangles = faces.ToArray();
            // Calculate normals

            /*
             * if (!gearGen.generateNormals)
             * {
             *      mesh.RecalculateNormals();
             *      normals.AddRange(mesh.normals);
             * }
             * else
             * { */
//				normals.AddRange(normalsA);
//				normals.AddRange(normalsB);
            mesh.normals = normals.ToArray();
            //}


            // Refresh internal parameters
            MeshUtils.TangentSolver(mesh);
            mesh.RecalculateBounds();


            numberOfVertices = mesh.vertexCount;
            numberOfFaces    = mesh.triangles.Length / 3;
        }
    }
Example #10
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);
                    }
                }
            }
        }
    }
Example #11
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;
            }
        }
    }