예제 #1
0
	public static pb_Object StairGenerator(Vector3 size, int steps, bool buildSides)
	{
		/// 4 vertices per quad, 2 quads per step.
		Vector3[] vertices = new Vector3[4 * steps * 2];
		pb_Face[] faces = new pb_Face[steps * 2];

		/// vertex index, face index
		int v = 0, t = 0;

		for(int i = 0; i < steps; i++)
		{
			float inc0 = i / (float) steps;
			float inc1 = (i + 1) / (float) steps;

			float x0 = size.x;
			float x1 = 0;
			float y0 = size.y * inc0;
			float y1 = size.y * inc1;
			float z0 = size.z * inc0;
			float z1 = size.z * inc1;

			vertices[v+0] = new Vector3(x0, y0, z0);
			vertices[v+1] = new Vector3(x1, y0, z0);
			vertices[v+2] = new Vector3(x0, y1, z0);
			vertices[v+3] = new Vector3(x1, y1, z0);

			vertices[v+4] = new Vector3(x0, y1, z0);
			vertices[v+5] = new Vector3(x1, y1, z0);
			vertices[v+6] = new Vector3(x0, y1, z1);
			vertices[v+7] = new Vector3(x1, y1, z1);

			faces[t+0] = new pb_Face( new int[] { 	v + 0,
													v + 1,
													v + 2,
													v + 1,
													v + 3,
													v + 2 });

			faces[t+1] = new pb_Face( new int[] { 	v + 4,
													v + 5,
													v + 6,
													v + 5,
													v + 7,
													v + 6 });

			v += 8;
			t += 2;
		}

		/// sides
		if(buildSides)
		{
			/// first step is special case - only needs a quad, but all other steps need
			/// a quad and tri.
			float x = 0f;

			for(int side = 0; side < 2; side++)
			{
				Vector3[] sides_v = new Vector3[ steps * 4 + (steps - 1) * 3 ];
				pb_Face[] sides_f = new pb_Face[ steps + steps-1 ];

				int sv = 0, st = 0;

				for(int i = 0; i < steps; i++)
				{
					float y0 = (Mathf.Max(i, 1) / (float) steps) * size.y;
					float y1 = ((i+1) / (float) steps) * size.y;

					float z0 = (i / (float)steps) * size.z;
					float z1 = ((i+1) / (float) steps) * size.z;

					sides_v[sv+0] = new Vector3(x, 0f, z0);
					sides_v[sv+1] = new Vector3(x, 0f, z1);
					sides_v[sv+2] = new Vector3(x, y0, z0);
					sides_v[sv+3] = new Vector3(x, y1, z1);

					sides_f[st++] = new pb_Face( side % 2 == 0 ?
						new int[] { v+0, v+1, v+2, v+1, v+3, v+2 } :
						new int[] { v+2, v+1, v+0, v+2, v+3, v+1 } );

					sides_f[st-1].textureGroup = side + 1;

					v += 4;
					sv += 4;

					/// that connecting triangle
					if(i > 0)
					{
						sides_v[sv+0] = new Vector3(x, y0, z0);
						sides_v[sv+1] = new Vector3(x, y1, z0);
						sides_v[sv+2] = new Vector3(x, y1, z1);

						sides_f[st++] = new pb_Face( side % 2 == 0 ? 
							new int[] { v+2, v+1, v+0 } :
							new int[] { v+0, v+1, v+2 } );

						sides_f[st-1].textureGroup = side + 1;

						v += 3;
						sv += 3;
					}
				}

				vertices = vertices.Concat(sides_v);
				faces = faces.Concat(sides_f);

				x += size.x;
			}

			// add that last back face
			vertices = vertices.Concat(new Vector3[] {
				new Vector3(0f, 0f, size.z),
				new Vector3(size.x, 0f, size.z),
				new Vector3(0f, size.y, size.z),
				new Vector3(size.x, size.y, size.z)
				});

			faces = faces.Add(new pb_Face(new int[] {v+0, v+1, v+2, v+1, v+3, v+2}));
		}

		pb_Object pb = pb_Object.CreateInstanceWithVerticesFaces(vertices, faces);
		pb.SetName("Stairs"); 

		return pb;	
	}
