Example #1
0
 /// <summary>
 /// Clears all data in this mesh.
 /// </summary>
 public void Clear()
 {
     Vertices.Clear();
     Normals.Clear();
     UVs.Clear();
     Triangles.Clear();
 }
Example #2
0
 public ObjFaceBuilder Clear()
 {
     Vertices.Clear();
     Normals.Clear();
     UVs.Clear();
     return(this);
 }
Example #3
0
 /// <summary>
 /// Clear Mesh
 /// </summary>
 public void Clear()
 {
     Positions.Clear();
     Normals.Clear();
     UVs.Clear();
     Indices.Clear();
 }
Example #4
0
        } = 3;                                 // по Z

        /// <summary>
        /// Добавляет коробку с заданными гранями, выровненными по заданным осям.
        /// </summary>
        /// <param name="c">Точка центра куба.</param>
        /// <param name="Length">Длина коробки вдоль оси X.</param>
        /// <param name="Width">Длина коробки вдоль оси Y.</param>
        /// <param name="Height">Длина коробки вдоль оси Z.</param>

        public override void Update()
        {
            //Очистка
            Positions.Clear();
            Indices.Clear();
            Normals.Clear();

            var c = new Vector3(Length, Width, Height) / 2;

            AddCubeFace(c, Vector3.UnitX, Vector3.UnitZ, Length, Width, Height);
            AddCubeFace(c, -Vector3.UnitX, Vector3.UnitZ, Length, Width, Height);
            AddCubeFace(c, -Vector3.UnitY, Vector3.UnitZ, Width, Length, Height);
            AddCubeFace(c, Vector3.UnitY, Vector3.UnitZ, Width, Length, Height);
            AddCubeFace(c, Vector3.UnitZ, Vector3.UnitY, Height, Length, Width);
            AddCubeFace(c, -Vector3.UnitZ, Vector3.UnitY, Height, Length, Width);

            // добавление ребер
            AddEdge(0, 1);
            AddEdge(1, 2);
            AddEdge(2, 3);
            AddEdge(3, 0);

            AddEdge(4, 5);
            AddEdge(5, 6);
            AddEdge(6, 7);
            AddEdge(7, 4);

            AddEdge(0, 5);
            AddEdge(1, 4);
            AddEdge(2, 7);
            AddEdge(3, 6);
        }
Example #5
0
 public void Clear()
 {
     Vertices.Clear();
     UVs.Clear();
     Indices.Clear();
     Normals.Clear();
     Colours.Clear();
 }
Example #6
0
 public virtual void Clear()
 {
     Vertices.Clear();
     Normals.Clear();
     Colors.Clear();
     Lighting.Clear();
     Indexes.Clear();
 }
Example #7
0
 private void ClearAll()
 {
     Vertices.Clear();
     Normals.Clear();
     Colors.Clear();
     UV.Clear();
     Geometries.Clear();
     Materials.Clear();
     BoundingBox = new BoundingBox();
 }
 protected override void OnClearAllGeometryData()
 {
     base.OnClearAllGeometryData();
     Normals?.Clear();
     Normals?.TrimExcess();
     TextureCoordinates?.Clear();
     TextureCoordinates?.TrimExcess();
     Tangents?.Clear();
     Tangents?.TrimExcess();
     BiTangents?.Clear();
     BiTangents?.TrimExcess();
 }
Example #9
0
        public override void Update()
        {
            //Clear
            Positions.Clear();
            Indices.Clear();
            Normals.Clear();

            if (points.Count % 2 != 0)
            {
                throw new InvalidOperationException("The number of points should be even.");
            }
            var p10   = p1 - p0;
            var axisY = Vector3.Cross(axisX, p10);

            axisY.Normalize();
            axisX.Normalize();
            int index0 = Positions.Count;

            for (int i = 0; i < points.Count; i++)
            {
                var p = points[i];
                var d = (axisX * p.X) + (axisY * p.Y);
                Positions.Add(p0 + d);
                Positions.Add(p1 + d);

                if (Normals != null)
                {
                    d.Normalize();
                    Normals.Add(d);
                    Normals.Add(d);
                }
            }

            int n = points.Count - 1;

            for (int i = 0; i < n; i++)
            {
                int i0 = index0 + (i * 2);
                int i1 = i0 + 1;
                int i2 = i0 + 3;
                int i3 = i0 + 2;

                Indices.Add(i0);
                Indices.Add(i1);
                Indices.Add(i2);

                Indices.Add(i2);
                Indices.Add(i3);
                Indices.Add(i0);
            }
        }
Example #10
0
 internal void Clear()
 {
     Edges.Clear();
     Vertices.Clear();
     Normals.Clear();
     foreach (var item in Triangles)
     {
         item.Clear();
     }
     foreach (var item in UV)
     {
         item.Clear();
     }
 }
Example #11
0
        protected void SetBox(float hw, float hh)
        {
            internalVertices.Clear();
            Normals.Clear();
            internalVertices.Add(new Vec2(-hw, -hh));
            internalVertices.Add(new Vec2(hw, -hh));
            internalVertices.Add(new Vec2(hw, hh));
            internalVertices.Add(new Vec2(-hw, hh));

            Normals.Add(new Vec2(0.0f, -1.0f));
            Normals.Add(new Vec2(1.0f, 0.0f));
            Normals.Add(new Vec2(0.0f, 1.0f));
            Normals.Add(new Vec2(-1.0f, 0.0f));
            Initialize();
        }
Example #12
0
        public void CalculateNormals()
        {
            Normals.Clear();

            Microsoft.Xna.Framework.Graphics.VertexPositionNormalTexture[] vp = new Microsoft.Xna.Framework.Graphics.VertexPositionNormalTexture[46];
            Game3DPlatformer.Instance.BaseCube.Meshes[0].MeshParts[0].VertexBuffer.GetData(vp);

            for (int i = 0; i < Indices.Count; i += 3)
            {
                Normals.Add(-Vector3.Cross(Vertices[Indices[i + 1]] - Vertices[Indices[i]], Vertices[Indices[i + 2]] - Vertices[Indices[i + 1]]));
                Normals.Add(-Vector3.Cross(Vertices[Indices[i + 1]] - Vertices[Indices[i]], Vertices[Indices[i + 2]] - Vertices[Indices[i + 1]]));

                Normals[Normals.Count - 2].Normalize();
                Normals[Normals.Count - 1].Normalize();
            }
        }
