public Segment3f(Vector3f p0, Vector3f p1) { //update_from_endpoints(p0, p1); Center = 0.5f * (p0 + p1); Direction = p1 - p0; Extent = 0.5f * Direction.Normalize(); }
public static float PlaneAngleD(Vector3f a, Vector3f b, int nPlaneNormalIdx = 1) { a[nPlaneNormalIdx] = b[nPlaneNormalIdx] = 0.0f; a.Normalize(); b.Normalize(); return(Vector3f.AngleD(a, b)); }
public void Scale(Vector3f s) { Center *= s; Extent *= s; AxisX *= s; AxisX.Normalize(); AxisY *= s; AxisY.Normalize(); AxisZ *= s; AxisZ.Normalize(); }
public Ray3f(Vector3f origin, Vector3f direction, bool bIsNormalized = false) { this.Origin = origin; this.Direction = direction; if (bIsNormalized == false && Direction.IsNormalized == false) { Direction.Normalize(); } }
public static float PlaneAngleSignedD(Vector3f vFrom, Vector3f vTo, int nPlaneNormalIdx = 1) { vFrom[nPlaneNormalIdx] = vTo[nPlaneNormalIdx] = 0.0f; vFrom.Normalize(); vTo.Normalize(); float fSign = Math.Sign(vFrom.Cross(vTo)[nPlaneNormalIdx]); float fAngle = fSign * Vector3f.AngleD(vFrom, vTo); return(fAngle); }
public static float PlaneAngleSignedD(Vector3f vFrom, Vector3f vTo, Vector3f planeN) { vFrom = vFrom - Vector3f.Dot(vFrom, planeN) * planeN; vTo = vTo - Vector3f.Dot(vTo, planeN) * planeN; vFrom.Normalize(); vTo.Normalize(); Vector3f c = Vector3f.Cross(vFrom, vTo); float fSign = Math.Sign(Vector3f.Dot(c, planeN)); float fAngle = fSign * Vector3f.AngleD(vFrom, vTo); return(fAngle); }
public static float PlaneAngleSignedD(Vector3f vFrom, Vector3f vTo, int nPlaneNormalIdx = 1) { vFrom[nPlaneNormalIdx] = vTo[nPlaneNormalIdx] = 0.0f; vFrom.Normalize(); vTo.Normalize(); Vector3f c = vFrom.Cross(vTo); if (c.LengthSquared < MathUtil.ZeroTolerancef) { // vectors are parallel return(vFrom.Dot(vTo) < 0 ? 180.0f : 0); } float fSign = Math.Sign(c[nPlaneNormalIdx]); float fAngle = fSign * Vector3f.AngleD(vFrom, vTo); return(fAngle); }
public static float PlaneAngleSignedD(Vector3f vFrom, Vector3f vTo, Vector3f planeN) { vFrom = vFrom - Vector3f.Dot(vFrom, planeN) * planeN; vTo = vTo - Vector3f.Dot(vTo, planeN) * planeN; vFrom.Normalize(); vTo.Normalize(); var c = Vector3f.Cross(vFrom, vTo); if (c.LengthSquared < MathUtil.ZeroTolerancef) { // vectors are parallel return(vFrom.Dot(vTo) < 0 ? 180.0f : 0); } float fSign = Math.Sign(Vector3f.Dot(c, planeN)); float fAngle = fSign * Vector3f.AngleD(vFrom, vTo); return(fAngle); }
override public MeshGenerator 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) * MathUtil.Deg2Radf; float fStartRad = StartAngleDeg * 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); var 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); } return(this); }
public static Matrix4f CreateRotationFromAxisAngle(Vector3f axis, float angle) { axis.Normalize(); float cos = (float)Math.Cos(-angle); float sin = (float)Math.Sin(-angle); float t = 1f - cos; float txx = t * axis.x * axis.x; float txy = t * axis.x * axis.y; float txz = t * axis.x * axis.z; float tyy = t * axis.y * axis.y; float tyz = t * axis.y * axis.z; float tzz = t * axis.z * axis.z; float sinx = sin * axis.x; float siny = sin * axis.y; float sinz = sin * axis.z; Matrix4f m = Identity; m.Row0 = new Vector4f(txx + cos, txy - sinz, txz + siny, 0f); m.Row1 = new Vector4f(txy + sinz, tyy + cos, tyz - sinx, 0f); m.Row2 = new Vector4f(txy - siny, tyz + sinx, tzz + cos, 0f); m.Row3 = new Vector4f(0f, 0f, 0f, 1f); return(m); }
void update_from_endpoints(Vector3f p0, Vector3f p1) { Center = 0.5f * (p0 + p1); Direction = p1 - p0; Extent = 0.5f * Direction.Normalize(); }
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) * MathUtil.Deg2Radf; float fStartRad = StartAngleDeg * 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) * MathUtil.Deg2Radf; float fStartRad = StartAngleDeg * 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); } } }