public static UnityEngine.Vector2Int GetSpiralPointByIndex(UnityEngine.Vector2Int center, int index) { if (index == 0) { return(center); } // given n an index in the squared spiral // p the sum of point in inner square // a the position on the current square // n = p + a var pos = UnityEngine.Vector2Int.zero; var n = index; var r = Mathf.FloorToInt((Mathf.Sqrt(n + 1) - 1) / 2) + 1; // compute radius : inverse arithmetic sum of 8+16+24+...= var p = (8 * r * (r - 1)) / 2; // compute total point on radius -1 : arithmetic sum of 8+16+24+... var en = r * 2; // points by face var a = (1 + n - p) % (r * 8); // compute de position and shift it so the first is (-r,-r) but (-r+1,-r) // so square can connect //var pos = [0, 0, r]; switch (Mathf.FloorToInt(a / (r * 2f))) { // find the face : 0 top, 1 right, 2, bottom, 3 left case 0: { pos[0] = a - r; pos[1] = -r; } break; case 1: { pos[0] = r; pos[1] = (a % en) - r; } break; case 2: { pos[0] = r - (a % en); pos[1] = r; } break; case 3: { pos[0] = -r; pos[1] = r - (a % en); } break; } return(center + pos); }
public void Validate() { if (surfaceDefinition == null) { surfaceDefinition = new ChiselSurfaceDefinition(); } if (surfaceDefinition.EnsureSize((int)SurfaceSides.TotalSides)) { var defaultRenderMaterial = ChiselMaterialManager.DefaultWallMaterial; var defaultPhysicsMaterial = ChiselMaterialManager.DefaultPhysicsMaterial; surfaceDefinition.surfaces[(int)SurfaceSides.Top].brushMaterial = ChiselBrushMaterial.CreateInstance(ChiselMaterialManager.DefaultFloorMaterial, defaultPhysicsMaterial); surfaceDefinition.surfaces[(int)SurfaceSides.Bottom].brushMaterial = ChiselBrushMaterial.CreateInstance(ChiselMaterialManager.DefaultFloorMaterial, defaultPhysicsMaterial); surfaceDefinition.surfaces[(int)SurfaceSides.Left].brushMaterial = ChiselBrushMaterial.CreateInstance(ChiselMaterialManager.DefaultWallMaterial, defaultPhysicsMaterial); surfaceDefinition.surfaces[(int)SurfaceSides.Right].brushMaterial = ChiselBrushMaterial.CreateInstance(ChiselMaterialManager.DefaultWallMaterial, defaultPhysicsMaterial); surfaceDefinition.surfaces[(int)SurfaceSides.Front].brushMaterial = ChiselBrushMaterial.CreateInstance(ChiselMaterialManager.DefaultWallMaterial, defaultPhysicsMaterial); surfaceDefinition.surfaces[(int)SurfaceSides.Back].brushMaterial = ChiselBrushMaterial.CreateInstance(ChiselMaterialManager.DefaultWallMaterial, defaultPhysicsMaterial); surfaceDefinition.surfaces[(int)SurfaceSides.Tread].brushMaterial = ChiselBrushMaterial.CreateInstance(ChiselMaterialManager.DefaultTreadMaterial, defaultPhysicsMaterial); surfaceDefinition.surfaces[(int)SurfaceSides.Step].brushMaterial = ChiselBrushMaterial.CreateInstance(ChiselMaterialManager.DefaultStepMaterial, defaultPhysicsMaterial); for (int i = 0; i < surfaceDefinition.surfaces.Length; i++) { if (surfaceDefinition.surfaces[i].brushMaterial == null) { surfaceDefinition.surfaces[i].brushMaterial = ChiselBrushMaterial.CreateInstance(defaultRenderMaterial, defaultPhysicsMaterial); } } } stepHeight = Mathf.Max(kMinStepHeight, stepHeight); stepDepth = Mathf.Clamp(stepDepth, kMinStepDepth, absDepth); treadHeight = Mathf.Max(0, treadHeight); nosingDepth = Mathf.Max(0, nosingDepth); nosingWidth = Mathf.Max(0, nosingWidth); width = Mathf.Max(kMinWidth, absWidth) * (width < 0 ? -1 : 1); depth = Mathf.Max(stepDepth, absDepth) * (depth < 0 ? -1 : 1); riserDepth = Mathf.Max(kMinRiserDepth, riserDepth); sideDepth = Mathf.Max(0, sideDepth); sideWidth = Mathf.Max(kMinSideWidth, sideWidth); sideHeight = Mathf.Max(0, sideHeight); var realHeight = Mathf.Max(stepHeight, absHeight); var maxPlateauHeight = realHeight - stepHeight; plateauHeight = Mathf.Clamp(plateauHeight, 0, maxPlateauHeight); var totalSteps = Mathf.Max(1, Mathf.FloorToInt((realHeight - plateauHeight + kStepSmudgeValue) / stepHeight)); var totalStepHeight = totalSteps * stepHeight; plateauHeight = Mathf.Max(0, realHeight - totalStepHeight); stepDepth = Mathf.Clamp(stepDepth, kMinStepDepth, absDepth / totalSteps); }
// Retorna em forma de indíce o ponto para qual esse vetor está apontando. // Considere que o angulo de 360º será dividido em fatias(slices). A função vai // retornar o indice para qual fatia esse vetor está apontando. // Esse indíce vai em sentido anti-horário. public static int VectorToIndex(Vector2 inputVector, int slices) { // Calcula a distancia em graus entre os pontos cardeais float step = 360f / slices; // Calcula metade da distância entre duas fatias. Isso vai ser usado para // que a fatia que representa o norte esteja sempre alinhada com o centro // do circulo. float northOffset = step / 2; // Calculando o angulo formado entre ponto norte(Vector2.up) e o vetor de entrada float angle = Vector2.SignedAngle(Vector2.up, inputVector.normalized); // Adiciona o offset para que o ponto norte seja centralizado angle += northOffset; // Caso o angulo seja negativo, é transformado em positivo adicionando 360 // O angulo retornado pela função SignedAngle é entre -180 e 180 graus. if (angle < 0) { angle += 360; } // Calcula e retorna quantas "fatias" esse angulo ocupa return(Mathf.FloorToInt(angle / step)); }
public void Validate() { if (surfaceAssets == null || surfaceDescriptions.Length != (int)SurfaceSides.TotalSides) { var defaultRenderMaterial = CSGMaterialManager.DefaultWallMaterial; var defaultPhysicsMaterial = CSGMaterialManager.DefaultPhysicsMaterial; surfaceAssets = new CSGSurfaceAsset[(int)SurfaceSides.TotalSides]; surfaceAssets[(int)SurfaceSides.Top] = CSGSurfaceAsset.CreateInstance(CSGMaterialManager.DefaultFloorMaterial, defaultPhysicsMaterial); surfaceAssets[(int)SurfaceSides.Bottom] = CSGSurfaceAsset.CreateInstance(CSGMaterialManager.DefaultFloorMaterial, defaultPhysicsMaterial); surfaceAssets[(int)SurfaceSides.Left] = CSGSurfaceAsset.CreateInstance(CSGMaterialManager.DefaultWallMaterial, defaultPhysicsMaterial); surfaceAssets[(int)SurfaceSides.Right] = CSGSurfaceAsset.CreateInstance(CSGMaterialManager.DefaultWallMaterial, defaultPhysicsMaterial); surfaceAssets[(int)SurfaceSides.Forward] = CSGSurfaceAsset.CreateInstance(CSGMaterialManager.DefaultWallMaterial, defaultPhysicsMaterial); surfaceAssets[(int)SurfaceSides.Back] = CSGSurfaceAsset.CreateInstance(CSGMaterialManager.DefaultWallMaterial, defaultPhysicsMaterial); surfaceAssets[(int)SurfaceSides.Tread] = CSGSurfaceAsset.CreateInstance(CSGMaterialManager.DefaultTreadMaterial, defaultPhysicsMaterial); surfaceAssets[(int)SurfaceSides.Step] = CSGSurfaceAsset.CreateInstance(CSGMaterialManager.DefaultStepMaterial, defaultPhysicsMaterial); for (int i = 0; i < surfaceAssets.Length; i++) { if (surfaceAssets[i] == null) { surfaceAssets[i] = CSGSurfaceAsset.CreateInstance(defaultRenderMaterial, defaultPhysicsMaterial); } } topSurface = surfaceAssets[(int)SurfaceSides.Top]; bottomSurface = surfaceAssets[(int)SurfaceSides.Bottom]; leftSurface = surfaceAssets[(int)SurfaceSides.Left]; rightSurface = surfaceAssets[(int)SurfaceSides.Right]; forwardSurface = surfaceAssets[(int)SurfaceSides.Forward]; backSurface = surfaceAssets[(int)SurfaceSides.Back]; treadSurface = surfaceAssets[(int)SurfaceSides.Tread]; stepSurface = surfaceAssets[(int)SurfaceSides.Step]; } if (surfaceDescriptions == null || surfaceDescriptions.Length != 6) { var surfaceFlags = CSGDefaults.SurfaceFlags; surfaceDescriptions = new SurfaceDescription[6]; for (int i = 0; i < 6; i++) { surfaceDescriptions[i] = new SurfaceDescription { surfaceFlags = surfaceFlags, UV0 = UVMatrix.centered }; } } stepHeight = Mathf.Max(kMinStepHeight, stepHeight); stepDepth = Mathf.Clamp(stepDepth, kMinStepDepth, Mathf.Abs(depth)); treadHeight = Mathf.Max(0, treadHeight); nosingDepth = Mathf.Max(0, nosingDepth); nosingWidth = Mathf.Max(0, nosingWidth); width = Mathf.Max(kMinWidth, Mathf.Abs(width)) * (width < 0 ? -1 : 1); depth = Mathf.Max(stepDepth, Mathf.Abs(depth)) * (depth < 0 ? -1 : 1); riserDepth = Mathf.Max(kMinRiserDepth, riserDepth); sideDepth = Mathf.Max(0, sideDepth); sideWidth = Mathf.Max(kMinSideWidth, sideWidth); sideHeight = Mathf.Max(0, sideHeight); var absHeight = Mathf.Max(stepHeight, Mathf.Abs(height)); var maxPlateauHeight = absHeight - stepHeight; plateauHeight = Mathf.Clamp(plateauHeight, 0, maxPlateauHeight); var totalSteps = Mathf.Max(1, Mathf.FloorToInt((absHeight - plateauHeight) / stepHeight)); var totalStepHeight = totalSteps * stepHeight; plateauHeight = Mathf.Max(0, absHeight - totalStepHeight); stepDepth = Mathf.Clamp(stepDepth, kMinStepDepth, Mathf.Abs(depth) / totalSteps); }
// // TODO: code below needs to be cleaned up & simplified // public void OnEdit(IChiselHandles handles) { var newDefinition = this; { var stepDepthOffset = this.StepDepthOffset; var stepHeight = this.stepHeight; var stepCount = this.StepCount; var bounds = this.bounds; var steps = handles.moveSnappingSteps; steps.y = stepHeight; if (handles.DoBoundsHandle(ref bounds, snappingSteps: steps)) { newDefinition.bounds = bounds; } var min = new Vector3(Mathf.Min(bounds.min.x, bounds.max.x), Mathf.Min(bounds.min.y, bounds.max.y), Mathf.Min(bounds.min.z, bounds.max.z)); var max = new Vector3(Mathf.Max(bounds.min.x, bounds.max.x), Mathf.Max(bounds.min.y, bounds.max.y), Mathf.Max(bounds.min.z, bounds.max.z)); var size = (max - min); var heightStart = bounds.max.y + (bounds.size.y < 0 ? size.y : 0); var edgeHeight = heightStart - stepHeight * stepCount; var pHeight0 = new Vector3(min.x, edgeHeight, max.z); var pHeight1 = new Vector3(max.x, edgeHeight, max.z); var depthStart = bounds.min.z - (bounds.size.z < 0 ? size.z : 0); var pDepth0 = new Vector3(min.x, max.y, depthStart + stepDepthOffset); var pDepth1 = new Vector3(max.x, max.y, depthStart + stepDepthOffset); if (handles.DoTurnHandle(ref bounds)) { newDefinition.bounds = bounds; } if (handles.DoEdgeHandle1D(out edgeHeight, Axis.Y, pHeight0, pHeight1, snappingStep: stepHeight)) { var totalStepHeight = Mathf.Clamp((heightStart - edgeHeight), size.y % stepHeight, size.y); const float kSmudgeValue = 0.0001f; var oldStepCount = newDefinition.StepCount; var newStepCount = Mathf.Max(1, Mathf.FloorToInt((Mathf.Abs(totalStepHeight) + kSmudgeValue) / stepHeight)); newDefinition.stepDepth = (oldStepCount * newDefinition.stepDepth) / newStepCount; newDefinition.plateauHeight = size.y - (stepHeight * newStepCount); } if (handles.DoEdgeHandle1D(out stepDepthOffset, Axis.Z, pDepth0, pDepth1, snappingStep: ChiselLinearStairsDefinition.kMinStepDepth)) { stepDepthOffset -= depthStart; stepDepthOffset = Mathf.Clamp(stepDepthOffset, 0, this.absDepth - ChiselLinearStairsDefinition.kMinStepDepth); newDefinition.stepDepth = ((this.absDepth - stepDepthOffset) / this.StepCount); } float heightOffset; var prevModified = handles.modified; { var direction = Vector3.Cross(Vector3.forward, pHeight0 - pDepth0).normalized; handles.DoEdgeHandle1DOffset(out var height0vec, Axis.Y, pHeight0, pDepth0, direction, snappingStep: stepHeight); handles.DoEdgeHandle1DOffset(out var height1vec, Axis.Y, pHeight1, pDepth1, direction, snappingStep: stepHeight); var height0 = Vector3.Dot(direction, height0vec); var height1 = Vector3.Dot(direction, height1vec); if (Mathf.Abs(height0) > Mathf.Abs(height1)) { heightOffset = height0; } else { heightOffset = height1; } } if (prevModified != handles.modified) { newDefinition.plateauHeight += heightOffset; } } if (handles.modified) { this = newDefinition; } }