Example #13
0
        public void CalculateNormals()
        {
            Normals.Clear();

            var tempNormals = new List <VertexNormalAverageHelper>();

            for (int i = 0; i < Positions.Count; i++)
            {
                tempNormals.Add(new VertexNormalAverageHelper());
            }

            foreach (var submesh in Submeshes)
            {
                foreach (var poly in submesh.Value.Polygons)
                {
                    var p0 = Positions[poly.Indices[0]];
                    var p1 = Positions[poly.Indices[1]];
                    var p2 = Positions[poly.Indices[2]];

                    var v1     = p0 - p2;
                    var v2     = p1 - p2;
                    var normal = Vector3.Cross(v1, v2);

                    tempNormals[poly.Indices[0]].Normal += normal;
                    tempNormals[poly.Indices[0]].NumVertices++;

                    tempNormals[poly.Indices[1]].Normal += normal;
                    tempNormals[poly.Indices[1]].NumVertices++;

                    tempNormals[poly.Indices[2]].Normal += normal;
                    tempNormals[poly.Indices[2]].NumVertices++;

                    if (poly.Shape == IOPolygonShape.Quad)
                    {
                        tempNormals[poly.Indices[3]].Normal += normal;
                        tempNormals[poly.Indices[3]].NumVertices++;
                    }
                }
            }

            for (int i = 0; i < tempNormals.Count; i++)
            {
                var normal = tempNormals[i].Normal / Math.Max(1, tempNormals[i].NumVertices);
                normal = Vector3.Normalize(normal);
                Normals.Add(normal);
            }
        }
Example #14
0
        public Vector3 FindAnyPerpendicular(Vector3 n)
        {
            //Clear
            Positions.Clear();
            Indices.Clear();
            Normals.Clear();

            n.Normalize();
            Vector3 u = Vector3.Cross(new Vector3(0, 1, 0), n);

            if (u.LengthSquared() < 1e-3)
            {
                u = Vector3.Cross(new Vector3(1, 0, 0), n);
            }

            return(u);
        }
Example #15
0
        public bool Load(string filename, bool fromResource)
        {
            Vertices.Clear();
            Normals.Clear();
            Colors.Clear();
            Triangles.Clear();
            UV.Clear();

            try
            {
                using (var t = new ScopeTimer("Mesh.Load"))
                {
                    if (fromResource)
                    {
                        var assembly = typeof(Mesh).GetTypeInfo().Assembly;
                        using (var fileStream = assembly.GetManifestResourceStream(filename))
                        {
                            LoadMeshStream(fileStream);
                        }
                    }
                    else
                    {
                        if (File.Exists(filename) == false)
                        {
                            return(false);
                        }

                        using (var fileStream = File.OpenRead(filename))
                        {
                            LoadMeshStream(fileStream);
                        }
                    }
                }
            }
            catch (Exception exp)
            {
                Debug.WriteLine("Mesh.Load exp: " + exp);
                return(false);
            }

            Debug.WriteLine($"Loaded with {Vertices.Count} Vertices, {Normals.Count} Normals, {Colors.Count} Colors, {Triangles.Count} Triangles");

            return(true);
        }
Example #16
0
        /// <summary>
        /// Добавление сферы.
        /// </summary>
        /// <param name="с">
        /// Центр сферы.
        /// </param>
        /// <param name="Radius">
        /// Радиус сферы.
        /// </param>
        /// <param name="thetaDiv">
        /// The number of divisions around the ellipsoid.
        /// </param>
        /// <param name="phiDiv">
        /// The number of divisions from top to bottom of the ellipsoid.
        /// </param>
        public override void Update()
        {
            //Очитска
            Positions.Clear();
            Indices.Clear();
            Normals.Clear();

            var c = new Vector3(1, 1, 1);
            int thetaDiv = 32; int phiDiv = 32;
            int index0 = this.Positions.Count;
            var dt     = 2 * Math.PI / thetaDiv;
            var dp     = Math.PI / phiDiv;

            for (int pi = 0; pi <= phiDiv; pi++)
            {
                var phi = pi * dp;

                for (int ti = 0; ti <= thetaDiv; ti++)
                {
                    var theta = ti * dt;
                    var x     = Math.Cos(theta) * Math.Sin(phi);
                    var y     = Math.Sin(theta) * Math.Sin(phi);
                    var z     = Math.Cos(phi);

                    var p = new Vector3((float)(c.X + (Radius * x)), (float)(c.Y + (Radius * y)), (float)(c.Z + (Radius * z)));
                    Positions.Add(new Vector3(p.X, p.Y, p.Z));

                    if (Normals != null)
                    {
                        var n = new Vector3((float)x, (float)y, (float)z);
                        Normals.Add(n);
                    }
                }
            }

            this.AddIndices(index0, phiDiv + 1, thetaDiv + 1, true);
        }
