Skip to content
This repository has been archived by the owner on Feb 11, 2024. It is now read-only.

Commit

Permalink
Merge pull request #30 from Henry00IS/CurvedStairsFeatures
Browse files Browse the repository at this point in the history
Additional Features for Curved Staircase Compound Brushes
  • Loading branch information
Sabresaurus authored Jan 30, 2018
2 parents 885896a + 6c9e1d6 commit df20e52
Show file tree
Hide file tree
Showing 2 changed files with 274 additions and 63 deletions.
266 changes: 211 additions & 55 deletions Scripts/Brushes/CompoundBrushes/CurvedStairBrush.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,22 @@ public class CurvedStairBrush : CompoundBrush
[SerializeField]
bool counterClockwise = false;

/// <summary>Whether the stairs reach down to the bottom.</summary>
[SerializeField]
bool fillToBottom = true;

/// <summary>Whether to generate stairs or a curved wall.</summary>
[SerializeField]
bool curvedWall = false;

/// <summary>Whether the floor is stairs or a smooth slope.</summary>
[SerializeField]
bool slopedFloor = false;

/// <summary>Whether the ceiling is stairs or a smooth slope.</summary>
[SerializeField]
bool slopedCeiling = false;

/// <summary>The last known extents of the compound brush to detect user resizing the bounds.</summary>
private Vector3 m_LastKnownExtents;
/// <summary>The last known position of the compound brush to prevent movement on resizing the bounds.</summary>
Expand Down Expand Up @@ -102,7 +118,6 @@ public override void Invalidate (bool polygonsChanged)

// local variables
List<Vector3> vertexPositions = new List<Vector3>();
Plane plane;
Vector3 rotateStep = new Vector3();
Vector3 vertex = new Vector3(), newVertex = new Vector3();
float adjustment;
Expand All @@ -128,7 +143,10 @@ public override void Invalidate (bool polygonsChanged)

newVertex = Quaternion.Euler(rotateStep * x) * vertex;
vertexPositions.Add(new Vector3(newVertex.x, vertex.z - adjustment, newVertex.y));
vertex.z += stepHeight;
if (curvedWall)
vertex.z = stepHeight * numSteps;
else
vertex.z += stepHeight;
vertexPositions.Add(new Vector3(newVertex.x, vertex.z, newVertex.y));
}

Expand All @@ -145,7 +163,10 @@ public override void Invalidate (bool polygonsChanged)

newVertex = Quaternion.Euler(rotateStep * x) * vertex;
vertexPositions.Add(new Vector3(newVertex.x, vertex.z - adjustment, newVertex.y));
vertex.z += stepHeight;
if (curvedWall)
vertex.z = stepHeight * numSteps;
else
vertex.z += stepHeight;
vertexPositions.Add(new Vector3(newVertex.x, vertex.z, newVertex.y));
}

Expand Down Expand Up @@ -183,6 +204,14 @@ public override void Invalidate (bool polygonsChanged)
index3 = 3;
}

// we force NoCSG mode if special NoCSG operators are used.
if (curvedWall) { slopedFloor = false; slopedCeiling = false; }
if (fillToBottom) { slopedCeiling = false; }
if (slopedFloor || slopedCeiling)
{
this.IsNoCSG = true;
}

// we calculate the bounds of the output csg.
Bounds csgBounds = new Bounds();

Expand All @@ -207,109 +236,219 @@ public override void Invalidate (bool polygonsChanged)
// | Back | Left | Right | Front | Bottom | Top |
// +--------+--------+--------+--------+--------+--------+



// retrieve the vertices of the top polygon.
Vertex[] vertices = polygons[5].Vertices;

// step top.
vertices[index0].Position = vertexPositions[outerStart + (i * 2) + 2];
vertices[index1].Position = vertexPositions[outerStart + (i * 2) + 1];
vertices[index2].Position = vertexPositions[innerStart + (i * 2) + 1];
vertices[index3].Position = vertexPositions[innerStart + (i * 2) + 2];
if (slopedFloor)
{
// create a smooth slope.
vertices[index0].Position = vertexPositions[outerStart + (i * 2) + 2 + 1];
vertices[index1].Position = vertexPositions[outerStart + (i * 2) + 1];
vertices[index2].Position = vertexPositions[innerStart + (i * 2) + 1];
vertices[index3].Position = vertexPositions[innerStart + (i * 2) + 2 + 1];
}
else
{
// create blocky stairs.
vertices[index0].Position = vertexPositions[outerStart + (i * 2) + 2];
vertices[index1].Position = vertexPositions[outerStart + (i * 2) + 1];
vertices[index2].Position = vertexPositions[innerStart + (i * 2) + 1];
vertices[index3].Position = vertexPositions[innerStart + (i * 2) + 2];
}

