public void mirrorDuplicate() { ClayObject mirrorClayObj = null; ClayObject[] clayObjs = this.getClayContainer().GetComponentsInChildren <ClayObject>(); for (int i = 0; i < clayObjs.Length; ++i) { ClayObject clayObj = clayObjs[i]; if (clayObj.name == "mirror_" + this.name) { if (clayObj.blend == this.blend && clayObj.attrs == this.attrs) { mirrorClayObj = clayObj; break; } } } if (mirrorClayObj == null) { mirrorClayObj = Instantiate(this.gameObject, this.getClayContainer().transform).GetComponent <ClayObject>(); mirrorClayObj.name = "mirror_" + this.name; } Matrix4x4 mirrorMat = Matrix4x4.Scale(new Vector3(-1.0f, 1.0f, 1.0f)); mirrorMat = mirrorMat * this.transform.localToWorldMatrix; mirrorClayObj.transform.localScale = mirrorMat.lossyScale; mirrorClayObj.transform.position = new Vector3(mirrorMat[0, 3], mirrorMat[1, 3], mirrorMat[2, 3]); mirrorClayObj.transform.rotation = mirrorMat.rotation; this.getClayContainer().clayObjectUpdated(mirrorClayObj); }
void drawOffsetMode(ClayObject clayObj) { EditorGUI.BeginChangeCheck(); int numSolids = EditorGUILayout.IntField("solids", clayObj.getNumSolids()); bool allowSceneObjects = true; clayObj.offsetter = (GameObject)EditorGUILayout.ObjectField("offsetter", clayObj.offsetter, typeof(GameObject), allowSceneObjects); if (EditorGUI.EndChangeCheck()) { if (numSolids < 1) { numSolids = 1; } else if (numSolids > 100) { numSolids = 100; } clayObj.setOffsetNum(numSolids); UnityEditor.EditorApplication.QueuePlayerLoopUpdate(); } }
static void renameToAnimate(MenuCommand command) { if (UnityEditor.Selection.gameObjects.Length > 0) { ClayObject clayObj = UnityEditor.Selection.gameObjects[0].GetComponent <ClayObject>(); if (clayObj != null) { ClayContainer container = clayObj.getClayContainer(); ClayContainer._skipHierarchyChanges = true; // otherwise each rename will trigger onHierarchyChange int numClayObjs = container.getNumClayObjects(); for (int i = 0; i < numClayObjs; ++i) { ClayObject currentClayObj = container.getClayObject(i); if (currentClayObj.gameObject.name.StartsWith("clay_")) { container.autoRenameClayObject(currentClayObj); currentClayObj.name = "(" + i + ")" + currentClayObj.gameObject.name; } } ClayContainer._skipHierarchyChanges = false; } } }
public void mirrorDuplicate() { ClayObject mirrorClayObj = null; ClayObject[] clayObjs = this.getClayContainer().GetComponentsInChildren <ClayObject>(); for (int i = 0; i < clayObjs.Length; ++i) { ClayObject clayObj = clayObjs[i]; if (clayObj.name == "mirror_" + this.name) { if (clayObj.blend == this.blend && clayObj.attrs == this.attrs) { mirrorClayObj = clayObj; break; } } } if (mirrorClayObj == null) { mirrorClayObj = Instantiate(this.gameObject, this.transform.parent).GetComponent <ClayObject>(); mirrorClayObj.name = "mirror_" + this.name; } Plane mirrorPlane = new Plane(this.transform.parent.right, this.transform.parent.position); Vector3 pointOnPlane = mirrorPlane.ClosestPointOnPlane(this.transform.position); float distanceToPlane = mirrorPlane.GetDistanceToPoint(this.transform.position); Vector3 mirrorPos = pointOnPlane - mirrorPlane.normal * distanceToPlane; mirrorClayObj.transform.position = mirrorPos; mirrorClayObj.transform.rotation = Quaternion.LookRotation(Vector3.Reflect(this.transform.rotation * Vector3.forward, mirrorPlane.normal), Vector3.Reflect(this.transform.rotation * Vector3.up, mirrorPlane.normal)); mirrorClayObj.transform.localScale = this.transform.localScale; this.getClayContainer().clayObjectUpdated(mirrorClayObj); }
static void sendAfterClayObject(MenuCommand command) { if (UnityEditor.Selection.gameObjects.Length > 0) { ClayObject clayObj = UnityEditor.Selection.gameObjects[0].GetComponent <ClayObject>(); if (clayObj != null) { clayObj.getClayContainer().selectToReorder(clayObj, 1); } } }
static void OrderFromHierarchyOn(MenuCommand command) { if (UnityEditor.Selection.gameObjects.Length > 0) { ClayObject clayObj = UnityEditor.Selection.gameObjects[0].GetComponent <ClayObject>(); if (clayObj != null) { clayObj.getClayContainer().setClayObjectsOrderLocked(true); } } }
void autoRename(ClayObject clayObj, string[] solidsLabels) { string blendSign = "+"; if (clayObj.blend < 0.0f) { blendSign = "-"; } string isColoring = ""; if (clayObj.attrs.w == 1.0f) { blendSign = ""; isColoring = "[paint]"; } clayObj.gameObject.name = "clay_" + solidsLabels[clayObj.primitiveType] + blendSign + isColoring; }
void drawSplineMode(ClayObject clayObj) { EditorGUI.BeginChangeCheck(); int subdivs = EditorGUILayout.IntField("subdivs", clayObj.getSplineSubdiv()); var list = this.serializedObject.FindProperty("splinePoints"); EditorGUILayout.PropertyField(list, new GUIContent("spline points"), true); if (EditorGUI.EndChangeCheck()) { this.serializedObject.ApplyModifiedProperties(); clayObj.setSplineSubdiv(subdivs); UnityEditor.EditorApplication.QueuePlayerLoopUpdate(); } }
void drawSplineMode(ClayObject clayObj) { EditorGUI.BeginChangeCheck(); int subdivs = EditorGUILayout.IntField("subdivs", clayObj.getSplineSubdiv()); GUILayout.BeginHorizontal(); int numPoints = clayObj.splinePoints.Count - 2; EditorGUILayout.LabelField("control points: " + numPoints); if (GUILayout.Button(new GUIContent("+", ""))) { clayObj.addSplineControlPoint(); } if (GUILayout.Button(new GUIContent("-", ""))) { clayObj.removeLastSplineControlPoint(); } GUILayout.EndHorizontal(); // var list = this.serializedObject.FindProperty("splinePoints"); // EditorGUILayout.PropertyField(list, new GUIContent("spline points"), true); if (EditorGUI.EndChangeCheck()) { // this.serializedObject.ApplyModifiedProperties(); clayObj.setSplineSubdiv(subdivs); UnityEditor.EditorApplication.QueuePlayerLoopUpdate(); } }
public override void OnInspectorGUI() { UnityEditor.EditorApplication.QueuePlayerLoopUpdate(); ClayObject clayObj = (ClayObject)this.targets[0]; ClayContainer clayxel = clayObj.getClayContainer(); if (clayxel == null) { return; } EditorGUI.BeginChangeCheck(); string[] solidsLabels = clayxel.getSolidsCatalogueLabels(); int primitiveType = EditorGUILayout.Popup("solidType", clayObj.primitiveType, solidsLabels); float blend = EditorGUILayout.Slider("blend", Mathf.Abs(clayObj.blend) * 100.0f, 0.0f, 100.0f); if (clayObj.blend < 0.0f) { if (blend < 0.001f) { blend = 0.001f; } blend *= -1.0f; } blend *= 0.01f; if (blend > 1.0f) { blend = 1.0f; } else if (blend < -1.0f) { blend = -1.0f; } GUILayout.BeginHorizontal(); Color defaultColor = GUI.backgroundColor; if (clayObj.blend >= 0.0f) { GUI.backgroundColor = Color.yellow; } if (GUILayout.Button(new GUIContent("add", "Additive blend"))) { blend = Mathf.Abs(blend); } GUI.backgroundColor = defaultColor; if (clayObj.blend < 0.0f) { GUI.backgroundColor = Color.yellow; } if (GUILayout.Button(new GUIContent("sub", "Subtractive blend"))) { if (blend == 0.0f) { blend = 0.0001f; } blend = blend * -1.0f; } GUI.backgroundColor = defaultColor; GUILayout.EndHorizontal(); Color color = EditorGUILayout.ColorField("color", clayObj.color); Dictionary <string, float> paramValues = new Dictionary <string, float>(); paramValues["x"] = clayObj.attrs.x; paramValues["y"] = clayObj.attrs.y; paramValues["z"] = clayObj.attrs.z; paramValues["w"] = clayObj.attrs.w; List <string[]> parameters = clayxel.getSolidsCatalogueParameters(primitiveType); List <string> wMaskLabels = new List <string>(); for (int paramIt = 0; paramIt < parameters.Count; ++paramIt) { string[] parameterValues = parameters[paramIt]; string attr = parameterValues[0]; string label = parameterValues[1]; string defaultValue = parameterValues[2]; if (primitiveType != clayObj.primitiveType) { // reset to default params when changing primitive type paramValues[attr] = float.Parse(defaultValue, CultureInfo.InvariantCulture); } if (attr.StartsWith("w")) { wMaskLabels.Add(label); } else { paramValues[attr] = EditorGUILayout.FloatField(label, paramValues[attr] * 100.0f) * 0.01f; } } if (wMaskLabels.Count > 0) { paramValues["w"] = (float)EditorGUILayout.MaskField("options", (int)clayObj.attrs.w, wMaskLabels.ToArray()); } if (EditorGUI.EndChangeCheck()) { ClayContainer._inspectorUpdate(); ClayContainer._skipHierarchyChanges = true; Undo.RecordObjects(this.targets, "changed clayobject"); for (int i = 1; i < this.targets.Length; ++i) { bool somethingChanged = false; ClayObject currentClayObj = (ClayObject)this.targets[i]; bool shouldAutoRename = false; if (Mathf.Abs(clayObj.blend - blend) > 0.001f || Mathf.Sign(clayObj.blend) != Mathf.Sign(blend)) { currentClayObj.blend = blend; somethingChanged = true; shouldAutoRename = true; } if (clayObj.color != color) { currentClayObj.color = color; somethingChanged = true; } if (clayObj.primitiveType != primitiveType) { currentClayObj.primitiveType = primitiveType; somethingChanged = true; shouldAutoRename = true; } if (clayObj.attrs.x != paramValues["x"]) { currentClayObj.attrs.x = paramValues["x"]; somethingChanged = true; } if (clayObj.attrs.y != paramValues["y"]) { currentClayObj.attrs.y = paramValues["y"]; somethingChanged = true; } if (clayObj.attrs.z != paramValues["z"]) { currentClayObj.attrs.z = paramValues["z"]; somethingChanged = true; } if (clayObj.attrs.w != paramValues["w"]) { currentClayObj.attrs.w = paramValues["w"]; somethingChanged = true; shouldAutoRename = true; } if (somethingChanged) { currentClayObj.getClayContainer().clayObjectUpdated(currentClayObj); if (shouldAutoRename) { if (currentClayObj.gameObject.name.StartsWith("clay_")) { clayxel.autoRenameClayObject(currentClayObj); } } } ClayContainer._skipHierarchyChanges = false; } clayObj.blend = blend; clayObj.color = color; clayObj.primitiveType = primitiveType; clayObj.attrs.x = paramValues["x"]; clayObj.attrs.y = paramValues["y"]; clayObj.attrs.z = paramValues["z"]; clayObj.attrs.w = paramValues["w"]; if (clayObj.gameObject.name.StartsWith("clay_")) { clayxel.autoRenameClayObject(clayObj); } clayObj.forceUpdate(); UnityEditor.EditorApplication.QueuePlayerLoopUpdate(); ClayContainer.getSceneView().Repaint(); if (!Application.isPlaying) { EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene()); } } EditorGUILayout.Space(); EditorGUI.BeginChangeCheck(); ClayObject.ClayObjectMode mode = (ClayObject.ClayObjectMode)EditorGUILayout.EnumPopup("mode", clayObj.mode); if (EditorGUI.EndChangeCheck()) { clayObj.setMode(mode); UnityEditor.EditorApplication.QueuePlayerLoopUpdate(); if (!Application.isPlaying) { EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene()); } } if (clayObj.mode == ClayObject.ClayObjectMode.offset) { this.drawOffsetMode(clayObj); } else if (clayObj.mode == ClayObject.ClayObjectMode.spline) { this.drawSplineMode(clayObj); } EditorGUILayout.Space(); GUILayout.BeginHorizontal(); GUI.enabled = !clayxel.isClayObjectsOrderLocked(); int clayObjectId = EditorGUILayout.IntField("order", clayObj.clayObjectId); GUI.enabled = true; if (!clayxel.isClayObjectsOrderLocked()) { if (clayObjectId != clayObj.clayObjectId) { int idOffset = clayObjectId - clayObj.clayObjectId; clayxel.reorderClayObject(clayObj.clayObjectId, idOffset); } } if (GUILayout.Button(new GUIContent("↑", ""))) { clayxel.reorderClayObject(clayObj.clayObjectId, -1); } if (GUILayout.Button(new GUIContent("↓", ""))) { clayxel.reorderClayObject(clayObj.clayObjectId, 1); } if (GUILayout.Button(new GUIContent("⋮", ""))) { EditorUtility.DisplayPopupMenu(new Rect(Event.current.mousePosition.x, Event.current.mousePosition.y, 0, 0), "Component/Clayxels/ClayObject", null); } GUILayout.EndHorizontal(); }
public override void OnInspectorGUI() { Color defaultColor = GUI.backgroundColor; ClayContainer clayxel = (ClayContainer)this.target; EditorGUILayout.LabelField("Clayxels V1.31"); EditorGUILayout.Space(); string userWarn = clayxel._getUserWarning(); if (userWarn != "") { GUIStyle s = new GUIStyle(); s.wordWrap = true; s.normal.textColor = Color.yellow; EditorGUILayout.LabelField(userWarn, s); } if (clayxel.getNumSolids() > clayxel.getMaxSolids()) { GUIStyle s = new GUIStyle(); s.wordWrap = true; s.normal.textColor = Color.yellow; EditorGUILayout.LabelField("Max solid count exeeded, open Global Config to tweak settings."); } if (clayxel.instanceOf != null) { ClayContainer newInstance = (ClayContainer)EditorGUILayout.ObjectField(new GUIContent("instance", "Set this to point at another clayContainer in scene to make this into an instance and avoid having to compute the same thing twice."), clayxel.instanceOf, typeof(ClayContainer), true); if (newInstance != clayxel.instanceOf && newInstance != clayxel) { clayxel.instanceOf = newInstance; clayxel.init(); // UnityEditor.EditorApplication.QueuePlayerLoopUpdate(); // ClayContainer.getSceneView().Repaint(); if (!Application.isPlaying) { EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene()); } } EditorGUILayout.Space(); if (GUILayout.Button((new GUIContent("global config", "")))) { ClayxelsPrefsWindow.Open(); } return; } if (clayxel.isFrozen()) { if (GUILayout.Button(new GUIContent("defrost clayxels", "Back to live clayxels."))) { clayxel.defrostContainersHierarchy(); // UnityEditor.EditorApplication.QueuePlayerLoopUpdate(); // ClayContainer.getSceneView().Repaint(); } EditorGUILayout.Space(); if (GUILayout.Button((new GUIContent("global config", "")))) { ClayxelsPrefsWindow.Open(); } return; } EditorGUI.BeginChangeCheck(); int clayxelDetail = EditorGUILayout.IntField(new GUIContent("clayxel detail", "How coarse or finely detailed is your sculpt. Enable Gizmos in your viewport to see the boundaries."), clayxel.getClayxelDetail()); if (EditorGUI.EndChangeCheck()) { ClayContainer._inspectorUpdate(); clayxel.setClayxelDetail(clayxelDetail); if (!Application.isPlaying) { EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene()); } return; } GUILayout.BeginHorizontal(); GUI.backgroundColor = defaultColor; if (!clayxel.isAutoBoundsActive()) { EditorGUI.BeginChangeCheck(); Vector3Int boundsScale = EditorGUILayout.Vector3IntField(new GUIContent("bounds scale", "How much work area you have for your sculpt within this container. Enable Gizmos in your viewport to see the boundaries."), clayxel.getBoundsScale()); if (EditorGUI.EndChangeCheck()) { ClayContainer._inspectorUpdate(); clayxel.setBoundsScale(boundsScale.x, boundsScale.y, boundsScale.z); clayxel.init(); clayxel.needsUpdate = true; // UnityEditor.EditorApplication.QueuePlayerLoopUpdate(); // ClayContainer.getSceneView().Repaint(); if (!Application.isPlaying) { EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene()); } return; } if (GUILayout.Button(new GUIContent("-", ""))) { ClayContainer._inspectorUpdate(); Vector3Int bounds = clayxel.getBoundsScale(); clayxel.setBoundsScale(bounds.x - 1, bounds.y - 1, bounds.z - 1); clayxel.init(); clayxel.needsUpdate = true; // UnityEditor.EditorApplication.QueuePlayerLoopUpdate(); // ClayContainer.getSceneView().Repaint(); if (!Application.isPlaying) { EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene()); } return; } if (GUILayout.Button(new GUIContent("+", ""))) { ClayContainer._inspectorUpdate(); Vector3Int bounds = clayxel.getBoundsScale(); clayxel.setBoundsScale(bounds.x + 1, bounds.y + 1, bounds.z + 1); clayxel.init(); clayxel.needsUpdate = true; // UnityEditor.EditorApplication.QueuePlayerLoopUpdate(); // ClayContainer.getSceneView().Repaint(); if (!Application.isPlaying) { EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene()); } return; } if (GUILayout.Button(new GUIContent("auto", ""))) { clayxel.setAutoBoundsActive(true); // UnityEditor.EditorApplication.QueuePlayerLoopUpdate(); // ClayContainer.getSceneView().Repaint(); if (!Application.isPlaying) { EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene()); } } } else { GUI.backgroundColor = Color.yellow; GUILayout.BeginHorizontal(); EditorGUILayout.LabelField("bounds scale"); if (GUILayout.Button(new GUIContent("auto", ""))) { clayxel.setAutoBoundsActive(false); } GUILayout.EndHorizontal(); } GUI.backgroundColor = defaultColor; GUILayout.EndHorizontal(); EditorGUILayout.Space(); if (GUILayout.Button(new GUIContent("add clay", "lets get this party started"))) { ClayObject clayObj = ((ClayContainer)this.target).addClayObject(); Undo.RegisterCreatedObjectUndo(clayObj.gameObject, "added clayxel solid"); UnityEditor.Selection.objects = new GameObject[] { clayObj.gameObject }; clayxel.needsUpdate = true; // UnityEditor.EditorApplication.QueuePlayerLoopUpdate(); // ClayContainer.getSceneView().Repaint(); if (!Application.isPlaying) { EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene()); } return; } if (GUILayout.Button(new GUIContent("pick clay (" + ClayContainer.pickingKey + ")", "Press p on your keyboard to mouse pick ClayObjects from the viewport. Pressing Shift will add to a previous selection."))) { ClayContainer.startScenePicking(); } if (GUILayout.Button((new GUIContent("global config", "")))) { ClayxelsPrefsWindow.Open(); } clayxel.forceUpdate = EditorGUILayout.Toggle(new GUIContent("animate (forceUpdate)", "Enable if you're animating/moving the container as well as the clayObjects inside it."), clayxel.forceUpdate); EditorGUILayout.Space(); ClayxelInspector.extrasPanel = EditorGUILayout.Foldout(ClayxelInspector.extrasPanel, "extras", true); if (ClayxelInspector.extrasPanel) { ClayContainer instance = (ClayContainer)EditorGUILayout.ObjectField(new GUIContent("instance", "Set this to point at another clayContainer in scene to make this into an instance and avoid having to compute the same thing twice."), clayxel.instanceOf, typeof(ClayContainer), true); if (instance != clayxel.instanceOf && instance != clayxel) { clayxel.instanceOf = instance; // UnityEditor.EditorApplication.QueuePlayerLoopUpdate(); // ClayContainer.getSceneView().Repaint(); if (!Application.isPlaying) { EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene()); } } EditorGUILayout.Space(); if (clayxel.storeAssetPath == "") { clayxel.storeAssetPath = clayxel.gameObject.name; } clayxel.storeAssetPath = EditorGUILayout.TextField(new GUIContent("frozen asset name", "Specify an asset name to store frozen mesh or claymation on disk. Files are saved relative to this project's Assets folder."), clayxel.storeAssetPath); string[] paths = clayxel.storeAssetPath.Split('.'); if (paths.Length > 0) { clayxel.storeAssetPath = paths[0]; } EditorGUILayout.Space(); #if CLAYXELS_RETOPO clayxel.shouldRetopoMesh = EditorGUILayout.Toggle(new GUIContent("retopology", "Use this to generate meshes with a better topology."), clayxel.shouldRetopoMesh); if (clayxel.shouldRetopoMesh) { clayxel.retopoMaxVerts = EditorGUILayout.IntField(new GUIContent("vertex count", "-1 will let the tool decide on the best number of vertices."), clayxel.retopoMaxVerts); } #endif if (GUILayout.Button(new GUIContent("freeze mesh", "Switch between live clayxels and a frozen mesh."))) { clayxel.freezeContainersHierarchyToMesh(); #if CLAYXELS_RETOPO if (clayxel.shouldRetopoMesh) { int targetVertCount = RetopoUtils.getRetopoTargetVertsCount(clayxel.gameObject, clayxel.retopoMaxVerts); if (targetVertCount == 0) { return; } RetopoUtils.retopoMesh(clayxel.gameObject.GetComponent <MeshFilter>().sharedMesh, targetVertCount, -1); } #endif clayxel.transferMaterialPropertiesToMesh(); if (clayxel.storeAssetPath != "") { clayxel.storeMesh(clayxel.storeAssetPath); } } EditorGUILayout.Space(); AnimationClip claymationAnimClip = (AnimationClip)EditorGUILayout.ObjectField(new GUIContent("animClip (optional)", "Freeze an animation to disk using the claymation file format"), clayxel.claymationAnimClip, typeof(AnimationClip), true); if (claymationAnimClip != null && claymationAnimClip != clayxel.claymationAnimClip) { clayxel.claymationStartFrame = 0; clayxel.claymationEndFrame = (int)(claymationAnimClip.length * claymationAnimClip.frameRate); } clayxel.claymationAnimClip = claymationAnimClip; if (clayxel.claymationAnimClip != null) { clayxel.claymationStartFrame = EditorGUILayout.IntField(new GUIContent("start", ""), clayxel.claymationStartFrame); clayxel.claymationEndFrame = EditorGUILayout.IntField(new GUIContent("end", ""), clayxel.claymationEndFrame); } if (GUILayout.Button(new GUIContent("freeze claymation", "Freeze this container to a point-cloud file stored on disk and skip heavy computing."))) { clayxel.freezeClaymation(); } EditorGUI.BeginChangeCheck(); EditorGUILayout.Space(); bool castShadows = EditorGUILayout.Toggle("cast shadows", clayxel.getCastShadows()); if (EditorGUI.EndChangeCheck()) { ClayContainer._inspectorUpdate(); clayxel.setCastShadows(castShadows); if (!Application.isPlaying) { EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene()); } } // end of extras } EditorGUI.BeginChangeCheck(); EditorGUILayout.Space(); Material customMaterial = (Material)EditorGUILayout.ObjectField(new GUIContent("customMaterial", "Custom materials need to use shaders specifically made for clayxels. Use the provided shaders and examples as reference. "), clayxel.customMaterial, typeof(Material), false); if (EditorGUI.EndChangeCheck()) { ClayContainer._inspectorUpdate(); Undo.RecordObject(this.target, "changed clayxel container"); if (customMaterial != clayxel.customMaterial) { clayxel.setCustomMaterial(customMaterial); // clayxel.needsUpdate = true; // clayxel.forceUpdateAllSolids(); } // UnityEditor.EditorApplication.QueuePlayerLoopUpdate(); // ClayContainer.getSceneView().Repaint(); if (!Application.isPlaying) { EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene()); } } if (!clayxel.isFrozenToMesh()) { this.inspectMaterial(clayxel); } }
// Update is called once per frame void FixedUpdate() { if (!Clayxels.ClayContainer.isCacheEnabled()) { this.textObj.text = "To run this example you need to set CLAYXELS_CACHEON to 1 inside claySDF.compute"; return; } this.textObj.text = "FPS " + this.fps + " \nSolids: " + this.solids; this.transform.localEulerAngles = this.transform.localEulerAngles + new Vector3(0.0f, 1.0f, 0.0f); Transform childTrn = this.transform.GetChild(0); Clayxels.ClayObject clayObj = childTrn.gameObject.GetComponent <Clayxels.ClayObject>(); clayObj.primitiveType = UnityEngine.Random.Range(0, 6); if (UnityEngine.Random.Range(0, 100) > 20) { clayObj.blend = 0.1f; } else { clayObj.blend = -0.5f; } Color col = clayObj.color; clayObj.color = col + new Color( UnityEngine.Random.Range(-0.1f, 0.1f), UnityEngine.Random.Range(-0.1f, 0.1f), UnityEngine.Random.Range(-0.1f, 0.1f), 1.0f); if (clayObj.color.r < 0.0f) { clayObj.color.r = 0.0f; } else if (clayObj.color.r > 1.0f) { clayObj.color.r = 1.0f; } if (clayObj.color.g < 0.0f) { clayObj.color.g = 0.0f; } else if (clayObj.color.g > 1.0f) { clayObj.color.g = 1.0f; } if (clayObj.color.b < 0.0f) { clayObj.color.b = 0.0f; } else if (clayObj.color.b > 1.0f) { clayObj.color.b = 1.0f; } childTrn.localEulerAngles = childTrn.localEulerAngles + new Vector3( UnityEngine.Random.Range(-10.0f, 10.0f), UnityEngine.Random.Range(-10.0f, 10.0f), UnityEngine.Random.Range(-10.0f, 10.0f)); Vector3 newPos = childTrn.localPosition + new Vector3( UnityEngine.Random.Range(-0.5f, 0.5f), UnityEngine.Random.Range(-0.5f, 0.5f), UnityEngine.Random.Range(-0.5f, 0.5f)); if (newPos.x > 3.0f) { newPos.x = 3.0f; } else if (newPos.x < -3.0f) { newPos.x = -3.0f; } if (newPos.y > 3.0f) { newPos.y = 3.0f; } else if (newPos.y < -3.0f) { newPos.y = -3.0f; } if (newPos.z > 3.0f) { newPos.z = 3.0f; } else if (newPos.z < -3.0f) { newPos.z = -3.0f; } childTrn.localPosition = newPos; this.solids += 1; Clayxels.ClayContainer container = this.gameObject.GetComponent <Clayxels.ClayContainer>(); container.computeClay(); container.cacheClay(); }
public override void OnInspectorGUI() { ClayObject clayObj = (ClayObject)this.targets[0]; EditorGUI.BeginChangeCheck(); float blend = EditorGUILayout.FloatField("blend", clayObj.blend); if (blend > 1.0f) { blend = 1.0f; } else if (blend < -1.0f) { blend = -1.0f; } Color color = EditorGUILayout.ColorField("color", clayObj.color); ClayContainer clayxel = clayObj.getClayxelContainer(); string[] solidsLabels = clayxel.getSolidsCatalogueLabels(); int primitiveType = EditorGUILayout.Popup("solidType", clayObj.primitiveType, solidsLabels); Dictionary <string, float> paramValues = new Dictionary <string, float>(); paramValues["x"] = clayObj.attrs.x; paramValues["y"] = clayObj.attrs.y; paramValues["z"] = clayObj.attrs.z; paramValues["w"] = clayObj.attrs.w; List <string[]> parameters = clayxel.getSolidsCatalogueParameters(primitiveType); List <string> wMaskLabels = new List <string>(); for (int paramIt = 0; paramIt < parameters.Count; ++paramIt) { string[] parameterValues = parameters[paramIt]; string attr = parameterValues[0]; string label = parameterValues[1]; string defaultValue = parameterValues[2]; if (primitiveType != clayObj.primitiveType) { // reset to default params when changing primitive type paramValues[attr] = float.Parse(defaultValue); } if (attr.StartsWith("w")) { wMaskLabels.Add(label); } else { paramValues[attr] = EditorGUILayout.FloatField(label, paramValues[attr]); } } if (wMaskLabels.Count > 0) { paramValues["w"] = (float)EditorGUILayout.MaskField("options", (int)clayObj.attrs.w, wMaskLabels.ToArray()); } if (EditorGUI.EndChangeCheck()) { Undo.RecordObjects(this.targets, "changed clayobject"); for (int i = 1; i < this.targets.Length; ++i) { bool somethingChanged = false; ClayObject currentClayObj = (ClayObject)this.targets[i]; bool shouldAutoRename = false; if (clayObj.blend != blend) { currentClayObj.blend = blend; somethingChanged = true; shouldAutoRename = true; } if (clayObj.color != color) { currentClayObj.color = color; somethingChanged = true; } if (clayObj.primitiveType != primitiveType) { currentClayObj.primitiveType = primitiveType; somethingChanged = true; shouldAutoRename = true; } if (clayObj.attrs.x != paramValues["x"]) { currentClayObj.attrs.x = paramValues["x"]; somethingChanged = true; } if (clayObj.attrs.y != paramValues["y"]) { currentClayObj.attrs.y = paramValues["y"]; somethingChanged = true; } if (clayObj.attrs.z != paramValues["z"]) { currentClayObj.attrs.z = paramValues["z"]; somethingChanged = true; } if (clayObj.attrs.w != paramValues["w"]) { currentClayObj.attrs.w = paramValues["w"]; somethingChanged = true; shouldAutoRename = true; } if (somethingChanged) { currentClayObj.getClayxelContainer().clayObjectUpdated(currentClayObj); if (shouldAutoRename) { if (currentClayObj.gameObject.name.StartsWith("clay_")) { this.autoRename(currentClayObj, solidsLabels); } } } } clayObj.blend = blend; clayObj.color = color; clayObj.primitiveType = primitiveType; clayObj.attrs.x = paramValues["x"]; clayObj.attrs.y = paramValues["y"]; clayObj.attrs.z = paramValues["z"]; clayObj.attrs.w = paramValues["w"]; if (clayObj.gameObject.name.StartsWith("clay_")) { this.autoRename(clayObj, solidsLabels); } clayxel.clayObjectUpdated(clayObj); UnityEditor.EditorApplication.QueuePlayerLoopUpdate(); ClayContainer.getSceneView().Repaint(); } }
public override void OnInspectorGUI() { ClayContainer clayxel = (ClayContainer)this.target; EditorGUILayout.LabelField("Clayxels, V0.51 beta"); EditorGUILayout.LabelField("clayObjects: " + clayxel.getNumClayObjects()); #if !CLAYXELS_FULL EditorGUILayout.LabelField("free version limit is 64"); #else EditorGUILayout.LabelField("limit is " + clayxel.getMaxSolids()); #endif EditorGUILayout.Space(); EditorGUI.BeginChangeCheck(); int gridResolution = EditorGUILayout.IntField("resolution", clayxel.gridResolution); Vector3Int gridSize = EditorGUILayout.Vector3IntField("containerSize", new Vector3Int(clayxel.gridSizeX, clayxel.gridSizeY, clayxel.gridSizeZ)); if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(this.target, "changed clayxel grid"); clayxel.gridResolution = gridResolution; clayxel.gridSizeX = gridSize.x; clayxel.gridSizeY = gridSize.y; clayxel.gridSizeZ = gridSize.z; clayxel.init(); clayxel.needsUpdate = true; UnityEditor.EditorApplication.QueuePlayerLoopUpdate(); ClayContainer.getSceneView().Repaint(); return; } EditorGUI.BeginChangeCheck(); EditorGUILayout.Space(); Material customMaterial = (Material)EditorGUILayout.ObjectField("customMaterial", clayxel.customMaterial, typeof(Material), false); float materialSmoothness = 0.0f; float materialMetallic = 0.0f; Color materialEmission = new Color(); float materialEmissionIntensity = 0.0f; float splatSizeMultiplier = 1.0f; float normalOrientedSplat = 1.0f; Texture2D splatTexture = null; if (customMaterial == null) { materialSmoothness = EditorGUILayout.FloatField("smoothness", clayxel.materialSmoothness); materialMetallic = EditorGUILayout.FloatField("metallic", clayxel.materialMetallic); materialEmission = EditorGUILayout.ColorField("emission", clayxel.materialEmission); materialEmissionIntensity = EditorGUILayout.FloatField("emissionIntensity", clayxel.materialEmissionIntensity); splatSizeMultiplier = EditorGUILayout.FloatField("clayxelsSize", clayxel.splatSizeMultiplier); normalOrientedSplat = EditorGUILayout.FloatField("normal oritented", clayxel.normalOrientedSplat); splatTexture = (Texture2D)EditorGUILayout.ObjectField("texture", clayxel.splatTexture, typeof(Texture2D), false); } if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(this.target, "changed clayxel container"); if (customMaterial == null) { clayxel.materialSmoothness = materialSmoothness; clayxel.materialMetallic = materialMetallic; clayxel.materialEmission = materialEmission; clayxel.materialEmissionIntensity = materialEmissionIntensity; clayxel.splatSizeMultiplier = splatSizeMultiplier; clayxel.normalOrientedSplat = normalOrientedSplat; clayxel.splatTexture = splatTexture; } if (clayxel.normalOrientedSplat < 0.0f) { clayxel.normalOrientedSplat = 0.0f; } else if (clayxel.normalOrientedSplat > 1.0f) { clayxel.normalOrientedSplat = 1.0f; } clayxel.updateSplatLook(); if (customMaterial != clayxel.customMaterial) { clayxel.customMaterial = customMaterial; clayxel.init(); } clayxel.needsUpdate = true; clayxel.forceUpdateAllChunks(); UnityEditor.EditorApplication.QueuePlayerLoopUpdate(); ClayContainer.getSceneView().Repaint(); return; } EditorGUILayout.Space(); if (GUILayout.Button("reload all")) { ClayContainer.reloadAll(); } if (GUILayout.Button("pick solid (p)")) { ClayContainer.startPicking(); } if (GUILayout.Button("add solid")) { ClayObject clayObj = ((ClayContainer)this.target).addSolid(); Undo.RegisterCreatedObjectUndo(clayObj.gameObject, "added clayxel solid"); UnityEditor.Selection.objects = new GameObject[] { clayObj.gameObject }; clayxel.needsUpdate = true; UnityEditor.EditorApplication.QueuePlayerLoopUpdate(); ClayContainer.getSceneView().Repaint(); return; } EditorGUILayout.Space(); #if CLAYXELS_FULL clayxel.exportRetopoFBX = EditorGUILayout.Toggle("retopology", clayxel.exportRetopoFBX); if (clayxel.exportRetopoFBX) { clayxel.retopoMaxVerts = EditorGUILayout.IntField("max verts", clayxel.retopoMaxVerts); clayxel.retopoFbxFile = EditorGUILayout.TextField("export fbx", clayxel.retopoFbxFile); } #endif if (!clayxel.hasCachedMesh()) { if (GUILayout.Button("freeze to mesh")) { if (clayxel.exportRetopoFBX) { clayxel.retopoMesh(); } else { clayxel.generateMesh(); } } } else { if (GUILayout.Button("defrost clayxels")) { clayxel.disableMesh(); UnityEditor.EditorApplication.QueuePlayerLoopUpdate(); ClayContainer.getSceneView().Repaint(); } } }
// Color newColorValue; // Vector4 newVectorValue; // float newFloatValue; // Texture2D newTextureValue; // string changedMaterialProperty = ""; // ShaderPropertyType changedMaterialPropertyType; public override void OnInspectorGUI() { ClayContainer clayxel = (ClayContainer)this.target; EditorGUILayout.LabelField("Clayxels, V0.71 beta"); EditorGUILayout.LabelField("clayObjects: " + clayxel.getNumClayObjects()); #if !CLAYXELS_ONEUP EditorGUILayout.LabelField("itch.io limit: 64 clayObjects"); #else EditorGUILayout.LabelField("limit is " + clayxel.getMaxClayObjects()); #endif EditorGUILayout.Space(); EditorGUI.BeginChangeCheck(); int chunkSize = EditorGUILayout.IntField(new GUIContent("chunk size", "Small number means more detail in a smaller grid, big number results in less detail with a bigger grid. Enable Gizmos in your viewport to see the boundaries."), clayxel.chunkSize); Vector3Int gridSize = EditorGUILayout.Vector3IntField(new GUIContent("chunks", "Make the grid bigger by employing multiple chunks. The more chunks you have, the slower the computation."), new Vector3Int(clayxel.chunksX, clayxel.chunksY, clayxel.chunksZ)); if (EditorGUI.EndChangeCheck()) { ClayContainer.inspectorUpdate(); clayxel.chunkSize = chunkSize; clayxel.chunksX = gridSize.x; clayxel.chunksY = gridSize.y; clayxel.chunksZ = gridSize.z; clayxel.init(); clayxel.needsUpdate = true; UnityEditor.EditorApplication.QueuePlayerLoopUpdate(); ClayContainer.getSceneView().Repaint(); return; } EditorGUILayout.Space(); clayxel.forceUpdate = EditorGUILayout.Toggle(new GUIContent("update always", "Force this container to update on every frame, use it if you're moving the container as well as the clayObjects inside it."), clayxel.forceUpdate); if (GUILayout.Button((new GUIContent("reload all", "This is necessary after you make changes to the shader or to the claySDF file.")))) { ClayContainer.reloadAll(); } if (GUILayout.Button(new GUIContent("pick clay (p)", "Press p on your keyboard to mouse pick ClayObjects from the viewport. Pressing Shift will add to a previous selection."))) { ClayContainer.startPicking(); } if (GUILayout.Button(new GUIContent("add clay", "lets get this party started"))) { ClayObject clayObj = ((ClayContainer)this.target).addClayObject(); Undo.RegisterCreatedObjectUndo(clayObj.gameObject, "added clayxel solid"); UnityEditor.Selection.objects = new GameObject[] { clayObj.gameObject }; clayxel.needsUpdate = true; UnityEditor.EditorApplication.QueuePlayerLoopUpdate(); ClayContainer.getSceneView().Repaint(); return; } EditorGUILayout.Space(); #if CLAYXELS_ONEUP clayxel.shouldRetopoMesh = EditorGUILayout.Toggle(new GUIContent("retopology", "(Experimental) use this to save better meshes on disk"), clayxel.shouldRetopoMesh); if (clayxel.shouldRetopoMesh) { clayxel.retopoMaxVerts = EditorGUILayout.IntField(new GUIContent("max verts", "-1 will let the tool decide on the best number of vertices."), clayxel.retopoMaxVerts); } #endif clayxel.meshAssetPath = EditorGUILayout.TextField(new GUIContent("save asset", "Specify an asset name to store the computed mesh on disk. Files are saved relative to this project's Assets folder."), clayxel.meshAssetPath); string[] paths = clayxel.meshAssetPath.Split('.'); if (paths.Length > 0) { clayxel.meshAssetPath = paths[0]; } if (!clayxel.hasCachedMesh()) { if (GUILayout.Button(new GUIContent("freeze to mesh", "Switch between live clayxels and a frozen mesh that will not be updated."))) { clayxel.generateMesh(); if (clayxel.shouldRetopoMesh) { clayxel.retopoMesh(); } clayxel.transferMaterialPropertiesToMesh(); if (clayxel.meshAssetPath != "") { clayxel.storeMesh(); } } } else { if (GUILayout.Button(new GUIContent("defrost clayxels", "Back to live clayxels."))) { clayxel.disableMesh(); UnityEditor.EditorApplication.QueuePlayerLoopUpdate(); ClayContainer.getSceneView().Repaint(); } } EditorGUI.BeginChangeCheck(); EditorGUILayout.Space(); Material customMaterial = (Material)EditorGUILayout.ObjectField(new GUIContent("customMaterial", "Custom materials will need to use shaders that talk to clayxels. Use the provided shaders as reference, the Asset Store version also comes with editable Amplify shaders. "), clayxel.customMaterial, typeof(Material), false); if (EditorGUI.EndChangeCheck()) { ClayContainer.inspectorUpdate(); Undo.RecordObject(this.target, "changed clayxel container"); if (customMaterial != clayxel.customMaterial) { clayxel.customMaterial = customMaterial; clayxel.init(); } clayxel.needsUpdate = true; clayxel.forceUpdateAllChunks(); UnityEditor.EditorApplication.QueuePlayerLoopUpdate(); ClayContainer.getSceneView().Repaint(); } if (!clayxel.hasCachedMesh()) { this.inspectMaterial(clayxel); } }