Пример #1
0
        public float getFitScale(Vector2f reference)
        {
            Vector2f div = reference / size;

            return(Mathf.Min(div.x, div.y));
        }
Пример #2
0
 public Vector3d(Vector2f copy, double _z)
 {
     x = copy.x; y = copy.y; z = _z;
 }
Пример #3
0
 public bool Contains(Vector2f v)
 {
     return(v.grThan(min) && v.lessThan(max));
 }
Пример #4
0
 void update_from_endpoints(Vector2f p0, Vector2f p1)
 {
     Center    = 0.5f * (p0 + p1);
     Direction = p1 - p0;
     Extent    = 0.5f * Direction.Normalize();
 }
Пример #5
0
        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, ""));
            }
        }
Пример #6
0
        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));
        }
Пример #7
0
 public Segment2f(Vector2f center, Vector2f direction, float extent)
 {
     Center = center; Direction = direction; Extent = extent;
 }
Пример #8
0
 public void MoveMin(Vector2f vNewMin)
 {
     Max.x = vNewMin.x + (Max.x - Min.x);
     Max.y = vNewMin.y + (Max.y - Min.y);
     Min.Set(vNewMin);
 }
Пример #9
0
 public AxisAlignedBox2f(float fWidth, float fHeight)
 {
     Min = new Vector2f(0, 0);
     Max = new Vector2f(fWidth, fHeight);
 }
Пример #10
0
 public AxisAlignedBox2f(float fSquareSize)
 {
     Min = new Vector2f(0, 0);
     Max = new Vector2f(fSquareSize, fSquareSize);
 }
Пример #11
0
 //! relative translation
 public void Translate(Vector2f vTranslate)
 {
     Min.Add(vTranslate);
     Max.Add(vTranslate);
 }
Пример #12
0
 public bool Contains(Vector2f v)
 {
     return((Min.x < v.x) && (Min.y < v.y) && (Max.x > v.x) && (Max.y > v.y));
 }
Пример #13
0
 public AxisAlignedBox2f(float xmin, float ymin, float xmax, float ymax)
 {
     Min = new Vector2f(xmin, ymin);
     Max = new Vector2f(xmax, ymax);
 }
Пример #14
0
 public AxisAlignedBox2f(bool bIgnore)
 {
     Min = new Vector2f(Single.MaxValue, Single.MaxValue);
     Max = new Vector2f(Single.MinValue, Single.MinValue);
 }
Пример #15
0
        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);
        }
Пример #16
0
 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));
 }
Пример #17
0
        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, ""));
        }
Пример #18
0
 public AxisAlignedBox2f(Vector2f vCenter, float fHalfWidth)
 {
     Min = new Vector2f(vCenter.x - fHalfWidth, vCenter.y - fHalfWidth);
     Max = new Vector2f(vCenter.x + fHalfWidth, vCenter.y + fHalfWidth);
 }
Пример #19
0
 public void SetVertexUV(int vID, Vector2f UV)
 {
     Meshes[nActiveMesh].SetVertexUV(vID, UV);
 }
Пример #20
0
 public AxisAlignedBox2f(Vector2f vCenter)
 {
     Min = Max = vCenter;
 }
Пример #21
0
 public float Project(Vector2f p)
 {
     return((p - Center).Dot(Direction));
 }
Пример #22
0
 public AxisAlignedBox2f(AxisAlignedBox2f o)
 {
     Min = new Vector2f(o.Min);
     Max = new Vector2f(o.Max);
 }
Пример #23
0
 public Vector2d(Vector2f copy)
 {
     x = copy.x; y = copy.y;
 }
Пример #24
0
 public void expandToContain(Vector2f v)
 {
     min = min.min(v);
     max = max.max(v);
 }
Пример #25
0
 // u^T*M*v
 public float QForm(Vector2f u, Vector2f v)
 {
     return(u.Dot(this * v));
 }
Пример #26
0
        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);
        }