Ejemplo n.º 1
0
        private void Update(EvaluationContext context)
        {
            try
            {
                var resourceManager = ResourceManager.Instance();

                var lowerRadius = Radius.GetValue(context);
                var upperRadius = lowerRadius + RadiusOffset.GetValue(context);
                var height      = Height.GetValue(context);

                var rows    = Rows.GetValue(context).Clamp(1, 10000);
                var columns = Columns.GetValue(context).Clamp(1, 10000);

                var c      = Center.GetValue(context);
                var center = new SharpDX.Vector3(c.X, c.Y, c.Z);

                var spinInRad  = Spin.GetValue(context) * MathUtils.ToRad;
                var twistInRad = Twist.GetValue(context) * MathUtils.ToRad;
                var basePivot  = BasePivot.GetValue(context);

                var fillRatio   = Fill.GetValue(context) / 360f;
                var capSegments = CapSegments.GetValue(context).Clamp(0, 1000);
                var addCaps     = capSegments > 0;
                //var isHullClosed = true; //Math.Abs(fillRatio - 1) < 0.01f;

                var isFlipped = lowerRadius < 0;

                var vertexHullColumns = columns + 1;

                var hullVerticesCount = (rows + 1) * vertexHullColumns;
                var hullTriangleCount = rows * columns * 2;

                var capsVertexCount   = +2 * (capSegments * vertexHullColumns + 1);
                var capsTriangleCount = 2 * ((capSegments - 1) * columns * 2 + columns);

                var totalVertexCount   = hullVerticesCount + (addCaps ? capsVertexCount : 0);
                var totalTriangleCount = hullTriangleCount + (addCaps ? capsTriangleCount : 0);

                // Create buffers
                if (_vertexBufferData.Length != totalVertexCount)
                {
                    _vertexBufferData = new PbrVertex[totalVertexCount];
                }

                if (_indexBufferData.Length != totalTriangleCount)
                {
                    _indexBufferData = new SharpDX.Int3[totalTriangleCount];
                }

                // Initialize
                var radiusAngleFraction = fillRatio / (vertexHullColumns - 1) * 2.0 * Math.PI;
                var rowStep             = height / rows;

                // Hull
                for (var rowIndex = 0; rowIndex < rows + 1; ++rowIndex)
                {
                    var heightFraction = rowIndex / (float)rows;
                    var rowRadius      = MathUtils.Lerp(lowerRadius, upperRadius, heightFraction);
                    var nextRowRadius  = MathUtils.Lerp(lowerRadius, upperRadius, (rowIndex + 1) / (float)rows);
                    var rowLevel       = height * (heightFraction - basePivot);
                    var rowCenter      = new SharpDX.Vector3(0, rowLevel, 0);

                    for (var columnIndex = 0; columnIndex < vertexHullColumns; ++columnIndex)
                    {
                        var columnAngle = columnIndex * radiusAngleFraction + spinInRad + twistInRad * heightFraction + Math.PI;

                        var u0 = columnIndex / (float)columns;
                        var u1 = (columnIndex + 1) / (float)rows;

                        var v0 = addCaps ? ((rowIndex + 1) / (float)rows) / 2f
                                         : (rowIndex + 1) / (float)rows;
                        var v1 = addCaps ? (rowIndex / (float)rows) / 2f
                                        : rowIndex / (float)rows;

                        var p = new SharpDX.Vector3((float)Math.Sin(columnAngle) * rowRadius,
                                                    rowLevel,
                                                    (float)Math.Cos(columnAngle) * rowRadius);

                        var p1 = new SharpDX.Vector3((float)Math.Sin(columnAngle) * rowRadius,
                                                     rowLevel + rowStep,
                                                     (float)Math.Cos(columnAngle) * rowRadius
                                                     );

                        var p2 = new SharpDX.Vector3((float)Math.Sin(columnAngle + radiusAngleFraction) * nextRowRadius,
                                                     rowLevel,
                                                     (float)Math.Cos(columnAngle + radiusAngleFraction) * nextRowRadius
                                                     );

                        var uv0 = new SharpDX.Vector2(u0, v1);
                        var uv1 = new SharpDX.Vector2(u1, v1);
                        var uv2 = new SharpDX.Vector2(u1, v0);

                        var normal0 = SharpDX.Vector3.Normalize(p - rowCenter);

                        MeshUtils.CalcTBNSpace(p, uv0, p1, uv1, p2, uv2, normal0, out var tangent0, out var binormal0);

                        var vertexIndex = rowIndex * vertexHullColumns + columnIndex;
                        _vertexBufferData[vertexIndex] = new PbrVertex
                        {
                            Position  = p + center,
                            Normal    = isFlipped ? normal0 * -1 : normal0,
                            Tangent   = tangent0,
                            Bitangent = isFlipped ? binormal0 * -1 : binormal0,
                            Texcoord  = uv0,
                            Selection = 1
                        };

                        var faceIndex = 2 * (rowIndex * (vertexHullColumns - 1) + columnIndex);
                        if (columnIndex < vertexHullColumns - 1 && rowIndex < rows)
                        {
                            if (isFlipped)
                            {
                                _indexBufferData[faceIndex + 0] = new SharpDX.Int3(vertexIndex + vertexHullColumns, vertexIndex + 1, vertexIndex + 0);
                                _indexBufferData[faceIndex + 1] =
                                    new SharpDX.Int3(vertexIndex + vertexHullColumns + 1, vertexIndex + 1, vertexIndex + vertexHullColumns);
                            }
                            else
                            {
                                _indexBufferData[faceIndex + 0] = new SharpDX.Int3(vertexIndex + 0, vertexIndex + 1, vertexIndex + vertexHullColumns);
                                _indexBufferData[faceIndex + 1] =
                                    new SharpDX.Int3(vertexIndex + vertexHullColumns, vertexIndex + 1, vertexIndex + vertexHullColumns + 1);
                            }
                        }
                    }
                }

                // Caps
                if (addCaps)
                {
                    for (var capIndex = 0; capIndex <= 1; capIndex++)
                    {
                        var isLowerCap = capIndex == 0;
                        var capLevel   = ((isLowerCap ? 0 : 1) - basePivot) * height;
                        var capRadius  = isLowerCap ? lowerRadius : upperRadius;
                        var isReverse  = isFlipped ^ isLowerCap;

                        var centerVertexIndex = hullVerticesCount + (capsVertexCount / 2) * (capIndex + 1) - 1;

                        for (var capSegmentIndex = 0; capSegmentIndex < capSegments; ++capSegmentIndex)
                        {
                            var isCenterSegment = capSegmentIndex == capSegments - 1;

                            var capFraction     = 1f - (capSegmentIndex) / (float)capSegments;
                            var nextCapFraction = 1f - (capSegmentIndex + 1) / (float)capSegments;
                            var radius          = upperRadius * capFraction;
                            var nextRadius      = upperRadius * nextCapFraction;


                            for (var columnIndex = 0; columnIndex < vertexHullColumns; ++columnIndex)
                            {
                                var columnAngle = columnIndex * radiusAngleFraction + spinInRad + twistInRad * (isLowerCap ? 0 : 1) + Math.PI;

                                var xx = (float)Math.Sin(columnAngle);
                                var yy = (float)Math.Cos(columnAngle);

                                var p = new SharpDX.Vector3(-xx * radius,
                                                            capLevel,
                                                            -yy * radius);

                                var normal0 = isLowerCap ? SharpDX.Vector3.Down : SharpDX.Vector3.Up;

                                var tangent0  = SharpDX.Vector3.Left;
                                var binormal0 = SharpDX.Vector3.ForwardRH;

                                var vertexIndex = capSegmentIndex * vertexHullColumns + columnIndex
                                                  + hullVerticesCount + (capsVertexCount / 2) * capIndex;

                                // Write vertex
                                var capUvOffset = isLowerCap
                                                      ? new SharpDX.Vector2(-0.25f, -0.25f)
                                                      : new SharpDX.Vector2(0.25f, -0.25f);
                                _vertexBufferData[vertexIndex] = new PbrVertex
                                {
                                    Position  = p + center,
                                    Normal    = isFlipped ? normal0 * -1 : normal0,
                                    Tangent   = tangent0,
                                    Bitangent = isFlipped ? binormal0 * -1 : binormal0,
                                    Texcoord  = new SharpDX.Vector2(-xx * (isLowerCap ? -1 : 1), yy) * capFraction / 4 + capUvOffset,
                                    Selection = 1
                                };

                                if (isCenterSegment)
                                {
                                    if (columnIndex == 0)
                                    {
                                        _vertexBufferData[centerVertexIndex] = new PbrVertex
                                        {
                                            Position  = new SharpDX.Vector3(0, capLevel, 0) + center,
                                            Normal    = (isFlipped) ? normal0 * -1 : normal0,
                                            Tangent   = tangent0,
                                            Bitangent = (isFlipped ^ isLowerCap) ? binormal0 * -1 : binormal0,
                                            Texcoord  = capUvOffset,
                                            Selection = 1
                                        };
                                    }
                                }

                                if (columnIndex < vertexHullColumns - 1 && capSegmentIndex < capSegments)
                                {
                                    if (isCenterSegment)
                                    {
                                        var faceIndex = (capSegmentIndex * (vertexHullColumns - 1) * 2 + columnIndex)
                                                        + hullTriangleCount + (capsTriangleCount / 2) * capIndex;

                                        var f1 = isReverse
                                                     ? new SharpDX.Int3(vertexIndex + 1, vertexIndex, centerVertexIndex)
                                                     : new SharpDX.Int3(centerVertexIndex, vertexIndex, vertexIndex + 1);
                                        _indexBufferData[faceIndex] = f1;
                                    }
                                    else
                                    {
                                        var faceIndex = (capSegmentIndex * (vertexHullColumns - 1) * 2) + columnIndex * 2
                                                        + hullTriangleCount +
                                                        (capsTriangleCount / 2) * capIndex;

                                        _indexBufferData[faceIndex]
                                            = isReverse
                                                  ? new SharpDX.Int3(vertexIndex + vertexHullColumns, vertexIndex + 1, vertexIndex)
                                                  : new SharpDX.Int3(vertexIndex, vertexIndex + 1, vertexIndex + vertexHullColumns);

                                        _indexBufferData[faceIndex + 1]
                                            = isReverse
                                                  ? new SharpDX.Int3(vertexIndex + vertexHullColumns, vertexIndex + vertexHullColumns + 1, vertexIndex + 1)
                                                  : new SharpDX.Int3(vertexIndex + 1, vertexIndex + vertexHullColumns + 1, vertexIndex + vertexHullColumns);
                                    }
                                }
                            }
                        }
                    }
                }

                // Write Data
                _vertexBufferWithViews.Buffer = _vertexBuffer;
                resourceManager.SetupStructuredBuffer(_vertexBufferData, PbrVertex.Stride * totalVertexCount, PbrVertex.Stride, ref _vertexBuffer);
                resourceManager.CreateStructuredBufferSrv(_vertexBuffer, ref _vertexBufferWithViews.Srv);
                resourceManager.CreateStructuredBufferUav(_vertexBuffer, UnorderedAccessViewBufferFlags.None, ref _vertexBufferWithViews.Uav);

                _indexBufferWithViews.Buffer = _indexBuffer;
                const int stride = 3 * 4;
                resourceManager.SetupStructuredBuffer(_indexBufferData, stride * totalTriangleCount, stride, ref _indexBuffer);
                resourceManager.CreateStructuredBufferSrv(_indexBuffer, ref _indexBufferWithViews.Srv);
                resourceManager.CreateStructuredBufferUav(_indexBuffer, UnorderedAccessViewBufferFlags.None, ref _indexBufferWithViews.Uav);

                _data.VertexBuffer  = _vertexBufferWithViews;
                _data.IndicesBuffer = _indexBufferWithViews;
                Data.Value          = _data;
                Data.DirtyFlag.Clear();
            }
            catch (Exception e)
            {
                Log.Error("Failed to create torus mesh:" + e.Message);
            }
        }