예제 #2
0
	public static pb_Object CurvedStairGenerator(float stairWidth, float height, float innerRadius, float circumference, int steps, bool buildSides)
	{
		bool noInnerSide = innerRadius < Mathf.Epsilon;

		/// 4 vertices per quad, vertical step first, then floor step can be 3 or 4 verts depending on
		/// if the inner radius is 0 or not.
		Vector3[] vertices = new Vector3[(4 * steps) + ((noInnerSide ? 3 : 4) * steps)];
		pb_Face[] faces = new pb_Face[steps * 2];

		/// vertex index, face index
		int v = 0, t = 0;

		float cir = Mathf.Abs(circumference) * Mathf.Deg2Rad;
		float outerRadius = innerRadius + stairWidth;

		for(int i = 0; i < steps; i++)
		{
			float inc0 = (i / (float) steps) * cir;
			float inc1 = ((i + 1) / (float) steps) * cir;

			float h0 = ((i / (float) steps) * height);
			float h1 = (((i+1) / (float) steps) * height);

			Vector3 v0 = new Vector3(-Mathf.Cos(inc0), 0f, Mathf.Sin(inc0) );
			Vector3 v1 = new Vector3(-Mathf.Cos(inc1), 0f, Mathf.Sin(inc1) );

			/**
			 * 
			 *		/6-----/7
			 *	   /	  /
			 *	  /5_____/4
			 *	  |3	 |2
			 *	  |		 |
			 *	  |1_____|0
			 *
			 */

			vertices[v+0] = v0 * innerRadius;
			vertices[v+1] = v0 * outerRadius;
			vertices[v+2] = v0 * innerRadius;
			vertices[v+3] = v0 * outerRadius;

			vertices[v+0].y = h0;
			vertices[v+1].y = h0;
			vertices[v+2].y = h1;
			vertices[v+3].y = h1;

			vertices[v+4] = vertices[v+2];
			vertices[v+5] = vertices[v+3];

			vertices[v+6] = v1 * outerRadius;
			vertices[v+6].y = h1;

			if(!noInnerSide)
			{
				vertices[v+7] = v1 * innerRadius;
				vertices[v+7].y = h1;
			}
			
			faces[t+0] = new pb_Face( new int[] { 	
				v + 0,
				v + 1,
				v + 2,
				v + 1,
				v + 3,
				v + 2 });

			if(noInnerSide)
			{
				faces[t+1] = new pb_Face( new int[] {
					v + 4,
					v + 5,
					v + 6 });
			}
			else
			{
				faces[t+1] = new pb_Face( new int[] {
					v + 4,
					v + 5,
					v + 6,
					v + 4,
					v + 6,
					v + 7 });
			}

			v += noInnerSide ? 7 : 8;
			t += 2;
		}

		/// sides
		if(buildSides)
		{
			/// first step is special case - only needs a quad, but all other steps need
			/// a quad and tri.
			float x = noInnerSide ? innerRadius + stairWidth : innerRadius;;

			for(int side = (noInnerSide ? 1 : 0); side < 2; side++)
			{
				Vector3[] sides_v = new Vector3[ steps * 4 + (steps - 1) * 3 ];
				pb_Face[] sides_f = new pb_Face[ steps + steps-1 ];

				int sv = 0, st = 0;

				for(int i = 0; i < steps; i++)
				{
					float inc0 = (i / (float) steps) * cir;
					float inc1 = ((i + 1) / (float) steps) * cir;

					float h0 = ((Mathf.Max(i, 1) / (float) steps) * height);
					float h1 = (((i+1) / (float) steps) * height);

					Vector3 v0 = new Vector3(-Mathf.Cos(inc0), 0f, Mathf.Sin(inc0) ) * x;
					Vector3 v1 = new Vector3(-Mathf.Cos(inc1), 0f, Mathf.Sin(inc1) ) * x;	

					sides_v[sv+0] = v0;
					sides_v[sv+1] = v1;
					sides_v[sv+2] = v0;
					sides_v[sv+3] = v1;

					sides_v[sv+0].y = 0f;
					sides_v[sv+1].y = 0f;
					sides_v[sv+2].y = h0;
					sides_v[sv+3].y = h1;

					sides_f[st++] = new pb_Face( side % 2 == 0 ?
						new int[] { v+2, v+1, v+0, v+2, v+3, v+1 } :
						new int[] { v+0, v+1, v+2, v+1, v+3, v+2 } );

					
					v += 4;
					sv += 4;

					/// that connecting triangle
					if(i > 0)
					{
						sides_f[st-1].textureGroup = (side * steps) + i;

						sides_v[sv+0] = v0;
						sides_v[sv+1] = v1;
						sides_v[sv+2] = v0;
						sides_v[sv+0].y = h0;
						sides_v[sv+1].y = h1;
						sides_v[sv+2].y = h1;

						sides_f[st++] = new pb_Face( side % 2 == 0 ? 
							new int[] { v+2, v+1, v+0 } :
							new int[] { v+0, v+1, v+2 } );

						sides_f[st-1].textureGroup = (side * steps) + i;

						v += 3;
						sv += 3;
					}
				}

				vertices = vertices.Concat(sides_v);
				faces = faces.Concat(sides_f);

				x += stairWidth;
			}

			// // add that last back face
			float cos = -Mathf.Cos(cir), sin = Mathf.Sin(cir);

			vertices = vertices.Concat(new Vector3[] 
			{
				new Vector3(cos, 0f, sin) * innerRadius,
				new Vector3(cos, 0f, sin) * outerRadius,
				new Vector3(cos * innerRadius, height, sin * innerRadius),
				new Vector3(cos * outerRadius, height, sin * outerRadius)
				});

			faces = faces.Add(new pb_Face(new int[] {v+2, v+1, v+0, v+2, v+3, v+1}));
		}

		if(circumference < 0f)
		{
			Vector3 flip = new Vector3(-1f, 1f, 1f);

			for(int i = 0; i < vertices.Length; i++)
			{
				vertices[i].Scale(flip);
			}

			foreach(pb_Face f in faces)
				f.ReverseIndices();
		}

		pb_Object pb = pb_Object.CreateInstanceWithVerticesFaces(vertices, faces);
		pb.SetName("Stairs"); 

		return pb;	
	}