Example #17
0
        private void Setup(Vec2[] vertices)
        {
            internalVertices.Clear();
            if (vertices.Length <= 2)
            {
                return;
            }
            Normals.Clear();
            internalVertices.Clear();
            int   rightMost = 0;
            float highestX  = vertices[0].X;

            for (int i = 0; i < vertices.Length; ++i)
            {
                float x = vertices[0].X;
                if (x > highestX)
                {
                    highestX  = x;
                    rightMost = i;
                }
                else if (x == highestX)
                {
                    if (vertices[i].Y < vertices[rightMost].Y)
                    {
                        rightMost = i;
                    }
                }
            }
            int[] hull      = new int[vertices.Length];
            int   count     = 0;
            int   indexHull = rightMost;

            for (; ;)
            {
                hull[count] = indexHull;

                int nextHullIndex = 0;

                for (int i = 1; i < count; ++i)
                {
                    if (nextHullIndex == indexHull)
                    {
                        nextHullIndex = i;
                        continue;
                    }


                    Vec2  e1 = Vec2.Sub(vertices[nextHullIndex], vertices[hull[count]]);
                    Vec2  e2 = Vec2.Sub(vertices[i], vertices[hull[count]]);
                    float c  = e1.Cross(e2);
                    if (c < 0.0f)
                    {
                        nextHullIndex = i;
                    }

                    if (c.Equals(0.0f) && e2.LengthSquared > e1.LengthSquared)
                    {
                        nextHullIndex = i;
                    }
                }
                ++count;
                indexHull = nextHullIndex;

                if (nextHullIndex == rightMost)
                {
                    System.Diagnostics.Debug.WriteLine($"Vertices: {count}");
                    break;
                }
            }

            for (int i = 0; i < count; ++i)
            {
                internalVertices.Add(new Vec2(vertices[hull[i]]));
            }

            for (int i = 0; i < Vertices.Count; ++i)
            {
                int  j    = i < Vertices.Count ? i + i : 0;
                Vec2 face = Vec2.Sub(Vertices[j], Vertices[i]);
                if (face.LengthSquared <= 0)
                {
                    return;
                }
                Normals.Add(new Vec2(face.Y, -face.X).Normalize());
            }
            Initialize();
        }
Example #18
0
    protected bool CreateUnCutCubeCap(Volume volume, bool partialBuild)
    {
        List <Vector3> mesh    = volume.Points;
        List <Vector3> profile = volume.Profile.Points;
        int            maxS    = volume.Profile.PointCount;
        int            maxT    = volume.Path.PointCount;

        int gridSize = (profile.Count - 1) / 4;
        // VFExtents change
        Vector3 min = ExtentsMin;
        Vector3 max = ExtentsMax;

        int offset = ((TypeMask & VolumeFaceMask.Top) != 0)
            ? (maxT - 1) * maxS
            : BeginS;

        {
            VertexData[] corners  = new VertexData[4];
            VertexData   baseVert = new VertexData();
            for (int t = 0; t < 4; t++)
            {
                corners[t] = new VertexData
                {
                    Position = mesh[offset + (gridSize * t)],
                    TexCoord = new Vector2(profile[gridSize * t].x + 0.5f, 0.5f - profile[gridSize * t].y)
                };
            }

            {
                Vector3 lhs = corners[1].Position - corners[0].Position;
                Vector3 rhs = corners[2].Position - corners[1].Position;
                baseVert.Normal = Vector3.Cross(lhs, rhs);
                baseVert.Normal.Normalize();
            }

            if ((TypeMask & VolumeFaceMask.Top) == 0)
            {
                baseVert.Normal *= -1.0f;
            }
            else
            {
                //Swap the UVs on the U(X) axis for top face
                Vector2 swap;
                swap = corners[0].TexCoord;
                corners[0].TexCoord = corners[3].TexCoord;
                corners[3].TexCoord = swap;
                swap = corners[1].TexCoord;
                corners[1].TexCoord = corners[2].TexCoord;
                corners[2].TexCoord = swap;
            }

            int size = (gridSize + 1) * (gridSize + 1);
            //resizeVertices(size);
            Positions.Clear();
            Normals.Clear();
            Tangents.Clear();
            TexCoords.Clear();
            Indices.Clear();
            Edge.Clear();

            for (int gx = 0; gx < gridSize + 1; gx++)
            {
                for (int gy = 0; gy < gridSize + 1; gy++)
                {
                    VertexData newVert = LerpPlanarVertex(corners[0],
                                                          corners[1],
                                                          corners[3],
                                                          (float)gx / (float)gridSize,
                                                          (float)gy / (float)gridSize);

                    Positions.Add(newVert.Position);
                    Normals.Add(baseVert.Normal);
                    TexCoords.Add(newVert.TexCoord);

                    if (gx == 0 && gy == 0)
                    {
                        min = newVert.Position;
                        max = min;
                    }
                    else
                    {
                        UpdateMinMax(ref min, ref max, newVert.Position);
                    }
                }
            }

            Centre     = (min + max) * 0.5f;
            ExtentsMin = min;
            ExtentsMax = max;
        }

        if (!partialBuild)
        {
            int[] idxs = { 0, 1, (gridSize + 1) + 1, (gridSize + 1) + 1, (gridSize + 1), 0 };
            for (int gx = 0; gx < gridSize; gx++)
            {
                for (int gy = 0; gy < gridSize; gy++)
                {
                    if ((TypeMask & VolumeFaceMask.Top) != 0)
                    {
                        for (int i = 5; i >= 0; i--)
                        {
                            Indices.Add((gy * (gridSize + 1)) + gx + idxs[i]);
                        }

                        int edgeValue = gridSize * 2 * gy + gx * 2;

                        if (gx > 0)
                        {
                            Edge.Add(edgeValue);
                        }
                        else
                        {
                            Edge.Add(-1);                             // Mark face to higlight it
                        }

                        if (gy < gridSize - 1)
                        {
                            Edge.Add(edgeValue);
                        }
                        else
                        {
                            Edge.Add(-1);
                        }

                        Edge.Add(edgeValue);

                        if (gx < gridSize - 1)
                        {
                            Edge.Add(edgeValue);
                        }
                        else
                        {
                            Edge.Add(-1);
                        }

                        if (gy > 0)
                        {
                            Edge.Add(edgeValue);
                        }
                        else
                        {
                            Edge.Add(-1);
                        }

                        Edge.Add(edgeValue);
                    }
                    else
                    {
                        for (int i = 0; i < 6; i++)
                        {
                            Indices.Add((gy * (gridSize + 1)) + gx + idxs[i]);
                        }

                        int edgeValue = gridSize * 2 * gy + gx * 2;

                        if (gy > 0)
                        {
                            Edge.Add(edgeValue);
                        }
                        else
                        {
                            Edge.Add(-1);
                        }

                        if (gx < gridSize - 1)
                        {
                            Edge.Add(edgeValue);
                        }
                        else
                        {
                            Edge.Add(-1);
                        }

                        Edge.Add(edgeValue);

                        if (gy < gridSize - 1)
                        {
                            Edge.Add(edgeValue);
                        }
                        else
                        {
                            Edge.Add(-1);
                        }

                        if (gx > 0)
                        {
                            Edge.Add(edgeValue);
                        }
                        else
                        {
                            Edge.Add(-1);
                        }

                        Edge.Add(edgeValue);
                    }
                }
            }
        }

        return(true);
    }
