diff --git a/Samples/Composition/README.md b/Samples/Composition/README.md
new file mode 100644
index 000000000..fcc792394
--- /dev/null
+++ b/Samples/Composition/README.md
@@ -0,0 +1,23 @@
+---
+name: "Composition Samples"
+page_type: sample
+languages:
+- csharp
+products:
+- windows
+- windows-app-sdk
+urlFragment: rendering
+description: "Demonstrate the usage of rendering APIs (in both Microsoft.UI.Composition and Windows.UI.Composition) with WinAppSDK apps."
+extendedZipContent:
+- path: LICENSE
+ target: LICENSE
+---
+
+# Composition Samples
+Welcome to the Windows Composition Samples. These samples demonstrate the usage of both Microsoft.UI.Composition and Windows.UI.Composition APIs that you can use to enhance your Windows App SDK application.
+
+## Dynamic Refresh Rate Sample
+
+## Sample Gallery
+This is the place for the latest code samples, demos, and developer feedback around building beautiful and engaging WinUI3 apps. This repo focuses on the platform building blocks that make up the [Fluent Design System](https://fluent.microsoft.com/), with emphasis on creating UI using APIs in the [Microsoft.UI.Composition](https://docs.microsoft.com/windows/winui/api/microsoft.ui.composition) and [Microsoft.UI.Input](https://docs.microsoft.com/windows/winui/api/microsoft.ui.input) namespaces. For those of you familiar with the Universal Windows Platform Composition Samples, these samples are very similar but instead built on the APIs in the WinAppSDK (to learn more about the WinAppSDK, visit [here](https://docs.microsoft.com/windows/apps/windows-app-sdk/)).
+
diff --git a/Samples/Composition/SampleGallery/CONTRIBUTING.md b/Samples/Composition/SampleGallery/CONTRIBUTING.md
new file mode 100644
index 000000000..4a6f51569
--- /dev/null
+++ b/Samples/Composition/SampleGallery/CONTRIBUTING.md
@@ -0,0 +1,76 @@
+# Contributing
+
+The Windows Composition Samples repo is built on open source principles. We welcome and encourage community contributions to help improve the codebase, samples, and overall quality of this project. In order to contribute, please follow the guidelines below. Thank you for your interest in the Windows.UI.Composition Samples project!
+
+## Prerequisite - CLA
+
+Microsoft asks that all contributors sign a contributor license agreement (CLA).
+CLAs are generally common and accepted in most open source software projects.
+We all want Microsoft's open source projects to be as widely used and
+distributed as possible. We also want its users to be confident about the
+origins and continuing existence of the code. The CLA helps us achieve that
+goal by ensuring that we have the agreement of our contributors to use their
+work, whether it be code, or documentation.
+
+The CLA permits Microsoft to distribute your code and submissions without
+restriction. It doesn't require you to assign to us any copyright you have,
+the ownership of the copyright remains with you. You cannot withdraw
+permission for use of the contribution at a later date.
+
+We are generally seeking originally authored code, submissions and documentation
+as contributions. Should you wish to submit materials that are not your original
+work, you may submit them separately to the Project in accordance with the terms
+of the CLA.
+
+Our Azure Pull Request Bot will automatically check for a signed CLA when you
+submit a pull request. If there isn't a CLA on file, it will walk you through an all electronic process. **Note**: your employer may also have to complete an on-line form.
+
+## Source Directory Structure
+
+Since Windows.UI.Composition is constantly being updated, this project’s directory structure facilitates access to samples that will run on a variety of SDK versions. Each directory is numbered for the SDK version of the samples it contains. If you are unsure which SDK version you are using, you can create a new blank C# project and check the SDK version in its manifest.
+
+## Contribute - Pull Requests
+
+Create a pull request in order to submit new samples or fixes. All pull requests should follow the general guidelines below in addition to the guidelines specific to the type of pull request.
+
+### Pull Request Work Flow
+
+#### Creating a Branch
+
+In order to begin making changes for a pull request, first start by creating a new working branch. This can be done either in [Visual Studio](https://docs.microsoft.com/en-us/vsts/git/tutorial/branches?tabs=visual-studio), [via commandline](https://git-scm.com/book/en/v2/Git-Branching-Basic-Branching-and-Merging), or in other tools like the [GitHub Desktop app](https://help.github.com/desktop/guides/contributing-to-projects/creating-a-branch-for-your-work/).
+
+Please limit your branch changes to a single feature, sample, or bug fix for easier debugging, verification, and code review. This means for multiple samples or fixes you’ll have to create more than one branch with a correlating number of pull requests.
+
+#### Adding Work
+
+Using Visual Studio or your favorite editor, add your new content or edit existing files. You can commit multiple times while you are doing your work, or you can wait and commit only once when you're done.
+
+#### New Samples
+
+If making a new sample, you’ll want to create a new folder in the appropriate [Samples SDK folder](https://github.com/Microsoft/WindowsCompositionSamples/tree/master/SampleGallery/Samples) with a descriptive name. Copy the [sample template files](https://github.com/Microsoft/WindowsCompositionSamples/tree/master/SampleGallery/Samples/SampleTemplate) into your new folder and rename. You’ll also need to change the class names in both files, and add a good StaticSampleName and SampleDescription in the .cs file. The sample name should be short and match the intention of the sample; it will be the name displayed in the application. The description should be no more than a sentence and needs to concisely describe the purpose of the sample. It may also mention key APIs demonstrated.
+
+References to the new files will need to be added to the [sample definition](https://github.com/Microsoft/WindowsCompositionSamples/blob/master/SampleGallery/Shared/SampleDefinition.cs) page in order for them to show up in the application. Please place the reference under the appropriate SDK version block check and fill in the necessary information.
+
+You’ll notice the sample definition takes an imageUrl to use as the sample icon in the application, which you should place in the [Assets/SampleThumbnails](https://github.com/Microsoft/WindowsCompositionSamples/tree/master/SampleGallery/Assets/SampleThumbnails) folder.
+
+#### Verifying Changes
+
+To validate your changes, make sure you run all samples you have touched on x64, x86, and ARM. Please ensure that the project deploys to a mobile device or emulator as well as your desktop machine before submitting.
+
+#### Submitting Pull Requests
+
+After all changes have been committed and pushed to your branch, [create a pull request](https://github.com/Microsoft/WindowsCompositionSamples/compare). Please add a title and include a comment describing what changes have been made in detail. Double check that the Base branch is 'master' and your branch is the compared head.
+
+If creating a pull request to fix an existing open GitHub issue, please make sure to cross-reference the issue in the pull request and vice versa by using [supported GitHub issue and pull request autolinking](https://help.github.com/articles/autolinked-references-and-urls/). If no issue exists, please first [create a GitHub Issue](https://github.com/Microsoft/WindowsCompositionSamples/issues/new) then add the cross-referencing.
+
+Upon submitting the pull request, one of the site administrators will process it, review it, and provide feedback if necessary. Once all feedback is resolved, the pull request will be approved and integrated into the gallery.
+
+## UserVoice, GitHub Issues, & StackOverflow
+
+Alternative outlets for community participation are available through UserVoice, Github Issues, and StackOverflow.
+
+The [UWP UserVoice site](https://wpdev.uservoice.com/forums/110705-universal-windows-platform/category/58517-xaml-controls-composition) can be used to vote on and create suggestions for improvements to the Windows developer platform. Suggestions are reviewed by the Windows platform developer team and your feedback is used for planning and understanding how developers use the platform.
+
+This repo’s [GitHub Issues](https://github.com/Microsoft/WindowsCompositionSamples/issues) section can be used for asking questions about usage and bugs, but may also be used to respectfully interact with other community members to collaboratively answer questions and discover the innovative ways others are leveraging Windows APIs.
+
+Finally, StackOverflow has an active community of Windows UI developers where you can ask questions. Tag with ['uwp'](https://stackoverflow.com/questions/tagged/uwp) (or your appropriate application architecture), and tags indicating your framework. Some known active tags for Composition include ['windows-composition-api'](https://stackoverflow.com/questions/tagged/windows-composition-api?mixed=1) and ['xaml-composition'](https://stackoverflow.com/questions/tagged/xaml-composition?mixed=1).
diff --git a/Samples/Composition/SampleGallery/LICENSE.txt b/Samples/Composition/SampleGallery/LICENSE.txt
new file mode 100644
index 000000000..e697a2597
--- /dev/null
+++ b/Samples/Composition/SampleGallery/LICENSE.txt
@@ -0,0 +1,24 @@
+ The MIT License (MIT)
+
+
+Copyright (c) Microsoft Corporation
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/Samples/Composition/SampleGallery/PrivacyPolicy.md b/Samples/Composition/SampleGallery/PrivacyPolicy.md
new file mode 100644
index 000000000..8c085a2ad
--- /dev/null
+++ b/Samples/Composition/SampleGallery/PrivacyPolicy.md
@@ -0,0 +1 @@
+Windows UI Sample Gallery Privacy Policy
===========
Personal Data We Collect
-------------
None.
How We Use Your Personal Data
-------------
We do not collect or transmit any personal data. We do not store any personal data.
Reasons We Share Your Personal Data
-------------
We do not collect personal data and therefore do not share any of your personal data.
Control You Have Over Your Personal Data
-------------
Because we do not collect any personal data we do not offer any control over the use and sharing of this information, nor do we offer access to this data.
\ No newline at end of file
diff --git a/Samples/Composition/SampleGallery/README.md b/Samples/Composition/SampleGallery/README.md
new file mode 100644
index 000000000..d6fd1f82c
--- /dev/null
+++ b/Samples/Composition/SampleGallery/README.md
@@ -0,0 +1,76 @@
+---
+name: "Composition Sample Gallery"
+page_type: sample
+languages:
+- csharp
+- cpp
+products:
+- windows
+- windows-app-sdk
+urlFragment: rendering
+description: "Sample Gallery that showcases different use cases for the rendering APIs within Microsoft.UI.Composition."
+extendedZipContent:
+- path: LICENSE
+ target: LICENSE
+---
+
+# Composition Samples
+
+
+
+Welcome to the Composition Samples! For those of you familiar with the Universal Windows Platform Composition Samples, these samples are very similar but instead built on the APIs in the WinAppSDK (to learn more about the WinAppSDK, visit [here](https://docs.microsoft.com/windows/apps/windows-app-sdk/)). This is the place for the latest code samples, demos, and developer feedback around building beautiful and engaging WinUI3 apps. This repo focuses on the platform building blocks that make up the [Fluent Design System](https://fluent.microsoft.com/), with emphasis on creating UI using APIs in the [Microsoft.UI.Composition](https://docs.microsoft.com/windows/winui/api/microsoft.ui.composition) and [Microsoft.UI.Input](https://docs.microsoft.com/windows/winui/api/microsoft.ui.input) namespaces.
+
+Inside this repo, you’ll find the following additional info:
+
+* [Getting started building and deploying readme](STARTUP.md)
+* [Info on Questions and Contributing](CONTRIBUTING.md)
+
+If you are a developer getting familiar with the WinUI 3.0 platform, want to build beautiful and innovative UI experiences, and don't mind a few bugs here and there, then this is the place for you!
+
+We also want to see what inspiring UX you're building, so feel free to reach out on Twitter [@WindowsUI](https://twitter.com/windowsui).
+
+## Project Structure
+
+The following outlines the key folders for the project.
+
+### Demos
+
+The Demos folder contains standalone code demos that are focused on combining many concepts and feature sets into interesting user experiences.
+
+### Sample Gallery
+
+The Sample Gallery is an application that contains many samples, each demonstrating a different concept or API. The WinAppSDK samples automatically work downlevel to Windows 10 version 1809 (build 17763) which means as long as your Windows OS version is 1809 or higher, you'll automatically get all the latest features.
+
+### Samples Common
+
+These are early reference implementations, prototypes, and utilities the team has built over the course of developing our demos and code examples. This is a set of common code patterns that are shared across code samples and demos.
+
+### ExpressionBuilder
+
+A set of C# classes enabling you to build ExpressionAnimations in a more type-safe environment.
+
+### Samples Native
+
+A native library used to access some lower-level functionality that has no WinRT projections.
+
+## Contributing
+
+We encourage and welcome community involvement and contribution in this project. You'll find some details and guidelines for contribution in the [contributing readme](CONTRIBUTING.md).
+
+This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
+
+## Related Projects
+
+This project is focused on experimenting with Microsoft.UI.Composition and Microsoft.UI.Input APIs to create beautiful, unique, and engaging user experiences. If instead you’re looking to get started with higher-level UI concepts with heavier focus on XAML-based controls, check out related projects:
+
+ * [Xaml Controls Gallery](https://github.com/microsoft/Xaml-Controls-Gallery/tree/winui3) for WinUI3 controls-based UI
+ * [Windows UI Library (WinUI)](https://docs.microsoft.com/windows/apps/winui/) NuGet packages for XAML controls
+ * [Windows App SDK](https://docs.microsoft.com/windows/apps/windows-app-sdk/) Documentation for the new WinAppSDK
+
+## Privacy
+
+These samples do not collect any telemetry. A detailed privacy agreement can be found [here](https://go.microsoft.com/fwlink/?LinkId=521839) or in the 'Settings' section of the app.
+
+## Images
+
+ The images used in this application are sourced from a variety of Microsoft employees, but we'd like to specially thank Conroy for his contribution. [See more of his content here.](https://www.instagram.com/conroy.williamson/)
\ No newline at end of file
diff --git a/Samples/Composition/SampleGallery/STARTUP.md b/Samples/Composition/SampleGallery/STARTUP.md
new file mode 100644
index 000000000..03c59a76a
--- /dev/null
+++ b/Samples/Composition/SampleGallery/STARTUP.md
@@ -0,0 +1,19 @@
+# Getting Started
+
+Here you'll find some helpful guidance on how to locally build and run this project.
+
+## Prerequisites
+
+For local development, please visit this [link](https://docs.microsoft.com/windows/apps/windows-app-sdk/set-up-your-development-environment?tabs=vs%2Cstable) to set up your development environment before building this project.
+
+## Cloning and Building
+
+Once you have Visual Studio and the appropriate SDK(s) installed, clone the Windows Composition Samples repo locally. Cloning instructions can be found [here](https://help.github.com/articles/cloning-a-repository/).
+
+Open the SampleGallery solution file (.sln extension) in Visual Studio to view and manage the project.
+
+Open up the Solution Explorer (Under the "View" menu item in the top left), right click the SampleGalleryPkg and click "Set as Startup Project". You will also need to change the solution platform to x64 instead of Arm64.
+
+You'll want to restore dependencies or install yourself through NuGet in order to avoid dependency errors. To manage the NuGet dependencies in Visual Studio, right click the Sample Gallery project and select 'Manage NuGet Packages', then search for and install necessary dependencies.
+
+Clean the solution, then build and deploy it to run the application.
\ No newline at end of file
diff --git a/Samples/Composition/SampleGallery/cs-winui/.gitattributes b/Samples/Composition/SampleGallery/cs-winui/.gitattributes
new file mode 100644
index 000000000..bdb0cabc8
--- /dev/null
+++ b/Samples/Composition/SampleGallery/cs-winui/.gitattributes
@@ -0,0 +1,17 @@
+# Auto detect text files and perform LF normalization
+* text=auto
+
+# Custom for Visual Studio
+*.cs diff=csharp
+
+# Standard to msysgit
+*.doc diff=astextplain
+*.DOC diff=astextplain
+*.docx diff=astextplain
+*.DOCX diff=astextplain
+*.dot diff=astextplain
+*.DOT diff=astextplain
+*.pdf diff=astextplain
+*.PDF diff=astextplain
+*.rtf diff=astextplain
+*.RTF diff=astextplain
diff --git a/Samples/Composition/SampleGallery/cs-winui/.github/issue_template.md b/Samples/Composition/SampleGallery/cs-winui/.github/issue_template.md
new file mode 100644
index 000000000..13d391db9
--- /dev/null
+++ b/Samples/Composition/SampleGallery/cs-winui/.github/issue_template.md
@@ -0,0 +1,32 @@
+
+
+## Issue Type
+
+[ ] Bug Report
+[ ] Feature Request
+[ ] Sample request
+[ ] Documentation issue or request
+[ ] Other – Please describe:
+
+## UserVoice link
+
+
+## Current Behavior
+
+
+
+## Expected Behavior
+
+
+
+## Steps to Reproduce (for bugs)
+
+1.
+2.
+3.
+
+## Your Environment
+
+* SDK #:
+* Operating System build # :
+* Visual Studio Version # :
diff --git a/Samples/Composition/SampleGallery/cs-winui/.github/pull_request_template.md b/Samples/Composition/SampleGallery/cs-winui/.github/pull_request_template.md
new file mode 100644
index 000000000..773b8cbab
--- /dev/null
+++ b/Samples/Composition/SampleGallery/cs-winui/.github/pull_request_template.md
@@ -0,0 +1,15 @@
+
+
+## Pull Request Type
+[ ] Bugfix
+[ ] New Sample
+[ ] Other - Please describe:
+
+## Issue
+ #
+
+## Proposed Changes
+-
+-
+
+## Screenshot/GIF (if applicable):
diff --git a/Samples/Composition/SampleGallery/cs-winui/.gitignore b/Samples/Composition/SampleGallery/cs-winui/.gitignore
new file mode 100644
index 000000000..4be969893
--- /dev/null
+++ b/Samples/Composition/SampleGallery/cs-winui/.gitignore
@@ -0,0 +1,232 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+
+old/
+
+# User-specific files
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+build/
+bld/
+[Bb]in/
+[Oo]bj/
+*.binlog
+
+# Visual Studio 2015 cache/options directory
+.vs/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUNIT
+*.VisualState.xml
+TestResult.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# DNX
+project.lock.json
+artifacts/
+
+*_i.c
+*_p.c
+*_i.h
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+*.VC.opendb
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# JustCode is a .NET coding add-in
+.JustCode
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+## TODO: Comment the next line if you want to checkin your
+## web deploy settings but do note that will include unencrypted
+## passwords
+#*.pubxml
+
+*.publishproj
+
+# NuGet Packages
+*.nupkg
+# The packages folder can be ignored because of Package Restore
+**/packages/*
+# except build/, which is used as an MSBuild target.
+!**/packages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/packages/repositories.config
+
+# Windows Azure Build Output
+csx/
+*.build.csdef
+
+# Windows Store app package directory
+AppPackages/
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!*.[Cc]ache/
+
+# Others
+ClientBin/
+[Ss]tyle[Cc]op.*
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.pfx
+*.publishsettings
+node_modules/
+orleans.codegen.cs
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+
+# SQL Server files
+*.mdf
+*.ldf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# LightSwitch generated files
+GeneratedArtifacts/
+_Pvt_Extensions/
+ModelManifest.xml
+
+# Store-related files
+SampleGallery/Package.StoreAssociation.xml
+SampleGallery/_pkginfo.txt
+BundleArtifacts/
+AI Files/
+
+# Other files to ignore
+*.zip
+*.bundle
+*.appx
+*.appxbundle
+*.dll
+*.exe
+
diff --git a/Samples/Composition/SampleGallery/cs-winui/CodeAnalysis.ruleset b/Samples/Composition/SampleGallery/cs-winui/CodeAnalysis.ruleset
new file mode 100644
index 000000000..01f45cf69
--- /dev/null
+++ b/Samples/Composition/SampleGallery/cs-winui/CodeAnalysis.ruleset
@@ -0,0 +1,119 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Samples/Composition/SampleGallery/cs-winui/Directory.Build.props b/Samples/Composition/SampleGallery/cs-winui/Directory.Build.props
new file mode 100644
index 000000000..aff5b50b0
--- /dev/null
+++ b/Samples/Composition/SampleGallery/cs-winui/Directory.Build.props
@@ -0,0 +1,7 @@
+
+
+ $(MSBuildThisFileDirectory)CodeAnalysis.ruleset
+
+
+
+
diff --git a/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/Docs/ExpressionBuilder_Documentation.docx b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/Docs/ExpressionBuilder_Documentation.docx
new file mode 100644
index 000000000..a4fd7fc9e
Binary files /dev/null and b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/Docs/ExpressionBuilder_Documentation.docx differ
diff --git a/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder.sln b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder.sln
new file mode 100644
index 000000000..f48b2a0f6
--- /dev/null
+++ b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder.sln
@@ -0,0 +1,40 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.25420.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExpressionBuilder", "ExpressionBuilder\ExpressionBuilder.csproj", "{97F79CB4-FB7B-4DC3-8A08-28FA5694A73C}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|ARM = Debug|ARM
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|Any CPU = Release|Any CPU
+ Release|ARM = Release|ARM
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {97F79CB4-FB7B-4DC3-8A08-28FA5694A73C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {97F79CB4-FB7B-4DC3-8A08-28FA5694A73C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {97F79CB4-FB7B-4DC3-8A08-28FA5694A73C}.Debug|ARM.ActiveCfg = Debug|ARM
+ {97F79CB4-FB7B-4DC3-8A08-28FA5694A73C}.Debug|ARM.Build.0 = Debug|ARM
+ {97F79CB4-FB7B-4DC3-8A08-28FA5694A73C}.Debug|x64.ActiveCfg = Debug|x64
+ {97F79CB4-FB7B-4DC3-8A08-28FA5694A73C}.Debug|x64.Build.0 = Debug|x64
+ {97F79CB4-FB7B-4DC3-8A08-28FA5694A73C}.Debug|x86.ActiveCfg = Debug|x86
+ {97F79CB4-FB7B-4DC3-8A08-28FA5694A73C}.Debug|x86.Build.0 = Debug|x86
+ {97F79CB4-FB7B-4DC3-8A08-28FA5694A73C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {97F79CB4-FB7B-4DC3-8A08-28FA5694A73C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {97F79CB4-FB7B-4DC3-8A08-28FA5694A73C}.Release|ARM.ActiveCfg = Release|ARM
+ {97F79CB4-FB7B-4DC3-8A08-28FA5694A73C}.Release|ARM.Build.0 = Release|ARM
+ {97F79CB4-FB7B-4DC3-8A08-28FA5694A73C}.Release|x64.ActiveCfg = Release|x64
+ {97F79CB4-FB7B-4DC3-8A08-28FA5694A73C}.Release|x64.Build.0 = Release|x64
+ {97F79CB4-FB7B-4DC3-8A08-28FA5694A73C}.Release|x86.ActiveCfg = Release|x86
+ {97F79CB4-FB7B-4DC3-8A08-28FA5694A73C}.Release|x86.Build.0 = Release|x86
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionBuilder.CompositionExtensions.cs b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionBuilder.CompositionExtensions.cs
new file mode 100644
index 000000000..072b7e48c
--- /dev/null
+++ b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionBuilder.CompositionExtensions.cs
@@ -0,0 +1,135 @@
+///---------------------------------------------------------------------------------------------------------------------
+///
+/// Copyright (c) Microsoft Corporation. All rights reserved.
+///
+///---------------------------------------------------------------------------------------------------------------------
+
+namespace ExpressionBuilder
+{
+ using System.Numerics;
+
+ using Microsoft.UI.Composition;
+ using Microsoft.UI.Composition.Interactions;
+
+ ///---------------------------------------------------------------------------------------------------------------------
+ ///
+ /// class CompositionExtensions
+ /// ToDo: Add description after docs written
+ ///
+ ///---------------------------------------------------------------------------------------------------------------------
+
+ public static class CompositionExtensions
+ {
+ /// Create an ExpressionNode reference to this CompositionObject.
+ public static AmbientLightReferenceNode GetReference(this AmbientLight compObj) { return new AmbientLightReferenceNode(null, compObj); }
+ public static ColorBrushReferenceNode GetReference(this CompositionColorBrush compObj) { return new ColorBrushReferenceNode(null, compObj); }
+ public static DistantLightReferenceNode GetReference(this DistantLight compObj) { return new DistantLightReferenceNode(null, compObj); }
+ public static DropShadowReferenceNode GetReference(this DropShadow compObj) { return new DropShadowReferenceNode(null, compObj); }
+ public static InsetClipReferenceNode GetReference(this InsetClip compObj) { return new InsetClipReferenceNode(null, compObj); }
+ public static InteractionTrackerReferenceNode GetReference(this InteractionTracker compObj) { return new InteractionTrackerReferenceNode(null, compObj); }
+ public static NineGridBrushReferenceNode GetReference(this CompositionNineGridBrush compObj) { return new NineGridBrushReferenceNode(null, compObj); }
+ public static PointLightReferenceNode GetReference(this PointLight compObj) { return new PointLightReferenceNode(null, compObj); }
+ public static PropertySetReferenceNode GetReference(this CompositionPropertySet compObj) { return new PropertySetReferenceNode(null, compObj); }
+ public static SpotLightReferenceNode GetReference(this SpotLight compObj) { return new SpotLightReferenceNode(null, compObj); }
+ public static SurfaceBrushReferenceNode GetReference(this CompositionSurfaceBrush compObj) { return new SurfaceBrushReferenceNode(null, compObj); }
+ public static VisualReferenceNode GetReference(this Visual compObj) { return new VisualReferenceNode(null, compObj); }
+
+ /// Create an ExpressionNode reference to this specialized PropertySet.
+ public static T GetSpecializedReference(this CompositionPropertySet ps) where T : PropertySetReferenceNode
+ {
+ if (typeof(T) == typeof(ManipulationPropertySetReferenceNode))
+ {
+ return new ManipulationPropertySetReferenceNode(null, ps) as T;
+ }
+ else if (typeof(T) == typeof(PointerPositionPropertySetReferenceNode))
+ {
+ return new PointerPositionPropertySetReferenceNode(null, ps) as T;
+ }
+ else
+ {
+ throw new System.Exception("Invalid property set specialization");
+ }
+ }
+
+ /// Connects the specified ExpressionNode with the specified property of the object.
+ /// The name of the property that the expression will target.
+ /// The root ExpressionNode that represents the ExpressionAnimation.
+ public static void StartAnimation(this CompositionObject compObject, string propertyName, ExpressionNode expressionNode)
+ {
+ compObject.StartAnimation(propertyName, CreateExpressionAnimationFromNode(compObject.Compositor, expressionNode));
+ }
+
+ /// Inserts a KeyFrame whose value is calculated using the specified ExpressionNode.
+ /// The time the key frame should occur at, expressed as a percentage of the animation Duration. Allowed value is from 0.0 to 1.0.
+ /// The root ExpressionNode that represents the ExpressionAnimation.
+ /// The easing function to use when interpolating between frames.
+ public static void InsertExpressionKeyFrame(this KeyFrameAnimation keyframeAnimation, float normalizedProgressKey, ExpressionNode expressionNode, CompositionEasingFunction easing = null)
+ {
+ keyframeAnimation.InsertExpressionKeyFrame(normalizedProgressKey, expressionNode.ToExpressionString(), easing);
+
+ expressionNode.SetAllParameters(keyframeAnimation);
+ }
+
+ /// Use the value of specified ExpressionNode to determine if this inertia modifier should be chosen.
+ /// The root ExpressionNode that represents the ExpressionAnimation.
+ public static void SetCondition(this InteractionTrackerInertiaRestingValue modifier, ExpressionNode expressionNode)
+ {
+ modifier.Condition = CreateExpressionAnimationFromNode(modifier.Compositor, expressionNode);
+ }
+
+ /// Use the value of specified ExpressionNode as the resting value for this inertia modifier.
+ /// The root ExpressionNode that represents the ExpressionAnimation.
+ public static void SetRestingValue(this InteractionTrackerInertiaRestingValue modifier, ExpressionNode expressionNode)
+ {
+ modifier.RestingValue = CreateExpressionAnimationFromNode(modifier.Compositor, expressionNode);
+ }
+
+ /// Use the value of specified ExpressionNode to determine if this inertia modifier should be chosen.
+ /// The root ExpressionNode that represents the ExpressionAnimation.
+ public static void SetCondition(this InteractionTrackerInertiaMotion modifier, ExpressionNode expressionNode)
+ {
+ modifier.Condition = CreateExpressionAnimationFromNode(modifier.Compositor, expressionNode);
+ }
+
+ /// Use the value of specified ExpressionNode to dictate the motion for this inertia modifier.
+ /// The root ExpressionNode that represents the ExpressionAnimation.
+ public static void SetMotion(this InteractionTrackerInertiaMotion modifier, ExpressionNode expressionNode)
+ {
+ modifier.Motion = CreateExpressionAnimationFromNode(modifier.Compositor, expressionNode);
+ }
+
+ /// Tries to update the InteractionTracker's position by applying an animation.
+ /// The root ExpressionNode that represents the ExpressionAnimation to apply to the InteractionTracker's position.
+ public static void TryUpdatePositionWithAnimation(this InteractionTracker tracker, ExpressionNode expressionNode)
+ {
+ tracker.TryUpdatePositionWithAnimation(CreateExpressionAnimationFromNode(tracker.Compositor, expressionNode));
+ }
+
+ /// Tries to update the InteractionTracker's scale by applying an animation.
+ /// The root ExpressionNode that represents the ExpressionAnimation to apply to the InteractionTracker's scale.
+ /// The centerPoint to use when scaling.
+ public static void TryUpdateScaleWithAnimation(this InteractionTracker tracker, ExpressionNode expressionNode, Vector3 centerPoint)
+ {
+ tracker.TryUpdateScaleWithAnimation(CreateExpressionAnimationFromNode(tracker.Compositor, expressionNode), centerPoint);
+ }
+
+
+ //
+ // Helper functions
+ //
+
+ private static ExpressionAnimation CreateExpressionAnimationFromNode(Compositor compositor, ExpressionNode expressionNode)
+ {
+ // Only create a new animation if this node hasn't already generated one before, so we don't have to re-parse the expression string.
+ if (expressionNode._expressionAnimation == null)
+ {
+ expressionNode._expressionAnimation = compositor.CreateExpressionAnimation(expressionNode.ToExpressionString());
+ }
+
+ // We need to make sure all parameters are up to date, even if the animation already existed.
+ expressionNode.SetAllParameters(expressionNode._expressionAnimation);
+
+ return expressionNode._expressionAnimation;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionBuilder.ExpressionFunctions.cs b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionBuilder.ExpressionFunctions.cs
new file mode 100644
index 000000000..e2ead0997
--- /dev/null
+++ b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionBuilder.ExpressionFunctions.cs
@@ -0,0 +1,472 @@
+///---------------------------------------------------------------------------------------------------------------------
+///
+/// Copyright (c) Microsoft Corporation. All rights reserved.
+///
+///---------------------------------------------------------------------------------------------------------------------
+
+namespace ExpressionBuilder
+{
+ using System.Collections.Generic;
+
+ internal enum OperationType
+ {
+ Function,
+ Operator,
+ Constant,
+ Reference,
+ Conditional,
+ Swizzle,
+ }
+
+ ///---------------------------------------------------------------------------------------------------------------------
+ ///
+ /// class ExpressionFunctions
+ /// ToDo: Add description after docs written
+ ///
+ ///---------------------------------------------------------------------------------------------------------------------
+
+ public static class ExpressionFunctions
+ {
+ //
+ // Float-only math operations
+ //
+
+ /// Returns the angle (in radians) whose cosine is the specified number.
+ /// Value between �1 and 1, for which to calculate the arccosine (the inverse cosine).
+ public static ScalarNode ACos(ScalarNode val) { return Function(ExpressionNodeType.Acos, val); }
+
+ /// Returns the angle (in radians) whose sine is the specified number.
+ /// Value between �1 and 1, for which to calculate the arcsine (the inverse sine).
+ public static ScalarNode ASin(ScalarNode val) { return Function(ExpressionNodeType.Asin, val); }
+
+ /// Returns the angle (in radians) whose tangent is the specified number.
+ /// Value for which to calculate the arctan (the inverse tan).
+ public static ScalarNode ATan(ScalarNode val) { return Function(ExpressionNodeType.Atan, val); }
+
+ /// Returns the smallest integral value that is greater than or equal to the specified value.
+ /// The floating point number to round.
+ public static ScalarNode Ceil(ScalarNode val) { return Function(ExpressionNodeType.Ceil, val); }
+
+ /// Returns the cosine of the specified angle (in radians)
+ /// An angle, measured in radians.
+ public static ScalarNode Cos(ScalarNode val) { return Function(ExpressionNodeType.Cos, val); }
+
+ /// Returns the largest integer less than or equal to the specified value.
+ /// The floating point number to round.
+ public static ScalarNode Floor(ScalarNode val) { return Function(ExpressionNodeType.Floor, val); }
+
+ /// Returns the natural (base e) logarithm of a specified number.
+ /// The number whose natural logarithm is to be returned.
+ public static ScalarNode Ln(ScalarNode val) { return Function(ExpressionNodeType.Ln, val); }
+
+ /// Returns the base 10 logarithm of a specified number.
+ /// The number whose base 10 logarithm is to be calculated.
+ public static ScalarNode Log10(ScalarNode val) { return Function(ExpressionNodeType.Log10, val); }
+
+ /// Returns a specified number raised to the specified power.
+ /// A floating-point number to be raised to a power.
+ /// A floating-point number that specifies a power.
+ public static ScalarNode Pow(ScalarNode val1, ScalarNode val2) { return Function(ExpressionNodeType.Pow, val1, val2); }
+
+ /// Rounds a floating point value to the nearest integral value.
+ /// The floating point number to round.
+ public static ScalarNode Round(ScalarNode val) { return Function(ExpressionNodeType.Round, val); }
+
+ /// Returns the sine of the specified angle (in radians)
+ /// An angle, measured in radians.
+ public static ScalarNode Sin(ScalarNode val) { return Function(ExpressionNodeType.Sin, val); }
+
+ /// Returns the specified number multiplied by itself.
+ /// The floating point number to square.
+ public static ScalarNode Square(ScalarNode val) { return Function(ExpressionNodeType.Square, val); }
+
+ /// Returns the square root of a specified number.
+ /// The number whose square root is to be returned.
+ public static ScalarNode Sqrt(ScalarNode val) { return Function(ExpressionNodeType.Sqrt, val); }
+
+ /// Returns the tangent of the specified angle (in radians)
+ /// An angle, measured in radians.
+ public static ScalarNode Tan(ScalarNode val) { return Function(ExpressionNodeType.Tan, val); }
+
+ /// Converts an angle in radians to degrees as: val*180/PI.
+ /// A floating point value that represents an angle in radians.
+ public static ScalarNode ToDegrees(ScalarNode val) { return Function(ExpressionNodeType.ToDegrees, val); }
+
+ /// Converts an angle in degrees to radians as: val*PI/180.
+ /// A floating point value that represents an angle in degrees.
+ public static ScalarNode ToRadians(ScalarNode val) { return Function(ExpressionNodeType.ToRadians, val); }
+
+
+ //
+ // System.Numerics functions
+ //
+
+ /// Returns the absolute value of the specified input. For vectors, the absolute value of each subchannel is returned.
+ /// The input value.
+ public static ScalarNode Abs(ScalarNode val) { return Function(ExpressionNodeType.Absolute, val); }
+ public static Vector2Node Abs(Vector2Node val) { return Function(ExpressionNodeType.Absolute, val); }
+ public static Vector3Node Abs(Vector3Node val) { return Function(ExpressionNodeType.Absolute, val); }
+ public static Vector4Node Abs(Vector4Node val) { return Function(ExpressionNodeType.Absolute, val); }
+
+ /// Restricts a value to be within a specified range. For vectors, each subchannel is clamped.
+ /// The value to clamp.
+ /// The specified minimum range.
+ /// The specified maximum range.
+ public static ScalarNode Clamp(ScalarNode val, ScalarNode min, ScalarNode max) { return Function(ExpressionNodeType.Clamp, val, min, max); }
+ public static Vector2Node Clamp(Vector2Node val, Vector2Node min, Vector2Node max) { return Function(ExpressionNodeType.Clamp, val, min, max); }
+ public static Vector3Node Clamp(Vector3Node val, Vector3Node min, Vector3Node max) { return Function(ExpressionNodeType.Clamp, val, min, max); }
+ public static Vector4Node Clamp(Vector4Node val, Vector4Node min, Vector4Node max) { return Function(ExpressionNodeType.Clamp, val, min, max); }
+
+ /// Linearly interpolates between two colors in the default color space.
+ /// Color source value 1.
+ /// Color source value 2.
+ /// A value between 0 and 1.0 indicating the weight of val2.
+ public static ColorNode ColorLerp(ColorNode val1, ColorNode val2, ScalarNode progress) { return Function(ExpressionNodeType.ColorLerp, val1, val2, progress); }
+
+ /// Linearly interpolates between two colors in the HSL color space.
+ /// Color source value 1.
+ /// Color source value 2.
+ /// A value between 0 and 1.0 indicating the weight of val2.
+ public static ColorNode ColorLerpHsl(ColorNode val1, ColorNode val2, ScalarNode progress) { return Function(ExpressionNodeType.ColorLerpHsl, val1, val2, progress); }
+
+ /// Linearly interpolates between two colors in the RBG color space.
+ /// Color source value 1.
+ /// Color source value 2.
+ /// A value between 0 and 1.0 indicating the weight of val2.
+ public static ColorNode ColorLerpRgb(ColorNode val1, ColorNode val2, ScalarNode progress) { return Function(ExpressionNodeType.ColorLerpRgb, val1, val2, progress); }
+
+ /// Concatenates two Quaternions; the result represents the first rotation followed by the second rotation.
+ /// The first quaternion rotation in the series.
+ /// The second quaternion rotation in the series.
+ public static QuaternionNode Concatenate(QuaternionNode val1, QuaternionNode val2) { return Function(ExpressionNodeType.Concatenate, val1, val2); }
+
+ /// Returns the distance between two vectors as: sqrt((x1-x2)^2 + (y1-y2)^2 + ...).
+ /// Source value 1.
+ /// Source value 2.
+ public static ScalarNode Distance(ScalarNode val1, ScalarNode val2) { return Function(ExpressionNodeType.Distance, val1, val2); }
+ public static ScalarNode Distance(Vector2Node val1, Vector2Node val2) { return Function(ExpressionNodeType.Distance, val1, val2); }
+ public static ScalarNode Distance(Vector3Node val1, Vector3Node val2) { return Function(ExpressionNodeType.Distance, val1, val2); }
+ public static ScalarNode Distance(Vector4Node val1, Vector4Node val2) { return Function(ExpressionNodeType.Distance, val1, val2); }
+
+ /// Returns the squared distance between two vectors as: ((x1-x2)^2 + (y1-y2)^2 + ...).
+ /// Source value 1.
+ /// Source value 2.
+ public static ScalarNode DistanceSquared(ScalarNode val1, ScalarNode val2) { return Function(ExpressionNodeType.DistanceSquared, val1, val2); }
+ public static ScalarNode DistanceSquared(Vector2Node val1, Vector2Node val2) { return Function(ExpressionNodeType.DistanceSquared, val1, val2); }
+ public static ScalarNode DistanceSquared(Vector3Node val1, Vector3Node val2) { return Function(ExpressionNodeType.DistanceSquared, val1, val2); }
+ public static ScalarNode DistanceSquared(Vector4Node val1, Vector4Node val2) { return Function(ExpressionNodeType.DistanceSquared, val1, val2); }
+
+ /// Returns the inverse of the specified matrix.
+ /// The matrix to invert.
+ public static Matrix3x2Node Inverse(Matrix3x2Node val) { return Function(ExpressionNodeType.Inverse, val); }
+ public static Matrix4x4Node Inverse(Matrix4x4Node val) { return Function(ExpressionNodeType.Inverse, val); }
+
+ /// Returns the length of the vector as: sqrt(x^2 + y^2 + ...)
+ /// Vector value to return the length of.
+ public static ScalarNode Length(ScalarNode val) { return Function(ExpressionNodeType.Length, val); }
+ public static ScalarNode Length(Vector2Node val) { return Function(ExpressionNodeType.Length, val); }
+ public static ScalarNode Length(Vector3Node val) { return Function(ExpressionNodeType.Length, val); }
+ public static ScalarNode Length(Vector4Node val) { return Function(ExpressionNodeType.Length, val); }
+ public static ScalarNode Length(QuaternionNode val) { return Function(ExpressionNodeType.Length, val); }
+
+ /// Returns the squared length of the vector as: (x^2 + y^2 + ...)
+ /// Vector value to return the length squared of.
+ public static ScalarNode LengthSquared(ScalarNode val) { return Function(ExpressionNodeType.LengthSquared, val); }
+ public static ScalarNode LengthSquared(Vector2Node val) { return Function(ExpressionNodeType.LengthSquared, val); }
+ public static ScalarNode LengthSquared(Vector3Node val) { return Function(ExpressionNodeType.LengthSquared, val); }
+ public static ScalarNode LengthSquared(Vector4Node val) { return Function(ExpressionNodeType.LengthSquared, val); }
+ public static ScalarNode LengthSquared(QuaternionNode val) { return Function(ExpressionNodeType.LengthSquared, val); }
+
+ /// Linearly interpolates between two vectors as: Output.x = x1 + (x2-x1)*progress
+ /// Source value 1.
+ /// Source value 2.
+ /// A value between 0 and 1.0 indicating the weight of val2.
+ public static ScalarNode Lerp(ScalarNode val1, ScalarNode val2, ScalarNode progress) { return Function(ExpressionNodeType.Lerp, val1, val2, progress); }
+ public static Vector2Node Lerp(Vector2Node val1, Vector2Node val2, ScalarNode progress) { return Function(ExpressionNodeType.Lerp, val1, val2, progress); }
+ public static Vector3Node Lerp(Vector3Node val1, Vector3Node val2, ScalarNode progress) { return Function(ExpressionNodeType.Lerp, val1, val2, progress); }
+ public static Vector4Node Lerp(Vector4Node val1, Vector4Node val2, ScalarNode progress) { return Function(ExpressionNodeType.Lerp, val1, val2, progress); }
+
+ /// Returns the maximum of two values. For vectors, the max of each subchannel is returned.
+ /// Source value 1.
+ /// Source value 2.
+ public static ScalarNode Max(ScalarNode val1, ScalarNode val2) { return Function(ExpressionNodeType.Max, val1, val2); }
+ public static Vector2Node Max(Vector2Node val1, Vector2Node val2) { return Function(ExpressionNodeType.Max, val1, val2); }
+ public static Vector3Node Max(Vector3Node val1, Vector3Node val2) { return Function(ExpressionNodeType.Max, val1, val2); }
+ public static Vector4Node Max(Vector4Node val1, Vector4Node val2) { return Function(ExpressionNodeType.Max, val1, val2); }
+
+ /// Returns the minimum of two values. For vectors, the min of each subchannel is returned.
+ /// Source value 1.
+ /// Source value 2.
+ public static ScalarNode Min(ScalarNode val1, ScalarNode val2) { return Function(ExpressionNodeType.Min, val1, val2); }
+ public static Vector2Node Min(Vector2Node val1, Vector2Node val2) { return Function(ExpressionNodeType.Min, val1, val2); }
+ public static Vector3Node Min(Vector3Node val1, Vector3Node val2) { return Function(ExpressionNodeType.Min, val1, val2); }
+ public static Vector4Node Min(Vector4Node val1, Vector4Node val2) { return Function(ExpressionNodeType.Min, val1, val2); }
+
+ /// Returns the remainder resulting from dividing val1/val2. For vectors, the remainder for each subchannel is returned.
+ /// The numerator value.
+ /// The denominator value.
+ public static ScalarNode Mod(ScalarNode val1, ScalarNode val2) { return Function(ExpressionNodeType.Modulus, val1, val2); }
+ public static Vector2Node Mod(Vector2Node val1, Vector2Node val2) { return Function(ExpressionNodeType.Modulus, val1, val2); }
+ public static Vector3Node Mod(Vector3Node val1, Vector3Node val2) { return Function(ExpressionNodeType.Modulus, val1, val2); }
+ public static Vector4Node Mod(Vector4Node val1, Vector4Node val2) { return Function(ExpressionNodeType.Modulus, val1, val2); }
+
+ /// Returns the normalized version of a vector.
+ /// Vector value to normalize.
+ public static Vector2Node Normalize(Vector2Node val) { return Function(ExpressionNodeType.Normalize, val); }
+ public static Vector3Node Normalize(Vector3Node val) { return Function(ExpressionNodeType.Normalize, val); }
+ public static Vector4Node Normalize(Vector4Node val) { return Function(ExpressionNodeType.Normalize, val); }
+ public static QuaternionNode Normalize(QuaternionNode val) { return Function(ExpressionNodeType.Normalize, val); }
+
+ /// Multiply each subchannel of the specified vector/matrix by a float value.
+ /// Source value to scale.
+ /// Scaling value.
+ public static ScalarNode Scale(ScalarNode val1, ScalarNode val2) { return Function(ExpressionNodeType.Scale, val1, val2); }
+ public static Vector2Node Scale(Vector2Node val1, ScalarNode val2) { return Function(ExpressionNodeType.Scale, val1, val2); }
+ public static Vector3Node Scale(Vector3Node val1, ScalarNode val2) { return Function(ExpressionNodeType.Scale, val1, val2); }
+ public static Vector4Node Scale(Vector4Node val1, ScalarNode val2) { return Function(ExpressionNodeType.Scale, val1, val2); }
+ public static Matrix3x2Node Scale(Matrix3x2Node val1, ScalarNode val2) { return Function(ExpressionNodeType.Scale, val1, val2); }
+ public static Matrix4x4Node Scale(Matrix4x4Node val1, ScalarNode val2) { return Function(ExpressionNodeType.Scale, val1, val2); }
+
+ /// Spherically interpolates between two quaternions.
+ /// Quaternion source value 1.
+ /// Quaternion source value 2.
+ /// A value between 0 and 1.0 indicating the weight of val2.
+ public static QuaternionNode Slerp(QuaternionNode val1, QuaternionNode val2, ScalarNode progress) { return Function(ExpressionNodeType.Slerp, val1, val2, progress); }
+
+ /// Transforms a vector by the specified matrix.
+ /// Vector to be transformed.
+ /// The transformation matrix.
+ public static Vector2Node Transform(Vector2Node val1, Matrix3x2Node val2) { return Function(ExpressionNodeType.Transform, val1, val2); }
+ public static Vector4Node Transform(Vector4Node val1, Matrix4x4Node val2) { return Function(ExpressionNodeType.Transform, val1, val2); }
+
+
+ //
+ // System.Numerics Type Constructors
+ //
+
+ /// Creates a vector whose subchannels have the specified values.
+ public static Vector2Node Vector2(ScalarNode x, ScalarNode y) { return Function(ExpressionNodeType.Vector2, x, y); }
+ public static Vector3Node Vector3(ScalarNode x, ScalarNode y, ScalarNode z) { return Function(ExpressionNodeType.Vector3, x, y, z); }
+ public static Vector4Node Vector4(ScalarNode x, ScalarNode y, ScalarNode z, ScalarNode w) { return Function(ExpressionNodeType.Vector4, x, y, z, w); }
+
+ /// Creates a color in the HSL format.
+ /// Hue
+ /// Saturation
+ /// Luminosity
+ public static ColorNode ColorHsl(ScalarNode h, ScalarNode s, ScalarNode l) { return Function(ExpressionNodeType.ColorHsl, h, s, l); }
+
+ /// Creates a Color in the ARGB format.
+ public static ColorNode ColorRgb(ScalarNode alpha, ScalarNode red, ScalarNode green, ScalarNode blue)
+ { return Function(ExpressionNodeType.ColorRgb, alpha, red, green, blue); }
+
+ /// Creates a quaternion whose subchannels have the specified values.
+ public static QuaternionNode Quaternion(ScalarNode x, ScalarNode y, ScalarNode z, ScalarNode w) { return Function(ExpressionNodeType.Quaternion, x, y, z, w); }
+
+ /// Creates a matrix whose subchannels have the specified values.
+ public static Matrix3x2Node Matrix3x2(ScalarNode _11, ScalarNode _12, ScalarNode _21, ScalarNode _22, ScalarNode _31, ScalarNode _32)
+ { return Function(ExpressionNodeType.Matrix3x2, _11, _12, _21, _22, _31, _32); }
+
+ /// Creates a matrix whose subchannels have the specified values.
+ public static Matrix4x4Node Matrix4x4(ScalarNode _11, ScalarNode _12, ScalarNode _13, ScalarNode _14,
+ ScalarNode _21, ScalarNode _22, ScalarNode _23, ScalarNode _24,
+ ScalarNode _31, ScalarNode _32, ScalarNode _33, ScalarNode _34,
+ ScalarNode _41, ScalarNode _42, ScalarNode _43, ScalarNode _44)
+ { return Function(ExpressionNodeType.Matrix4x4, _11, _12, _13, _14, _21, _22, _23, _24, _31, _32, _33, _34, _41, _42, _43, _44); }
+
+ /// Creates a 4x4 matrix from a 3x2 matrix.
+ public static Matrix4x4Node Matrix4x4(Matrix3x2Node val)
+ { return Function(ExpressionNodeType.Matrix4x4,
+ val._11, val._12, (ScalarNode)0, (ScalarNode)0,
+ val._21, val._22, (ScalarNode)0, (ScalarNode)0,
+ (ScalarNode)0, (ScalarNode)0, (ScalarNode)1, (ScalarNode)0,
+ val._31, val._32, (ScalarNode)0, (ScalarNode)1); }
+
+ /// Creates a translation matrix from the specified vector.
+ /// Source translation vector.
+ public static Matrix3x2Node CreateTranslation(Vector2Node val) { return Function(ExpressionNodeType.Matrix3x2FromTranslation, val); }
+ public static Matrix4x4Node CreateTranslation(Vector3Node val) { return Function(ExpressionNodeType.Matrix4x4FromTranslation, val); }
+
+ /// Creates a scale matrix from the specified vector scale.
+ /// Source scaling vector.
+ public static Matrix3x2Node CreateScale(Vector2Node val) { return Function(ExpressionNodeType.Matrix3x2FromScale, val); }
+ public static Matrix4x4Node CreateScale(Vector3Node val) { return Function(ExpressionNodeType.Matrix4x4FromScale, val); }
+
+ /// Creates a skew matrix from the specified angles in radians.
+ /// X angle, in radians.
+ /// Y angle, in radians.
+ /// The centerpoint for the operation.
+ public static Matrix3x2Node CreateSkew(ScalarNode xAngle, ScalarNode yAngle, Vector2Node centerPoint)
+ { return Function(ExpressionNodeType.Matrix3x2FromSkew, xAngle, yAngle, centerPoint); }
+
+ /// Creates a rotation matrix using the given rotation in radians.
+ /// Angle, in radians.
+ public static Matrix3x2Node CreateRotation(ScalarNode angle) { return Function(ExpressionNodeType.Matrix3x2FromRotation, angle); }
+
+ /// Creates a matrix that rotates around an arbitrary vector.
+ /// Rotation axis
+ /// Angle, in radians.
+ public static Matrix4x4Node CreateMatrix4x4FromAxisAngle(Vector3Node axis, ScalarNode angle)
+ { return Function(ExpressionNodeType.Matrix4x4FromAxisAngle, axis, angle); }
+
+ /// Creates a quaternion that rotates around an arbitrary vector.
+ /// Rotation axis
+ /// Angle, in radians.
+ public static QuaternionNode CreateQuaternionFromAxisAngle(Vector3Node axis, ScalarNode angle)
+ { return Function(ExpressionNodeType.QuaternionFromAxisAngle, axis, angle); }
+
+
+ //
+ // Logical Operators
+ //
+
+ /// Performs a logical AND operation on two boolean values as: val1 && val2.
+ public static BooleanNode And(BooleanNode val1, BooleanNode val2) { return Function(ExpressionNodeType.And, val1, val2); }
+
+ /// Performs a logical OR operation on two boolean values as: val1 || val2.
+ public static BooleanNode Or (BooleanNode val1, BooleanNode val2) { return Function(ExpressionNodeType.Or, val1, val2); }
+
+ /// Performs a logical NOT operation on a specified boolean value as: !val.
+ public static BooleanNode Not(BooleanNode val) { return Function(ExpressionNodeType.Not, val); }
+
+
+ //
+ // Conditional
+ //
+
+ /// Returns one of two values, depending on the value of the boolean condition.
+ /// Boolean value used to determine whether to return the value represented by 'trueCase' or 'falseCase'.
+ /// Value to return if 'condition' evaluates to true.
+ /// Value to return if 'condition' evaluates to false.
+ public static ScalarNode Conditional(BooleanNode condition, ScalarNode trueCase, ScalarNode falseCase) { return Function(ExpressionNodeType.Conditional, condition, trueCase, falseCase); }
+ public static Vector2Node Conditional(BooleanNode condition, Vector2Node trueCase, Vector2Node falseCase) { return Function(ExpressionNodeType.Conditional, condition, trueCase, falseCase); }
+ public static Vector3Node Conditional(BooleanNode condition, Vector3Node trueCase, Vector3Node falseCase) { return Function(ExpressionNodeType.Conditional, condition, trueCase, falseCase); }
+ public static Vector4Node Conditional(BooleanNode condition, Vector4Node trueCase, Vector4Node falseCase) { return Function(ExpressionNodeType.Conditional, condition, trueCase, falseCase); }
+ public static ColorNode Conditional(BooleanNode condition, ColorNode trueCase, ColorNode falseCase) { return Function(ExpressionNodeType.Conditional, condition, trueCase, falseCase); }
+ public static QuaternionNode Conditional(BooleanNode condition, QuaternionNode trueCase, QuaternionNode falseCase) { return Function(ExpressionNodeType.Conditional, condition, trueCase, falseCase); }
+ public static Matrix3x2Node Conditional(BooleanNode condition, Matrix3x2Node trueCase, Matrix3x2Node falseCase) { return Function(ExpressionNodeType.Conditional, condition, trueCase, falseCase); }
+ public static Matrix4x4Node Conditional(BooleanNode condition, Matrix4x4Node trueCase, Matrix4x4Node falseCase) { return Function(ExpressionNodeType.Conditional, condition, trueCase, falseCase); }
+
+
+ //
+ // Helper functions
+ //
+
+ internal static T Function(ExpressionNodeType nodeType, params ExpressionNode [] expressionFunctionParams) where T : class
+ {
+ T newNode = ExpressionNode.CreateExpressionNode();
+
+ (newNode as ExpressionNode)._nodeType = nodeType;
+ foreach (var param in expressionFunctionParams)
+ {
+ (newNode as ExpressionNode)._children.Add(param);
+ }
+
+ return newNode;
+ }
+
+ internal static ExpressionNodeInfo GetNodeInfoFromType(ExpressionNodeType type)
+ {
+ return _expressionNodeInfo[type];
+ }
+
+
+ //
+ // Structs
+ //
+
+ internal struct ExpressionNodeInfo
+ {
+ public ExpressionNodeInfo(OperationType nodeOperationKind, string operationString)
+ {
+ NodeOperationKind = nodeOperationKind;
+ OperationString = operationString;
+ }
+
+ public OperationType NodeOperationKind;
+ public string OperationString;
+ }
+
+
+ //
+ // Data
+ //
+
+ private static readonly Dictionary _expressionNodeInfo = new Dictionary
+ {
+ { ExpressionNodeType.ConstantValue, new ExpressionNodeInfo(OperationType.Constant, null) },
+ { ExpressionNodeType.ConstantParameter, new ExpressionNodeInfo(OperationType.Constant, null) },
+ { ExpressionNodeType.CurrentValueProperty, new ExpressionNodeInfo(OperationType.Reference, null) },
+ { ExpressionNodeType.Reference, new ExpressionNodeInfo(OperationType.Reference, null) },
+ { ExpressionNodeType.ReferenceProperty, new ExpressionNodeInfo(OperationType.Reference, null) },
+ { ExpressionNodeType.StartingValueProperty, new ExpressionNodeInfo(OperationType.Reference, null) },
+ { ExpressionNodeType.TargetReference, new ExpressionNodeInfo(OperationType.Reference, null) },
+ { ExpressionNodeType.Conditional, new ExpressionNodeInfo(OperationType.Conditional, null) },
+ { ExpressionNodeType.Swizzle, new ExpressionNodeInfo(OperationType.Swizzle, null) },
+ { ExpressionNodeType.Add, new ExpressionNodeInfo(OperationType.Operator, "+") },
+ { ExpressionNodeType.And, new ExpressionNodeInfo(OperationType.Operator, "&&") },
+ { ExpressionNodeType.Divide, new ExpressionNodeInfo(OperationType.Operator, "/") },
+ { ExpressionNodeType.Equals, new ExpressionNodeInfo(OperationType.Operator, "==") },
+ { ExpressionNodeType.GreaterThan, new ExpressionNodeInfo(OperationType.Operator, ">") },
+ { ExpressionNodeType.GreaterThanEquals, new ExpressionNodeInfo(OperationType.Operator, ">=") },
+ { ExpressionNodeType.LessThan, new ExpressionNodeInfo(OperationType.Operator, "<") },
+ { ExpressionNodeType.LessThanEquals, new ExpressionNodeInfo(OperationType.Operator, "<=") },
+ { ExpressionNodeType.Multiply, new ExpressionNodeInfo(OperationType.Operator, "*") },
+ { ExpressionNodeType.Not, new ExpressionNodeInfo(OperationType.Operator, "!") },
+ { ExpressionNodeType.NotEquals, new ExpressionNodeInfo(OperationType.Operator, "!=") },
+ { ExpressionNodeType.Or, new ExpressionNodeInfo(OperationType.Operator, "||") },
+ { ExpressionNodeType.Subtract, new ExpressionNodeInfo(OperationType.Operator, "-") },
+ { ExpressionNodeType.Absolute, new ExpressionNodeInfo(OperationType.Function, "abs") },
+ { ExpressionNodeType.Acos, new ExpressionNodeInfo(OperationType.Function, "acos") },
+ { ExpressionNodeType.Asin, new ExpressionNodeInfo(OperationType.Function, "asin") },
+ { ExpressionNodeType.Atan, new ExpressionNodeInfo(OperationType.Function, "atan") },
+ { ExpressionNodeType.Cos, new ExpressionNodeInfo(OperationType.Function, "cos") },
+ { ExpressionNodeType.Ceil, new ExpressionNodeInfo(OperationType.Function, "ceil") },
+ { ExpressionNodeType.Clamp, new ExpressionNodeInfo(OperationType.Function, "clamp") },
+ { ExpressionNodeType.ColorHsl, new ExpressionNodeInfo(OperationType.Function, "colorhsl") },
+ { ExpressionNodeType.ColorRgb, new ExpressionNodeInfo(OperationType.Function, "colorrgb") },
+ { ExpressionNodeType.ColorLerp, new ExpressionNodeInfo(OperationType.Function, "colorlerp") },
+ { ExpressionNodeType.ColorLerpHsl, new ExpressionNodeInfo(OperationType.Function, "colorhsllerp") },
+ { ExpressionNodeType.ColorLerpRgb, new ExpressionNodeInfo(OperationType.Function, "colorrgblerp") },
+ { ExpressionNodeType.Concatenate, new ExpressionNodeInfo(OperationType.Function, "concatenate") },
+ { ExpressionNodeType.Distance, new ExpressionNodeInfo(OperationType.Function, "distance") },
+ { ExpressionNodeType.DistanceSquared, new ExpressionNodeInfo(OperationType.Function, "distancesquared") },
+ { ExpressionNodeType.Floor, new ExpressionNodeInfo(OperationType.Function, "floor") },
+ { ExpressionNodeType.Inverse, new ExpressionNodeInfo(OperationType.Function, "inverse") },
+ { ExpressionNodeType.Length, new ExpressionNodeInfo(OperationType.Function, "length") },
+ { ExpressionNodeType.LengthSquared, new ExpressionNodeInfo(OperationType.Function, "lengthsquared") },
+ { ExpressionNodeType.Lerp, new ExpressionNodeInfo(OperationType.Function, "lerp") },
+ { ExpressionNodeType.Ln, new ExpressionNodeInfo(OperationType.Function, "ln") },
+ { ExpressionNodeType.Log10, new ExpressionNodeInfo(OperationType.Function, "log10") },
+ { ExpressionNodeType.Max, new ExpressionNodeInfo(OperationType.Function, "max") },
+ { ExpressionNodeType.Matrix3x2FromRotation, new ExpressionNodeInfo(OperationType.Function, "matrix3x2.createrotation") },
+ { ExpressionNodeType.Matrix3x2FromScale, new ExpressionNodeInfo(OperationType.Function, "matrix3x2.createscale") },
+ { ExpressionNodeType.Matrix3x2FromSkew, new ExpressionNodeInfo(OperationType.Function, "matrix3x2.createskew") },
+ { ExpressionNodeType.Matrix3x2FromTranslation, new ExpressionNodeInfo(OperationType.Function, "matrix3x2.createtranslation") },
+ { ExpressionNodeType.Matrix3x2, new ExpressionNodeInfo(OperationType.Function, "matrix3x2") },
+ { ExpressionNodeType.Matrix4x4FromAxisAngle, new ExpressionNodeInfo(OperationType.Function, "matrix4x4.createfromaxisangle") },
+ { ExpressionNodeType.Matrix4x4FromScale, new ExpressionNodeInfo(OperationType.Function, "matrix4x4.createscale") },
+ { ExpressionNodeType.Matrix4x4FromTranslation, new ExpressionNodeInfo(OperationType.Function, "matrix4x4.createtranslation") },
+ { ExpressionNodeType.Matrix4x4, new ExpressionNodeInfo(OperationType.Function, "matrix4x4") },
+ { ExpressionNodeType.Min, new ExpressionNodeInfo(OperationType.Function, "min") },
+ { ExpressionNodeType.Modulus, new ExpressionNodeInfo(OperationType.Function, "mod") },
+ { ExpressionNodeType.Negate, new ExpressionNodeInfo(OperationType.Function, "-") },
+ { ExpressionNodeType.Normalize, new ExpressionNodeInfo(OperationType.Function, "normalize") },
+ { ExpressionNodeType.Pow, new ExpressionNodeInfo(OperationType.Function, "pow") },
+ { ExpressionNodeType.QuaternionFromAxisAngle, new ExpressionNodeInfo(OperationType.Function, "quaternion.createfromaxisangle") },
+ { ExpressionNodeType.Quaternion, new ExpressionNodeInfo(OperationType.Function, "quaternion") },
+ { ExpressionNodeType.Round, new ExpressionNodeInfo(OperationType.Function, "round") },
+ { ExpressionNodeType.Scale, new ExpressionNodeInfo(OperationType.Function, "scale") },
+ { ExpressionNodeType.Sin, new ExpressionNodeInfo(OperationType.Function, "sin") },
+ { ExpressionNodeType.Slerp, new ExpressionNodeInfo(OperationType.Function, "slerp") },
+ { ExpressionNodeType.Sqrt, new ExpressionNodeInfo(OperationType.Function, "sqrt") },
+ { ExpressionNodeType.Square, new ExpressionNodeInfo(OperationType.Function, "square") },
+ { ExpressionNodeType.Tan, new ExpressionNodeInfo(OperationType.Function, "tan") },
+ { ExpressionNodeType.ToDegrees, new ExpressionNodeInfo(OperationType.Function, "todegrees") },
+ { ExpressionNodeType.ToRadians, new ExpressionNodeInfo(OperationType.Function, "toradians") },
+ { ExpressionNodeType.Transform, new ExpressionNodeInfo(OperationType.Function, "transform") },
+ { ExpressionNodeType.Vector2, new ExpressionNodeInfo(OperationType.Function, "vector2") },
+ { ExpressionNodeType.Vector3, new ExpressionNodeInfo(OperationType.Function, "vector3") },
+ { ExpressionNodeType.Vector4, new ExpressionNodeInfo(OperationType.Function, "vector4") },
+ };
+ }
+}
\ No newline at end of file
diff --git a/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionBuilder.csproj b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionBuilder.csproj
new file mode 100644
index 000000000..97836668c
--- /dev/null
+++ b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionBuilder.csproj
@@ -0,0 +1,47 @@
+
+
+
+ net5.0-windows10.0.19041
+ 10.0.19041.0
+ 10.0.18362.0
+ ExpressionBuilder
+
+ AnyCPU;x86;x64
+ win-x86;win-x64;win10-x86
+
+
+ 1701;1702;8305
+
+
+ 1701;1702;8305
+
+
+ 1701;1702;8305;CA1416
+
+
+ 1701;1702;8305
+
+
+ 1701;1702;8305
+
+
+ 1701;1702;8305
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionNodes/ExpressionBuilder.BooleanNode.cs b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionNodes/ExpressionBuilder.BooleanNode.cs
new file mode 100644
index 000000000..08dc753fe
--- /dev/null
+++ b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionNodes/ExpressionBuilder.BooleanNode.cs
@@ -0,0 +1,60 @@
+///---------------------------------------------------------------------------------------------------------------------
+///
+/// Copyright (c) Microsoft Corporation. All rights reserved.
+///
+///---------------------------------------------------------------------------------------------------------------------
+
+namespace ExpressionBuilder
+{
+// Ignore warning: 'BooleanNode' defines operator == or operator != but does not override Object.Equals(object o) && Object.GetHashCode()
+#pragma warning disable CS0660, CS0661
+ public sealed class BooleanNode : ExpressionNode
+ {
+ internal BooleanNode()
+ {
+ }
+
+ internal BooleanNode(bool value)
+ {
+ _value = value;
+ _nodeType = ExpressionNodeType.ConstantValue;
+ }
+
+ internal BooleanNode(string paramName)
+ {
+ _paramName = paramName;
+ _nodeType = ExpressionNodeType.ConstantParameter;
+ }
+
+ internal BooleanNode(string paramName, bool value)
+ {
+ _paramName = paramName;
+ _value = value;
+ _nodeType = ExpressionNodeType.ConstantParameter;
+
+ SetBooleanParameter(paramName, value);
+ }
+
+
+ //
+ // Operator overloads
+ //
+
+ public static implicit operator BooleanNode(bool value) { return new BooleanNode(value); }
+
+ public static BooleanNode operator ==(BooleanNode left, BooleanNode right) { return ExpressionFunctions.Function(ExpressionNodeType.Equals, left, right); }
+ public static BooleanNode operator !=(BooleanNode left, BooleanNode right) { return ExpressionFunctions.Function(ExpressionNodeType.NotEquals, left, right); }
+
+ public static BooleanNode operator &(BooleanNode left, BooleanNode right) { return ExpressionFunctions.Function(ExpressionNodeType.And, left, right); }
+ public static BooleanNode operator |(BooleanNode left, BooleanNode right) { return ExpressionFunctions.Function(ExpressionNodeType.Or, left, right); }
+ public static BooleanNode operator !(BooleanNode value) { return ExpressionFunctions.Function(ExpressionNodeType.Not, value); }
+
+ internal protected override string GetValue()
+ {
+ return _value ? "true" : "false";
+ }
+
+ private bool _value;
+ }
+#pragma warning restore CS0660, CS0661
+}
\ No newline at end of file
diff --git a/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionNodes/ExpressionBuilder.ColorNode.cs b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionNodes/ExpressionBuilder.ColorNode.cs
new file mode 100644
index 000000000..bfe0cdcf3
--- /dev/null
+++ b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionNodes/ExpressionBuilder.ColorNode.cs
@@ -0,0 +1,58 @@
+///---------------------------------------------------------------------------------------------------------------------
+///
+/// Copyright (c) Microsoft Corporation. All rights reserved.
+///
+///---------------------------------------------------------------------------------------------------------------------
+
+namespace ExpressionBuilder
+{
+ using Windows.UI;
+
+// Ignore warning: 'ColorNode' defines operator == or operator != but does not override Object.Equals(object o) && Object.GetHashCode()
+#pragma warning disable CS0660, CS0661
+ public sealed class ColorNode : ExpressionNode
+ {
+ internal ColorNode()
+ {
+ }
+
+ internal ColorNode(Color value)
+ {
+ _value = value;
+ _nodeType = ExpressionNodeType.ConstantValue;
+ }
+
+ internal ColorNode(string paramName)
+ {
+ _paramName = paramName;
+ _nodeType = ExpressionNodeType.ConstantParameter;
+ }
+
+ internal ColorNode(string paramName, Color value)
+ {
+ _paramName = paramName;
+ _value = value;
+ _nodeType = ExpressionNodeType.ConstantParameter;
+
+ SetColorParameter(paramName, value);
+ }
+
+
+ //
+ // Operator overloads
+ //
+
+ public static implicit operator ColorNode(Color value) { return new ColorNode(value); }
+
+ public static BooleanNode operator ==(ColorNode left, ColorNode right) { return ExpressionFunctions.Function(ExpressionNodeType.Equals, left, right); }
+ public static BooleanNode operator !=(ColorNode left, ColorNode right) { return ExpressionFunctions.Function(ExpressionNodeType.NotEquals, left, right); }
+
+ internal protected override string GetValue()
+ {
+ return $"ColorRgb({_value.A},{_value.R},{_value.G},{_value.B})";
+ }
+
+ private Color _value;
+ }
+#pragma warning restore CS0660, CS0661
+}
\ No newline at end of file
diff --git a/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionNodes/ExpressionBuilder.ExpressionNode.cs b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionNodes/ExpressionBuilder.ExpressionNode.cs
new file mode 100644
index 000000000..59c1ae69b
--- /dev/null
+++ b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionNodes/ExpressionBuilder.ExpressionNode.cs
@@ -0,0 +1,626 @@
+///---------------------------------------------------------------------------------------------------------------------
+///
+/// Copyright (c) Microsoft Corporation. All rights reserved.
+///
+///---------------------------------------------------------------------------------------------------------------------
+
+namespace ExpressionBuilder
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Numerics;
+
+ using Windows.UI;
+
+ using Microsoft.UI.Composition;
+
+ internal enum ExpressionNodeType
+ {
+ ConstantValue,
+ ConstantParameter,
+ CurrentValueProperty,
+ Reference,
+ ReferenceProperty,
+ StartingValueProperty,
+ TargetReference,
+ Conditional,
+ Swizzle,
+ Add,
+ And,
+ Divide,
+ Equals,
+ GreaterThan,
+ GreaterThanEquals,
+ LessThan,
+ LessThanEquals,
+ Multiply,
+ Not,
+ NotEquals,
+ Or,
+ Subtract,
+ Absolute,
+ Acos,
+ Asin,
+ Atan,
+ Cos,
+ Ceil,
+ Clamp,
+ ColorHsl,
+ ColorRgb,
+ ColorLerp,
+ ColorLerpHsl,
+ ColorLerpRgb,
+ Concatenate,
+ Distance,
+ DistanceSquared,
+ Floor,
+ Inverse,
+ Length,
+ LengthSquared,
+ Lerp,
+ Ln,
+ Log10,
+ Max,
+ Matrix3x2FromRotation,
+ Matrix3x2FromScale,
+ Matrix3x2FromSkew,
+ Matrix3x2FromTranslation,
+ Matrix3x2,
+ Matrix4x4FromAxisAngle,
+ Matrix4x4FromScale,
+ Matrix4x4FromTranslation,
+ Matrix4x4,
+ Min,
+ Modulus,
+ Negate,
+ Normalize,
+ Pow,
+ QuaternionFromAxisAngle,
+ Quaternion,
+ Round,
+ Scale,
+ Sin,
+ Slerp,
+ Sqrt,
+ Square,
+ Tan,
+ ToDegrees,
+ ToRadians,
+ Transform,
+ Vector2,
+ Vector3,
+ Vector4,
+
+ Count
+ }
+
+ internal enum ValueKeywordKind
+ {
+ CurrentValue,
+ StartingValue,
+ }
+
+ ///---------------------------------------------------------------------------------------------------------------------
+ ///
+ /// class ExpressionNode
+ /// ToDo: Add description after docs written
+ ///
+ ///---------------------------------------------------------------------------------------------------------------------
+
+ public abstract class ExpressionNode
+ {
+ internal ExpressionNode() { }
+
+ /// Resolve a named reference parameter to the CompositionObject it will refer to.
+ /// The string name of the parameter to be resolved.
+ /// The composition object that the parameter should resolve to.
+ public void SetReferenceParameter(string parameterName, CompositionObject compObj)
+ {
+ // Make sure we have our reference list populated
+ EnsureReferenceInfo();
+
+ for (int i = 0; i < _objRefList.Count; i++)
+ {
+ if (string.Compare(_objRefList[i].ParameterName, parameterName, true /*ignoreCase*/) == 0)
+ {
+ var item = _objRefList[i];
+ item.CompObject = compObj;
+ _objRefList[i] = item;
+ }
+ }
+ }
+
+ /// Resolve a named parameter to the boolean value it will use.
+ /// The string name of the parameter to be resolved.
+ /// The value that the parameter should resolve to.
+ public void SetBooleanParameter(string parameterName, bool value) { _constParamMap[parameterName] = value; }
+
+ /// Resolve a named parameter to the float value it will use.
+ /// The string name of the parameter to be resolved.
+ /// The value that the parameter should resolve to.
+ public void SetScalarParameter(string parameterName, float value) { _constParamMap[parameterName] = value; }
+
+ /// Resolve a named parameter to the Vector2 value it will use.
+ /// The string name of the parameter to be resolved.
+ /// The value that the parameter should resolve to.
+ public void SetVector2Parameter(string parameterName, Vector2 value) { _constParamMap[parameterName] = value; }
+
+ /// Resolve a named parameter to the Vector3 value it will use.
+ /// The string name of the parameter to be resolved.
+ /// The value that the parameter should resolve to.
+ public void SetVector3Parameter(string parameterName, Vector3 value) { _constParamMap[parameterName] = value; }
+
+ /// Resolve a named parameter to the Vector4 value it will use.
+ /// The string name of the parameter to be resolved.
+ /// The value that the parameter should resolve to.
+ public void SetVector4Parameter(string parameterName, Vector4 value) { _constParamMap[parameterName] = value; }
+
+ /// Resolve a named parameter to the Color value it will use.
+ /// The string name of the parameter to be resolved.
+ /// The value that the parameter should resolve to.
+ public void SetColorParameter(string parameterName, Color value) { _constParamMap[parameterName] = value; }
+
+ /// Resolve a named parameter to the Quaternion value it will use.
+ /// The string name of the parameter to be resolved.
+ /// The value that the parameter should resolve to.
+ public void SetQuaternionParameter(string parameterName, Quaternion value) { _constParamMap[parameterName] = value; }
+
+ /// Resolve a named parameter to the Matrix3x2 value it will use.
+ /// The string name of the parameter to be resolved.
+ /// The value that the parameter should resolve to.
+ public void SetMatrix3x2Parameter(string parameterName, Matrix3x2 value) { _constParamMap[parameterName] = value; }
+
+ /// Resolve a named parameter to the Matrix4x4 value it will use.
+ /// The string name of the parameter to be resolved.
+ /// The value that the parameter should resolve to.
+ public void SetMatrix4x4Parameter(string parameterName, Matrix4x4 value) { _constParamMap[parameterName] = value; }
+
+ /// Releases all resources used by this ExpressionNode.
+ public void Dispose()
+ {
+ _objRefList = null;
+ _compObjToParamNameMap = null;
+ _constParamMap = null;
+ _subchannels = null;
+ _propertyName = null;
+ _nodeType = ExpressionNodeType.Count;
+
+ // Note: we don't recursively dispose all child nodes, as those nodes could be in use by a different Expression
+ _children = null;
+
+ if (_expressionAnimation != null)
+ {
+ _expressionAnimation.Dispose();
+ _expressionAnimation = null;
+ }
+ }
+
+ //
+ // Helper functions
+ //
+
+ internal static T CreateExpressionNode() where T : class
+ {
+ T newNode;
+
+ if (typeof(T) == typeof(BooleanNode))
+ {
+ newNode = new BooleanNode() as T;
+ }
+ else if (typeof(T) == typeof(ScalarNode))
+ {
+ newNode = new ScalarNode() as T;
+ }
+ else if (typeof(T) == typeof(Vector2Node))
+ {
+ newNode = new Vector2Node() as T;
+ }
+ else if (typeof(T) == typeof(Vector3Node))
+ {
+ newNode = new Vector3Node() as T;
+ }
+ else if (typeof(T) == typeof(Vector4Node))
+ {
+ newNode = new Vector4Node() as T;
+ }
+ else if (typeof(T) == typeof(ColorNode))
+ {
+ newNode = new ColorNode() as T;
+ }
+ else if (typeof(T) == typeof(QuaternionNode))
+ {
+ newNode = new QuaternionNode() as T;
+ }
+ else if (typeof(T) == typeof(Matrix3x2Node))
+ {
+ newNode = new Matrix3x2Node() as T;
+ }
+ else if (typeof(T) == typeof(Matrix4x4Node))
+ {
+ newNode = new Matrix4x4Node() as T;
+ }
+ else
+ {
+ throw new Exception("unexpected type");
+ }
+
+ return newNode;
+ }
+
+ internal string ToExpressionString()
+ {
+ if (_objRefList == null)
+ {
+ EnsureReferenceInfo();
+ }
+
+ return ToExpressionStringInternal();
+ }
+
+ internal void EnsureReferenceInfo()
+ {
+ if (_objRefList == null)
+ {
+ // Get all ReferenceNodes in this expression
+ HashSet referenceNodes = new HashSet();
+ PopulateParameterNodes(ref _constParamMap, ref referenceNodes);
+
+ // Find all CompositionObjects across all referenceNodes that need a paramName to be created
+ HashSet compObjects = new HashSet();
+ foreach (var refNode in referenceNodes)
+ {
+ if ((refNode.Reference != null) && (refNode.GetReferenceParamString() == null))
+ {
+ compObjects.Add(refNode.Reference);
+ }
+ }
+
+ // Create a map to store the generated paramNames for each CompObj
+ uint id = 0;
+ _compObjToParamNameMap = new Dictionary();
+ foreach (var compObj in compObjects)
+ {
+ // compObj.ToString() will return something like "Microsoft.UI.Composition.SpriteVisual"
+ // Make it look like "SpriteVisual_1"
+ string paramName = compObj.ToString();
+ paramName = $"{paramName.Substring(paramName.LastIndexOf('.') + 1)}_{++id}"; // make sure the created param name doesn't overwrite a custom name
+
+ _compObjToParamNameMap.Add(compObj, paramName);
+ }
+
+ // Go through all reference nodes again to create our full list of referenceInfo. This time, if
+ // the param name is null, look it up from our new map and store it.
+ _objRefList = new List();
+ foreach (var refNode in referenceNodes)
+ {
+ string paramName = refNode.GetReferenceParamString();
+
+ if ((refNode.Reference == null) && (paramName == null))
+ {
+ // This can't happen - if the ref is null it must be because it's a named param
+ throw new Exception("Reference and paramName can't both be null");
+ }
+
+ if (paramName == null)
+ {
+ paramName = _compObjToParamNameMap[refNode.Reference];
+ }
+
+ _objRefList.Add(new ReferenceInfo(paramName, refNode.Reference));
+ refNode._paramName = paramName;
+ }
+ }
+ }
+
+ internal void SetAllParameters(CompositionAnimation anim)
+ {
+ // Make sure the list is populated
+ EnsureReferenceInfo();
+
+ foreach (var refInfo in _objRefList)
+ {
+ anim.SetReferenceParameter(refInfo.ParameterName, refInfo.CompObject);
+ }
+
+ foreach (var constParam in _constParamMap)
+ {
+ if (constParam.Value.GetType() == typeof(bool))
+ {
+ anim.SetBooleanParameter(constParam.Key, (bool)constParam.Value);
+ }
+ else if (constParam.Value.GetType() == typeof(float))
+ {
+ anim.SetScalarParameter(constParam.Key, (float)constParam.Value);
+ }
+ else if (constParam.Value.GetType() == typeof(Vector2))
+ {
+ anim.SetVector2Parameter(constParam.Key, (Vector2)constParam.Value);
+ }
+ else if (constParam.Value.GetType() == typeof(Vector3))
+ {
+ anim.SetVector3Parameter(constParam.Key, (Vector3)constParam.Value);
+ }
+ else if (constParam.Value.GetType() == typeof(Vector4))
+ {
+ anim.SetVector4Parameter(constParam.Key, (Vector4)constParam.Value);
+ }
+ else if (constParam.Value.GetType() == typeof(Color))
+ {
+ anim.SetColorParameter(constParam.Key, (Color)constParam.Value);
+ }
+ else if (constParam.Value.GetType() == typeof(Quaternion))
+ {
+ anim.SetQuaternionParameter(constParam.Key, (Quaternion)constParam.Value);
+ }
+ else if (constParam.Value.GetType() == typeof(Matrix3x2))
+ {
+ anim.SetMatrix3x2Parameter(constParam.Key, (Matrix3x2)constParam.Value);
+ }
+ else if (constParam.Value.GetType() == typeof(Matrix4x4))
+ {
+ anim.SetMatrix4x4Parameter(constParam.Key, (Matrix4x4)constParam.Value);
+ }
+ else
+ {
+ throw new Exception($"Unexpected constant parameter datatype ({constParam.Value.GetType()})");
+ }
+ }
+ }
+
+ internal static T CreateValueKeyword(ValueKeywordKind keywordKind) where T : class
+ {
+ T node = CreateExpressionNode();
+
+ (node as ExpressionNode)._paramName = null;
+
+ switch (keywordKind)
+ {
+ case ValueKeywordKind.CurrentValue:
+ (node as ExpressionNode)._nodeType = ExpressionNodeType.CurrentValueProperty;
+ break;
+
+ case ValueKeywordKind.StartingValue:
+ (node as ExpressionNode)._nodeType = ExpressionNodeType.StartingValueProperty;
+ break;
+
+ default:
+ throw new Exception("Invalid ValueKeywordKind");
+ }
+
+ return node;
+ }
+
+ internal protected abstract string GetValue();
+
+ internal protected T SubchannelsInternal(params string[] subchannels) where T : class
+ {
+ ExpressionNodeType swizzleNodeType = ExpressionNodeType.Swizzle;
+ T newNode;
+
+ switch (subchannels.GetLength(0))
+ {
+ case 1:
+ newNode = ExpressionFunctions.Function(swizzleNodeType, this) as T;
+ break;
+
+ case 2:
+ newNode = ExpressionFunctions.Function(swizzleNodeType, this) as T;
+ break;
+
+ case 3:
+ newNode = ExpressionFunctions.Function(swizzleNodeType, this) as T;
+ break;
+
+ case 4:
+ newNode = ExpressionFunctions.Function(swizzleNodeType, this) as T;
+ break;
+
+ case 6:
+ newNode = ExpressionFunctions.Function(swizzleNodeType, this) as T;
+ break;
+
+ case 16:
+ newNode = ExpressionFunctions.Function(swizzleNodeType, this) as T;
+ break;
+
+ default:
+ throw new Exception($"Invalid subchannel count ({subchannels.GetLength(0)})");
+ }
+
+ (newNode as ExpressionNode)._subchannels = subchannels;
+
+ return newNode;
+ }
+
+ internal protected void PopulateParameterNodes(ref Dictionary constParamMap, ref HashSet referenceNodes)
+ {
+ var refNode = (this as ReferenceNode);
+ if ((refNode != null) && (refNode._nodeType != ExpressionNodeType.TargetReference))
+ {
+ referenceNodes.Add(refNode);
+ }
+
+ if ((_constParamMap != null) && (_constParamMap != constParamMap))
+ {
+ foreach (var entry in _constParamMap)
+ {
+ // If this parameter hasn't already been set on the root, use this node's parameter info
+ if (!constParamMap.ContainsKey(entry.Key))
+ {
+ constParamMap[entry.Key] = entry.Value;
+ }
+ }
+ }
+
+ foreach (var child in _children)
+ {
+ child.PopulateParameterNodes(ref constParamMap, ref referenceNodes);
+ }
+ }
+
+
+ private OperationType GetOperationKind() { return ExpressionFunctions.GetNodeInfoFromType(_nodeType).NodeOperationKind; }
+ private string GetOperationString() { return ExpressionFunctions.GetNodeInfoFromType(_nodeType).OperationString; }
+
+
+ private string ToExpressionStringInternal()
+ {
+ string ret = "";
+
+ // Do a recursive depth-first traversal of the node tree to print out the full expression string
+ switch (GetOperationKind())
+ {
+ case OperationType.Function:
+ if (_children.Count == 0)
+ {
+ throw new Exception("Can't have an expression function with no params");
+ }
+
+ ret = $"{GetOperationString()}({_children[0].ToExpressionStringInternal()}";
+ for (int i = 1; i < _children.Count; i++)
+ {
+ ret += "," + _children[i].ToExpressionStringInternal();
+ }
+ ret += ")";
+ break;
+
+ case OperationType.Operator:
+ if (_children.Count != 2)
+ {
+ throw new Exception("Can't have an operator that doesn't have 2 exactly params");
+ }
+
+ ret = $"({_children[0].ToExpressionStringInternal()} {GetOperationString()} {_children[1].ToExpressionStringInternal()})";
+ break;
+
+ case OperationType.Constant:
+ if (_children.Count == 0)
+ {
+ // If a parameterName was specified, use it. Otherwise write the value.
+ ret = _paramName ?? GetValue();
+ }
+ else
+ {
+ throw new Exception("Constants must have 0 children");
+ }
+ break;
+
+ case OperationType.Swizzle:
+ if (_children.Count != 1)
+ {
+ throw new Exception("Swizzles should have exactly 1 child");
+ }
+
+ string swizzleString = "";
+ foreach (var sub in _subchannels)
+ {
+ swizzleString += sub;
+ }
+
+ ret = $"{_children[0].ToExpressionStringInternal()}.{swizzleString}";
+ break;
+
+ case OperationType.Reference:
+ if ((_nodeType == ExpressionNodeType.Reference) ||
+ (_nodeType == ExpressionNodeType.TargetReference))
+ {
+ // This is the reference node itself
+ if (_children.Count != 0)
+ {
+ throw new Exception("References cannot have children");
+ }
+
+ ret = (this as ReferenceNode).GetReferenceParamString();
+ }
+ else if (_nodeType == ExpressionNodeType.ReferenceProperty)
+ {
+ // This is the property node of the reference
+ if (_children.Count != 1)
+ {
+ throw new Exception("Reference properties must have exactly one child");
+ }
+
+ if (_propertyName == null)
+ {
+ throw new Exception("Reference properties must have a property name");
+ }
+
+ ret = $"{_children[0].ToExpressionStringInternal()}.{_propertyName}";
+ }
+ else if (_nodeType == ExpressionNodeType.StartingValueProperty)
+ {
+ // This is a "this.StartingValue" node
+ if (_children.Count != 0)
+ {
+ throw new Exception("StartingValue references Cannot have children");
+ }
+
+ ret = "this.StartingValue";
+ }
+ else if (_nodeType == ExpressionNodeType.CurrentValueProperty)
+ {
+ // This is a "this.CurrentValue" node
+ if (_children.Count != 0)
+ {
+ throw new Exception("CurrentValue references Cannot have children");
+ }
+
+ ret = "this.CurrentValue";
+ }
+ else
+ {
+ throw new Exception("Unexpected NodeType for OperationType.Reference");
+ }
+ break;
+
+ case OperationType.Conditional:
+ if (_children.Count != 3)
+ {
+ throw new Exception("Conditionals must have exactly 3 children");
+ }
+
+ ret = $"(({_children[0].ToExpressionStringInternal()}) ? ({_children[1].ToExpressionStringInternal()}) : ({_children[2].ToExpressionStringInternal()}))";
+ break;
+
+ default:
+ throw new Exception($"Unexpected operation type ({GetOperationKind()}), nodeType = {_nodeType}");
+ }
+
+ return ret;
+ }
+
+ //
+ // Structs
+ //
+
+ internal struct ReferenceInfo
+ {
+ public ReferenceInfo(string paramName, CompositionObject compObj)
+ {
+ ParameterName = paramName;
+ CompObject = compObj;
+ }
+
+ public string ParameterName;
+ public CompositionObject CompObject;
+ }
+
+
+ //
+ // Data
+ //
+
+ private List _objRefList = null;
+ private Dictionary _compObjToParamNameMap = null;
+ private Dictionary _constParamMap = new Dictionary(StringComparer.CurrentCultureIgnoreCase);
+
+ internal protected string[] _subchannels = null;
+ internal string _propertyName = null;
+
+ internal ExpressionNodeType _nodeType;
+ internal List _children = new List();
+ internal string _paramName = null;
+
+ internal ExpressionAnimation _expressionAnimation = null;
+ }
+}
\ No newline at end of file
diff --git a/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionNodes/ExpressionBuilder.Matrix3x2Node.cs b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionNodes/ExpressionBuilder.Matrix3x2Node.cs
new file mode 100644
index 000000000..777db1f2b
--- /dev/null
+++ b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionNodes/ExpressionBuilder.Matrix3x2Node.cs
@@ -0,0 +1,107 @@
+///---------------------------------------------------------------------------------------------------------------------
+///
+/// Copyright (c) Microsoft Corporation. All rights reserved.
+///
+///---------------------------------------------------------------------------------------------------------------------
+
+namespace ExpressionBuilder
+{
+ using System.Numerics;
+
+// Ignore warning: 'Matrix3x2Node' defines operator == or operator != but does not override Object.Equals(object o) && Object.GetHashCode()
+#pragma warning disable CS0660, CS0661
+ public sealed class Matrix3x2Node : ExpressionNode
+ {
+ internal Matrix3x2Node()
+ {
+ }
+
+ internal Matrix3x2Node(Matrix3x2 value)
+ {
+ _value = value;
+ _nodeType = ExpressionNodeType.ConstantValue;
+ }
+
+ internal Matrix3x2Node(string paramName)
+ {
+ _paramName = paramName;
+ _nodeType = ExpressionNodeType.ConstantParameter;
+ }
+
+ internal Matrix3x2Node(string paramName, Matrix3x2 value)
+ {
+ _paramName = paramName;
+ _value = value;
+ _nodeType = ExpressionNodeType.ConstantParameter;
+
+ SetMatrix3x2Parameter(paramName, value);
+ }
+
+
+ //
+ // Operator overloads
+ //
+
+ public static implicit operator Matrix3x2Node(Matrix3x2 value) { return new Matrix3x2Node(value); }
+
+ public static Matrix3x2Node operator +(Matrix3x2Node left, Matrix3x2Node right) { return ExpressionFunctions.Function(ExpressionNodeType.Add, left, right); }
+ public static Matrix3x2Node operator -(Matrix3x2Node left, Matrix3x2Node right) { return ExpressionFunctions.Function(ExpressionNodeType.Subtract, left, right); }
+ public static Matrix3x2Node operator -(Matrix3x2Node value) { return ExpressionFunctions.Function(ExpressionNodeType.Negate, value); }
+
+ public static Matrix3x2Node operator *(Matrix3x2Node left, ScalarNode right) { return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); }
+ public static Matrix3x2Node operator *(Matrix3x2Node left, Matrix3x2Node right) { return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); }
+
+ public static BooleanNode operator ==(Matrix3x2Node left, Matrix3x2Node right) { return ExpressionFunctions.Function(ExpressionNodeType.Equals, left, right); }
+ public static BooleanNode operator !=(Matrix3x2Node left, Matrix3x2Node right) { return ExpressionFunctions.Function(ExpressionNodeType.NotEquals, left, right); }
+
+
+ //
+ // Subchannels
+ //
+
+ public enum Subchannel
+ {
+ _11, _12,
+ _21, _22,
+ _31, _32,
+ }
+
+ // Commonly accessed subchannels
+ public ScalarNode _11 { get { return GetSubchannels(Subchannel._11); } }
+ public ScalarNode _12 { get { return GetSubchannels(Subchannel._12); } }
+ public ScalarNode _21 { get { return GetSubchannels(Subchannel._21); } }
+ public ScalarNode _22 { get { return GetSubchannels(Subchannel._22); } }
+ public ScalarNode _31 { get { return GetSubchannels(Subchannel._31); } }
+ public ScalarNode _32 { get { return GetSubchannels(Subchannel._32); } }
+
+ /// Create a new type by re-arranging the Matrix subchannels.
+ public ScalarNode GetSubchannels(Subchannel s) { return SubchannelsInternal(s.ToString()); }
+ public Vector2Node GetSubchannels(Subchannel s1, Subchannel s2) { return SubchannelsInternal(s1.ToString(), s2.ToString()); }
+ public Vector3Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3) { return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString()); }
+ public Vector4Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3, Subchannel s4) { return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString(), s4.ToString()); }
+
+ public Matrix3x2Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3, Subchannel s4, Subchannel s5, Subchannel s6)
+ {
+ return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString(), s4.ToString(), s5.ToString(), s6.ToString());
+ }
+
+ public Matrix4x4Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3, Subchannel s4,
+ Subchannel s5, Subchannel s6, Subchannel s7, Subchannel s8,
+ Subchannel s9, Subchannel s10, Subchannel s11, Subchannel s12,
+ Subchannel s13, Subchannel s14, Subchannel s15, Subchannel s16)
+ {
+ return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString(), s4.ToString(),
+ s5.ToString(), s6.ToString(), s7.ToString(), s8.ToString(),
+ s9.ToString(), s10.ToString(), s11.ToString(), s12.ToString(),
+ s13.ToString(), s14.ToString(), s15.ToString(), s16.ToString());
+ }
+
+ internal protected override string GetValue()
+ {
+ return $"Matrix3x2({_value.M11},{_value.M12},{_value.M21},{_value.M22},{_value.M31},{_value.M32})";
+ }
+
+ private Matrix3x2 _value;
+ }
+#pragma warning restore CS0660, CS0661
+}
\ No newline at end of file
diff --git a/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionNodes/ExpressionBuilder.Matrix4x4Node.cs b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionNodes/ExpressionBuilder.Matrix4x4Node.cs
new file mode 100644
index 000000000..c9d65b6bb
--- /dev/null
+++ b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionNodes/ExpressionBuilder.Matrix4x4Node.cs
@@ -0,0 +1,123 @@
+///---------------------------------------------------------------------------------------------------------------------
+///
+/// Copyright (c) Microsoft Corporation. All rights reserved.
+///
+///---------------------------------------------------------------------------------------------------------------------
+
+namespace ExpressionBuilder
+{
+ using System.Numerics;
+
+// Ignore warning: 'Matrix4x4Node' defines operator == or operator != but does not override Object.Equals(object o) && Object.GetHashCode()
+#pragma warning disable CS0660, CS0661
+ public sealed class Matrix4x4Node : ExpressionNode
+ {
+ internal Matrix4x4Node()
+ {
+ }
+
+ internal Matrix4x4Node(Matrix4x4 value)
+ {
+ _value = value;
+ _nodeType = ExpressionNodeType.ConstantValue;
+ }
+
+ internal Matrix4x4Node(string paramName)
+ {
+ _paramName = paramName;
+ _nodeType = ExpressionNodeType.ConstantParameter;
+ }
+
+ internal Matrix4x4Node(string paramName, Matrix4x4 value)
+ {
+ _paramName = paramName;
+ _value = value;
+ _nodeType = ExpressionNodeType.ConstantParameter;
+
+ SetMatrix4x4Parameter(paramName, value);
+ }
+
+
+ //
+ // Operator overloads
+ //
+
+ public static implicit operator Matrix4x4Node(Matrix4x4 value) { return new Matrix4x4Node(value); }
+
+ public static Matrix4x4Node operator +(Matrix4x4Node left, Matrix4x4Node right) { return ExpressionFunctions.Function(ExpressionNodeType.Add, left, right); }
+ public static Matrix4x4Node operator -(Matrix4x4Node left, Matrix4x4Node right) { return ExpressionFunctions.Function(ExpressionNodeType.Subtract, left, right); }
+ public static Matrix4x4Node operator -(Matrix4x4Node value) { return ExpressionFunctions.Function(ExpressionNodeType.Negate, value); }
+
+ public static Matrix4x4Node operator *(Matrix4x4Node left, ScalarNode right) { return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); }
+ public static Matrix4x4Node operator *(Matrix4x4Node left, Matrix4x4Node right) { return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); }
+
+ public static BooleanNode operator ==(Matrix4x4Node left, Matrix4x4Node right) { return ExpressionFunctions.Function(ExpressionNodeType.Equals, left, right); }
+ public static BooleanNode operator !=(Matrix4x4Node left, Matrix4x4Node right) { return ExpressionFunctions.Function(ExpressionNodeType.NotEquals, left, right); }
+
+
+ //
+ // Subchannels
+ //
+
+ public enum Subchannel
+ {
+ _11, _12, _13, _14,
+ _21, _22, _23, _24,
+ _31, _32, _33, _34,
+ _41, _42, _43, _44,
+ }
+
+ // Commonly accessed subchannels
+ public ScalarNode _11 { get { return GetSubchannels(Subchannel._11); } }
+ public ScalarNode _12 { get { return GetSubchannels(Subchannel._12); } }
+ public ScalarNode _13 { get { return GetSubchannels(Subchannel._13); } }
+ public ScalarNode _14 { get { return GetSubchannels(Subchannel._14); } }
+ public ScalarNode _21 { get { return GetSubchannels(Subchannel._21); } }
+ public ScalarNode _22 { get { return GetSubchannels(Subchannel._22); } }
+ public ScalarNode _23 { get { return GetSubchannels(Subchannel._23); } }
+ public ScalarNode _24 { get { return GetSubchannels(Subchannel._24); } }
+ public ScalarNode _31 { get { return GetSubchannels(Subchannel._31); } }
+ public ScalarNode _32 { get { return GetSubchannels(Subchannel._32); } }
+ public ScalarNode _33 { get { return GetSubchannels(Subchannel._33); } }
+ public ScalarNode _34 { get { return GetSubchannels(Subchannel._34); } }
+ public ScalarNode _41 { get { return GetSubchannels(Subchannel._41); } }
+ public ScalarNode _42 { get { return GetSubchannels(Subchannel._42); } }
+ public ScalarNode _43 { get { return GetSubchannels(Subchannel._43); } }
+ public ScalarNode _44 { get { return GetSubchannels(Subchannel._44); } }
+ public Vector3Node _11_22_33 { get { return GetSubchannels(Subchannel._11, Subchannel._22, Subchannel._33); } }
+ public Vector3Node _41_42_43 { get { return GetSubchannels(Subchannel._41, Subchannel._42, Subchannel._43); } }
+
+ /// Create a new type by re-arranging the Matrix subchannels.
+ public ScalarNode GetSubchannels(Subchannel s) { return SubchannelsInternal(s.ToString()); }
+ public Vector2Node GetSubchannels(Subchannel s1, Subchannel s2) { return SubchannelsInternal(s1.ToString(), s2.ToString()); }
+ public Vector3Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3) { return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString()); }
+ public Vector4Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3, Subchannel s4) { return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString(), s4.ToString()); }
+
+ public Matrix3x2Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3, Subchannel s4, Subchannel s5, Subchannel s6)
+ {
+ return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString(), s4.ToString(), s5.ToString(), s6.ToString());
+ }
+
+ public Matrix4x4Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3, Subchannel s4,
+ Subchannel s5, Subchannel s6, Subchannel s7, Subchannel s8,
+ Subchannel s9, Subchannel s10, Subchannel s11, Subchannel s12,
+ Subchannel s13, Subchannel s14, Subchannel s15, Subchannel s16)
+ {
+ return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString(), s4.ToString(),
+ s5.ToString(), s6.ToString(), s7.ToString(), s8.ToString(),
+ s9.ToString(), s10.ToString(), s11.ToString(), s12.ToString(),
+ s13.ToString(), s14.ToString(), s15.ToString(), s16.ToString());
+ }
+
+ internal protected override string GetValue()
+ {
+ return $"Matrix4x4({_value.M11},{_value.M12},{_value.M13},{_value.M14}," +
+ $"{_value.M21},{_value.M22},{_value.M23},{_value.M24}," +
+ $"{_value.M31},{_value.M32},{_value.M33},{_value.M34}," +
+ $"{_value.M41},{_value.M42},{_value.M43},{_value.M44})";
+ }
+
+ private Matrix4x4 _value;
+ }
+#pragma warning restore CS0660, CS0661
+}
\ No newline at end of file
diff --git a/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionNodes/ExpressionBuilder.QuaternionNode.cs b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionNodes/ExpressionBuilder.QuaternionNode.cs
new file mode 100644
index 000000000..aaa8080c8
--- /dev/null
+++ b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionNodes/ExpressionBuilder.QuaternionNode.cs
@@ -0,0 +1,63 @@
+///---------------------------------------------------------------------------------------------------------------------
+///
+/// Copyright (c) Microsoft Corporation. All rights reserved.
+///
+///---------------------------------------------------------------------------------------------------------------------
+
+namespace ExpressionBuilder
+{
+ using System.Numerics;
+
+// Ignore warning: 'QuaternionNode' defines operator == or operator != but does not override Object.Equals(object o) && Object.GetHashCode()
+#pragma warning disable CS0660, CS0661
+ public sealed class QuaternionNode : ExpressionNode
+ {
+ internal QuaternionNode()
+ {
+ }
+
+ internal QuaternionNode(Quaternion value)
+ {
+ _value = value;
+ _nodeType = ExpressionNodeType.ConstantValue;
+ }
+
+ internal QuaternionNode(string paramName)
+ {
+ _paramName = paramName;
+ _nodeType = ExpressionNodeType.ConstantParameter;
+ }
+
+ internal QuaternionNode(string paramName, Quaternion value)
+ {
+ _paramName = paramName;
+ _value = value;
+ _nodeType = ExpressionNodeType.ConstantParameter;
+
+ SetQuaternionParameter(paramName, value);
+ }
+
+
+ //
+ // Operator overloads
+ //
+
+ public static implicit operator QuaternionNode(Quaternion value) { return new QuaternionNode(value); }
+
+ public static QuaternionNode operator *(QuaternionNode left, ScalarNode right) { return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); }
+ public static QuaternionNode operator *(QuaternionNode left, QuaternionNode right) { return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); }
+
+ public static QuaternionNode operator /(QuaternionNode left, QuaternionNode right) { return ExpressionFunctions.Function(ExpressionNodeType.Divide, left, right); }
+
+ public static BooleanNode operator ==(QuaternionNode left, QuaternionNode right) { return ExpressionFunctions.Function(ExpressionNodeType.Equals, left, right); }
+ public static BooleanNode operator !=(QuaternionNode left, QuaternionNode right) { return ExpressionFunctions.Function(ExpressionNodeType.NotEquals, left, right); }
+
+ internal protected override string GetValue()
+ {
+ return $"Quaternion({_value.X},{_value.Y},{_value.Z},{_value.W})";
+ }
+
+ private Quaternion _value;
+ }
+#pragma warning restore CS0660, CS0661
+}
\ No newline at end of file
diff --git a/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionNodes/ExpressionBuilder.ScalarNode.cs b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionNodes/ExpressionBuilder.ScalarNode.cs
new file mode 100644
index 000000000..e51c5a68c
--- /dev/null
+++ b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionNodes/ExpressionBuilder.ScalarNode.cs
@@ -0,0 +1,74 @@
+///---------------------------------------------------------------------------------------------------------------------
+///
+/// Copyright (c) Microsoft Corporation. All rights reserved.
+///
+///---------------------------------------------------------------------------------------------------------------------
+
+namespace ExpressionBuilder
+{
+// Ignore warning: 'ScalarNode' defines operator == or operator != but does not override Object.Equals(object o) && Object.GetHashCode()
+#pragma warning disable CS0660, CS0661
+ public sealed class ScalarNode : ExpressionNode
+ {
+ internal ScalarNode()
+ {
+ }
+
+ internal ScalarNode(float value)
+ {
+ _value = value;
+ _nodeType = ExpressionNodeType.ConstantValue;
+ }
+
+ internal ScalarNode(string paramName)
+ {
+ _paramName = paramName;
+ _nodeType = ExpressionNodeType.ConstantParameter;
+ }
+
+ internal ScalarNode(string paramName, float value)
+ {
+ _paramName = paramName;
+ _value = value;
+ _nodeType = ExpressionNodeType.ConstantParameter;
+
+ SetScalarParameter(paramName, value);
+ }
+
+
+ //
+ // Operator overloads
+ //
+
+ public static implicit operator ScalarNode(float value) { return new ScalarNode(value); }
+ public static implicit operator ScalarNode(int value) { return new ScalarNode((float)value); }
+
+ public static ScalarNode operator +(ScalarNode left, ScalarNode right) { return ExpressionFunctions.Function(ExpressionNodeType.Add, left, right); }
+ public static ScalarNode operator -(ScalarNode left, ScalarNode right) { return ExpressionFunctions.Function(ExpressionNodeType.Subtract, left, right); }
+ public static ScalarNode operator -(ScalarNode value) { return ExpressionFunctions.Function(ExpressionNodeType.Negate, value); }
+
+ public static ScalarNode operator *(ScalarNode left, ScalarNode right) { return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); }
+ public static Vector2Node operator *(ScalarNode left, Vector2Node right) { return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); }
+ public static Vector3Node operator *(ScalarNode left, Vector3Node right) { return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); }
+ public static Vector4Node operator *(ScalarNode left, Vector4Node right) { return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); }
+ public static Matrix4x4Node operator *(ScalarNode left, Matrix4x4Node right) { return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); }
+
+ public static ScalarNode operator /(ScalarNode left, ScalarNode right) { return ExpressionFunctions.Function(ExpressionNodeType.Divide, left, right); }
+ public static ScalarNode operator %(ScalarNode left, ScalarNode right) { return ExpressionFunctions.Function(ExpressionNodeType.Modulus, left, right); }
+
+ public static BooleanNode operator ==(ScalarNode left, ScalarNode right) { return ExpressionFunctions.Function(ExpressionNodeType.Equals, left, right); }
+ public static BooleanNode operator !=(ScalarNode left, ScalarNode right) { return ExpressionFunctions.Function(ExpressionNodeType.NotEquals, left, right); }
+ public static BooleanNode operator <=(ScalarNode left, ScalarNode right) { return ExpressionFunctions.Function(ExpressionNodeType.LessThanEquals, left, right); }
+ public static BooleanNode operator <(ScalarNode left, ScalarNode right) { return ExpressionFunctions.Function(ExpressionNodeType.LessThan, left, right); }
+ public static BooleanNode operator >=(ScalarNode left, ScalarNode right) { return ExpressionFunctions.Function(ExpressionNodeType.GreaterThanEquals, left, right); }
+ public static BooleanNode operator >(ScalarNode left, ScalarNode right) { return ExpressionFunctions.Function(ExpressionNodeType.GreaterThan, left, right); }
+
+ internal protected override string GetValue()
+ {
+ return _value.ToString();
+ }
+
+ private float _value;
+ }
+#pragma warning restore CS0660, CS0661
+}
\ No newline at end of file
diff --git a/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionNodes/ExpressionBuilder.Vector2Node.cs b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionNodes/ExpressionBuilder.Vector2Node.cs
new file mode 100644
index 000000000..c54a8eb7b
--- /dev/null
+++ b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionNodes/ExpressionBuilder.Vector2Node.cs
@@ -0,0 +1,105 @@
+///---------------------------------------------------------------------------------------------------------------------
+///
+/// Copyright (c) Microsoft Corporation. All rights reserved.
+///
+///---------------------------------------------------------------------------------------------------------------------
+
+namespace ExpressionBuilder
+{
+ using System.Numerics;
+
+// Ignore warning: 'Vector2Node' defines operator == or operator != but does not override Object.Equals(object o) && Object.GetHashCode()
+#pragma warning disable CS0660, CS0661
+ public sealed class Vector2Node : ExpressionNode
+ {
+ internal Vector2Node()
+ {
+ }
+
+ internal Vector2Node(Vector2 value)
+ {
+ _value = value;
+ _nodeType = ExpressionNodeType.ConstantValue;
+ }
+
+ internal Vector2Node(string paramName)
+ {
+ _paramName = paramName;
+ _nodeType = ExpressionNodeType.ConstantParameter;
+ }
+
+ internal Vector2Node(string paramName, Vector2 value)
+ {
+ _paramName = paramName;
+ _value = value;
+ _nodeType = ExpressionNodeType.ConstantParameter;
+
+ SetVector2Parameter(paramName, value);
+ }
+
+
+ //
+ // Operator overloads
+ //
+
+ public static implicit operator Vector2Node(Vector2 value) { return new Vector2Node(value); }
+
+ public static Vector2Node operator +(Vector2Node left, Vector2Node right) { return ExpressionFunctions.Function(ExpressionNodeType.Add, left, right); }
+ public static Vector2Node operator -(Vector2Node left, Vector2Node right) { return ExpressionFunctions.Function(ExpressionNodeType.Subtract, left, right); }
+ public static Vector2Node operator -(Vector2Node value) { return ExpressionFunctions.Function(ExpressionNodeType.Negate, value); }
+
+ public static Vector2Node operator *(Vector2Node left, ScalarNode right) { return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); }
+ public static Vector2Node operator *(Vector2Node left, Vector2Node right) { return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); }
+
+ public static Vector2Node operator /(Vector2Node left, Vector2Node right) { return ExpressionFunctions.Function(ExpressionNodeType.Divide, left, right); }
+ public static Vector2Node operator %(Vector2Node left, Vector2Node right) { return ExpressionFunctions.Function(ExpressionNodeType.Modulus, left, right); }
+
+ public static BooleanNode operator ==(Vector2Node left, Vector2Node right) { return ExpressionFunctions.Function(ExpressionNodeType.Equals, left, right); }
+ public static BooleanNode operator !=(Vector2Node left, Vector2Node right) { return ExpressionFunctions.Function(ExpressionNodeType.NotEquals, left, right); }
+
+
+ //
+ // Subchannels
+ //
+
+ public enum Subchannel
+ {
+ X,
+ Y
+ }
+
+ // Commonly accessed subchannels
+ public ScalarNode X { get { return GetSubchannels(Subchannel.X); } }
+ public ScalarNode Y { get { return GetSubchannels(Subchannel.Y); } }
+
+ /// Create a new type by re-arranging the Vector subchannels.
+ public ScalarNode GetSubchannels(Subchannel s) { return SubchannelsInternal(s.ToString()); }
+ public Vector2Node GetSubchannels(Subchannel s1, Subchannel s2) { return SubchannelsInternal(s1.ToString(), s2.ToString()); }
+ public Vector3Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3) { return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString()); }
+ public Vector4Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3, Subchannel s4) { return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString(), s4.ToString()); }
+
+ public Matrix3x2Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3, Subchannel s4, Subchannel s5, Subchannel s6)
+ {
+ return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString(), s4.ToString(), s5.ToString(), s6.ToString());
+ }
+
+ public Matrix4x4Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3, Subchannel s4,
+ Subchannel s5, Subchannel s6, Subchannel s7, Subchannel s8,
+ Subchannel s9, Subchannel s10, Subchannel s11, Subchannel s12,
+ Subchannel s13, Subchannel s14, Subchannel s15, Subchannel s16)
+ {
+ return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString(), s4.ToString(),
+ s5.ToString(), s6.ToString(), s7.ToString(), s8.ToString(),
+ s9.ToString(), s10.ToString(), s11.ToString(), s12.ToString(),
+ s13.ToString(), s14.ToString(), s15.ToString(), s16.ToString());
+ }
+
+ internal protected override string GetValue()
+ {
+ return $"Vector2({_value.X},{_value.Y})";
+ }
+
+ private Vector2 _value;
+ }
+#pragma warning restore CS0660, CS0661
+}
\ No newline at end of file
diff --git a/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionNodes/ExpressionBuilder.Vector3Node.cs b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionNodes/ExpressionBuilder.Vector3Node.cs
new file mode 100644
index 000000000..7023ae039
--- /dev/null
+++ b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionNodes/ExpressionBuilder.Vector3Node.cs
@@ -0,0 +1,108 @@
+///---------------------------------------------------------------------------------------------------------------------
+///
+/// Copyright (c) Microsoft Corporation. All rights reserved.
+///
+///---------------------------------------------------------------------------------------------------------------------
+
+namespace ExpressionBuilder
+{
+ using System.Numerics;
+
+// Ignore warning: 'Vector3Node' defines operator == or operator != but does not override Object.Equals(object o) && Object.GetHashCode()
+#pragma warning disable CS0660, CS0661
+ public sealed class Vector3Node : ExpressionNode
+ {
+ internal Vector3Node()
+ {
+ }
+
+ internal Vector3Node(Vector3 value)
+ {
+ _value = value;
+ _nodeType = ExpressionNodeType.ConstantValue;
+ }
+
+ internal Vector3Node(string paramName)
+ {
+ _paramName = paramName;
+ _nodeType = ExpressionNodeType.ConstantParameter;
+ }
+
+ internal Vector3Node(string paramName, Vector3 value)
+ {
+ _paramName = paramName;
+ _value = value;
+ _nodeType = ExpressionNodeType.ConstantParameter;
+
+ SetVector3Parameter(paramName, value);
+ }
+
+
+ //
+ // Operator overloads
+ //
+
+ public static implicit operator Vector3Node(Vector3 value) { return new Vector3Node(value); }
+
+ public static Vector3Node operator +(Vector3Node left, Vector3Node right) { return ExpressionFunctions.Function(ExpressionNodeType.Add, left, right); }
+ public static Vector3Node operator -(Vector3Node left, Vector3Node right) { return ExpressionFunctions.Function(ExpressionNodeType.Subtract, left, right); }
+ public static Vector3Node operator -(Vector3Node value) { return ExpressionFunctions.Function(ExpressionNodeType.Negate, value); }
+
+ public static Vector3Node operator *(Vector3Node left, ScalarNode right) { return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); }
+ public static Vector3Node operator *(Vector3Node left, Vector3Node right) { return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); }
+
+ public static Vector3Node operator /(Vector3Node left, Vector3Node right) { return ExpressionFunctions.Function(ExpressionNodeType.Divide, left, right); }
+ public static Vector3Node operator %(Vector3Node left, Vector3Node right) { return ExpressionFunctions.Function(ExpressionNodeType.Modulus, left, right); }
+
+ public static BooleanNode operator ==(Vector3Node left, Vector3Node right) { return ExpressionFunctions.Function(ExpressionNodeType.Equals, left, right); }
+ public static BooleanNode operator !=(Vector3Node left, Vector3Node right) { return ExpressionFunctions.Function(ExpressionNodeType.NotEquals, left, right); }
+
+
+ //
+ // Subchannels
+ //
+
+ public enum Subchannel
+ {
+ X,
+ Y,
+ Z
+ }
+
+ // Commonly accessed subchannels
+ public ScalarNode X { get { return GetSubchannels(Subchannel.X); } }
+ public ScalarNode Y { get { return GetSubchannels(Subchannel.Y); } }
+ public ScalarNode Z { get { return GetSubchannels(Subchannel.Z); } }
+ public Vector2Node XY { get { return GetSubchannels(Subchannel.X, Subchannel.Y); } }
+
+ /// Create a new type by re-arranging the Vector subchannels.
+ public ScalarNode GetSubchannels(Subchannel s) { return SubchannelsInternal(s.ToString()); }
+ public Vector2Node GetSubchannels(Subchannel s1, Subchannel s2) { return SubchannelsInternal(s1.ToString(), s2.ToString()); }
+ public Vector3Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3) { return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString()); }
+ public Vector4Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3, Subchannel s4) { return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString(), s4.ToString()); }
+
+ public Matrix3x2Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3, Subchannel s4, Subchannel s5, Subchannel s6)
+ {
+ return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString(), s4.ToString(), s5.ToString(), s6.ToString());
+ }
+
+ public Matrix4x4Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3, Subchannel s4,
+ Subchannel s5, Subchannel s6, Subchannel s7, Subchannel s8,
+ Subchannel s9, Subchannel s10, Subchannel s11, Subchannel s12,
+ Subchannel s13, Subchannel s14, Subchannel s15, Subchannel s16)
+ {
+ return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString(), s4.ToString(),
+ s5.ToString(), s6.ToString(), s7.ToString(), s8.ToString(),
+ s9.ToString(), s10.ToString(), s11.ToString(), s12.ToString(),
+ s13.ToString(), s14.ToString(), s15.ToString(), s16.ToString());
+ }
+
+ internal protected override string GetValue()
+ {
+ return $"Vector3({_value.X},{_value.Y},{_value.Z})";
+ }
+
+ private Vector3 _value;
+ }
+#pragma warning restore CS0660, CS0661
+}
\ No newline at end of file
diff --git a/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionNodes/ExpressionBuilder.Vector4Node.cs b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionNodes/ExpressionBuilder.Vector4Node.cs
new file mode 100644
index 000000000..19ca5f787
--- /dev/null
+++ b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionNodes/ExpressionBuilder.Vector4Node.cs
@@ -0,0 +1,111 @@
+///---------------------------------------------------------------------------------------------------------------------
+///
+/// Copyright (c) Microsoft Corporation. All rights reserved.
+///
+///---------------------------------------------------------------------------------------------------------------------
+
+namespace ExpressionBuilder
+{
+ using System.Numerics;
+
+// Ignore warning: 'Vector4Node' defines operator == or operator != but does not override Object.Equals(object o) && Object.GetHashCode()
+#pragma warning disable CS0660, CS0661
+ public sealed class Vector4Node : ExpressionNode
+ {
+ internal Vector4Node()
+ {
+ }
+
+ internal Vector4Node(Vector4 value)
+ {
+ _value = value;
+ _nodeType = ExpressionNodeType.ConstantValue;
+ }
+
+ internal Vector4Node(string paramName)
+ {
+ _paramName = paramName;
+ _nodeType = ExpressionNodeType.ConstantParameter;
+ }
+
+ internal Vector4Node(string paramName, Vector4 value)
+ {
+ _paramName = paramName;
+ _value = value;
+ _nodeType = ExpressionNodeType.ConstantParameter;
+
+ SetVector4Parameter(paramName, value);
+ }
+
+
+ //
+ // Operator overloads
+ //
+
+ public static implicit operator Vector4Node(Vector4 value) { return new Vector4Node(value); }
+
+ public static Vector4Node operator +(Vector4Node left, Vector4Node right) { return ExpressionFunctions.Function(ExpressionNodeType.Add, left, right); }
+ public static Vector4Node operator -(Vector4Node left, Vector4Node right) { return ExpressionFunctions.Function(ExpressionNodeType.Subtract, left, right); }
+ public static Vector4Node operator -(Vector4Node value) { return ExpressionFunctions.Function(ExpressionNodeType.Negate, value); }
+
+ public static Vector4Node operator *(Vector4Node left, ScalarNode right) { return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); }
+ public static Vector4Node operator *(Vector4Node left, Vector4Node right) { return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); }
+
+ public static Vector4Node operator /(Vector4Node left, Vector4Node right) { return ExpressionFunctions.Function(ExpressionNodeType.Divide, left, right); }
+ public static Vector4Node operator %(Vector4Node left, Vector4Node right) { return ExpressionFunctions.Function(ExpressionNodeType.Modulus, left, right); }
+
+ public static BooleanNode operator ==(Vector4Node left, Vector4Node right) { return ExpressionFunctions.Function(ExpressionNodeType.Equals, left, right); }
+ public static BooleanNode operator !=(Vector4Node left, Vector4Node right) { return ExpressionFunctions.Function(ExpressionNodeType.NotEquals, left, right); }
+
+
+ //
+ // Subchannels
+ //
+
+ public enum Subchannel
+ {
+ X,
+ Y,
+ Z,
+ W
+ }
+
+ // Commonly accessed subchannels
+ public ScalarNode X { get { return GetSubchannels(Subchannel.X); } }
+ public ScalarNode Y { get { return GetSubchannels(Subchannel.Y); } }
+ public ScalarNode Z { get { return GetSubchannels(Subchannel.Z); } }
+ public ScalarNode W { get { return GetSubchannels(Subchannel.W); } }
+ public Vector2Node XY { get { return GetSubchannels(Subchannel.X, Subchannel.Y); } }
+ public Vector3Node XYZ { get { return GetSubchannels(Subchannel.X, Subchannel.Y, Subchannel.Z); } }
+
+ /// Create a new type by re-arranging the Vector subchannels.
+ public ScalarNode GetSubchannels(Subchannel s) { return SubchannelsInternal(s.ToString()); }
+ public Vector2Node GetSubchannels(Subchannel s1, Subchannel s2) { return SubchannelsInternal(s1.ToString(), s2.ToString()); }
+ public Vector3Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3) { return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString()); }
+ public Vector4Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3, Subchannel s4) { return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString(), s4.ToString()); }
+
+ public Matrix3x2Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3, Subchannel s4, Subchannel s5, Subchannel s6)
+ {
+ return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString(), s4.ToString(), s5.ToString(), s6.ToString());
+ }
+
+ public Matrix4x4Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3, Subchannel s4,
+ Subchannel s5, Subchannel s6, Subchannel s7, Subchannel s8,
+ Subchannel s9, Subchannel s10, Subchannel s11, Subchannel s12,
+ Subchannel s13, Subchannel s14, Subchannel s15, Subchannel s16)
+ {
+ return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString(), s4.ToString(),
+ s5.ToString(), s6.ToString(), s7.ToString(), s8.ToString(),
+ s9.ToString(), s10.ToString(), s11.ToString(), s12.ToString(),
+ s13.ToString(), s14.ToString(), s15.ToString(), s16.ToString());
+ }
+
+ internal protected override string GetValue()
+ {
+ return $"Vector4({_value.X},{_value.Y},{_value.Z},{_value.W})";
+ }
+
+ private Vector4 _value;
+ }
+#pragma warning restore CS0660, CS0661
+}
\ No newline at end of file
diff --git a/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionValues/ExpressionBuilder.ExpressionValues.Constant.cs b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionValues/ExpressionBuilder.ExpressionValues.Constant.cs
new file mode 100644
index 000000000..a819ecc38
--- /dev/null
+++ b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionValues/ExpressionBuilder.ExpressionValues.Constant.cs
@@ -0,0 +1,116 @@
+///---------------------------------------------------------------------------------------------------------------------
+///
+/// Copyright (c) Microsoft Corporation. All rights reserved.
+///
+///---------------------------------------------------------------------------------------------------------------------
+
+namespace ExpressionBuilder
+{
+ using System.Numerics;
+ using Windows.UI;
+
+ ///---------------------------------------------------------------------------------------------------------------------
+ ///
+ /// class ExpressionValues.Constant
+ /// ToDo: Add description after docs written
+ ///
+ ///---------------------------------------------------------------------------------------------------------------------
+
+ // ExpressionValues is a static class instead of a namespace to improve intellisense discoverablity and consistency with the other helper classes.
+ public static partial class ExpressionValues
+ {
+ /// Create a constant parameter whose value can be changed without recreating the expression.
+ public static class Constant
+ {
+ //
+ // Constant parameters with no default value
+ //
+
+ /// Creates a named constant parameter of type bool.
+ /// The name that will be used to refer to the parameter at a later time.
+ public static BooleanNode CreateConstantBoolean(string paramName) { return new BooleanNode(paramName); }
+
+ /// Creates a named constant parameter of type float.
+ /// The name that will be used to refer to the parameter at a later time.
+ public static ScalarNode CreateConstantScalar(string paramName) { return new ScalarNode(paramName); }
+
+ /// Creates a named constant parameter of type Vector2.
+ /// The name that will be used to refer to the parameter at a later time.
+ public static Vector2Node CreateConstantVector2(string paramName) { return new Vector2Node(paramName); }
+
+ /// Creates a named constant parameter of type Vector3.
+ /// The name that will be used to refer to the parameter at a later time.
+ public static Vector3Node CreateConstantVector3(string paramName) { return new Vector3Node(paramName); }
+
+ /// Creates a named constant parameter of type Vector4.
+ /// The name that will be used to refer to the parameter at a later time.
+ public static Vector4Node CreateConstantVector4(string paramName) { return new Vector4Node(paramName); }
+
+ /// Creates a named constant parameter of type Color.
+ /// The name that will be used to refer to the parameter at a later time.
+ public static ColorNode CreateConstantColor(string paramName) { return new ColorNode(paramName); }
+
+ /// Creates a named constant parameter of type Quaternion.
+ /// The name that will be used to refer to the parameter at a later time.
+ public static QuaternionNode CreateConstantQuaternion(string paramName) { return new QuaternionNode(paramName); }
+
+ /// Creates a named constant parameter of type Matrix3x2.
+ /// The name that will be used to refer to the parameter at a later time.
+ public static Matrix3x2Node CreateConstantMatrix3x2(string paramName) { return new Matrix3x2Node(paramName); }
+
+ /// Creates a named constant parameter of type Matrix4x4.
+ /// The name that will be used to refer to the parameter at a later time.
+ public static Matrix4x4Node CreateConstantMatrix4x4(string paramName) { return new Matrix4x4Node(paramName); }
+
+
+ //
+ // Constant parameters with a default value
+ //
+
+ /// Creates a named constant parameter of type bool, initialized with the specified value.
+ /// The name that will be used to refer to the parameter at a later time.
+ /// The value of the parameter.
+ public static BooleanNode CreateConstantBoolean(string paramName, bool value) { return new BooleanNode(paramName, value); }
+
+ /// Creates a named constant parameter of type float, initialized with the specified value.
+ /// The name that will be used to refer to the parameter at a later time.
+ /// The value of the parameter.
+ public static ScalarNode CreateConstantScalar(string paramName, float value) { return new ScalarNode(paramName, value); }
+
+ /// Creates a named constant parameter of type Vector2, initialized with the specified value.
+ /// The name that will be used to refer to the parameter at a later time.
+ /// The value of the parameter.
+ public static Vector2Node CreateConstantVector2(string paramName, Vector2 value) { return new Vector2Node(paramName, value); }
+
+ /// Creates a named constant parameter of type Vector3, initialized with the specified value.
+ /// The name that will be used to refer to the parameter at a later time.
+ /// The value of the parameter.
+ public static Vector3Node CreateConstantVector3(string paramName, Vector3 value) { return new Vector3Node(paramName, value); }
+
+ /// Creates a named constant parameter of type Vector4, initialized with the specified value.
+ /// The name that will be used to refer to the parameter at a later time.
+ /// The value of the parameter.
+ public static Vector4Node CreateConstantVector4(string paramName, Vector4 value) { return new Vector4Node(paramName, value); }
+
+ /// Creates a named constant parameter of type Color, initialized with the specified value.
+ /// The name that will be used to refer to the parameter at a later time.
+ /// The value of the parameter.
+ public static ColorNode CreateConstantColor(string paramName, Color value) { return new ColorNode(paramName, value); }
+
+ /// Creates a named constant parameter of type Quaternion, initialized with the specified value.
+ /// The name that will be used to refer to the parameter at a later time.
+ /// The value of the parameter.
+ public static QuaternionNode CreateConstantQuaternion(string paramName, Quaternion value) { return new QuaternionNode(paramName, value); }
+
+ /// Creates a named constant parameter of type Matrix3x2, initialized with the specified value.
+ /// The name that will be used to refer to the parameter at a later time.
+ /// The value of the parameter.
+ public static Matrix3x2Node CreateConstantMatrix3x2(string paramName, Matrix3x2 value) { return new Matrix3x2Node(paramName, value); }
+
+ /// Creates a named constant parameter of type Matrix4x4, initialized with the specified value.
+ /// The name that will be used to refer to the parameter at a later time.
+ /// The value of the parameter.
+ public static Matrix4x4Node CreateConstantMatrix4x4(string paramName, Matrix4x4 value) { return new Matrix4x4Node(paramName, value); }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionValues/ExpressionBuilder.ExpressionValues.CurrentValue.cs b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionValues/ExpressionBuilder.ExpressionValues.CurrentValue.cs
new file mode 100644
index 000000000..410d04eee
--- /dev/null
+++ b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionValues/ExpressionBuilder.ExpressionValues.CurrentValue.cs
@@ -0,0 +1,50 @@
+///---------------------------------------------------------------------------------------------------------------------
+///
+/// Copyright (c) Microsoft Corporation. All rights reserved.
+///
+///---------------------------------------------------------------------------------------------------------------------
+
+namespace ExpressionBuilder
+{
+ ///---------------------------------------------------------------------------------------------------------------------
+ ///
+ /// class ExpressionValues.CurrentValue
+ /// ToDo: Add description after docs written
+ ///
+ ///---------------------------------------------------------------------------------------------------------------------
+
+ // ExpressionValues is a static class instead of a namespace to improve intellisense discoverablity and consistency with the other helper classes.
+ public static partial class ExpressionValues
+ {
+ /// Refer to the current value of the property this expression is connected to.
+ public static class CurrentValue
+ {
+ /// Create a reference to the current value of the boolean property that this expression will be connected to.
+ public static BooleanNode CreateBooleanCurrentValue() { return ExpressionNode.CreateValueKeyword(ValueKeywordKind.CurrentValue); }
+
+ /// Create a reference to the current value of the float property that this expression will be connected to.
+ public static ScalarNode CreateScalarCurrentValue() { return ExpressionNode.CreateValueKeyword(ValueKeywordKind.CurrentValue); }
+
+ /// Create a reference to the current value of the Vector2 property that this expression will be connected to.
+ public static Vector2Node CreateVector2CurrentValue() { return ExpressionNode.CreateValueKeyword(ValueKeywordKind.CurrentValue); }
+
+ /// Create a reference to the current value of the Vector3 property that this expression will be connected to.
+ public static Vector3Node CreateVector3CurrentValue() { return ExpressionNode.CreateValueKeyword(ValueKeywordKind.CurrentValue); }
+
+ /// Create a reference to the current value of the Vector4 property that this expression will be connected to.
+ public static Vector4Node CreateVector4CurrentValue() { return ExpressionNode.CreateValueKeyword(ValueKeywordKind.CurrentValue); }
+
+ /// Create a reference to the current value of the Color property that this expression will be connected to.
+ public static ColorNode CreateColorCurrentValue() { return ExpressionNode.CreateValueKeyword(ValueKeywordKind.CurrentValue); }
+
+ /// Create a reference to the current value of the Quaternion property that this expression will be connected to.
+ public static QuaternionNode CreateQuaternionCurrentValue() { return ExpressionNode.CreateValueKeyword(ValueKeywordKind.CurrentValue); }
+
+ /// Create a reference to the current value of the Matrix3x2 property that this expression will be connected to.
+ public static Matrix3x2Node CreateMatrix3x2CurrentValue() { return ExpressionNode.CreateValueKeyword(ValueKeywordKind.CurrentValue); }
+
+ /// Create a reference to the current value of the Matrix4x4 property that this expression will be connected to.
+ public static Matrix4x4Node CreateMatrix4x4CurrentValue() { return ExpressionNode.CreateValueKeyword(ValueKeywordKind.CurrentValue); }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionValues/ExpressionBuilder.ExpressionValues.Reference.cs b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionValues/ExpressionBuilder.ExpressionValues.Reference.cs
new file mode 100644
index 000000000..42e9ef214
--- /dev/null
+++ b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionValues/ExpressionBuilder.ExpressionValues.Reference.cs
@@ -0,0 +1,73 @@
+///---------------------------------------------------------------------------------------------------------------------
+///
+/// Copyright (c) Microsoft Corporation. All rights reserved.
+///
+///---------------------------------------------------------------------------------------------------------------------
+
+namespace ExpressionBuilder
+{
+ using Windows.UI;
+
+ ///---------------------------------------------------------------------------------------------------------------------
+ ///
+ /// class ExpressionValues
+ /// ToDo: Add description after docs written
+ ///
+ ///---------------------------------------------------------------------------------------------------------------------
+
+ // ExpressionValues is a static class instead of a namespace to improve intellisense discoverablity and consistency with the other helper classes.
+ public static partial class ExpressionValues
+ {
+ /// Create a reference to a CompositionObject.
+ public static class Reference
+ {
+ /// Creates a named reference parameter to an AmbientLight.
+ /// The name that will be used to refer to the parameter at a later time.
+ public static AmbientLightReferenceNode CreateAmbientLightReference(string parameterName) { return new AmbientLightReferenceNode(parameterName); }
+
+ /// Creates a named reference parameter to a ColorBrush.
+ /// The name that will be used to refer to the parameter at a later time.
+ public static ColorBrushReferenceNode CreateColorBrushReference(string parameterName) { return new ColorBrushReferenceNode(parameterName); }
+
+ /// Creates a named reference parameter to a DistantLight.
+ /// The name that will be used to refer to the parameter at a later time.
+ public static DistantLightReferenceNode CreateDistantLightReference(string parameterName) { return new DistantLightReferenceNode(parameterName); }
+
+ /// Creates a named reference parameter to a DropShadow.
+ /// The name that will be used to refer to the parameter at a later time.
+ public static DropShadowReferenceNode CreateDropShadowReference(string parameterName) { return new DropShadowReferenceNode(parameterName); }
+
+ /// Creates a named reference parameter to an InsetClip.
+ /// The name that will be used to refer to the parameter at a later time.
+ public static InsetClipReferenceNode CreateInsetClipReference(string parameterName) { return new InsetClipReferenceNode(parameterName); }
+
+ /// Creates a named reference parameter to an InteractionTracker.
+ /// The name that will be used to refer to the parameter at a later time.
+ public static InteractionTrackerReferenceNode CreateInteractionTrackerReference(string parameterName) { return new InteractionTrackerReferenceNode(parameterName); }
+
+ /// Creates a named reference parameter to a NineGridBrush.
+ /// The name that will be used to refer to the parameter at a later time.
+ public static NineGridBrushReferenceNode CreateNineGridBrushReference(string parameterName) { return new NineGridBrushReferenceNode(parameterName); }
+
+ /// Creates a named reference parameter to a PointLight.
+ /// The name that will be used to refer to the parameter at a later time.
+ public static PointLightReferenceNode CreatePointLightReference(string parameterName) { return new PointLightReferenceNode(parameterName); }
+
+ /// Creates a named reference parameter to a PropertySet.
+ /// The name that will be used to refer to the parameter at a later time.
+ public static PropertySetReferenceNode CreatePropertySetReference(string parameterName) { return new PropertySetReferenceNode(parameterName); }
+
+ /// Creates a named reference parameter to a SpotLight.
+ /// The name that will be used to refer to the parameter at a later time.
+ public static SpotLightReferenceNode CreateSpotLightReference(string parameterName) { return new SpotLightReferenceNode(parameterName); }
+
+ /// Creates a named reference parameter to a SurfaceBrush.
+ /// The name that will be used to refer to the parameter at a later time.
+ public static SurfaceBrushReferenceNode CreateSurfaceBrushReference(string parameterName) { return new SurfaceBrushReferenceNode(parameterName); }
+
+ /// Creates a named reference parameter to a Visual.
+ /// The name that will be used to refer to the parameter at a later time.
+ public static VisualReferenceNode CreateVisualReference(string parameterName) { return new VisualReferenceNode(parameterName); }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionValues/ExpressionBuilder.ExpressionValues.StartingValue.cs b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionValues/ExpressionBuilder.ExpressionValues.StartingValue.cs
new file mode 100644
index 000000000..295ba2dc6
--- /dev/null
+++ b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionValues/ExpressionBuilder.ExpressionValues.StartingValue.cs
@@ -0,0 +1,50 @@
+///---------------------------------------------------------------------------------------------------------------------
+///
+/// Copyright (c) Microsoft Corporation. All rights reserved.
+///
+///---------------------------------------------------------------------------------------------------------------------
+
+namespace ExpressionBuilder
+{
+ ///---------------------------------------------------------------------------------------------------------------------
+ ///
+ /// class ExpressionValues.StartingValue
+ /// ToDo: Add description after docs written
+ ///
+ ///---------------------------------------------------------------------------------------------------------------------
+
+ // ExpressionValues is a static class instead of a namespace to improve intellisense discoverablity and consistency with the other helper classes.
+ public static partial class ExpressionValues
+ {
+ /// Refer to the value of the property this expression is connected to, sampled during the first frame of execution.
+ public static class StartingValue
+ {
+ /// Create a reference to the starting value of the boolean property that this expression will be connected to.
+ public static BooleanNode CreateBooleanStartingValue() { return ExpressionNode.CreateValueKeyword(ValueKeywordKind.StartingValue); }
+
+ /// Create a reference to the starting value of the float property that this expression will be connected to.
+ public static ScalarNode CreateScalarStartingValue() { return ExpressionNode.CreateValueKeyword(ValueKeywordKind.StartingValue); }
+
+ /// Create a reference to the starting value of the Vector2 property that this expression will be connected to.
+ public static Vector2Node CreateVector2StartingValue() { return ExpressionNode.CreateValueKeyword(ValueKeywordKind.StartingValue); }
+
+ /// Create a reference to the starting value of the Vector3 property that this expression will be connected to.
+ public static Vector3Node CreateVector3StartingValue() { return ExpressionNode.CreateValueKeyword(ValueKeywordKind.StartingValue); }
+
+ /// Create a reference to the starting value of the Vector4 property that this expression will be connected to.
+ public static Vector4Node CreateVector4StartingValue() { return ExpressionNode.CreateValueKeyword(ValueKeywordKind.StartingValue); }
+
+ /// Create a reference to the starting value of the Color property that this expression will be connected to.
+ public static ColorNode CreateColorStartingValue() { return ExpressionNode.CreateValueKeyword(ValueKeywordKind.StartingValue); }
+
+ /// Create a reference to the starting value of the Quaternion property that this expression will be connected to.
+ public static QuaternionNode CreateQuaternionStartingValue() { return ExpressionNode.CreateValueKeyword(ValueKeywordKind.StartingValue); }
+
+ /// Create a reference to the starting value of the Matrix3x2 property that this expression will be connected to.
+ public static Matrix3x2Node CreateMatrix3x2StartingValue() { return ExpressionNode.CreateValueKeyword(ValueKeywordKind.StartingValue); }
+
+ /// Create a reference to the starting value of the Matrix4x4 property that this expression will be connected to.
+ public static Matrix4x4Node CreateMatrix4x4StartingValue() { return ExpressionNode.CreateValueKeyword(ValueKeywordKind.StartingValue); }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionValues/ExpressionBuilder.ExpressionValues.Target.cs b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionValues/ExpressionBuilder.ExpressionValues.Target.cs
new file mode 100644
index 000000000..e614e5c4a
--- /dev/null
+++ b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ExpressionValues/ExpressionBuilder.ExpressionValues.Target.cs
@@ -0,0 +1,59 @@
+///---------------------------------------------------------------------------------------------------------------------
+///
+/// Copyright (c) Microsoft Corporation. All rights reserved.
+///
+///---------------------------------------------------------------------------------------------------------------------
+
+namespace ExpressionBuilder
+{
+ ///---------------------------------------------------------------------------------------------------------------------
+ ///
+ /// class ExpressionValues.Target
+ /// ToDo: Add description after docs written
+ ///
+ ///---------------------------------------------------------------------------------------------------------------------
+
+ // ExpressionValues is a static class instead of a namespace to improve intellisense discoverablity and consistency with the other helper classes.
+ public static partial class ExpressionValues
+ {
+ /// Create a reference to the CompositionObject this expression will be connected to.
+ public static class Target
+ {
+ /// Create a reference to the AmbientLight target that this expression will be connected to.
+ public static AmbientLightReferenceNode CreateAmbientLightTarget() { return AmbientLightReferenceNode.CreateTargetReference(); }
+
+ /// Create a reference to the ColorBrush target that this expression will be connected to.
+ public static ColorBrushReferenceNode CreateColorBrushTarget() { return ColorBrushReferenceNode.CreateTargetReference(); }
+
+ /// Create a reference to the DistantLight target that this expression will be connected to.
+ public static DistantLightReferenceNode CreateDistantLightTarget() { return DistantLightReferenceNode.CreateTargetReference(); }
+
+ /// Create a reference to the DropShadow target that this expression will be connected to.
+ public static DropShadowReferenceNode CreateDropShadowTarget() { return DropShadowReferenceNode.CreateTargetReference(); }
+
+ /// Create a reference to the InsetClip target that this expression will be connected to.
+ public static InsetClipReferenceNode CreateInsetClipTarget() { return InsetClipReferenceNode.CreateTargetReference(); }
+
+ /// Create a reference to the InteractionTracker target that this expression will be connected to.
+ public static InteractionTrackerReferenceNode CreateInteractionTrackerTarget() { return InteractionTrackerReferenceNode.CreateTargetReference(); }
+
+ /// Create a reference to the NineGridBrush target that this expression will be connected to.
+ public static NineGridBrushReferenceNode CreateNineGridBrushTarget() { return NineGridBrushReferenceNode.CreateTargetReference(); }
+
+ /// Create a reference to the PointLight target that this expression will be connected to.
+ public static PointLightReferenceNode CreatePointLightTarget() { return PointLightReferenceNode.CreateTargetReference(); }
+
+ /// Create a reference to the PropertySet target that this expression will be connected to.
+ public static PropertySetReferenceNode CreatePropertySetTarget() { return PropertySetReferenceNode.CreateTargetReference(); }
+
+ /// Create a reference to the SpotLight target that this expression will be connected to.
+ public static SpotLightReferenceNode CreateSpotLightTarget() { return SpotLightReferenceNode.CreateTargetReference(); }
+
+ /// Create a reference to the SurfaceBrush target that this expression will be connected to.
+ public static SurfaceBrushReferenceNode CreateSurfaceBrushTarget() { return SurfaceBrushReferenceNode.CreateTargetReference(); }
+
+ /// Create a reference to the Visual target that this expression will be connected to.
+ public static VisualReferenceNode CreateVisualTarget() { return VisualReferenceNode.CreateTargetReference(); }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/Properties/AssemblyInfo.cs b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..880bddcc5
--- /dev/null
+++ b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/Properties/AssemblyInfo.cs
@@ -0,0 +1,29 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("ExpressionBuilder")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("ExpressionBuilder")]
+[assembly: AssemblyCopyright("Copyright © 2017")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: ComVisible(false)]
\ No newline at end of file
diff --git a/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/Properties/ExpressionBuilder.rd.xml b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/Properties/ExpressionBuilder.rd.xml
new file mode 100644
index 000000000..7cb554fa5
--- /dev/null
+++ b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/Properties/ExpressionBuilder.rd.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
diff --git a/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ReferenceNodes/ExpressionBuilder.AmbientLightReferenceNode.cs b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ReferenceNodes/ExpressionBuilder.AmbientLightReferenceNode.cs
new file mode 100644
index 000000000..ecaddfaa7
--- /dev/null
+++ b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ReferenceNodes/ExpressionBuilder.AmbientLightReferenceNode.cs
@@ -0,0 +1,26 @@
+///---------------------------------------------------------------------------------------------------------------------
+///
+/// Copyright (c) Microsoft Corporation. All rights reserved.
+///
+///---------------------------------------------------------------------------------------------------------------------
+
+namespace ExpressionBuilder
+{
+ using Microsoft.UI.Composition;
+
+ public sealed class AmbientLightReferenceNode : ReferenceNode
+ {
+ internal AmbientLightReferenceNode(string paramName, AmbientLight light = null) : base(paramName, light) { }
+
+ internal static AmbientLightReferenceNode CreateTargetReference()
+ {
+ var node = new AmbientLightReferenceNode(null);
+ node._nodeType = ExpressionNodeType.TargetReference;
+
+ return node;
+ }
+
+ // Animatable properties
+ public ColorNode Color { get { return ReferenceProperty("Color"); } }
+ }
+}
\ No newline at end of file
diff --git a/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ReferenceNodes/ExpressionBuilder.ColorBrushReferenceNode.cs b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ReferenceNodes/ExpressionBuilder.ColorBrushReferenceNode.cs
new file mode 100644
index 000000000..be716ddda
--- /dev/null
+++ b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ReferenceNodes/ExpressionBuilder.ColorBrushReferenceNode.cs
@@ -0,0 +1,26 @@
+///---------------------------------------------------------------------------------------------------------------------
+///
+/// Copyright (c) Microsoft Corporation. All rights reserved.
+///
+///---------------------------------------------------------------------------------------------------------------------
+
+namespace ExpressionBuilder
+{
+ using Microsoft.UI.Composition;
+
+ public sealed class ColorBrushReferenceNode : ReferenceNode
+ {
+ internal ColorBrushReferenceNode(string paramName, CompositionColorBrush brush = null) : base(paramName, brush) { }
+
+ internal static ColorBrushReferenceNode CreateTargetReference()
+ {
+ var node = new ColorBrushReferenceNode(null);
+ node._nodeType = ExpressionNodeType.TargetReference;
+
+ return node;
+ }
+
+ // Animatable properties
+ public ColorNode Color { get { return ReferenceProperty("Color"); } }
+ }
+}
\ No newline at end of file
diff --git a/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ReferenceNodes/ExpressionBuilder.DistantLightReferenceNode.cs b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ReferenceNodes/ExpressionBuilder.DistantLightReferenceNode.cs
new file mode 100644
index 000000000..5b82dce1e
--- /dev/null
+++ b/Samples/Composition/SampleGallery/cs-winui/ExpressionBuilder/ExpressionBuilder/ReferenceNodes/ExpressionBuilder.DistantLightReferenceNode.cs
@@ -0,0 +1,27 @@
+///---------------------------------------------------------------------------------------------------------------------
+///
+/// Copyright (c) Microsoft Corporation. All rights reserved.
+///
+///---------------------------------------------------------------------------------------------------------------------
+
+namespace ExpressionBuilder
+{
+ using Microsoft.UI.Composition;
+
+ public sealed class DistantLightReferenceNode : ReferenceNode
+ {
+ internal DistantLightReferenceNode(string paramName, DistantLight light = null) : base(paramName, light) { }
+
+ internal static DistantLightReferenceNode CreateTargetReference()
+ {
+ var node = new DistantLightReferenceNode(null);
+ node._nodeType = ExpressionNodeType.TargetReference;
+
+ return node;
+ }
+
+ // Animatable properties
+ public ColorNode Color { get { return ReferenceProperty("Color"); } }
+ public Vector3Node Direction { get { return ReferenceProperty