// calculate a normal using a virtual plane.
GenerateNormals(polygons[5]);

// update uv coordinates to prevent distortions using barnaby's genius utilities.
vertices[index0].UV = GeometryHelper.GetUVForPosition(polygons[5], vertexPositions[outerStart + (i * 2) + 2]);
vertices[index1].UV = GeometryHelper.GetUVForPosition(polygons[5], vertexPositions[outerStart + (i * 2) + 1]);
vertices[index2].UV = GeometryHelper.GetUVForPosition(polygons[5], vertexPositions[innerStart + (i * 2) + 1]);
vertices[index3].UV = GeometryHelper.GetUVForPosition(polygons[5], vertexPositions[innerStart + (i * 2) + 2]);
GenerateUvCoordinates(polygons[5]);



// retrieve the vertices of the front polygon.
vertices = polygons[3].Vertices;

// step front.
vertices[index0].Position = vertexPositions[outerStart + (i * 2) + 1];
vertices[index1].Position = vertexPositions[bottomOuterStart + i];
vertices[index2].Position = vertexPositions[bottomInnerStart + i];
vertices[index3].Position = vertexPositions[innerStart + (i * 2) + 1];
if (fillToBottom)
{
// fill downwards to the bottom.
vertices[index0].Position = vertexPositions[outerStart + (i * 2) + 1];
vertices[index1].Position = vertexPositions[bottomOuterStart + i];
vertices[index2].Position = vertexPositions[bottomInnerStart + i];
vertices[index3].Position = vertexPositions[innerStart + (i * 2) + 1];
}
else
{
// fill downwards to the step height.
vertices[index0].Position = vertexPositions[outerStart + (i * 2) + 1];
vertices[index1].Position = vertexPositions[outerStart + (i * 2) + 1] - new Vector3(0.0f, stepHeight, 0.0f);
vertices[index2].Position = vertexPositions[innerStart + (i * 2) + 1] - new Vector3(0.0f, stepHeight, 0.0f);
vertices[index3].Position = vertexPositions[innerStart + (i * 2) + 1];
}
if (slopedCeiling)
{
// create a smooth ceiling slope.
vertices[index1].Position -= new Vector3(0.0f, stepHeight, 0.0f);
vertices[index2].Position -= new Vector3(0.0f, stepHeight, 0.0f);
}

// calculate a normal using a virtual plane.
plane = new Plane(vertices[index1].Position, vertices[index2].Position, vertices[index3].Position);
vertices[index0].Normal = plane.normal;
vertices[index1].Normal = plane.normal;
vertices[index2].Normal = plane.normal;
vertices[index3].Normal = plane.normal;
GenerateNormals(polygons[3]);

// update uv coordinates to prevent distortions using barnaby's genius utilities.
GenerateUvCoordinates(polygons[3]);



// retrieve the vertices of the left polygon.
vertices = polygons[1].Vertices;

// inner curve.
vertices[index0].Position = vertexPositions[bottomInnerStart + i + 1];
vertices[index1].Position = vertexPositions[innerStart + (i * 2) + 2];
vertices[index2].Position = vertexPositions[innerStart + (i * 2) + 1];
vertices[index3].Position = vertexPositions[bottomInnerStart + i];
if (fillToBottom)
{
// fill downwards to the bottom.
vertices[index0].Position = vertexPositions[bottomInnerStart + i + 1];
vertices[index1].Position = vertexPositions[innerStart + (i * 2) + 2];
vertices[index2].Position = vertexPositions[innerStart + (i * 2) + 1];
vertices[index3].Position = vertexPositions[bottomInnerStart + i];
}
else
{
// fill downwards to the step height.
vertices[index0].Position = vertexPositions[innerStart + (i * 2) + 2] - new Vector3(0.0f, stepHeight, 0.0f);
vertices[index1].Position = vertexPositions[innerStart + (i * 2) + 2];
vertices[index2].Position = vertexPositions[innerStart + (i * 2) + 1];
vertices[index3].Position = vertexPositions[innerStart + (i * 2) + 1] - new Vector3(0.0f, stepHeight, 0.0f);
}
if (slopedFloor)
{
// create a smooth floor slope.
vertices[index1].Position = vertexPositions[innerStart + (i * 2) + 2 + 1];
}
if (slopedCeiling)
{
// create a smooth ceiling slope.
vertices[index3].Position = vertexPositions[innerStart + (i * 2) + 1] - new Vector3(0.0f, stepHeight * 2.0f, 0.0f);
}