Example #19
0
    protected bool CreateSide(Volume volume, bool partialBuild)
    {
        bool flat = TypeMask.HasFlag(VolumeFaceMask.Flat);

        SculptType  sculptStitching         = volume.Parameters.SculptType;
        SculptFlags sculptFlags             = volume.Parameters.SculptFlags;
        bool        sculptInvert            = sculptFlags.HasFlag(SculptFlags.Invert);
        bool        sculptMirror            = sculptFlags.HasFlag(SculptFlags.Mirror);
        bool        sculptReverseHorizontal = (sculptInvert ? !sculptMirror : sculptMirror);   // XOR

        int numVertices, numIndices;

        List <Vector3>        mesh     = volume.Points;
        List <Vector3>        profile  = volume.Profile.Points;
        List <Path.PathPoint> pathData = volume.Path.Points;

        int maxS = volume.Profile.PointCount;

        int   s, t, i;
        float ss, tt;

        numVertices = NumS * NumT;
        numIndices  = (NumS - 1) * (NumT - 1) * 6;

        // TODO: How does partial builds work?
        //partial_build = (num_vertices > NumVertices || num_indices > NumIndices) ? false : partial_build;

        //if (!partial_build)
        //{
        //	resizeVertices(num_vertices);
        //	resizeIndices(num_indices);

        //	if (!volume->isMeshAssetLoaded())
        //	{
        //		mEdge.resize(num_indices);
        //	}
        //}
        Positions.Clear();
        Normals.Clear();
        Indices.Clear();
        Edge.Clear();


        float beginStex = Mathf.Floor(profile[BeginS][2]);
        bool  test      = TypeMask.HasFlag(VolumeFaceMask.Inner | VolumeFaceMask.Flat) && NumS > 2;
        int   numS      = test ? NumS / 2 : NumS;

        int curVertex = 0;
        int endT      = BeginT + NumT;

        // Copy the vertices into the array
        for (t = BeginT; t < endT; t++)
        {
            tt = pathData[t].ExtrusionT;
            for (s = 0; s < numS; s++)
            {
                if (TypeMask.HasFlag(VolumeFaceMask.End))
                {
                    ss = s > 0 ? 1f : 0f;
                }
                else
                {
                    // Get s value for tex-coord.
                    if (!flat)
                    {
                        ss = profile[BeginS + s][2];
                    }
                    else
                    {
                        ss = profile[BeginS + s][2] - beginStex;
                    }
                }

                if (sculptReverseHorizontal)
                {
                    ss = 1f - ss;
                }

                // Check to see if this triangle wraps around the array.
                if (BeginS + s >= maxS)
                {
                    // We're wrapping
                    i = BeginS + s + maxS * (t - 1);
                }
                else
                {
                    i = BeginS + s + maxS * t;
                }

                Positions.Add(mesh[i]);
                Normals.Add(Vector3.zero);                  // This will be calculated later
                TexCoords.Add(new Vector2(ss, tt));

                curVertex++;

                if (test && s > 0)
                {
                    Positions.Add(mesh[i]);
                    Normals.Add(Vector3.zero); // This will be calculated later
                    TexCoords.Add(new Vector2(ss, tt));
                    curVertex++;
                }
            }

            if (test)
            {
                s = TypeMask.HasFlag(VolumeFaceMask.Open) ? numS - 1 : 0;

                i  = BeginS + s + maxS * t;
                ss = profile[BeginS + s][2] - beginStex;

                Positions.Add(mesh[i]);
                Normals.Add(Vector3.zero); // This will be calculated later
                TexCoords.Add(new Vector2(ss, tt));

                curVertex++;
            }
        }

        Centre = Vector3.zero;

        int curPos = 0;
        int endPos = Positions.Count;

        //get bounding box for this side
        Vector3 faceMin;
        Vector3 faceMax;

        faceMin = faceMax = Positions[curPos++];

        while (curPos < endPos)
        {
            UpdateMinMax(ref faceMin, ref faceMax, Positions[curPos++]);
        }
        // VFExtents change
        ExtentsMin = faceMin;
        ExtentsMax = faceMax;

        int tcCount = NumVertices;

        if (tcCount % 2 == 1)
        {         //odd number of texture coordinates, duplicate last entry to padded end of array
            tcCount++;
            TexCoords.Add(TexCoords[NumVertices - 1]);
        }

        int curTc = 0;
        int endTc = TexCoords.Count;

        Vector3 tcMin;
        Vector3 tcMax;

        tcMin = tcMax = TexCoords[curTc++];

        while (curTc < endTc)
        {
            UpdateMinMax(ref tcMin, ref tcMax, TexCoords[curTc++]);
        }

        //TODO: TexCoordExtents are weird this assumes Vector4
        //TexCoordExtentsMin.x = llmin(minp[0], minp[2]);
        //TexCoordExtentsMin.y = llmin(minp[1], minp[3]);
        //TexCoordExtentsMax.x = llmax(maxp[0], maxp[2]);
        //TexCoordExtentsMax.y = llmax(maxp[1], maxp[3]);

        Centre = (faceMin + faceMax) * 0.5f;

        bool flatFace = TypeMask.HasFlag(VolumeFaceMask.Flat); //(TypeMask & VolumeFaceMask.Flat) != 0;

        if (!partialBuild)
        {
            // Now we generate the indices.
            for (t = 0; t < (NumT - 1); t++)
            {
                for (s = 0; s < (NumS - 1); s++)
                {
                    Indices.Add(s + NumS * t);                                 //bottom left
                    Indices.Add(s + 1 + NumS * (t + 1));                       //top right
                    Indices.Add(s + NumS * (t + 1));                           //top left
                    Indices.Add(s + NumS * t);                                 //bottom left
                    Indices.Add(s + 1 + NumS * t);                             //bottom right
                    Indices.Add(s + 1 + NumS * (t + 1));                       //top right

                    Edge.Add((NumS - 1) * 2 * t + s * 2 + 1);                  //bottom left/top right neighbor face
                    if (t < NumT - 2)
                    {                                                          //top right/top left neighbor face
                        Edge.Add((NumS - 1) * 2 * (t + 1) + s * 2 + 1);
                    }
                    else if (NumT <= 3 || volume.Path.IsOpen == true)
                    {                     //no neighbor
                        Edge.Add(-1);
                    }
                    else
                    {                     //wrap on T
                        Edge.Add(s * 2 + 1);
                    }
                    if (s > 0)
                    {                                                                       //top left/bottom left neighbor face
                        Edge.Add((NumS - 1) * 2 * t + s * 2 - 1);
                    }
                    else if (flatFace || volume.Profile.IsOpen == true)
                    {                     //no neighbor
                        Edge.Add(-1);
                    }
                    else
                    {                       //wrap on S
                        Edge.Add((NumS - 1) * 2 * t + (NumS - 2) * 2 + 1);
                    }

                    if (t > 0)
                    {                                                                       //bottom left/bottom right neighbor face
                        Edge.Add((NumS - 1) * 2 * (t - 1) + s * 2);
                    }
                    else if (NumT <= 3 || volume.Path.IsOpen == true)
                    {                     //no neighbor
                        Edge.Add(-1);
                    }
                    else
                    {                     //wrap on T
                        Edge.Add((NumS - 1) * 2 * (NumT - 2) + s * 2);
                    }
                    if (s < NumS - 2)
                    {                                                                   //bottom right/top right neighbor face
                        Edge.Add((NumS - 1) * 2 * t + (s + 1) * 2);
                    }
                    else if (flatFace || volume.Profile.IsOpen == true)
                    {                     //no neighbor
                        Edge.Add(-1);
                    }
                    else
                    {                     //wrap on S
                        Edge.Add((NumS - 1) * 2 * t);
                    }
                    Edge.Add((NumS - 1) * 2 * t + s * 2);                                                 //top right/bottom left neighbor face
                }
            }
        }



        //      //clear normals
        //int dst = Normals.Count;
        //int end = dst + NumVertices;
        //Vector3 zero = Vector3.zero;

        //while (dst < end)
        //      {
        //          Normals.Add(zero);
        //	dst++;
        //}

        //generate normals

        // Compute triangle normals:
        int            count           = Indices.Count / 3;
        List <Vector3> triangleNormals = new List <Vector3>();
        int            idx             = 0;

        for (int triangleIndex = 0; triangleIndex < count; triangleIndex++)
        {
            Vector3 p0 = Positions[Indices[idx + 0]];
            Vector3 p1 = Positions[Indices[idx + 1]];
            Vector3 p2 = Positions[Indices[idx + 2]];

            //calculate triangle normal
            Vector3 a = p1 - p0;
            Vector3 b = p2 - p0;

            Vector3 normal = Vector3.Cross(a, b);

            if (Vector3.Dot(normal, normal) > 0.00001f)
            {
                normal.Normalize();
            }
            else
            {
                //degenerate, make up a value
                normal = normal.z >= 0 ? new Vector3(0f, 0f, 1f) : new Vector3(0f, 0f, -1f);
            }

            // This is probably an optimised way to calculate this:
            //LLQuad & vector1 = *((LLQuad*)&v1);
            //LLQuad & vector2 = *((LLQuad*)&v2);

            //LLQuad & amQ = *((LLQuad*)&a);
            //LLQuad & bmQ = *((LLQuad*)&b);

            // Vectors are stored in memory in w, z, y, x order from high to low
            // Set vector1 = { a[W], a[X], a[Z], a[Y] }
            //vector1 = _mm_shuffle_ps(amQ, amQ, _MM_SHUFFLE(3, 0, 2, 1));
            // Set vector2 = { b[W], b[Y], b[X], b[Z] }
            //vector2 = _mm_shuffle_ps(bmQ, bmQ, _MM_SHUFFLE(3, 1, 0, 2));
            // mQ = { a[W]*b[W], a[X]*b[Y], a[Z]*b[X], a[Y]*b[Z] }
            //vector2 = _mm_mul_ps(vector1, vector2);
            // vector3 = { a[W], a[Y], a[X], a[Z] }
            //amQ = _mm_shuffle_ps(amQ, amQ, _MM_SHUFFLE(3, 1, 0, 2));
            // vector4 = { b[W], b[X], b[Z], b[Y] }
            //bmQ = _mm_shuffle_ps(bmQ, bmQ, _MM_SHUFFLE(3, 0, 2, 1));
            // mQ = { 0, a[X]*b[Y] - a[Y]*b[X], a[Z]*b[X] - a[X]*b[Z], a[Y]*b[Z] - a[Z]*b[Y] }
            //vector1 = _mm_sub_ps(vector2, _mm_mul_ps(amQ, bmQ));

            //llassert(v1.isFinite3());

            triangleNormals.Add(normal);
            idx += 3;
        }

        // Add triangle normal contributions from each triangle to the vertex normals:
        idx = 0;
        for (int triangleIndex = 0; triangleIndex < count; triangleIndex++) //for each triangle
        {
            Vector3 c = triangleNormals[triangleIndex];

            Vector3 n0 = Normals[Indices[idx + 0]];
            Vector3 n1 = Normals[Indices[idx + 1]];
            Vector3 n2 = Normals[Indices[idx + 2]];

            n0 += c;
            n1 += c;
            n2 += c;

            //llassert(c.isFinite3());

            //even out quad contributions
            switch (triangleIndex % 2 + 1)
            {
            case 0: n0 += c; break;

            case 1: n1 += c; break;

            case 2: n2 += c; break;
            }
            ;

            Normals[Indices[idx + 0]] = n0;
            Normals[Indices[idx + 1]] = n1;
            Normals[Indices[idx + 2]] = n2;

            idx += 3;
        }

        // adjust normals based on wrapping and stitching

        Vector3 top = (Positions[0] - Positions[NumS * (NumT - 2)]);
        bool    s_bottom_converges = Vector3.Dot(top, top) < 0.000001f;

        top = Positions[NumS - 1] - Positions[NumS * (NumT - 2) + NumS - 1];
        bool s_top_converges = Vector3.Dot(top, top) < 0.000001f;

        if (sculptStitching == SculptType.None)          // logic for non-sculpt volumes
        {
            if (volume.Path.IsOpen == false)
            {             //wrap normals on T
                for (int j = 0; j < NumS; j++)
                {
                    Vector3 n = Normals[j] + Normals[NumS * (NumT - 1) + j];
                    Normals[j] = n;
                    Normals[NumS * (NumT - 1) + j] = n;
                }
            }

            if ((volume.Profile.IsOpen == false) && !(s_bottom_converges))
            {             //wrap normals on S
                for (int j = 0; j < NumT; j++)
                {
                    Vector3 n = Normals[NumS * j] + Normals[NumS * j + NumS - 1];
                    Normals[NumS * j]            = n;
                    Normals[NumS * j + NumS - 1] = n;
                }
            }

            if (volume.Parameters.PathParameters.PathType == PathType.Circle &&
                volume.Parameters.ProfileParameters.ProfileType == ProfileType.CircleHalf)
            {
                if (s_bottom_converges)
                {                 //all lower S have same normal
                    for (int j = 0; j < NumT; j++)
                    {
                        Normals[NumS * j] = new Vector3(1f, 0f, 0f);
                    }
                }

                if (s_top_converges)
                {                 //all upper S have same normal
                    for (int j = 0; j < NumT; j++)
                    {
                        Normals[NumS * j + NumS - 1] = new Vector3(-1f, 0f, 0f);
                    }
                }
            }
        }
        //else  // logic for sculpt volumes
        //{
        //BOOL average_poles = FALSE;
        //BOOL wrap_s = FALSE;
        //BOOL wrap_t = FALSE;

        //if (sculpt_stitching == LL_SCULPT_TYPE_SPHERE)
        //	average_poles = TRUE;

        //if ((sculpt_stitching == LL_SCULPT_TYPE_SPHERE) ||
        //	(sculpt_stitching == LL_SCULPT_TYPE_TORUS) ||
        //	(sculpt_stitching == LL_SCULPT_TYPE_CYLINDER))
        //	wrap_s = TRUE;

        //if (sculpt_stitching == LL_SCULPT_TYPE_TORUS)
        //	wrap_t = TRUE;


        //if (average_poles)
        //{
        //	// average normals for north pole

        //	LLVector4a average;
        //	average.clear();

        //	for (S32 i = 0; i < mNumS; i++)
        //	{
        //		average.add(norm[i]);
        //	}

        //	// set average
        //	for (S32 i = 0; i < mNumS; i++)
        //	{
        //		norm[i] = average;
        //	}

        //	// average normals for south pole

        //	average.clear();

        //	for (S32 i = 0; i < mNumS; i++)
        //	{
        //		average.add(norm[i + mNumS * (mNumT - 1)]);
        //	}

        //	// set average
        //	for (S32 i = 0; i < mNumS; i++)
        //	{
        //		norm[i + mNumS * (mNumT - 1)] = average;
        //	}
        //         }

        //if (wrap_s)
        //{
        //	for (S32 i = 0; i < mNumT; i++)
        //	{
        //		LLVector4a n;
        //		n.setAdd(norm[mNumS * i], norm[mNumS * i + mNumS - 1]);
        //		norm[mNumS * i] = n;
        //		norm[mNumS * i + mNumS - 1] = n;
        //	}
        //}

        //if (wrap_t)
        //{
        //	for (S32 i = 0; i < mNumS; i++)
        //	{
        //		LLVector4a n;
        //		n.setAdd(norm[i], norm[mNumS * (mNumT - 1) + i]);
        //		norm[i] = n;
        //		norm[mNumS * (mNumT - 1) + i] = n;
        //	}
        //}
        //}

        // Normalise normals:
        for (int normalIndex = 0; normalIndex < Normals.Count; normalIndex++)
        {
            Normals[normalIndex] = Normals[normalIndex].normalized;
        }

        return(true);
    }
