public static void loadNodeIcons() { if (ArchimatixEngine.nodeIcons != null) { return; } ArchimatixEngine.nodeIcons = new Dictionary <string, Texture2D>(); // The ? wildcard is used here to make sure that .jpg.meta files are not being returned String[] nodeIconPaths = Directory.GetFiles(ArchimatixEngine.ArchimatixAssetPath + "/ui/NodeIcons/", "*.jp?"); string filename; string nodeIconName; for (int i = 0; i < nodeIconPaths.Length; i++) { //Debug.Log(nodeIconPaths[i]); filename = System.IO.Path.GetFileName(nodeIconPaths[i]); if (!string.IsNullOrEmpty(filename) && filename.Length > 10) { // strip extension nodeIconName = System.IO.Path.GetFileNameWithoutExtension(nodeIconPaths[i]); if (!string.IsNullOrEmpty(filename) && nodeIconName.Length > 10) { //strip prefix of "zz-AXNode-" nodeIconName = nodeIconName.Substring(10); ArchimatixEngine.nodeIcons.Add(nodeIconName, (Texture2D)AssetDatabase.LoadAssetAtPath(ArchimatixEngine.ArchimatixAssetPath + "/ui/NodeIcons/" + filename, typeof(Texture2D))); } } } // custom nodes with name of form zz_AXNode-typename Archimatix.discoverThirdPartyNodes(); foreach (String name in Archimatix.customNodeNames) { string typeName = name; DirectoryInfo info = new DirectoryInfo(Application.dataPath); FileInfo[] files = info.GetFiles("zz_AXNode-" + typeName + ".jpg", SearchOption.AllDirectories); if (files != null && files.Length > 0) { string iconRelPath = ArchimatixUtils.getRelativeFilePath(files[0].ToString()); //Debug.Log("path: " + typeName + " --- " + iconRelPath); if (!ArchimatixEngine.nodeIcons.ContainsKey(typeName)) { ArchimatixEngine.nodeIcons.Add(typeName, (Texture2D)AssetDatabase.LoadAssetAtPath(iconRelPath, typeof(Texture2D))); } } } }
// GROUPER::GENERATE public override GameObject generate(bool makeGameObjects, AXParametricObject initiator_po, bool isReplica) { //if (ArchimatixUtils.doDebug) //Debug.Log (parametricObject.Name + " generate +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); if (!parametricObject.isActive) { return(null); } if (parametricObject.Groupees == null) { return(null); } preGenerate(); parametricObject.useMeshInputs = true; if (parametricObject.meshInputs == null) { parametricObject.meshInputs = new List <AXParameter>(); } // PROCESS INPUT SHAPES // pass Input Shape through... //Debug.Log( parametricObject.Name + " <><><><><> PROCESS INPUT SHAPES"); List <AXParameter> inputShapes = parametricObject.getAllInputShapes(); for (int i = 0; i < inputShapes.Count; i++) { AXParameter inputShape = inputShapes[i]; if (inputShape != null) { inputShape.polyTree = null; AXShape.thickenAndOffset(ref inputShape, inputShape.DependsOn); } } GameObject go = null; if (makeGameObjects && !parametricObject.combineMeshes) { go = ArchimatixUtils.createAXGameObject(parametricObject.Name, parametricObject); } List <AXMesh> ax_meshes = new List <AXMesh>(); List <AXMesh> boundingMeshes = new List <AXMesh>(); // for each input //List<AXParameter> inputMeshes = parametricObject.getAllInputMeshParameters(); // Reinstate the original functionality of the Grouper as simple combiner in addition to Groupees. if (inputs != null && inputs.Count > 0) { for (int i = 0; i < inputs.Count; i++) { if (inputs[i] != null && inputs[i].DependsOn != null) { if (inputs[i].Dependents != null || inputs[i].Dependents.Count == 0) { AXParameter src_p = inputs[i].DependsOn; AXParametricObject src_po = inputs[i].DependsOn.parametricObject; //if (! parametricObject.visited_pos.Contains (groupee)) //Debug.Log("groupee.generateOutputNow: " + groupee.Name + " isAltered="+groupee.isAltered); if (src_po.isAltered) { src_po.generateOutputNow(makeGameObjects, initiator_po); //Debug.Log("XXXXX: " + groupee.Output.meshes.Count); src_po.isAltered = false; parametricObject.model.AlteredPOs.Remove(src_po); } if (src_p != null && src_p.meshes != null) { for (int j = 0; j < src_p.meshes.Count; j++) { AXMesh dep_amesh = src_p.meshes [j]; ax_meshes.Add(dep_amesh.Clone(dep_amesh.transMatrix)); } } // BOUNDING MESHES //boundsCombinator[i].mesh = input_p.DependsOn.parametricObject.boundsMesh; //boundsCombinator[i].transform = input_p.DependsOn.parametricObject.generator.localMatrixWithAxisRotationAndAlignment; if (src_po.boundsMesh != null) { boundingMeshes.Add(new AXMesh(src_po.boundsMesh, src_po.generator.localMatrixWithAxisRotationAndAlignment)); } // GAME_OBJECTS if (makeGameObjects && !parametricObject.combineMeshes) { GameObject plugGO = src_po.generator.generate(true, initiator_po, isReplica); if (plugGO != null) { plugGO.transform.parent = go.transform; } } } } } } // *** GROUPEES - Generate the groupees here // so that all the inputs (thicknesses, etc.) have been processed first. //List<AXParametricObject> visited_pos = new List<AXParametricObject>(); if (parametricObject.Groupees != null && parametricObject.Groupees.Count > 0) { for (int i = 0; i < parametricObject.Groupees.Count; i++) { AXParametricObject groupee = parametricObject.Groupees [i]; //if (! parametricObject.visited_pos.Contains (groupee)) //Debug.Log("groupee.generateOutputNow: " + groupee.Name + " isAltered="+groupee.isAltered); if (groupee.isAltered) { groupee.generateOutputNow(makeGameObjects, initiator_po); //Debug.Log("XXXXX: " + groupee.Output.meshes.Count); groupee.isAltered = false; parametricObject.model.AlteredPOs.Remove(groupee); } } } // BOUNDING // Process for (int i = 0; i < parametricObject.Groupees.Count; i++) { AXParametricObject groupee = parametricObject.Groupees [i]; //if (input_p != null && input_p.DependsOn != null && input_p.DependsOn.meshes != null && input_p.DependsOn.meshes.Count > 0) { //if (groupee != null && groupee.is3D() && ! groupee.hasDependents() && groupee.Output != null && groupee.Output.meshes != null) if (groupee != null && groupee.is3D() && groupee.shouldRenderSelf(true)) { // AX_MESHES //Debug.Log("(*) (*) (*) (*) groupee: " + groupee.Name + " " +groupee.Output.meshes.Count + " isAltered = " + groupee.isAltered); if (groupee.Output != null && groupee.Output.meshes != null) { for (int j = 0; j < groupee.Output.meshes.Count; j++) { AXMesh dep_amesh = groupee.Output.meshes [j]; ax_meshes.Add(dep_amesh.Clone(dep_amesh.transMatrix)); } } // BOUNDING MESHES //boundsCombinator[i].mesh = input_p.DependsOn.parametricObject.boundsMesh; //boundsCombinator[i].transform = input_p.DependsOn.parametricObject.generator.localMatrixWithAxisRotationAndAlignment; if (groupee.boundsMesh != null) { boundingMeshes.Add(new AXMesh(groupee.boundsMesh, groupee.generator.localMatrixWithAxisRotationAndAlignment)); } // GAME_OBJECTS if (makeGameObjects && !parametricObject.combineMeshes) { GameObject plugGO = groupee.generator.generate(true, initiator_po, isReplica); if (plugGO != null) { plugGO.transform.parent = go.transform; } } } } // FINISH AX_MESHES //Debug.Log("ORG: " + ax_meshes.Count); parametricObject.finishMultiAXMeshAndOutput(ax_meshes, isReplica); // FINISH BOUNDS CombineInstance[] boundsCombinator = new CombineInstance[boundingMeshes.Count]; for (int bb = 0; bb < boundsCombinator.Length; bb++) { boundsCombinator[bb].mesh = boundingMeshes[bb].mesh; boundsCombinator[bb].transform = boundingMeshes[bb].transMatrix; } setBoundsWithCombinator(boundsCombinator); if (P_BoundsX != null && !P_BoundsX.hasRelations() && !P_BoundsX.hasExpressions()) { P_BoundsX.FloatVal = parametricObject.bounds.size.x; } if (P_BoundsY != null && !P_BoundsY.hasRelations() && !P_BoundsY.hasExpressions()) { P_BoundsY.FloatVal = parametricObject.bounds.size.y; } if (P_BoundsZ != null && !P_BoundsZ.hasRelations() && !P_BoundsZ.hasExpressions()) { P_BoundsZ.FloatVal = parametricObject.bounds.size.z; } // FINISH GAME_OBJECTS if (makeGameObjects) { if (parametricObject.combineMeshes) { go = parametricObject.makeGameObjectsFromAXMeshes(ax_meshes, true, false); // COMBINE ALL THE MESHES CombineInstance[] combine = new CombineInstance[ax_meshes.Count]; int combineCt = 0; for (int i = 0; i < ax_meshes.Count; i++) { AXMesh _amesh = ax_meshes [i]; combine [combineCt].mesh = _amesh.mesh; combine [combineCt].transform = _amesh.transMatrix; combineCt++; } Mesh combinedMesh = new Mesh(); combinedMesh.CombineMeshes(combine); // If combine, use combined mesh as invisible collider MeshFilter mf = (MeshFilter)go.GetComponent(typeof(MeshFilter)); if (mf == null) { mf = (MeshFilter)go.AddComponent(typeof(MeshFilter)); } if (mf != null) { mf.sharedMesh = combinedMesh; parametricObject.addCollider(go); } } else { Matrix4x4 tmx = parametricObject.getLocalMatrix(); go.transform.rotation = AXUtilities.QuaternionFromMatrix(tmx); go.transform.position = AXUtilities.GetPosition(tmx); go.transform.localScale = parametricObject.getLocalScaleAxisRotated(); } return(go); } //parametricObject.model.sw.milestone(parametricObject.Name + " generate"); return(null); }
public static int GeometryControlsOnGUI(int cur_y, AXNodeGraphEditorWindow editor, AXParametricObject po) { int gap = ArchimatixUtils.gap; int lineHgt = ArchimatixUtils.lineHgt; float x1 = 10; float x2 = 20; float winMargin = ArchimatixUtils.indent; float innerWidth = po.rect.width - 2 * winMargin; AXParameter p = null; // Geometry (and other) controllers if (po.geometryControls != null && po.geometryControls.children != null) { for (int i = 0; i < po.geometryControls.children.Count; i++) { p = po.geometryControls.children[i] as AXParameter; if (p.PType != AXParameter.ParameterType.None && p.PType != AXParameter.ParameterType.GeometryControl) { continue; } // these points are world, not relative to the this GUIWindow p.inputPoint = new Vector2(po.rect.x, po.rect.y + cur_y + lineHgt / 2); p.outputPoint = new Vector2(po.rect.x + po.rect.width, po.rect.y + cur_y + lineHgt / 2); Rect pRect = new Rect(x1, cur_y, innerWidth, lineHgt); try { int hgt = ParameterGUI.OnGUI(pRect, editor, p); cur_y += hgt + gap; } catch { } } } if (po.is2D() || po.generator is Grouper) { if (GUI.Button(new Rect(x2, cur_y, lineHgt * 1.25f, lineHgt), new GUIContent("+", "Create a new Control Parameter"))) { Undo.RegisterCompleteObjectUndo(po.model, "New AXParameter"); AXParameter tmpP = po.addParameter(new AXParameter()); foreach (AXParameter pop in po.parameters) { if (pop != p) { pop.isOpen = false; } } po.model.indexedParameters.Add(tmpP.Guid, tmpP); po.doneEditing(); tmpP.isOpen = true; tmpP.isEditing = false; tmpP.shouldFocus = true; //po.isEditing = true; po.model.cleanGraph(); AXNodeGraphEditorWindow.repaintIfOpen(); } /* * if (GUI.Button (new Rect(x1+editButtonWid+6, cur_y, editButtonWid,lineHgt), "Done" )) * po.doneEditing(); * else * if (GUI.Button (new Rect(x1+editButtonWid+6, cur_y, editButtonWid,lineHgt), "Edit Controls" )) * po.isEditing = true; */ cur_y += lineHgt + gap + 5; } if (po.generator is MaterialTool) { MaterialTool materialTool = (po.generator as MaterialTool); GUIStyle labelstyle = GUI.skin.GetStyle("Label"); labelstyle.alignment = TextAnchor.MiddleLeft; GUI.Label(new Rect(10, cur_y, 250, 32), " Texels/Unit: " + materialTool.texelsPerUnit.ToString("F0")); cur_y += 32; } else if (po.generator is ShapeOffsetter) { ShapeOffsetter offsetter = (po.generator as ShapeOffsetter); AXParameter output_p = offsetter.P_Output; if (output_p == null) { output_p = po.getParameter("Output Shape"); } if (output_p == null) { return(cur_y); } Rect tRect = new Rect(25, cur_y, 150, 16); GUIStyle labelstyle = GUI.skin.GetStyle("Label"); labelstyle.alignment = TextAnchor.MiddleLeft; /* * if (p.PType == AXParameter.ParameterType.Output) * { * labelstyle.alignment = TextAnchor.MiddleRight; * labelstyle.fixedWidth = lRect.width+5; * } */ // JOIN_TYPE: Square, Round, Miter if (offsetter.offset != 0) { string[] options = ArchimatixUtils.getMenuOptions("JoinType"); EditorGUIUtility.labelWidth = 75; //-50; EditorGUI.BeginChangeCheck(); output_p.joinType = (JoinType)EditorGUI.Popup(tRect, "JoinType", (int)output_p.joinType, options); if (EditorGUI.EndChangeCheck()) { Undo.RegisterCompleteObjectUndo(po.model, "value change for JoinType"); po.model.autobuild(); } cur_y += ArchimatixUtils.lineHgt + ArchimatixUtils.gap; } // ARC_TOLERANCE (for JoinType.Round) if (output_p.joinType == AXClipperLib.JoinType.jtRound || output_p.endType == AXClipperLib.EndType.etOpenRound) { tRect.y = cur_y; if (float.IsNaN(output_p.arcTolerance)) { output_p.arcTolerance = 50; } if (output_p.arcTolerance < .25f) { output_p.arcTolerance = .25f; } float smooth = (float)(120 / (output_p.arcTolerance * output_p.arcTolerance)); AXEditorUtilities.assertFloatFieldKeyCodeValidity("shapehandler_Text_smoothness_" + output_p.Guid + "_" + output_p.Name); EditorGUI.BeginChangeCheck(); GUI.SetNextControlName("shapehandler" + output_p.Name); smooth = EditorGUI.FloatField(tRect, "smoothness", smooth); if (EditorGUI.EndChangeCheck()) { output_p.arcTolerance = (float)(Mathf.Sqrt(120 / smooth)); Undo.RegisterCompleteObjectUndo(po.model, "value change for " + output_p.Name); if (output_p.arcTolerance < .25f) { output_p.arcTolerance = .25f; } if (output_p.arcTolerance > 50) { output_p.arcTolerance = 50; } if (float.IsNaN(output_p.arcTolerance)) { output_p.arcTolerance = 50; } po.model.isAltered(20); } cur_y += ArchimatixUtils.lineHgt + ArchimatixUtils.gap; } } return(cur_y); }
public static void makePrefab(AXModel model, string prefabPath, AXNodeGraphEditorWindow _editor) { //if (model == null) // return null; if (model.generatedGameObjects != null) { // extrat folder path from path //string filename = System.IO.Path.GetFileName (filepath); string prefabName = System.IO.Path.GetFileNameWithoutExtension(prefabPath); string relativePrefabPath = ArchimatixUtils.getRelativeFilePath(prefabPath); string folderPath = System.IO.Path.GetDirectoryName(prefabPath); string relativeFolderPath = ArchimatixUtils.getRelativeFilePath(folderPath); // if no directory selected in dialog, then relativeFolderPath is empty if (String.IsNullOrEmpty(relativeFolderPath)) { relativeFolderPath = "Assets"; } Debug.Log(folderPath + " :: " + relativeFolderPath + " :: " + prefabName); model.build(); GameObject stampedGO = model.stamp(); // Only save unique, sharedMeshes to the AssetsDatabase List <Mesh> meshesToSave = new List <Mesh> (); int meshCount = 0; Transform[] transforms = stampedGO.GetComponentsInChildren <Transform> (); foreach (Transform transform in transforms) { MeshFilter meshFilter = transform.gameObject.GetComponent <MeshFilter> (); if (meshFilter != null) { Mesh mesh = meshFilter.sharedMesh; if (mesh != null && !meshesToSave.Contains(mesh)) { ; meshesToSave.Add(mesh); meshCount++; } GameObjectUtility.SetStaticEditorFlags(transform.gameObject, StaticEditorFlags.LightmapStatic); } } AssetDatabase.DeleteAsset(relativePrefabPath); // [not sure why this is needed here to correct the filepath, but not in the Library Save dalog...] relativePrefabPath = relativePrefabPath.Replace('\\', '/'); var prefab = PrefabUtility.CreateEmptyPrefab(relativePrefabPath); int i = 0; foreach (Mesh mesh in meshesToSave) /* * { * if (string.IsNullOrEmpty(mesh.name)) * mesh.name = prefabName+"_"+(i++); * AssetDatabase.DeleteAsset (relativePrefabPath+"/"+mesh.name); * AssetDatabase.AddObjectToAsset(mesh, relativePrefabPath); * } */ { // Compliments of Enoch if (string.IsNullOrEmpty(mesh.name)) { mesh.name = prefabName + "_" + (i++); } var path = AssetDatabase.GetAssetPath(mesh); if (string.IsNullOrEmpty(path)) { AssetDatabase.AddObjectToAsset(mesh, relativePrefabPath); } } AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); PrefabUtility.ReplacePrefab(stampedGO, prefab, ReplacePrefabOptions.ConnectToPrefab); stampedGO.name = prefabName; //Selection.activeGameObject = stampedGO; //buildStatus = BuildStatus.Generated; //Close(); } }
// GENERATE PAIR_REPEATER public override GameObject generate(bool makeGameObjects, AXParametricObject initiator_po, bool isReplica) { //Debug.Log ("PairRepeater::Generate "); if (parametricObject == null || !parametricObject.isActive) { return(null); } preGenerate(); if ((nodeSrc_p == null || nodeSrc_p.meshes == null || nodeSrc_p.meshes.Count == 0) && (nodeSrc_po != null && !(nodeSrc_po.generator is PrefabInstancer))) { return(null); } if (P_Node == null || P_Node.DependsOn == null) { return(null); } GameObject go = null; if (makeGameObjects && !parametricObject.combineMeshes) { go = ArchimatixUtils.createAXGameObject(parametricObject.Name, parametricObject); } List <AXMesh> ax_meshes = new List <AXMesh>(); GameObject plugGO = null; if (makeGameObjects && !parametricObject.combineMeshes) { plugGO = nodeSrc_po.generator.generate(true, initiator_po, isReplica); if (plugGO == null) { return(null); } } float separationX = zAxis ? 0 : separation; float separationZ = zAxis ? -separation : 0; CombineInstance[] boundsCombinator = new CombineInstance[2]; // * RIGHT INSTANCE * // -------------------------------------------------------------------- // Right Instance is at Address 0... Matrix4x4 localPlacement_mx = localNodeMatrixFromAddress(0); // use submeshes for right instance // AX_MESHES for (int mi = 0; mi < P_Node.DependsOn.meshes.Count; mi++) { AXMesh dep_amesh = P_Node.DependsOn.meshes [mi]; ax_meshes.Add(dep_amesh.Clone(localPlacement_mx * dep_amesh.transMatrix)); } // BOUNDING MESHES boundsCombinator[0].mesh = nodeSrc_po.boundsMesh; boundsCombinator[0].transform = localPlacement_mx * nodeSrc_po.generator.localMatrixWithAxisRotationAndAlignment; // GAME_OBJECTS if (plugGO != null && makeGameObjects && !parametricObject.combineMeshes) { Matrix4x4 mx = localPlacement_mx * nodeSrc_po.generator.localMatrixWithAxisRotationAndAlignment; GameObject copyGO = (GameObject)GameObject.Instantiate(plugGO, AXUtilities.GetPosition(mx), AXUtilities.QuaternionFromMatrix(mx)); copyGO.transform.localScale = nodeSrc_po.getLocalScaleAxisRotated(); AXGameObject axgo = copyGO.GetComponent <AXGameObject>(); if (axgo != null) { axgo.consumerAddress = "node_0"; } copyGO.name = copyGO.name + "_node_right"; copyGO.transform.parent = go.transform; } // * INVERSE (LEFT) INSTANCE // -------------------------------------------------------------------- // ***--- AX_MESHES - INVERSE (LEFT) ---*** translate = new Vector3(-separationX / 2, 0, -separationZ / 2); // LOCAL PLACEMENT localPlacement_mx = localNodeMatrixFromAddress(1); // use submeshes for left instance for (int mi = 0; mi < P_Node.DependsOn.meshes.Count; mi++) { // CLONE AXMesh dep_amesh = P_Node.DependsOn.meshes [mi]; AXMesh clone = dep_amesh.Clone(); // SYMETRICAL? if (symmetrical) { clone.mesh = AXMesh.freezeWithMatrix(dep_amesh.mesh, symmetryM * dep_amesh.transMatrix); clone.transMatrix = localPlacement_mx * symmetryM.inverse; } else { clone = dep_amesh.Clone(localPlacement_mx * symmetryM.inverse * dep_amesh.transMatrix); } // ADD TO AX_MESHES ax_meshes.Add(clone); } // BOUNDING MESHES boundsCombinator[1].mesh = nodeSrc_po.boundsMesh; boundsCombinator[1].transform = localPlacement_mx * nodeSrc_po.generator.localMatrixWithAxisRotationAndAlignment; // *** --- INVERSE (LEFT) - GAME_OBJECT ---** if (plugGO != null && makeGameObjects && !parametricObject.combineMeshes) { // LOCAL PLACEMENT //Matrix4x4 mx = localPlacement_mx * symmetryM * nodeSrc_po.generator.localMatrixWithAxisRotationAndAlignment; Matrix4x4 mx = localPlacement_mx * nodeSrc_po.generator.localMatrixWithAxisRotationAndAlignment; // GAME_OBJECT GameObject copyGO = (GameObject)GameObject.Instantiate(plugGO, AXUtilities.GetPosition(mx), AXUtilities.QuaternionFromMatrix(mx)); copyGO.transform.localScale = nodeSrc_po.getLocalScaleAxisRotated(); // SYMETRICAL? if (symmetrical) { copyGO.transform.localScale = copyGO.transform.localScale * -1; if (zAxis) { copyGO.transform.Rotate(0, 180, 180); } else { copyGO.transform.Rotate(180, 0, 0); } } // Force a refreshing of the colliders down the instatiatined hierachy // Based on a solution provided by pkamat here:http://forum.unity3d.com/threads/how-to-update-a-mesh-collider.32467/ foreach (MeshCollider mc in copyGO.GetComponentsInChildren <MeshCollider>()) { mc.sharedMesh = null; mc.sharedMesh = mc.gameObject.GetComponent <MeshFilter>().sharedMesh; } // ADD GAME_OBJECT AXGameObject axgo = copyGO.GetComponent <AXGameObject>(); if (axgo != null) { axgo.consumerAddress = "node_1"; } copyGO.name = copyGO.name + "_node_left"; copyGO.transform.parent = go.transform; } GameObject.DestroyImmediate(plugGO); // COMBINE ALL THE MESHES CombineInstance[] combine = new CombineInstance[ax_meshes.Count]; int combineCt = 0; for (int i = 0; i < ax_meshes.Count; i++) { AXMesh _amesh = ax_meshes [i]; combine [combineCt].mesh = _amesh.mesh; combine [combineCt].transform = _amesh.transMatrix; combineCt++; } Mesh combinedMesh = new Mesh(); combinedMesh.CombineMeshes(combine); combinedMesh.RecalculateBounds(); // BOUNDARY - Use combined meshes for boundary setBoundsWithCombinator(boundsCombinator); /* * // BOUNDS & CENTER * * Vector3 margin = new Vector3(source_po.bounds.size.x, source_po.bounds.size.y, source_po.bounds.size.z); * Bounds b = new Bounds(); * b.size = new Vector3(separationX + margin.x, margin.y, separationZ + margin.z); * b.extents = b.size/2; * b.center = source_po.bounds.center;// + new Vector3(0, b.extents.y, 0); * * parametricObject.margin = margin; * parametricObject.bounds = b; */ // FINISH parametricObject.finishMultiAXMeshAndOutput(ax_meshes, isReplica); // Turn ax_meshes into GameObjects if (makeGameObjects) { if (parametricObject.combineMeshes) { go = parametricObject.makeGameObjectsFromAXMeshes(ax_meshes, true, false); // If combine, use combined mesh as invisible collider MeshFilter mf = (MeshFilter)go.GetComponent(typeof(MeshFilter)); if (mf == null) { mf = (MeshFilter)go.AddComponent(typeof(MeshFilter)); } if (mf != null) { mf.sharedMesh = combinedMesh; parametricObject.addCollider(go); } } //Matrix4x4 tmx = parametricObject.generator.localMatrix; Matrix4x4 tmx = parametricObject.getLocalMatrix(); go.transform.rotation = AXUtilities.QuaternionFromMatrix(tmx); go.transform.position = AXUtilities.GetPosition(tmx); go.transform.localScale = parametricObject.getLocalScaleAxisRotated(); return(go); } return(null); }
// GENERATE GRID_REPEATER public override GameObject generate(bool makeGameObjects, AXParametricObject initiator_po, bool isReplica) { //Debug.Log(parametricObject.Name + " Generate"); if (parametricObject == null || !parametricObject.isActive) { return(null); } if (repeaterToolU == null || repeaterToolV == null) { return(null); } preGenerate(); // NODE_MESH AXParametricObject nodeSrc_po = null; GameObject nodePlugGO = null; if (nodeSrc_p != null) { nodeSrc_po = nodeSrc_p.parametricObject; if (makeGameObjects && !parametricObject.combineMeshes) { nodePlugGO = nodeSrc_po.generator.generate(true, initiator_po, isReplica); } } // CELL_MESH AXParametricObject cellSrc_po = null; GameObject cellPlugGO = null; if (cellSrc_p != null) { cellSrc_po = cellSrc_p.parametricObject; if (makeGameObjects && !parametricObject.combineMeshes) { cellPlugGO = cellSrc_po.generator.generate(true, initiator_po, isReplica); } } // BAY_SPAN_U AXParametricObject spanUSrc_po = null; GameObject spanUPlugGO = null; if (spanUSrc_p != null) { spanUSrc_po = spanUSrc_p.parametricObject; if (makeGameObjects && !parametricObject.combineMeshes) { spanUPlugGO = spanUSrc_po.generator.generate(true, initiator_po, isReplica); } } // BAY_SPAN_V AXParametricObject spanVSrc_po = null; GameObject spanVPlugGO = null; if (spanVSrc_p != null) { spanVSrc_po = spanVSrc_p.parametricObject; if (makeGameObjects && !parametricObject.combineMeshes) { spanVPlugGO = spanVSrc_po.generator.generate(true, initiator_po, isReplica); } } if (nodeSrc_po == null && cellSrc_po == null && spanUSrc_po == null && spanVSrc_po == null) { AXParameter output_p = getPreferredOutputParameter(); if (output_p != null) { output_p.meshes = null; } return(null); } GameObject go = null; if (makeGameObjects && !parametricObject.combineMeshes) { go = ArchimatixUtils.createAXGameObject(parametricObject.Name, parametricObject); } // BOUNDING_SHAPE Paths boundingSolids = null; Paths boundingHoles = null; if (P_BoundingShape != null && P_BoundingShape.DependsOn != null) { AXParameter bounding_src_p = null; if (P_BoundingShape != null) { bounding_src_p = P_BoundingShape.DependsOn; // USING SINGLE SPLINE INPUT } boundingShapeSrc_po = bounding_src_p.parametricObject; AXShape.thickenAndOffset(ref P_BoundingShape, bounding_src_p); // now boundin_p has offset and thickened polytree or paths. boundingSolids = P_BoundingShape.getTransformedSubjPaths(); boundingHoles = P_BoundingShape.getTransformedHolePaths(); } List <AXMesh> ax_meshes = new List <AXMesh>(); Matrix4x4 localPlacement_mx = Matrix4x4.identity; // ----------------------------------- int max_reps = 150; int cellsU = Mathf.Clamp(repeaterToolU.cells, 1, max_reps); float actualBayU = repeaterToolU.actualBay; int cellsV = Mathf.Clamp(repeaterToolV.cells, 1, max_reps); float actualBayV = repeaterToolV.actualBay; shiftU = -cellsU * actualBayU / 2; shiftV = -cellsV * actualBayV / 2; // BAY SPAN // Spanners are meshers that get replicated and sized to fit the bay... // prepare mesh to iterate in each direction //List<AXMesh> ax_meshes_X = new List<AXMesh>(); //List<AXMesh> ax_meshes_Z = new List<AXMesh>(); AXMesh tmpMesh; if (spanUSrc_p != null) { //ax_meshes_X = spanUSrc_p.meshes; //ax_meshes_Z = spanUSrc_p.meshes; } /* NEED TO INTEGRATE THIS BACK IN IN THE FUTRE... * if (bay_span_source != null) * { * * // 1. cache source object * bay_span_source.cacheParameterValues(); * * * // Y_AXIS * * AXParameter p_bayv = parametricObject.getParameter("actual_bay_V"); * AXParameter p_bayv_client = null; * if (p_bayv != null) * { * foreach (AXRelation rel in p_bayv.relations) * { * p_bayv_client = rel.getRelatedTo(p_bayv); * p_bayv_client.intiateRipple_setFloatValueFromGUIChange(abayy); * } * } * * * AXParameter p_bayu = parametricObject.getParameter("actual_bay_U"); * AXParameter p_bayu_client = null; * * // X-AXIS * // For now, only set the boundaries. * // Perhaps later, may want to set other like controls as in Replicant * * // If there is a relation to actual_bay_U, propogate it * if (p_bayu != null) * { * foreach (AXRelation rel in p_bayu.relations) * { * p_bayu_client = rel.getRelatedTo(p_bayu); * p_bayu_client.intiateRipple_setFloatValueFromGUIChange(abayx); * } * } * * //bay_span_source.propagateParameterByBinding(1, bayx); * //bay_span_source.propagateParameterByBinding(2, bayy); * * // 2. re_generate with temporary values set by this Replicant * bay_span_source.generateOutputNow (makeGameObjects, parametricObject); * * // 3. Now that the bay_span_source has been regergrab the meshes from the input sources and add them here * AXParameter output_p = bay_span_source.getParameter("Output Mesh"); * foreach (AXMesh amesh in output_p.meshes) * ax_meshes_X.Add (amesh.Clone(amesh.transMatrix)); * * * * // Z-AXIS * // Use the bayz now to generate x * * if (p_bayu != null) * { * foreach (AXRelation rel in p_bayu.relations) * { * p_bayu_client = rel.getRelatedTo(p_bayu); * p_bayu_client.intiateRipple_setFloatValueFromGUIChange(abayz); * } * } * * //bay_span_source.propagateParameterByBinding(1, bayz); * * * // 2. re_generate with temporary values set by this Replicant * bay_span_source.generateOutputNow (makeGameObjects, parametricObject); * * // 3. Now that the bay_span_source has been regergrab the meshes from the input sources and add them here * foreach (AXMesh amesh in output_p.meshes) * ax_meshes_Z.Add (amesh.Clone(amesh.transMatrix)); * * * // 4. restore source object; as though we were never here! * bay_span_source.revertParametersFromCache(); * * //Debug.Log ("HAVE BAY SPAN -- " + output_p.meshes.Count); * * * } */ /* NEED TO INTEGRATE THIS BACK IN IN THE FUTRE... * if (cell_center_source != null) * { * // Y-AXIS * // For now, only set the boundaries. * // Perhaps later, may want to set other like controls as in Replicant * // 1. cache source object * cell_center_source.cacheParameterValues(); * * * * //bay_center_source.propagateParameterByBinding(1, bayx); * //bay_center_source.propagateParameterByBinding(3, bayz); * * // 2. re_generate with temporary values set by this Replicant * cell_center_source.generateOutputNow (makeGameObjects, parametricObject); * * // 3. Now that the bay_span_source has been regenerted, grab the meshes from the input sources and add them here * AXParameter bc_output_p = cell_center_source.getParameter("Output Mesh"); * foreach (AXMesh amesh in bc_output_p.meshes) * ax_meshes_Y.Add (amesh.Clone(amesh.transMatrix)); * * // 4. restore source object; as though we were never here! * cell_center_source.revertParametersFromCache(); * * } */ // BOUNDING List <AXMesh> boundingMeshes = new List <AXMesh>(); for (int i = 0; i <= cellsU; i++) { for (int k = 0; k <= cellsV; k++) { bool exclude = false; IntPoint ip = new IntPoint((i * actualBayU + shiftU) * AXGeometryTools.Utilities.IntPointPrecision, (k * actualBayV + shiftV) * AXGeometryTools.Utilities.IntPointPrecision); if (boundingSolids != null) { exclude = true; if (boundingSolids != null) { foreach (Path path in boundingSolids) { if (Clipper.PointInPolygon(ip, path) == 1 && Clipper.Orientation(path)) { exclude = false; break; } } } if (boundingHoles != null) { foreach (Path hole in boundingHoles) { if (Clipper.PointInPolygon(ip, hole) == 1) { exclude = true; break; } } } } exclude = (boundingIsVoid) ? !exclude : exclude; if (exclude) { continue; } // NODES if (nodeSrc_po != null && nodeSrc_p.meshes != null && ((i <= repeaterToolU.edgeCount || i >= cellsU - repeaterToolU.edgeCount) || (k <= repeaterToolV.edgeCount || k >= cellsV - repeaterToolV.edgeCount))) { string this_address = "node_" + i + "_" + k; // LOCAL PLACEMENT NODE localPlacement_mx = localNodeMatrixFromAddress(i, k); // AX_MESHES for (int mi = 0; mi < nodeSrc_p.meshes.Count; mi++) { AXMesh dep_amesh = nodeSrc_p.meshes [mi]; tmpMesh = dep_amesh.Clone(localPlacement_mx * dep_amesh.transMatrix); tmpMesh.subItemAddress = this_address; ax_meshes.Add(tmpMesh); } // BOUNDING boundingMeshes.Add(new AXMesh(nodeSrc_po.boundsMesh, localPlacement_mx * nodeSrc_po.generator.localMatrix)); // GAME_OBJECTS if (nodePlugGO != null && makeGameObjects && !parametricObject.combineMeshes) { Matrix4x4 mx = localPlacement_mx * nodeSrc_po.generator.localMatrixWithAxisRotationAndAlignment; GameObject copyGO = (GameObject)GameObject.Instantiate(nodePlugGO, AXUtilities.GetPosition(mx), AXUtilities.QuaternionFromMatrix(mx)); copyGO.transform.localScale = new Vector3(copyGO.transform.localScale.x * jitterScale.x, copyGO.transform.localScale.y * jitterScale.y, copyGO.transform.localScale.z * jitterScale.z); #if UNITY_EDITOR //if (parametricObject.model.isSelected(nodeSrc_po) && nodeSrc_po.selectedConsumerAddress == this_address) // Selection.activeGameObject = copyGO; #endif AXGameObject axgo = copyGO.GetComponent <AXGameObject>(); if (axgo != null) { axgo.consumerAddress = this_address; } copyGO.name = copyGO.name + "_" + this_address; copyGO.transform.parent = go.transform; } } // \NODES // CELL CENTERS if (cellSrc_po != null && cellSrc_p.meshes != null && i < cellsU && k < cellsV && ((i < repeaterToolU.edgeCount || i > cellsU - repeaterToolU.edgeCount - 1) || (k < repeaterToolV.edgeCount || k > cellsV - repeaterToolV.edgeCount - 1))) { string this_address = "cell_" + i + "_" + k; // LOCAL PLACEMENT localPlacement_mx = localCellMatrixFromAddress(i, k); // AX_MESHES for (int mi = 0; mi < cellSrc_p.meshes.Count; mi++) { AXMesh dep_amesh = cellSrc_p.meshes [mi]; tmpMesh = dep_amesh.Clone(localPlacement_mx * dep_amesh.transMatrix); tmpMesh.subItemAddress = this_address; ax_meshes.Add(tmpMesh); } // BOUNDING boundingMeshes.Add(new AXMesh(cellSrc_po.boundsMesh, localPlacement_mx * cellSrc_po.generator.localMatrix)); // GAME_OBJECTS if (cellPlugGO != null && makeGameObjects && !parametricObject.combineMeshes) { Matrix4x4 mx = localPlacement_mx * cellSrc_po.generator.localMatrixWithAxisRotationAndAlignment; GameObject copyGO = (GameObject)GameObject.Instantiate(cellPlugGO, AXUtilities.GetPosition(mx), AXUtilities.QuaternionFromMatrix(mx)); copyGO.transform.localScale = new Vector3(copyGO.transform.localScale.x * jitterScale.x, copyGO.transform.localScale.y * jitterScale.y, copyGO.transform.localScale.z * jitterScale.z); #if UNITY_EDITOR //if (parametricObject.model.isSelected(cellSrc_po) && cellSrc_po.selectedConsumerAddress == this_address) //Selection.activeGameObject = copyGO; #endif AXGameObject axgo = copyGO.GetComponent <AXGameObject>(); if (axgo != null) { axgo.consumerAddress = this_address; } copyGO.name = copyGO.name + "_" + this_address; copyGO.transform.parent = go.transform; } } // SPAN_U if (spanUSrc_po != null && spanUSrc_p.meshes != null && i < cellsU && k <= cellsV && ((i < repeaterToolV.edgeCount || i > cellsU - repeaterToolU.edgeCount - 1) || (k <= repeaterToolV.edgeCount || k > cellsV - repeaterToolV.edgeCount - 1))) { string this_address = "spanU_" + i + "_" + k; // LOCAL PLACEMENT SPAN_U localPlacement_mx = localSpanUMatrixFromAddress(i, k); // AX_MESHES for (int mi = 0; mi < spanUSrc_p.meshes.Count; mi++) { AXMesh dep_amesh = spanUSrc_p.meshes [mi]; tmpMesh = dep_amesh.Clone(localPlacement_mx * dep_amesh.transMatrix); tmpMesh.subItemAddress = this_address; ax_meshes.Add(tmpMesh); } // BOUNDING boundingMeshes.Add(new AXMesh(spanUSrc_po.boundsMesh, localPlacement_mx * spanUSrc_po.generator.localMatrix)); // GAME_OBJECTS if (spanUSrc_po != null && makeGameObjects && !parametricObject.combineMeshes) { Matrix4x4 mx = localPlacement_mx * spanUSrc_po.generator.localMatrixWithAxisRotationAndAlignment; GameObject copyGO = (GameObject)GameObject.Instantiate(spanUPlugGO, AXUtilities.GetPosition(mx), AXUtilities.QuaternionFromMatrix(mx)); copyGO.transform.localScale = new Vector3(copyGO.transform.localScale.x * jitterScale.x, copyGO.transform.localScale.y * jitterScale.y, copyGO.transform.localScale.z * jitterScale.z); #if UNITY_EDITOR //if (parametricObject.model.isSelected(spanUSrc_po) && spanUSrc_po.selectedConsumerAddress == this_address) // Selection.activeGameObject = copyGO; #endif AXGameObject axgo = copyGO.GetComponent <AXGameObject>(); if (axgo != null) { axgo.consumerAddress = this_address; } copyGO.name = copyGO.name + "_" + this_address; copyGO.transform.parent = go.transform; } } // SPAN_V if (spanVSrc_po != null && spanVSrc_p.meshes != null && i <= cellsU && k < cellsV && ((i <= repeaterToolU.edgeCount || i > cellsU - repeaterToolU.edgeCount - 1) || (k < repeaterToolV.edgeCount || k > cellsV - repeaterToolV.edgeCount - 1))) { string this_address = "spanV_" + i + "_" + k; // LOCAL PLACEMENT SPAN_U localPlacement_mx = localSpanVMatrixFromAddress(i, k); // AX_MESHES for (int mi = 0; mi < spanVSrc_p.meshes.Count; mi++) { AXMesh dep_amesh = spanVSrc_p.meshes [mi]; tmpMesh = dep_amesh.Clone(localPlacement_mx * dep_amesh.transMatrix); tmpMesh.subItemAddress = this_address; ax_meshes.Add(tmpMesh); } // BOUNDING boundingMeshes.Add(new AXMesh(spanVSrc_po.boundsMesh, localPlacement_mx * spanVSrc_po.generator.localMatrix)); // GAME_OBJECTS if (spanVSrc_po != null && makeGameObjects && !parametricObject.combineMeshes) { Matrix4x4 mx = localPlacement_mx * spanVSrc_po.generator.localMatrixWithAxisRotationAndAlignment; GameObject copyGO = (GameObject)GameObject.Instantiate(spanVPlugGO, AXUtilities.GetPosition(mx), AXUtilities.QuaternionFromMatrix(mx)); copyGO.transform.localScale = new Vector3(copyGO.transform.localScale.x * jitterScale.x, copyGO.transform.localScale.y * jitterScale.y, copyGO.transform.localScale.z * jitterScale.z); #if UNITY_EDITOR //if (parametricObject.model.isSelected(spanVSrc_po) && spanVSrc_po.selectedConsumerAddress == this_address) // Selection.activeGameObject = copyGO; #endif AXGameObject axgo = copyGO.GetComponent <AXGameObject>(); if (axgo != null) { axgo.consumerAddress = this_address; } copyGO.name = copyGO.name + "_" + this_address; copyGO.transform.parent = go.transform; } } } // k } //i GameObject.DestroyImmediate(nodePlugGO); GameObject.DestroyImmediate(cellPlugGO); GameObject.DestroyImmediate(spanUPlugGO); GameObject.DestroyImmediate(spanVPlugGO); // FINISH AX_MESHES parametricObject.finishMultiAXMeshAndOutput(ax_meshes, isReplica); // FINISH BOUNDS CombineInstance[] boundsCombinator = new CombineInstance[boundingMeshes.Count]; for (int bb = 0; bb < boundsCombinator.Length; bb++) { boundsCombinator[bb].mesh = boundingMeshes[bb].mesh; boundsCombinator[bb].transform = boundingMeshes[bb].transMatrix; } setBoundsWithCombinator(boundsCombinator); // FINISH GAME_OBJECTS if (makeGameObjects) { if (parametricObject.combineMeshes) { go = parametricObject.makeGameObjectsFromAXMeshes(ax_meshes, true); } Matrix4x4 tmx = parametricObject.generator.localMatrixWithAxisRotationAndAlignment; go.transform.rotation = AXUtilities.QuaternionFromMatrix(tmx); go.transform.position = AXUtilities.GetPosition(tmx); go.transform.localScale = parametricObject.getLocalScaleAxisRotated(); return(go); } return(null); }
// GENERATE PLAN_REPEATER public override GameObject generate(bool makeGameObjects, AXParametricObject initiator_po, bool renderToOutputParameter) { if (parametricObject == null || !parametricObject.isActive) { return(null); } //Debug.Log("yo ******* makeGameObjects="+makeGameObjects); // RESULTING MESHES ax_meshes = new List <AXMesh>(); paths_SubsplineIndices = new List <SubsplineIndices[]>(); preGenerate(); planSrc_p = P_Plan.DependsOn; // getUpstreamSourceParameter(P_Plan); planSrc_po = (planSrc_p != null) ? planSrc_p.parametricObject : null; //Debug.Log("planSrc_po = " + planSrc_po.Name+"."+planSrc_p.Name + " ... " + planSrc_p.DependsOn.PType + " ..... " + planSrc_p.getPaths()); P_Plan.polyTree = null; AXShape.thickenAndOffset(ref P_Plan, planSrc_p); if (P_Plan.reverse) { P_Plan.doReverse(); } planPaths = P_Plan.getPaths(); if (planPaths == null || planPaths.Count == 0) { return(null); } // ** CREATE PLAN_SPLINES ** if (planPaths != null && planPaths.Count > 0) { planSplines = new Spline[planPaths.Count]; if (planSplines != null) { for (int i = 0; i < planSplines.Length; i++) { planSplines[i] = new Spline(planPaths[i], (P_Plan.shapeState == ShapeState.Closed) ? true : false); } } } //Debug.Log("controlVertices="+ planSplines[0].controlVertices.Count); // CORNER_MESH GameObject cornerPlugGO = null; if (cornerSrc_p != null) { cornerSrc_po = cornerSrc_p.parametricObject; if (makeGameObjects && !parametricObject.combineMeshes) { cornerPlugGO = cornerSrc_po.generator.generate(true, initiator_po, renderToOutputParameter); } } // NODE_MESH GameObject nodePlugGO = null; if (nodeSrc_p != null) { nodeSrc_po = nodeSrc_p.parametricObject; //Debug.Log("yo makeGameObjects="+makeGameObjects+", parametricObject.combineMeshes="+parametricObject.combineMeshes); if (makeGameObjects && !parametricObject.combineMeshes) { nodePlugGO = nodeSrc_po.generator.generate(true, initiator_po, renderToOutputParameter); } } // CELL_MESH GameObject cellPlugGO = null; if (cellSrc_p != null) { cellSrc_po = cellSrc_p.parametricObject; if (makeGameObjects && !parametricObject.combineMeshes) { cellPlugGO = cellSrc_po.generator.generate(true, initiator_po, renderToOutputParameter); } } // Plan // This is the main spline used for the iteration //AXParameter plan_p = ip.DependsOn; // The section spline is used to provide the connective tissue around corners // SECTION // The plan may have multiple paths. Each may generate a separate GO. sectionSrc_p = P_Section.DependsOn; //getUpstreamSourceParameter(P_Section); sectionSrc_po = (sectionSrc_p != null) ? sectionSrc_p.parametricObject : null; if (sectionSrc_po != null) { P_Section.polyTree = null; AXShape.thickenAndOffset(ref P_Section, sectionSrc_p); if (P_Section.reverse) { P_Section.doReverse(); } } float bay_U = parametricObject.floatValue("bay_U"); float bay_V = parametricObject.floatValue("bay_V"); if (bay_U == 0) { bay_U = .1f; } if (bay_V == 0) { bay_V = 10f; } float margin_U = parametricObject.floatValue("margin_U"); Vector2 prevV = new Vector2(); //Vector3 scaler1 = Vector3.one; //float margin = 2.5f; Vector2 firstPM = new Vector2(); Vector2 prevVM = new Vector2(); AXSpline secSpline = null; AXSplineExtrudeGenerator tmpEXSP = null; if (sectionSrc_p != null && sectionSrc_p.spline != null && sectionSrc_p.spline.vertCount > 0) { secSpline = sectionSrc_p.spline; } tmpEXSP = new AXSplineExtrudeGenerator(); Material tmp_mat = parametricObject.axMat.mat; if (parametricObject.axTex != null) { tmpEXSP.uScale = parametricObject.axTex.scale.x; tmpEXSP.vScale = parametricObject.axTex.scale.y; tmpEXSP.uShift = -parametricObject.axTex.shift.x; tmpEXSP.vShift = parametricObject.axTex.shift.y; } float runningU = 0; //ip.spline.getAnglesArray(); //Spline sectionSpline = null; // = new Spline(sectionPath, sectionIsClosed, sec_p.breakGeom, sec_p.breakNorm); GameObject go = null; GameObject planGO = null; if (makeGameObjects && !parametricObject.combineMeshes) { go = ArchimatixUtils.createAXGameObject(parametricObject.Name, parametricObject); } // BOUNDING List <AXMesh> boundingMeshes = new List <AXMesh>(); // FOR EACH PATH for (int path_i = 0; path_i < planPaths.Count; path_i++) { if (makeGameObjects && !parametricObject.combineMeshes) { planGO = ArchimatixUtils.createAXGameObject(parametricObject.Name + "_" + path_i, parametricObject); } // **** PREPARE EACH SPLINE *** // Spline planSpline = planSplines[path_i]; planSpline.breakAngleCorners = cornerBreakAngle; planSpline.shapeState = P_Plan.shapeState; // Create subsplines between each break point planSpline.getSmoothSubsplineIndicies(0, maxSegmentLength); // ....... DEBUG //Pather.printPaths(planPaths); planSpline.groupNearBreakAngleVertices(inset * 2); if (planSpline.groupedCornerNodes == null || planSpline.groupedCornerNodes.Count == 0) { inset = 0; } // **** PREPARE EACH SPLINE *** // Matrix4x4 localPlacement_mx = Matrix4x4.identity; // INSET PLANSWEEPS GameObject plansweepGO = null; if (sectionSrc_p != null && inset > 0 && planSpline.insetSplines != null) { // convert planSpline.insetSplines to Paths Paths insetPaths = AXGeometryTools.Utilities.Splines2Paths(planSpline.insetSplines); AXParameter tmpPlanP = new AXParameter(); tmpPlanP.parametricObject = parametricObject; tmpPlanP.paths = insetPaths; tmpPlanP.Type = AXParameter.DataType.Shape; tmpPlanP.shapeState = ShapeState.Open; tmpPlanP.breakGeom = 0; if (planSpline.insetSplines.Count == 1) { tmpPlanP.shapeState = planSpline.insetSplines[0].shapeState; } topCap = false; botCap = false; plansweepGO = generateFirstPass(initiator_po, makeGameObjects, tmpPlanP, P_Section, Matrix4x4.identity, renderToOutputParameter, false); if (makeGameObjects && !parametricObject.combineMeshes && plansweepGO != null) { plansweepGO.transform.parent = go.transform; } } AXMesh tmpMesh = null; if (planSpline.insetSpanSplines != null && planSpline.insetSpanSplines.Count > 0) { //Debug.Log(".....????>> spanSpline.subsplines.Count="+ planSpline.insetSpanSplines.Count + " --- " + planSpline.subsplines.Count ); for (int si = 0; si < planSpline.insetSpanSplines.Count; si++) { planSpline.insetSpanSplines[si].setRepeaterTransforms(si, inset, bay); } // SPAN NODES - MESHES ALONG SUBSPLINES if (nodeSrc_p != null && nodeSrc_p.meshes != null) { //int endCount = (P_Plan != null && P_Plan.shapeState == ShapeState.Open) ? planSpline.subsplines.Count-1 : planSpline.subsplines.Count; int endCount = (P_Plan != null && P_Plan.shapeState == ShapeState.Open) ? planSpline.insetSpanSplines.Count - 1 : planSpline.insetSpanSplines.Count; for (int i = 0; i < endCount; i++) { //SubsplineIndices rsi = planSpline.subsplines[i]; Spline spanSpline = planSpline.insetSpanSplines[i]; //Debug.Log(i + "||||||||||> " + spanSpline.toString()); List <Matrix4x4> nodeMatrices = spanSpline.repeaterNodeTransforms; // on each of these nodes, place a nodePlug instance. bool spanNodesAtBreakCorners = true; int starter = (inset > 0 || spanNodesAtBreakCorners) ? 0 : 1; //Debug.Log("starter="+starter); int ender = (inset > 0 || spanSpline.shapeState == ShapeState.Open || planSpline.subsplines.Count == 1) ? nodeMatrices.Count : nodeMatrices.Count - 1; //Debug.Log("starter="+starter +", ender="+ender + ", nodeMatrices.Count=" + nodeMatrices.Count); //Debug.Log("(inset > 0 && spanNodesAtBreakCorners)="+(inset > 0 && spanNodesAtBreakCorners)+", nodeMatrices.Length="+nodeMatrices.Length+", starter="+starter+", ender="+ender); string this_address = ""; if (nodeMatrices != null) { for (int ii = starter; ii < ender; ii++) { this_address = "node_" + path_i + "_" + i + "_" + ii; //Debug.Log("this_address="+this_address); // LOCAL_PLACEMENT localPlacement_mx = localMatrixFromAddress(RepeaterItem.Node, path_i, i, ii); // AX_MESHES for (int mi = 0; mi < nodeSrc_p.meshes.Count; mi++) { AXMesh dep_amesh = nodeSrc_p.meshes [mi]; tmpMesh = dep_amesh.Clone(localPlacement_mx * dep_amesh.transMatrix); tmpMesh.subItemAddress = this_address; ax_meshes.Add(tmpMesh); } // BOUNDING boundingMeshes.Add(new AXMesh(nodeSrc_po.boundsMesh, localPlacement_mx * nodeSrc_po.generator.localMatrix)); //Debug.Log("boundingMeshes: " + boundingMeshes.Count); // GAME_OBJECTS if (nodePlugGO != null && makeGameObjects && !parametricObject.combineMeshes) { Matrix4x4 mx = localPlacement_mx * nodeSrc_po.generator.localMatrixWithAxisRotationAndAlignment; GameObject copyGO = (GameObject)GameObject.Instantiate(nodePlugGO, AXUtilities.GetPosition(mx), AXUtilities.QuaternionFromMatrix(mx)); Vector3 newJitterScale = jitterScale + Vector3.one; copyGO.transform.localScale = new Vector3(copyGO.transform.localScale.x * newJitterScale.x, copyGO.transform.localScale.y * newJitterScale.y, copyGO.transform.localScale.z * newJitterScale.z); copyGO.transform.localScale += jitterScale; AXGameObject axgo = copyGO.GetComponent <AXGameObject>(); if (axgo != null) { axgo.consumerAddress = this_address; //Debug.Log("ADD ADDRESS: " + this_address); } copyGO.name = copyGO.name + "_" + this_address; //Debug.Log("copyGO.name = "+copyGO.name); copyGO.transform.parent = planGO.transform; } } } } } // \NODE MESHES // CELL NODES - MESHES ALONG SUBSPLINES if (cellSrc_p != null && cellSrc_p.meshes != null) { //int endCount = (P_Plan != null && P_Plan.shapeState == ShapeState.Open) ? planSpline.subsplines.Count-1 : planSpline.subsplines.Count; int endCount = (P_Plan != null && P_Plan.shapeState == ShapeState.Open) ? planSpline.insetSpanSplines.Count - 1 : planSpline.insetSpanSplines.Count; for (int i = 0; i < endCount; i++) { //SubsplineIndices rsi = planSpline.subsplines[i]; Spline spanSpline = planSpline.insetSpanSplines[i]; spanSpline.setRepeaterTransforms(i, inset, bay); List <Matrix4x4> cellMatrices = spanSpline.repeaterCellTransforms; // on each of these cell, place a nodePlug instance. //bool spanNodesAtBreakCorners = true; int starter = 0; //spanNodesAtBreakCorners ? 0 : 1; //int ender = (inset > 0 || spanNodesAtBreakCorners) ? cellMatrices.Count : cellMatrices.Count-1; int ender = cellMatrices.Count; //Debug.Log("(inset > 0 && spanNodesAtBreakCorners)="+(inset > 0 && spanNodesAtBreakCorners)+", nodeMatrices.Length="+nodeMatrices.Length+", starter="+starter+", ender="+ender); string this_address = ""; if (cellMatrices != null) { for (int ii = starter; ii < ender; ii++) { // ADDRESS this_address = "cell_" + path_i + "_" + i + "_" + ii; // LOCAL_PLACEMENT localPlacement_mx = localMatrixFromAddress(RepeaterItem.Cell, path_i, i, ii); // AX_MESHES for (int mi = 0; mi < cellSrc_p.meshes.Count; mi++) { AXMesh dep_amesh = cellSrc_p.meshes [mi]; tmpMesh = dep_amesh.Clone(localPlacement_mx * dep_amesh.transMatrix); tmpMesh.subItemAddress = this_address; ax_meshes.Add(tmpMesh); } // BOUNDING boundingMeshes.Add(new AXMesh(cellSrc_po.boundsMesh, localPlacement_mx * cellSrc_po.generator.localMatrix)); // GAME_OBJECTS if (cellPlugGO != null && makeGameObjects && !parametricObject.combineMeshes) { Matrix4x4 mx = localPlacement_mx * cellSrc_po.generator.localMatrixWithAxisRotationAndAlignment; GameObject copyGO = (GameObject)GameObject.Instantiate(cellPlugGO, AXUtilities.GetPosition(mx), AXUtilities.QuaternionFromMatrix(mx)); Vector3 newJitterScale = jitterScale + Vector3.one; copyGO.transform.localScale = new Vector3(copyGO.transform.localScale.x * newJitterScale.x, copyGO.transform.localScale.y * newJitterScale.y, copyGO.transform.localScale.z * newJitterScale.z); copyGO.transform.localScale += jitterScale; AXGameObject axgo = copyGO.GetComponent <AXGameObject>(); if (axgo != null) { axgo.consumerAddress = this_address; //Debug.Log("ADD ADDRESS: " + this_address); } copyGO.name = copyGO.name + "_"; // + this_address; //Debug.Log("copyGO.name = "+copyGO.name); copyGO.transform.parent = planGO.transform; } } } } } // \CELL MESHES } // \each spanSpline // BREAK CORNER MESHES if (cornerSrc_p != null && cornerSrc_p.meshes != null) { for (int bi = 0; bi < planSpline.breakIndices.Count; bi++) { // ADDRESS string this_address = "corner_" + path_i + "_" + planSpline.breakIndices[bi]; // LOCAL_PLACEMENT localPlacement_mx = localMatrixFromAddress(RepeaterItem.Corner, path_i, planSpline.breakIndices[bi]); // AX_MESHES for (int mi = 0; mi < cornerSrc_p.meshes.Count; mi++) { AXMesh dep_amesh = cornerSrc_p.meshes [mi]; tmpMesh = dep_amesh.Clone(localPlacement_mx * dep_amesh.transMatrix); tmpMesh.subItemAddress = this_address; ax_meshes.Add(tmpMesh); } // BOUNDING boundingMeshes.Add(new AXMesh(cornerSrc_po.boundsMesh, localPlacement_mx * cornerSrc_po.generator.localMatrix)); // GAME_OBJECTS if (cornerPlugGO != null && makeGameObjects && !parametricObject.combineMeshes) { Matrix4x4 mx = localPlacement_mx * cornerSrc_po.generator.localMatrixWithAxisRotationAndAlignment; GameObject copyGO = (GameObject)GameObject.Instantiate(cornerPlugGO, AXUtilities.GetPosition(mx), AXUtilities.QuaternionFromMatrix(mx)); Vector3 newJitterScale = jitterScale + Vector3.one; copyGO.transform.localScale = new Vector3(copyGO.transform.localScale.x * newJitterScale.x, copyGO.transform.localScale.y * newJitterScale.y, copyGO.transform.localScale.z * newJitterScale.z); copyGO.transform.localScale += jitterScale; AXGameObject axgo = copyGO.GetComponent <AXGameObject>(); if (axgo != null) { axgo.consumerAddress = this_address; } copyGO.name = copyGO.name + "_" + this_address; copyGO.transform.parent = planGO.transform; } } } /* * int cells = Mathf.CeilToInt( md/bay_U ); * int nby = Mathf.CeilToInt( height/bay_V ); * * //Debug.Log ("d="+d+", md="+md); * * float actual_bayx = md/cells; * float actual_bayy = height/nby; * * // CREATE VERSIONS OF INPUT BAY_CENTER MESH(ES) USING BOUNDING BOX * // ****************************************************************************** * // someting similar shoud be added to griditerator, stepiterator, and where else? * * // instead of prev, would be better to create a dictionary of bounds and AXMeshes? * if (bay_span_p != null && (prevActuralBayx != actual_bayx || prevActuralBayx != actual_bayy)) * { * // regnerate the input meshes using actual_bayx * bay_span_p.Parent.setParameterValueByName("uScale", parametricObject.floatValue("uScale")); * bay_span_p.Parent.setParameterValueByName("vScale", parametricObject.floatValue("vScale")); * bay_span_p.Parent.setParameterValueByName("uShift", parametricObject.floatValue("uShift")); * bay_span_p.Parent.setParameterValueByName("vShift", parametricObject.floatValue("vShift")); * * //bay_span_p.Parent.generateOutputNow (makeGameObjects, parametricObject, true);//, new Vector3(actual_bayx, actual_bayy, margin_th)); * * } * // ****************************************************************************** * * * // CREATE VERSIONS OF INPUT BAY_CENTER MESH(ES) USING BOUNDING BOX * // ****************************************************************************** * // someting similar shoud be added to griditerator, stepiterator, and where else? * * // instead of prev, would be better to create a dictionary of bounds and AXMeshes? * if (node_p != null && (prevActuralBayx != actual_bayx || prevActuralBayx != actual_bayy)) * { * // regnerate the input meshes using actual_bayx * node_p.Parent.setParameterValueByName("uScale", parametricObject.floatValue("uScale")); * node_p.Parent.setParameterValueByName("vScale", parametricObject.floatValue("vScale")); * node_p.Parent.setParameterValueByName("uShift", parametricObject.floatValue("uShift")); * node_p.Parent.setParameterValueByName("vShift", parametricObject.floatValue("vShift")); * * //node_p.Parent.generateOutputNow (makeGameObjects, parametricObject, true);//, new Vector3(actual_bayx, actual_bayy, margin_th)); * * } * // ****************************************************************************** */ //margin_U = .5f; if (margin_U > 0 && planSpline.isClosed) { AXSpline connSpline2 = new AXSpline(); connSpline2.Push(prevVM); connSpline2.Push(prevV); connSpline2.Push(firstPM); connSpline2.isClosed = false; tmpEXSP.uShift = parametricObject.floatValue("uShift") + (runningU) / tmpEXSP.uScale; Mesh mesh = tmpEXSP.generate(connSpline2, secSpline); ax_meshes.Add(new AXMesh(mesh, Matrix4x4.identity, tmp_mat)); } if (makeGameObjects && !parametricObject.combineMeshes) { planGO.transform.parent = go.transform; } } // end paths //GameObject.DestroyImmediate(bay_spanPlugGO); GameObject.DestroyImmediate(cornerPlugGO); GameObject.DestroyImmediate(nodePlugGO); GameObject.DestroyImmediate(cellPlugGO); // FINISH AX_MESHES //Debug.Log("finish " + ax_meshes.Count); parametricObject.finishMultiAXMeshAndOutput(ax_meshes, renderToOutputParameter); // FINISH BOUNDS CombineInstance[] boundsCombinator = new CombineInstance[boundingMeshes.Count]; for (int bb = 0; bb < boundsCombinator.Length; bb++) { boundsCombinator[bb].mesh = boundingMeshes[bb].mesh; boundsCombinator[bb].transform = boundingMeshes[bb].transMatrix; } setBoundsWithCombinator(boundsCombinator); // FINISH GAME_OBJECTS if (makeGameObjects) { if (parametricObject.combineMeshes) { go = parametricObject.makeGameObjectsFromAXMeshes(ax_meshes, true); } Matrix4x4 tmx = parametricObject.getLocalMatrix(); go.transform.rotation = AXUtilities.QuaternionFromMatrix(tmx); go.transform.position = AXUtilities.GetPosition(tmx); go.transform.localScale = parametricObject.getLocalScaleAxisRotated(); //AXUtilities.GetScale(tmx); if (P_Plan.reverse) { P_Plan.doReverse(); } if (P_Section != null && P_Section.reverse) { P_Section.doReverse(); } return(go); } else { // Submit AXMeshes for realtime rendering //parametricObject.finishMultiAXMeshAndOutput(ax_meshes, renderToOutputParameter); //setBoundaryFromMeshes(ax_meshes); } if (P_Plan.reverse) { P_Plan.doReverse(); } if (P_Section != null && P_Section.reverse) { P_Section.doReverse(); } return(null); }
// GENERATE PHYSICS_JOINER public override GameObject generate(bool makeGameObjects, AXParametricObject initiator_po, bool isReplica) { if (toSrc_po == null || fromSrc_po == null) return null; if (parametricObject == null || ! parametricObject.isActive) return null; preGenerate(); // FROM_MESH GameObject fromPlugGO = null; if (fromSrc_p != null && fromSrc_po != null) { if (makeGameObjects && ! parametricObject.combineMeshes) fromPlugGO = fromSrc_po.generator.generate(true, initiator_po, isReplica); } // TO_MESH GameObject toPlugGO = null; if (toSrc_p != null && toSrc_po != null) { if (makeGameObjects && ! parametricObject.combineMeshes) toPlugGO = toSrc_po.generator.generate(true, initiator_po, isReplica); } // LIVE MESHES List<AXMesh> ax_meshes = new List<AXMesh>(fromSrc_p.meshes); if (toSrc_p != null) ax_meshes.AddRange(toSrc_p.meshes); List<AXMesh> boundingMeshes = new List<AXMesh>(); boundingMeshes.Add(new AXMesh(fromSrc_po.boundsMesh, fromSrc_po.generator.localMatrixWithAxisRotationAndAlignment)); if (toSrc_po != null) boundingMeshes.Add(new AXMesh(toSrc_po.boundsMesh, toSrc_po.generator.localMatrixWithAxisRotationAndAlignment)); // FINISH BOUNDS CombineInstance[] boundsCombinator = new CombineInstance[boundingMeshes.Count]; for(int bb=0; bb<boundsCombinator.Length; bb++) { boundsCombinator[bb].mesh = boundingMeshes[bb].mesh; boundsCombinator[bb].transform = boundingMeshes[bb].transMatrix; } setBoundsWithCombinator(boundsCombinator); GameObject go = null; if (toSrc_po != null && fromSrc_po != null) { if (makeGameObjects && ! parametricObject.combineMeshes) { go = ArchimatixUtils.createAXGameObject(parametricObject.Name, parametricObject); fromPlugGO.transform.parent = go.transform; toPlugGO.transform.parent = go.transform; // CONNECT RIGIDBODIES WITH FIXED_JOINT COMPONENT Rigidbody[] fromRBs = fromPlugGO.GetComponentsInChildren<Rigidbody>(); Rigidbody[] toRBs = toPlugGO.GetComponentsInChildren<Rigidbody>(); if (fromRBs != null && fromRBs.Length>0 && toRBs != null && toRBs.Length>0) { for(int i=0; i<toRBs.Length; i++) { FixedJoint fj = fromRBs[0].gameObject.AddComponent<FixedJoint>(); fj.connectedBody = toRBs[i]; fj.breakForce = breakForce; } } } } parametricObject.finishMultiAXMeshAndOutput(ax_meshes, isReplica); //GameObject.DestroyImmediate(fromPlugGO); return go; }
// GROUPER::GENERATE public override GameObject generate(bool makeGameObjects, AXParametricObject initiator_po, bool isReplica) { //if (ArchimatixUtils.doDebug) //Debug.Log (parametricObject.Name + " generate +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); if (!parametricObject.isActive) { return(null); } preGenerate(); GameObject go = null; if (makeGameObjects && !parametricObject.combineMeshes) { go = ArchimatixUtils.createAXGameObject(parametricObject.Name, parametricObject); } List <AXMesh> ax_meshes = new List <AXMesh>(); // BOUNDING List <AXMesh> boundingMeshes = new List <AXMesh>(); // Reinstate the original functionality of the Grouper as simple combiner in addition to Groupees. if (inputs != null && inputs.Count > 0) { // ALL if (channel == inputs.Count) { for (int i = 0; i < inputs.Count; i++) { if (inputs[i] != null && inputs[i].DependsOn != null) { if (inputs[i].Dependents != null || inputs[i].Dependents.Count == 0) { AXParameter src_p = inputs[i].DependsOn; AXParametricObject src_po = inputs[i].DependsOn.parametricObject; //if (! parametricObject.visited_pos.Contains (groupee)) //Debug.Log("groupee.generateOutputNow: " + groupee.Name + " isAltered="+groupee.isAltered); if (src_po.isAltered) { src_po.generateOutputNow(makeGameObjects, initiator_po); //Debug.Log("XXXXX: " + groupee.Output.meshes.Count); src_po.isAltered = false; parametricObject.model.AlteredPOs.Remove(src_po); } if (src_p != null && src_p.meshes != null) { for (int j = 0; j < src_p.meshes.Count; j++) { AXMesh dep_amesh = src_p.meshes [j]; ax_meshes.Add(dep_amesh.Clone(dep_amesh.transMatrix)); } } // BOUNDING MESHES //boundsCombinator[i].mesh = input_p.DependsOn.parametricObject.boundsMesh; //boundsCombinator[i].transform = input_p.DependsOn.parametricObject.generator.localMatrixWithAxisRotationAndAlignment; if (src_po.boundsMesh != null) { boundingMeshes.Add(new AXMesh(src_po.boundsMesh, src_po.generator.localMatrixWithAxisRotationAndAlignment)); } // GAME_OBJECTS if (makeGameObjects && !parametricObject.combineMeshes) { GameObject plugGO = src_po.generator.generate(true, initiator_po, isReplica); if (plugGO != null) { plugGO.transform.parent = go.transform; } } } } } } // JUST ONE CHANNEL else if (inputs.Count > channel && inputs[channel] != null) { AXParameter src_p = inputs[channel].DependsOn; if (src_p != null) { AXParametricObject src_po = src_p.parametricObject; if (src_po.is3D()) { if (src_po.Output != null && src_po.Output.meshes != null) { for (int j = 0; j < src_po.Output.meshes.Count; j++) { AXMesh dep_amesh = src_po.Output.meshes [j]; ax_meshes.Add(dep_amesh.Clone(dep_amesh.transMatrix)); } } // BOUNDING MESHES //boundsCombinator[i].mesh = input_p.DependsOn.parametricObject.boundsMesh; //boundsCombinator[i].transform = input_p.DependsOn.parametricObject.generator.localMatrixWithAxisRotationAndAlignment; if (src_po.boundsMesh != null) { boundingMeshes.Add(new AXMesh(src_po.boundsMesh, src_po.generator.localMatrixWithAxisRotationAndAlignment)); } // GAME_OBJECTS if (makeGameObjects && !parametricObject.combineMeshes) { GameObject plugGO = src_po.generator.generate(true, initiator_po, isReplica); if (plugGO != null) { plugGO.transform.parent = go.transform; } } } P_Output.meshes = src_p.meshes; } } // FINISH AX_MESHES //Debug.Log("ORG: " + ax_meshes.Count); parametricObject.finishMultiAXMeshAndOutput(ax_meshes, isReplica); // FINISH BOUNDS CombineInstance[] boundsCombinator = new CombineInstance[boundingMeshes.Count]; for (int bb = 0; bb < boundsCombinator.Length; bb++) { boundsCombinator[bb].mesh = boundingMeshes[bb].mesh; boundsCombinator[bb].transform = boundingMeshes[bb].transMatrix; } setBoundsWithCombinator(boundsCombinator); if (P_BoundsX != null && !P_BoundsX.hasRelations() && !P_BoundsX.hasExpressions()) { P_BoundsX.FloatVal = parametricObject.bounds.size.x; } if (P_BoundsY != null && !P_BoundsY.hasRelations() && !P_BoundsY.hasExpressions()) { P_BoundsY.FloatVal = parametricObject.bounds.size.y; } if (P_BoundsZ != null && !P_BoundsZ.hasRelations() && !P_BoundsZ.hasExpressions()) { P_BoundsZ.FloatVal = parametricObject.bounds.size.z; } } // FINISH GAME_OBJECTS if (makeGameObjects) { if (parametricObject.combineMeshes) { go = parametricObject.makeGameObjectsFromAXMeshes(ax_meshes, true, false); // COMBINE ALL THE MESHES CombineInstance[] combine = new CombineInstance[ax_meshes.Count]; int combineCt = 0; for (int i = 0; i < ax_meshes.Count; i++) { AXMesh _amesh = ax_meshes [i]; combine [combineCt].mesh = _amesh.mesh; combine [combineCt].transform = _amesh.transMatrix; combineCt++; } Mesh combinedMesh = new Mesh(); combinedMesh.CombineMeshes(combine); // If combine, use combined mesh as invisible collider MeshFilter mf = (MeshFilter)go.GetComponent(typeof(MeshFilter)); if (mf == null) { mf = (MeshFilter)go.AddComponent(typeof(MeshFilter)); } if (mf != null) { mf.sharedMesh = combinedMesh; parametricObject.addCollider(go); } } else { Matrix4x4 tmx = parametricObject.getLocalMatrix(); go.transform.rotation = AXUtilities.QuaternionFromMatrix(tmx); go.transform.position = AXUtilities.GetPosition(tmx); go.transform.localScale = parametricObject.getLocalScaleAxisRotated(); } return(go); } return(null); }
// GENERATE LINEAR_REPEATER public override GameObject generate(bool makeGameObjects, AXParametricObject initiator_po, bool isReplica) { //Debug.Log("repeaterToolU="+repeaterToolU+", repeaterToolV="+repeaterToolV); if (parametricObject == null || !parametricObject.isActive) { return(null); } if (repeaterTool == null) { return(null); } preGenerate(); // FLOOR_MESH (NODE_MESH) AXParametricObject nodeSrc_po = null; GameObject nodePlugGO = null; //Debug.Log("Get source"); if (nodeSrc_p != null) { nodeSrc_po = nodeSrc_p.parametricObject; if (makeGameObjects && !parametricObject.combineMeshes) { nodePlugGO = nodeSrc_po.generator.generate(true, initiator_po, isReplica); } } // STORY MESH (CELL_MESH) AXParametricObject storySrc_po = null; GameObject storyPlugGO = null; if (storySrc_p != null) { storySrc_po = storySrc_p.parametricObject; if (makeGameObjects && !parametricObject.combineMeshes) { storyPlugGO = storySrc_po.generator.generate(true, initiator_po, isReplica); } } // TOP_FLOOR AXParametricObject topSrc_po = null; GameObject topPlugGO = null; if (topSrc_p != null) { topSrc_po = topSrc_p.parametricObject; if (makeGameObjects && !parametricObject.combineMeshes) { topPlugGO = topSrc_po.generator.generate(true, initiator_po, isReplica); } } // BOTTOM_FLOOR AXParametricObject bottomSrc_po = null; GameObject bottomPlugGO = null; if (bottomSrc_p != null) { bottomSrc_po = bottomSrc_p.parametricObject; if (makeGameObjects && !parametricObject.combineMeshes) { bottomPlugGO = bottomSrc_po.generator.generate(true, initiator_po, isReplica); } } if (nodeSrc_po == null && storySrc_po == null && topSrc_po == null && bottomSrc_po == null) { if (P_Output != null) { P_Output.meshes = null; } return(null); } GameObject go = null; if (makeGameObjects && !parametricObject.combineMeshes) { go = ArchimatixUtils.createAXGameObject(parametricObject.Name, parametricObject); } List <AXMesh> ax_meshes = new List <AXMesh>(); Matrix4x4 localPlacement_mx = Matrix4x4.identity; // ----------------------------------- int max_reps = 150; int cellsU = Mathf.Clamp(repeaterTool.cells, 1, max_reps); float actualBayU = repeaterTool.actualBay; shiftU = -cellsU * actualBayU / 2; AXMesh tmpMesh; // BAY SPAN // Spanners are meshers that get replicated and sized to fit the bay... // prepare mesh to iterate in each direction // BOUNDING int boundingObjectCount = 0; if (nodeSrc_po != null && nodeSrc_p.meshes != null) { boundingObjectCount += cellsU + 1; if (!topFloor) { boundingObjectCount--; } if (!bottomFloor) { boundingObjectCount--; } } if (storySrc_p != null && storySrc_p.meshes != null) { boundingObjectCount += cellsU; if (!topStory) { boundingObjectCount--; } if (!bottomStory) { boundingObjectCount--; } } //Debug.Log(cellsU + " :::::: " + boundingObjectCount); CombineInstance[] boundsCombinator = new CombineInstance[boundingObjectCount]; int boundingCursor = 0; // LOOP for (int i = 0; i <= cellsU; i++) { // FLOORS (NODES) if ((i == 0 && bottomFloor) || (i == cellsU && topFloor) || (i > 0 && i < cellsU)) { AXParameter tmpSrc_p = nodeSrc_p; AXParametricObject tmpSrc_po = nodeSrc_po; GameObject tmpPlugGO = nodePlugGO; if (i == 0 && bottomSrc_p != null) { tmpSrc_p = bottomSrc_p; tmpSrc_po = bottomSrc_po; tmpPlugGO = bottomPlugGO; } else if (i == cellsU && topSrc_p != null) { tmpSrc_p = topSrc_p; tmpSrc_po = topSrc_po; tmpPlugGO = topPlugGO; } if (tmpSrc_po != null && tmpSrc_p.meshes != null) { string this_address = "node_" + i; localPlacement_mx = localNodeMatrixFromAddress(i); // AX_MESHES for (int j = 0; j < tmpSrc_p.meshes.Count; j++) { AXMesh dep_amesh = tmpSrc_p.meshes [j]; tmpMesh = dep_amesh.Clone(localPlacement_mx * dep_amesh.transMatrix); tmpMesh.subItemAddress = this_address; ax_meshes.Add(tmpMesh); } // BOUNDING MESHES boundsCombinator[boundingCursor].mesh = tmpSrc_po.boundsMesh; boundsCombinator[boundingCursor].transform = localPlacement_mx * tmpSrc_po.generator.localMatrixWithAxisRotationAndAlignment; boundingCursor++; // GAME_OBJECTS if (tmpPlugGO != null && makeGameObjects && !parametricObject.combineMeshes) { //Matrix4x4 mx = localPlacement_mx * parametricObject.getTransMatrix() * source.getTransMatrix(); //Debug.Log(nodeSrc_po.getLocalMatrix()); Matrix4x4 mx = localPlacement_mx * tmpSrc_po.generator.localMatrixWithAxisRotationAndAlignment; GameObject copyGO = (GameObject)GameObject.Instantiate(tmpPlugGO, AXUtilities.GetPosition(mx), AXUtilities.QuaternionFromMatrix(mx)); copyGO.transform.localScale = new Vector3(copyGO.transform.localScale.x * jitterScale.x, copyGO.transform.localScale.y * jitterScale.y, copyGO.transform.localScale.z * jitterScale.z); #if UNITY_EDITOR //if (parametricObject.model.isSelected(tmpSrc_po) && tmpSrc_po.selectedConsumerAddress == this_address) // Selection.activeGameObject = copyGO; #endif AXGameObject axgo = copyGO.GetComponent <AXGameObject>(); if (axgo != null) { axgo.consumerAddress = this_address; } copyGO.name = copyGO.name + "_" + this_address; copyGO.transform.parent = go.transform; } } // \NODES } // STORIES (CELLS) if ((i == 0 && bottomStory) || (i == cellsU - 1 && topStory) || (i > 0 && i < cellsU - 1)) { if (storySrc_p != null && storySrc_p.meshes != null && i < cellsU) { string this_address = "cell_" + i; // LOCAL_PLACEMENT localPlacement_mx = localCellMatrixFromAddress(i); // AX_MESHES for (int j = 0; j < storySrc_p.meshes.Count; j++) { AXMesh dep_amesh = storySrc_p.meshes [j]; tmpMesh = dep_amesh.Clone(localPlacement_mx * dep_amesh.transMatrix); tmpMesh.subItemAddress = this_address; ax_meshes.Add(tmpMesh); } // BOUNDING MESHES if (boundsCombinator.Length > boundingCursor) { boundsCombinator[boundingCursor].mesh = storySrc_po.boundsMesh; boundsCombinator[boundingCursor].transform = localPlacement_mx * storySrc_po.generator.localMatrixWithAxisRotationAndAlignment; boundingCursor++; } // GAME_OBJECTS if (storyPlugGO != null && makeGameObjects && !parametricObject.combineMeshes) { //Matrix4x4 mx = localPlacement_mx * parametricObject.getTransMatrix() * source.getTransMatrix(); Matrix4x4 mx = localPlacement_mx * storySrc_po.generator.localMatrixWithAxisRotationAndAlignment; GameObject copyGO = (GameObject)GameObject.Instantiate(storyPlugGO, AXUtilities.GetPosition(mx), AXUtilities.QuaternionFromMatrix(mx)); AXGameObject axgo = copyGO.GetComponent <AXGameObject>(); if (axgo != null) { axgo.consumerAddress = this_address; } copyGO.name = copyGO.name + "_" + this_address; copyGO.transform.parent = go.transform; } } // \ STORIES (CELLS) } } //i GameObject.DestroyImmediate(nodePlugGO); GameObject.DestroyImmediate(storyPlugGO); GameObject.DestroyImmediate(topPlugGO); GameObject.DestroyImmediate(bottomPlugGO); parametricObject.finishMultiAXMeshAndOutput(ax_meshes, isReplica); setBoundsWithCombinator(boundsCombinator); // Turn ax_meshes into GameObjects if (makeGameObjects) { if (parametricObject.combineMeshes) { go = parametricObject.makeGameObjectsFromAXMeshes(ax_meshes, true); } Matrix4x4 tmx = parametricObject.getLocalMatrix(); go.transform.rotation = AXUtilities.QuaternionFromMatrix(tmx); go.transform.position = AXUtilities.GetPosition(tmx); go.transform.localScale = parametricObject.getLocalScaleAxisRotated(); //AXUtilities.GetScale(tmx); return(go); } return(null); }
// GROUPER::GENERATE public override GameObject generate(bool makeGameObjects, AXParametricObject initiator_po, bool renderToOutputParameter) { //if (ArchimatixUtils.doDebug) //Debug.Log (parametricObject.Name + " generate +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); if (! parametricObject.isActive) return null; if (parametricObject.prefab == null) return null; preGenerate(); // MESHES FROM PREFAB List<AXMesh> ax_meshes = new List<AXMesh>(); Transform[] transforms = parametricObject.prefab.GetComponentsInChildren<Transform>(); //Debug.Log("transforms: " + transforms.Length); for(int i=0; i<transforms.Length; i++) { MeshFilter mf = transforms[i].gameObject.GetComponent<MeshFilter>(); Debug.Log("mf="+mf); if (mf != null) { Material mater = AXModel.defaultMaterial; Renderer renderer = transforms[i].gameObject.GetComponent<Renderer>(); if (renderer != null) mater = renderer.sharedMaterial; ax_meshes.Add (new AXMesh (mf.sharedMesh, transforms[i].localToWorldMatrix, mater)); } } //Debug.Log("ax_meshes: " + ax_meshes.Count); CombineInstance[] boundsCombinator = new CombineInstance[ax_meshes.Count]; int boundingCursor = 0; for(int i=0; i<ax_meshes.Count; i++) { boundsCombinator[boundingCursor].mesh = ax_meshes[i].mesh; boundsCombinator[boundingCursor].transform = ax_meshes[i].drawMeshMatrix;// localPlacement_mx * tmpSrc_po.generator.localMatrixWithAxisRotationAndAlignment; boundingCursor++; } setBoundsWithCombinator(boundsCombinator); parametricObject.finishMultiAXMeshAndOutput(ax_meshes, renderToOutputParameter); // GAME_OBJECTS if (makeGameObjects) { GameObject go = GameObject.Instantiate( parametricObject.prefab); Transform[] ntransforms = go.GetComponentsInChildren<Transform>(); for(int i=0; i<ntransforms.Length; i++) { ArchimatixUtils.AddAXGameObjectTo(parametricObject, ntransforms[i].gameObject); } //GameObject go = ArchimatixUtils.createAXGameObjectFromPrefab(parametricObject, parametricObject.prefab); Matrix4x4 tmx = parametricObject.getLocalMatrix(); //Debug.Log(tmx); go.transform.rotation = AXUtilities.QuaternionFromMatrix(tmx); go.transform.position = AXUtilities.GetPosition(tmx); go.transform.localScale = parametricObject.getLocalScaleAxisRotated(); return go; } return null; }
// DETAIL VIEW public void doDetailView() { GUIStyle shadowDown = new GUIStyle(); Texture2D bgTex = (Texture2D)AssetDatabase.LoadAssetAtPath(ArchimatixEngine.ArchimatixAssetPath + "/ui/Shadow.png", typeof(Texture2D)); shadowDown.normal.background = bgTex; if (EditorGUILayout.BeginFadeGroup(showDetailItem.faded)) { // DETAIL VIEW GUILayout.Space(15); GUILayout.BeginHorizontal(shadowDown, GUILayout.Height(18)); GUILayout.Label(" "); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); // LARGE THUMBNAIL string thumbnailPath = Path.ChangeExtension(detailItem.readIntoLibraryFromRelativeAXOBJPath, ".jpg"); string thumbnailRelativePath = ArchimatixUtils.getRelativeFilePath(thumbnailPath);; Texture2D tex = (Texture2D)AssetDatabase.LoadAssetAtPath(thumbnailRelativePath, typeof(Texture2D)); GUILayout.Label(tex, GUILayout.Width(256)); GUIStyle labelstyle = GUI.skin.GetStyle("Label"); GUIStyle buttonstyle = GUI.skin.GetStyle("Button"); GUILayout.Space(30); // DATA SHEET GUILayout.BeginVertical(); // NAME labelstyle.fontSize = 24; GUILayout.Label(detailItem.Name); labelstyle.fontSize = 10; if (editingDetailItem) { detailItem.author = GUILayout.TextField(detailItem.author); EditorGUILayout.LabelField("Tags"); detailItem.tags = GUILayout.TextField(detailItem.tags); // TAG CATEGORIES GUILayout.BeginHorizontal(); string tags = "," + detailItem.tags + ","; foreach (KeyValuePair <string, List <string> > kv in ArchimatixEngine.library.categories) { GUILayout.BeginVertical(); GUILayout.Label(kv.Key); foreach (string tag in kv.Value) { tags = "," + detailItem.tags + ","; //GUILayout.Label ("- "+tag); EditorGUI.BeginChangeCheck(); EditorGUILayout.ToggleLeft(tag, tags.Contains("," + tag + ","), GUILayout.Width(150)); if (EditorGUI.EndChangeCheck()) { if (tags.Contains(tag)) { tags = tags.Replace(("," + tag + ","), ","); } else { tags += tag; } detailItem.tags = tags.Trim(new Char[] { ' ', ',' }); } } GUILayout.EndVertical(); } GUILayout.EndHorizontal(); // TAG CATEGORIES GUILayout.FlexibleSpace(); buttonstyle.alignment = TextAnchor.MiddleCenter; GUILayout.BeginHorizontal(); if (GUILayout.Button("Cancel", GUILayout.Width(50))) { editingDetailItem = false; } if (GUILayout.Button("Save", GUILayout.Width(50))) { Debug.Log("Saving author as: " + detailItem.author); editingDetailItem = false; //library.saveParametricObjectMetadata(detailItem); } GUILayout.EndHorizontal(); buttonstyle.alignment = TextAnchor.UpperLeft; } else { // AUTHOR string author = (string.IsNullOrEmpty(detailItem.author)) ? "anonymous" : detailItem.author; GUILayout.BeginHorizontal(); labelstyle.alignment = TextAnchor.MiddleRight; GUILayout.Label("By: ", GUILayout.Width(50)); labelstyle.alignment = TextAnchor.MiddleLeft; GUILayout.Label(author); GUILayout.EndHorizontal(); if (string.IsNullOrEmpty(detailItem.tags)) { detailItem.tags = ""; } string tmpTags = detailItem.tags.Replace(",", ", "); GUILayout.BeginHorizontal(); labelstyle.alignment = TextAnchor.MiddleRight; GUILayout.Label("Tags: ", GUILayout.Width(50)); labelstyle.alignment = TextAnchor.MiddleLeft; if (tmpTags == null || tmpTags == "") { tmpTags = "none"; } GUILayout.Label(tmpTags); GUILayout.EndHorizontal(); GUILayout.FlexibleSpace(); buttonstyle.alignment = TextAnchor.MiddleCenter; if (GUILayout.Button("Edit", GUILayout.Width(50))) { editingDetailItem = true; } buttonstyle.alignment = TextAnchor.UpperLeft; } GUILayout.EndVertical(); GUILayout.EndHorizontal(); // bottom shadow Texture2D bgTexUp = (Texture2D)AssetDatabase.LoadAssetAtPath(ArchimatixEngine.ArchimatixAssetPath + "/ui/ShadowUp.png", typeof(Texture2D)); shadowDown.normal.background = bgTexUp; GUILayout.BeginHorizontal(shadowDown, GUILayout.Height(18)); GUILayout.Label(" "); GUILayout.EndHorizontal(); GUILayout.Space(15); } EditorGUILayout.EndFadeGroup(); }
// Supports the generation of runtime controllers for AXModels public static void createControllerButtonAction(AXModel model) { GameObject runtimeControllerGO = null; foreach (Transform child in model.transform) { if (child.name == "runtimeController") { runtimeControllerGO = child.gameObject; break; } } if (runtimeControllerGO == null) { // Create one runtimeControllerGO = new GameObject("runtimeController"); runtimeControllerGO.transform.parent = model.gameObject.transform; } string fullPath = ""; if (runtimeControllerGO != null) { AXRuntimeControllerBase runtimeController = runtimeControllerGO.GetComponent <AXRuntimeControllerBase>(); // 1. GET runctimeController filePath... if (runtimeController != null) { // 1A. GET FilePath from Component MonoScript ms = MonoScript.FromMonoBehaviour(runtimeController); string relativeAssetPath = AssetDatabase.GetAssetPath(ms.GetInstanceID()); fullPath = ArchimatixUtils.getAbsoluteLibraryPath(relativeAssetPath); } else { // 1B. Since a controller does not exist, we must create one from a tempalte, update it and the // let AX know that a new class will be available to add to the GameObject after scripts reload. // 1B.1. CREATE file based on a template... fullPath = EditorUtility.SaveFilePanel( "Save New Controller File", ArchimatixUtils.getAbsoluteLibraryPath("Assets"), "MyRuntimeController", "cs"); // 1B.2. LOCATE TEMPLATE file AXRuntimeControllerTemplate.cs DirectoryInfo info = new DirectoryInfo(Application.dataPath); FileInfo[] files = info.GetFiles("AXRuntimeControllerTemplate.cs", SearchOption.AllDirectories); string templateFilePath = ""; if (files != null && files.Length > 0) { templateFilePath = files[0].ToString(); } // 1B.3. COPY TEMPLATE to fullPath if (!string.IsNullOrEmpty(templateFilePath) && File.Exists(templateFilePath)) { File.Copy(templateFilePath, fullPath, true); } // 1B.4. REPLACE the classname string newClassName = System.IO.Path.GetFileNameWithoutExtension(fullPath); File.WriteAllText(fullPath, File.ReadAllText(fullPath).Replace("AXRuntimeControllerTemplate", newClassName)); // 1B.5. SET UP TO CONNECT CLASS TO GAMEOBJECT AFTER ALL SCRIPTS RELOAD // ArchimatixEngine will notice this on DidReloadAllScripts and add this class as a component to the runtimeControllerGO EditorPrefs.SetString("AddComponentByGameObjectIDAndClassname", (runtimeControllerGO.GetInstanceID() + "_" + newClassName)); } // 2. REWRITE the auto-generated region of the file // based on the model's exposed runtime parameters. if (File.Exists(fullPath)) { AXRuntimeEditor.updateControllerFile(fullPath, model); } // 3. Let the user know that this script writing // starts a Reload of all scripts EditorUtility.DisplayDialog("Reloading Scripts", "This may take a few seconds.", "Ok"); // 4. REFRESH DB - This is asynchronous and will reload all scripts. AssetDatabase.Refresh(); } }
public override GameObject generate(bool makeGameObjects, AXParametricObject initiator_po, bool isReplica) { if (parametricObject == null || !parametricObject.isActive) { return(null); } if (P_PrototypePlan == null || P_Prototype == null) { return(null); } preGenerate(); // PLAN planSrc_p = P_Plan.DependsOn; // getUpstreamSourceParameter(P_Plan); planSrc_po = (planSrc_p != null) ? planSrc_p.parametricObject : null; P_Plan.polyTree = null; AXShape.thickenAndOffset(ref P_Plan, planSrc_p); planPaths = P_Plan.getPaths(); if (planPaths == null || planPaths.Count == 0) { return(null); } prototypePlanSrc_p = P_PrototypePlan.DependsOn; prototypePlanSrc_po = (prototypePlanSrc_p != null) ? prototypePlanSrc_p.parametricObject : null; prototypeSrc_p = P_Prototype.DependsOn; prototypePlanSrc_po = (prototypeSrc_p != null) ? prototypeSrc_p.parametricObject : null; if (prototypePlanSrc_p == null || prototypePlanSrc_po == null || prototypeSrc_po == null) { return(null); } AXParameter srcSrc_p = prototypePlanSrc_p.DependsOn; if (srcSrc_p == null) { return(null); } // AX_MESHES List <AXMesh> ax_meshes = new List <AXMesh>(); GameObject go = null; if (makeGameObjects && !parametricObject.combineMeshes) { go = ArchimatixUtils.createAXGameObject(parametricObject.Name, parametricObject); } Perlin perlin = new Perlin(); perlin.OctaveCount = 1; perlin.Frequency = .05f; GameObject replicant = null; foreach (Path plan in planPaths) { // 1. cache source object //prototypeSrc_po.cacheParameterValues(); Paths tmpPaths = new Paths(); tmpPaths.Add(plan); IntPoint planCenter = AXGeometryTools.Utilities.getCenter(tmpPaths); Vector3 centerPt = AXGeometryTools.Utilities.IntPt2Vec3(planCenter); //Debug.Log("Center: " + centerPt); srcSrc_p.paths = tmpPaths; float area = ((float)Clipper.Area(plan)) / 1000000000; //Debug.Log(area); float perlinVal = (float)perlin.GetValue(centerPt); float h = 3 + 100 * (float)Math.Exp(-(.1f * area)) + 5 * perlinVal; // (float) perlin.GetValue(2,3,4); AXParameter sHeight = prototypeSrc_po.getParameter("Height"); sHeight.initiateRipple_setFloatValueFromGUIChange(h); prototypeSrc_po.generator.pollControlValuesFromParmeters(); prototypeSrc_po.isAltered = true; replicant = prototypeSrc_po.generateOutputNow(makeGameObjects, parametricObject, true); if (replicant != null) { replicant.transform.parent = go.transform; } AXParameter output_p = prototypeSrc_po.getParameter("Output Mesh"); foreach (AXMesh amesh in output_p.meshes) { ax_meshes.Add(amesh.Clone(amesh.transMatrix)); } } // FINISH AX_MESHES parametricObject.finishMultiAXMeshAndOutput(ax_meshes, isReplica); if (makeGameObjects) { return(go); } return(null); }
// return the height of this gui area public static int OnGUI(Rect pRect, AXNodeGraphEditorWindow editor, AXParameter p) { Event e = Event.current; if (Event.current.type == EventType.KeyUp) { if (p != null && !GUI.GetNameOfFocusedControl().Contains("logicTextArea_")) { p.parametricObject.model.autobuildDelayed(1000); } } int hgt = (int)pRect.height; float foldoutWidth = 20; float boxWidth = pRect.width - foldoutWidth - ArchimatixUtils.indent; float cur_x = ArchimatixUtils.cur_x; float box_w = ArchimatixUtils.paletteRect.width - cur_x - 3 * ArchimatixUtils.indent; int cur_y = (int)pRect.y; Color inactiveColor = new Color(.7f, .7f, .7f); Color oldBackgroundColor = GUI.backgroundColor; Color dataColor = editor.getDataColor(p.Type); if (!EditorGUIUtility.isProSkin) { dataColor = new Color(dataColor.r, dataColor.b, dataColor.g, .3f); } GUI.color = dataColor; Rect boxRect = new Rect(cur_x + ArchimatixUtils.indent, cur_y, box_w, ArchimatixUtils.lineHgt); GUI.Box(boxRect, " "); GUI.Box(boxRect, " "); GUI.color = Color.white; int margin = 24; float x0 = pRect.x + 14; float xTF = pRect.x + 12; float wid = pRect.width - margin; int indent = (int)x0 + 2; int lineHgt = 16; int gap = 2; if (p.isEditing) { hgt *= 5; hgt += 8; GUI.Box(new Rect(pRect.x - 6, pRect.y - 3, boxWidth, lineHgt * (8 + p.expressions.Count)), GUIContent.none); } if (p.Parent == null) { return(0); } if (p.Parent != null && p.to_delete == true) { p.Parent.removeParameter(p); return(0); } Color defcolor = GUI.color; // input/ouput sockets GUI.backgroundColor = dataColor; // INPUT SOCKET string buttonLabel = null; Rect buttonRect; if (p.isEditing || p.hasInputSocket) { if (p.isEditing && !p.hasInputSocket) { GUI.color = new Color(defcolor.r, defcolor.g, defcolor.b, .3f); } buttonLabel = (editor.InputParameterBeingDragged == p) ? "-" : ""; buttonRect = new Rect(-3, pRect.y, ArchimatixEngine.buttonSize, ArchimatixEngine.buttonSize); // button color if (editor.OutputParameterBeingDragged != null) { if (editor.OutputParameterBeingDragged.Type != p.Type) { GUI.backgroundColor = inactiveColor; } else if (buttonRect.Contains(Event.current.mousePosition)) { GUI.backgroundColor = Color.white; } } else if (editor.InputParameterBeingDragged != null) { if (editor.InputParameterBeingDragged == p) { GUI.backgroundColor = Color.white; } else { GUI.backgroundColor = inactiveColor; } } // Input Button if (editor.OutputParameterBeingDragged != null && (editor.OutputParameterBeingDragged.parametricObject == p.parametricObject || editor.OutputParameterBeingDragged.Type != p.Type)) { GUI.enabled = false; } if (GUI.Button(buttonRect, buttonLabel)) { if (p.isEditing) { p.hasOutputSocket = (!p.hasOutputSocket); } else { if (Event.current.command) { Debug.Log("CONTEXT"); } else if (editor.OutputParameterBeingDragged != null && editor.OutputParameterBeingDragged.Type != p.Type) { editor.OutputParameterBeingDragged = null; } else { editor.inputSocketClicked(p); } } } GUI.enabled = true; } GUI.backgroundColor = editor.getDataColor(p.Type); GUI.color = defcolor; // INPUT SOCKET // OUTPUT SOCKET if (p.isEditing || p.hasOutputSocket) { if (p.isEditing && !p.hasOutputSocket) { GUI.color = new Color(defcolor.r, defcolor.g, defcolor.b, .3f); } buttonLabel = (editor.OutputParameterBeingDragged == p) ? "-" : ""; buttonRect = new Rect(p.Parent.rect.width - pRect.height + 3, pRect.y, ArchimatixEngine.buttonSize, ArchimatixEngine.buttonSize); // button color if (editor.InputParameterBeingDragged != null) { if (editor.InputParameterBeingDragged.Type != p.Type) { GUI.backgroundColor = inactiveColor; } else if (buttonRect.Contains(Event.current.mousePosition)) { GUI.backgroundColor = Color.white; } } else if (editor.OutputParameterBeingDragged != null) { if (editor.OutputParameterBeingDragged == p) { GUI.backgroundColor = Color.white; } else { GUI.backgroundColor = inactiveColor; } } // Output Button if (editor.InputParameterBeingDragged != null && (editor.InputParameterBeingDragged.parametricObject == p.parametricObject || editor.InputParameterBeingDragged.Type != p.Type)) { GUI.enabled = false; } if (GUI.Button(buttonRect, buttonLabel)) { if (p.isEditing) { p.hasOutputSocket = (!p.hasOutputSocket); } else { if (Event.current.control) { // DISPLAY CONTEXT MENU FOR THINGS YOU CAN USE THIS OUTPUT FOR Debug.Log("context"); //model.selectPO(parametricObject); MeshOuputMenu.contextMenu(p, e.mousePosition); e.Use(); } else if (editor.InputParameterBeingDragged != null && editor.InputParameterBeingDragged.Type != p.Type) { editor.InputParameterBeingDragged = null; } else { editor.outputSocketClicked(p); } } } GUI.enabled = true; } GUI.color = defcolor; // OUTPUT SOCKET // SLIDER AND NUMBER FIELD Rect nameLabelRect = new Rect(x0, pRect.y, wid - 30, 16); Rect cntlRect = new Rect(x0, pRect.y, wid, 16); //Rect boxRect = new Rect(xb, pRect.y+vMargin, boxWidth, pRect.height-vMargin*2); /* * if (hasInputSocket && ! hasOutputSocket) * boxRect = new Rect(xb, pRect.y+vMargin, inputwid, pRect.height-vMargin*2); * else if(! hasInputSocket && hasOutputSocket) * boxRect = new Rect(xb+x_output, pRect.y+vMargin, inputwid+4, pRect.height-vMargin*2); */ Rect textFieldRect = new Rect(xTF + 3, pRect.y, wid - 60, pRect.height + 2); // -- DON'T USE PROPERTY DRAWER TO HANDLE UNDO WITH SLIDER // we need o get the updated value atomically, which the propertydrawer does not seem to do (slower update) // BINDING HIGHLIGHT BACKGROUND BOX //Handles.yAxisColor; //GUI.color = Handles.yAxisColor; /* * if (p.sizeBindingAxis > 0) * { * switch(p.sizeBindingAxis) * { * case Axis.X: * GUI.color = Handles.xAxisColor; break; * case Axis.Y: * GUI.color = Handles.yAxisColor; break; * case Axis.Z: * GUI.color = Handles.zAxisColor; break; * * } * * GUI.Box (new Rect(boxRect.x-m, boxRect.y-m, boxRect.width+4*m, boxRect.height+2*m), GUIContent.none); * GUI.Box (new Rect(boxRect.x-m, boxRect.y-m, boxRect.width+4*m, boxRect.height+2*m), GUIContent.none); * GUI.Box (new Rect(boxRect.x-m, boxRect.y-m, boxRect.width+4*m, boxRect.height+2*m), GUIContent.none); * GUI.Box (new Rect(boxRect.x-m, boxRect.y-m, boxRect.width+4*m, boxRect.height+2*m), GUIContent.none); * GUI.Box (new Rect(boxRect.x-m, boxRect.y-m, boxRect.width+4*m, boxRect.height+2*m), GUIContent.none); * GUI.Box (new Rect(boxRect.x-m, boxRect.y-m, boxRect.width+4*m, boxRect.height+2*m), GUIContent.none); * } */ /* * if (EditorGUIUtility.isProSkin) * GUI.color = new Color(defcolor.r, defcolor.b, defcolor.g, 1f); * else * GUI.color = new Color(defcolor.r, defcolor.b, defcolor.g, .4f); * * GUI.Box (boxRect, GUIContent.none); * GUI.color = defcolor; * * if (EditorGUIUtility.isProSkin) * { * GUI.Box (boxRect, GUIContent.none); * GUI.Box (boxRect, GUIContent.none); * if (p.Parent.model.isSelected(p.Parent)) * GUI.Box (boxRect, GUIContent.none); * } */ // BINDING HIGHLIGHT BACKGROUND BOX // PROPERTYDRAWER //EditorGUI.PropertyField(pRect, pProperty); //OR... GUIStyle labelstyle = GUI.skin.GetStyle("Label"); labelstyle.alignment = TextAnchor.MiddleLeft; GUIStyle buttonstyle = GUI.skin.GetStyle("Button"); buttonstyle.alignment = TextAnchor.MiddleLeft; // NAME string nameString = p.Name; // + "_" + Guid; if (p.PType == AXParameter.ParameterType.Input) { labelstyle.alignment = TextAnchor.MiddleLeft; labelstyle.fixedWidth = boxRect.width - 10; GUI.Label(nameLabelRect, nameString); } else if (p.PType == AXParameter.ParameterType.Output) { labelstyle.alignment = TextAnchor.MiddleRight; labelstyle.fixedWidth = boxRect.width - 10; GUI.Label(nameLabelRect, nameString); } else if ((p.hasInputSocket && !p.hasOutputSocket)) { labelstyle.alignment = TextAnchor.MiddleLeft; if (p.Parent.isEditing) { GUI.Label(nameLabelRect, nameString); } else { GUI.Label(nameLabelRect, nameString); } } else if (p.PType == AXParameter.ParameterType.Output) //(!hasInputSocket && hasOutputSocket) { labelstyle.alignment = TextAnchor.MiddleRight; if (p.Parent.isEditing) { GUI.Label(nameLabelRect, nameString + " .... "); } else { GUI.Label(cntlRect, nameString); } } else if (p.Type == AXParameter.DataType.Plane) { labelstyle.alignment = TextAnchor.MiddleRight; if (p.Parent.isEditing) { GUI.Label(nameLabelRect, nameString); } else { GUI.Label(cntlRect, nameString); } } else if (p.Type == AXParameter.DataType.MaterialTool) { labelstyle.alignment = TextAnchor.MiddleLeft; if (p.Parent.isEditing) { GUI.Label(nameLabelRect, nameString); } else { GUI.Label(cntlRect, nameString); } } else if ((p.hasInputSocket && p.hasOutputSocket)) { EditorGUIUtility.fieldWidth = wid / 3.2f; //36; EditorGUIUtility.labelWidth = wid - EditorGUIUtility.fieldWidth; GUI.backgroundColor = Color.white; EditorGUI.BeginChangeCheck(); p.isOpen = EditorGUI.Foldout(new Rect(pRect.x, cur_y, 20, lineHgt), p.isOpen, ""); if (EditorGUI.EndChangeCheck()) { if (p.isOpen) { foreach (AXParameter pop in p.parametricObject.parameters) { if (pop != p) { pop.isOpen = false; } } } } if (p.isOpen) { // NAME GUI.SetNextControlName("ParameterName_Text_NameField" + p.Guid + "_" + p.Name); p.Name = EditorGUI.TextField(textFieldRect, p.Name); if (p.shouldFocus) { GUI.FocusControl("ParameterName_Text_NameField" + p.Guid + "_" + p.Name); p.shouldFocus = false; } // DELETE PARAMETER if (GUI.Button(new Rect(pRect.width - 2 * lineHgt * 1.5f, cur_y - 1, lineHgt * 1.25f, lineHgt), "-")) { //Debug.Log("remove..."); p.parametricObject.removeParameter(p); //p.expressions.RemoveAt(i); } // MOVE PARAMETER UP if (GUI.Button(new Rect(pRect.width - lineHgt * 1.5f, cur_y - 1, lineHgt * 1.25f, lineHgt), "^")) { //Debug.Log("remove..."); p.parametricObject.moveParameterUp(p); //p.expressions.RemoveAt(i); } cur_y += lineHgt + gap * 3; GUI.Box(new Rect((x0 - 4), cur_y - 4, (pRect.width - 20), ((6 + p.expressions.Count) * lineHgt)), " "); // DATA_TYPE //EditorGUI.PropertyField( new Rect((textFieldRect.x+textFieldRect.width)+6, textFieldRect.y, 60, 22), pProperty.FindPropertyRelative("m_type"), GUIContent.none); //EditorGUI.PropertyField( new Rect((textFieldRect.x+textFieldRect.width)+6, textFieldRect.y, 60, 22), m_type, GUIContent.none); //Rect rec = new Rect((textFieldRect.x+textFieldRect.width)+6, textFieldRect.y, 60, 22); Rect rec = new Rect(x0, cur_y, 60, 22); //m_type = (DataType) EditorGUI.EnumPopup(rec, m_type, "YUP"); string dataType_menu = "Float|Int|Bool|String"; string[] dataType_options = dataType_menu.Split('|'); EditorGUI.BeginChangeCheck(); int typeOption = (int)p.Type; if (typeOption == (int)AXParameter.DataType.String) { typeOption = 3; } typeOption = (int)EditorGUI.Popup( rec, "", typeOption, dataType_options); if (EditorGUI.EndChangeCheck()) { Undo.RegisterCompleteObjectUndo(p.parametricObject.model, "Parameter Type"); p.Type = (AXParameter.DataType)typeOption; if (p.Type == AXParameter.DataType.Spline) { p.Type = AXParameter.DataType.String; } } cur_y += lineHgt + gap * 3; // EXPOSE AS RUNTIME Interface ------------ //EditorGUIUtility.labelWidth = wid-36; cntlRect = new Rect(x0, cur_y, wid, 16); EditorGUI.BeginChangeCheck(); p.exposeAsInterface = EditorGUI.Toggle(cntlRect, "Expose", p.exposeAsInterface); if (EditorGUI.EndChangeCheck()) { Undo.RegisterCompleteObjectUndo(p.parametricObject.model, "Expose Parameter"); if (p.exposeAsInterface) { p.parametricObject.model.addExposedParameter(p); } else { p.parametricObject.model.removeExposedParameter(p); } } cur_y += lineHgt + gap; /* * if (p.Type == AXParameter.DataType.Float) * { * EditorGUI.BeginChangeCheck (); * * //EditorGUIUtility.labelWidth = 20; * GUI.backgroundColor = Color.white; * GUI.Label(new Rect(indent, cur_y, 200,16), "Bind externally in: "); * p.sizeBindingAxis = EditorGUI.Popup( * new Rect((textFieldRect.x+textFieldRect.width)+6, cur_y, 60,16), * "", * p.sizeBindingAxis, * new string[] { * "None", * "X", * "Y", * "Z" * }); * if (EditorGUI.EndChangeCheck ()) { * Undo.RegisterCompleteObjectUndo (p.parametricObject.model, "Size bind Axis"); * Debug.Log ("sizeBindingAxis changed to "+p.sizeBindingAxis ); * * } * cur_y += lineHgt; * } */ // STRING if (p.Type == AXParameter.DataType.String) { p.StringVal = EditorGUI.TextField(new Rect(indent, cur_y, wid - 10, lineHgt), p.StringVal); cur_y += lineHgt; } // NUMBER else if (p.Type == AXParameter.DataType.Float || (p.Type == AXParameter.DataType.Int)) { GUI.Label(new Rect(indent, cur_y, 200, 16), new GUIContent("Expressions", "When the value of this parameter changes, define its effect on other paramters with mathematical descriptions using this parameter.")); cur_y += lineHgt; // expressions if (p.expressions == null) { p.expressions = new List <string>(); } if (p.expressions.Count == 0) { p.expressions.Add(""); } for (int i = 0; i < p.expressions.Count; i++) { GUI.SetNextControlName("ParameterExpression_" + i + "_Text_" + p.Guid + "_" + p.Name); p.expressions[i] = EditorGUI.TextField(new Rect(indent, cur_y, wid - 30, lineHgt), p.expressions[i]); if (GUI.Button(new Rect(pRect.width - lineHgt * 1.5f, cur_y - 1, lineHgt * 1.25f, lineHgt), "-")) { p.expressions.RemoveAt(i); } cur_y += lineHgt + gap * 2; } if (GUI.Button(new Rect(pRect.width - lineHgt * 1.5f, cur_y, lineHgt * 1.25f, lineHgt), new GUIContent("+", "Add an expression to this Parameter"))) { p.expressions.Add(""); } cur_y += lineHgt; } cur_y += lineHgt; // DONE if (GUI.Button(new Rect((wid - 30 - lineHgt * 1.5f), cur_y - 1, 50, pRect.height), "Done")) { p.isOpen = false; p.shouldFocus = false; AXEditorUtilities.clearFocus(); } // MOVE PARAMETER UP if (GUI.Button(new Rect(pRect.width - lineHgt * 1.5f, cur_y - 1, lineHgt * 1.25f, lineHgt), "v")) { //Debug.Log("remove..."); p.parametricObject.moveParameterDown(p); //p.expressions.RemoveAt(i); } cur_y += lineHgt; } else // (not open) { // NOT EDITING, RATHER USING string bindingLabel = ""; switch (p.sizeBindingAxis) { case Axis.X: bindingLabel = " [X]"; break; case Axis.Y: bindingLabel = " [Y]"; break; case Axis.Z: bindingLabel = " [Z]"; break; } switch (p.Type) { case AXParameter.DataType.AnimationCurve: GUILayout.BeginArea(new Rect(indent, cur_y, wid - 10, 2 * lineHgt)); EditorGUI.BeginChangeCheck(); EditorGUILayout.CurveField(p.animationCurve); if (EditorGUI.EndChangeCheck()) { Undo.RegisterCompleteObjectUndo(p.parametricObject.model, "ModifierCurve"); p.parametricObject.model.isAltered(28); } GUILayout.EndArea(); break; case AXParameter.DataType.Float: // FLOAT SLIDER if (p.PType != AXParameter.ParameterType.DerivedValue) { // VALIDATE INPUT - IF INVALID >> LOSE FOCUS AXEditorUtilities.assertFloatFieldKeyCodeValidity("FloatField_Text_FloatField_" + p.Name); EditorGUI.BeginChangeCheck(); GUI.SetNextControlName("FloatField_Text_" + p.Guid + "_" + p.Name); p.val = EditorGUI.FloatField(cntlRect, nameString + bindingLabel, p.val); if (EditorGUI.EndChangeCheck()) { //Debug.Log(val); Undo.RegisterCompleteObjectUndo(p.Parent.model, "value change for " + p.Name); p.Parent.initiateRipple_setFloatValueFromGUIChange(p.Name, p.val); p.parametricObject.model.isAltered(27); p.parametricObject.generator.adjustWorldMatrices(); } } else { Rect labelRect = cntlRect; labelRect.width = cntlRect.width - 25; GUI.Label(labelRect, p.Name); GUI.Label(new Rect(cntlRect.width - 10, cntlRect.y, 18, cntlRect.height), "" + p.val); } if (p.shouldFocus) { GUI.FocusControl("FloatField_Text_" + p.Guid + "_" + p.Name); p.shouldFocus = false; } break; case AXParameter.DataType.Int: { // INT SLIDER // VALIDATE INPUT - IF INVALID >> LOSE FOCUS /* * if (Event.current.type == EventType.KeyDown) * { * if(Event.current.keyCode != KeyCode.None && !AXEditorUtilities.isValidIntFieldKeyCode(Event.current.keyCode) && GUI.GetNameOfFocusedControl() == ("IntField_" + p.Name)) * { * Event.current.Use(); * GUI.FocusControl("dummy_label"); * } * } */ AXEditorUtilities.assertIntFieldKeyCodeValidity("IntField_" + p.Name); EditorGUI.BeginChangeCheck(); GUI.SetNextControlName("IntField_" + p.Guid + "_" + p.Name); p.intval = EditorGUI.IntField(cntlRect, nameString, p.intval); if (EditorGUI.EndChangeCheck()) { Undo.RegisterCompleteObjectUndo(p.Parent.model, "value change for " + p.Name); p.initiateRipple_setIntValueFromGUIChange(p.intval); p.parametricObject.model.isAltered(28); p.parametricObject.generator.adjustWorldMatrices(); } break; } case AXParameter.DataType.Bool: { EditorGUIUtility.labelWidth = wid - 16; EditorGUI.BeginChangeCheck(); GUI.SetNextControlName("BoolToggle_" + p.Guid + "_" + p.Name); p.boolval = EditorGUI.Toggle(cntlRect, nameString, p.boolval); if (EditorGUI.EndChangeCheck()) { Undo.RegisterCompleteObjectUndo(p.Parent.model, "value change for " + p.Name); p.parametricObject.initiateRipple_setBoolParameterValueByName(p.Name, p.boolval); p.parametricObject.model.autobuild(); p.parametricObject.generator.adjustWorldMatrices(); } break; } case AXParameter.DataType.String: labelstyle.alignment = TextAnchor.MiddleLeft; if (p.Parent.isEditing) { GUI.Label(nameLabelRect, nameString); } else { GUI.Label(nameLabelRect, nameString); } break; case AXParameter.DataType.Option: { // OPTION POPUP string[] options = ArchimatixUtils.getMenuOptions(p.Name); EditorGUIUtility.labelWidth = wid - 50; EditorGUI.BeginChangeCheck(); GUI.SetNextControlName("OptionPopup_" + p.Guid + "_" + p.Name); p.intval = EditorGUI.Popup( cntlRect, p.Name, p.intval, options); if (EditorGUI.EndChangeCheck()) { Undo.RegisterCompleteObjectUndo(p.Parent.model, "value change for " + p.Name); p.parametricObject.model.autobuild(); if (p.PType == AXParameter.ParameterType.PositionControl) { p.parametricObject.generator.adjustWorldMatrices(); } } break; } case AXParameter.DataType.CustomOption: { // OPTION POPUP string[] options = p.optionLabels.ToArray(); EditorGUIUtility.labelWidth = wid * .5f; EditorGUI.BeginChangeCheck(); GUI.SetNextControlName("CustomOptionPopup_" + p.Guid + "_" + p.Name); p.intval = EditorGUI.Popup( cntlRect, p.Name, p.intval, options); if (EditorGUI.EndChangeCheck()) { Undo.RegisterCompleteObjectUndo(p.Parent.model, "value change for " + p.Name); p.parametricObject.model.autobuild(); if (p.PType == AXParameter.ParameterType.PositionControl) { p.parametricObject.generator.adjustWorldMatrices(); } } break; } } // END switch (Type) } } cur_y += lineHgt; GUI.backgroundColor = oldBackgroundColor; /* * if(GUI.changed && ! editor.codeChanged) * { * Debug.Log ("generate " + Parent.Name + " :: " + Name); * //Parent.generateOutput("guid01"); * * * } */ GUI.color = defcolor; return(cur_y - (int)pRect.y); }
// return the height of this gui area public static void OnGUI(Rect headerRect, AXNodeGraphEditorWindow editor) { Event e = Event.current; AXModel model = editor.model; // DO HEADER MENU BAR -- MODEL MENU GUILayout.BeginArea(headerRect); GUILayout.BeginHorizontal(); GUIStyle labelstyle = new GUIStyle(GUI.skin.label); labelstyle.alignment = TextAnchor.LowerLeft; labelstyle.fixedWidth = 150; GUILayout.Space(5); if (GUILayout.Button("2D")) { ArchimatixEngine.openLibrary2D(); } if (GUILayout.Button("3D")) { ArchimatixEngine.openLibrary3D(); } // NEW MODEL GUILayout.Space(10); if (GUILayout.Button("▼")) { AXModel[] allModels = ArchimatixUtils.getAllModels(); GenericMenu menu = new GenericMenu(); //menu.AddSeparator("Library ..."); if (allModels != null && allModels.Length > 0) { for (int i = 0; i < allModels.Length; i++) { AXModel m = allModels [i]; menu.AddItem(new GUIContent(m.gameObject.name), false, () => { Selection.activeGameObject = m.gameObject; ArchimatixEngine.currentModel = m; }); } } menu.AddSeparator(""); menu.AddItem(new GUIContent("New Model"), false, () => { AXEditorUtilities.createNewModel(); }); menu.ShowAsContext(); } Color bgc = GUI.backgroundColor; GUI.backgroundColor = Color.clear; if (model != null) { // SELECTED MODEL if (GUILayout.Button(model.name)) { model.currentWorkingGroupPO = null; model.selectAllVisibleInGroup(null); float framePadding = 50; Rect allRect = AXUtilities.getBoundaryRectFromPOs(model.selectedPOs); allRect.x -= framePadding; allRect.y -= framePadding; allRect.width += framePadding * 2; allRect.height += framePadding * 2; AXNodeGraphEditorWindow.zoomToRectIfOpen(allRect); } if (model.currentWorkingGroupPO != null) { if (model.currentWorkingGroupPO.grouper != null) { // Make breadcrumb trail List <AXParametricObject> crumbs = new List <AXParametricObject>(); AXParametricObject cursor = model.currentWorkingGroupPO; while (cursor.grouper != null) { crumbs.Add(cursor.grouper); cursor = cursor.grouper; } crumbs.Reverse(); // model button frames for (int i = 0; i < crumbs.Count; i++) { if (GUILayout.Button("> " + crumbs[i].Name)) { model.currentWorkingGroupPO = crumbs[i]; Rect grouperCanvasRect = model.currentWorkingGroupPO.getBoundsRect(); editor.zoomToRect(grouperCanvasRect); } } } GUILayout.Button("> " + model.currentWorkingGroupPO.Name); } } GUILayout.FlexibleSpace(); if (model != null) { Color buildBG = Color.Lerp(Color.cyan, Color.white, .8f); string buildLabel = "Rebuild"; if (model.buildStatus == AXModel.BuildStatus.Generated) { buildBG = Color.red; buildLabel = "Build"; } GUI.backgroundColor = buildBG; if (GUILayout.Button(buildLabel)) { model.build(); } GUI.backgroundColor = Color.cyan; if (model.generatedGameObjects != null && model.generatedGameObjects.transform.childCount == 0) { GUI.enabled = false; } if (GUILayout.Button("Stamp")) { model.stamp(); } if (GUILayout.Button("Prefab")) { string startDir = Application.dataPath; string path = EditorUtility.SaveFilePanel( "Save Prefab", startDir, ("" + model.name), "prefab"); if (!string.IsNullOrEmpty(path)) { AXPrefabWindow.makePrefab(model, path, editor); } } GUI.enabled = true; GUILayout.Space(4); } GUILayout.EndHorizontal(); GUILayout.EndArea(); GUI.backgroundColor = bgc; }
public static int OnGUI_Spline(Rect pRect, AXNodeGraphEditorWindow editor, AXParameter p) { float cur_x = ArchimatixUtils.cur_x; //float box_w = ArchimatixUtils.paletteRect.width - cur_x - 3*ArchimatixUtils.indent; float box_w = pRect.width - cur_x - 1 * ArchimatixUtils.indent; int cur_y = (int)pRect.y; int lineHgt = (int)pRect.height; int gap = 5; int margin = 24; float wid = pRect.width - margin; Color shapeColor = editor.getDataColor(AXParameter.DataType.Spline); Color oldBackgroundColor = GUI.backgroundColor; Color dataColor = editor.getDataColor(p.Type); GUI.backgroundColor = dataColor; // INPUT if (editor.OutputParameterBeingDragged != null && editor.OutputParameterBeingDragged.Type != AXParameter.DataType.Spline) { GUI.enabled = false; } if (p.PType != AXParameter.ParameterType.Output) { if (GUI.Button(new Rect(-3, cur_y, ArchimatixEngine.buttonSize, ArchimatixEngine.buttonSize), "")) { if (editor.OutputParameterBeingDragged != null && editor.OutputParameterBeingDragged.Type != p.Type) { editor.OutputParameterBeingDragged = null; } else { editor.inputSocketClicked(p); } } } GUI.enabled = true; // OUTPUT if (editor.InputParameterBeingDragged == null || editor.InputParameterBeingDragged.Type == AXParameter.DataType.Spline) { if (GUI.Button(new Rect(pRect.width + 6, cur_y, ArchimatixEngine.buttonSize, ArchimatixEngine.buttonSize), "")) { if (editor.OutputParameterBeingDragged != null && editor.OutputParameterBeingDragged.Type != p.Type) { editor.OutputParameterBeingDragged = null; } else { editor.outputSocketClicked(p); } } } // LABEL Rect boxRect = new Rect(cur_x + ArchimatixUtils.indent + 3, cur_y, box_w, pRect.height); Rect lRect = boxRect; lRect.x += 3; lRect.width -= 10; GUIStyle labelstyle = GUI.skin.GetStyle("Label"); labelstyle.alignment = TextAnchor.MiddleLeft; if (p.PType == AXParameter.ParameterType.Output) { labelstyle.alignment = TextAnchor.MiddleRight; labelstyle.fixedWidth = lRect.width - 13; } GUI.Box(boxRect, " "); GUI.Box(boxRect, " "); GUI.Box(boxRect, " "); GUI.Box(boxRect, " "); //Debug.Log(p.Name + " - " + p.ParentNode+ " - " + p.ParentNode.Name); string label = p.Name; if (p.ParentNode != null && p.ParentNode is AXShape) { if (p.DependsOn != null) { if (p.DependsOn.Parent != null) { label = p.DependsOn.Parent.Name; } } } GUI.Label(lRect, label); // SOLID/VOID TOGGLE if (p.PType == AXParameter.ParameterType.Input && p.ParentNode != null && (p.ParentNode is AXShape)) { // Texture2D solidVoidIconTexture = (Texture2D) AssetDatabase.LoadAssetAtPath(ArchimatixEngine.ArchimatixAssetPath+"/ui/GeneralIcons/"+iconname, typeof(Texture2D)); Texture2D solidVoidIconTexture = (p.polyType == PolyType.ptSubject) ? editor.solidIconTexture : editor.voidIconTexture; Rect svRect = new Rect(boxRect.x + boxRect.width - lineHgt, cur_y, lineHgt, lineHgt); if (GUI.Button(svRect, new GUIContent(solidVoidIconTexture, "Solid/Void"), GUIStyle.none)) //if(GUI.Button ( bRect, solidVoidIconTexture, GUIStyle.none)) { p.polyType = (p.polyType == PolyType.ptSubject) ? PolyType.ptClip : PolyType.ptSubject; p.parametricObject.model.autobuild(); } GUI.Label(new Rect(10, 40, 100, 40), GUI.tooltip); } // OPEN/CLOSED TOGGLE else { Texture2D solidOpenClosedTexture = (p.shapeState == ShapeState.Open) ? editor.shapeOpenIconTexture : editor.shapeClosedIconTexture; Rect svRect = new Rect(boxRect.x + boxRect.width - lineHgt - 2, cur_y, lineHgt + 2, lineHgt + 2); if (GUI.Button(svRect, new GUIContent(solidOpenClosedTexture, "Open/Closed"), GUIStyle.none)) //if(GUI.Button ( bRect, solidVoidIconTexture, GUIStyle.none)) { p.shapeState = (p.shapeState == ShapeState.Open) ? ShapeState.Closed : ShapeState.Open; p.parametricObject.model.autobuild(); } GUI.Label(new Rect(10, 40, 100, 40), GUI.tooltip); } // FOLDOUT (isOpen) GUI.backgroundColor = new Color(1, 1, 1, 1f); p.isOpen = EditorGUI.Foldout(new Rect(cur_x, cur_y, 15, lineHgt), p.isOpen, ""); GUI.backgroundColor = shapeColor; cur_y += lineHgt + gap; Rect tRect = pRect; tRect.x = 30; tRect.width = pRect.width - 20; if (p.isOpen) { ArchimatixUtils.cur_x += ArchimatixUtils.indent; lineHgt = ArchimatixUtils.lineHgtSmall; p.drawClosed = false; string[] options; tRect.x += 2; tRect.y = cur_y; tRect.width -= 11; tRect.height = 16; Rect cntlRect = tRect; // new Rect(x0, cur_y, wid, 16); cntlRect.height = 16; // EXPOSE AS RUNTIME Interface ------------ //EditorGUIUtility.labelWidth = wid-36; cntlRect = new Rect(tRect.x, cur_y, wid, 16); EditorGUI.BeginChangeCheck(); p.exposeAsInterface = EditorGUI.Toggle(cntlRect, "Runtime", p.exposeAsInterface); if (EditorGUI.EndChangeCheck()) { Undo.RegisterCompleteObjectUndo(p.parametricObject.model, "Expose Parameter"); if (p.exposeAsInterface) { p.parametricObject.model.addExposedParameter(p); } else { p.parametricObject.model.removeExposedParameter(p); } } cur_y += lineHgt + gap; // BREAK MINMAXSLIDER tRect.y = cur_y; GUI.Label(tRect, "Break Geom|Norms"); cur_y += lineHgt; GUI.backgroundColor = Color.white; tRect.y = cur_y; EditorGUI.BeginChangeCheck(); #if UNITY_5_5_OR_NEWER EditorGUI.MinMaxSlider( tRect, GUIContent.none, ref p.breakGeom, ref p.breakNorm, 0, 100); #else EditorGUI.MinMaxSlider( GUIContent.none, tRect, ref p.breakGeom, ref p.breakNorm, 0, 100); #endif if (EditorGUI.EndChangeCheck()) { Undo.RegisterCompleteObjectUndo(p.parametricObject.model, "Max Min Slider"); p.parametricObject.model.isAltered(1); } cur_y += lineHgt + gap; cntlRect.y = cur_y; // REVERSE EditorGUI.BeginChangeCheck(); p.reverse = GUI.Toggle(cntlRect, p.reverse, "Reverse"); if (EditorGUI.EndChangeCheck()) { Undo.RegisterCompleteObjectUndo(p.parametricObject.model, "Reverse"); p.parametricObject.model.autobuild(); } cur_y += lineHgt + gap; cntlRect.y = cur_y; // SYMMETRY EditorGUI.BeginChangeCheck(); p.symmetry = GUI.Toggle(cntlRect, p.symmetry, "Symetry"); if (EditorGUI.EndChangeCheck()) { Undo.RegisterCompleteObjectUndo(p.parametricObject.model, "Symetry"); p.parametricObject.model.autobuild(); } cur_y += lineHgt + gap; cntlRect.y = cur_y; // SYMMETRY SEPERATION if (p.symmetry) { EditorGUI.BeginChangeCheck(); EditorGUIUtility.labelWidth = .5f * wid; GUI.SetNextControlName("FloatField_SymSeperation_Text_" + p.Guid + "_"); p.symSeperation = EditorGUI.FloatField(cntlRect, "Seperation", p.symSeperation); if (EditorGUI.EndChangeCheck()) { Undo.RegisterCompleteObjectUndo(p.parametricObject.model, "SymetrySeperation"); p.parametricObject.model.autobuild(); } cur_y += lineHgt + gap; cntlRect.y = cur_y; } // FLIP_X EditorGUI.BeginChangeCheck(); p.flipX = GUI.Toggle(cntlRect, p.flipX, "FlipX"); if (EditorGUI.EndChangeCheck()) { Undo.RegisterCompleteObjectUndo(p.parametricObject.model, "Flip X"); p.parametricObject.model.autobuild(); p.parametricObject.generator.adjustWorldMatrices(); } cur_y += lineHgt + gap; tRect.y = cur_y; tRect.height = 16; // SHAPE_STATE options = ArchimatixUtils.getMenuOptions("ShapeState"); EditorGUIUtility.labelWidth = .5f * wid; //-50; EditorGUI.BeginChangeCheck(); p.shapeState = (ShapeState)EditorGUI.Popup( tRect, "ShapeState", (int)p.shapeState, options); if (EditorGUI.EndChangeCheck()) { Undo.RegisterCompleteObjectUndo(p.parametricObject.model, "Shape State"); p.parametricObject.model.autobuild(); } cur_y += lineHgt + gap; cntlRect.y = cur_y; cntlRect.height = ArchimatixUtils.lineHgtSmall; // THICKNESS AXEditorUtilities.assertFloatFieldKeyCodeValidity("FloatField_Thickness"); EditorGUI.BeginChangeCheck(); GUI.SetNextControlName("FloatField_Thickness_Text_" + p.Guid + "_"); p.thickness = EditorGUI.FloatField(cntlRect, "Thickness", p.thickness); if (EditorGUI.EndChangeCheck()) { Undo.RegisterCompleteObjectUndo(p.Parent.model, "value change for Thickness"); p.thickness = Mathf.Max(p.thickness, 0); p.parametricObject.model.isAltered(2); } cur_y += ArchimatixUtils.lineHgtSmall + gap; if (p.shapeState == ShapeState.Closed) { cntlRect.y = cur_y; cntlRect.height = ArchimatixUtils.lineHgtSmall; // ROUNDNESS AXEditorUtilities.assertFloatFieldKeyCodeValidity("FloatField_Roundness"); EditorGUI.BeginChangeCheck(); GUI.SetNextControlName("FloatField_Roundness_Text_" + p.Guid + "_"); p.roundness = EditorGUI.FloatField(cntlRect, "Roundness", p.roundness); if (EditorGUI.EndChangeCheck()) { Undo.RegisterCompleteObjectUndo(p.Parent.model, "value change for Roundness"); p.parametricObject.model.isAltered(3); } cur_y += ArchimatixUtils.lineHgtSmall + gap; cntlRect.y = cur_y; cntlRect.height = ArchimatixUtils.lineHgtSmall; // OFFSET AXEditorUtilities.assertFloatFieldKeyCodeValidity("FloatField_Offset"); EditorGUI.BeginChangeCheck(); GUI.SetNextControlName("FloatField_Offset_Text_" + p.Guid + "_"); p.offset = EditorGUI.FloatField(cntlRect, "Offset", p.offset); if (EditorGUI.EndChangeCheck()) { Undo.RegisterCompleteObjectUndo(p.Parent.model, "value change for Offset"); p.parametricObject.model.isAltered(3); } cur_y += ArchimatixUtils.lineHgtSmall + gap; } if (p.thickness > 0) { if (p.shapeState == ShapeState.Closed) { // CLOSED if (p.thickness > 0) { p.endType = AXClipperLib.EndType.etClosedLine; } else { p.endType = AXClipperLib.EndType.etClosedPolygon; } } else { // OPEN switch (p.openEndType) { case AXParameter.OpenEndType.Butt: p.endType = AXClipperLib.EndType.etOpenButt; break; case AXParameter.OpenEndType.Square: p.endType = AXClipperLib.EndType.etOpenSquare; break; case AXParameter.OpenEndType.Round: p.endType = AXClipperLib.EndType.etOpenRound; break; default: p.endType = AXClipperLib.EndType.etOpenSquare; break; } } } if (p.shapeState == ShapeState.Closed) { p.drawClosed = true; } if ((p.thickness > 0) || (p.roundness != 0) || (p.offset != 0)) { p.drawClosed = true; tRect.y = cur_y; options = ArchimatixUtils.getMenuOptions("JoinType"); EditorGUIUtility.labelWidth = .5f * wid; //-50; EditorGUI.BeginChangeCheck(); p.joinType = (AXClipperLib.JoinType)EditorGUI.Popup( tRect, "JoinType", (int)p.joinType, options); if (EditorGUI.EndChangeCheck()) { Undo.RegisterCompleteObjectUndo(p.Parent.model, "value change for JoinType"); p.parametricObject.model.autobuild(); } cur_y += lineHgt + gap; if (p.joinType == AXClipperLib.JoinType.jtRound || p.endType == AXClipperLib.EndType.etOpenRound) { tRect.y = cur_y; AXEditorUtilities.assertFloatFieldKeyCodeValidity("FloatField_smoothness"); if (float.IsNaN(p.arcTolerance)) { p.arcTolerance = 50; } if (p.arcTolerance < .25f) { p.arcTolerance = .25f; } float tmp_arcTol = p.arcTolerance; float smoothness = (float)(120 / (p.arcTolerance * p.arcTolerance)); EditorGUI.BeginChangeCheck(); GUI.SetNextControlName("FloatField_smoothness_Text_" + p.Guid + "_"); smoothness = EditorGUI.FloatField(tRect, "smoothness", smoothness); if (EditorGUI.EndChangeCheck()) { smoothness = Mathf.Clamp(smoothness, .048f, 2.0f); float smoothLOD = ((smoothness - .048f) * p.parametricObject.model.segmentReductionFactor) + .048f; p.arcTolerance = (float)(Math.Sqrt(120 / smoothLOD)); if (p.arcTolerance != tmp_arcTol && p.Parent.model.readyToRegisterUndo) { //Debug.Log ("REGISTER UNDO"); float newval = p.arcTolerance; p.arcTolerance = tmp_arcTol; Undo.RegisterCompleteObjectUndo(p.Parent.model, "value change for " + p.Name); p.arcTolerance = newval; p.Parent.model.readyToRegisterUndo = false; } if (p.arcTolerance < .25f) { p.arcTolerance = .25f; } if (p.arcTolerance > 50) { p.arcTolerance = 50; } if (float.IsNaN(p.arcTolerance)) { p.arcTolerance = 50; } p.parametricObject.model.isAltered(4); } cur_y += lineHgt + gap; } } if (p.shapeState == ShapeState.Open && p.thickness > 0) { // OPEN_END_TYPE options = ArchimatixUtils.getMenuOptions("OpenEndType"); EditorGUIUtility.labelWidth = .5f * wid; //-50; tRect.y = cur_y; EditorGUI.BeginChangeCheck(); p.openEndType = (AXParameter.OpenEndType)EditorGUI.Popup( tRect, "EndType", (int)p.openEndType, options); if (EditorGUI.EndChangeCheck()) { Undo.RegisterCompleteObjectUndo(p.Parent.model, "value change for EndType"); } cur_y += lineHgt + gap; } cur_y += lineHgt / 2; // SUBDIVISION cntlRect.y = cur_y; EditorGUI.BeginChangeCheck(); GUI.SetNextControlName("FloatField_Subdivision_Text_" + p.Guid + "_"); p.subdivision = (float)EditorGUI.IntField(cntlRect, "Subdivision", (int)p.subdivision); if (EditorGUI.EndChangeCheck()) { Undo.RegisterCompleteObjectUndo(p.Parent.model, "value change for Subdivision"); if (p.subdivision < 0) { p.subdivision = 0; } p.parametricObject.model.isAltered(3); } ArchimatixUtils.cur_x -= ArchimatixUtils.indent; cur_y += 2 * lineHgt; } GUI.backgroundColor = oldBackgroundColor; return(cur_y); }
// return the height of this gui area public static void OnGUI(AXParameterAlias pa) { AXParameter p = pa.parameter; //Event e = Event.current; // if (Event.current.type == EventType.KeyUp) // { // if (p != null && ! GUI.GetNameOfFocusedControl().Contains("logicTextArea_") ) // { // p.parametricObject.model.autobuildDelayed(1000); // } // } //Color oldBackgroundColor = GUI.backgroundColor; if (p == null || p.parametricObject == null) { return; } //Color defcolor = GUI.color; GUILayout.BeginHorizontal(); // FOLDOUT GUIStyle toggleStyle = new GUIStyle(EditorStyles.foldout); toggleStyle.fixedWidth = 50; pa.isEditing = EditorGUILayout.Foldout(pa.isEditing, GUIContent.none); //Debug.Log(pa.isEditing); // SLIDER AND NUMBER FIELD GUIStyle textfieldStyle = new GUIStyle(GUI.skin.textField); textfieldStyle.fixedWidth = 150; GUIStyle labelWrap = new GUIStyle(GUI.skin.label); labelWrap.stretchWidth = true; labelWrap.wordWrap = true; labelWrap.fontSize = 9; labelWrap.fixedWidth = 150; if (pa.isEditing) { GUILayout.BeginVertical(); pa.alias = GUILayout.TextField(pa.alias, textfieldStyle); GUILayout.Label("You can edit the alias without altering the source parameter.", labelWrap); GUILayout.Label("Actual: ", labelWrap); if (GUILayout.Button(pa.parameter.parametricObject.Name + "." + pa.parameter.Name)) { pa.parameter.parametricObject.model.selectPO(pa.parameter.parametricObject); pa.parameter.ParentNode.isOpen = true; float framePadding = 200; Rect allRect = AXUtilities.getBoundaryRectFromPOs(pa.parameter.parametricObject.model.selectedPOs); allRect.x -= framePadding; allRect.y -= framePadding; allRect.width += framePadding * 2; allRect.height += framePadding * 2; AXNodeGraphEditorWindow.zoomToRectIfOpen(allRect); } GUILayout.Space(15); GUILayout.EndVertical(); } else { string nameString = pa.alias; switch (p.Type) { case AXParameter.DataType.Float: // FLOAT SLIDER if (p.PType != AXParameter.ParameterType.DerivedValue) { // VALIDATE INPUT - IF INVALID >> LOSE FOCUS AXEditorUtilities.assertFloatFieldKeyCodeValidity("FloatField_Text_" + p.Name); EditorGUI.BeginChangeCheck(); GUI.SetNextControlName("FloatField_Text_" + p.Guid + "_" + p.Name); p.val = EditorGUILayout.FloatField(nameString, p.val); if (EditorGUI.EndChangeCheck()) { //Debug.Log(val); Undo.RegisterCompleteObjectUndo(p.Parent.model, "value change for " + p.Name); p.Parent.initiateRipple_setFloatValueFromGUIChange(p.Name, p.val); p.parametricObject.model.isAltered(27); p.parametricObject.generator.adjustWorldMatrices(); } } else { GUILayout.Label(p.Name); GUILayout.Label("" + p.val); } break; case AXParameter.DataType.Int: { // INT SLIDER // VALIDATE INPUT - IF INVALID >> LOSE FOCUS /* * if (Event.current.type == EventType.KeyDown) * { * if(Event.current.keyCode != KeyCode.None && !AXEditorUtilities.isValidIntFieldKeyCode(Event.current.keyCode) && GUI.GetNameOfFocusedControl() == ("IntField_" + p.Name)) * { * Event.current.Use(); * GUI.FocusControl("dummy_label"); * } * } */ AXEditorUtilities.assertIntFieldKeyCodeValidity("IntField_" + p.Name); EditorGUI.BeginChangeCheck(); GUI.SetNextControlName("IntField_" + p.Guid + "_" + p.Name); p.intval = EditorGUILayout.IntField(nameString, p.intval); if (EditorGUI.EndChangeCheck()) { Undo.RegisterCompleteObjectUndo(p.Parent.model, "value change for " + p.Name); p.initiateRipple_setIntValueFromGUIChange(p.intval); p.parametricObject.model.isAltered(28); p.parametricObject.generator.adjustWorldMatrices(); } break; } case AXParameter.DataType.Bool: { EditorGUI.BeginChangeCheck(); GUI.SetNextControlName("BoolToggle_" + p.Guid + "_" + p.Name); p.boolval = EditorGUILayout.Toggle(nameString, p.boolval); if (EditorGUI.EndChangeCheck()) { Undo.RegisterCompleteObjectUndo(p.Parent.model, "value change for " + p.Name); p.parametricObject.initiateRipple_setBoolParameterValueByName(p.Name, p.boolval); p.parametricObject.model.autobuild(); p.parametricObject.generator.adjustWorldMatrices(); } break; } case AXParameter.DataType.String: if (p.Parent.isEditing) { GUILayout.Label(nameString); } else { GUILayout.Label(nameString); } break; case AXParameter.DataType.Option: { // OPTION POPUP string[] options = ArchimatixUtils.getMenuOptions(p.Name); EditorGUI.BeginChangeCheck(); GUI.SetNextControlName("OptionPopup_" + p.Guid + "_" + p.Name); p.intval = EditorGUILayout.Popup( nameString, p.intval, options); if (EditorGUI.EndChangeCheck()) { Undo.RegisterCompleteObjectUndo(p.Parent.model, "value change for " + p.Name); p.parametricObject.model.autobuild(); if (p.PType == AXParameter.ParameterType.PositionControl) { p.parametricObject.generator.adjustWorldMatrices(); } } break; } case AXParameter.DataType.CustomOption: { // OPTION POPUP string[] options = p.optionLabels.ToArray(); EditorGUI.BeginChangeCheck(); GUI.SetNextControlName("CustomOptionPopup_" + p.Guid + "_" + p.Name); p.intval = EditorGUILayout.Popup( nameString, p.intval, options); if (EditorGUI.EndChangeCheck()) { Undo.RegisterCompleteObjectUndo(p.Parent.model, "value change for " + p.Name); if (p.PType == AXParameter.ParameterType.PositionControl) { p.parametricObject.generator.adjustWorldMatrices(); } p.parametricObject.model.autobuild(); } break; } case AXParameter.DataType.Spline: { GUILayout.Label(pa.alias); break; } } // END switch (Type) } GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); //GUI.backgroundColor = oldBackgroundColor; //GUI.color = defcolor; }
// GENERATE STEP_REPEATER public override GameObject generate(bool makeGameObjects, AXParametricObject initiator_po, bool isReplica) { if (parametricObject == null || !parametricObject.isActive) { return(null); } preGenerate(); // NODE_MESH GameObject nodePlugGO = null; if (nodeSrc_p != null) { nodeSrc_po = nodeSrc_p.parametricObject; if (makeGameObjects && !parametricObject.combineMeshes) { nodePlugGO = nodeSrc_po.generator.generate(true, initiator_po, isReplica); } } // CELL_MESH GameObject cellPlugGO = null; if (cellSrc_p != null) { cellSrc_po = cellSrc_p.parametricObject; if (makeGameObjects && !parametricObject.combineMeshes) { cellPlugGO = cellSrc_po.generator.generate(true, initiator_po, isReplica); } } if (nodeSrc_po == null && cellSrc_po == null) { if (P_Output != null) { P_Output.meshes = null; } return(null); } GameObject go = null; if (makeGameObjects && !parametricObject.combineMeshes) { go = ArchimatixUtils.createAXGameObject(parametricObject.Name, parametricObject); } List <AXMesh> ax_meshes = new List <AXMesh>(); Matrix4x4 localPlacement_mx = Matrix4x4.identity; // ----------------------------------- shiftU = 0; //shiftU = (topStep) ? (-steps * actual_tread / 2) : (-(steps-1) * actual_tread / 2); AXMesh tmpMesh; // BOUNDING CombineInstance[] boundsCombinator = new CombineInstance[steps]; // LOOP //Debug.Log(nodeSrc_po.Name + ": " + nodeSrc_po.boundsMesh.vertices.Length); //AXGeometryTools.Utilities for (int i = 0; i < steps; i++) { //Debug.Log("["+i+"] i*actualBay="+i*actualBay+", perval="+perlval); if (i == steps - 1 && !topStep) { break; } // NODES if (nodeSrc_po != null && nodeSrc_p.meshes != null) { string this_address = "node_" + i; // LOCAL_PLACEMENT localPlacement_mx = localMatrixFromAddress(RepeaterItem.Node, i); // AX_MESHES for (int mi = 0; mi < nodeSrc_p.meshes.Count; mi++) { AXMesh dep_amesh = nodeSrc_p.meshes [mi]; tmpMesh = dep_amesh.Clone(localPlacement_mx * dep_amesh.transMatrix); tmpMesh.subItemAddress = this_address; ax_meshes.Add(tmpMesh); } // BOUNDING MESHES boundsCombinator[i].mesh = nodeSrc_po.boundsMesh; boundsCombinator[i].transform = localPlacement_mx * nodeSrc_po.generator.localMatrixWithAxisRotationAndAlignment; // GAME_OBJECTS if (nodePlugGO != null && makeGameObjects && !parametricObject.combineMeshes) { //Matrix4x4 mx = localPlacement_mx * parametricObject.getTransMatrix() * source.getTransMatrix(); //Debug.Log(nodeSrc_po.getLocalMatrix()); Matrix4x4 mx = localPlacement_mx * nodeSrc_po.generator.localMatrixWithAxisRotationAndAlignment; GameObject copyGO = (GameObject)GameObject.Instantiate(nodePlugGO, AXUtilities.GetPosition(mx), AXUtilities.QuaternionFromMatrix(mx)); Vector3 newJitterScale = jitterScale + Vector3.one; copyGO.transform.localScale = new Vector3(copyGO.transform.localScale.x * newJitterScale.x, copyGO.transform.localScale.y * newJitterScale.y, copyGO.transform.localScale.z * newJitterScale.z); copyGO.transform.localScale += jitterScale; #if UNITY_EDITOR //if (parametricObject.model.isSelected(nodeSrc_po) && nodeSrc_po.selectedConsumerAddress == this_address) // Selection.activeGameObject = copyGO; #endif AXGameObject axgo = copyGO.GetComponent <AXGameObject>(); if (axgo != null) { axgo.consumerAddress = this_address; } copyGO.name = copyGO.name + "_" + this_address; copyGO.transform.parent = go.transform; } } // \NODES // CELLS if (cellSrc_po != null && cellSrc_p.meshes != null) { string this_address = "cell_" + i; // LOCAL_PLACEMENT localPlacement_mx = localMatrixFromAddress(RepeaterItem.Cell, i); // AX_MESHES for (int mi = 0; mi < cellSrc_p.meshes.Count; mi++) { AXMesh dep_amesh = cellSrc_p.meshes [mi]; tmpMesh = dep_amesh.Clone(localPlacement_mx * dep_amesh.transMatrix); tmpMesh.subItemAddress = this_address; ax_meshes.Add(tmpMesh); } // BOUNDING MESHES boundsCombinator[i].mesh = cellSrc_po.boundsMesh; boundsCombinator[i].transform = localPlacement_mx * cellSrc_po.generator.localMatrixWithAxisRotationAndAlignment; // GAME_OBJECTS if (cellPlugGO != null && makeGameObjects && !parametricObject.combineMeshes) { //Matrix4x4 mx = localPlacement_mx * parametricObject.getTransMatrix() * source.getTransMatrix(); //Debug.Log(cellSrc_po.getLocalMatrix()); Matrix4x4 mx = localPlacement_mx * cellSrc_po.generator.localMatrixWithAxisRotationAndAlignment; GameObject copyGO = (GameObject)GameObject.Instantiate(cellPlugGO, AXUtilities.GetPosition(mx), AXUtilities.QuaternionFromMatrix(mx)); Vector3 newJitterScale = jitterScale + Vector3.one; copyGO.transform.localScale = new Vector3(copyGO.transform.localScale.x * newJitterScale.x, copyGO.transform.localScale.y * newJitterScale.y, copyGO.transform.localScale.z * newJitterScale.z); copyGO.transform.localScale += jitterScale; #if UNITY_EDITOR //if (parametricObject.model.isSelected(nodeSrc_po) && nodeSrc_po.selectedConsumerAddress == this_address) // Selection.activeGameObject = copyGO; #endif AXGameObject axgo = copyGO.GetComponent <AXGameObject>(); if (axgo != null) { axgo.consumerAddress = this_address; } copyGO.name = copyGO.name + "_" + this_address; copyGO.transform.parent = go.transform; } } // \CELLS } //i //Debug.Log(parametricObject.Name + " : " + parametricObject.bounds); GameObject.DestroyImmediate(nodePlugGO); GameObject.DestroyImmediate(cellPlugGO); // FINNISH AX_MESHES parametricObject.finishMultiAXMeshAndOutput(ax_meshes, isReplica); // FINISH BOUNDARIES setBoundsWithCombinator(boundsCombinator); // Turn ax_meshes into GameObjects if (makeGameObjects) { if (parametricObject.combineMeshes) { go = parametricObject.makeGameObjectsFromAXMeshes(ax_meshes, true); } Matrix4x4 tmx = parametricObject.getLocalMatrix(); go.transform.rotation = AXUtilities.QuaternionFromMatrix(tmx); go.transform.position = AXUtilities.GetPosition(tmx); go.transform.localScale = parametricObject.getLocalScaleAxisRotated(); //AXUtilities.GetScale(tmx); return(go); } return(null); }
// GENERATE LATHE // The only thing a Lathe Node does is prepare a circular Section. Otherwise it is simple a PlanSweep. public override GameObject generate(bool makeGameObjects, AXParametricObject initiator_po, bool renderToOutputParameter) { if (parametricObject == null || !parametricObject.isActive) { return(null); } // RESULTING MESHES ax_meshes = new List <AXMesh>(); preGenerate(); // PLAN - is an arc or circle // generate the plane shape. A circle at .5 radius AXParameter plan_p = new AXParameter(); plan_p.Parent = parametricObject; plan_p.Type = AXParameter.DataType.Shape; plan_p.paths = new Paths(); float actingRadius = radius + MIN_RAD; //Debug.Log("actingRadius="+actingRadius); int msegs = Mathf.Max(1, Mathf.FloorToInt(((float)segs * parametricObject.model.segmentReductionFactor))); if (snappedSweepAngle == 360) { plan_p.paths.Add(AXTurtle.Circle(actingRadius, msegs)); plan_p.shapeState = ShapeState.Closed; } else { plan_p.paths.Add(AXTurtle.Arc(actingRadius, 0, snappedSweepAngle, msegs)); plan_p.shapeState = ShapeState.Open; } //plan_p.breakGeom = 10; plan_p.breakNorm = (faceted ? 10 : 135); plan_p.breakGeom = (continuousU ? 100 : 10); // In order to conceptualize the section as at a vert rather than the normal case for PlanSweep where it is on a length, // shift the section out by: dx = R ( 1 - cos(ß/2)) // http://www.archimatix.com/geometry/compensating-for-plansweep-in-a-lathe-mesher float beta = snappedSweepAngle / segs; float dx = actingRadius * (1 - Mathf.Cos(Mathf.Deg2Rad * beta / 2)); //Debug.Log("actingRadius="+actingRadius+", beta="+beta+", dx="+dx); ShiftRadMatrix = Matrix4x4.TRS(new Vector3(-MIN_RAD + dx, 0, 0), Quaternion.identity, Vector3.one); // SECTION // The plan may have multiple paths. Each may generate a separate GO. if (P_Section == null || sectionSrc_p == null || !sectionSrc_p.parametricObject.isActive) { return(null); } P_Section.polyTree = null; P_Section.thickness = 0; P_Section.offset = 0; AXShape.thickenAndOffset(ref P_Section, sectionSrc_p); //Debug.Log(parametricObject.Name); //Debug.Log(ShiftRadMatrix); if (P_Section.polyTree != null) { AX.Generators.Generator2D.transformPolyTree(P_Section.polyTree, ShiftRadMatrix); } else { P_Section.paths = AX.Generators.Generator2D.transformPaths(P_Section.paths, ShiftRadMatrix); } GameObject retGO = null; if (makeGameObjects && P_Section.polyTree == null && P_Section.paths != null && P_Section.paths.Count > 1) { //Debug.Log("make one for each section"); retGO = ArchimatixUtils.createAXGameObject(parametricObject.Name, parametricObject); for (int i = 0; i < P_Section.paths.Count; i++) { AXParameter tmpSecP = new AXParameter(); tmpSecP.shapeState = ShapeState.Open; tmpSecP.parametricObject = parametricObject; Paths tmpPaths = new Paths(); tmpPaths.Add(P_Section.paths[i]); tmpSecP.paths = tmpPaths; GameObject tmpObj = generateFirstPass(initiator_po, makeGameObjects, plan_p, tmpSecP, ShiftRadMatrix, renderToOutputParameter); tmpObj.transform.parent = retGO.transform; } } else { retGO = generateFirstPass(initiator_po, makeGameObjects, plan_p, P_Section, ShiftRadMatrix, renderToOutputParameter); } // FINISH AX_MESHES parametricObject.finishMultiAXMeshAndOutput(ax_meshes, renderToOutputParameter); // FINISH BOUNDING setBoundaryFromAXMeshes(ax_meshes); if (P_Section.polyTree != null) { AX.Generators.Generator2D.transformPolyTree(P_Section.polyTree, ShiftRadMatrix.inverse); } //else // P_Section.paths = AX.Generators.Generator2D.transformPaths(P_Section.paths, ShiftRadMatrix); return(retGO); }
// GENERATE // This is the main function for generating a Shape, Mesh, or any other output that a node may be tasked with generating. // You can do pre processing of Inputs here, but that might best be done in an override of pollControlValuesFromParmeters(). // // Often, you will be creating a list of AXMesh objects. AXMesh has a Mesh, a Matrix4x4 and a Material // to be used when drawing the ouput to the scene before creating GameObjects. Your list of AXMeshes generated // is pased to the model via parametricObject.finishMultiAXMeshAndOutput(). // // When generate() is called by AX, it will be either with makeGameObjects set to true or false. // makeGameObjects=False is passed when the user is dragging a parameter and the model is regenerateing multiple times per second. // makeGameObjects=True is passed when the user has stopped editing (for example, OnMouseup from a Handle) and it is time to // build a GameObject hierarchy. public override GameObject generate(bool makeGameObjects, AXParametricObject initiator_po, bool isReplica) { if (parametricObject == null || !parametricObject.hasInputMeshReady("Input Mesh")) { return(null); } // At this point the amount variable has been set to the FloatValue of its amount parameter. preGenerate(); //Vector3 center = Vector3.zero; // AXMeshes are the key product of a Generator3D List <AXMesh> ax_meshes = new List <AXMesh>(); AXParameter inputSrc_p = P_Input.DependsOn; AXParametricObject inputSrc_po = inputSrc_p.parametricObject; if (inputSrc_p != null && inputSrc_p.meshes != null) // Is there an input node connected to this node? { //Debug.Log("P_Input.DependsOn.meshes.Count="+P_Input.DependsOn.meshes.Count + ", "+ P_Input.DependsOn.meshes[0].GetType()); AXMesh amesh = null; // BOUNDING //CombineInstance[] boundsCombinator = new CombineInstance[ P_Input.DependsOn.meshes.Count]; // EACH MESH for (int i = 0; i < P_Input.DependsOn.meshes.Count; i++) { // Instance does not inhereit and build on the transform of its source object. amesh = P_Input.DependsOn.meshes [i].Clone(); Mesh m = amesh.mesh; Vector3[] verts = m.vertices; // ---------- EACH VERTEX ---------------------- for (int j = 0; j < verts.Length; j++) { Vector3 vert = new Vector3(verts[j].x, verts[j].y, verts[j].z); vert = P_Input.DependsOn.meshes[i].drawMeshMatrix.MultiplyPoint3x4(vert); float scale = modifierCurve.Evaluate(vert.x); vert = new Vector3(vert.x, (vert.y + amount * vert.x) + scale, vert.z); verts [j] = P_Input.DependsOn.meshes[i].drawMeshMatrix.inverse.MultiplyPoint3x4(vert); } // ---------- EACH VERTEX ---------------------- m.vertices = verts; amesh.mesh.RecalculateNormals(); ax_meshes.Add(amesh); } parametricObject.boundsMesh = ArchimatixUtils.meshClone(inputSrc_po.boundsMesh); Vector3[] boundsVerts = parametricObject.boundsMesh.vertices; // ---------- EACH VERTEX ---------------------- for (int j = 0; j < boundsVerts.Length; j++) { Vector3 vert = new Vector3(boundsVerts[j].x, boundsVerts[j].y, boundsVerts[j].z); //vert = P_Input.DependsOn.meshes[i].drawMeshMatrix.MultiplyPoint3x4(vert); float scale = modifierCurve.Evaluate(vert.x); boundsVerts [j] = new Vector3(vert.x, (vert.y + amount * vert.x) + scale, vert.z); //boundsVerts [j] = P_Input.DependsOn.meshes[i].drawMeshMatrix.inverse.MultiplyPoint3x4(vert); } // ---------- EACH VERTEX ---------------------- parametricObject.boundsMesh.vertices = boundsVerts; parametricObject.boundsMesh.RecalculateBounds(); //parametricObject.bounds = inputSrc_po.bounds; parametricObject.bounds = parametricObject.boundsMesh.bounds; parametricObject.finishMultiAXMeshAndOutput(ax_meshes, isReplica); if (makeGameObjects) { return(parametricObject.makeGameObjectsFromAXMeshes(ax_meshes)); } } return(null); }
// GENERATE LINEAR_REPEATER public override GameObject generate(bool makeGameObjects, AXParametricObject initiator_po, bool isReplica) { //Debug.Log("repeaterToolU="+repeaterToolU+", repeaterToolV="+repeaterToolV); //Debug.Log("LINEAR REPEATER: Gentrate"); if (parametricObject == null || !parametricObject.isActive) { return(null); } if (repeaterToolU == null && repeaterToolV == null) { return(null); } preGenerate(); repeaterTool = (zAxis) ? repeaterToolV : repeaterToolU; repeaterTool = repeaterToolU; //Terrain terrain = Terrain.activeTerrain; // NODE_MESH AXParametricObject nodeSrc_po = null; GameObject nodePlugGO = null; if (nodeSrc_p != null) { nodeSrc_po = nodeSrc_p.parametricObject; if (makeGameObjects && !parametricObject.combineMeshes) { nodePlugGO = nodeSrc_po.generator.generate(true, initiator_po, isReplica); } } // CELL_MESH AXParametricObject cellSrc_po = null; GameObject cellPlugGO = null; if (cellSrc_p != null) { cellSrc_po = cellSrc_p.parametricObject; if (makeGameObjects && !parametricObject.combineMeshes) { cellPlugGO = cellSrc_po.generator.generate(true, initiator_po, isReplica); } } // BAY_SPAN AXParametricObject spanSrc_po = null; GameObject spanPlugGO = null; if (spanUSrc_p != null) { spanSrc_po = spanUSrc_p.parametricObject; if (makeGameObjects && !parametricObject.combineMeshes) { spanPlugGO = spanSrc_po.generator.generate(true, initiator_po, isReplica); } } if (nodeSrc_po == null && spanSrc_po == null && cellSrc_po == null) { if (P_Output != null) { P_Output.meshes = null; } return(null); } GameObject go = null; if (makeGameObjects && !parametricObject.combineMeshes) { go = ArchimatixUtils.createAXGameObject(parametricObject.Name, parametricObject); } Paths boundingSolids = null; Paths boundingHoles = null; List <AXMesh> ax_meshes = new List <AXMesh>(); Matrix4x4 localPlacement_mx = Matrix4x4.identity; // ----------------------------------- int max_reps = 150; int cellsU = Mathf.Clamp(repeaterTool.cells, 1, max_reps); float actualBayU = repeaterTool.actualBay; if (float.IsNaN(actualBayU)) { return(null); } shiftU = -cellsU * actualBayU / 2; AXMesh tmpMesh; // BAY SPAN // Spanners are meshers that get replicated and sized to fit the bay... // prepare mesh to iterate in each direction List <AXMesh> ax_meshes_X = new List <AXMesh>(); if (spanUSrc_p != null) { ax_meshes_X = spanUSrc_p.meshes; } /* NEED TO INTEGRATE THIS BACK IN IN THE FUTRE... * if (cell_center_source != null) * { * // Y-AXIS * // For now, only set the boundaries. * // Perhaps later, may want to set other like controls as in Replicant * // 1. cache source object * cell_center_source.cacheParameterValues(); * * * * //bay_center_source.propagateParameterByBinding(1, bayx); * //bay_center_source.propagateParameterByBinding(3, bayz); * * // 2. re_generate with temporary values set by this Replicant * cell_center_source.generateOutputNow (makeGameObjects, parametricObject); * * // 3. Now that the bay_span_source has been regenerted, grab the meshes from the input sources and add them here * AXParameter bc_output_p = cell_center_source.getParameter("Output Mesh"); * foreach (AXMesh amesh in bc_output_p.meshes) * ax_meshes_Y.Add (amesh.Clone(amesh.transMatrix)); * * // 4. restore source object; as though we were never here! * cell_center_source.revertParametersFromCache(); * * } */ // BOUNDING int boundingObjectCount = 0; if (nodeSrc_po != null && nodeSrc_p.meshes != null) { boundingObjectCount += cellsU + 1; if (!doFirstNode) { boundingObjectCount--; } if (!doLastNode) { boundingObjectCount--; } } else if (cellSrc_p != null && cellSrc_p.meshes != null) { boundingObjectCount += cellsU; } if (spanUSrc_p != null && spanUSrc_p.meshes != null) { boundingObjectCount += cellsU; } CombineInstance[] boundsCombinator = new CombineInstance[boundingObjectCount]; // FOR EACH ADDRESS for (int i = 0; i <= cellsU; i++) { //Debug.Log("["+i+"] i*actualBay="+i*actualBay+", perval="+perlval); if (boundingSolids != null) { IntPoint ip = new IntPoint((i * repeaterToolU.actualBay + shiftU) * AXGeometryTools.Utilities.IntPointPrecision, 0); bool exclude = true; if (boundingSolids != null) { foreach (Path path in boundingSolids) { if (Clipper.PointInPolygon(ip, path) == 1 && Clipper.Orientation(path)) { exclude = false; break; } } } if (boundingHoles != null) { foreach (Path hole in boundingHoles) { if (Clipper.PointInPolygon(ip, hole) == 1) { exclude = true; break; } } } if (exclude) { continue; } } //Debug.Log(" ** ** ** * " + nodeSrc_p.meshes); // NODES if (nodeSrc_po != null && nodeSrc_p.meshes != null) { // Debug.Log("nodeSrc_po.getLocalAlignMatrix()"+nodeSrc_po.getLocalAlignMatrix()); if ((i > 0 && i < cellsU) || (i == 0 && doFirstNode) || (i == (cellsU) && doLastNode)) { string this_address = "node_" + i; int ni = doFirstNode ? i : i - 1; // LOCAL_PLACEMENT // localPlacement_mx = localNodeMatrixFromAddress(i); if (float.IsNaN(localPlacement_mx.m00)) { continue; } // AX_MESHES for (int mi = 0; mi < nodeSrc_p.meshes.Count; mi++) { AXMesh dep_amesh = nodeSrc_p.meshes [mi]; //tmpMesh = dep_amesh.CloneTransformed (localPlacement_mx * dep_amesh.transMatrix); tmpMesh = dep_amesh.Clone(localPlacement_mx * dep_amesh.transMatrix); tmpMesh.subItemAddress = this_address; ax_meshes.Add(tmpMesh); } // BOUNDING MESHES boundsCombinator[ni].mesh = nodeSrc_po.boundsMesh; boundsCombinator[ni].transform = localPlacement_mx * nodeSrc_po.generator.localMatrixWithAxisRotationAndAlignment; // GAME_OBJECTS if (nodePlugGO != null && makeGameObjects && !parametricObject.combineMeshes) { //Matrix4x4 mx = localPlacement_mx * parametricObject.getTransMatrix() * source.getTransMatrix(); //Debug.Log(nodeSrc_po.getLocalMatrix()); Matrix4x4 mx = localPlacement_mx * nodeSrc_po.generator.localMatrixWithAxisRotationAndAlignment; GameObject copyGO = (GameObject)GameObject.Instantiate(nodePlugGO, AXUtilities.GetPosition(mx), AXUtilities.QuaternionFromMatrix(mx)); copyGO.transform.localScale = new Vector3(copyGO.transform.localScale.x * jitterScale.x, copyGO.transform.localScale.y * jitterScale.y, copyGO.transform.localScale.z * jitterScale.z); AXGameObject axgo = copyGO.GetComponent <AXGameObject>(); if (axgo != null) { axgo.consumerAddress = this_address; } copyGO.name = copyGO.name + "_" + this_address; copyGO.transform.parent = go.transform; } } } // \NODES // CELL CENTERS if (cellSrc_p != null && cellSrc_p.meshes != null && i < cellsU) { string this_address = "cell_" + i; //Debug.Log("Here"); // LOCAL_PLACEMENT localPlacement_mx = localCellMatrixFromAddress(i); // ACTUAL MESHES for (int mi = 0; mi < cellSrc_p.meshes.Count; mi++) { AXMesh dep_amesh = cellSrc_p.meshes [mi]; tmpMesh = dep_amesh.Clone(localPlacement_mx * dep_amesh.transMatrix); tmpMesh.subItemAddress = this_address; ax_meshes.Add(tmpMesh); } // BOUNDING MESHES boundsCombinator[i].mesh = cellSrc_po.boundsMesh; boundsCombinator[i].transform = localPlacement_mx * cellSrc_po.generator.localMatrixWithAxisRotationAndAlignment;; // GAME_OBJECTS if (cellPlugGO != null && makeGameObjects && !parametricObject.combineMeshes) { //Matrix4x4 mx = localPlacement_mx * parametricObject.getTransMatrix() * source.getTransMatrix(); Matrix4x4 mx = localPlacement_mx * cellSrc_po.generator.localMatrixWithAxisRotationAndAlignment; GameObject copyGO = (GameObject)GameObject.Instantiate(cellPlugGO, AXUtilities.GetPosition(mx), AXUtilities.QuaternionFromMatrix(mx)); copyGO.transform.localScale = new Vector3(copyGO.transform.localScale.x * jitterScale.x, copyGO.transform.localScale.y * jitterScale.y, copyGO.transform.localScale.z * jitterScale.z); AXGameObject axgo = copyGO.GetComponent <AXGameObject>(); if (axgo != null) { axgo.consumerAddress = this_address; } copyGO.name = copyGO.name + "_" + this_address; copyGO.transform.parent = go.transform; //Debug.Log("LINEAR: " + axgo.consumerAddress); } } // \CELLS // SPANS if (spanUSrc_p != null && spanUSrc_p.meshes != null && i < cellsU) { string this_address = "spanU_" + i; // X-AXIS // LOCAL_PLACEMENT localPlacement_mx = localCellMatrixFromAddress(i); // AX_MESHES // AX_MESHES for (int mi = 0; mi < ax_meshes_X.Count; mi++) { AXMesh dep_amesh = ax_meshes_X [mi]; tmpMesh = dep_amesh.Clone(localPlacement_mx * dep_amesh.transMatrix); tmpMesh.subItemAddress = this_address; ax_meshes.Add(tmpMesh); } // BOUNDING MESHES boundsCombinator[i].mesh = spanUSrc_po.boundsMesh; boundsCombinator[i].transform = localPlacement_mx * spanUSrc_po.generator.localMatrixWithAxisRotationAndAlignment; // GAME_OBJECTS if (spanPlugGO != null && makeGameObjects && !parametricObject.combineMeshes) { Matrix4x4 mx = localPlacement_mx * spanSrc_po.generator.localMatrixWithAxisRotationAndAlignment; GameObject copyGO = (GameObject)GameObject.Instantiate(spanPlugGO, AXUtilities.GetPosition(mx), AXUtilities.QuaternionFromMatrix(mx)); copyGO.transform.localScale = new Vector3(copyGO.transform.localScale.x * jitterScale.x, copyGO.transform.localScale.y * jitterScale.y, copyGO.transform.localScale.z * jitterScale.z); AXGameObject axgo = copyGO.GetComponent <AXGameObject>(); if (axgo != null) { axgo.consumerAddress = this_address; } copyGO.name = copyGO.name + "_" + this_address; copyGO.transform.parent = go.transform; } } // \SPANS } //i GameObject.DestroyImmediate(nodePlugGO); GameObject.DestroyImmediate(cellPlugGO); GameObject.DestroyImmediate(spanPlugGO); parametricObject.finishMultiAXMeshAndOutput(ax_meshes, isReplica); setBoundsWithCombinator(boundsCombinator); // Turn ax_meshes into GameObjects if (makeGameObjects) { if (parametricObject.combineMeshes) { go = parametricObject.makeGameObjectsFromAXMeshes(ax_meshes, true); } Matrix4x4 tmx = parametricObject.getLocalMatrix(); go.transform.rotation = AXUtilities.QuaternionFromMatrix(tmx); go.transform.position = AXUtilities.GetPosition(tmx); go.transform.localScale = parametricObject.getLocalScaleAxisRotated(); //AXUtilities.GetScale(tmx); return(go); } return(null); }