private void Update(EvaluationContext context) { var closeCircle = CloseCircle.GetValue(context); var circleOffset = closeCircle ? 1 : 0; var corners = Count.GetValue(context).Clamp(1, 10000); var pointCount = corners + circleOffset; var listCount = corners + 2 * circleOffset; // Separator if (_pointList.NumElements != listCount) { //_points = new T3.Core.DataTypes.Point[count]; _pointList.SetLength(listCount); } var axis = Axis.GetValue(context); var center = Center.GetValue(context); var offset = Offset.GetValue(context); var radius = Radius.GetValue(context); var radiusOffset = RadiusOffset.GetValue(context); var thickness = W.GetValue(context); var thicknessOffset = WOffset.GetValue(context); var angelInRads = StartAngel.GetValue(context) * MathUtils.ToRad + (float)Math.PI / 2; var deltaAngle = -Cycles.GetValue(context) * MathUtils.Pi2 / (pointCount - circleOffset); for (var index = 0; index < pointCount; index++) { var f = corners == 1 ? 1 : (float)index / pointCount; var length = MathUtils.Lerp(radius, radius + radiusOffset, f); var v = Vector3.UnitX * length; var rot = Quaternion.CreateFromAxisAngle(axis, angelInRads); var vInAxis = Vector3.Transform(v, rot) + Vector3.Lerp(center, center + offset, f); var p = new Point { Position = vInAxis, W = MathUtils.Lerp(thickness, thickness + thicknessOffset, f), Orientation = rot }; _pointList[index] = p; angelInRads += deltaAngle; } if (closeCircle) { _pointList[listCount - 1] = Point.Separator(); } ResultList.Value = _pointList; }
private void Update(EvaluationContext context) { var resourceManager = ResourceManager.Instance(); var numEntries = Count.GetValue(context); numEntries = Math.Max(numEntries, 1); numEntries = Math.Min(numEntries, 500000); var bufferData = new BufferEntry[numEntries]; var color = Color.GetValue(context); var random = new Random(Seed.GetValue(context)); var radius = Radius.GetValue(context); var objectToWorld = context.ObjectToWorld; for (int index = 0; index < numEntries; index++) { float u = random.NextFloat(0, 1); float v = random.NextFloat(0, 1); float theta = SharpDX.MathUtil.TwoPi * u; float z = 1.0f - 2.0f * v; float phi = (float)Math.Acos(z); float sinPhi = (float)Math.Sin(phi); float x = sinPhi * (float)Math.Cos(theta); float y = sinPhi * (float)Math.Sin(theta); var posInObject = new Vector3(x, y, z); // dir *= radius; posInObject *= random.NextFloat(0.0f, radius); var posInWorld = Vector3.Transform(posInObject, objectToWorld); bufferData[index].Pos = new Vector3(posInWorld.X, posInWorld.Y, posInWorld.Z); bufferData[index].Id = _id; bufferData[index].Color = new Vector4(color.X, color.Y, color.Z, color.W); } var stride = 32; resourceManager.SetupStructuredBuffer(bufferData, stride * numEntries, stride, ref _buffer); resourceManager.CreateStructuredBufferSrv(_buffer, ref PointCloudSrv.Value); }
private void Update(EvaluationContext context) { float fov = MathUtil.DegreesToRadians(Fov.GetValue(context)); float aspectRatio = AspectRatio.GetValue(context); if (aspectRatio < 0.0001f) { aspectRatio = (float)context.RequestedResolution.Width / context.RequestedResolution.Height; } System.Numerics.Vector2 clip = NearFarClip.GetValue(context); Matrix cameraToClipSpace = Matrix.PerspectiveFovRH(fov, aspectRatio, clip.X, clip.Y); // var pos = Position.GetValue(context); // Vector3 eye = new Vector3(pos.X, pos.Y, pos.Z); Vector3 p = new Vector3(0, 0, Radius.GetValue(context)); var seed = Seed.GetValue(context); var wobbleSpeed = WobbleSpeed.GetValue(context); var wobbleComplexity = (int)MathUtils.Clamp(WobbleComplexity.GetValue(context), 1, 8); //var offset = var rotOffset = RotationOffset.GetValue(context); // Orbit rotation System.Numerics.Vector3 t = Center.GetValue(context); Vector3 target = new Vector3(t.X, t.Y, t.Z); var rot = Matrix.RotationYawPitchRoll( ComputeAngle(SpinAngleAndWobble, 1) + MathUtil.DegreesToRadians((float)(SpinRate.GetValue(context) * (EvaluationContext.BeatTime + SpinOffset.GetValue(context)) * 360 + MathUtils.PerlinNoise(0, 1, 6, seed) * 360)) , -ComputeAngle(OrbitAngleAndWobble, 2), 0); var p2 = Vector3.Transform(p, rot); var eye = new Vector3(p2.X, p2.Y, p2.Z); // View rotation var viewDirection = target - eye; var rotateAim = Matrix.RotationYawPitchRoll( ComputeAngle(AimYawAngleAndWobble, 3) + rotOffset.X * MathUtils.ToRad, ComputeAngle(AimPitchAngleAndWobble, 4) + rotOffset.Y * MathUtils.ToRad, rotOffset.Z * MathUtils.ToRad); var adjustedViewDirection = Vector3.TransformNormal(viewDirection, rotateAim); target = eye + adjustedViewDirection; // Computing matrix var u = Up.GetValue(context); Vector3 up = new Vector3(u.X, u.Y, u.Z); var roll = ComputeAngle(AimRollAngleAndWobble, 5); var rotateAroundViewDirection = Matrix.RotationAxis(adjustedViewDirection, roll); up = Vector3.TransformNormal(up, rotateAroundViewDirection); Matrix worldToCamera = Matrix.LookAtRH(eye, target, up); var prevCameraToClipSpace = context.CameraToClipSpace; context.CameraToClipSpace = cameraToClipSpace; var prevWorldToCamera = context.WorldToCamera; context.WorldToCamera = worldToCamera; Command.GetValue(context); context.CameraToClipSpace = prevCameraToClipSpace; context.WorldToCamera = prevWorldToCamera; float ComputeAngle(Slot <Vector2> angleAndWobbleInput, int seedIndex) { var angleAndWobble = angleAndWobbleInput.GetValue(context); var wobble = Math.Abs(angleAndWobble.Y) < 0.001f ? 0 : (MathUtils.PerlinNoise((float)EvaluationContext.BeatTime * wobbleSpeed, 1, wobbleComplexity, seed - 123 * seedIndex) - 0.5f) * 2 * angleAndWobble.Y; return(MathUtil.DegreesToRadians(angleAndWobble.X + wobble)); } }
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); } }
private void Update(EvaluationContext context) { try { var resourceManager = ResourceManager.Instance(); var radius = Radius.GetValue(context); //var tubeRadius = Thickness.GetValue(context); var segments = Segments.GetValue(context); var uSegments = segments.Width.Clamp(2, 10000) + 1; var vSegments = segments.Height.Clamp(2, 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 = FlatShaded.GetValue(context); // fillRadius / vSegments > smoothAngle / 360 || tubeFill / uSegments > smoothAngle / 360; var polTriangleCount = 2 * uSegments; var sideTriangleCount = (vSegments - 2) * uSegments * 2; var triangleCount = polTriangleCount + sideTriangleCount; var verticesCount = (vSegments + 1) * (uSegments); // Create buffers if (_vertexBufferData.Length != verticesCount) { _vertexBufferData = new PbrVertex[verticesCount]; } if (_indexBufferData.Length != triangleCount) { _indexBufferData = new SharpDX.Int3[triangleCount]; } // Initialize var vAngleFraction = 1f / (vSegments - 1) * 1.0 * Math.PI; var uAngleFraction = 1f / (uSegments - 1) * 2.0 * Math.PI; for (int vIndex = 0; vIndex < vSegments; ++vIndex) { var vAngle = vIndex * vAngleFraction; var tubePosition1Y = Math.Cos(vAngle) * radius; var radius1 = Math.Sin(vAngleFraction * vIndex) * radius; var v0 = 1 - vIndex / (float)(vSegments - 1); var isTop = vIndex == 0; var isBottom = vIndex == vSegments - 1; if (isTop || isBottom) { var normalPol0 = SharpDX.Vector3.Up; var normalPol1 = SharpDX.Vector3.Down; for (int uIndex = 0; uIndex < uSegments; ++uIndex) { var u0 = (uIndex) / (float)(uSegments - 1); var uAngle = uIndex * uAngleFraction; // top var tangentPol0 = SharpDX.Vector3.Normalize(new SharpDX.Vector3(MathF.Sin((float)uAngle), 0, MathF.Cos((float)uAngle))); var binormalPol0 = SharpDX.Vector3.Normalize(new SharpDX.Vector3(MathF.Sin((float)uAngle + MathF.PI / 2), 0, MathF.Cos((float)uAngle + MathF.PI / 2))); var pPol0 = new SharpDX.Vector3(0, radius, 0); var uv0 = new SharpDX.Vector2(u0, 1); _vertexBufferData[0 + uIndex] = new PbrVertex { Position = pPol0, Normal = normalPol0, Tangent = tangentPol0, Bitangent = binormalPol0, Texcoord = uv0, Selection = 1, }; // bottom var tangentPol1 = SharpDX.Vector3.Normalize(new SharpDX.Vector3(MathF.Sin((float)uAngle + MathF.PI / 2), 0, MathF.Cos((float)uAngle + MathF.PI / 2))); var binormalPol1 = SharpDX.Vector3.Normalize(new SharpDX.Vector3(MathF.Sin((float)uAngle), 0, MathF.Cos((float)uAngle))); var pPol1 = new SharpDX.Vector3(0, -radius, 0); var uv1 = new SharpDX.Vector2(u0, 0); _vertexBufferData[(vSegments - 1) * uSegments + uIndex] = new PbrVertex { Position = pPol1, Normal = normalPol1, Tangent = tangentPol1, Bitangent = binormalPol1, Texcoord = uv1, Selection = 1, }; if (uIndex >= uSegments - 1) { continue; } _indexBufferData[uIndex] = new SharpDX.Int3(uIndex, uIndex + uSegments, uIndex + uSegments + 1); _indexBufferData[uIndex] = new SharpDX.Int3(uIndex, uIndex + uSegments, uIndex + uSegments + 1); } } else { for (int uIndex = 0; uIndex < uSegments; ++uIndex) { var vVertexIndex = vIndex * uSegments; var faceIndex = 2 * (uIndex + vIndex * (uSegments - 1)); var u0 = (uIndex) / (float)(uSegments - 1); var uAngle = uIndex * uAngleFraction; var p = new SharpDX.Vector3((float)(Math.Sin(uAngle) * radius1), (float)tubePosition1Y, (float)(Math.Cos(uAngle) * radius1) ); var uv0 = new SharpDX.Vector2(u0, v0); var normal0 = SharpDX.Vector3.Normalize(p); var tangent0 = SharpDX.Vector3.Normalize(new SharpDX.Vector3(normal0.Z, 0, -normal0.X)); var binormal0 = SharpDX.Vector3.Cross(normal0, tangent0); _vertexBufferData[vVertexIndex + uIndex] = new PbrVertex { Position = p, Normal = normal0, Tangent = tangent0, Bitangent = binormal0, Texcoord = uv0, Selection = 1, }; if (vIndex >= vSegments - 1 || uIndex >= uSegments - 1) { continue; } var nextUIndex = (uIndex + 1) % uSegments; _indexBufferData[faceIndex + 0] = new SharpDX.Int3(vVertexIndex + nextUIndex, vVertexIndex + uIndex + 0, vVertexIndex + uIndex + uSegments); _indexBufferData[faceIndex + 1] = new SharpDX.Int3((vVertexIndex + nextUIndex + uSegments), (vVertexIndex + nextUIndex), vVertexIndex + uIndex + uSegments + 0); } } } // 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 * triangleCount, 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 sphere mesh:" + e.Message); } }
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); } }