private static VFXExpression PatchVFXExpression(VFXExpression input, bool insertGPUTransformation, bool patchReadAttributeForSpawn, IEnumerable <VFXLayoutElementDesc> globalEventAttribute) { if (insertGPUTransformation) { switch (input.valueType) { case VFXValueType.ColorGradient: input = new VFXExpressionBakeGradient(input); break; case VFXValueType.Curve: input = new VFXExpressionBakeCurve(input); break; default: break; } } if (patchReadAttributeForSpawn && input is VFXAttributeExpression) { var attribute = input as VFXAttributeExpression; if (attribute.attributeLocation == VFXAttributeLocation.Current) { if (globalEventAttribute == null) { throw new InvalidOperationException("m_GlobalEventAttribute is null"); } var layoutDesc = globalEventAttribute.FirstOrDefault(o => o.name == attribute.attributeName); if (layoutDesc.name != attribute.attributeName) { throw new InvalidOperationException("Unable to find " + attribute.attributeName + " in globalEventAttribute"); } input = new VFXReadEventAttributeExpression(attribute.attribute, layoutDesc.offset.element); } } return(input); }
private VFXExpression PatchVFXExpression(VFXExpression input, VFXExpression targetExpression, bool insertGPUTransformation, bool patchReadAttributeForSpawn, IEnumerable <VFXLayoutElementDesc> globalEventAttribute) { if (insertGPUTransformation) { switch (input.valueType) { case VFXValueType.ColorGradient: input = new VFXExpressionBakeGradient(input); break; case VFXValueType.Curve: input = new VFXExpressionBakeCurve(input); break; case VFXValueType.Mesh: case VFXValueType.SkinnedMeshRenderer: if (targetExpression != null) { if (input.valueType == VFXValueType.Mesh) { switch (targetExpression.operation) { case VFXExpressionOperation.SampleMeshVertexFloat: case VFXExpressionOperation.SampleMeshVertexFloat2: case VFXExpressionOperation.SampleMeshVertexFloat3: case VFXExpressionOperation.SampleMeshVertexFloat4: case VFXExpressionOperation.SampleMeshVertexColor: var channelFormatAndDimensionAndStream = targetExpression.parents[2]; channelFormatAndDimensionAndStream = Compile(channelFormatAndDimensionAndStream); if (!(channelFormatAndDimensionAndStream is VFXExpressionMeshChannelInfos)) { throw new InvalidOperationException("Unexpected type of expression in mesh sampling : " + channelFormatAndDimensionAndStream); } input = new VFXExpressionVertexBufferFromMesh(input, channelFormatAndDimensionAndStream); break; case VFXExpressionOperation.SampleMeshIndex: input = new VFXExpressionIndexBufferFromMesh(input); break; default: throw new InvalidOperationException("Unexpected source operation for InsertGPUTransformation : " + targetExpression.operation); } } else //VFXValueType.SkinnedMeshRenderer { if (targetExpression is VFXExpressionSampleSkinnedMeshRendererFloat || targetExpression is VFXExpressionSampleSkinnedMeshRendererFloat2 || targetExpression is VFXExpressionSampleSkinnedMeshRendererFloat3 || targetExpression is VFXExpressionSampleSkinnedMeshRendererFloat4 || targetExpression is VFXExpressionSampleSkinnedMeshRendererColor) { var channelFormatAndDimensionAndStream = targetExpression.parents[2]; channelFormatAndDimensionAndStream = Compile(channelFormatAndDimensionAndStream); if (!(channelFormatAndDimensionAndStream is VFXExpressionMeshChannelInfos)) { throw new InvalidOperationException("Unexpected type of expression in skinned mesh sampling : " + channelFormatAndDimensionAndStream); } input = new VFXExpressionVertexBufferFromSkinnedMeshRenderer(input, channelFormatAndDimensionAndStream); } else { throw new InvalidOperationException("Unexpected source operation for InsertGPUTransformation : " + targetExpression); } } } //else sourceExpression is null, we can't determine usage but it's possible if value is declared but not used. break; case VFXValueType.Buffer: { //Save expression usage for later HLSL shader generation if (targetExpression is VFXExpressionSampleBuffer) { var sampledType = (targetExpression as VFXExpressionSampleBuffer).GetSampledType(); if (!m_GraphicsBufferUsageType.TryGetValue(input, out var registeredType)) { m_GraphicsBufferUsageType.Add(input, sampledType); } else if (registeredType != sampledType) { throw new InvalidOperationException(string.Format("Diverging type usage for GraphicsBuffer : {0}, {1}", registeredType, sampledType)); } } } break; default: //Nothing to patch on this type break; } if (input.valueType == VFXValueType.Buffer && targetExpression is VFXExpressionSampleBuffer) { if (!m_GraphicsBufferUsageType.ContainsKey(input)) { m_GraphicsBufferUsageType.Add(input, (targetExpression as VFXExpressionSampleBuffer).GetSampledType()); } } } if (patchReadAttributeForSpawn && input is VFXAttributeExpression) { var attribute = input as VFXAttributeExpression; if (attribute.attributeLocation == VFXAttributeLocation.Current) { if (globalEventAttribute == null) { throw new InvalidOperationException("m_GlobalEventAttribute is null"); } var layoutDesc = globalEventAttribute.FirstOrDefault(o => o.name == attribute.attributeName); if (layoutDesc.name != attribute.attributeName) { throw new InvalidOperationException("Unable to find " + attribute.attributeName + " in globalEventAttribute"); } input = new VFXReadEventAttributeExpression(attribute.attribute, layoutDesc.offset.element); } } return(input); }