static void Union() { // we need at least two selected objects if (Selection.gameObjects.Length > 1) { CSGObject obj = Selection.activeGameObject.GetComponent <CSGObject>(); if (obj) { obj.PerformCSG(CsgOperation.ECsgOperation.CsgOper_Additive, Selection.gameObjects); } if (GlobalSettings.DeleteSlaves) { // destroy slaves if we want to foreach (GameObject go in Selection.gameObjects) { if (Selection.activeGameObject != go && go.GetComponent <CSGObject>()) { GameObject.DestroyImmediate(go); } } } } }
static void AddComponent() { for (int i = 0; i < Selection.gameObjects.Length; ++i) { GameObject go = Selection.gameObjects[i]; CSGObject obj = go.GetComponent <CSGObject>(); Mesh mesh = go.GetComponent <MeshFilter>() != null?go.GetComponent <MeshFilter>().sharedMesh : null; if (!obj && mesh) { // TODO: add bsp tree generation on add... CSGObject csg = go.AddComponent <CSGObject>(); MeshFilter filter = go.GetComponent <MeshFilter>(); // clone mesh as every csg object needs his own mesh filter.sharedMesh = ObjectCloner.CloneMesh(filter.sharedMesh); // csg.CreateFromMesh(); } else { Debug.Log("No Mesh or already an CSG Object"); } } }
static void Intersect() { // we need at least two selected objects if (Selection.gameObjects.Length > 1) { CSGObject obj = Selection.activeGameObject.GetComponent <CSGObject>(); if (obj) { obj.PerformCSG(CsgOperation.ECsgOperation.CsgOper_Intersect, Selection.gameObjects); } if (GlobalSettings.DeleteSlaves) { foreach (GameObject go in Selection.gameObjects) { // if we are not the active game object and are a CSG Object if (Selection.activeGameObject != go && go.GetComponent <CSGObject>()) { GameObject.DestroyImmediate(go); } } } } }
void Draw(CSGObject obj, int pass, int _ref = -1) { if (_ref != -1) { Material.SetInt("_Ref", _ref); } Material.SetPass(pass); Graphics.DrawMeshNow(obj.Mesh, obj.Renderer.localToWorldMatrix); }
public static void Subtract(GameObject a, GameObject b) { CSGObject obj = a.GetComponent <CSGObject>(); GameObject[] slaves = new GameObject[2] { a, b }; obj.PerformCSG(CsgOperation.ECsgOperation.CsgOper_Subtractive, slaves); a.name = "(" + a.name + ") - (" + b.name + ")"; }
static void MeshOptimize() { for (int i = 0; i < Selection.gameObjects.Length; ++i) { GameObject go = Selection.gameObjects[i]; CSGObject obj = go.GetComponent <CSGObject>(); if (obj) { obj.Optimize(); } } }
static void DrawDebug() { for (int i = 0; i < Selection.gameObjects.Length; ++i) { GameObject go = Selection.gameObjects[i]; CSGObject obj = go.GetComponent <CSGObject>(); if (obj) { obj.DrawDebug(); } } }
static void MergeBspFaces() { for (int i = 0; i < Selection.gameObjects.Length; ++i) { GameObject go = Selection.gameObjects[i]; CSGObject obj = go.GetComponent <CSGObject>(); if (obj) { obj.MergeFaces(); } } }
static void MeshToFaces() { for (int i = 0; i < Selection.gameObjects.Length; ++i) { GameObject go = Selection.gameObjects[i]; CSGObject obj = go.GetComponent <CSGObject>(); if (obj) { obj.TransferFacesToMesh(); } } }
public override bool Calculate() { if (value != null) { CSGObject csg = value.GetComponent <CSGObject>(); if (csg == null) { csg = value.AddComponent <CSGObject>(); } csg.GenerateSolid(); } Outputs[0].SetValue <GameObject> (value); return(true); }
private bool intersect( CSGObject inOther ) { MeshFilter thisMeshFilter = GetComponent<MeshFilter>(); MeshFilter otherMeshFilter = inOther.GetComponent<MeshFilter>(); if( thisMeshFilter == null || otherMeshFilter == null ) return false; Mesh thisMesh = thisMeshFilter.sharedMesh; Mesh otherMesh = otherMeshFilter.sharedMesh; if( thisMesh == null || otherMesh == null ) return false; return thisMesh.bounds.Intersects( otherMesh.bounds ); }
// public void Perform( ECsgOperation inOper, CSGObject inMaster, CSGObject inSlave ) { // we are processing our slave faces processState = EProcessState.Process_Slave; // process faces against master tree PerformFaces( inMaster.rootNode, inSlave.faces ); // process face from master tree processState = EProcessState.Process_Master; // perform master faces on slave bsp tree PerformTree( inMaster.rootNode, inSlave.rootNode ); // check if how do we need to process generated faces if( inOper == ECsgOperation.CsgOper_Additive || inOper == ECsgOperation.CsgOper_Subtractive ) { // add deferred faces to master tree... for( int i = 0; i < deferredFaces.Count; i++ ) { Face defFace = ((DeferredFace)deferredFaces[i]).face; BspNode startNode = ((DeferredFace)deferredFaces[i]).node; // testing startNode = inMaster.rootNode; // add node to master tree BspGen.AddNodeRecursive( startNode, defFace, BspNode.BspFlags_IsNew ); } } else { // clear old faces list inMaster.faces.Clear(); // copy created faces for( int i = 0; i < deferredFaces.Count; i++ ) { inMaster.faces.Add( deferredFaces[i].face ); } } // clear deferred faces deferredFaces.Clear(); }
static void BuildTree() { for (int i = 0; i < Selection.gameObjects.Length; ++i) { GameObject go = Selection.gameObjects[i]; CSGObject obj = go.GetComponent <CSGObject>(); if (obj) { obj.CreateFromMesh(); BspGen gen = new BspGen(GlobalSettings.BspOptimization); obj.rootNode = gen.GenerateBspTree(obj.faces); } } }
// public void Perform(ECsgOperation inOper, CSGObject inMaster, CSGObject inSlave) { // we are processing our slave faces processState = EProcessState.Process_Slave; // process faces against master tree PerformFaces(inMaster.rootNode, inSlave.faces); // process face from master tree processState = EProcessState.Process_Master; // perform master faces on slave bsp tree PerformTree(inMaster.rootNode, inSlave.rootNode); // check if how do we need to process generated faces if (inOper == ECsgOperation.CsgOper_Additive || inOper == ECsgOperation.CsgOper_Subtractive) { // add deferred faces to master tree... for (int i = 0; i < deferredFaces.Count; i++) { CSGFace defFace = ((DeferredFace)deferredFaces[i]).face; BspNode startNode = ((DeferredFace)deferredFaces[i]).node; // testing startNode = inMaster.rootNode; // add node to master tree BspGen.AddNodeRecursive(startNode, defFace, BspNode.BspFlags_IsNew); } } else { // clear old faces list inMaster.faces.Clear(); // copy created faces for (int i = 0; i < deferredFaces.Count; i++) { inMaster.faces.Add(deferredFaces[i].face); } } // clear deferred faces deferredFaces.Clear(); }
private bool intersect(CSGObject inOther) { MeshFilter thisMeshFilter = GetComponent <MeshFilter>(); MeshFilter otherMeshFilter = inOther.GetComponent <MeshFilter>(); if (thisMeshFilter == null || otherMeshFilter == null) { return(false); } Mesh thisMesh = thisMeshFilter.sharedMesh; Mesh otherMesh = otherMeshFilter.sharedMesh; if (thisMesh == null || otherMesh == null) { return(false); } return(thisMesh.bounds.Intersects(otherMesh.bounds)); }
public IEnumerator Spawn(Transform parent, Vector3 scale) { //List<GameObject> brushes = new List<GameObject>(); List <CSGObject> adds = new List <CSGObject>(); List <Bounds> bounds = new List <Bounds>(); int progress = 0; foreach (Actor actor in actors) { progress++; EditorCoroutineRunner.UpdateUIProgressBar(progress / (float)actors.Count); yield return(new WaitForSeconds(0.05f)); GameObject go = actor.Spawn(parent, scale); if (actor is Brush) { Brush brush = actor as Brush; CSGObject csg = go.AddComponent <CSGObject>(); Bounds b = go.GetComponent <MeshRenderer>().bounds; if (brush.additive) { adds.Add(csg); bounds.Add(b); } else { for (int i = 0; i < adds.Count; i++) { if (b.Intersects(bounds[i])) { adds[i].PerformCSG(CsgOperation.ECsgOperation.CsgOper_Subtractive, new GameObject[] { go }); } } GameObject.DestroyImmediate(go); } } } }
public override bool Calculate() { if (Inputs [0].connection != null) { parent = Inputs [0].connection.GetValue <GameObject> (); } string name = ""; // Make a primitive everytime calculate is called (in case type or loc changes) switch (type) { case PrimitiveType.Cube: name = CSGPrimitives.MakePrimitiveName(this.GetHashCode()); value = GameObject.Find(name); if (value != null) { DestroyImmediate(value); } value = GameObject.CreatePrimitive(UnityEngine.PrimitiveType.Cube); value.name = name; break; case PrimitiveType.Plane: name = CSGPrimitives.MakePrimitiveName(this.GetHashCode()); value = GameObject.Find(name); if (value != null) { DestroyImmediate(value); } value = GameObject.CreatePrimitive(UnityEngine.PrimitiveType.Plane); value.name = name; break; case PrimitiveType.Cone: value = CSGPrimitives.CreateCone(this.GetHashCode()); break; case PrimitiveType.Tube: name = CSGPrimitives.MakePrimitiveName(this.GetHashCode()); value = GameObject.Find(name); if (value != null) { DestroyImmediate(value); } value = GameObject.CreatePrimitive(UnityEngine.PrimitiveType.Cylinder); value.name = name; break; case PrimitiveType.Sphere: name = CSGPrimitives.MakePrimitiveName(this.GetHashCode()); value = GameObject.Find(name); if (value != null) { DestroyImmediate(value); } value = GameObject.CreatePrimitive(UnityEngine.PrimitiveType.Sphere); value.name = name; break; case PrimitiveType.Torus: value = CSGPrimitives.CreateTorus(this.GetHashCode()); break; } if (value != null) { CSGObject csg = value.GetComponent <CSGObject>(); if (csg == null) { csg = value.AddComponent <CSGObject>(); } csg.GenerateSolid(); if (parent != null) { value.transform.SetParent(parent.transform); value.transform.localPosition = location; } else { value.transform.SetParent(null); value.transform.position = location; } } Outputs[0].SetValue <GameObject> (value); return(true); }
// Use this for initialization public override void Build() { min = new Vector3(-32.0f, -32.0f, -32.0f); max = new Vector3(32.0f, 32.0f, 32.0f); // GameObject go = new GameObject(); go.name = "CubeGeo"; MeshFilter mf = go.AddComponent <MeshFilter>(); MeshRenderer mr = go.AddComponent <MeshRenderer>(); CSGObject csg = go.AddComponent <CSGObject>(); if (mf.sharedMesh == null) { mf.sharedMesh = new Mesh(); } Mesh mesh = mf.sharedMesh; Vector3 p0 = new Vector3(min.x, min.y, min.z); Vector3 p1 = new Vector3(min.x, min.y, max.z); Vector3 p2 = new Vector3(min.x, max.y, min.z); Vector3 p3 = new Vector3(min.x, max.y, max.z); Vector3 p4 = new Vector3(max.x, min.y, min.z); Vector3 p5 = new Vector3(max.x, min.y, max.z); Vector3 p6 = new Vector3(max.x, max.y, min.z); Vector3 p7 = new Vector3(max.x, max.y, max.z); mesh.Clear(); mesh.vertices = new Vector3[] { // left p0, p1, p2, p3, // right p4, p5, p6, p7, // front p1, p3, p5, p7, // back p0, p2, p4, p6, // top p2, p3, p6, p7, // bottom p0, p1, p4, p5 }; mesh.uv = new Vector2[] { // left new Vector2(0, 0), new Vector2(1, 0), new Vector2(0, 1), new Vector2(1, 1), // right new Vector2(0, 0), new Vector2(1, 0), new Vector2(0, 1), new Vector2(1, 1), // front new Vector2(0, 0), new Vector2(1, 0), new Vector2(0, 1), new Vector2(1, 1), // back new Vector2(0, 0), new Vector2(1, 0), new Vector2(0, 1), new Vector2(1, 1), // top new Vector2(0, 0), new Vector2(1, 0), new Vector2(0, 1), new Vector2(1, 1), // bottom new Vector2(0, 0), new Vector2(1, 0), new Vector2(0, 1), new Vector2(1, 1) }; mesh.triangles = new int[] { // left 0, 1, 2, 2, 1, 3, // right 4, 6, 5, 5, 6, 7, // front 8, 10, 9, 9, 10, 11, // back 12, 13, 14, 14, 13, 15, // top 16, 17, 18, 18, 17, 19, // bottom 20, 22, 21, 21, 22, 23 }; mesh.RecalculateNormals(); mesh.RecalculateBounds(); if (sharedMaterial == null) { sharedMaterial = new Material(Shader.Find("Unlit/Texture")); } mr.sharedMaterial = sharedMaterial; // mr.sharedMaterial.shader = Shader.Find("Unlit/Texture"); Debug.Log(csg); Debug.Log(mesh); Debug.Log(sharedMaterial); // create csg stuff (DUMMY) // csg.CreateFromMesh( mesh, sharedMaterial ); mesh.Optimize(); }
public override bool Calculate() { if (!allInputsReady()) { return(false); } if (Inputs [0].connection != null) { Input1Val = Inputs [0].connection.GetValue <GameObject> (); CSGObject csg = Input1Val.GetComponent <CSGObject>(); if (csg == null) { csg = Input1Val.AddComponent <CSGObject>(); } csg.GenerateSolid(); } if (Inputs [1].connection != null) { Input2Val = Inputs [1].connection.GetValue <GameObject> (); CSGObject csg = Input2Val.GetComponent <CSGObject> (); if (csg == null) { csg = Input2Val.AddComponent <CSGObject> (); } csg.GenerateSolid(); } if ((Input1Val != null) && (Input2Val != null)) { solid1 = Input1Val.GetComponent <CSGObject> ().GetSolid(); solid2 = Input2Val.GetComponent <CSGObject> ().GetSolid(); modeller = new BooleanModeller(solid1, solid2); output = null; switch (type) { case CalcType.Union: output = modeller.getUnion(); break; case CalcType.Intersection: output = modeller.getIntersection(); break; case CalcType.Difference: output = modeller.getDifference(); break; } if (output != null) { string goname = string.Format("CSGOut_{0}", (int)this.GetHashCode()); GameObject gout = GameObject.Find(goname); if (gout == null) { gout = new GameObject(goname); } CSGObject csg = gout.GetComponent <CSGObject>(); if (csg == null) { csg = gout.AddComponent <CSGObject>(); } csg.AssignSolid(output); CSGGameObject.GenerateMesh(gout, objectMaterial, output); Outputs [0].SetValue <GameObject> (gout); } } else { return(false); } return(true); }
// Use this for initialization public override void OnInspectorGUI() { CSGObject obj = (CSGObject)target; GUILayout.BeginHorizontal(); if (GUILayout.Button("Intersect")) { // find game objects (TODO: check if they are touching us) Object[] others = FindObjectsOfType(typeof(GameObject)); GameObject[] gos = new GameObject[others.Length]; int i = 0; foreach (GameObject gameObj in others) { gos[i] = gameObj; ++i; } obj.PerformCSG(CsgOperation.ECsgOperation.CsgOper_Intersect, gos); } if (GUILayout.Button("DeIntersect")) { // find game objects (TODO: check if they are touching us) Object[] others = FindObjectsOfType(typeof(GameObject)); GameObject[] gos = new GameObject[others.Length]; int i = 0; foreach (GameObject gameObj in others) { gos[i] = gameObj; ++i; } obj.PerformCSG(CsgOperation.ECsgOperation.CsgOper_DeIntersect, gos); } GUILayout.Button("..."); GUILayout.EndHorizontal(); EditorGUILayout.BeginVertical(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Texturing"); obj.texMode = EditorGUILayout.Popup(obj.texMode, new string[] { "Original", "Planar Mapping" }); EditorGUILayout.EndHorizontal(); // add if (obj.texMode == CSGObject.TexMode_Planar) { // offset u EditorGUILayout.BeginHorizontal(); float newTexOffsetU = EditorGUILayout.FloatField("OffsetU", obj.globalTexOffsetU); if (obj.globalTexOffsetU != newTexOffsetU) { obj.globalTexOffsetU = newTexOffsetU; obj.TransferFacesToMesh(); } EditorGUILayout.EndHorizontal(); // offset v EditorGUILayout.BeginHorizontal(); float newTexOffsetV = EditorGUILayout.FloatField("OffsetV", obj.globalTexOffsetV); if (obj.globalTexOffsetV != newTexOffsetV) { obj.globalTexOffsetV = newTexOffsetV; obj.TransferFacesToMesh(); } EditorGUILayout.EndHorizontal(); // scale u EditorGUILayout.BeginHorizontal(); float newTexScaleU = EditorGUILayout.FloatField("ScaleU", obj.globalTexScaleU); newTexScaleU = Mathf.Clamp(newTexScaleU, 0.001f, 16.0f); if (obj.globalTexScaleU != newTexScaleU) { obj.globalTexScaleU = newTexScaleU; obj.TransferFacesToMesh(); } EditorGUILayout.EndHorizontal(); // scale v EditorGUILayout.BeginHorizontal(); float newTexScaleV = EditorGUILayout.FloatField("ScaleV", obj.globalTexScaleV); newTexScaleV = Mathf.Clamp(newTexScaleV, 0.001f, 16.0f); if (obj.globalTexScaleV != newTexScaleV) { obj.globalTexScaleV = newTexScaleV; obj.TransferFacesToMesh(); } EditorGUILayout.EndHorizontal(); } EditorGUILayout.EndVertical(); }
/// <summary> /// Performs CSG Operation on this Object (Master) with given Slaves. /// </summary> /// <param name='inOper'> /// In oper. /// </param> /// <param name='inSlaves'> /// In slaves. /// </param> public void PerformCSG(CsgOperation.ECsgOperation inOper, GameObject[] inSlaves) { // CreateFromMesh(); // create bsp generator BspGen gen = new BspGen(GlobalSettings.BspOptimization); rootNode = gen.GenerateBspTree(faces); List <CSGFace> savedFaces = new List <CSGFace>(); // foreach (GameObject g in inSlaves) { CSGObject slave = g.GetComponent <CSGObject>(); // if we have a csg object and we are not our self // and intersecting if (slave && g != gameObject && intersect(slave)) { Debug.Log(g.name); // slave.CreateFromMesh(); // .... BspGen genSlave = new BspGen(GlobalSettings.BspOptimization); slave.rootNode = genSlave.GenerateBspTree(slave.faces); CsgVisitor visitor = null; switch (inOper) { case CsgOperation.ECsgOperation.CsgOper_Additive: visitor = new UnionVisitor(); break; case CsgOperation.ECsgOperation.CsgOper_Subtractive: visitor = new SubtractiveVisitor(); break; case CsgOperation.ECsgOperation.CsgOper_Intersect: visitor = new IntersectVisitor(); break; case CsgOperation.ECsgOperation.CsgOper_DeIntersect: visitor = new DeIntersectVisitor(); break; default: visitor = null; break; } CsgOperation oper = new CsgOperation(visitor); oper.Perform(inOper, this, slave); // save faces savedFaces.AddRange(faces); } } // If we want to merge Coplanars after every Operation if (GlobalSettings.MergeCoplanars) { MergeFaces(); } // for additive or subtracte operation, built faces list from bsp tree // for others, use faces directly if (inOper == CsgOperation.ECsgOperation.CsgOper_Additive || inOper == CsgOperation.ECsgOperation.CsgOper_Subtractive) { // create new face list List <CSGFace> newFaces = new List <CSGFace>(); // create faces from bsp nodes BspHelper.FacesFromNodes(rootNode, newFaces); // copy to face list faces = newFaces; } else { // copy saved faces faces = savedFaces; } // Face.MergeCoplanars( faces ); // copy to unity structure TransferFacesToMesh(); // dumb tree // BspHelper.DumpTree( rootNode ); }