Ejemplo n.º 2
0
        private void Update(EvaluationContext context)
        {
            try
            {
                var resourceManager = ResourceManager.Instance();

                var majorRadius = Radius.GetValue(context);
                var tubeRadius  = Thickness.GetValue(context);

                var segments       = Segments.GetValue(context);
                var radiusSegments = segments.Width.Clamp(1, 10000) + 1;
                var tubeSegments   = segments.Height.Clamp(1, 10000) + 1;

                var spin           = Spin.GetValue(context);
                var radiusSpin     = spin.X * MathUtils.ToRad;
                var spinMinorInRad = spin.Y * MathUtils.ToRad;

                var fill       = Fill.GetValue(context);
                var fillRadius = fill.X / 360f;
                var tubeFill   = fill.Y / 360f;

                var smoothAngle = SmoothAngle.GetValue(context);

                var useFlatShading = fillRadius / tubeSegments > smoothAngle / 360 || tubeFill / radiusSegments > smoothAngle / 360;
                var faceCount      = (tubeSegments - 1) * (radiusSegments - 1) * 2;
                var verticesCount  = tubeSegments * radiusSegments;

                // Create buffers
                if (_vertexBufferData.Length != verticesCount)
                {
                    _vertexBufferData = new PbrVertex[verticesCount];
                }

                if (_indexBufferData.Length != faceCount)
                {
                    _indexBufferData = new SharpDX.Int3[faceCount];
                }


                // Initialize
                var tubeAngleFraction   = tubeFill / (tubeSegments - 1) * 2.0 * Math.PI;
                var radiusAngleFraction = fillRadius / (radiusSegments - 1) * 2.0 * Math.PI;

                for (int tubeIndex = 0; tubeIndex < tubeSegments; ++tubeIndex)
                {
                    var tubeAngle = tubeIndex * tubeAngleFraction + spinMinorInRad;

                    double tubePosition1X = Math.Sin(tubeAngle) * tubeRadius;
                    double tubePosition1Y = Math.Cos(tubeAngle) * tubeRadius;
                    double tubePosition2X = Math.Sin(tubeAngle + tubeAngleFraction) * tubeRadius;
                    double tubePosition2Y = Math.Cos(tubeAngle + tubeAngleFraction) * tubeRadius;

                    var v0 = tubeIndex / (float)(tubeSegments - 1);
                    var v1 = (tubeIndex + 1) / (float)(tubeSegments - 1);

                    for (int radiusIndex = 0; radiusIndex < radiusSegments; ++radiusIndex)
                    {
                        var vertexIndex = radiusIndex + tubeIndex * radiusSegments;
                        var faceIndex   = 2 * (radiusIndex + tubeIndex * (radiusSegments - 1));

                        var u0 = (radiusIndex) / (float)(radiusSegments - 1);
                        var u1 = (radiusIndex + 1) / (float)(radiusSegments - 1);

                        var radiusAngle = radiusIndex * radiusAngleFraction + radiusSpin;

                        var p = new SharpDX.Vector3((float)(Math.Sin(radiusAngle) * (tubePosition1X + majorRadius)),
                                                    (float)(Math.Cos(radiusAngle) * (tubePosition1X + majorRadius)),
                                                    (float)tubePosition1Y);

                        var p1 = new SharpDX.Vector3((float)(Math.Sin(radiusAngle + radiusAngleFraction) * (tubePosition1X + majorRadius)),
                                                     (float)(Math.Cos(radiusAngle + radiusAngleFraction) * (tubePosition1X + majorRadius)),
                                                     (float)tubePosition1Y);

                        var p2 = new SharpDX.Vector3((float)(Math.Sin(radiusAngle) * (tubePosition2X + majorRadius)),
                                                     (float)(Math.Cos(radiusAngle) * (tubePosition2X + majorRadius)),
                                                     (float)tubePosition2Y);

                        var uv0 = new SharpDX.Vector2(u0, v1);
                        var uv1 = new SharpDX.Vector2(u1, v1);
                        var uv2 = new SharpDX.Vector2(u1, v0);

                        var tubeCenter1 = new SharpDX.Vector3((float)Math.Sin(radiusAngle), (float)Math.Cos(radiusAngle), 0.0f) * majorRadius;
                        var normal0     = SharpDX.Vector3.Normalize(useFlatShading
                                                                    ? SharpDX.Vector3.Cross(p - p1, p - p2)
                                                                    : p - tubeCenter1);

                        MeshUtils.CalcTBNSpace(p, uv0, p1, uv1, p2, uv2, normal0, out var tangent0, out var binormal0);

                        _vertexBufferData[vertexIndex + 0] = new PbrVertex
                        {
                            Position  = p,
                            Normal    = normal0,
                            Tangent   = tangent0,
                            Bitangent = binormal0,
                            Texcoord  = uv0,
                            Selection = 1,
                        };

                        if (tubeIndex >= tubeSegments - 1 || radiusIndex >= radiusSegments - 1)
                        {
                            continue;
                        }

                        _indexBufferData[faceIndex + 0] = new SharpDX.Int3(vertexIndex + 0, vertexIndex + 1, vertexIndex + radiusSegments);
                        _indexBufferData[faceIndex + 1] = new SharpDX.Int3(vertexIndex + radiusSegments, vertexIndex + 1, vertexIndex + radiusSegments + 1);
                    }
                }

                // Write Data
                _vertexBufferWithViews.Buffer = _vertexBuffer;
                resourceManager.SetupStructuredBuffer(_vertexBufferData, PbrVertex.Stride * verticesCount, PbrVertex.Stride, ref _vertexBuffer);
                resourceManager.CreateStructuredBufferSrv(_vertexBuffer, ref _vertexBufferWithViews.Srv);
                resourceManager.CreateStructuredBufferUav(_vertexBuffer, UnorderedAccessViewBufferFlags.None, ref _vertexBufferWithViews.Uav);

                _indexBufferWithViews.Buffer = _indexBuffer;
                const int stride = 3 * 4;
                resourceManager.SetupStructuredBuffer(_indexBufferData, stride * faceCount, stride, ref _indexBuffer);
                resourceManager.CreateStructuredBufferSrv(_indexBuffer, ref _indexBufferWithViews.Srv);
                resourceManager.CreateStructuredBufferUav(_indexBuffer, UnorderedAccessViewBufferFlags.None, ref _indexBufferWithViews.Uav);

                _data.VertexBuffer  = _vertexBufferWithViews;
                _data.IndicesBuffer = _indexBufferWithViews;
                Data.Value          = _data;
                Data.DirtyFlag.Clear();
            }
            catch (Exception e)
            {
                Log.Error("Failed to create torus mesh:" + e.Message);
            }
        }
Ejemplo n.º 3
0
 public double GetValue(int hwnd)
 {
     return(spin.GetValue(hwnd));
 }