// calculate a normal using a virtual plane.
plane = new Plane(vertices[index1].Position, vertices[index2].Position, vertices[index3].Position);
vertices[index0].Normal = plane.normal;
vertices[index1].Normal = plane.normal;
vertices[index2].Normal = plane.normal;
vertices[index3].Normal = plane.normal;
GenerateNormals(polygons[1]);

// update uv coordinates to prevent distortions using barnaby's genius utilities.
GenerateUvCoordinates(polygons[1]);



// retrieve the vertices of the right polygon.
vertices = polygons[2].Vertices;

// outer curve.
vertices[index0].Position = vertexPositions[outerStart + (i * 2) + 2];
vertices[index1].Position = vertexPositions[bottomOuterStart + i + 1];
vertices[index2].Position = vertexPositions[bottomOuterStart + i];
vertices[index3].Position = vertexPositions[outerStart + (i * 2) + 1];
if (fillToBottom)
{
// fill downwards to the bottom.
vertices[index0].Position = vertexPositions[outerStart + (i * 2) + 2];
vertices[index1].Position = vertexPositions[bottomOuterStart + i + 1];
vertices[index2].Position = vertexPositions[bottomOuterStart + i];
vertices[index3].Position = vertexPositions[outerStart + (i * 2) + 1];
}
else
{
// fill downwards to the step height.
vertices[index0].Position = vertexPositions[outerStart + (i * 2) + 2];
vertices[index1].Position = vertexPositions[outerStart + (i * 2) + 2] - new Vector3(0.0f, stepHeight, 0.0f);
vertices[index2].Position = vertexPositions[outerStart + (i * 2) + 1] - new Vector3(0.0f, stepHeight, 0.0f);
vertices[index3].Position = vertexPositions[outerStart + (i * 2) + 1];
}
if (slopedFloor)
{
// create a smooth floor slope.
vertices[index0].Position = vertexPositions[outerStart + (i * 2) + 2 + 1];
}
if (slopedCeiling)
{
// create a smooth ceiling slope.
vertices[index2].Position = vertexPositions[outerStart + (i * 2) + 1] - new Vector3(0.0f, stepHeight * 2.0f, 0.0f);
}

// calculate a normal using a virtual plane.
plane = new Plane(vertices[index1].Position, vertices[index2].Position, vertices[index3].Position);
vertices[index0].Normal = plane.normal;
vertices[index1].Normal = plane.normal;
vertices[index2].Normal = plane.normal;
vertices[index3].Normal = plane.normal;
GenerateNormals(polygons[2]);

// update uv coordinates to prevent distortions using barnaby's genius utilities.
GenerateUvCoordinates(polygons[2]);



// retrieve the vertices of the bottom polygon.
vertices = polygons[4].Vertices;

// bottom.
vertices[index0].Position = vertexPositions[bottomOuterStart + i];
vertices[index1].Position = vertexPositions[bottomOuterStart + i + 1];
vertices[index2].Position = vertexPositions[bottomInnerStart + i + 1];
vertices[index3].Position = vertexPositions[bottomInnerStart + i];
if (fillToBottom)
{
// fill downwards to the bottom.
vertices[index0].Position = vertexPositions[bottomOuterStart + i];
vertices[index1].Position = vertexPositions[bottomOuterStart + i + 1];
vertices[index2].Position = vertexPositions[bottomInnerStart + i + 1];
vertices[index3].Position = vertexPositions[bottomInnerStart + i];
}
else
{
// fill downwards to the step height.
vertices[index0].Position = vertexPositions[outerStart + (i * 2) + 1] - new Vector3(0.0f, stepHeight, 0.0f);
vertices[index1].Position = vertexPositions[outerStart + (i * 2) + 2] - new Vector3(0.0f, stepHeight, 0.0f);
vertices[index2].Position = vertexPositions[innerStart + (i * 2) + 2] - new Vector3(0.0f, stepHeight, 0.0f);
vertices[index3].Position = vertexPositions[innerStart + (i * 2) + 1] - new Vector3(0.0f, stepHeight, 0.0f);
}
if (slopedCeiling)
{
// create a smooth ceiling slope.
vertices[index0].Position = vertexPositions[outerStart + (i * 2) + 1] - new Vector3(0.0f, stepHeight * 2.0f, 0.0f);
vertices[index3].Position = vertexPositions[innerStart + (i * 2) + 1] - new Vector3(0.0f, stepHeight * 2.0f, 0.0f);
}

