public float getFitScale(Vector2f reference) { Vector2f div = reference / size; return(Mathf.Min(div.x, div.y)); }
public Vector3d(Vector2f copy, double _z) { x = copy.x; y = copy.y; z = _z; }
public bool Contains(Vector2f v) { return(v.grThan(min) && v.lessThan(max)); }
void update_from_endpoints(Vector2f p0, Vector2f p1) { Center = 0.5f * (p0 + p1); Direction = p1 - p0; Extent = 0.5f * Direction.Normalize(); }
private bool is3ds; // usd to shwo that the 4D4D magic number has been found public IOReadResult Read(BinaryReader reader, ReadOptions options, IMeshBuilder builder) { ushort ChunkID; String ChnkID = ""; UInt32 Clength; MeshName = ""; hasMesh = false; is3ds = false; // Process the file - fails very politely when there is no more data while (true) { //Get the Id of the next Chunk try { ChunkID = reader.ReadUInt16(); } catch { break; } ChnkID = ChunkID.ToString("X"); //Get the size of the next chunk in chars Clength = reader.ReadUInt32(); //Process based on Chunk ID switch (ChnkID) { case "4D4D": //This is a new file header is3ds = true; reader.ReadChars(10); break; case "3D3D": //This is a new Object Header reader.ReadChars(10); break; case "4000": //This is an object Block. Store the name temporarily in case it is a mesh List <char> name = new List <char>(); while (true) { char next = reader.ReadChar(); if (next == 0) { break; } name.Add(next); } MeshName = new String(name.ToArray <char>()); break; case "4100": // This is a new Mesh. Retrieve the name and add if the builder supports Metadata builder.AppendNewMesh(false, false, false, false); if (builder.SupportsMetaData) { builder.AppendMetaData("name", MeshName); } break; case "4110": // List of Vertexes ushort VertexCount = reader.ReadUInt16(); for (int x = 0; x < VertexCount; x++) { double X = reader.ReadSingle(); double Y = reader.ReadSingle(); double Z = reader.ReadSingle(); builder.AppendVertex(X, Y, Z); } break; case "4120": // List of Triangles ushort PolygonCount = reader.ReadUInt16(); for (int j = 0; j < PolygonCount; j++) { int a = reader.ReadInt16(); int b = reader.ReadInt16(); int c = reader.ReadInt16(); int flags = reader.ReadUInt16(); builder.AppendTriangle(a, b, c); } break; case "4130": // Mapping from Vertex to Material - retrieved but not currently used List <char> mname = new List <char>(); while (true) { char next = reader.ReadChar(); if (next == 0) { break; } mname.Add(next); } string MatName = new String(mname.ToArray <char>()); ushort entries = reader.ReadUInt16(); for (int i = 0; i < entries; i++) { ushort face = reader.ReadUInt16(); } break; case "4140": // List of UVs per vertex ushort uvCount = reader.ReadUInt16(); for (ushort y = 0; y < uvCount; y++) { Vector2f UV = new Vector2f(reader.ReadSingle(), reader.ReadSingle()); builder.SetVertexUV(y, UV); } break; default: // Any other chunk - retrieved and not used - held in dump temporarily for debug char[] dump = reader.ReadChars((int)Clength - 6); break; } } if (!is3ds) { return(new IOReadResult(IOCode.FileAccessError, "File is not in .3DS format")); } else if (!hasMesh) { return(new IOReadResult(IOCode.FileParsingError, "no mesh found in file")); } else { return(new IOReadResult(IOCode.Ok, "")); } }
protected Vector2f bilerp(ref Vector2f v00, ref Vector2f v10, ref Vector2f v11, ref Vector2f v01, float tx, float ty) { var a = Vector2f.Lerp(ref v00, ref v01, ty); var b = Vector2f.Lerp(ref v10, ref v11, ty); return(Vector2f.Lerp(a, b, tx)); }
public Segment2f(Vector2f center, Vector2f direction, float extent) { Center = center; Direction = direction; Extent = extent; }
public void MoveMin(Vector2f vNewMin) { Max.x = vNewMin.x + (Max.x - Min.x); Max.y = vNewMin.y + (Max.y - Min.y); Min.Set(vNewMin); }
public AxisAlignedBox2f(float fWidth, float fHeight) { Min = new Vector2f(0, 0); Max = new Vector2f(fWidth, fHeight); }
public AxisAlignedBox2f(float fSquareSize) { Min = new Vector2f(0, 0); Max = new Vector2f(fSquareSize, fSquareSize); }
//! relative translation public void Translate(Vector2f vTranslate) { Min.Add(vTranslate); Max.Add(vTranslate); }
public bool Contains(Vector2f v) { return((Min.x < v.x) && (Min.y < v.y) && (Max.x > v.x) && (Max.y > v.y)); }
public AxisAlignedBox2f(float xmin, float ymin, float xmax, float ymax) { Min = new Vector2f(xmin, ymin); Max = new Vector2f(xmax, ymax); }
public AxisAlignedBox2f(bool bIgnore) { Min = new Vector2f(Single.MaxValue, Single.MaxValue); Max = new Vector2f(Single.MinValue, Single.MinValue); }
public override MeshGenerator 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); } } return(this); }
public AxisAlignedBox2f(Vector2f vMin, Vector2f vMax) { Min = new Vector2f(Math.Min(vMin.x, vMax.x), Math.Min(vMin.y, vMax.y)); Max = new Vector2f(Math.Max(vMin.x, vMax.x), Math.Max(vMin.y, vMax.y)); }
public IOWriteResult Write(TextWriter writer, List <WriteMesh> vMeshes, WriteOptions options) { if (options.groupNamePrefix != null) { GroupNamePrefix = options.groupNamePrefix; } if (options.GroupNameF != null) { GroupNameF = options.GroupNameF; } int nAccumCountV = 1; // OBJ indices always start at 1 int nAccumCountUV = 1; // collect materials string sMaterialLib = ""; int nHaveMaterials = 0; if (options.bWriteMaterials && options.MaterialFilePath.Length > 0) { List <GenericMaterial> vMaterials = MeshIOUtil.FindUniqueMaterialList(vMeshes); IOWriteResult ok = write_materials(vMaterials, options); if (ok.code == IOCode.Ok) { sMaterialLib = Path.GetFileName(options.MaterialFilePath); nHaveMaterials = vMeshes.Count; } } if (options.AsciiHeaderFunc != null) { writer.WriteLine(options.AsciiHeaderFunc()); } if (sMaterialLib != "") { writer.WriteLine("mtllib {0}", sMaterialLib); } for (int mi = 0; mi < vMeshes.Count; ++mi) { IMesh mesh = vMeshes[mi].Mesh; if (options.ProgressFunc != null) { options.ProgressFunc(mi, vMeshes.Count); } bool bVtxColors = options.bPerVertexColors && mesh.HasVertexColors; bool bNormals = options.bPerVertexNormals && mesh.HasVertexNormals; // use separate UV set if we have it, otherwise write per-vertex UVs if we have those bool bVtxUVs = options.bPerVertexUVs && mesh.HasVertexUVs; if (vMeshes[mi].UVs != null) { bVtxUVs = false; } int[] mapV = new int[mesh.MaxVertexID]; if (vMeshes[mi].Name != null) { writer.WriteLine("o " + vMeshes[mi].Name); } // write vertices for this mesh foreach (int vi in mesh.VertexIndices()) { mapV[vi] = nAccumCountV++; Vector3d v = mesh.GetVertex(vi); if (bVtxColors) { Vector3d c = mesh.GetVertexColor(vi); writer.WriteLine("v {0} {1} {2} {3:F8} {4:F8} {5:F8}", v[0], v[1], v[2], c[0], c[1], c[2]); } else { writer.WriteLine("v {0} {1} {2}", v[0], v[1], v[2]); } if (bNormals) { Vector3d n = mesh.GetVertexNormal(vi); writer.WriteLine("vn {0:F10} {1:F10} {2:F10}", n[0], n[1], n[2]); } if (bVtxUVs) { Vector2f uv = mesh.GetVertexUV(vi); writer.WriteLine("vt {0:F10} {1:F10}", uv.x, uv.y); } } // write independent UVs for this mesh, if we have them IIndexMap mapUV = (bVtxUVs) ? new IdentityIndexMap() : null; DenseUVMesh uvSet = null; if (vMeshes[mi].UVs != null) { uvSet = vMeshes[mi].UVs; int nUV = uvSet.UVs.Length; IndexMap fullMap = new IndexMap(false, nUV); // [TODO] do we really need a map here? is just integer shift, no? for (int ui = 0; ui < nUV; ++ui) { writer.WriteLine("vt {0:F8} {1:F8}", uvSet.UVs[ui].x, uvSet.UVs[ui].y); fullMap[ui] = nAccumCountUV++; } mapUV = fullMap; } // check if we need to write usemtl lines for this mesh bool bWriteMaterials = nHaveMaterials > 0 && vMeshes[mi].TriToMaterialMap != null && vMeshes[mi].Materials != null; // various ways we can write triangles to minimize state changes... // [TODO] support writing materials when mesh has groups!! if (options.bWriteGroups && mesh.HasTriangleGroups) { write_triangles_bygroup(writer, mesh, mapV, uvSet, mapUV, bNormals); } else { write_triangles_flat(writer, vMeshes[mi], mapV, uvSet, mapUV, bNormals, bWriteMaterials); } if (options.ProgressFunc != null) { options.ProgressFunc(mi + 1, vMeshes.Count); } } return(new IOWriteResult(IOCode.Ok, "")); }
public AxisAlignedBox2f(Vector2f vCenter, float fHalfWidth) { Min = new Vector2f(vCenter.x - fHalfWidth, vCenter.y - fHalfWidth); Max = new Vector2f(vCenter.x + fHalfWidth, vCenter.y + fHalfWidth); }
public void SetVertexUV(int vID, Vector2f UV) { Meshes[nActiveMesh].SetVertexUV(vID, UV); }
public AxisAlignedBox2f(Vector2f vCenter) { Min = Max = vCenter; }
public float Project(Vector2f p) { return((p - Center).Dot(Direction)); }
public AxisAlignedBox2f(AxisAlignedBox2f o) { Min = new Vector2f(o.Min); Max = new Vector2f(o.Max); }
public Vector2d(Vector2f copy) { x = copy.x; y = copy.y; }
public void expandToContain(Vector2f v) { min = min.min(v); max = max.max(v); }
// u^T*M*v public float QForm(Vector2f u, Vector2f v) { return(u.Dot(this * v)); }
override public MeshGenerator 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.FromPlaneUV((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); } } return(this); }