Beispiel #1
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);
    }
Beispiel #2
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);
    }