// calculate a normal using a virtual plane.
GenerateNormals(polygons[4]);

// update uv coordinates to prevent distortions using barnaby's genius utilities.
vertices[index0].UV = GeometryHelper.GetUVForPosition(polygons[4], vertexPositions[bottomOuterStart + i]);
vertices[index1].UV = GeometryHelper.GetUVForPosition(polygons[4], vertexPositions[bottomOuterStart + i + 1]);
vertices[index2].UV = GeometryHelper.GetUVForPosition(polygons[4], vertexPositions[bottomInnerStart + i + 1]);
vertices[index3].UV = GeometryHelper.GetUVForPosition(polygons[4], vertexPositions[bottomInnerStart + i]);
GenerateUvCoordinates(polygons[4]);



// retrieve the vertices of the back polygon.
vertices = polygons[0].Vertices;

// back panel.
vertices[index0].Position = vertexPositions[bottomOuterStart + i + 1];
vertices[index1].Position = vertexPositions[outerStart + (i * 2) + 2];
vertices[index2].Position = vertexPositions[innerStart + (i * 2) + 2];
vertices[index3].Position = vertexPositions[bottomInnerStart + i + 1];
if (fillToBottom)
{
// fill downwards to the bottom.
vertices[index0].Position = vertexPositions[bottomOuterStart + i + 1];
vertices[index1].Position = vertexPositions[outerStart + (i * 2) + 2];
vertices[index2].Position = vertexPositions[innerStart + (i * 2) + 2];
vertices[index3].Position = vertexPositions[bottomInnerStart + i + 1];
}
else
{
// fill downwards to the step height.
vertices[index0].Position = vertexPositions[outerStart + (i * 2) + 2] - new Vector3(0.0f, stepHeight, 0.0f);
vertices[index1].Position = vertexPositions[outerStart + (i * 2) + 2];
vertices[index2].Position = vertexPositions[innerStart + (i * 2) + 2];
vertices[index3].Position = vertexPositions[innerStart + (i * 2) + 2] - new Vector3(0.0f, stepHeight, 0.0f);
}
if (slopedFloor)
{
// create a smooth floor slope.
vertices[index1].Position = vertexPositions[outerStart + (i * 2) + 2 + 1];
vertices[index2].Position = vertexPositions[innerStart + (i * 2) + 2 + 1];
}

// calculate a normal using a virtual plane.
plane = new Plane(vertices[index1].Position, vertices[index2].Position, vertices[index3].Position);
vertices[index0].Normal = plane.normal;
vertices[index1].Normal = plane.normal;
vertices[index2].Normal = plane.normal;
vertices[index3].Normal = plane.normal;
GenerateNormals(polygons[0]);

// update uv coordinates to prevent distortions using barnaby's genius utilities.
GenerateUvCoordinates(polygons[0]);



generatedBrushes[i].Invalidate(true);
csgBounds.Encapsulate(generatedBrushes[i].GetBounds());
Expand All @@ -320,6 +459,23 @@ public override void Invalidate (bool polygonsChanged)
m_LastKnownExtents = localBounds.extents;
m_LastKnownPosition = transform.localPosition;
}

/// <summary>
/// Generates the UV coordinates for a <see cref="Polygon"/> automatically.
/// </summary>
/// <param name="polygon">The polygon to be updated.</param>
private void GenerateUvCoordinates(Polygon polygon)
{
foreach (Vertex vertex in polygon.Vertices)
vertex.UV = GeometryHelper.GetUVForPosition(polygon, vertex.Position);
}

private void GenerateNormals(Polygon polygon)
{
Plane plane = new Plane(polygon.Vertices[1].Position, polygon.Vertices[2].Position, polygon.Vertices[3].Position);
foreach (Vertex vertex in polygon.Vertices)
vertex.Normal = plane.normal;
}
}
}

Expand Down
Loading

0 comments on commit df20e52

Please sign in to comment.