public Runtime.GLTF SetModelAttributes(Runtime.GLTF wrapper, Runtime.Material material, List <Property> combo, ref glTFLoader.Schema.Gltf gltf) { // Switch from the flat plane to a model with multiple nodes wrapper = Common.MultiNode(); var nodeList = new List <Runtime.Node>(); nodeList.Add(wrapper.Scenes[0].Nodes[0]); nodeList.Add(wrapper.Scenes[0].Nodes[0].Children[0]); // Add a new child node that will inherit the transformations nodeList.Add((DeepCopy.CloneObject(wrapper.Scenes[0].Nodes[0]))); nodeList[2].Name = "Node1"; nodeList[2].Children = null; nodeList[1].Children = new List <Runtime.Node>(); nodeList[1].Children.Add(nodeList[2]); // Clear the vertex normal and tangent values already in the model foreach (var node in nodeList) { node.Mesh.MeshPrimitives[0].Normals = null; node.Mesh.MeshPrimitives[0].Tangents = null; } foreach (Property property in combo) { if (property.name == Propertyname.Matrix) { nodeList[1].Matrix = specialProperties[0].value; } else if (property.name == Propertyname.Translation || property.name == Propertyname.Translation_X || property.name == Propertyname.Translation_Y || property.name == Propertyname.Translation_Z) { nodeList[1].Translation = property.value; } else if (property.name == Propertyname.Rotation) { nodeList[1].Rotation = specialProperties[1].value; } else if (property.name == Propertyname.Scale) { nodeList[1].Scale = property.value; } } // Apply the material to each node foreach (var node in nodeList) { node.Mesh.MeshPrimitives[0].Material = material; } return(wrapper); }
public Runtime.GLTF SetModelAttributes(Runtime.GLTF wrapper, Runtime.Material material, List <Property> combo, ref glTFLoader.Schema.Gltf gltf) { foreach (var req in requiredProperty) { if (req.name == Propertyname.ExtensionUsed_SpecularGlossiness) { // Initialize SpecGloss for every set material.Extensions = new List <Runtime.Extensions.Extension>(); material.Extensions.Add(new Runtime.Extensions.PbrSpecularGlossiness()); if (wrapper.ExtensionsUsed == null) { wrapper.ExtensionsUsed = new List <string>(); } wrapper.ExtensionsUsed = wrapper.ExtensionsUsed.Union( new string[] { "KHR_materials_pbrSpecularGlossiness" }).ToList(); } else if (req.name == Propertyname.BaseColorTexture) { // Apply the fallback MetallicRoughness for every set material.MetallicRoughnessMaterial = new Runtime.PbrMetallicRoughness { BaseColorTexture = new Runtime.Texture { Source = req.value } }; } } var material2 = DeepCopy.CloneObject(material); Runtime.MeshPrimitive prim0 = null; Runtime.MeshPrimitive prim1 = null; foreach (var property in specialProperties) { if (property.name == Propertyname.Primitives_Split1) { prim0 = new Runtime.MeshPrimitive { Positions = property.value.Positions, Indices = property.value.Indices, }; } else if (property.name == Propertyname.Primitives_Split2) { prim1 = new Runtime.MeshPrimitive { Positions = property.value.Positions, Indices = property.value.Indices, }; } else if (property.propertyGroup == 0 ) { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives = new List <Runtime.MeshPrimitive> { prim0, prim1 }; } if (property.name == Propertyname.Primitive0VertexUV0) { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].TextureCoordSets = new List <List <Vector2> >(); wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].TextureCoordSets.Add( specialProperties.Find(e => e.name == Propertyname.Primitive0VertexUV0).value); } else if (property.name == Propertyname.Primitive1VertexUV0) { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].TextureCoordSets = new List <List <Vector2> >(); wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].TextureCoordSets.Add( specialProperties.Find(e => e.name == Propertyname.Primitive1VertexUV0).value); } } foreach (Property property in combo) { switch (property.name) { case Propertyname.SpecularGlossinessOnMaterial0_Yes: // Default. No changes needed break; case Propertyname.SpecularGlossinessOnMaterial0_No: material.Extensions = null; break; case Propertyname.SpecularGlossinessOnMaterial1_Yes: // Default. No changes needed break; case Propertyname.SpecularGlossinessOnMaterial1_No: material2.Extensions = null; break; } } wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].Material = material; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].Material = material2; return(wrapper); }
public Runtime.GLTF SetModelAttributes(Runtime.GLTF wrapper, Runtime.Material material, List <Property> combo, ref glTFLoader.Schema.Gltf gltf) { // Determines which of the primitives will have the material and attributes applied to it var splitType = combo.Find(e => e.propertyGroup == 1); foreach (Property property in combo) { if (property.name == Propertyname.Primitives_Split1 || property.name == Propertyname.Primitives_Split2 || property.name == Propertyname.Primitives_Split3 || property.name == Propertyname.Primitives_Split4) { // Same plane, but split into two triangle primitives var primitive0 = specialProperties.Find(e => e.name == Propertyname.Primitive_0); var primitive1 = specialProperties.Find(e => e.name == Propertyname.Primitive_1); Runtime.MeshPrimitive prim0 = new Runtime.MeshPrimitive { Positions = primitive0.value.Positions, Indices = primitive0.value.Indices, }; Runtime.MeshPrimitive prim1 = new Runtime.MeshPrimitive { Positions = primitive1.value.Positions, Indices = primitive1.value.Indices, }; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives = new List <Runtime.MeshPrimitive> { prim0, prim1 }; } if (property.name == Propertyname.BaseColorTexture) { if (material.MetallicRoughnessMaterial == null) { material.MetallicRoughnessMaterial = new Runtime.PbrMetallicRoughness(); material.MetallicRoughnessMaterial.BaseColorTexture = new Runtime.Texture(); } material.MetallicRoughnessMaterial.BaseColorTexture.Source = property.value; material.MetallicRoughnessMaterial.BaseColorTexture.TexCoordIndex = 0; } if (property.name == Propertyname.NormalTexture) { if (material.NormalTexture == null) { material.NormalTexture = new Runtime.Texture(); } material.NormalTexture.Source = property.value; material.NormalTexture.TexCoordIndex = 0; } // Attributes set for only the first primitive if (splitType.name == Propertyname.Primitives_Split1) { if (property.name == Propertyname.VertexNormal) { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].Normals = property.value; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].Normals = null; } else if (property.name == Propertyname.VertexTangent) { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].Tangents = property.value; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].Tangents = null; } else if (property.name == Propertyname.VertexColor_Vector4_Float) { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].Colors = property.value; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].Colors = null; } else if (ReadmeStringHelper.GenerateNameWithSpaces(property.name.ToString()) == ReadmeStringHelper.GenerateNameWithSpaces(Propertyname.Primitive0VertexUV0.ToString())) // All UV0 { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].TextureCoordSets = new List <List <Vector2> >(); wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].TextureCoordSets = null; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].TextureCoordSets.Add( specialProperties.Find(e => e.name == Propertyname.Primitive0VertexUV0).value); } else if (ReadmeStringHelper.GenerateNameWithSpaces(property.name.ToString()) == ReadmeStringHelper.GenerateNameWithSpaces(Propertyname.Primitive0VertexUV1.ToString())) // All UV1 { if (wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].TextureCoordSets == null) { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].TextureCoordSets = new List <List <Vector2> >(); } wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].TextureCoordSets.Add( specialProperties.Find(e => e.name == Propertyname.Primitive0VertexUV1).value); } } // Attributes set for only the second primitive else if (splitType.name == Propertyname.Primitives_Split2) { if (property.name == Propertyname.VertexNormal) { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].Normals = null; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].Normals = property.value; } else if (property.name == Propertyname.VertexTangent) { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].Tangents = null; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].Tangents = property.value; } else if (property.name == Propertyname.VertexColor_Vector4_Float) { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].Colors = null; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].Colors = property.value; } else if (ReadmeStringHelper.GenerateNameWithSpaces(property.name.ToString()) == ReadmeStringHelper.GenerateNameWithSpaces(Propertyname.Primitive1VertexUV0.ToString())) // All UV0 { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].TextureCoordSets = null; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].TextureCoordSets = new List <List <Vector2> >(); wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].TextureCoordSets.Add( specialProperties.Find(e => e.name == Propertyname.Primitive1VertexUV0).value); } else if (ReadmeStringHelper.GenerateNameWithSpaces(property.name.ToString()) == ReadmeStringHelper.GenerateNameWithSpaces(Propertyname.Primitive1VertexUV1.ToString())) // All UV1 { if (wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].TextureCoordSets == null) { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].TextureCoordSets = new List <List <Vector2> >(); } wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].TextureCoordSets.Add( specialProperties.Find(e => e.name == Propertyname.Primitive1VertexUV1).value); } } // Attributes set for both of the primitives else if (splitType.name == Propertyname.Primitives_Split3) { if (property.name == Propertyname.VertexNormal) { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].Normals = property.value; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].Normals = property.value; } else if (property.name == Propertyname.VertexTangent) { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].Tangents = property.value; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].Tangents = property.value; } else if (property.name == Propertyname.VertexColor_Vector4_Float) { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].Colors = property.value; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].Colors = property.value; } else if (property.name == Propertyname.Primitive0VertexUV0) { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].TextureCoordSets = new List <List <Vector2> >(); wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].TextureCoordSets.Add( specialProperties.Find(e => e.name == Propertyname.Primitive0VertexUV0).value); } else if (property.name == Propertyname.Primitive1VertexUV0) { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].TextureCoordSets = new List <List <Vector2> >(); wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].TextureCoordSets.Add( specialProperties.Find(e => e.name == Propertyname.Primitive1VertexUV0).value); } else if (property.name == Propertyname.Primitive0VertexUV1) { if (wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].TextureCoordSets == null) { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].TextureCoordSets = new List <List <Vector2> >(); } wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].TextureCoordSets.Add( specialProperties.Find(e => e.name == Propertyname.Primitive0VertexUV1).value); } else if (property.name == Propertyname.Primitive1VertexUV1) { if (wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].TextureCoordSets == null) { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].TextureCoordSets = new List <List <Vector2> >(); } wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].TextureCoordSets.Add( specialProperties.Find(e => e.name == Propertyname.Primitive1VertexUV1).value); } } // Attributes set for neither of the primitives else if (splitType.name == Propertyname.Primitives_Split4) { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].Normals = null; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].Normals = null; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].Tangents = null; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].Tangents = null; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].Colors = null; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].Colors = null; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].TextureCoordSets = null; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].TextureCoordSets = null; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].TextureCoordSets = null; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].TextureCoordSets = null; } } // Material needs to be a deep copy here, or both primitives will get the same Mat. if (material.MetallicRoughnessMaterial != null) { if (splitType.name == Propertyname.Primitives_Split1 || splitType.name == Propertyname.Primitives_Split3) { var mat = DeepCopy.CloneObject(material); wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].Material = mat; } if (splitType.name == Propertyname.Primitives_Split2 || splitType.name == Propertyname.Primitives_Split3) { var mat = DeepCopy.CloneObject(material); wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].Material = mat; } } // Use the second UV if it has been set if (splitType.name != Propertyname.Primitives_Split4) { var prim0UV1 = combo.Find(e => e.name == Propertyname.Primitive0VertexUV1); var prim1UV1 = combo.Find(e => e.name == Propertyname.Primitive1VertexUV1); if (prim0UV1 != null) { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0]. Material.MetallicRoughnessMaterial.BaseColorTexture.TexCoordIndex = 1; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0]. Material.NormalTexture.TexCoordIndex = 1; } if (prim1UV1 != null) { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1]. Material.MetallicRoughnessMaterial.BaseColorTexture.TexCoordIndex = 1; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1]. Material.NormalTexture.TexCoordIndex = 1; } } return(wrapper); }
public Runtime.GLTF SetModelAttributes(Runtime.GLTF wrapper, Runtime.Material material0, List <Property> combo, ref glTFLoader.Schema.Gltf gltf) { // Same plane, but split into two triangle primitives var primitive1 = specialProperties.Find(e => e.name == Propertyname.Primitives_Split1); var primitive2 = specialProperties.Find(e => e.name == Propertyname.Primitives_Split2); Runtime.MeshPrimitive prim0 = new Runtime.MeshPrimitive { Positions = primitive1.value.Positions, Indices = primitive1.value.Indices, }; Runtime.MeshPrimitive prim2 = new Runtime.MeshPrimitive { Positions = primitive2.value.Positions, Indices = primitive2.value.Indices, }; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives = new List <Runtime.MeshPrimitive> { prim0, prim2 }; // Make a second material var material1 = DeepCopy.CloneObject(material0); // Set the base color factor on both materials material0.MetallicRoughnessMaterial = new Runtime.PbrMetallicRoughness(); material1.MetallicRoughnessMaterial = new Runtime.PbrMetallicRoughness(); material0.MetallicRoughnessMaterial.BaseColorFactor = requiredProperty.Find(e => e.name == Propertyname.Material0WithBaseColorFactor).value; material1.MetallicRoughnessMaterial.BaseColorFactor = requiredProperty.Find(e => e.name == Propertyname.Material1WithBaseColorFactor).value; foreach (Property property in combo) { switch (property.name) { case Propertyname.Primitive0_Material0BaseColorFactor: { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].Material = material0; break; } case Propertyname.Primitive0_Material1BaseColorFactor: { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].Material = material1; break; } case Propertyname.Primitive1_Material0BaseColorFactor: { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].Material = material0; break; } case Propertyname.Primitive1_Material1BaseColorFactor: { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].Material = material1; break; } } } return(wrapper); }
public Animation_NodeMisc(List <string> imageList) { var baseColorTexture = new Texture { Source = UseTexture(imageList, "BaseColor_Cube") }; // There are no common properties in this model group that are reported in the readme. Model CreateModel(Action <List <Property>, List <AnimationChannel>, List <Node>, List <Animation> > setProperties) { var properties = new List <Property>(); var cubeMeshPrimitive = MeshPrimitive.CreateCube(); // Apply the common properties to the gltf. cubeMeshPrimitive.Material = new Runtime.Material { PbrMetallicRoughness = new PbrMetallicRoughness { BaseColorTexture = new TextureInfo { Texture = baseColorTexture }, }, }; var channels = new List <AnimationChannel> { new AnimationChannel() }; var nodes = new List <Node> { new Node(), }; var animations = new List <Animation> { new Animation { Channels = channels } }; // Apply the properties that are specific to this gltf. setProperties(properties, channels, nodes, animations); // Create the gltf object. foreach (var node in nodes) { node.Mesh = new Runtime.Mesh { MeshPrimitives = new List <Runtime.MeshPrimitive> { cubeMeshPrimitive } }; } GLTF gltf = CreateGLTF(() => new Scene { Nodes = nodes }); gltf.Animations = animations; return(new Model { Properties = properties, GLTF = gltf, Animated = true, }); } void SetTranslationChannelTarget(AnimationChannel channel, Node node) { channel.Target = new AnimationChannelTarget { Node = node, Path = AnimationChannelTargetPath.Translation, }; } void SetRotationChannelTarget(AnimationChannel channel, Node node) { channel.Target = new AnimationChannelTarget { Node = node, Path = AnimationChannelTargetPath.Rotation, }; } void SetLinearSamplerForTranslation(AnimationChannel channel) { channel.Sampler = new AnimationSampler { Interpolation = AnimationSamplerInterpolation.Linear, Input = Data.Create(new[] { 0.0f, 2.0f, 4.0f, }), Output = Data.Create(new[] { new Vector3(-0.1f, 0.0f, 0.0f), new Vector3(0.1f, 0.0f, 0.0f), new Vector3(-0.1f, 0.0f, 0.0f), }), }; } void SetLinearSamplerForHorizontalRotation(AnimationChannel channel) { channel.Sampler = new AnimationSampler { Interpolation = AnimationSamplerInterpolation.Linear, Input = Data.Create(new[] { 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, }), Output = Data.Create(new[] { Quaternion.CreateFromYawPitchRoll(FloatMath.ToRadians(90.0f), 0.0f, 0.0f), Quaternion.Identity, Quaternion.CreateFromYawPitchRoll(FloatMath.ToRadians(-90.0f), 0.0f, 0.0f), Quaternion.Identity, Quaternion.CreateFromYawPitchRoll(FloatMath.ToRadians(90.0f), 0.0f, 0.0f), }), }; } void SetLinearSamplerForVerticalRotation(AnimationChannel channel) { channel.Sampler = new AnimationSampler { Interpolation = AnimationSamplerInterpolation.Linear, Input = Data.Create(new[] { 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, }), Output = Data.Create(new[] { Quaternion.CreateFromYawPitchRoll(0.0f, FloatMath.ToRadians(90.0f), 0.0f), Quaternion.Identity, Quaternion.CreateFromYawPitchRoll(0.0f, FloatMath.ToRadians(-90.0f), 0.0f), Quaternion.Identity, Quaternion.CreateFromYawPitchRoll(0.0f, FloatMath.ToRadians(90.0f), 0.0f), }), }; } void SetLinearSamplerForConstantRotation(AnimationChannel channel) { channel.Sampler = new AnimationSampler { Interpolation = AnimationSamplerInterpolation.Linear, Input = Data.Create(new[] { 0.0f, 6.0f, }), Output = Data.Create(new[] { Quaternion.CreateFromYawPitchRoll(-FloatMath.Pi / 3.0f, 0.0f, 0.0f), Quaternion.CreateFromYawPitchRoll(-FloatMath.Pi / 3.0f, 0.0f, 0.0f), }), }; } void SetLinearSamplerForTranslationStartsAboveZero(AnimationChannel channel) { channel.Sampler = new AnimationSampler { Interpolation = AnimationSamplerInterpolation.Linear, Input = Data.Create(new[] { 2.0f, 4.0f, 6.0f, }), Output = Data.Create(new[] { new Vector3(0.0f, -0.1f, 0.0f), new Vector3(0.0f, 0.1f, 0.0f), new Vector3(0.0f, -0.1f, 0.0f), }), }; } void SetLinearSamplerWithOneKey(AnimationChannel channel) { channel.Sampler = new AnimationSampler { Interpolation = AnimationSamplerInterpolation.Linear, Input = Data.Create(new[] { 0.0f, }), Output = Data.Create(new[] { new Vector3(-0.1f, 0.0f, 0.0f), }), }; } void SetLinearSamplerForRotationThatStartsAboveZero(AnimationChannel channel) { channel.Sampler = new AnimationSampler { Interpolation = AnimationSamplerInterpolation.Linear, Input = Data.Create(new[] { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, }), Output = Data.Create(new[] { Quaternion.CreateFromYawPitchRoll(FloatMath.ToRadians(90.0f), 0.0f, 0.0f), Quaternion.Identity, Quaternion.CreateFromYawPitchRoll(FloatMath.ToRadians(-90.0f), 0.0f, 0.0f), Quaternion.Identity, Quaternion.CreateFromYawPitchRoll(FloatMath.ToRadians(90.0f), 0.0f, 0.0f), }), }; } void CreateMultipleChannelsWithUniqueTargets(List <AnimationChannel> channels, Node node) { // The first channel is already added as a common property. channels.Add(new AnimationChannel()); SetTranslationChannelTarget(channels[0], node); SetRotationChannelTarget(channels[1], node); var samplerPropertiesList = new List <Property>(); SetLinearSamplerForTranslation(channels[0]); SetLinearSamplerForHorizontalRotation(channels[1]); } void CreateMultipleChannelsWithDifferentTimes(List <AnimationChannel> channels, Node node) { // The first channel is already added as a common property. channels.Add(new AnimationChannel()); SetTranslationChannelTarget(channels[0], node); SetRotationChannelTarget(channels[1], node); SetLinearSamplerForTranslationStartsAboveZero(channels[0]); SetLinearSamplerForRotationThatStartsAboveZero(channels[1]); } void CreateMultipleChannelsForDifferentNodes(List <AnimationChannel> channels, Node node0, Node node1) { // The first channel is already added as a common property. channels.Add(new AnimationChannel()); SetRotationChannelTarget(channels[0], node0); SetRotationChannelTarget(channels[1], node1); SetLinearSamplerForHorizontalRotation(channels[0]); SetLinearSamplerForVerticalRotation(channels[1]); } Models = new List <Model> { CreateModel((properties, channels, nodes, animations) => { // Multiple channels CreateMultipleChannelsWithUniqueTargets(channels, nodes[0]); properties.Add(new Property(PropertyName.Description, "There are two channels. The first channel targets translation. The second channel targets rotation. The start and end times of both channels are `0.0` and `4.0` respectively.")); }), CreateModel((properties, channels, nodes, animations) => { // Curve that doesn't start at zero SetRotationChannelTarget(channels[0], nodes[0]); SetLinearSamplerForRotationThatStartsAboveZero(channels[0]); properties.Add(new Property(PropertyName.Description, "There is one channel with a non-zero start time. The channel targets rotation. The start time is `1.0`.")); }), CreateModel((properties, channels, nodes, animations) => { // Two channels with different start/end times CreateMultipleChannelsWithDifferentTimes(channels, nodes[0]); properties.Add(new Property(PropertyName.Description, "There are two channels with different start and end times. The first channel targets translation with start and end times of `2.0` and `6.0` respectively. The second channel targets rotation with start and end times of `1.0` and `5.0` respectively.")); }), CreateModel((properties, channels, nodes, animations) => { // Has only one key SetTranslationChannelTarget(channels[0], nodes[0]); SetLinearSamplerWithOneKey(channels[0]); properties.Add(new Property(PropertyName.Description, "There is one channel with only one keyframe. The channel targets translation with a value of <code>[-0.1, 0.0, 0.0]</code>.")); }), CreateModel((properties, channels, nodes, animations) => { // Creates a second node based on the existing node, and applies a transform to help differentiate them. nodes.Add(DeepCopy.CloneObject(nodes[0])); nodes[0].Translation = new Vector3(-0.2f, 0.0f, 0.0f); nodes[1].Translation = new Vector3(0.2f, 0.0f, 0.0f); nodes[0].Scale = new Vector3(0.5f, 0.5f, 0.5f); nodes[1].Scale = new Vector3(0.5f, 0.5f, 0.5f); // One animation, two channels for two nodes. CreateMultipleChannelsForDifferentNodes(channels, nodes[0], nodes[1]); properties.Add(new Property(PropertyName.Description, "There are two channels with different nodes. The first channel targets the left node and rotation along the X axis. The second channel targets the right node and rotation along the Y axis.")); }), CreateModel((properties, channels, nodes, animations) => { // Rotate the model, and then apply the same target animation to it (Animation overrides) nodes[0].Rotation = Quaternion.CreateFromYawPitchRoll(FloatMath.Pi / 3.0f, 0.0f, 0.0f); SetRotationChannelTarget(channels[0], nodes[0]); SetLinearSamplerForConstantRotation(channels[0]); properties.Add(new Property(PropertyName.Description, "There is one channel that targets a node. The node has a rotation of <code>[0.0, 0.5, 0.0, 0.866]</code>. The channel overrides the rotation of the node to a different constant value of <code>[0.0, -0.5, 0.0, 0.866]</code>.")); }), CreateModel((properties, channels, nodes, animations) => { // Rotate the model, and then apply an translation animation to it (Animation doesn't override rotation) nodes[0].Rotation = Quaternion.CreateFromYawPitchRoll(FloatMath.Pi / 3.0f, 0.0f, 0.0f); SetTranslationChannelTarget(channels[0], nodes[0]); SetLinearSamplerForTranslation(channels[0]); properties.Add(new Property(PropertyName.Description, "There is one channel that targets a node. The node has a rotation of <code>[0.0, 0.5, 0.0, 0.866]</code>. The channel targets the translation of the node.")); }), CreateModel((properties, channels, nodes, animations) => { // Two animations. One rotates, the other translates. They should not interact or bleed across. var channel = new AnimationChannel(); SetTranslationChannelTarget(channel, nodes[0]); SetLinearSamplerForTranslation(channel); animations.Add(new Animation { Channels = new[] { channel } }); // The first animation is already added as an empty common property. SetRotationChannelTarget(channels[0], nodes[0]); SetLinearSamplerForHorizontalRotation(channels[0]); properties.Add(new Property(PropertyName.Description, "There are two animations, each with one channel. The first animation's channel targets rotation. The second animation's channel targets translation.")); }), CreateModel((properties, channels, nodes, animations) => { // Multiple channels, but one omits node (the channel with no target node is ignored per the spec). CreateMultipleChannelsForDifferentNodes(channels, null, nodes[0]); properties.Add(new Property(PropertyName.Description, "There are two channels. The first channel has a rotation along the X axis but does not specify a node. The second channel does target the node and has a rotation along the Y axis.")); }), }; GenerateUsedPropertiesList(); }