private void Update(EvaluationContext context) { try { var resourceManager = ResourceManager.Instance(); var scale = Scale.GetValue(context); var stretch = Stretch.GetValue(context); var stretchDX = new SharpDX.Vector3(stretch.X, stretch.Y, stretch.Z); var pivot = Pivot.GetValue(context); var pivotDX = new SharpDX.Vector3(pivot.X, pivot.Y, pivot.Z); var rotation = Rotation.GetValue(context); var cubeRotationMatrix = Matrix.RotationYawPitchRoll(MathUtil.DegreesToRadians(rotation.Y), MathUtil.DegreesToRadians(rotation.X), MathUtil.DegreesToRadians(rotation.Z)); var center = Center.GetValue(context); // var offset = new SharpDX.Vector3(stretch.X * scale * (pivot.X - 0.5f), // stretch.Y * scale * (pivot.Y - 0.5f), // stretch.Z * scale * (pivot.Z - 0.5f)); var offset = -SharpDX.Vector3.One * 0.5f; var center2 = new SharpDX.Vector3(center.X, center.Y, center.Z); var segments = Segments.GetValue(context); _xSegments = segments.X.Clamp(1, 10000) + 1; _ySegments = segments.Y.Clamp(1, 10000) + 1; _zSegments = segments.Z.Clamp(1, 10000) + 1; var faceCount = (_ySegments - 1) * (_xSegments - 1) * 2 * 2 // front / back + (_ySegments - 1) * (_zSegments - 1) * 2 * 2 // top / bottom + (_xSegments - 1) * (_zSegments - 1) * 2 * 2; // left / right var verticesCount = (_ySegments * _xSegments + _ySegments * _zSegments + _xSegments * _zSegments) * 2; // Create buffers if (_vertexBufferData.Length != verticesCount) { _vertexBufferData = new PbrVertex[verticesCount]; } if (_indexBufferData.Length != faceCount) { _indexBufferData = new SharpDX.Int3[faceCount]; } int sideFaceIndex = 0; int sideVertexIndex = 0; for (var sideIndex = 0; sideIndex < _sides.Length; sideIndex++) { var side = _sides[sideIndex]; var sideRotationMatrix = Matrix.RotationYawPitchRoll(side.SideRotation.Y, side.SideRotation.X, side.SideRotation.Z); var rotationMatrix = Matrix.Multiply(sideRotationMatrix, cubeRotationMatrix); var columnCount = GetSegmentCountForAxis(side.ColumnAxis); var rowCount = GetSegmentCountForAxis(side.RowAxis); var columnStretch = GetComponentForAxis(side.ColumnAxis, stretch); var rowStretch = GetComponentForAxis(side.RowAxis, stretch); var depthStretch = GetComponentForAxis(side.DepthAxis, stretch); double columnStep = 1.0 / (columnCount - 1); double rowStep = 1.0 / (rowCount - 1); float depthScale = 1f; var normal = SharpDX.Vector3.TransformNormal(SharpDX.Vector3.ForwardLH, rotationMatrix); var tangent = SharpDX.Vector3.TransformNormal(SharpDX.Vector3.Right, rotationMatrix); var binormal = SharpDX.Vector3.TransformNormal(SharpDX.Vector3.Up, rotationMatrix); // Initialize for (int columnIndex = 0; columnIndex < columnCount; ++columnIndex) { var columnFragment = (float)(columnIndex * columnStep); var u0 = columnIndex / ((float)columnCount - 1); for (int rowIndex = 0; rowIndex < rowCount; ++rowIndex) { var rowFragment = (float)(rowIndex * rowStep); var vertexIndex = rowIndex + columnIndex * rowCount + sideVertexIndex; var faceIndex = 2 * (rowIndex + columnIndex * (rowCount - 1)) + sideFaceIndex; var p = new SharpDX.Vector3(columnFragment, rowFragment, depthScale); var v0 = (rowIndex) / ((float)rowCount - 1); var uv0 = new SharpDX.Vector2(u0, v0); var position = (SharpDX.Vector3.TransformNormal(p + offset, sideRotationMatrix) + pivotDX) * stretchDX * scale; position = SharpDX.Vector3.TransformNormal(position, cubeRotationMatrix); _vertexBufferData[vertexIndex + 0] = new PbrVertex { Position = position + center2, Normal = normal, Tangent = tangent, Bitangent = binormal, Texcoord = uv0, Selection = 1, }; if (columnIndex >= columnCount - 1 || rowIndex >= rowCount - 1) { continue; } _indexBufferData[faceIndex + 0] = new SharpDX.Int3(vertexIndex, vertexIndex + rowCount, vertexIndex + 1); _indexBufferData[faceIndex + 1] = new SharpDX.Int3(vertexIndex + rowCount, vertexIndex + rowCount + 1, vertexIndex + 1); } } sideVertexIndex += columnCount * rowCount; sideFaceIndex += (columnCount - 1) * (rowCount - 1) * 2; } // 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 cube 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 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 scale = Scale.GetValue(context); var stretch = Stretch.GetValue(context); var pivot = Pivot.GetValue(context); var rotation = Rotation.GetValue(context); float yaw = MathUtil.DegreesToRadians(rotation.Y); float pitch = MathUtil.DegreesToRadians(rotation.X); float roll = MathUtil.DegreesToRadians(rotation.Z); var rotationMatrix = Matrix.RotationYawPitchRoll(yaw, pitch, roll); //var offset = var center = Center.GetValue(context); //var centerRotated = SharpDX.Vector3.Transform(new SharpDX.Vector3(center.X, center.Y, center.Z), rotationMatrix); var offset = new SharpDX.Vector3(stretch.X * scale * (pivot.X - 0.5f), stretch.Y * scale * (pivot.Y - 0.5f), 0); var center2 = new SharpDX.Vector3(center.X, center.Y, center.Z); var segments = Segments.GetValue(context); var columns = segments.Width.Clamp(1, 10000) + 1; var rows = segments.Height.Clamp(1, 10000) + 1; var faceCount = (columns - 1) * (rows - 1) * 2; var verticesCount = columns * rows; // Create buffers if (_vertexBufferData.Length != verticesCount) { _vertexBufferData = new PbrVertex[verticesCount]; } if (_indexBufferData.Length != faceCount) { _indexBufferData = new SharpDX.Int3[faceCount]; } double columnStep = (scale * stretch.X) / (columns - 1); double rowStep = (scale * stretch.Y) / (rows - 1); // var normal = SharpDX.Vector3.ForwardRH; // var tangent = SharpDX.Vector3.Right; // var binormal = SharpDX.Vector3.Up; var normal = SharpDX.Vector3.TransformNormal(SharpDX.Vector3.ForwardLH, rotationMatrix); var tangent = SharpDX.Vector3.TransformNormal(SharpDX.Vector3.Right, rotationMatrix); var binormal = SharpDX.Vector3.TransformNormal(SharpDX.Vector3.Up, rotationMatrix); // Initialize for (int columnIndex = 0; columnIndex < columns; ++columnIndex) { var columnFragment = (float)(columnIndex * columnStep); var u0 = columnIndex / ((float)columns - 1); //var v1 = (columnIndex + 1) / (float)columns; for (int rowIndex = 0; rowIndex < rows; ++rowIndex) { var rowFragment = (float)(rowIndex * rowStep); //var rowFragment = ((float)rowIndex / rows - pivot.Y) * stretch.Y; var vertexIndex = rowIndex + columnIndex * rows; var faceIndex = 2 * (rowIndex + columnIndex * (rows - 1)); var p = new SharpDX.Vector3(columnFragment, rowFragment, 0); var v0 = (rowIndex) / ((float)rows - 1); var uv0 = new SharpDX.Vector2(u0, v0); _vertexBufferData[vertexIndex + 0] = new PbrVertex { Position = SharpDX.Vector3.TransformNormal(p + offset, rotationMatrix) + center2, Normal = normal, Tangent = tangent, Bitangent = binormal, Texcoord = uv0, Selection = 1, }; if (columnIndex >= columns - 1 || rowIndex >= rows - 1) { continue; } _indexBufferData[faceIndex + 0] = new SharpDX.Int3(vertexIndex, vertexIndex + rows, vertexIndex + 1); _indexBufferData[faceIndex + 1] = new SharpDX.Int3(vertexIndex + rows, vertexIndex + rows + 1, vertexIndex + 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); } }