public void UpdateSymmetryType() { int SymmetryCode = SymmetryWindow.GetSymmetryType(); LastSym = SymmetryCode; }
public void GenerateRotationSymmetry(Quaternion Rotation) { Vector3 Euler = Rotation.eulerAngles; switch (LastSym) { case 1: PaintRotations = new Quaternion[2]; PaintRotations[0] = Rotation; PaintRotations[1] = Quaternion.Euler(new Vector3(Euler.x, 180 - Euler.y, Euler.z)) * Quaternion.Euler(Vector3.up * 180); //GetHorizonalSymetry(); //PaintRotations[1] = MassMath.MirrorQuaternionZ(Rotation) * Quaternion.Euler(Vector3.up * 180); //GetHorizonalSymetry(); break; case 2: PaintRotations = new Quaternion[2]; PaintRotations[0] = Rotation; //PaintRotations[1] = MassMath.MirrorQuaternionZ(Rotation); //GetVerticalSymetry(); PaintRotations[1] = Quaternion.Euler(new Vector3(Euler.x, 180 - Euler.y, Euler.z)); //GetHorizonalSymetry(); break; case 3: PaintRotations = new Quaternion[2]; PaintRotations[0] = Rotation; PaintRotations[1] = Quaternion.Euler(new Vector3(Euler.x, 180 + Euler.y, Euler.z)); //GetHorizontalVerticalSymetry(); break; case 4: PaintRotations = new Quaternion[4]; PaintRotations[0] = Rotation; PaintRotations[1] = Quaternion.Euler(new Vector3(Euler.x, 180 - Euler.y, Euler.z)) * Quaternion.Euler(Vector3.up * 180); //GetHorizonalSymetry(); PaintRotations[2] = Quaternion.Euler(new Vector3(Euler.x, 180 - Euler.y, Euler.z)); //GetVerticalSymetry(); PaintRotations[3] = Quaternion.Euler(new Vector3(Euler.x, 180 + Euler.y, Euler.z)); //GetHorizontalVerticalSymetry(); break; case 5: PaintRotations = new Quaternion[2]; PaintRotations[0] = Rotation; PaintRotations[1] = Quaternion.Euler(new Vector3(Euler.x, 180 - Euler.y, Euler.z)) * Quaternion.Euler(Vector3.up * 180); //GetHorizonalSymetry(); break; case 6: PaintRotations = new Quaternion[2]; PaintRotations[0] = Rotation; PaintRotations[1] = Quaternion.Euler(new Vector3(Euler.x, 180 - Euler.y, Euler.z)); //GetHorizonalSymetry(); break; case 7: PaintRotations = new Quaternion[4]; PaintRotations[0] = Rotation; PaintRotations[1] = Quaternion.Euler(new Vector3(Euler.x, 180 - Euler.y, Euler.z)) * Quaternion.Euler(Vector3.up * 180); //GetHorizonalSymetry(); PaintRotations[2] = Quaternion.Euler(new Vector3(Euler.x, 180 - Euler.y, Euler.z)); //GetVerticalSymetry(); PaintRotations[3] = Quaternion.Euler(new Vector3(Euler.x, 180 + Euler.y, Euler.z)); //GetHorizontalVerticalSymetry(); break; case 8: int Count = SymmetryWindow.GetRotationSym(); PaintRotations = new Quaternion[Count]; PaintRotations[0] = Rotation; float angle = 360.0f / (float)Count; for (int i = 1; i < Count; i++) { PaintRotations[i] = Quaternion.Euler(Vector3.up * (angle * i)) * Rotation; } break; default: PaintRotations = new Quaternion[1]; PaintRotations[0] = Rotation; break; } }
// Generate positions - need to be done before paint public void GenerateSymmetry(Vector3 Pos, float Size = 0, float Scatter = 0, float ScatterSize = 0) { BrushPos = Pos; AddScatter(ref BrushPos, Scatter, ScatterSize); if (Size > 0) { /* * BrushPos += (Quaternion.Euler(Vector3.up * Random.Range(0, 360)) * Vector3.forward * * (Size * Mathf.Lerp(1, 0, Mathf.Pow(Random.Range(0f, 1f), 2f))) * ); */ Vector2 BrushCircle = Random.insideUnitCircle * Size; BrushPos.x += BrushCircle.x; BrushPos.z += BrushCircle.y; } switch (LastSym) { case 1: PaintPositions = new Vector3[2]; PaintPositions[0] = BrushPos; PaintPositions[1] = GetHorizonalSymetry(); break; case 2: PaintPositions = new Vector3[2]; PaintPositions[0] = BrushPos; PaintPositions[1] = GetVerticalSymetry(); break; case 3: PaintPositions = new Vector3[2]; PaintPositions[0] = BrushPos; PaintPositions[1] = GetHorizontalVerticalSymetry(); break; case 4: PaintPositions = new Vector3[4]; PaintPositions[0] = BrushPos; PaintPositions[1] = GetHorizonalSymetry(); PaintPositions[2] = GetVerticalSymetry(); PaintPositions[3] = GetHorizontalVerticalSymetry(); break; case 5: PaintPositions = new Vector3[2]; PaintPositions[0] = BrushPos; PaintPositions[1] = GetDiagonal1Symetry(); break; case 6: PaintPositions = new Vector3[2]; PaintPositions[0] = BrushPos; PaintPositions[1] = GetDiagonal2Symetry(); break; case 7: PaintPositions = new Vector3[4]; PaintPositions[0] = BrushPos; PaintPositions[1] = GetDiagonal1Symetry(); PaintPositions[2] = GetDiagonal2Symetry(); PaintPositions[3] = GetDiagonal3Symetry(); break; case 8: int Count = SymmetryWindow.GetRotationSym(); PaintPositions = new Vector3[Count]; PaintPositions[0] = BrushPos; float angle = 360.0f / (float)Count; for (int i = 1; i < Count; i++) { PaintPositions[i] = GetRotationSymetry(angle * i); } break; default: PaintPositions = new Vector3[1]; PaintPositions[0] = BrushPos; break; } }
void Update() { if (!PlacementObject) { enabled = false; return; } if (!SelectionManager.Current.IsPointerOnGameplay()) { return; } Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit hit; if (Physics.Raycast(ray, out hit, 1000, RaycastMask)) { if (LastSym != SymmetryWindow.GetSymmetryType()) { GenerateSymmetry(); } if (!PlacementObject.activeSelf) { PlacementObject.SetActive(true); for (int i = 0; i < PlacementSymmetry.Length; i++) { PlacementSymmetry[i].SetActive(true); } } // Rotate bool Rotating = false; if (SelectionManager.AllowRotation) { if (Input.GetKeyDown(KeyCode.E)) { /*if (MinRotAngle > 1) * { * PlaceAngle += MinRotAngle; * if (PlaceAngle >= 360) * PlaceAngle = 0; * PlacementObject.transform.rotation = Quaternion.Euler(Vector3.up * PlaceAngle); * } * else*/ { RotationStartMousePos = Input.mousePosition; StartRotation = PlacementObject.transform.eulerAngles; } } else if (Input.GetKeyUp(KeyCode.E)) { ChangeControlerType.ChangeCurrentControler(0); } else if (Input.GetKey(KeyCode.E)) { Rotating = true; Vector3 NewRot = StartRotation + Vector3.down * ((Input.mousePosition.x - RotationStartMousePos.x) * 0.5f); if (MinRotAngle > 1) { int ClampedRot = (int)(NewRot.y / MinRotAngle); NewRot.y = MinRotAngle * ClampedRot; } PlacementObject.transform.eulerAngles = NewRot; } } //Scale bool Scaling = false; if (!Rotating && SelectionManager.AllowScale) { if (Input.GetKeyDown(KeyCode.R)) { RotationStartMousePos = Input.mousePosition; StartScale = PlacementObject.transform.localScale; LastHitPoint = hit.point; } else if (Input.GetKeyUp(KeyCode.R)) { ChangeControlerType.ChangeCurrentControler(0); } else if (Input.GetKey(KeyCode.R)) { Scaling = true; Vector3 Scale = StartScale; float ScalingScale = (Scale.x + Scale.y + Scale.z) / 3f; float ScalePower = (Input.mousePosition.x - RotationStartMousePos.x) * 0.003f * ScalingScale; Scale.x = Mathf.Clamp(Scale.x + ScalePower, 0.005f, 100); Scale.y = Mathf.Clamp(Scale.y + ScalePower, 0.005f, 100); Scale.z = Mathf.Clamp(Scale.z + ScalePower, 0.005f, 100); PlacementObject.transform.localScale = Scale; } } if (!Rotating) { Vector3 Point = hit.point; if (Scaling) { Point = LastHitPoint; } if (SelectionManager.Current.SnapToGrid) { PlacementObject.transform.position = ScmapEditor.SnapToGridCenter(Point, true, SnapToWater); } else if (SnapToWater) { PlacementObject.transform.position = ScmapEditor.ClampToWater(Point); } else { PlacementObject.transform.position = Point; } } UpdateSymmetryObjects(); // Action if (Input.GetKey(KeyCode.E) || Input.GetKey(KeyCode.R) || KeyboardManager.BrushSizeHold() || KeyboardManager.BrushStrengthHold()) { } else if (Input.GetMouseButtonDown(0)) { Place(); } } else if (PlacementObject.activeSelf) { PlacementObject.SetActive(false); for (int i = 0; i < PlacementSymmetry.Length; i++) { PlacementSymmetry[i].SetActive(false); } } }
public void GenerateSymmetry() { LastSym = SymmetryWindow.GetSymmetryType(); //LastTolerance = SymmetryWindow.GetTolerance(); for (int i = 0; i < PlacementSymmetry.Length; i++) { Destroy(PlacementSymmetry[i]); } switch (LastSym) { case 1: // X SymmetryMatrix = new Matrix4x4[1]; InvertRotation = new bool[1]; SymmetryMatrix[0] = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(-1, 1, 1)); InvertRotation[0] = true; break; case 2: // Z SymmetryMatrix = new Matrix4x4[1]; InvertRotation = new bool[1]; SymmetryMatrix[0] = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(1, 1, -1)); InvertRotation[0] = true; break; case 3: // XZ SymmetryMatrix = new Matrix4x4[1]; InvertRotation = new bool[1]; SymmetryMatrix[0] = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(-1, 1, -1)); InvertRotation[0] = false; break; case 4: // X Z XZ SymmetryMatrix = new Matrix4x4[3]; InvertRotation = new bool[3]; SymmetryMatrix[0] = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(-1, 1, 1)); InvertRotation[0] = true; SymmetryMatrix[1] = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(1, 1, -1)); InvertRotation[1] = true; SymmetryMatrix[2] = SymmetryMatrix[0] * SymmetryMatrix[1]; InvertRotation[2] = false; //SymmetryMatrix[2] = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(-1, 1, -1)); break; case 5: // Diagonal1 SymmetryMatrix = new Matrix4x4[1]; InvertRotation = new bool[1]; SymmetryMatrix[0] = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(Vector3.up * 90), new Vector3(-1, 1, 1)); InvertRotation[0] = true; break; case 6: // Diagonal 2 SymmetryMatrix = new Matrix4x4[1]; InvertRotation = new bool[1]; SymmetryMatrix[0] = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(Vector3.down * 90), new Vector3(-1, 1, 1)); InvertRotation[0] = true; break; case 7: // Diagonal 3 SymmetryMatrix = new Matrix4x4[3]; InvertRotation = new bool[3]; SymmetryMatrix[0] = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(Vector3.up * 90), new Vector3(-1, 1, 1)); InvertRotation[0] = true; SymmetryMatrix[1] = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(Vector3.down * 90), new Vector3(-1, 1, 1)); InvertRotation[1] = true; SymmetryMatrix[2] = SymmetryMatrix[0] * SymmetryMatrix[1]; InvertRotation[2] = false; break; case 8: // Rotation int RotCount = SymmetryWindow.GetRotationSym() - 1; float angle = 360.0f / (float)(RotCount + 1); SymmetryMatrix = new Matrix4x4[RotCount]; InvertRotation = new bool[RotCount]; for (int i = 0; i < RotCount; i++) { SymmetryMatrix[i] = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(Vector3.up * (angle * (i + 1))), Vector3.one); InvertRotation[i] = false; } break; default: SymmetryMatrix = new Matrix4x4[0]; break; } PlacementSymmetry = new GameObject[SymmetryMatrix.Length]; for (int i = 0; i < PlacementSymmetry.Length; i++) { PlacementSymmetry[i] = Instantiate(PlacementObject) as GameObject; InstantiateAction?.Invoke(PlacementSymmetry[i]); } }
void DoPaintSymmetryPaint() { if (Invert) { float Tolerance = SymmetryWindow.GetTolerance(); BrushGenerator.Current.GenerateSymmetry(BrushPos, 0, Scatter.value, size); float SearchSize = Mathf.Clamp(size, MinimumRenderBrushSize, MaximumBrushSize); PropGameObject ClosestInstance = SearchClosestProp(BrushGenerator.Current.PaintPositions[0], SearchSize); if (ClosestInstance == null) { return; // No props found } BrushPos = ClosestInstance.transform.position; BrushGenerator.Current.GenerateSymmetry(BrushPos, 0, 0, 0); for (int i = 0; i < BrushGenerator.Current.PaintPositions.Length; i++) { if (i == 0) { RegisterUndo(); TotalMassCount -= ClosestInstance.Connected.Group.PropObject.BP.ReclaimMassMax; TotalEnergyCount -= ClosestInstance.Connected.Group.PropObject.BP.ReclaimEnergyMax; TotalReclaimTime -= ClosestInstance.Connected.Group.PropObject.BP.ReclaimTime; ClosestInstance.Connected.Group.PropsInstances.Remove(ClosestInstance.Connected); Destroy(ClosestInstance.gameObject); } else { PropGameObject TestObj = SearchClosestProp(BrushGenerator.Current.PaintPositions[i], Tolerance); if (TestObj != null) { TotalMassCount -= TestObj.Connected.Group.PropObject.BP.ReclaimMassMax; TotalEnergyCount -= TestObj.Connected.Group.PropObject.BP.ReclaimEnergyMax; TotalReclaimTime -= TestObj.Connected.Group.PropObject.BP.ReclaimTime; TestObj.Connected.Group.PropsInstances.Remove(TestObj.Connected); Destroy(TestObj.gameObject); } } } } else { RandomProp = GetRandomProp(); BrushGenerator.Current.GenerateSymmetry(BrushPos, size, Scatter.value, size); float RotMin = PaintButtons[RandomProp].RotationMin.intValue; float RotMax = PaintButtons[RandomProp].RotationMax.intValue; BrushGenerator.Current.GenerateRotationSymmetry(Quaternion.Euler(Vector3.up * Random.Range(RotMin, RotMax))); // Search group id RandomPropGroup = -1; for (int i = 0; i < AllPropsTypes.Count; i++) { if (AllPropsTypes[i].LoadBlueprint == PaintPropObjects[RandomProp].BP.Path) { RandomPropGroup = i; break; } } if (RandomPropGroup < 0) // Create new group { PropTypeGroup NewGroup = new PropTypeGroup(PaintPropObjects[RandomProp]); RandomPropGroup = AllPropsTypes.Count; AllPropsTypes.Add(NewGroup); } //float BrushSlope = ScmapEditor.Current.Teren. int Min = BrushMini.intValue; int Max = BrushMax.intValue; if (Min > 0 || Max < 90) { Vector3 LocalPos = ScmapEditor.Current.Teren.transform.InverseTransformPoint(BrushGenerator.Current.PaintPositions[0]); LocalPos.x /= ScmapEditor.Current.Teren.terrainData.size.x; LocalPos.z /= ScmapEditor.Current.Teren.terrainData.size.z; float angle = Vector3.Angle(Vector3.up, ScmapEditor.Current.Teren.terrainData.GetInterpolatedNormal(LocalPos.x, LocalPos.z)); if ((angle < Min && Min > 0) || (angle > Max && Max < 90)) { return; } } if (!AllowWaterLevel.isOn && ScmapEditor.Current.map.Water.HasWater) { if (ScmapEditor.Current.Teren.SampleHeight(BrushGenerator.Current.PaintPositions[0]) <= ScmapEditor.Current.WaterLevel.position.y) { return; } } for (int i = 0; i < BrushGenerator.Current.PaintPositions.Length; i++) { Paint(BrushGenerator.Current.PaintPositions[i], BrushGenerator.Current.PaintRotations[i]); } } }