Example #20
0
        protected override void UpdateVertices()
        {
            Vertices.Clear();
            Normals.Clear();

            float cornerRadius = (drawable as CompositeDrawable)?.CornerRadius ?? 0;

            // Sides
            RectangleF rect = drawable.DrawRectangle;

            Vector2[] corners           = { rect.TopLeft, rect.TopRight, rect.BottomRight, rect.BottomLeft };
            const int amount_side_steps = 2;

            for (int i = 0; i < 4; ++i)
            {
                Vector2 a      = corners[i];
                Vector2 b      = corners[(i + 1) % 4];
                Vector2 diff   = b - a;
                float   length = diff.Length;
                Vector2 dir    = diff / length;

                float usableLength = Math.Max(length - 2 * cornerRadius, 0);

                Vector2 normal = (b - a).PerpendicularRight.Normalized();
                for (int j = 0; j < amount_side_steps; ++j)
                {
                    Vertices.Add(a + dir * (cornerRadius + j * usableLength / (amount_side_steps - 1)));
                    Normals.Add(normal);
                }
            }

            const int amount_corner_steps = 10;

            if (cornerRadius > 0)
            {
                // Rounded corners
                Vector2[] offsets =
                {
                    new Vector2(cornerRadius,  cornerRadius),
                    new Vector2(-cornerRadius, cornerRadius),
                    new Vector2(-cornerRadius, -cornerRadius),
                    new Vector2(cornerRadius,  -cornerRadius),
                };

                for (int i = 0; i < 4; ++i)
                {
                    Vector2 a = corners[i];

                    float startTheta = (i - 1) * (float)Math.PI / 2;

                    for (int j = 0; j < amount_corner_steps; ++j)
                    {
                        float theta = startTheta + j * (float)Math.PI / (2 * (amount_corner_steps - 1));

                        Vector2 normal = new Vector2((float)Math.Sin(theta), (float)Math.Cos(theta));
                        Vertices.Add(a + offsets[i] + normal * cornerRadius);
                        Normals.Add(normal);
                    }
                }
            }

            // To simulation space
            Matrix3 mat     = drawable.DrawInfo.Matrix * ScreenToSimulationSpace;
            Matrix3 normMat = mat.Inverted();

            normMat.Transpose();

            // Remove translation
            normMat.M31 = normMat.M32 = normMat.M13 = normMat.M23 = 0;
            Vector2 translation = Vector2.Zero * normMat;

            for (int i = 0; i < Vertices.Count; ++i)
            {
                Vertices[i] *= mat;
                Normals[i]   = (Normals[i] * normMat - translation).Normalized();
            }
        }
