public void AppendTriangles(IndexArray3i t, int[] groups = null) { Triangles.Add(t.array); if (HasTriangleGroups) { if (groups != null) { FaceGroups.Add(groups); } else { FaceGroups.Add(0, t.Count); } } }
public override void Generate() { vertices = new VectorArray3d((NoSharedVertices) ? (4 * 6) : 8); uv = new VectorArray2f(vertices.Count); normals = new VectorArray3f(vertices.Count); triangles = new IndexArray3i(2 * 6); if (NoSharedVertices == false) { for (int i = 0; i < 8; ++i) { vertices[i] = Box.Corner(i); normals[i] = (Vector3F)(vertices[i] - Box.Center[i]).Normalized; uv[i] = Vector2F.Zero; // what to do for UVs in this case ?!? } int ti = 0; for (int fi = 0; fi < 6; ++fi) { triangles.Set(ti++, gIndices.BoxFaces[fi, 0], gIndices.BoxFaces[fi, 1], gIndices.BoxFaces[fi, 2], Clockwise); triangles.Set(ti++, gIndices.BoxFaces[fi, 0], gIndices.BoxFaces[fi, 2], gIndices.BoxFaces[fi, 3], Clockwise); } } else { int ti = 0; int vi = 0; Vector2F[] square_uv = new Vector2F[4] { Vector2F.Zero, new Vector2F(1, 0), new Vector2F(1, 1), new Vector2F(0, 1) }; for (int fi = 0; fi < 6; ++fi) { int v0 = vi++; vi += 3; int ni = gIndices.BoxFaceNormals[fi]; Vector3F n = (Vector3F)(Math.Sign(ni) * Box.Axis(Math.Abs(ni) - 1)); for (int j = 0; j < 4; ++j) { vertices[v0 + j] = Box.Corner(gIndices.BoxFaces[fi, j]); normals[v0 + j] = n; uv[v0 + j] = square_uv[j]; } triangles.Set(ti++, v0, v0 + 1, v0 + 2, Clockwise); triangles.Set(ti++, v0, v0 + 2, v0 + 3, Clockwise); } } }
private SimpleMesh ToMesh() { int vcount = GetVertexCount(); MdalVertexIterator vi = Mdal.MDAL_M_vertexIterator(this); VectorArray3d v = vi.GetVertexes(vcount); bool hasColors; VectorArray3f c = GetColors(vcount, out hasColors); SimpleMesh mesh = new SimpleMesh(); mesh.AppendVertices(v, null, c); int fcount = GetFaceCount(); MdalFaceIterator fi = Mdal.MDAL_M_faceIterator(this); IndexArray3i tri = fi.GetTris(fcount, Mdal.MDAL_M_faceVerticesMaximumCount(this)); mesh.AppendTriangles(tri); return(mesh); }
void Complete(IntermediateMeshGenerator intermediate) { vertices = new VectorArray3d(intermediate.Vertices.Count); normals = new VectorArray3f(intermediate.Normals.Count); triangles = new IndexArray3i(intermediate.Triangles.Count); for (int idx = 0; idx < intermediate.Vertices.Count; idx++) { vertices[idx] = intermediate.Vertices[idx]; } for (int idx = 0; idx < intermediate.Normals.Count; idx++) { normals[idx] = intermediate.Normals[idx]; } for (int idx = 0; idx < intermediate.Triangles.Count; idx++) { triangles[idx] = intermediate.Triangles[idx]; } }
override public void Generate() { bool bClosed = ((EndAngleDeg - StartAngleDeg) > 359.99f); int nRingSize = (NoSharedVertices && bClosed) ? Slices + 1 : Slices; vertices = new VectorArray3d(2 * nRingSize); uv = new VectorArray2f(vertices.Count); normals = new VectorArray3f(vertices.Count); triangles = new IndexArray3i(2 * Slices); float fTotalRange = (EndAngleDeg - StartAngleDeg) * math.MathUtil.Deg2Radf; float fStartRad = StartAngleDeg * math.MathUtil.Deg2Radf; float fDelta = (bClosed) ? fTotalRange / Slices : fTotalRange / (Slices - 1); for (int k = 0; k < nRingSize; ++k) { float angle = fStartRad + (float)k * fDelta; double cosa = Math.Cos(angle), sina = Math.Sin(angle); vertices[k] = new Vector3D(BaseRadius * cosa, 0, BaseRadius * sina); vertices[nRingSize + k] = new Vector3D(TopRadius * cosa, Height, TopRadius * sina); float t = (float)k / (float)Slices; uv[k] = new Vector2F(t, 0.0f); uv[nRingSize + k] = new Vector2F(t, 1.0f); Vector3F n = new Vector3F((float)cosa, 0, (float)sina); n.Normalize(); normals[k] = normals[nRingSize + k] = n; } int ti = 0; for (int k = 0; k < nRingSize - 1; ++k) { triangles.Set(ti++, k, k + 1, nRingSize + k + 1, Clockwise); triangles.Set(ti++, k, nRingSize + k + 1, nRingSize + k, Clockwise); } if (bClosed && NoSharedVertices == false) // close disc if we went all the way { triangles.Set(ti++, nRingSize - 1, 0, nRingSize, Clockwise); triangles.Set(ti++, nRingSize - 1, nRingSize, 2 * nRingSize - 1, Clockwise); } }
override public void Generate() { vertices = new VectorArray3d(Slices + 1); uv = new VectorArray2f(Slices + 1); normals = new VectorArray3f(Slices + 1); triangles = new IndexArray3i(Slices); int vi = 0; vertices[vi] = Vector3D.Zero; uv[vi] = new Vector2F(0.5f, 0.5f); normals[vi] = Vector3F.AxisY; vi++; bool bFullDisc = ((EndAngleDeg - StartAngleDeg) > 359.99f); float fTotalRange = (EndAngleDeg - StartAngleDeg) * math.MathUtil.Deg2Radf; float fStartRad = StartAngleDeg * math.MathUtil.Deg2Radf; float fDelta = (bFullDisc) ? fTotalRange / Slices : fTotalRange / (Slices - 1); for (int k = 0; k < Slices; ++k) { float a = fStartRad + (float)k * fDelta; double cosa = Math.Cos(a), sina = Math.Sin(a); vertices[vi] = new Vector3D(Radius * cosa, 0, Radius * sina); uv[vi] = new Vector2F(0.5f * (1.0f + cosa), 0.5f * (1 + sina)); normals[vi] = Vector3F.AxisY; vi++; } int ti = 0; for (int k = 1; k < Slices; ++k) { triangles.Set(ti++, k, 0, k + 1, Clockwise); } if (bFullDisc) // close disc if we went all the way { triangles.Set(ti++, Slices, 0, 1, Clockwise); } }
override public void Generate() { vertices = new VectorArray3d(2 * Slices); uv = new VectorArray2f(2 * Slices); normals = new VectorArray3f(2 * Slices); triangles = new IndexArray3i(2 * Slices); bool bFullDisc = ((EndAngleDeg - StartAngleDeg) > 359.99f); float fTotalRange = (EndAngleDeg - StartAngleDeg) * math.MathUtil.Deg2Radf; float fStartRad = StartAngleDeg * math.MathUtil.Deg2Radf; float fDelta = (bFullDisc) ? fTotalRange / Slices : fTotalRange / (Slices - 1); float fUVRatio = InnerRadius / OuterRadius; for (int k = 0; k < Slices; ++k) { float angle = fStartRad + (float)k * fDelta; double cosa = Math.Cos(angle), sina = Math.Sin(angle); vertices[k] = new Vector3D(InnerRadius * cosa, 0, InnerRadius * sina); vertices[Slices + k] = new Vector3D(OuterRadius * cosa, 0, OuterRadius * sina); uv[k] = new Vector2F(0.5f * (1.0f + fUVRatio * cosa), 0.5f * (1.0f + fUVRatio * sina)); uv[Slices + k] = new Vector2F(0.5f * (1.0f + cosa), 0.5f * (1.0f + sina)); normals[k] = normals[Slices + k] = Vector3F.AxisY; } int ti = 0; for (int k = 0; k < Slices - 1; ++k) { triangles.Set(ti++, k, k + 1, Slices + k + 1, Clockwise); triangles.Set(ti++, k, Slices + k + 1, Slices + k, Clockwise); } if (bFullDisc) // close disc if we went all the way { triangles.Set(ti++, Slices - 1, 0, Slices, Clockwise); triangles.Set(ti++, Slices - 1, Slices, 2 * Slices - 1, Clockwise); } }
override public void Generate() { bool bClosed = ((EndAngleDeg - StartAngleDeg) > 359.99f); int nRingSize = (NoSharedVertices && bClosed) ? Slices + 1 : Slices; int nCapVertices = (NoSharedVertices) ? Slices + 1 : 1; int nFaceVertices = (NoSharedVertices && bClosed == false) ? 8 : 0; vertices = new VectorArray3d(2 * nRingSize + 2 * nCapVertices + nFaceVertices); uv = new VectorArray2f(vertices.Count); normals = new VectorArray3f(vertices.Count); int nCylTris = 2 * Slices; int nCapTris = 2 * Slices; int nFaceTris = (bClosed == false) ? 4 : 0; triangles = new IndexArray3i(nCylTris + nCapTris + nFaceTris); groups = new int[triangles.Count]; float fTotalRange = (EndAngleDeg - StartAngleDeg) * math.MathUtil.Deg2Radf; float fStartRad = StartAngleDeg * math.MathUtil.Deg2Radf; float fDelta = (bClosed) ? fTotalRange / Slices : fTotalRange / (Slices - 1); // generate top and bottom rings for cylinder for (int k = 0; k < nRingSize; ++k) { float angle = fStartRad + (float)k * fDelta; double cosa = Math.Cos(angle), sina = Math.Sin(angle); vertices[k] = new Vector3D(BaseRadius * cosa, 0, BaseRadius * sina); vertices[nRingSize + k] = new Vector3D(TopRadius * cosa, Height, TopRadius * sina); float t = (float)k / (float)Slices; uv[k] = new Vector2F(t, 0.0f); uv[nRingSize + k] = new Vector2F(t, 1.0f); Vector3F n = new Vector3F((float)cosa, 0, (float)sina); n.Normalize(); normals[k] = normals[nRingSize + k] = n; } // generate cylinder panels int ti = 0; for (int k = 0; k < nRingSize - 1; ++k) { groups[ti] = 1; triangles.Set(ti++, k, k + 1, nRingSize + k + 1, Clockwise); groups[ti] = 1; triangles.Set(ti++, k, nRingSize + k + 1, nRingSize + k, Clockwise); } if (bClosed && NoSharedVertices == false) // close disc if we went all the way { groups[ti] = 1; triangles.Set(ti++, nRingSize - 1, 0, nRingSize, Clockwise); groups[ti] = 1; triangles.Set(ti++, nRingSize - 1, nRingSize, 2 * nRingSize - 1, Clockwise); } int nBottomC = 2 * nRingSize; vertices[nBottomC] = new Vector3D(0, 0, 0); uv[nBottomC] = new Vector2F(0.5f, 0.5f); normals[nBottomC] = new Vector3F(0, -1, 0); int nTopC = 2 * nRingSize + 1; vertices[nTopC] = new Vector3D(0, Height, 0); uv[nTopC] = new Vector2F(0.5f, 0.5f); normals[nTopC] = new Vector3F(0, 1, 0); if (NoSharedVertices) { int nStartB = 2 * nRingSize + 2; for (int k = 0; k < Slices; ++k) { float a = fStartRad + (float)k * fDelta; double cosa = Math.Cos(a), sina = Math.Sin(a); vertices[nStartB + k] = new Vector3D(BaseRadius * cosa, 0, BaseRadius * sina); uv[nStartB + k] = new Vector2F(0.5f * (1.0f + cosa), 0.5f * (1 + sina)); normals[nStartB + k] = -Vector3F.AxisY; } append_disc(Slices, nBottomC, nStartB, bClosed, Clockwise, ref ti, 2); int nStartT = 2 * nRingSize + 2 + Slices; for (int k = 0; k < Slices; ++k) { float a = fStartRad + (float)k * fDelta; double cosa = Math.Cos(a), sina = Math.Sin(a); vertices[nStartT + k] = new Vector3D(TopRadius * cosa, Height, TopRadius * sina); uv[nStartT + k] = new Vector2F(0.5f * (1.0f + cosa), 0.5f * (1 + sina)); normals[nStartT + k] = Vector3F.AxisY; } append_disc(Slices, nTopC, nStartT, bClosed, !Clockwise, ref ti, 3); // ugh this is very ugly but hard to see the pattern... if (bClosed == false) { int nStartF = 2 * nRingSize + 2 + 2 * Slices; vertices[nStartF] = vertices[nStartF + 5] = vertices[nBottomC]; vertices[nStartF + 1] = vertices[nStartF + 4] = vertices[nTopC]; vertices[nStartF + 2] = vertices[nRingSize]; vertices[nStartF + 3] = vertices[0]; vertices[nStartF + 6] = vertices[nRingSize - 1]; vertices[nStartF + 7] = vertices[2 * nRingSize - 1]; normals[nStartF] = normals[nStartF + 1] = normals[nStartF + 2] = normals[nStartF + 3] = estimate_normal(nStartF, nStartF + 1, nStartF + 2); normals[nStartF + 4] = normals[nStartF + 5] = normals[nStartF + 6] = normals[nStartF + 7] = estimate_normal(nStartF + 4, nStartF + 5, nStartF + 6); uv[nStartF] = uv[nStartF + 5] = new Vector2F(0, 0); uv[nStartF + 1] = uv[nStartF + 4] = new Vector2F(0, 1); uv[nStartF + 2] = uv[nStartF + 7] = new Vector2F(1, 1); uv[nStartF + 3] = uv[nStartF + 6] = new Vector2F(1, 0); append_rectangle(nStartF + 0, nStartF + 1, nStartF + 2, nStartF + 3, !Clockwise, ref ti, 4); append_rectangle(nStartF + 4, nStartF + 5, nStartF + 6, nStartF + 7, !Clockwise, ref ti, 5); } } else { append_disc(Slices, nBottomC, 0, bClosed, Clockwise, ref ti, 2); append_disc(Slices, nTopC, nRingSize, bClosed, !Clockwise, ref ti, 3); if (bClosed == false) { append_rectangle(nBottomC, 0, nRingSize, nTopC, Clockwise, ref ti, 4); append_rectangle(nRingSize - 1, nBottomC, nTopC, 2 * nRingSize - 1, Clockwise, ref ti, 5); } } }
override public void Generate() { int nRings = (NoSharedVertices) ? 2 * (Sections.Length - 1) : Sections.Length; int nRingSize = (NoSharedVertices) ? Slices + 1 : Slices; int nCapVertices = (NoSharedVertices) ? Slices + 1 : 1; if (Capped == false) { nCapVertices = 0; } vertices = new VectorArray3d(nRings * nRingSize + 2 * nCapVertices); uv = new VectorArray2f(vertices.Count); normals = new VectorArray3f(vertices.Count); int nSpanTris = (Sections.Length - 1) * (2 * Slices); int nCapTris = (Capped) ? 2 * Slices : 0; triangles = new IndexArray3i(nSpanTris + nCapTris); float fDelta = (float)((Math.PI * 2.0) / Slices); float fYSpan = Sections.Last().SectionY - Sections[0].SectionY; if (fYSpan == 0) { fYSpan = 1.0f; } // generate top and bottom rings for cylinder int ri = 0; for (int si = 0; si < Sections.Length; ++si) { int nStartR = ri * nRingSize; float y = Sections[si].SectionY; float yt = (y - Sections[0].SectionY) / fYSpan; for (int j = 0; j < nRingSize; ++j) { int k = nStartR + j; float angle = (float)j * fDelta; double cosa = Math.Cos(angle), sina = Math.Sin(angle); vertices[k] = new Vector3D(Sections[si].Radius * cosa, y, Sections[si].Radius * sina); float t = (float)j / (float)(Slices - 1); uv[k] = new Vector2F(t, yt); Vector3F n = new Vector3F((float)cosa, 0, (float)sina); n.Normalize(); normals[k] = n; } ri++; if (NoSharedVertices && si != 0 && si != Sections.Length - 1) { duplicate_vertex_span(nStartR, nRingSize); ri++; } } // generate triangles int ti = 0; ri = 0; for (int si = 0; si < Sections.Length - 1; ++si) { int r0 = ri * nRingSize; int r1 = r0 + nRingSize; ri += (NoSharedVertices) ? 2 : 1; for (int k = 0; k < nRingSize - 1; ++k) { triangles.Set(ti++, r0 + k, r0 + k + 1, r1 + k + 1, Clockwise); triangles.Set(ti++, r0 + k, r1 + k + 1, r1 + k, Clockwise); } if (NoSharedVertices == false) // close disc if we went all the way { triangles.Set(ti++, r1 - 1, r0, r1, Clockwise); triangles.Set(ti++, r1 - 1, r1, r1 + nRingSize - 1, Clockwise); } } if (Capped) { // add endcap verts var s0 = Sections[0]; var sN = Sections.Last(); int nBottomC = nRings * nRingSize; vertices[nBottomC] = new Vector3D(0, s0.SectionY, 0); uv[nBottomC] = new Vector2F(0.5f, 0.5f); normals[nBottomC] = new Vector3F(0, -1, 0); startCapCenterIndex = nBottomC; int nTopC = nBottomC + 1; vertices[nTopC] = new Vector3D(0, sN.SectionY, 0); uv[nTopC] = new Vector2F(0.5f, 0.5f); normals[nTopC] = new Vector3F(0, 1, 0); endCapCenterIndex = nTopC; if (NoSharedVertices) { int nStartB = nTopC + 1; for (int k = 0; k < Slices; ++k) { float a = (float)k * fDelta; double cosa = Math.Cos(a), sina = Math.Sin(a); vertices[nStartB + k] = new Vector3D(s0.Radius * cosa, s0.SectionY, s0.Radius * sina); uv[nStartB + k] = new Vector2F(0.5f * (1.0f + cosa), 0.5f * (1 + sina)); normals[nStartB + k] = -Vector3F.AxisY; } append_disc(Slices, nBottomC, nStartB, true, Clockwise, ref ti); int nStartT = nStartB + Slices; for (int k = 0; k < Slices; ++k) { float a = (float)k * fDelta; double cosa = Math.Cos(a), sina = Math.Sin(a); vertices[nStartT + k] = new Vector3D(sN.Radius * cosa, sN.SectionY, sN.Radius * sina); uv[nStartT + k] = new Vector2F(0.5f * (1.0f + cosa), 0.5f * (1 + sina)); normals[nStartT + k] = Vector3F.AxisY; } append_disc(Slices, nTopC, nStartT, true, !Clockwise, ref ti); } else { append_disc(Slices, nBottomC, 0, true, Clockwise, ref ti); append_disc(Slices, nTopC, nRingSize * (Sections.Length - 1), true, !Clockwise, ref ti); } } }
override public void Generate() { bool bClosed = ((EndAngleDeg - StartAngleDeg) > 359.99f); int nRingSize = (NoSharedVertices && bClosed) ? Slices + 1 : Slices; int nTipVertices = (NoSharedVertices) ? nRingSize : 1; int nCapVertices = (NoSharedVertices) ? Slices + 1 : 1; int nFaceVertices = (NoSharedVertices && bClosed == false) ? 6 : 0; vertices = new VectorArray3d(nRingSize + nTipVertices + nCapVertices + nFaceVertices); uv = new VectorArray2f(vertices.Count); normals = new VectorArray3f(vertices.Count); int nConeTris = (NoSharedVertices) ? 2 * Slices : Slices; int nCapTris = Slices; int nFaceTris = (bClosed == false) ? 2 : 0; triangles = new IndexArray3i(nConeTris + nCapTris + nFaceTris); float fTotalRange = (EndAngleDeg - StartAngleDeg) * math.MathUtil.Deg2Radf; float fStartRad = StartAngleDeg * math.MathUtil.Deg2Radf; float fDelta = (bClosed) ? fTotalRange / Slices : fTotalRange / (Slices - 1); // generate rings for (int k = 0; k < nRingSize; ++k) { float angle = fStartRad + (float)k * fDelta; double cosa = Math.Cos(angle), sina = Math.Sin(angle); vertices[k] = new Vector3D(BaseRadius * cosa, 0, BaseRadius * sina); uv[k] = new Vector2F(0.5f * (1.0f + cosa), 0.5f * (1 + sina)); Vector3F n = new Vector3F(cosa * Height, BaseRadius / Height, sina * Height); n.Normalize(); normals[k] = n; if (NoSharedVertices) { vertices[nRingSize + k] = new Vector3D(0, Height, 0); uv[nRingSize + k] = new Vector2F(0.5f, 0.5f); normals[nRingSize + k] = n; } } if (NoSharedVertices == false) { vertices[nRingSize] = new Vector3D(0, Height, 0); normals[nRingSize] = Vector3F.AxisY; uv[nRingSize] = new Vector2F(0.5f, 0.5f); } // generate cylinder panels int ti = 0; if (NoSharedVertices) { for (int k = 0; k < nRingSize - 1; ++k) { triangles.Set(ti++, k, k + 1, nRingSize + k + 1, Clockwise); triangles.Set(ti++, k, nRingSize + k + 1, nRingSize + k, Clockwise); } } else { append_disc(Slices, nRingSize, 0, bClosed, !Clockwise, ref ti); } int nBottomC = nRingSize + nTipVertices; vertices[nBottomC] = new Vector3D(0, 0, 0); uv[nBottomC] = new Vector2F(0.5f, 0.5f); normals[nBottomC] = new Vector3F(0, -1, 0); if (NoSharedVertices) { int nStartB = nBottomC + 1; for (int k = 0; k < Slices; ++k) { float a = fStartRad + (float)k * fDelta; double cosa = Math.Cos(a), sina = Math.Sin(a); vertices[nStartB + k] = new Vector3D(BaseRadius * cosa, 0, BaseRadius * sina); uv[nStartB + k] = new Vector2F(0.5f * (1.0f + cosa), 0.5f * (1 + sina)); normals[nStartB + k] = -Vector3F.AxisY; } append_disc(Slices, nBottomC, nStartB, bClosed, Clockwise, ref ti); // ugh this is very ugly but hard to see the pattern... if (bClosed == false) { int nStartF = nStartB + Slices; vertices[nStartF] = vertices[nStartF + 4] = vertices[nBottomC]; vertices[nStartF + 1] = vertices[nStartF + 3] = new Vector3D(0, Height, 0);; vertices[nStartF + 2] = vertices[0];; vertices[nStartF + 5] = vertices[nRingSize - 1]; normals[nStartF] = normals[nStartF + 1] = normals[nStartF + 2] = estimate_normal(nStartF, nStartF + 1, nStartF + 2); normals[nStartF + 3] = normals[nStartF + 4] = normals[nStartF + 5] = estimate_normal(nStartF + 3, nStartF + 4, nStartF + 5); uv[nStartF] = uv[nStartF + 4] = new Vector2F(0, 0); uv[nStartF + 1] = uv[nStartF + 3] = new Vector2F(0, 1); uv[nStartF + 2] = uv[nStartF + 5] = new Vector2F(1, 0); triangles.Set(ti++, nStartF + 0, nStartF + 1, nStartF + 2, !Clockwise); triangles.Set(ti++, nStartF + 3, nStartF + 4, nStartF + 5, !Clockwise); } } else { append_disc(Slices, nBottomC, 0, bClosed, Clockwise, ref ti); if (bClosed == false) { triangles.Set(ti++, nBottomC, nRingSize, 0, !Clockwise); triangles.Set(ti++, nBottomC, nRingSize, nRingSize - 1, Clockwise); } } }
public override void Generate() { int nRings = Curve.Length; int nRingSize = (NoSharedVertices) ? Slices + 1 : Slices; int nCapVertices = (NoSharedVertices) ? Slices + 1 : 1; if (Capped == false) { nCapVertices = 0; } vertices = new VectorArray3d(nRingSize * nRings + 2 * nCapVertices); uv = new VectorArray2f(vertices.Count); normals = new VectorArray3f(vertices.Count); int nSpanTris = (nRings - 1) * (2 * Slices); int nCapTris = (Capped) ? 2 * Slices : 0; triangles = new IndexArray3i(nSpanTris + nCapTris); float fDelta = (float)((Math.PI * 2.0) / Slices); Frame3f f = Axis; // generate tube for (int ri = 0; ri < nRings; ++ri) { Vector3D v_along = Curve[ri]; Vector3F v_frame = f.ToFrameP((Vector3F)v_along); float uv_along = (float)ri / (float)(nRings - 1); // generate vertices int nStartR = ri * nRingSize; for (int j = 0; j < nRingSize; ++j) { float angle = (float)j * fDelta; // [TODO] this is not efficient...use Matrix3f? Vector3F v_rot = Quaternionf.AxisAngleR(Vector3F.AxisY, angle) * v_frame; Vector3D v_new = f.FromFrameP(v_rot); int k = nStartR + j; vertices[k] = v_new; float uv_around = (float)j / (float)(nRingSize); uv[k] = new Vector2F(uv_along, uv_around); // [TODO] proper normal Vector3F n = (Vector3F)(v_new - f.Origin).Normalized; normals[k] = n; } } // generate triangles int ti = 0; for (int ri = 0; ri < nRings - 1; ++ri) { int r0 = ri * nRingSize; int r1 = r0 + nRingSize; for (int k = 0; k < nRingSize - 1; ++k) { triangles.Set(ti++, r0 + k, r0 + k + 1, r1 + k + 1, Clockwise); triangles.Set(ti++, r0 + k, r1 + k + 1, r1 + k, Clockwise); } if (NoSharedVertices == false) // close disc if we went all the way { triangles.Set(ti++, r1 - 1, r0, r1, Clockwise); triangles.Set(ti++, r1 - 1, r1, r1 + nRingSize - 1, Clockwise); } } if (Capped) { // find avg start loop size Vector3D vAvgStart = Vector3D.Zero, vAvgEnd = Vector3D.Zero; for (int k = 0; k < Slices; ++k) { vAvgStart += vertices[k]; vAvgEnd += vertices[(nRings - 1) * nRingSize + k]; } vAvgStart /= (double)Slices; vAvgEnd /= (double)Slices; Frame3f fStart = f; fStart.Origin = (Vector3F)vAvgStart; Frame3f fEnd = f; fEnd.Origin = (Vector3F)vAvgEnd; // add endcap verts int nBottomC = nRings * nRingSize; vertices[nBottomC] = fStart.Origin; uv[nBottomC] = new Vector2F(0.5f, 0.5f); normals[nBottomC] = -fStart.Z; startCapCenterIndex = nBottomC; int nTopC = nBottomC + 1; vertices[nTopC] = fEnd.Origin; uv[nTopC] = new Vector2F(0.5f, 0.5f); normals[nTopC] = fEnd.Z; endCapCenterIndex = nTopC; if (NoSharedVertices) { // duplicate first loop and make a fan w/ bottom-center int nExistingB = 0; int nStartB = nTopC + 1; for (int k = 0; k < Slices; ++k) { vertices[nStartB + k] = vertices[nExistingB + k]; //uv[nStartB + k] = (Vector2f)Polygon.Vertices[k].Normalized; float angle = (float)k * fDelta; double cosa = Math.Cos(angle), sina = Math.Sin(angle); uv[nStartB + k] = new Vector2F(0.5f * (1.0f + cosa), 0.5f * (1 + sina)); normals[nStartB + k] = normals[nBottomC]; } append_disc(Slices, nBottomC, nStartB, true, Clockwise, ref ti); // duplicate second loop and make fan int nExistingT = nRingSize * (nRings - 1); int nStartT = nStartB + Slices; for (int k = 0; k < Slices; ++k) { vertices[nStartT + k] = vertices[nExistingT + k]; //uv[nStartT + k] = (Vector2f)Polygon.Vertices[k].Normalized; float angle = (float)k * fDelta; double cosa = Math.Cos(angle), sina = Math.Sin(angle); uv[nStartT + k] = new Vector2F(0.5f * (1.0f + cosa), 0.5f * (1 + sina)); normals[nStartT + k] = normals[nTopC]; } append_disc(Slices, nTopC, nStartT, true, !Clockwise, ref ti); } else { append_disc(Slices, nBottomC, 0, true, Clockwise, ref ti); append_disc(Slices, nTopC, nRingSize * (nRings - 1), true, !Clockwise, ref ti); } } }
public DMesh3 CreateMesh(List <Vector3d> path, List <Polygon2d> polys, VectorArray3d seam) { // Ignore first and last path/polys for mesh generation. // We just need the extra path positions to calculate a // continuous tangent at the seams. List <Vector3d> pathXZ = new List <Vector3d>(); for (int i = 0; i < path.Count; i++) { pathXZ.Add(new Vector3d(path[i].x, 0, path[i].z)); } int nVerts = path.Count - 2; int nPolys = polys.Count - 2; // Same VertexCount for all Polygons. int nSlices = polys[0].VertexCount; int nPolySize = nSlices + 1; int nVecs = nVerts * nPolySize; vertices = new VectorArray3d(nVecs); normals = new VectorArray3f(nVecs); uv = new VectorArray2f(nVecs); int quad_strips = nVerts - 1; int nSpanTris = quad_strips * (2 * nSlices); triangles = new IndexArray3i(nSpanTris); Frame3f fCur = new Frame3f(frame); double pathLength = CurveUtils.ArcLength(path.GetRange(1, nVerts)); double accum_path_u = 0; for (int ri = 0; ri < nPolys; ++ri) { int si = ri + 1; // actual path/polys index for mesh Vector3d tangent = CurveUtils.GetTangent(pathXZ, si); fCur.Origin = (Vector3f)path[si]; fCur.AlignAxis(2, (Vector3f)tangent); int nStartR = ri * nPolySize; double accum_ring_v = 0; bool copy = ri == nPolys - 1; bool paste = ri == 0; for (int j = 0; j < nPolySize; ++j) { int k = nStartR + j; Vector2d pv = polys[si].Vertices[j % nSlices]; Vector2d pvNext = polys[si].Vertices[(j + 1) % nSlices]; Vector3d v = fCur.FromPlaneUV((Vector2f)pv, 2); vertices[k] = v; Vector3f n = (Vector3f)(v - fCur.Origin).Normalized; normals[k] = n; uv[k] = new Vector2f(accum_path_u, accum_ring_v); accum_ring_v += (pv.Distance(pvNext) / polys[si].ArcLength); if (copy) { Seam[j] = vertices[k]; } else if (paste) { vertices[k] = seam[j]; } } double d = path[si].Distance(path[si + 1]); accum_path_u += d / pathLength; } int nStop = nVerts - 1; int ti = 0; for (int ri = 0; ri < nStop; ++ri) { int r0 = ri * nPolySize; int r1 = r0 + nPolySize; for (int k = 0; k < nPolySize - 1; ++k) { triangles.Set(ti++, r0 + k, r0 + k + 1, r1 + k + 1, Clockwise); triangles.Set(ti++, r0 + k, r1 + k + 1, r1 + k, Clockwise); } } return(MakeDMesh()); }
override public void Generate() { vertices = new VectorArray3d(4); uv = new VectorArray2f(4); normals = new VectorArray3f(4); triangles = new IndexArray3i(2); vertices[0] = new Vector3D(-Width / 2.0f, 0, -Height / 2.0f); vertices[1] = new Vector3D(Width / 2.0f, 0, -Height / 2.0f); vertices[2] = new Vector3D(Width / 2.0f, 0, Height / 2.0f); vertices[3] = new Vector3D(-Width / 2.0f, 0, Height / 2.0f); normals[0] = normals[1] = normals[2] = normals[3] = Vector3F.AxisY; float uvleft = 0.0f, uvright = 1.0f, uvbottom = 0.0f, uvtop = 1.0f; // if we want the UV subregion, we assume it is if (UVMode != UVModes.FullUVSquare) { if (Width > Height) { float a = Height / Width; if (UVMode == UVModes.CenteredUVRectangle) { uvbottom = 0.5f - a / 2.0f; uvtop = 0.5f + a / 2.0f; } else { uvtop = a; } } else if (Height > Width) { float a = Width / Height; if (UVMode == UVModes.CenteredUVRectangle) { uvleft = 0.5f - a / 2.0f; uvright = 0.5f + a / 2.0f; } else { uvright = a; } } } uv[0] = new Vector2F(uvleft, uvbottom); uv[1] = new Vector2F(uvright, uvbottom); uv[2] = new Vector2F(uvright, uvtop); uv[3] = new Vector2F(uvleft, uvtop); if (Clockwise == true) { triangles.Set(0, 0, 1, 2); triangles.Set(1, 0, 2, 3); } else { triangles.Set(0, 0, 2, 1); triangles.Set(1, 0, 3, 2); } }
override public void Generate() { int corner_v = 0, corner_t = 0; for (int k = 0; k < 4; ++k) { if (((int)SharpCorners & (1 << k)) != 0) { corner_v += 1; corner_t += 2; } else { corner_v += CornerSteps; corner_t += (CornerSteps + 1); } } vertices = new VectorArray3d(12 + corner_v); uv = new VectorArray2f(vertices.Count); normals = new VectorArray3f(vertices.Count); triangles = new IndexArray3i(10 + corner_t); float innerW = Width - 2 * Radius; float innerH = Height - 2 * Radius; // make vertices for inner "cross" (ie 5 squares) vertices[0] = new Vector3D(-innerW / 2.0f, 0, -innerH / 2.0f); vertices[1] = new Vector3D(innerW / 2.0f, 0, -innerH / 2.0f); vertices[2] = new Vector3D(innerW / 2.0f, 0, innerH / 2.0f); vertices[3] = new Vector3D(-innerW / 2.0f, 0, innerH / 2.0f); vertices[4] = new Vector3D(-innerW / 2, 0, -Height / 2); vertices[5] = new Vector3D(innerW / 2, 0, -Height / 2); vertices[6] = new Vector3D(Width / 2, 0, -innerH / 2); vertices[7] = new Vector3D(Width / 2, 0, innerH / 2); vertices[8] = new Vector3D(innerW / 2, 0, Height / 2); vertices[9] = new Vector3D(-innerW / 2, 0, Height / 2); vertices[10] = new Vector3D(-Width / 2, 0, innerH / 2); vertices[11] = new Vector3D(-Width / 2, 0, -innerH / 2); // make triangles for inner cross bool cycle = (Clockwise == false); int ti = 0; append_rectangle(0, 1, 2, 3, cycle, ref ti); append_rectangle(4, 5, 1, 0, cycle, ref ti); append_rectangle(1, 6, 7, 2, cycle, ref ti); append_rectangle(3, 2, 8, 9, cycle, ref ti); append_rectangle(11, 0, 3, 10, cycle, ref ti); int vi = 12; for (int j = 0; j < 4; ++j) { bool sharp = ((int)SharpCorners & (1 << j)) > 0; if (sharp) { append_2d_disc_segment(corner_spans[3 * j], corner_spans[3 * j + 1], corner_spans[3 * j + 2], 1, cycle, ref vi, ref ti, -1, math.MathUtil.SqrtTwo * Radius); } else { append_2d_disc_segment(corner_spans[3 * j], corner_spans[3 * j + 1], corner_spans[3 * j + 2], CornerSteps, cycle, ref vi, ref ti); } } for (int k = 0; k < vertices.Count; ++k) { normals[k] = Vector3F.AxisY; } float uvleft = 0.0f, uvright = 1.0f, uvbottom = 0.0f, uvtop = 1.0f; // if we want the UV subregion, we assume it is if (UVMode != UVModes.FullUVSquare) { if (Width > Height) { float a = Height / Width; if (UVMode == UVModes.CenteredUVRectangle) { uvbottom = 0.5f - a / 2.0f; uvtop = 0.5f + a / 2.0f; } else { uvtop = a; } } else if (Height > Width) { float a = Width / Height; if (UVMode == UVModes.CenteredUVRectangle) { uvleft = 0.5f - a / 2.0f; uvright = 0.5f + a / 2.0f; } else { uvright = a; } } } Vector3D c = new Vector3D(-Width / 2, 0, -Height / 2); for (int k = 0; k < vertices.Count; ++k) { Vector3D v = vertices[k]; double tx = (v.x - c.x) / Width; double ty = (v.y - c.y) / Height; uv[k] = new Vector2F((1 - tx) * uvleft + (tx) * uvright, (1 - ty) * uvbottom + (ty) * uvtop); } }
override public void Generate() { if (Polygon == null) { Polygon = Polygon2d.MakeCircle(1.0f, 8); } int Slices = Polygon.VertexCount; int nRings = Vertices.Count; int nRingSize = (NoSharedVertices) ? Slices + 1 : Slices; int nCapVertices = (NoSharedVertices) ? Slices + 1 : 1; if (Capped == false) { nCapVertices = 0; } vertices = new VectorArray3d(nRings * nRingSize + 2 * nCapVertices); uv = new VectorArray2f(vertices.Count); normals = new VectorArray3f(vertices.Count); int nSpanTris = (Vertices.Count - 1) * (2 * Slices); int nCapTris = (Capped) ? 2 * Slices : 0; triangles = new IndexArray3i(nSpanTris + nCapTris); Frame3f fCur = new Frame3f(Frame); Vector3D dv = CurveUtils.GetTangent(Vertices, 0);; fCur.Origin = (Vector3F)Vertices[0]; fCur.AlignAxis(2, (Vector3F)dv); Frame3f fStart = new Frame3f(fCur); // generate tube for (int ri = 0; ri < nRings; ++ri) { // propagate frame if (ri != 0) { Vector3D tan = CurveUtils.GetTangent(Vertices, ri); fCur.Origin = (Vector3F)Vertices[ri]; if (ri == 11) { dv = tan; } fCur.AlignAxis(2, (Vector3F)tan); } float uv_along = (float)ri / (float)(nRings - 1); // generate vertices int nStartR = ri * nRingSize; for (int j = 0; j < nRingSize; ++j) { float uv_around = (float)j / (float)(nRings); int k = nStartR + j; Vector2D pv = Polygon.Vertices[j % Slices]; Vector3D v = fCur.FromFrameP((Vector2F)pv, 2); vertices[k] = v; uv[k] = new Vector2F(uv_along, uv_around); Vector3F n = (Vector3F)(v - fCur.Origin).Normalized; normals[k] = n; } } // generate triangles int ti = 0; for (int ri = 0; ri < nRings - 1; ++ri) { int r0 = ri * nRingSize; int r1 = r0 + nRingSize; for (int k = 0; k < nRingSize - 1; ++k) { triangles.Set(ti++, r0 + k, r0 + k + 1, r1 + k + 1, Clockwise); triangles.Set(ti++, r0 + k, r1 + k + 1, r1 + k, Clockwise); } if (NoSharedVertices == false) // close disc if we went all the way { triangles.Set(ti++, r1 - 1, r0, r1, Clockwise); triangles.Set(ti++, r1 - 1, r1, r1 + nRingSize - 1, Clockwise); } } if (Capped) { // add endcap verts int nBottomC = nRings * nRingSize; vertices[nBottomC] = fStart.Origin; uv[nBottomC] = new Vector2F(0.5f, 0.5f); normals[nBottomC] = -fStart.Z; startCapCenterIndex = nBottomC; int nTopC = nBottomC + 1; vertices[nTopC] = fCur.Origin; uv[nTopC] = new Vector2F(0.5f, 0.5f); normals[nTopC] = fCur.Z; endCapCenterIndex = nTopC; if (NoSharedVertices) { // duplicate first loop and make a fan w/ bottom-center int nExistingB = 0; int nStartB = nTopC + 1; for (int k = 0; k < Slices; ++k) { vertices[nStartB + k] = vertices[nExistingB + k]; uv[nStartB + k] = (Vector2F)Polygon.Vertices[k].Normalized; normals[nStartB + k] = normals[nBottomC]; } append_disc(Slices, nBottomC, nStartB, true, Clockwise, ref ti); // duplicate second loop and make fan int nExistingT = nRingSize * (nRings - 1); int nStartT = nStartB + Slices; for (int k = 0; k < Slices; ++k) { vertices[nStartT + k] = vertices[nExistingT + k]; uv[nStartT + k] = (Vector2F)Polygon.Vertices[k].Normalized; normals[nStartT + k] = normals[nTopC]; } append_disc(Slices, nTopC, nStartT, true, !Clockwise, ref ti); } else { append_disc(Slices, nBottomC, 0, true, Clockwise, ref ti); append_disc(Slices, nTopC, nRingSize * (nRings - 1), true, !Clockwise, ref ti); } } }