protected override VFXExpression[] BuildExpression(VFXExpression[] inputExpression) { var attribute = VFXAttribute.Find(this.attribute); if (attribute.variadic == VFXVariadic.True) { var attributes = new VFXAttribute[] { VFXAttribute.Find(attribute.name + "X"), VFXAttribute.Find(attribute.name + "Y"), VFXAttribute.Find(attribute.name + "Z") }; var expressions = attributes.Select(a => new VFXAttributeExpression(a, location)).ToArray(); var componentStack = new Stack <VFXExpression>(); int outputSize = mask.Length; for (int iComponent = 0; iComponent < outputSize; iComponent++) { char componentChar = char.ToLower(mask[iComponent]); int currentComponent = Math.Min(componentChar - 'x', 2); componentStack.Push(expressions[currentComponent]); } VFXExpression finalExpression = null; if (componentStack.Count == 1) { finalExpression = componentStack.Pop(); } else { finalExpression = new VFXExpressionCombine(componentStack.Reverse().ToArray()); } return(new[] { finalExpression }); } else { var expression = new VFXAttributeExpression(attribute, location); return(new VFXExpression[] { expression }); } }
static public VFXExpression Sequential3D(VFXExpression origin, VFXExpression axisX, VFXExpression axisY, VFXExpression axisZ, VFXExpression index, VFXExpression countX, VFXExpression countY, VFXExpression countZ) { index = VFXOperatorUtility.Modulo(index, countX * countY * countZ); var z = new VFXExpressionCastUintToFloat(VFXOperatorUtility.Modulo(index, countZ)); var y = new VFXExpressionCastUintToFloat(VFXOperatorUtility.Modulo(index / countZ, countY)); var x = new VFXExpressionCastUintToFloat(index / (countY * countZ)); VFXExpression volumeSize = new VFXExpressionCombine(new VFXExpressionCastUintToFloat(countX), new VFXExpressionCastUintToFloat(countY), new VFXExpressionCastUintToFloat(countZ)); volumeSize = volumeSize - VFXOperatorUtility.OneExpression[VFXValueType.Float3]; var scaleAxisZero = Saturate(volumeSize); //Handle special case for one count => lead to be centered on origin (instead of -axis) volumeSize = new VFXExpressionMax(volumeSize, VFXOperatorUtility.OneExpression[VFXValueType.Float3]); var dt = new VFXExpressionCombine(x, y, z) / volumeSize; dt = dt * VFXOperatorUtility.TwoExpression[VFXValueType.Float3] - VFXOperatorUtility.OneExpression[VFXValueType.Float3]; var r = origin; r += dt.xxx * scaleAxisZero.xxx * axisX; r += dt.yyy * scaleAxisZero.yyy * axisY; r += dt.zzz * scaleAxisZero.zzz * axisZ; return(r); }
static public VFXExpression UniformScaleMatrix(VFXExpression scale) { var scale3 = new VFXExpressionCombine(scale, scale, scale); var zero = ZeroExpression[VFXValueType.Float3]; return(new VFXExpressionTRSToMatrix(zero, zero, scale3)); }
static public VFXExpression PolarToRectangular(VFXExpression theta, VFXExpression distance) { //x = cos(angle) * distance //y = sin(angle) * distance var result = new VFXExpressionCombine(new VFXExpression[] { new VFXExpressionCos(theta), new VFXExpressionSin(theta) }); return(result * CastFloat(distance, VFXValueType.Float2)); }
static public VFXExpression SequentialLine(VFXExpression start, VFXExpression end, VFXExpression index, VFXExpression count) { VFXExpression dt = new VFXExpressionCastUintToFloat(VFXOperatorUtility.Modulo(index, count)); dt = dt / new VFXExpressionCastUintToFloat(count); dt = new VFXExpressionCombine(dt, dt, dt); return(VFXOperatorUtility.Lerp(start, end, dt)); }
static public VFXExpression CastFloat(VFXExpression from, VFXValueType toValueType, float defaultValue = 0.0f) { if (!VFXExpressionNumericOperation.IsFloatValueType(from.valueType) || !VFXExpressionNumericOperation.IsFloatValueType(toValueType)) { throw new ArgumentException(string.Format("Invalid CastFloat : {0} to {1}", from, toValueType)); } if (from.valueType == toValueType) { return(from); } var fromValueType = from.valueType; var fromValueTypeSize = VFXExpression.TypeToSize(fromValueType); var toValueTypeSize = VFXExpression.TypeToSize(toValueType); var inputComponent = new VFXExpression[fromValueTypeSize]; var outputComponent = new VFXExpression[toValueTypeSize]; if (inputComponent.Length == 1) { inputComponent[0] = from; } else { for (int iChannel = 0; iChannel < fromValueTypeSize; ++iChannel) { inputComponent[iChannel] = from[iChannel]; } } for (int iChannel = 0; iChannel < toValueTypeSize; ++iChannel) { if (iChannel < fromValueTypeSize) { outputComponent[iChannel] = inputComponent[iChannel]; } else if (fromValueTypeSize == 1) { //Manage same logic behavior for float => floatN in HLSL outputComponent[iChannel] = inputComponent[0]; } else { outputComponent[iChannel] = VFXValue.Constant(defaultValue); } } if (toValueTypeSize == 1) { return(outputComponent[0]); } var combine = new VFXExpressionCombine(outputComponent); return(combine); }
static public VFXExpression SequentialLine(VFXExpression start, VFXExpression end, VFXExpression index, VFXExpression count) { VFXExpression dt = new VFXExpressionCastUintToFloat(VFXOperatorUtility.Modulo(index, count)); var size = new VFXExpressionCastUintToFloat(count) - VFXOperatorUtility.OneExpression[VFXValueType.Float]; size = new VFXExpressionMax(size, VFXOperatorUtility.OneExpression[VFXValueType.Float]); dt = dt / size; dt = new VFXExpressionCombine(dt, dt, dt); return(VFXOperatorUtility.Lerp(start, end, dt)); }
static public VFXExpression GetOrthographicMatrix(VFXExpression orthoSize, VFXExpression aspect, VFXExpression zNear, VFXExpression zFar) { var deltaZ = zNear - zFar; var oneOverSize = OneExpression[VFXValueType.Float] / orthoSize; var zero = ZeroExpression[VFXValueType.Float]; var m0 = new VFXExpressionCombine(oneOverSize / aspect, zero, zero, zero); var m1 = new VFXExpressionCombine(zero, oneOverSize, zero, zero); var m2 = new VFXExpressionCombine(zero, zero, MinusOneExpression[VFXValueType.Float] * TwoExpression[VFXValueType.Float] / deltaZ, zero); var m3 = new VFXExpressionCombine(zero, zero, (zFar + zNear) / deltaZ, OneExpression[VFXValueType.Float]); return(new VFXExpressionVector4sToMatrix(m0, m1, m2, m3)); }
// TODO Use a dedicated expression for that static public VFXExpression Transpose(VFXExpression matrix) { var m0 = new VFXExpressionMatrixToVector4s(matrix, VFXValue.Constant(0)); var m1 = new VFXExpressionMatrixToVector4s(matrix, VFXValue.Constant(1)); var m2 = new VFXExpressionMatrixToVector4s(matrix, VFXValue.Constant(2)); var m3 = new VFXExpressionMatrixToVector4s(matrix, VFXValue.Constant(3)); var n0 = new VFXExpressionCombine(m0.x, m1.x, m2.x, m3.x); var n1 = new VFXExpressionCombine(m0.y, m1.y, m2.y, m3.y); var n2 = new VFXExpressionCombine(m0.z, m1.z, m2.z, m3.z); var n3 = new VFXExpressionCombine(m0.w, m1.w, m2.w, m3.w); return(new VFXExpressionVector4sToMatrix(n0, n1, n2, n3)); }
static public VFXExpression GetPerspectiveMatrix(VFXExpression fov, VFXExpression aspect, VFXExpression zNear, VFXExpression zFar) { var fovHalf = fov / TwoExpression[VFXValueType.Float]; var cotangent = new VFXExpressionCos(fovHalf) / new VFXExpressionSin(fovHalf); var deltaZ = zNear - zFar; var zero = ZeroExpression[VFXValueType.Float]; var m0 = new VFXExpressionCombine(cotangent / aspect, zero, zero, zero); var m1 = new VFXExpressionCombine(zero, cotangent, zero, zero); var m2 = new VFXExpressionCombine(zero, zero, MinusOneExpression[VFXValueType.Float] * (zFar + zNear) / deltaZ, OneExpression[VFXValueType.Float]); var m3 = new VFXExpressionCombine(zero, zero, TwoExpression[VFXValueType.Float] * zNear * zFar / deltaZ, zero); return(new VFXExpressionVector4sToMatrix(m0, m1, m2, m3)); }
static public VFXExpression SequentialCircle(VFXExpression center, VFXExpression radius, VFXExpression normal, VFXExpression up, VFXExpression index, VFXExpression count) { VFXExpression dt = new VFXExpressionCastUintToFloat(VFXOperatorUtility.Modulo(index, count)); dt = dt / new VFXExpressionCastUintToFloat(count); var cos = new VFXExpressionCos(dt * VFXOperatorUtility.TauExpression[VFXValueType.Float]) as VFXExpression; var sin = new VFXExpressionSin(dt * VFXOperatorUtility.TauExpression[VFXValueType.Float]) as VFXExpression; var left = VFXOperatorUtility.Normalize(VFXOperatorUtility.Cross(normal, up)); radius = new VFXExpressionCombine(radius, radius, radius); sin = new VFXExpressionCombine(sin, sin, sin); cos = new VFXExpressionCombine(cos, cos, cos); return(center + (cos * up + sin * left) * radius); }
static public VFXExpression SphericalToRectangular(VFXExpression theta, VFXExpression phi, VFXExpression distance) { //x = cos(theta) * cos(phi) * distance //y = sin(theta) * cos(phi) * distance //z = sin(phi) * distance var cosTheta = new VFXExpressionCos(theta); var cosPhi = new VFXExpressionCos(phi); var sinTheta = new VFXExpressionSin(theta); var sinPhi = new VFXExpressionSin(phi); var x = (cosTheta * cosPhi); var y = sinPhi; var z = (sinTheta * cosPhi); var result = new VFXExpressionCombine(new VFXExpression[] { x, y, z }); return(result * CastFloat(distance, VFXValueType.Float3)); }
static public VFXExpression SequentialCircle(VFXExpression center, VFXExpression radius, VFXExpression normal, VFXExpression up, VFXExpression index, VFXExpression count, SequentialAddressingMode mode) { VFXExpression countForAddressing = count; if (mode == SequentialAddressingMode.Clamp || mode == SequentialAddressingMode.Mirror) { //Explicitly close the circle loop, if `index` equals to `count`, adds an extra step. countForAddressing = count + OneExpression[VFXValueType.Uint32]; } VFXExpression dt = ApplyAddressingMode(index, countForAddressing, mode); dt = new VFXExpressionCastUintToFloat(dt); dt = dt / new VFXExpressionCastUintToFloat(count); var cos = new VFXExpressionCos(dt * VFXOperatorUtility.TauExpression[VFXValueType.Float]) as VFXExpression; var sin = new VFXExpressionSin(dt * VFXOperatorUtility.TauExpression[VFXValueType.Float]) as VFXExpression; var left = VFXOperatorUtility.Normalize(VFXOperatorUtility.Cross(normal, up)); radius = new VFXExpressionCombine(radius, radius, radius); sin = new VFXExpressionCombine(sin, sin, sin); cos = new VFXExpressionCombine(cos, cos, cos); return(center + (cos * up + sin * left) * radius); }