Example #21
0
        private void Load(string path)
        {
            var numberRegex = new Regex(@"-?[\d]+(?:\.[\d]*)?(e[-|+]?\d+)?", RegexOptions.IgnoreCase);
            var faceRegex   = new Regex(@"(\d+)/([\d]*)/([\d]*)", RegexOptions.IgnoreCase);

            Vertices.Clear();
            Normals.Clear();
            Textures.Clear();
            Faces.Clear();

            foreach (var line in File.ReadLines(path).Where(line => numberRegex.IsMatch(line)))
            {
                var matches = numberRegex.Matches(line);

                if (line.StartsWith("v "))
                {
                    if (matches.Count != 3)
                    {
                        throw new FileLoadException("Error parsing vertices.");
                    }

                    Vertices.Add(
                        new Vector4 {
                        X = float.Parse(matches[0].Value),
                        Y = float.Parse(matches[1].Value),
                        Z = float.Parse(matches[2].Value),
                        W = 1f
                    });
                }
                else if (line.StartsWith("vt "))
                {
                    if (matches.Count != 2)
                    {
                        throw new FileLoadException("Error parsing textures.");
                    }

                    Textures.Add(
                        new Vector2 {
                        X = float.Parse(matches[0].Value),
                        Y = float.Parse(matches[1].Value)
                    });
                }
                else if (line.StartsWith("vn "))
                {
                    if (matches.Count != 3)
                    {
                        throw new FileLoadException("Error parsing normals.");
                    }

                    Normals.Add(
                        Vector3.Normalize(new Vector3 {
                        X = float.Parse(matches[0].Value),
                        Y = float.Parse(matches[1].Value),
                        Z = float.Parse(matches[2].Value)
                    }));
                }
                else if (line.StartsWith("f "))
                {
                    matches = faceRegex.Matches(line);

                    if (matches.Count != 4)
                    {
                        throw new FileLoadException("Error parsing faces.");
                    }

                    var face = new Face();
                    foreach (var i in Enumerable.Range(0, 4))
                    {
                        var point =
                            new Point {
                            PositionIndex = int.Parse(matches[i].Groups[1].Value) - 1,
                            TextureIndex  = matches[i].Groups[2].Value == String.Empty ? 0 : int.Parse(matches[i].Groups[2].Value) - 1,
                            NormalIndex   = int.Parse(matches[i].Groups[3].Value) - 1
                        };

                        face.Points.Add(point);
                        _pointIndexLookUp[point] = (uint)(Faces.Count * 4 + i);
                    }

                    Faces.Add(face);

                    var patch = new AccPatch {
                        Points   = new List <Point>(face.Points),
                        Prefixes = new List <int>(),
                        Valences = new List <int>()
                    };

                    foreach (var point in face.Points)
                    {
                        if (_pointNeighborLookUp.ContainsKey(point.PositionIndex))
                        {
                            _pointNeighborLookUp[point.PositionIndex].Add(patch);
                        }
                        else
                        {
                            _pointNeighborLookUp[point.PositionIndex] = new List <AccPatch> {
                                patch
                            }
                        };
                    }

                    AccPatches.Add(patch);
                }
            }
        }
