Пример #1
0
        /// <inheritdoc />
        public override List <int> GenerateIndexList(int resolutionU, int resolutionV, int indexOffset = 0)
        {
            // The index list of a model tells the GPU between which vertices to draw triangles. Each three consecutive
            // indices constitute a single triangle. Since the Capsule vertex array consists of several lists stitched
            // together, the indices of the shaft and endCap will have shifted by some amount. Therefore, calculate
            // this index offset for all submodels:
            int indexOffset2 = indexOffset + Hemisphere.CalculateVertexCount(resolutionU, resolutionU / 4) - resolutionU;
            int indexOffset3 = indexOffset2 + Cylinder.CalculateVertexCount(resolutionU, resolutionV) - resolutionU;
            int indexOffset4 = indexOffset3 + Hemisphere.CalculateVertexCount(resolutionU, resolutionU / 4) - resolutionU;

            // Generate the startCap indices as normal:
            List <int> startCapList = startCap.GenerateIndexList(resolutionU, resolutionU / 4, indexOffset);

            // Generate a shaft, using the last ring of the startCap to begin with. This is done by subtracting
            // `resolutionU` from indexOffset2. This automatically stitches the gap between the start cap and the shaft:
            List <int> shaftList = shaft.GenerateIndexList(resolutionU, resolutionV - 1, indexOffset2);

            // Generate the endCap indices as normal:
            List <int> endCapList = endCap.GenerateIndexList(resolutionU, resolutionU / 4, indexOffset3);

            // The final ring between the endCap and the shaft must be generated manually:
            List <int> stitchList = new List <int>(resolutionU);

            // Add a ring of triangles:
            for (int i = 1; i < resolutionU - 1; i++)
            {
                int invertedI = resolutionU - i;
                stitchList.Add(indexOffset + invertedI + indexOffset4);
                stitchList.Add(indexOffset + (i + 1) + indexOffset3 - resolutionU);
                stitchList.Add(indexOffset + i + indexOffset3 - resolutionU);

                stitchList.Add(indexOffset + (invertedI - 1) + indexOffset4);
                stitchList.Add(indexOffset + (i + 1) + indexOffset3 - resolutionU);
                stitchList.Add(indexOffset + invertedI + indexOffset4);
            }

            // Stitch the end of the ring of triangles:
            stitchList.Add(indexOffset + 1 + indexOffset4);
            stitchList.Add(indexOffset + indexOffset3 - resolutionU);
            stitchList.Add(indexOffset + resolutionU - 1 + indexOffset3 - resolutionU);

            stitchList.Add(indexOffset + indexOffset4);
            stitchList.Add(indexOffset + indexOffset3 - resolutionU);
            stitchList.Add(indexOffset + 1 + indexOffset4);

            stitchList.Add(indexOffset + resolutionU - 1 + indexOffset4);
            stitchList.Add(indexOffset + 1 + indexOffset3 - resolutionU);
            stitchList.Add(indexOffset + indexOffset3 - resolutionU);

            stitchList.Add(indexOffset + indexOffset4);
            stitchList.Add(indexOffset + resolutionU - 1 + indexOffset4);
            stitchList.Add(indexOffset + indexOffset3 - resolutionU);

            return(startCapList.Concat(shaftList).Concat(endCapList).Concat(stitchList).ToList());
        }
        public override List <int> GenerateIndexList(int resolutionU, int resolutionV, int indexOffset = 0)
        {
            int indexOffset2 = indexOffset + Hemisphere.CalculateVertexCount(resolutionU, resolutionU / 4);
            int indexOffset3 = indexOffset + indexOffset2 + Cylinder.CalculateVertexCount(resolutionU, resolutionV);

            List <int> startCapList = startCap.GenerateIndexList(resolutionU, resolutionU / 4, indexOffset);
            List <int> shaftList    = shaft.GenerateIndexList(resolutionU, resolutionV, indexOffset2);
            List <int> endCapList   = endCap.GenerateIndexList(resolutionU, resolutionU / 4, indexOffset3);

            return(startCapList.Concat(shaftList).Concat(endCapList).ToList());
        }
 public Capsule(Cylinder shaft)
 {
     this.shaft    = shaft;
     this.startCap = new Hemisphere(
         shaft.Radius.GetValueAt(0.0f),
         shaft.CenterCurve.GetStartPosition(),
         -shaft.CenterCurve.GetTangentAt(0.0f)
         );
     this.endCap = new Hemisphere(
         shaft.Radius.GetValueAt(1.0f),
         shaft.CenterCurve.GetEndPosition(),
         shaft.CenterCurve.GetTangentAt(1.0f)
         );
 }