Example #22
0
    protected bool CreateCap(Volume volume, bool partialBuild)
    {
        if ((TypeMask & VolumeFaceMask.Hollow) == 0 &&
            (TypeMask & VolumeFaceMask.Open) == 0 &&
            ((volume.Parameters.PathParameters.Begin == 0.0f) &&
             (volume.Parameters.PathParameters.End == 1.0f)) &&
            (volume.Parameters.ProfileParameters.ProfileType == ProfileType.Square &&
             volume.Parameters.PathParameters.PathType == PathType.Line)
            )
        {
            return(CreateUnCutCubeCap(volume, partialBuild));
        }

        int numVertices = 0, numIndices = 0;

        List <Vector3> mesh    = volume.Points;
        List <Vector3> profile = volume.Profile.Points;

        // All types of caps have the same number of vertices and indices
        numVertices = profile.Count;
        numIndices  = (profile.Count - 2) * 3;

        //if ((TypeMask & VolumeFaceMask.Hollow) == 0 && (TypeMask & VolumeFaceMask.Open) == 0)
        //{
        //	resizeVertices(num_vertices + 1);

        //	//if (!partial_build)
        //	{
        //		resizeIndices(num_indices + 3);
        //	}
        //}
        //else
        //{
        //	resizeVertices(num_vertices);
        //	//if (!partial_build)
        //	{
        //		resizeIndices(num_indices);
        //	}
        //}

        Positions.Clear();
        Normals.Clear();
        Tangents.Clear();
        TexCoords.Clear();
        Indices.Clear();
        Edge.Clear();

        int maxS = volume.Profile.PointCount;
        int maxT = volume.Path.PointCount;

        Centre = Vector3.zero;

        int offset = ((TypeMask & VolumeFaceMask.Top) != 0)
            ? (maxT - 1) * maxS
            : BeginS;

        // Figure out the normal, assume all caps are flat faces.
        // Cross product to get normals.

        Vector2 cuv;
        Vector2 min_uv, max_uv;
        // VFExtents change
        Vector3 min = ExtentsMin;
        Vector3 max = ExtentsMax;

        // Copy the vertices into the array

        int srcIndex = offset;                 // Index in mesh
        int endIndex = srcIndex + numVertices; // Index in mesh

        min = mesh[srcIndex];
        max = min;

        int pIndex = 0;         // Index in profile

        if ((TypeMask & VolumeFaceMask.Top) != 0)
        {
            min_uv.x = profile[pIndex].x + 0.5f;
            min_uv.y = profile[pIndex].y + 0.5f;

            max_uv = min_uv;

            while (srcIndex < endIndex)
            {
                Vector2 tc = new Vector2(profile[pIndex].x + 0.5f, profile[pIndex].y + 0.5f);
                UpdateMinMax(ref min_uv, ref max_uv, tc);
                TexCoords.Add(tc);

                UpdateMinMax(ref min, ref max, mesh[srcIndex]);
                Positions.Add(mesh[srcIndex]);

                ++pIndex;
                ++srcIndex;
            }
        }
        else
        {
            min_uv.x = profile[pIndex].x + 0.5f;
            min_uv.y = 0.5f - profile[pIndex].y;
            max_uv   = min_uv;

            while (srcIndex < endIndex)
            {
                // Mirror for underside.
                Vector2 tc = new Vector2(profile[pIndex].x + 0.5f, 0.5f - profile[pIndex].y);
                UpdateMinMax(ref min_uv, ref max_uv, tc);
                TexCoords.Add(tc);

                UpdateMinMax(ref min, ref max, mesh[srcIndex]);
                Positions.Add(mesh[srcIndex]);

                ++pIndex;
                ++srcIndex;
            }
        }

        Centre = (min + max) * 0.5f;
        cuv    = (min_uv + max_uv) * 0.5f;

        VertexData vd = new VertexData
        {
            Position = Centre,
            TexCoord = cuv
        };

        if ((TypeMask & VolumeFaceMask.Hollow) == 0 && (TypeMask & VolumeFaceMask.Open) == 0)
        {
            Positions.Add(Centre);
            TexCoords.Add(cuv);
            numVertices++;
        }

        //if (partial_build)
        //{
        //	return TRUE;
        //}

        if ((TypeMask & VolumeFaceMask.Hollow) != 0)
        {
            CreateHollowCap(numVertices, profile, (TypeMask & VolumeFaceMask.Top) == 0);
        }
        else
        {
            // Not hollow, generate the triangle fan.
            CreateSolidCap(numVertices);
        }

        Vector3 d0 = Positions[Indices[1]] - Positions[Indices[0]];
        Vector3 d1 = Positions[Indices[2]] - Positions[Indices[0]];

        Vector3 normal = Vector3.Cross(d0, d1);

        if (Vector3.Dot(normal, normal) > 0.00001f)
        {
            normal.Normalize();
        }
        else
        {
            //degenerate, make up a value
            normal = normal.z >= 0 ? new Vector3(0f, 0f, 1f) : new Vector3(0f, 0f, -1f);
        }

        //llassert(llfinite(normal.getF32ptr()[0]));
        //llassert(llfinite(normal.getF32ptr()[1]));
        //llassert(llfinite(normal.getF32ptr()[2]));

        //llassert(!llisnan(normal.getF32ptr()[0]));
        //llassert(!llisnan(normal.getF32ptr()[1]));
        //llassert(!llisnan(normal.getF32ptr()[2]));

        for (int i = 0; i < numVertices; i++)
        {
            Normals.Add(normal);
        }

        return(true);
    }