Пример #4
0
        /// <summary>
        ///     Construct a new <c>Capsule</c> around a central curve, the <c>centerCurve</c>.
        ///     The radius at each point on the central axis is defined by a one-dimensional function <c>radius</c>.
        ///
        ///     The surface is parametrized with the coordinates \f$u, \phi\f$, with \f$u\f (along the length of the
        ///     shaft) and \f$\phi \in [0, 2 \pi]\f$ along the radial coordinate. A <c>Capsule</c> consists of a
        ///     cylindrical shaft with two hemisphere end caps. $\f$u \in [-\frac{1}{2} \pi, 0]\f$ marks the region
        ///     in parametrized coordinates of the hemisphere at the start point of the cylinder,
        ///     $\f$u \in [0, 1]\f$ marks the region in parametrized coordinates of the central shaft,
        ///     and $\f$u \in [1, 1 + \frac{1}{2} \pi]\f$ marks the region in parametrized coordinates of the hemisphere
        ///     at the end point of the cylinder. The <c>heightMap</c> is a two-dimensional function defined on these
        ///     coordinates on the domain given above.
        /// </summary>
        /// <param name="centerCurve">
        ///     <inheritdoc cref="Capsule.CenterCurve"/>
        /// </param>
        /// <param name="heightMap">
        ///     The radius at each point on the surface. A <c>Capsule</c> is generated around a central curve, with each
        ///     point on the surface at a certain distance from the curve defined by <c>heightMap</c>. <c>heightMap</c>
        ///     is therefore a two-dimensional function $h(u, \phi)$ that outputs a distance from the curve at each of
        ///     the surface's parametric coordinates.
        /// </param>
        public Capsule(Curve centerCurve, ContinuousMap <Vector2, float> heightMap)
        {
            Vector3 startTangent = -centerCurve.GetTangentAt(0.0f);
            Vector3 startNormal  = centerCurve.GetNormalAt(0.0f);

            Vector3 endTangent = centerCurve.GetTangentAt(1.0f);
            Vector3 endNormal  = centerCurve.GetNormalAt(1.0f);

            this.shaft    = new Cylinder(centerCurve, heightMap);
            this.startCap = new Hemisphere(
                new ShiftedMap2D <float>(new Vector2(0.0f, -0.5f * (float)Math.PI), heightMap),
                centerCurve.GetStartPosition(),
                startTangent,
                startNormal,
                -Vector3.Cross(startTangent, startNormal)
                );
            this.endCap = new Hemisphere(
                new ShiftedMap2D <float>(new Vector2(0.0f, 1.0f + 0.5f * (float)Math.PI), new Vector2(1.0f, -1.0f), heightMap),
                centerCurve.GetEndPosition(),
                endTangent,
                endNormal,
                -Vector3.Cross(endTangent, endNormal)
                );
        }
Пример #5
0
        /// <summary>
        ///     Construct a new <c>Capsule</c> around a central curve, the <c>centerCurve</c>.
        ///     The radius at each point on the central axis is defined by a one-dimensional function <c>radius</c>.
        ///
        ///     The surface is parametrized with the coordinates \f$u, \phi\f$, with \f$u\f (along the length of the
        ///     shaft) and \f$\phi \in [0, 2 \pi]\f$ along the radial coordinate. A <c>Capsule</c> consists of a
        ///     cylindrical shaft with two hemisphere end caps. $\f$u \in [-\frac{1}{2} \pi, 0]\f$ marks the region
        ///     in parametrized coordinates of the hemisphere at the start point of the cylinder,
        ///     $\f$u \in [0, 1]\f$ marks the region in parametrized coordinates of the central shaft,
        ///     and $\f$u \in [1, 1 + \frac{1}{2} \pi]\f$ marks the region in parametrized coordinates of the hemisphere
        ///     at the end point of the cylinder. The <c>heightMap</c> is a two-dimensional function defined on these
        ///     coordinates on the domain given above.
        /// </summary>
        /// <param name="centerCurve">
        ///     <inheritdoc cref="Capsule.CenterCurve"/>
        /// </param>
        /// <param name="heightMap">
        ///     The radius at each point on the surface. A <c>Capsule</c> is generated around a central curve, with each
        ///     point on the surface at a certain distance from the curve defined by <c>heightMap</c>. <c>heightMap</c>
        ///     is therefore a two-dimensional function $h(u, \phi)$ that outputs a distance from the curve at each of
        ///     the surface's parametric coordinates.
        /// </param>
        public Capsule(Curve centerCurve, ContinuousMap <dvec2, double> heightMap)
        {
            dvec3 startTangent = -centerCurve.GetTangentAt(0.0);
            dvec3 startNormal  = centerCurve.GetNormalAt(0.0);

            dvec3 endTangent = centerCurve.GetTangentAt(1.0);
            dvec3 endNormal  = centerCurve.GetNormalAt(1.0);

            this.shaft    = new Cylinder(centerCurve, heightMap);
            this.startCap = new Hemisphere(
                new ShiftedMap2D <double>(new dvec2(0.0, -0.5 * Math.PI), heightMap),
                centerCurve.GetStartPosition(),
                startTangent,
                startNormal,
                -dvec3.Cross(startTangent, startNormal)
                );
            this.endCap = new Hemisphere(
                new ShiftedMap2D <double>(new dvec2(0.0, 1.0 + 0.5 * Math.PI), new dvec2(1.0, -1.0), heightMap),
                centerCurve.GetEndPosition(),
                endTangent,
                endNormal,
                -dvec3.Cross(endTangent, endNormal)
                );
        }