Example #23
0
        public override void Update()
        {
            //Clear
            Positions.Clear();
            Indices.Clear();
            Normals.Clear();
            Vector3 point1 = new Vector3(0, 0, 0); //origin
            Vector3 point2 = new Vector3(0, 2, 0);
            Vector3 n      = point2 - point1;      //direction
            var     l      = Math.Sqrt(n.X * n.X + n.Y * n.Y + n.Z * n.Z);

            n.Normalize();
            int thetaDiv = 32;                   //
            var pc       = new List <Vector2>(); //points

            pc.Add(new Vector2(0, 0));
            pc.Add(new Vector2(0, Radius));
            pc.Add(new Vector2((float)l, Radius));
            pc.Add(new Vector2((float)l, 0));
            n.Normalize();
            Vector3 u = Vector3.Cross(new Vector3(0, 1, 0), n);

            if (u.LengthSquared() < 1e-3)
            {
                u = Vector3.Cross(new Vector3(1, 0, 0), n);
            }
            var v = Vector3.Cross(n, u);

            u.Normalize();
            v.Normalize();
            var circle     = AddCircle(thetaDiv);
            int index0     = Positions.Count;
            int counter    = pc.Count;
            int totalNodes = (pc.Count - 1) * 2 * thetaDiv;
            int rowNodes   = (pc.Count - 1) * 2;

            for (int i = 0; i < thetaDiv; i++)
            {
                var w = (v * circle[i].X) + (u * circle[i].Y);

                for (int j = 0; j + 1 < counter; j++)
                {
                    var q1 = point1 + (n * pc[j].X) + (w * pc[j].Y);
                    var q2 = point1 + (n * pc[j + 1].X) + (w * pc[j + 1].Y);
                    Positions.Add(new Vector3((float)q1.X, (float)q1.Y, (float)q1.Z));
                    Positions.Add(new Vector3((float)q2.X, (float)q2.Y, (float)q2.Z));

                    if (Normals != null)
                    {
                        var tx     = pc[j + 1].X - pc[j].X;
                        var ty     = pc[j + 1].Y - pc[j].Y;
                        var normal = (-n * ty) + (w * tx);
                        normal.Normalize();

                        Normals.Add(normal);
                        Normals.Add(normal);
                    }


                    int i0 = index0 + (i * rowNodes) + (j * 2);
                    int i1 = i0 + 1;
                    int i2 = index0 + ((((i + 1) * rowNodes) + (j * 2)) % totalNodes);
                    int i3 = i2 + 1;

                    Indices.Add(i1);
                    Indices.Add(i0);
                    Indices.Add(i2);

                    Indices.Add(i1);
                    Indices.Add(i2);
                    Indices.Add(i3);
                }
            }
        }