public Material_SpecularGlossiness(List <string> imageList) { Runtime.Image diffuseTextureImage = UseTexture(imageList, "Diffuse_Plane"); Runtime.Image specularGlossinessTextureImage = UseTexture(imageList, "SpecularGlossiness_Plane"); Runtime.Image baseColorTextureImage = UseTexture(imageList, "BaseColor_X"); // Track the common properties for use in the readme. CommonProperties.Add(new Property(PropertyName.ExtensionUsed, "Specular Glossiness")); CommonProperties.Add(new Property(PropertyName.ExtensionRequired, "Specular Glossiness")); CommonProperties.Add(new Property(PropertyName.BaseColorTexture, baseColorTextureImage)); Model CreateModel(Action <List <Property>, Runtime.MeshPrimitive, Runtime.Material, KHR_materials_pbrSpecularGlossiness> setProperties) { var properties = new List <Property>(); var meshPrimitive = MeshPrimitive.CreateSinglePlane(); var extension = new KHR_materials_pbrSpecularGlossiness(); meshPrimitive.Material = new Runtime.Material(); meshPrimitive.Material.Extensions = new List <Extension> { extension }; meshPrimitive.Material.MetallicRoughnessMaterial = new Runtime.PbrMetallicRoughness(); // Apply the common properties to the gltf. meshPrimitive.Material.MetallicRoughnessMaterial.BaseColorTexture = new Runtime.Texture { Source = baseColorTextureImage }; // Apply the properties that are specific to this gltf. setProperties(properties, meshPrimitive, meshPrimitive.Material, extension); // Create the gltf object. return(new Model { Properties = properties, GLTF = CreateGLTF(() => new Runtime.Scene { Nodes = new[] { new Runtime.Node { Mesh = new Runtime.Mesh { MeshPrimitives = new[] { meshPrimitive } }, }, }, }, extensionsUsed: new List <string> { "KHR_materials_pbrSpecularGlossiness" }, extensionsRequired: new List <string> { "KHR_materials_pbrSpecularGlossiness" }), }); } void SetVertexColor(List <Property> properties, Runtime.MeshPrimitive meshPrimitive) { var vertexColors = new[] { new Vector4(0.0f, 0.0f, 1.0f, 0.8f), new Vector4(1.0f, 0.0f, 0.0f, 0.8f), new Vector4(0.0f, 0.0f, 1.0f, 0.8f), new Vector4(1.0f, 0.0f, 0.0f, 0.8f) }; meshPrimitive.ColorComponentType = ColorComponentTypeEnum.FLOAT; meshPrimitive.ColorType = ColorTypeEnum.VEC3; meshPrimitive.Colors = vertexColors; properties.Add(new Property(PropertyName.VertexColor, "Vector3 Float")); } void SetDiffuseTexture(List <Property> properties, KHR_materials_pbrSpecularGlossiness extension) { extension.DiffuseTexture = new Runtime.Texture { Source = diffuseTextureImage }; properties.Add(new Property(PropertyName.DiffuseTexture, diffuseTextureImage)); } void SetDiffuseFactor(List <Property> properties, KHR_materials_pbrSpecularGlossiness extension) { var diffuseFactorValue = new Vector4(0.2f, 0.2f, 0.2f, 0.8f); extension.DiffuseFactor = diffuseFactorValue; properties.Add(new Property(PropertyName.DiffuseFactor, diffuseFactorValue)); } void SetSpecularGlossinessTexture(List <Property> properties, KHR_materials_pbrSpecularGlossiness extension) { extension.SpecularGlossinessTexture = new Runtime.Texture { Source = specularGlossinessTextureImage }; properties.Add(new Property(PropertyName.SpecularGlossinessTexture, specularGlossinessTextureImage)); } void SetSpecularFactor(List <Property> properties, KHR_materials_pbrSpecularGlossiness extension) { var specularFactorValue = new Vector3(0.4f, 0.4f, 0.4f); extension.SpecularFactor = specularFactorValue; properties.Add(new Property(PropertyName.SpecularFactor, specularFactorValue)); } void SetSpecularFactorToZero(List <Property> properties, KHR_materials_pbrSpecularGlossiness extension) { var specularFactorValue = new Vector3(0.0f, 0.0f, 0.0f); extension.SpecularFactor = specularFactorValue; properties.Add(new Property(PropertyName.SpecularFactor, specularFactorValue)); } void SetGlossinessFactor(List <Property> properties, KHR_materials_pbrSpecularGlossiness extension) { extension.GlossinessFactor = 0.3f; properties.Add(new Property(PropertyName.GlossinessFactor, extension.GlossinessFactor)); } Models = new List <Model> { CreateModel((properties, meshPrimitive, material, extension) => { // There are no properties set on this model. }), CreateModel((properties, meshPrimitive, material, extension) => { SetVertexColor(properties, meshPrimitive); SetSpecularFactorToZero(properties, extension); }), CreateModel((properties, meshPrimitive, material, extension) => { SetDiffuseTexture(properties, extension); SetSpecularFactorToZero(properties, extension); }), CreateModel((properties, meshPrimitive, material, extension) => { SetDiffuseFactor(properties, extension); SetSpecularFactorToZero(properties, extension); }), CreateModel((properties, meshPrimitive, material, extension) => { SetSpecularGlossinessTexture(properties, extension); }), CreateModel((properties, meshPrimitive, material, extension) => { SetSpecularFactor(properties, extension); }), CreateModel((properties, meshPrimitive, material, extension) => { SetGlossinessFactor(properties, extension); }), CreateModel((properties, meshPrimitive, material, extension) => { SetVertexColor(properties, meshPrimitive); SetDiffuseTexture(properties, extension); SetSpecularFactorToZero(properties, extension); }), CreateModel((properties, meshPrimitive, material, extension) => { SetDiffuseTexture(properties, extension); SetDiffuseFactor(properties, extension); SetSpecularFactorToZero(properties, extension); }), CreateModel((properties, meshPrimitive, material, extension) => { SetDiffuseTexture(properties, extension); SetGlossinessFactor(properties, extension); }), CreateModel((properties, meshPrimitive, material, extension) => { SetSpecularGlossinessTexture(properties, extension); SetSpecularFactor(properties, extension); }), CreateModel((properties, meshPrimitive, material, extension) => { SetSpecularGlossinessTexture(properties, extension); SetGlossinessFactor(properties, extension); }), CreateModel((properties, meshPrimitive, material, extension) => { SetDiffuseTexture(properties, extension); SetSpecularFactor(properties, extension); SetGlossinessFactor(properties, extension); }), CreateModel((properties, meshPrimitive, material, extension) => { SetVertexColor(properties, meshPrimitive); SetDiffuseTexture(properties, extension); SetDiffuseFactor(properties, extension); SetSpecularGlossinessTexture(properties, extension); SetSpecularFactor(properties, extension); SetGlossinessFactor(properties, extension); }), }; GenerateUsedPropertiesList(); }
public Instancing(List <string> imageList) { var baseColorImageA = UseTexture(imageList, "BaseColor_A"); var baseColorImageB = UseTexture(imageList, "BaseColor_B"); var baseColorImageCube = UseTexture(imageList, "BaseColor_Cube"); var distantCamera = new Manifest.Camera(new Vector3(0.0f, 0.0f, 2.7f)); // There are no common properties in this model group that are reported in the readme. TextureInfo CreateTextureInfo(Image source) { return(new TextureInfo { Texture = new Texture { Source = source, } }); } Model CreateModel(Action <List <Property>, List <Node>, List <Animation> > setProperties, Action <Model> setCamera) { var properties = new List <Property>(); var animations = new List <Animation>(); var animated = true; var nodes = new List <Node>(); // Apply the properties that are specific to this gltf. setProperties(properties, nodes, animations); // If no animations are used, null out that property. if (!animations.Any()) { animations = null; animated = false; } // Create the gltf object. var model = new Model { Properties = properties, GLTF = CreateGLTF(() => new Scene { Nodes = nodes }, animations: animations), Animated = animated, }; setCamera(model); return(model); } var samplerInputLinear = Data.Create(new[] { 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, }); var samplerInputCurve = Data.Create(new[] { 0.0f, 0.5f, 1.0f, 2.0f, 4.0f, }); var samplerOutput = 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), }); var samplerOutputReverse = 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), }); Runtime.Material CreateMaterial(TextureInfo textureInfo) { return(new Runtime.Material { PbrMetallicRoughness = new PbrMetallicRoughness { BaseColorTexture = textureInfo } }); } void AddMeshPrimitivesToSingleNode(List <Node> nodes, List <Runtime.MeshPrimitive> meshPrimitives) { // If there are multiple mesh primitives, offset their position so they don't overlap. if (meshPrimitives.Count > 1) { meshPrimitives[0].Positions.Values = meshPrimitives[0].Positions.Values.Select(position => { return(new Vector3(position.X - 0.6f, position.Y, position.Z)); }); meshPrimitives[1].Positions.Values = meshPrimitives[1].Positions.Values.Select(position => { return(new Vector3(position.X + 0.6f, position.Y, position.Z)); }); } nodes.Add( new Node { Mesh = new Runtime.Mesh { MeshPrimitives = meshPrimitives } } ); } void AddMeshPrimitivesToMultipleNodes(List <Node> nodes, Runtime.MeshPrimitive meshPrimitives0, Runtime.MeshPrimitive meshPrimitives1) { nodes.AddRange(new[] { new Node { Translation = new Vector3(-0.6f, 0.0f, 0.0f), Mesh = new Runtime.Mesh { MeshPrimitives = new List <Runtime.MeshPrimitive> { meshPrimitives0 } } }, new Node { Translation = new Vector3(0.6f, 0.0f, 0.0f), Mesh = new Runtime.Mesh { MeshPrimitives = new List <Runtime.MeshPrimitive> { meshPrimitives1 } } } } ); } void AddAnimation(List <Animation> animations, List <Node> nodes, AnimationSampler sampler0, AnimationSampler sampler1, bool samplerInstanced) { animations.Add(new Animation { Channels = new List <AnimationChannel> { new AnimationChannel { Target = new AnimationChannelTarget { Node = nodes[0], Path = AnimationChannelTargetPath.Rotation, }, Sampler = sampler0 }, new AnimationChannel { Target = new AnimationChannelTarget { Node = nodes[1], Path = AnimationChannelTargetPath.Rotation, }, Sampler = sampler1 }, } }); } Models = new List <Model> { CreateModel((properties, nodes, animations) => { var meshPrimitives = new List <Runtime.MeshPrimitive> { MeshPrimitive.CreateSinglePlane(includeTextureCoords: false), MeshPrimitive.CreateSinglePlane(includeTextureCoords: false) }; foreach (Runtime.MeshPrimitive meshPrimitive in meshPrimitives) { // This non-standard set of texture coordinates is larger than the texture but not an exact multiple, so it allows texture sampler settings to be visible. meshPrimitive.TexCoords0 = Data.Create <Vector2> ( new[] { new Vector2(1.3f, 1.3f), new Vector2(-0.3f, 1.3f), new Vector2(-0.3f, -0.3f), new Vector2(1.3f, -0.3f), } ); } meshPrimitives[0].Material = CreateMaterial(CreateTextureInfo(baseColorImageA)); meshPrimitives[1].Material = CreateMaterial(CreateTextureInfo(baseColorImageA)); meshPrimitives[0].Material.PbrMetallicRoughness.BaseColorTexture.Texture.Sampler = new Sampler { WrapT = SamplerWrap.ClampToEdge, WrapS = SamplerWrap.ClampToEdge }; meshPrimitives[1].Material.PbrMetallicRoughness.BaseColorTexture.Texture.Sampler = new Sampler { WrapT = SamplerWrap.MirroredRepeat, WrapS = SamplerWrap.MirroredRepeat }; AddMeshPrimitivesToSingleNode(nodes, meshPrimitives); properties.Add(new Property(PropertyName.Description, "Two textures using the same image as their source.")); properties.Add(new Property(PropertyName.Difference, "The texture sampler `WrapT` and `WrapS` are set to `CLAMP_TO_EDGE` for one and `MIRRORED_REPEAT` for the other.")); }, (model) => { model.Camera = distantCamera; }), CreateModel((properties, nodes, animations) => { var meshPrimitives = new List <Runtime.MeshPrimitive> { MeshPrimitive.CreateSinglePlane(includeTextureCoords: false), MeshPrimitive.CreateSinglePlane(includeTextureCoords: false) }; meshPrimitives[0].Material = CreateMaterial(CreateTextureInfo(baseColorImageA)); meshPrimitives[1].Material = CreateMaterial(CreateTextureInfo(baseColorImageB)); var sampler = new Sampler { WrapT = SamplerWrap.ClampToEdge, WrapS = SamplerWrap.ClampToEdge }; foreach (Runtime.MeshPrimitive meshPrimitive in meshPrimitives) { meshPrimitive.Material.PbrMetallicRoughness.BaseColorTexture.Texture.Sampler = sampler; // This non-standard set of texture coordinates is larger than the texture but not an exact multiple, so it allows texture sampler settings to be visible. meshPrimitive.TexCoords0 = Data.Create <Vector2> ( new[] { new Vector2(1.3f, 1.3f), new Vector2(-0.3f, 1.3f), new Vector2(-0.3f, -0.3f), new Vector2(1.3f, -0.3f), } ); } AddMeshPrimitivesToSingleNode(nodes, meshPrimitives); properties.Add(new Property(PropertyName.Description, "Two textures using the same sampler.")); properties.Add(new Property(PropertyName.Difference, "One texture uses image A while the other uses image B.")); }, (model) => { model.Camera = distantCamera; }), CreateModel((properties, nodes, animations) => { var meshPrimitives = new List <Runtime.MeshPrimitive> { MeshPrimitive.CreateSinglePlane(), MeshPrimitive.CreateSinglePlane() }; var texture = CreateTextureInfo(baseColorImageA); foreach (Runtime.MeshPrimitive meshPrimitive in meshPrimitives) { meshPrimitive.Material = CreateMaterial(texture); } meshPrimitives[0].Material.PbrMetallicRoughness.BaseColorTexture = meshPrimitives[1].Material.PbrMetallicRoughness.BaseColorTexture; meshPrimitives[1].Material.PbrMetallicRoughness.BaseColorFactor = new Vector4(0.5f, 0.5f, 1.0f, 1.0f); AddMeshPrimitivesToSingleNode(nodes, meshPrimitives); properties.Add(new Property(PropertyName.Description, "Two textures using the same source image.")); properties.Add(new Property(PropertyName.Difference, "One material does not have a baseColorFactor and the other has a blue baseColorFactor.")); }, (model) => { model.Camera = distantCamera; }), CreateModel((properties, nodes, animations) => { var meshPrimitives = new List <Runtime.MeshPrimitive> { MeshPrimitive.CreateSinglePlane(), MeshPrimitive.CreateSinglePlane(includeTextureCoords: false) }; var material = CreateMaterial(CreateTextureInfo(baseColorImageA)); foreach (Runtime.MeshPrimitive meshPrimitive in meshPrimitives) { meshPrimitive.Material = material; } // One of the primitives has a 'zoomed in' texture coordinate set. meshPrimitives[1].TexCoords0 = Data.Create <Vector2> ( new[] { new Vector2(0.9f, 0.9f), new Vector2(0.1f, 0.9f), new Vector2(0.1f, 0.1f), new Vector2(0.9f, 0.1f), } ); AddMeshPrimitivesToSingleNode(nodes, meshPrimitives); properties.Add(new Property(PropertyName.Description, "Two primitives using the same material.")); properties.Add(new Property(PropertyName.Difference, "One primitive has texture coordinates that displays all of texture A, while the other primitive has textures coordinates that don't display the border.")); }, (model) => { model.Camera = distantCamera; }), CreateModel((properties, nodes, animations) => { var meshPrimitive0 = MeshPrimitive.CreateSinglePlane(); var meshPrimitive1 = MeshPrimitive.CreateSinglePlane(); meshPrimitive0.Material = CreateMaterial(CreateTextureInfo(baseColorImageA)); meshPrimitive1.Material = CreateMaterial(CreateTextureInfo(baseColorImageB)); meshPrimitive0.Positions = meshPrimitive1.Positions; AddMeshPrimitivesToMultipleNodes(nodes, meshPrimitive0, meshPrimitive1); properties.Add(new Property(PropertyName.Description, "Two primitives using the same accessors for the `POSITION` attribute.")); properties.Add(new Property(PropertyName.Difference, "One primitive uses texture A while the other primitive uses texture B.")); }, (model) => { model.Camera = distantCamera; }), CreateModel((properties, nodes, animations) => { var meshPrimitive0 = MeshPrimitive.CreateSinglePlane(includeIndices: false); var meshPrimitive1 = MeshPrimitive.CreateSinglePlane(); meshPrimitive0.Material = CreateMaterial(CreateTextureInfo(baseColorImageA)); meshPrimitive1.Material = CreateMaterial(CreateTextureInfo(baseColorImageB)); meshPrimitive0.Indices = meshPrimitive1.Indices; AddMeshPrimitivesToMultipleNodes(nodes, meshPrimitive0, meshPrimitive1); properties.Add(new Property(PropertyName.Description, "Two primitives using the same accessors for indices.")); properties.Add(new Property(PropertyName.Difference, "One primitive uses texture A while the other primitive uses texture B.")); }, (model) => { model.Camera = distantCamera; }), CreateModel((properties, nodes, animations) => { var meshPrimitive = MeshPrimitive.CreateSinglePlane(); meshPrimitive.Material = CreateMaterial(CreateTextureInfo(baseColorImageA)); AddMeshPrimitivesToMultipleNodes(nodes, meshPrimitive, meshPrimitive); nodes[1].Mesh = nodes[0].Mesh; properties.Add(new Property(PropertyName.Description, "Two nodes using the same mesh.")); properties.Add(new Property(PropertyName.Difference, "The two nodes have different translations.")); }, (model) => { model.Camera = distantCamera; }), CreateModel((properties, nodes, animations) => { nodes.AddRange(Nodes.CreateFoldingPlaneSkin("skinA", 2, 3)); nodes[0].Name = "plane0"; nodes[0].Mesh.MeshPrimitives.ElementAt(0).Material = CreateMaterial(CreateTextureInfo(baseColorImageA)); nodes[0].Mesh.MeshPrimitives.ElementAt(0).TexCoords0 = Data.Create(Nodes.GetSkinATexCoords()); // Adds just the node containing the mesh, dropping the data for a second set of joints. nodes.Add(Nodes.CreateFoldingPlaneSkin("skinA", 2, 3)[0]); nodes[2].Name = "plane1"; nodes[2].Mesh.MeshPrimitives.ElementAt(0).Material = CreateMaterial(CreateTextureInfo(baseColorImageB)); nodes[2].Mesh.MeshPrimitives.ElementAt(0).TexCoords0 = Data.Create(Nodes.GetSkinATexCoords()); nodes[2].Skin = nodes[0].Skin; // Offsets the position of both meshes so they don't overlap. nodes[0].Mesh.MeshPrimitives.ElementAt(0).Positions.Values = nodes[0].Mesh.MeshPrimitives.ElementAt(0).Positions.Values.Select(position => { return(new Vector3(position.X - 0.3f, position.Y, position.Z)); }); nodes[2].Mesh.MeshPrimitives.ElementAt(0).Positions.Values = nodes[2].Mesh.MeshPrimitives.ElementAt(0).Positions.Values.Select(position => { return(new Vector3(position.X + 0.3f, position.Y, position.Z)); }); properties.Add(new Property(PropertyName.Description, "Two nodes using the same skin.")); properties.Add(new Property(PropertyName.Difference, "The two mesh primitives have different `POSITION` values.")); }, (model) => { model.Camera = null; }), CreateModel((properties, nodes, animations) => { nodes.AddRange(Nodes.CreateFoldingPlaneSkin("skinA", 2, 3)); nodes[0].Name = "plane0"; nodes[0].Mesh.MeshPrimitives.ElementAt(0).Material = CreateMaterial(CreateTextureInfo(baseColorImageA)); nodes[0].Mesh.MeshPrimitives.ElementAt(0).TexCoords0 = Data.Create(Nodes.GetSkinATexCoords()); // Adds just the node containing the mesh, dropping the data for a second set of joints. nodes.Add(Nodes.CreateFoldingPlaneSkin("skinA", 2, 3)[0]); nodes[2].Name = "plane1"; nodes[2].Mesh.MeshPrimitives.ElementAt(0).Material = CreateMaterial(CreateTextureInfo(baseColorImageB)); nodes[2].Mesh.MeshPrimitives.ElementAt(0).TexCoords0 = Data.Create(Nodes.GetSkinATexCoords()); nodes[2].Skin.Joints = nodes[0].Skin.Joints; // Creates new inverseBindMatrices for the second skin, rotating the flap further than the default value would. nodes[2].Skin.InverseBindMatrices = Data.Create(new[] { nodes[2].Skin.InverseBindMatrices.Values.First(), Matrix4x4.Multiply(nodes[2].Skin.InverseBindMatrices.Values.ElementAt(1), Matrix4x4.CreateRotationX(FloatMath.ToRadians(-30))), }); // Offsets the position of both meshes so they don't overlap. nodes[0].Mesh.MeshPrimitives.ElementAt(0).Positions.Values = nodes[0].Mesh.MeshPrimitives.ElementAt(0).Positions.Values.Select(position => new Vector3(position.X - 0.3f, position.Y, position.Z)); nodes[2].Mesh.MeshPrimitives.ElementAt(0).Positions.Values = nodes[2].Mesh.MeshPrimitives.ElementAt(0).Positions.Values.Select(position => new Vector3(position.X + 0.3f, position.Y, position.Z)); properties.Add(new Property(PropertyName.Description, "Two skins using the same joints.")); properties.Add(new Property(PropertyName.Difference, "The skin with texture B has inverseBindMatrices that fold twice as far as the skin with texture A.")); }, (model) => { model.Camera = null; }), CreateModel((properties, nodes, animations) => { nodes.AddRange(Nodes.CreateFoldingPlaneSkin("skinA", 2, 3)); nodes[0].Name = "plane0"; nodes[0].Mesh.MeshPrimitives.ElementAt(0).Material = CreateMaterial(CreateTextureInfo(baseColorImageA)); nodes[0].Mesh.MeshPrimitives.ElementAt(0).TexCoords0 = Data.Create(Nodes.GetSkinATexCoords()); nodes[1].Translation = Vector3.Add((Vector3)nodes[1].Translation, new Vector3(-0.3f, 0.0f, 0.0f)); nodes.AddRange(Nodes.CreateFoldingPlaneSkin("skinA", 2, 3)); nodes[2].Name = "plane1"; nodes[2].Mesh.MeshPrimitives.ElementAt(0).Material = CreateMaterial(CreateTextureInfo(baseColorImageB)); nodes[2].Mesh.MeshPrimitives.ElementAt(0).TexCoords0 = Data.Create(Nodes.GetSkinATexCoords()); nodes[3].Translation = Vector3.Add((Vector3)nodes[3].Translation, new Vector3(0.3f, 0.0f, 0.0f)); nodes[2].Skin.InverseBindMatrices = nodes[0].Skin.InverseBindMatrices; properties.Add(new Property(PropertyName.Description, "Two skins using the same inverseBindMatrices.")); properties.Add(new Property(PropertyName.Difference, "The base joint for the two skins have different translations.")); }, (model) => { model.Camera = null; }), CreateModel((properties, nodes, animations) => { var meshPrimitive0 = MeshPrimitive.CreateCube(); var meshPrimitive1 = MeshPrimitive.CreateCube(); var textureInfo = CreateTextureInfo(baseColorImageCube); meshPrimitive0.Material = CreateMaterial(textureInfo); meshPrimitive1.Material = CreateMaterial(textureInfo); AddMeshPrimitivesToMultipleNodes(nodes, meshPrimitive0, meshPrimitive1); var sampler = new AnimationSampler { Interpolation = AnimationSamplerInterpolation.Linear, Input = samplerInputLinear, Output = samplerOutput, }; AddAnimation(animations, nodes, sampler, sampler, true); properties.Add(new Property(PropertyName.Description, "Two animation channels using the same sampler.")); properties.Add(new Property(PropertyName.Difference, "The two animation channels target different nodes.")); }, (model) => { model.Camera = distantCamera; }), CreateModel((properties, nodes, animations) => { var meshPrimitive0 = MeshPrimitive.CreateCube(); var meshPrimitive1 = MeshPrimitive.CreateCube(); var textureInfo = CreateTextureInfo(baseColorImageCube); meshPrimitive0.Material = CreateMaterial(textureInfo); meshPrimitive1.Material = CreateMaterial(textureInfo); AddMeshPrimitivesToMultipleNodes(nodes, meshPrimitive0, meshPrimitive1); var sampler0 = new AnimationSampler { Interpolation = AnimationSamplerInterpolation.Linear, Input = samplerInputLinear, Output = samplerOutput, }; var sampler1 = new AnimationSampler { Interpolation = AnimationSamplerInterpolation.Linear, Input = samplerInputLinear, Output = samplerOutputReverse, }; AddAnimation(animations, nodes, sampler0, sampler1, false); properties.Add(new Property(PropertyName.Description, "Two animation samplers using the same input accessors.")); properties.Add(new Property(PropertyName.Difference, "The two animation samplers have different output values.")); }, (model) => { model.Camera = distantCamera; }), CreateModel((properties, nodes, animations) => { var meshPrimitive0 = MeshPrimitive.CreateCube(); var meshPrimitive1 = MeshPrimitive.CreateCube(); var textureInfo = CreateTextureInfo(baseColorImageCube); meshPrimitive0.Material = CreateMaterial(textureInfo); meshPrimitive1.Material = CreateMaterial(textureInfo); AddMeshPrimitivesToMultipleNodes(nodes, meshPrimitive0, meshPrimitive1); var sampler0 = new AnimationSampler { Interpolation = AnimationSamplerInterpolation.Linear, Input = samplerInputLinear, Output = samplerOutput, }; var sampler1 = new AnimationSampler { Interpolation = AnimationSamplerInterpolation.Linear, Input = samplerInputCurve, Output = samplerOutput, }; AddAnimation(animations, nodes, sampler0, sampler1, false); properties.Add(new Property(PropertyName.Description, "Two animation samplers using the same output accessors.")); properties.Add(new Property(PropertyName.Difference, "The two animation samplers have different input values.")); }, (model) => { model.Camera = distantCamera; }), // To be implemented later. Needs to work as a type of interleaving. //CreateModel((properties, nodes, animations) => //{ // var meshPrimitives = new List<Runtime.MeshPrimitive> // { // MeshPrimitive.CreateSinglePlane(includeTextureCoords: false), // MeshPrimitive.CreateSinglePlane(includeTextureCoords: false) // }; // meshPrimitives[0].TexCoords0 = meshPrimitives[1].TexCoords0 = MeshPrimitive.GetSinglePlaneTextureCoordSets(); // meshPrimitives[0].Normals = meshPrimitives[1].Normals = MeshPrimitive.GetSinglePlaneNormals(); // foreach (Runtime.MeshPrimitive meshPrimitive in meshPrimitives) // { // meshPrimitive.BufferViewsInstanced = true; // meshPrimitive.Material = CreateMaterial(); // } // AddMeshPrimitivesToSingleNode(nodes, meshPrimitives); // properties.Add(new Property(PropertyName.Description, "Two accessors using the same buffer view.")); //}, (model) => { model.Camera = null; }), }; GenerateUsedPropertiesList(); }
internal static int AddLineLoop(this Gltf gltf, string name, List <byte> buffer, double[] vertices, ushort[] indices, double[] vMin, double[] vMax, ushort iMin, ushort iMax, int materialId, MeshPrimitive.ModeEnum mode, Transform transform = null) { var m = new glTFLoader.Schema.Mesh(); m.Name = name; var vBuff = gltf.AddBufferView(0, buffer.Count, vertices.Length * sizeof(float), null, null); var iBuff = gltf.AddBufferView(0, buffer.Count + vertices.Length * sizeof(float), indices.Length * sizeof(ushort), null, null); foreach (var v in vertices) { buffer.AddRange(BitConverter.GetBytes((float)v)); } foreach (var i in indices) { buffer.AddRange(BitConverter.GetBytes(i)); } while (buffer.Count % 4 != 0) { // Console.WriteLine("Padding..."); buffer.Add(0); } var vAccess = gltf.AddAccessor(vBuff, 0, Accessor.ComponentTypeEnum.FLOAT, vertices.Length / 3, new[] { (float)vMin[0], (float)vMin[1], (float)vMin[2] }, new[] { (float)vMax[0], (float)vMax[1], (float)vMax[2] }, Accessor.TypeEnum.VEC3); var iAccess = gltf.AddAccessor(iBuff, 0, Accessor.ComponentTypeEnum.UNSIGNED_SHORT, indices.Length, new[] { (float)iMin }, new[] { (float)iMax }, Accessor.TypeEnum.SCALAR); var prim = new MeshPrimitive(); prim.Indices = iAccess; prim.Material = materialId; prim.Mode = mode; prim.Attributes = new Dictionary <string, int> { { "POSITION", vAccess } }; m.Primitives = new[] { prim }; // Add mesh to gltf if (gltf.Meshes != null) { // TODO: Get rid of this resizing. var meshes = gltf.Meshes.ToList(); meshes.Add(m); gltf.Meshes = meshes.ToArray(); } else { gltf.Meshes = new[] { m }; } var parentId = 0; if (transform != null) { var a = transform.XAxis; var b = transform.YAxis; var c = transform.ZAxis; var transNode = new Node(); transNode.Matrix = new[] { (float)a.X, (float)a.Y, (float)a.Z, 0.0f, (float)b.X, (float)b.Y, (float)b.Z, 0.0f, (float)c.X, (float)c.Y, (float)c.Z, 0.0f, (float)transform.Origin.X, (float)transform.Origin.Y, (float)transform.Origin.Z, 1.0f }; parentId = gltf.AddNode(transNode, 0); } // Add mesh node to gltf var node = new Node(); node.Mesh = gltf.Meshes.Length - 1; gltf.AddNode(node, parentId); return(gltf.Meshes.Length - 1); }
protected virtual GameObject CreateMeshPrimitive(MeshPrimitive primitive, int meshID, int primitiveIndex) { var primitiveObj = new GameObject("Primitive"); var meshFilter = primitiveObj.AddComponent <MeshFilter>(); if (_assetCache.MeshCache[meshID][primitiveIndex] == null) { _assetCache.MeshCache[meshID][primitiveIndex] = new MeshCacheData(); } if (_assetCache.MeshCache[meshID][primitiveIndex].LoadedMesh == null) { if (_assetCache.MeshCache[meshID][primitiveIndex].MeshAttributes.Count == 0) { BuildMeshAttributes(primitive, meshID, primitiveIndex); } var meshAttributes = _assetCache.MeshCache[meshID][primitiveIndex].MeshAttributes; var vertexCount = primitive.Attributes[SemanticProperties.POSITION].Value.Count; // todo optimize: There are multiple copies being performed to turn the buffer data into mesh data. Look into reducing them UnityEngine.Mesh mesh = new UnityEngine.Mesh { vertices = primitive.Attributes.ContainsKey(SemanticProperties.POSITION) ? meshAttributes[SemanticProperties.POSITION].AccessorContent.AsVertices.ToUnityVector3() : null, normals = primitive.Attributes.ContainsKey(SemanticProperties.NORMAL) ? meshAttributes[SemanticProperties.NORMAL].AccessorContent.AsNormals.ToUnityVector3() : null, uv = primitive.Attributes.ContainsKey(SemanticProperties.TexCoord(0)) ? meshAttributes[SemanticProperties.TexCoord(0)].AccessorContent.AsTexcoords.ToUnityVector2() : null, uv2 = primitive.Attributes.ContainsKey(SemanticProperties.TexCoord(1)) ? meshAttributes[SemanticProperties.TexCoord(1)].AccessorContent.AsTexcoords.ToUnityVector2() : null, uv3 = primitive.Attributes.ContainsKey(SemanticProperties.TexCoord(2)) ? meshAttributes[SemanticProperties.TexCoord(2)].AccessorContent.AsTexcoords.ToUnityVector2() : null, uv4 = primitive.Attributes.ContainsKey(SemanticProperties.TexCoord(3)) ? meshAttributes[SemanticProperties.TexCoord(3)].AccessorContent.AsTexcoords.ToUnityVector2() : null, colors = primitive.Attributes.ContainsKey(SemanticProperties.Color(0)) ? meshAttributes[SemanticProperties.Color(0)].AccessorContent.AsColors.ToUnityColor() : null, triangles = primitive.Indices != null ? meshAttributes[SemanticProperties.INDICES].AccessorContent.AsTriangles : MeshPrimitive.GenerateTriangles(vertexCount), tangents = primitive.Attributes.ContainsKey(SemanticProperties.TANGENT) ? meshAttributes[SemanticProperties.TANGENT].AccessorContent.AsTangents.ToUnityVector4() : null }; _assetCache.MeshCache[meshID][primitiveIndex].LoadedMesh = mesh; } meshFilter.sharedMesh = _assetCache.MeshCache[meshID][primitiveIndex].LoadedMesh; var materialWrapper = CreateMaterial( primitive.Material != null ? primitive.Material.Value : DefaultMaterial, primitive.Material != null ? primitive.Material.Id : -1 ); var meshRenderer = primitiveObj.AddComponent <MeshRenderer>(); meshRenderer.material = materialWrapper.GetContents(primitive.Attributes.ContainsKey(SemanticProperties.Color(0))); if (_addColliders) { var meshCollider = primitiveObj.AddComponent <MeshCollider>(); meshCollider.sharedMesh = meshFilter.mesh; } return(primitiveObj); }
private void ExportNormalMaterial(UnityEngine.Material material, MeshPrimitive primitive, ExporterEntry entry) { primitive.Material = entry.SaveNormalMaterial(material); }
public Material_MetallicRoughness(List <string> imageList) { var baseColorTexture = new Texture { Source = UseTexture(imageList, "BaseColor_Plane") }; var metallicRoughnessTexture = new Texture { Source = UseTexture(imageList, "MetallicRoughness_Plane") }; // There are no common properties in this model group. Model CreateModel(Action <List <Property>, Runtime.MeshPrimitive, PbrMetallicRoughness> setProperties) { var properties = new List <Property>(); var meshPrimitive = MeshPrimitive.CreateSinglePlane(includeTextureCoords: false); // Apply the properties that are specific to this gltf. meshPrimitive.Material = new Runtime.Material { PbrMetallicRoughness = new PbrMetallicRoughness() }; setProperties(properties, meshPrimitive, meshPrimitive.Material.PbrMetallicRoughness); // Create the gltf object. return(new Model { Properties = properties, GLTF = CreateGLTF(() => new Scene { Nodes = new[] { new Node { Mesh = new Runtime.Mesh { MeshPrimitives = new List <Runtime.MeshPrimitive> { meshPrimitive } }, }, }, }), }); } void SetVertexColor(List <Property> properties, Runtime.MeshPrimitive meshPrimitive) { meshPrimitive.Colors = Data.Create ( new[] { new Vector3(0.0f, 0.0f, 1.0f), new Vector3(1.0f, 0.0f, 0.0f), new Vector3(0.0f, 0.0f, 1.0f), new Vector3(1.0f, 0.0f, 0.0f), } ); properties.Add(new Property(PropertyName.VertexColor, $"Vector3 Float")); } void SetBaseColorTexture(List <Property> properties, PbrMetallicRoughness metallicRoughness) { metallicRoughness.BaseColorTexture = new TextureInfo { Texture = baseColorTexture }; properties.Add(new Property(PropertyName.BaseColorTexture, baseColorTexture.Source.ToReadmeString())); } void SetBaseColorFactor(List <Property> properties, PbrMetallicRoughness metallicRoughness) { var baseColorFactorValue = new Vector4(0.2f, 0.2f, 0.2f, 0.8f); metallicRoughness.BaseColorFactor = baseColorFactorValue; properties.Add(new Property(PropertyName.BaseColorFactor, baseColorFactorValue.ToReadmeString())); } void SetMetallicRoughnessTexture(List <Property> properties, PbrMetallicRoughness metallicRoughness) { metallicRoughness.MetallicRoughnessTexture = new TextureInfo { Texture = metallicRoughnessTexture }; properties.Add(new Property(PropertyName.MetallicRoughnessTexture, metallicRoughnessTexture.Source.ToReadmeString())); } void SetMetallicFactor(List <Property> properties, PbrMetallicRoughness metallicRoughness) { metallicRoughness.MetallicFactor = 0.0f; properties.Add(new Property(PropertyName.MetallicFactor, metallicRoughness.MetallicFactor.ToReadmeString())); } void SetRoughnessFactor(List <Property> properties, PbrMetallicRoughness metallicRoughness) { metallicRoughness.RoughnessFactor = 0.0f; properties.Add(new Property(PropertyName.RoughnessFactor, metallicRoughness.RoughnessFactor.ToReadmeString())); } Models = new List <Model> { CreateModel((properties, meshPrimitive, metallicRoughness) => { // There are no properties set on this model. }), CreateModel((properties, meshPrimitive, metallicRoughness) => { SetVertexColor(properties, meshPrimitive); }), CreateModel((properties, meshPrimitive, metallicRoughness) => { meshPrimitive.TexCoords0 = Data.Create(MeshPrimitive.GetSinglePlaneTexCoords()); SetBaseColorTexture(properties, metallicRoughness); }), CreateModel((properties, meshPrimitive, metallicRoughness) => { SetBaseColorFactor(properties, metallicRoughness); }), CreateModel((properties, meshPrimitive, metallicRoughness) => { meshPrimitive.TexCoords0 = Data.Create(MeshPrimitive.GetSinglePlaneTexCoords()); SetMetallicRoughnessTexture(properties, metallicRoughness); }), CreateModel((properties, meshPrimitive, metallicRoughness) => { SetMetallicFactor(properties, metallicRoughness); }), CreateModel((properties, meshPrimitive, metallicRoughness) => { SetRoughnessFactor(properties, metallicRoughness); }), CreateModel((properties, meshPrimitive, metallicRoughness) => { meshPrimitive.TexCoords0 = Data.Create(MeshPrimitive.GetSinglePlaneTexCoords()); SetVertexColor(properties, meshPrimitive); SetBaseColorTexture(properties, metallicRoughness); }), CreateModel((properties, meshPrimitive, metallicRoughness) => { meshPrimitive.TexCoords0 = Data.Create(MeshPrimitive.GetSinglePlaneTexCoords()); SetBaseColorTexture(properties, metallicRoughness); SetBaseColorFactor(properties, metallicRoughness); }), CreateModel((properties, meshPrimitive, metallicRoughness) => { meshPrimitive.TexCoords0 = Data.Create(MeshPrimitive.GetSinglePlaneTexCoords()); SetMetallicRoughnessTexture(properties, metallicRoughness); SetMetallicFactor(properties, metallicRoughness); }), CreateModel((properties, meshPrimitive, metallicRoughness) => { meshPrimitive.TexCoords0 = Data.Create(MeshPrimitive.GetSinglePlaneTexCoords()); SetMetallicRoughnessTexture(properties, metallicRoughness); SetRoughnessFactor(properties, metallicRoughness); }), CreateModel((properties, meshPrimitive, metallicRoughness) => { meshPrimitive.TexCoords0 = Data.Create(MeshPrimitive.GetSinglePlaneTexCoords()); SetVertexColor(properties, meshPrimitive); SetBaseColorTexture(properties, metallicRoughness); SetBaseColorFactor(properties, metallicRoughness); SetMetallicRoughnessTexture(properties, metallicRoughness); SetMetallicFactor(properties, metallicRoughness); SetRoughnessFactor(properties, metallicRoughness); }), }; GenerateUsedPropertiesList(); }
public void MeshPrimitiveEqualTest() { var a = new MeshPrimitive { attributes = new Attributes { POSITION = 42 } }; var b = new MeshPrimitive { attributes = new Attributes { POSITION = 42 } }; Assert.IsTrue(a.Equals(b)); a.targets = new[] { new MorphTarget { POSITION = 0 } }; b.targets = null; Assert.IsFalse(a.Equals(b)); a.targets = new[] { new MorphTarget { POSITION = 0 } }; b.targets = new[] { new MorphTarget { POSITION = 0 } }; Assert.IsTrue(a.Equals(b)); a.targets = new[] { new MorphTarget { POSITION = 0 } }; b.targets = new[] { new MorphTarget { POSITION = 0, NORMAL = 1 } }; Assert.IsFalse(a.Equals(b)); a.targets = null; b.targets = new[] { new MorphTarget { POSITION = 0 } }; Assert.IsFalse(a.Equals(b)); a.targets = new[] { new MorphTarget { POSITION = 0 } }; b.targets = new[] { new MorphTarget { POSITION = 0 }, new MorphTarget { POSITION = 0 } }; Assert.IsFalse(a.Equals(b)); a = new MeshPrimitive { attributes = new Attributes { POSITION = 41 } }; b = new MeshPrimitive { attributes = new Attributes { POSITION = 42 } }; Assert.IsFalse(a.Equals(b)); a.targets = new[] { new MorphTarget { POSITION = 0 } }; b.targets = new[] { new MorphTarget { POSITION = 0 } }; Assert.IsFalse(a.Equals(b)); }
public Model GenerateModel(MeshPrimitive meshPrimitive, string name, IEnumerable <Attribution> attributions = null) { return(GenerateModel(new List <MeshPrimitive> { meshPrimitive }, name, attributions)); }
public MeshPrimitive GenerateLine(IEnumerable <GeoPoint> points, Vector4 color, float width) { MeshPrimitive mesh = null; try { if (points == null) { _logger?.LogWarning("Points are empty."); } else { if (width == 0) { // Basic line strip declaration mesh = new MeshPrimitive() { Colors = points.Select(c => color) , ColorComponentType = MeshPrimitive.ColorComponentTypeEnum.FLOAT , ColorType = MeshPrimitive.ColorTypeEnum.VEC4 , Mode = MeshPrimitive.ModeEnum.LINE_STRIP , Positions = points.Select(pt => pt.ToVector3()) , Material = new Material() }; } else { // https://gist.github.com/gszauer/5718441 // Line triangle mesh List <Vector3> sections = points.Select(pt => pt.ToVector3()) .Distinct() .ToList(); List <Vector3> vertices = new List <Vector3>(sections.Count * 2); for (int i = 0; i < sections.Count - 1; i++) { Vector3 current = sections[i]; Vector3 next = sections[i + 1]; Vector3 dir = Vector3.Normalize(next - current); // translate the vector to the left along its way Vector3 side = Vector3.Cross(dir, Vector3.UnitY) * width; Vector3 v0 = current - side; // 0 Vector3 v1 = current + side; // 1 vertices.Add(v0); vertices.Add(v1); if (i == sections.Count - 2) // add last vertices { v0 = next - side; // 0 v1 = next + side; // 1 vertices.Add(v0); vertices.Add(v1); } } // add last vertices List <int> indices = new List <int>((sections.Count - 1) * 6); for (int i = 0; i < sections.Count - 1; i++) { int i0 = i * 2; indices.Add(i0); indices.Add(i0 + 1); indices.Add(i0 + 3); indices.Add(i0 + 0); indices.Add(i0 + 3); indices.Add(i0 + 2); } IEnumerable <Vector3> normals = _meshService.ComputeNormals(vertices, indices); // Basic line strip declaration mesh = new MeshPrimitive() { Colors = vertices.Select(v => color) , ColorComponentType = MeshPrimitive.ColorComponentTypeEnum.FLOAT , ColorType = MeshPrimitive.ColorTypeEnum.VEC4 , Mode = MeshPrimitive.ModeEnum.TRIANGLES , Positions = vertices , Material = new Material() { DoubleSided = true } , Indices = indices , Normals = normals , IndexComponentType = MeshPrimitive.IndexComponentTypeEnum.UNSIGNED_INT }; } } } catch (Exception ex) { _logger?.LogError(ex, ex.ToString()); throw; } return(mesh); }
public Accessor_SparseType(List <string> imageList) { var baseColorTextureA = new Texture { Source = UseTexture(imageList, "BaseColor_A") }; var baseColorTextureB = new Texture { Source = UseTexture(imageList, "BaseColor_B") }; UseFigure(imageList, "SparseAccessor_Input"); UseFigure(imageList, "SparseAccessor_Output-Rotation"); UseFigure(imageList, "SparseAccessor_NoBufferView"); // There are no common properties in this model group that are reported in the readme. Model CreateModel(Action <List <Property>, Animation, List <Node> > setProperties) { var properties = new List <Property>(); var animated = true; var meshPrimitive0 = MeshPrimitive.CreateSinglePlane(includeTextureCoords: false); var meshPrimitive1 = MeshPrimitive.CreateSinglePlane(includeTextureCoords: false); var nodes = new List <Node> { new Node { Mesh = new Runtime.Mesh { MeshPrimitives = new List <Runtime.MeshPrimitive> { meshPrimitive0 } } }, new Node { Mesh = new Runtime.Mesh { MeshPrimitives = new List <Runtime.MeshPrimitive> { meshPrimitive1 } } } }; var animation = new Animation(); var animations = new List <Animation> { animation }; // Apply the properties that are specific to this gltf. setProperties(properties, animation, nodes); // If no animations are used, null out that property. if (animation.Channels == null) { animations = null; animated = false; } // Create the gltf object. return(new Model { Properties = properties, GLTF = CreateGLTF ( () => new Scene { Nodes = nodes }, animations: animations ), Animated = animated, Camera = new Manifest.Camera(new Vector3(0.0f, 0.0f, 2.75f)) }); } var samplerInputLinear = new[] { 0.0f, 1.0f, 2.0f, }; var samplerInputSparse = 1.5f; var samplerOutputTranslationSparse = new Vector3(0.0f, 0.2f, 0.0f); var samplerOutputRotation = new[] { Quaternion.CreateFromYawPitchRoll(0.0f, FloatMath.ToRadians(-45.0f), 0.0f), Quaternion.CreateFromYawPitchRoll(0.0f, FloatMath.ToRadians(45.0f), 0.0f), Quaternion.CreateFromYawPitchRoll(0.0f, FloatMath.ToRadians(-45.0f), 0.0f), }; var samplerOutputRotationSparse = Quaternion.CreateFromYawPitchRoll(0.0f, FloatMath.ToRadians(-90.0f), 0.0f); List <AnimationChannel> CreateChannels(List <Node> nodes, AnimationSampler sampler0, AnimationSampler sampler1) { return(new List <AnimationChannel> { new AnimationChannel { Target = new AnimationChannelTarget { Node = nodes[0], }, Sampler = sampler0 }, new AnimationChannel { Target = new AnimationChannelTarget { Node = nodes[1], }, Sampler = sampler1 }, }); } void SetAnimationPaths(List <AnimationChannel> channels, AnimationChannelTargetPath path, List <Property> properties) { foreach (var channel in channels) { channel.Target.Path = path; } } void OffsetPositions(List <Node> nodes) { // Offsets the positions of the mesh primitives so they don't overlap. This is done because animation translations override node translations. nodes[0].Mesh.MeshPrimitives.First().Positions.Values = nodes[0].Mesh.MeshPrimitives.First().Positions.Values.Select(position => { return(new Vector3(position.X - 0.6f, position.Y, position.Z)); }); nodes[1].Mesh.MeshPrimitives.First().Positions.Values = nodes[1].Mesh.MeshPrimitives.First().Positions.Values.Select(position => { return(new Vector3(position.X + 0.6f, position.Y, position.Z)); }); } void SetTexture(List <Node> nodes) { nodes[0].Mesh.MeshPrimitives.First().Material = new Runtime.Material { PbrMetallicRoughness = new PbrMetallicRoughness { BaseColorTexture = new TextureInfo { Texture = baseColorTextureA } } }; nodes[1].Mesh.MeshPrimitives.First().Material = new Runtime.Material { PbrMetallicRoughness = new PbrMetallicRoughness { BaseColorTexture = new TextureInfo { Texture = baseColorTextureB } } }; nodes[0].Mesh.MeshPrimitives.First().TexCoords0 = Data.Create(MeshPrimitive.GetSinglePlaneTexCoords()); nodes[1].Mesh.MeshPrimitives.First().TexCoords0 = Data.Create(MeshPrimitive.GetSinglePlaneTexCoords()); } Models = new List <Model> { CreateModel((properties, animation, nodes) => { SetTexture(nodes); OffsetPositions(nodes); var sampler0 = new AnimationSampler { Interpolation = AnimationSamplerInterpolation.Linear, Input = Data.Create(samplerInputLinear), Output = Data.Create(samplerOutputRotation), }; var sampler1 = new AnimationSampler { Interpolation = AnimationSamplerInterpolation.Linear, Input = Data.Create(samplerInputLinear, DataSparse.Create ( DataType.UnsignedByte, new Dictionary <int, float> { { 1, samplerInputSparse } } )), Output = Data.Create(samplerOutputRotation), }; var channels = CreateChannels(nodes, sampler0, sampler1); animation.Channels = channels; SetAnimationPaths(channels, AnimationChannelTargetPath.Rotation, properties); properties.Add(new Property(PropertyName.SparseAccessor, "Input")); properties.Add(new Property(PropertyName.IndicesType, sampler1.Input.Sparse.IndicesOutputType.ToReadmeString())); properties.Add(new Property(PropertyName.ValueType, sampler1.Input.OutputType.ToReadmeString())); properties.Add(new Property(PropertyName.BufferView, ":white_check_mark:")); properties.Add(new Property(PropertyName.Description, "See Figure 1")); }), CreateModel((properties, animation, nodes) => { SetTexture(nodes); OffsetPositions(nodes); var sampler0 = new AnimationSampler { Interpolation = AnimationSamplerInterpolation.Linear, Input = Data.Create(samplerInputLinear), Output = Data.Create(samplerOutputRotation), }; var sampler1 = new AnimationSampler { Interpolation = AnimationSamplerInterpolation.Linear, Input = Data.Create(samplerInputLinear, DataSparse.Create ( DataType.UnsignedShort, new Dictionary <int, float> { { 1, samplerInputSparse } } )), Output = Data.Create(samplerOutputRotation), }; var channels = CreateChannels(nodes, sampler0, sampler1); animation.Channels = channels; SetAnimationPaths(channels, AnimationChannelTargetPath.Rotation, properties); properties.Add(new Property(PropertyName.SparseAccessor, "Input")); properties.Add(new Property(PropertyName.IndicesType, sampler1.Input.Sparse.IndicesOutputType.ToReadmeString())); properties.Add(new Property(PropertyName.ValueType, sampler1.Input.OutputType.ToReadmeString())); properties.Add(new Property(PropertyName.BufferView, ":white_check_mark:")); properties.Add(new Property(PropertyName.Description, "See Figure 1")); }), CreateModel((properties, animation, nodes) => { SetTexture(nodes); OffsetPositions(nodes); var sampler0 = new AnimationSampler { Interpolation = AnimationSamplerInterpolation.Linear, Input = Data.Create(samplerInputLinear), Output = Data.Create(samplerOutputRotation), }; var sampler1 = new AnimationSampler { Interpolation = AnimationSamplerInterpolation.Linear, Input = Data.Create(samplerInputLinear, DataSparse.Create ( DataType.UnsignedInt, new Dictionary <int, float> { { 1, samplerInputSparse } } )), Output = Data.Create(samplerOutputRotation), }; var channels = CreateChannels(nodes, sampler0, sampler1); animation.Channels = channels; SetAnimationPaths(channels, AnimationChannelTargetPath.Rotation, properties); properties.Add(new Property(PropertyName.SparseAccessor, "Input")); properties.Add(new Property(PropertyName.IndicesType, sampler1.Input.Sparse.IndicesOutputType.ToReadmeString())); properties.Add(new Property(PropertyName.ValueType, sampler1.Input.OutputType.ToReadmeString())); properties.Add(new Property(PropertyName.BufferView, ":white_check_mark:")); properties.Add(new Property(PropertyName.Description, "See Figure 1")); }), CreateModel((properties, animation, nodes) => { SetTexture(nodes); OffsetPositions(nodes); var sampler0 = new AnimationSampler { Interpolation = AnimationSamplerInterpolation.Linear, Input = Data.Create(samplerInputLinear), Output = Data.Create(samplerOutputRotation, DataType.NormalizedByte), }; var sampler1 = new AnimationSampler { Interpolation = AnimationSamplerInterpolation.Linear, Input = Data.Create(samplerInputLinear), Output = Data.Create(samplerOutputRotation, DataType.NormalizedByte, DataSparse.Create ( DataType.UnsignedByte, new Dictionary <int, Quaternion> { { 1, samplerOutputRotationSparse } } )), }; var channels = CreateChannels(nodes, sampler0, sampler1); animation.Channels = channels; SetAnimationPaths(channels, AnimationChannelTargetPath.Rotation, properties); properties.Add(new Property(PropertyName.SparseAccessor, "Output")); properties.Add(new Property(PropertyName.IndicesType, ((Data <Quaternion>)sampler1.Output).Sparse.IndicesOutputType.ToReadmeString())); properties.Add(new Property(PropertyName.ValueType, sampler1.Output.OutputType.ToReadmeString())); properties.Add(new Property(PropertyName.BufferView, ":white_check_mark:")); properties.Add(new Property(PropertyName.Description, "See Figure 2")); }), CreateModel((properties, animation, nodes) => { SetTexture(nodes); OffsetPositions(nodes); var sampler0 = new AnimationSampler { Interpolation = AnimationSamplerInterpolation.Linear, Input = Data.Create(samplerInputLinear), Output = Data.Create(samplerOutputRotation, DataType.NormalizedShort), }; var sampler1 = new AnimationSampler { Interpolation = AnimationSamplerInterpolation.Linear, Input = Data.Create(samplerInputLinear), Output = Data.Create(samplerOutputRotation, DataType.NormalizedShort, DataSparse.Create ( DataType.UnsignedByte, new Dictionary <int, Quaternion> { { 1, samplerOutputRotationSparse } } )), }; var channels = CreateChannels(nodes, sampler0, sampler1); animation.Channels = channels; SetAnimationPaths(channels, AnimationChannelTargetPath.Rotation, properties); properties.Add(new Property(PropertyName.SparseAccessor, "Output")); properties.Add(new Property(PropertyName.IndicesType, ((Data <Quaternion>)sampler1.Output).Sparse.IndicesOutputType.ToReadmeString())); properties.Add(new Property(PropertyName.ValueType, sampler1.Output.OutputType.ToReadmeString())); properties.Add(new Property(PropertyName.BufferView, ":white_check_mark:")); properties.Add(new Property(PropertyName.Description, "See Figure 2")); }), CreateModel((properties, animation, nodes) => { // Add extra vertexes that will be used by the sparse accessor. SetTexture(nodes); var positions = MeshPrimitive.GetSinglePlanePositions().Concat(new[] { new Vector3(0.25f, -0.5f, 0.0f), new Vector3(-0.25f, 0.5f, 0.0f), }); var texCoords = MeshPrimitive.GetSinglePlaneTexCoords().Concat(new[] { new Vector2(1.0f, 1.0f), new Vector2(0.0f, 0.0f), }); foreach (var node in nodes) { node.Mesh.MeshPrimitives.First().Positions.Values = positions; node.Mesh.MeshPrimitives.First().TexCoords0.Values = texCoords; } OffsetPositions(nodes); var meshPrimitiveIndices = nodes[1].Mesh.MeshPrimitives.First().Indices; meshPrimitiveIndices.Values = nodes[0].Mesh.MeshPrimitives.First().Indices.Values; meshPrimitiveIndices.Sparse = DataSparse.Create ( DataType.UnsignedByte, new Dictionary <int, int> { { 1, 4 }, { 5, 5 }, } ); properties.Add(new Property(PropertyName.SparseAccessor, "Mesh Primitive Indices")); properties.Add(new Property(PropertyName.IndicesType, meshPrimitiveIndices.Sparse.IndicesOutputType.ToReadmeString())); properties.Add(new Property(PropertyName.ValueType, meshPrimitiveIndices.OutputType.ToReadmeString())); properties.Add(new Property(PropertyName.BufferView, ":white_check_mark:")); properties.Add(new Property(PropertyName.Description, "See the description for the Mesh Primitive Indices model in [Accessor_Sparse](../Accessor_Sparse/README.md).")); }), CreateModel((properties, animation, nodes) => { SetTexture(nodes); nodes.RemoveAt(0); var sampler = new AnimationSampler { Interpolation = AnimationSamplerInterpolation.Linear, Input = Data.Create(samplerInputLinear), Output = Data.Create(Enumerable.Repeat(default(Vector3), 3), DataSparse.Create ( DataType.UnsignedByte, new Dictionary <int, Vector3> { { 1, samplerOutputTranslationSparse } } )), }; var channels = new List <AnimationChannel> { new AnimationChannel { Target = new AnimationChannelTarget { Node = nodes[0], Path = AnimationChannelTargetPath.Translation }, Sampler = sampler }, }; animation.Channels = channels; properties.Add(new Property(PropertyName.SparseAccessor, "Output")); properties.Add(new Property(PropertyName.IndicesType, ((Data <Vector3>)sampler.Output).Sparse.IndicesOutputType.ToReadmeString())); properties.Add(new Property(PropertyName.ValueType, ((Data <Vector3>)sampler.Output).OutputType.ToReadmeString())); properties.Add(new Property(PropertyName.BufferView, "")); properties.Add(new Property(PropertyName.Description, "See Figure 3")); }), }; GenerateUsedPropertiesList(); }
public Buffer_Interleaved(List <string> imageList) { var baseColorTextureImage = UseTexture(imageList, "BaseColor_Grey"); // Track the common properties for use in the readme. CommonProperties.Add(new Property(PropertyName.BaseColorTexture, baseColorTextureImage)); Model CreateModel(Action <List <Property>, Runtime.MeshPrimitive> setProperties) { var properties = new List <Property>(); var meshPrimitive = MeshPrimitive.CreateSinglePlane(); // Apply the common properties to the gltf. meshPrimitive.Interleave = true; meshPrimitive.Colors = new[] { new Vector4(0.0f, 1.0f, 0.0f, 0.2f), new Vector4(1.0f, 0.0f, 0.0f, 0.2f), new Vector4(1.0f, 1.0f, 0.0f, 0.2f), new Vector4(0.0f, 0.0f, 1.0f, 0.2f) }; meshPrimitive.Material = new Runtime.Material() { MetallicRoughnessMaterial = new Runtime.PbrMetallicRoughness() { BaseColorTexture = new Runtime.Texture() { Source = baseColorTextureImage, Sampler = new Runtime.Sampler(), }, }, }; // Apply the properties that are specific to this gltf. setProperties(properties, meshPrimitive); // Create the gltf object return(new Model { Properties = properties, GLTF = CreateGLTF(() => new Runtime.Scene() { Nodes = new[] { new Runtime.Node { Mesh = new Runtime.Mesh { MeshPrimitives = new[] { meshPrimitive } }, }, }, }), }); } void SetUvTypeFloat(List <Property> properties, Runtime.MeshPrimitive meshPrimitive) { meshPrimitive.TextureCoordsComponentType = Runtime.MeshPrimitive.TextureCoordsComponentTypeEnum.FLOAT; properties.Add(new Property(PropertyName.VertexUV0, "Float")); } void SetUvTypeTypeByte(List <Property> properties, Runtime.MeshPrimitive meshPrimitive) { meshPrimitive.TextureCoordsComponentType = Runtime.MeshPrimitive.TextureCoordsComponentTypeEnum.NORMALIZED_UBYTE; properties.Add(new Property(PropertyName.VertexUV0, "Byte")); } void SetUvTypeTypeShort(List <Property> properties, Runtime.MeshPrimitive meshPrimitive) { meshPrimitive.TextureCoordsComponentType = Runtime.MeshPrimitive.TextureCoordsComponentTypeEnum.NORMALIZED_USHORT; properties.Add(new Property(PropertyName.VertexUV0, "Short")); } void SetColorTypeFloat(List <Property> properties, Runtime.MeshPrimitive meshPrimitive) { meshPrimitive.ColorComponentType = Runtime.MeshPrimitive.ColorComponentTypeEnum.FLOAT; meshPrimitive.ColorType = Runtime.MeshPrimitive.ColorTypeEnum.VEC3; properties.Add(new Property(PropertyName.VertexColor, "Vector3 Float")); } void SetColorTypeByte(List <Property> properties, Runtime.MeshPrimitive meshPrimitive) { meshPrimitive.ColorComponentType = Runtime.MeshPrimitive.ColorComponentTypeEnum.NORMALIZED_UBYTE; meshPrimitive.ColorType = Runtime.MeshPrimitive.ColorTypeEnum.VEC3; properties.Add(new Property(PropertyName.VertexColor, "Vector3 Byte")); } void SetColorTypeShort(List <Property> properties, Runtime.MeshPrimitive meshPrimitive) { meshPrimitive.ColorComponentType = Runtime.MeshPrimitive.ColorComponentTypeEnum.NORMALIZED_USHORT; meshPrimitive.ColorType = Runtime.MeshPrimitive.ColorTypeEnum.VEC3; properties.Add(new Property(PropertyName.VertexColor, "Vector3 Short")); } this.Models = new List <Model> { CreateModel((properties, meshPrimitive) => { SetUvTypeFloat(properties, meshPrimitive); SetColorTypeFloat(properties, meshPrimitive); }), CreateModel((properties, meshPrimitive) => { SetUvTypeFloat(properties, meshPrimitive); SetColorTypeByte(properties, meshPrimitive); }), CreateModel((properties, meshPrimitive) => { SetUvTypeFloat(properties, meshPrimitive); SetColorTypeShort(properties, meshPrimitive); }), CreateModel((properties, meshPrimitive) => { SetUvTypeTypeByte(properties, meshPrimitive); SetColorTypeFloat(properties, meshPrimitive); }), CreateModel((properties, meshPrimitive) => { SetUvTypeTypeShort(properties, meshPrimitive); SetColorTypeFloat(properties, meshPrimitive); }), }; GenerateUsedPropertiesList(); }
internal static int AddLineLoop(this Gltf gltf, string name, List <byte> buffer, List <BufferView> bufferViews, List <Accessor> accessors, byte[] vertices, byte[] indices, double[] vMin, double[] vMax, ushort iMin, ushort iMax, int materialId, MeshPrimitive.ModeEnum mode, List <glTFLoader.Schema.Mesh> meshes, List <glTFLoader.Schema.Node> nodes, Transform transform = null) { var m = new glTFLoader.Schema.Mesh(); m.Name = name; var vBuff = AddBufferView(bufferViews, 0, buffer.Count, vertices.Length, null, null); var iBuff = AddBufferView(bufferViews, 0, buffer.Count + vertices.Length, indices.Length, null, null); buffer.AddRange(vertices); buffer.AddRange(indices); while (buffer.Count % 4 != 0) { // Console.WriteLine("Padding..."); buffer.Add(0); } var vAccess = AddAccessor(accessors, vBuff, 0, Accessor.ComponentTypeEnum.FLOAT, vertices.Length / sizeof(float) / 3, new[] { (float)vMin[0], (float)vMin[1], (float)vMin[2] }, new[] { (float)vMax[0], (float)vMax[1], (float)vMax[2] }, Accessor.TypeEnum.VEC3); var iAccess = AddAccessor(accessors, iBuff, 0, Accessor.ComponentTypeEnum.UNSIGNED_SHORT, indices.Length / sizeof(ushort), new[] { (float)iMin }, new[] { (float)iMax }, Accessor.TypeEnum.SCALAR); var prim = new MeshPrimitive(); prim.Indices = iAccess; prim.Material = materialId; prim.Mode = mode; prim.Attributes = new Dictionary <string, int> { { "POSITION", vAccess } }; m.Primitives = new[] { prim }; // Add mesh to gltf meshes.Add(m); var parentId = 0; if (transform != null) { var a = transform.XAxis; var b = transform.YAxis; var c = transform.ZAxis; var transNode = new Node(); transNode.Matrix = new[] { (float)a.X, (float)a.Y, (float)a.Z, 0.0f, (float)b.X, (float)b.Y, (float)b.Z, 0.0f, (float)c.X, (float)c.Y, (float)c.Z, 0.0f, (float)transform.Origin.X, (float)transform.Origin.Y, (float)transform.Origin.Z, 1.0f }; parentId = gltf.AddNode(nodes, transNode, 0); } // Add mesh node to gltf var node = new Node(); node.Mesh = meshes.Count - 1; gltf.AddNode(nodes, node, parentId); return(meshes.Count - 1); }
internal static int AddTriangleMesh(this Gltf gltf, string name, List <byte> buffer, List <BufferView> bufferViews, List <Accessor> accessors, byte[] vertices, byte[] normals, byte[] indices, byte[] colors, byte[] uvs, double[] vMin, double[] vMax, double[] nMin, double[] nMax, ushort iMin, ushort iMax, double[] uvMin, double[] uvMax, int materialId, float[] cMin, float[] cMax, int?parent_index, List <glTFLoader.Schema.Mesh> meshes) { var m = new glTFLoader.Schema.Mesh(); m.Name = name; var vBuff = AddBufferView(bufferViews, 0, buffer.Count, vertices.Length, null, null); buffer.AddRange(vertices); var nBuff = AddBufferView(bufferViews, 0, buffer.Count, normals.Length, null, null); buffer.AddRange(normals); var iBuff = AddBufferView(bufferViews, 0, buffer.Count, indices.Length, null, null); buffer.AddRange(indices); while (buffer.Count % 4 != 0) { // Console.WriteLine("Padding..."); buffer.Add(0); } var vAccess = AddAccessor(accessors, vBuff, 0, Accessor.ComponentTypeEnum.FLOAT, vertices.Length / sizeof(float) / 3, new[] { (float)vMin[0], (float)vMin[1], (float)vMin[2] }, new[] { (float)vMax[0], (float)vMax[1], (float)vMax[2] }, Accessor.TypeEnum.VEC3); var nAccess = AddAccessor(accessors, nBuff, 0, Accessor.ComponentTypeEnum.FLOAT, normals.Length / sizeof(float) / 3, new[] { (float)nMin[0], (float)nMin[1], (float)nMin[2] }, new[] { (float)nMax[0], (float)nMax[1], (float)nMax[2] }, Accessor.TypeEnum.VEC3); var iAccess = AddAccessor(accessors, iBuff, 0, Accessor.ComponentTypeEnum.UNSIGNED_SHORT, indices.Length / sizeof(ushort), new[] { (float)iMin }, new[] { (float)iMax }, Accessor.TypeEnum.SCALAR); var prim = new MeshPrimitive(); prim.Indices = iAccess; prim.Material = materialId; prim.Mode = MeshPrimitive.ModeEnum.TRIANGLES; prim.Attributes = new Dictionary <string, int> { { "NORMAL", nAccess }, { "POSITION", vAccess } }; if (uvs.Length > 0) { var uvBuff = AddBufferView(bufferViews, 0, buffer.Count, uvs.Length, null, null); buffer.AddRange(uvs); var uvAccess = AddAccessor(accessors, uvBuff, 0, Accessor.ComponentTypeEnum.FLOAT, uvs.Length / sizeof(float) / 2, new[] { (float)uvMin[0], (float)uvMin[1] }, new[] { (float)uvMax[0], (float)uvMax[1] }, Accessor.TypeEnum.VEC2); prim.Attributes.Add("TEXCOORD_0", uvAccess); } // TODO: Add to the buffer above instead of inside this block. // There's a chance the padding operation will put padding before // the color information. if (colors.Length > 0) { var cBuff = AddBufferView(bufferViews, 0, buffer.Count, colors.Length, null, null); buffer.AddRange(colors); var cAccess = AddAccessor(accessors, cBuff, 0, Accessor.ComponentTypeEnum.FLOAT, colors.Length / sizeof(float) / 3, cMin, cMax, Accessor.TypeEnum.VEC3); prim.Attributes.Add("COLOR_0", cAccess); } m.Primitives = new[] { prim }; // Add mesh to gltf meshes.Add(m); return(meshes.Count - 1); }
public Animation_Node(List <string> imageList) { Runtime.Image baseColorTextureImage = 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 <Runtime.AnimationChannel>, Runtime.Node> setProperties) { var properties = new List <Property>(); var cubeMeshPrimitive = MeshPrimitive.CreateCube(); // Apply the common properties to the gltf. cubeMeshPrimitive.Material = new Runtime.Material { MetallicRoughnessMaterial = new Runtime.PbrMetallicRoughness { BaseColorTexture = new Runtime.Texture { Source = baseColorTextureImage }, }, }; var channels = new List <Runtime.AnimationChannel> { new Runtime.AnimationChannel() }; var node = new Runtime.Node(); // Apply the properties that are specific to this gltf. setProperties(properties, channels, node); // Create the gltf object. node.Mesh = new Runtime.Mesh { MeshPrimitives = new[] { cubeMeshPrimitive } }; Runtime.GLTF gltf = CreateGLTF(() => new Runtime.Scene() { Nodes = new[] { node }, }); gltf.Animations = new[] { new Runtime.Animation { Channels = channels } }; return(new Model { Properties = properties, GLTF = gltf, Animated = true, }); } void SetTranslationChannelTarget(List <Property> properties, Runtime.AnimationChannel channel, Runtime.Node node) { channel.Target = new Runtime.AnimationChannelTarget { Node = node, Path = Runtime.AnimationChannelTarget.PathEnum.TRANSLATION, }; properties.Add(new Property(PropertyName.Target, "Translation")); } void SetRotationChannelTarget(List <Property> properties, Runtime.AnimationChannel channel, Runtime.Node node) { channel.Target = new Runtime.AnimationChannelTarget { Node = node, Path = Runtime.AnimationChannelTarget.PathEnum.ROTATION, }; properties.Add(new Property(PropertyName.Target, "Rotation")); } void SetScaleChannelTarget(List <Property> properties, Runtime.AnimationChannel channel, Runtime.Node node) { channel.Target = new Runtime.AnimationChannelTarget { Node = node, Path = Runtime.AnimationChannelTarget.PathEnum.SCALE, }; properties.Add(new Property(PropertyName.Target, "Scale")); } void SetLinearSamplerForTranslation(List <Property> properties, Runtime.AnimationChannel channel) { channel.Sampler = new Runtime.LinearAnimationSampler <Vector3> ( new[] { 0.0f, 1.0f, 2.0f, }, 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), } ); properties.Add(new Property(PropertyName.Interpolation, "Linear")); } void SetLinearSamplerForScale(List <Property> properties, Runtime.AnimationChannel channel) { channel.Sampler = new Runtime.LinearAnimationSampler <Vector3> ( new[] { 0.0f, 1.0f, 2.0f, }, new[] { new Vector3(0.8f, 0.8f, 0.8f), new Vector3(1.2f, 1.2f, 1.2f), new Vector3(0.8f, 0.8f, 0.8f), } ); properties.Add(new Property(PropertyName.Interpolation, "Linear")); } void SetLinearSamplerForRotation(List <Property> properties, Runtime.AnimationChannel channel) { channel.Sampler = new Runtime.LinearAnimationSampler <Quaternion> ( new[] { 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, }, 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), } ); properties.Add(new Property(PropertyName.Interpolation, "Linear")); } void SetStepSamplerForTranslation(List <Property> properties, Runtime.AnimationChannel channel) { channel.Sampler = new Runtime.StepAnimationSampler <Vector3> ( new[] { 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, }, new[] { new Vector3(-0.1f, 0.0f, 0.0f), new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.1f, 0.0f, 0.0f), new Vector3(0.0f, 0.0f, 0.0f), new Vector3(-0.1f, 0.0f, 0.0f), } ); properties.Add(new Property(PropertyName.Interpolation, "Step")); } void SetCubicSplineSamplerForTranslation(List <Property> properties, Runtime.AnimationChannel channel) { channel.Sampler = new Runtime.CubicSplineAnimationSampler <Vector3> ( new[] { 0.0f, 1.0f, 2.0f, }, new[] { new Runtime.CubicSplineAnimationSampler <Vector3> .Key { InTangent = new Vector3(0.0f, 0.0f, 0.0f), Value = new Vector3(-0.1f, 0.0f, 0.0f), OutTangent = new Vector3(0.0f, 0.0f, 0.0f) }, new Runtime.CubicSplineAnimationSampler <Vector3> .Key { InTangent = new Vector3(0.0f, 0.0f, 0.0f), Value = new Vector3(0.1f, 0.0f, 0.0f), OutTangent = new Vector3(0.0f, -0.3f, 0.0f) }, new Runtime.CubicSplineAnimationSampler <Vector3> .Key { InTangent = new Vector3(0.0f, 0.0f, 0.0f), Value = new Vector3(-0.1f, 0.0f, 0.0f), OutTangent = new Vector3(0.0f, 0.0f, 0.0f) } } ); properties.Add(new Property(PropertyName.Interpolation, "Cubic Spline")); } void CreateCubicSplineSamplerForRotation(List <Property> properties, Runtime.AnimationChannel channel) { channel.Sampler = new Runtime.CubicSplineAnimationSampler <Quaternion> ( new[] { 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, }, new[] { new Runtime.CubicSplineAnimationSampler <Quaternion> .Key { InTangent = new Quaternion(0.0f, 0.0f, 0.0f, 0.0f), Value = Quaternion.CreateFromYawPitchRoll(FloatMath.ToRadians(90.0f), 0.0f, 0.0f), OutTangent = new Quaternion(0.0f, 0.0f, 0.0f, 0.0f) }, new Runtime.CubicSplineAnimationSampler <Quaternion> .Key { InTangent = new Quaternion(0.0f, 0.0f, 0.0f, 0.0f), Value = Quaternion.Identity, OutTangent = new Quaternion(0.0f, 0.0f, 0.0f, 0.0f) }, new Runtime.CubicSplineAnimationSampler <Quaternion> .Key { InTangent = new Quaternion(0.0f, 0.0f, 0.0f, 0.0f), Value = Quaternion.CreateFromYawPitchRoll(FloatMath.ToRadians(-90.0f), 0.0f, 0.0f), OutTangent = new Quaternion(0.0f, 0.0f, 0.0f, 0.0f) }, new Runtime.CubicSplineAnimationSampler <Quaternion> .Key { InTangent = new Quaternion(0.0f, 0.0f, 0.0f, 0.0f), Value = Quaternion.Identity, OutTangent = new Quaternion(0.0f, 0.0f, 0.0f, 0.0f) }, new Runtime.CubicSplineAnimationSampler <Quaternion> .Key { InTangent = new Quaternion(0.0f, 0.0f, 0.0f, 0.0f), Value = Quaternion.CreateFromYawPitchRoll(FloatMath.ToRadians(90.0f), 0.0f, 0.0f), OutTangent = new Quaternion(0.0f, 0.0f, 0.0f, 0.0f) }, } ); properties.Add(new Property(PropertyName.Interpolation, "Cubic Spline")); } Models = new List <Model> { CreateModel((properties, channels, node) => { SetTranslationChannelTarget(properties, channels[0], node); SetLinearSamplerForTranslation(properties, channels[0]); }), CreateModel((properties, channels, node) => { SetRotationChannelTarget(properties, channels[0], node); SetLinearSamplerForRotation(properties, channels[0]); }), CreateModel((properties, channels, node) => { SetScaleChannelTarget(properties, channels[0], node); SetLinearSamplerForScale(properties, channels[0]); }), CreateModel((properties, channels, node) => { SetTranslationChannelTarget(properties, channels[0], node); SetStepSamplerForTranslation(properties, channels[0]); }), CreateModel((properties, channels, node) => { SetTranslationChannelTarget(properties, channels[0], node); SetCubicSplineSamplerForTranslation(properties, channels[0]); }), CreateModel((properties, channels, node) => { SetRotationChannelTarget(properties, channels[0], node); CreateCubicSplineSamplerForRotation(properties, channels[0]); }), }; GenerateUsedPropertiesList(); }
public Mesh_PrimitivesUV(List <string> imageList) { Runtime.Image baseColorTextureImage = UseTexture(imageList, "BaseColor_Plane"); Runtime.Image normalImage = UseTexture(imageList, "Normal_Plane"); UseFigure(imageList, "Indices_Primitive0"); UseFigure(imageList, "Indices_Primitive1"); UseFigure(imageList, "UVSpace2"); UseFigure(imageList, "UVSpace3"); UseFigure(imageList, "UVSpace4"); UseFigure(imageList, "UVSpace5"); // Track the common properties for use in the readme. var vertexNormalValue = new List <Vector3> { new Vector3(0.0f, 0.0f, 1.0f), new Vector3(0.0f, 0.0f, 1.0f), new Vector3(0.0f, 0.0f, 1.0f), }; var tangentValue = new List <Vector4> { new Vector4(1.0f, 0.0f, 0.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f), }; var vertexColorValue = new List <Vector4> { new Vector4(0.0f, 1.0f, 0.0f, 0.2f), new Vector4(1.0f, 0.0f, 0.0f, 0.2f), new Vector4(0.0f, 0.0f, 1.0f, 0.2f), }; CommonProperties.Add(new Property(PropertyName.VertexNormal, vertexNormalValue.ToReadmeString())); CommonProperties.Add(new Property(PropertyName.VertexTangent, tangentValue.ToReadmeString())); CommonProperties.Add(new Property(PropertyName.VertexColor, vertexColorValue.ToReadmeString())); CommonProperties.Add(new Property(PropertyName.NormalTexture, normalImage.ToReadmeString())); CommonProperties.Add(new Property(PropertyName.BaseColorTexture, baseColorTextureImage.ToReadmeString())); Model CreateModel(Action <List <Property>, Runtime.MeshPrimitive, Runtime.MeshPrimitive> setProperties) { var properties = new List <Property>(); List <Runtime.MeshPrimitive> meshPrimitives = MeshPrimitive.CreateMultiPrimitivePlane(); // Apply the common properties to the gltf. foreach (var meshPrimitive in meshPrimitives) { meshPrimitive.TextureCoordSets = new List <List <Vector2> >(); meshPrimitive.Material = new Runtime.Material { MetallicRoughnessMaterial = new Runtime.PbrMetallicRoughness { MetallicFactor = 0 } }; } // Apply the properties that are specific to this gltf. setProperties(properties, meshPrimitives[0], meshPrimitives[1]); // Create the gltf object return(new Model { Properties = properties, GLTF = CreateGLTF(() => new Runtime.Scene { Nodes = new List <Runtime.Node> { new Runtime.Node { Mesh = new Runtime.Mesh { MeshPrimitives = meshPrimitives }, }, }, }), }); } void SetCommonProperties(Runtime.MeshPrimitive meshPrimitive) { meshPrimitive.Normals = vertexNormalValue; meshPrimitive.Tangents = tangentValue; meshPrimitive.Colors = vertexColorValue; meshPrimitive.Material.NormalTexture = new Runtime.Texture { Source = normalImage }; meshPrimitive.Material.MetallicRoughnessMaterial.BaseColorTexture = new Runtime.Texture() { Source = baseColorTextureImage }; } void SetNullUV(Runtime.MeshPrimitive meshPrimitive) { meshPrimitive.Material = null; meshPrimitive.TextureCoordSets = null; } void SetPrimitiveZeroVertexUVZero(List <Property> properties, Runtime.MeshPrimitive meshPrimitive) { SetCommonProperties(meshPrimitive); meshPrimitive.TextureCoordSets = meshPrimitive.TextureCoordSets.Concat( new[] { new[] { new Vector2(0.0f, 1.0f), new Vector2(1.0f, 0.0f), new Vector2(0.0f, 0.0f), } }); properties.Add(new Property(PropertyName.Primitive0VertexUV0, ":white_check_mark:")); } void SetPrimitiveOneVertexUVZero(List <Property> properties, Runtime.MeshPrimitive meshPrimitive) { SetCommonProperties(meshPrimitive); meshPrimitive.TextureCoordSets = meshPrimitive.TextureCoordSets.Concat( new[] { new[] { new Vector2(0.0f, 1.0f), new Vector2(1.0f, 1.0f), new Vector2(1.0f, 0.0f), } }); properties.Add(new Property(PropertyName.Primitive1VertexUV0, ":white_check_mark:")); } void SetPrimitiveZeroVertexUVOne(List <Property> properties, Runtime.MeshPrimitive meshPrimitive) { SetCommonProperties(meshPrimitive); meshPrimitive.Material.MetallicRoughnessMaterial.BaseColorTexture.TexCoordIndex = 1; meshPrimitive.Material.NormalTexture.TexCoordIndex = 1; meshPrimitive.TextureCoordSets = meshPrimitive.TextureCoordSets.Concat( new[] { new[] { new Vector2(0.5f, 0.5f), new Vector2(1.0f, 0.0f), new Vector2(0.5f, 0.0f), } }); properties.Add(new Property(PropertyName.Primitive0VertexUV1, ":white_check_mark:")); } void SetPrimitiveOneVertexUVOne(List <Property> properties, Runtime.MeshPrimitive meshPrimitive) { SetCommonProperties(meshPrimitive); meshPrimitive.Material.MetallicRoughnessMaterial.BaseColorTexture.TexCoordIndex = 1; meshPrimitive.Material.NormalTexture.TexCoordIndex = 1; meshPrimitive.TextureCoordSets = meshPrimitive.TextureCoordSets.Concat( new[] { new[] { new Vector2(0.5f, 0.5f), new Vector2(1.0f, 0.5f), new Vector2(1.0f, 0.0f), } }); properties.Add(new Property(PropertyName.Primitive1VertexUV1, ":white_check_mark:")); } Models = new List <Model> { CreateModel((properties, meshPrimitiveZero, meshPrimitiveOne) => { SetNullUV(meshPrimitiveZero); SetNullUV(meshPrimitiveOne); }), CreateModel((properties, meshPrimitiveZero, meshPrimitiveOne) => { SetPrimitiveZeroVertexUVZero(properties, meshPrimitiveZero); SetNullUV(meshPrimitiveOne); }), CreateModel((properties, meshPrimitiveZero, meshPrimitiveOne) => { SetPrimitiveOneVertexUVZero(properties, meshPrimitiveOne); SetNullUV(meshPrimitiveZero); }), CreateModel((properties, meshPrimitiveZero, meshPrimitiveOne) => { SetPrimitiveZeroVertexUVZero(properties, meshPrimitiveZero); SetPrimitiveOneVertexUVZero(properties, meshPrimitiveOne); }), CreateModel((properties, meshPrimitiveZero, meshPrimitiveOne) => { SetPrimitiveZeroVertexUVZero(properties, meshPrimitiveZero); SetPrimitiveZeroVertexUVOne(properties, meshPrimitiveZero); SetNullUV(meshPrimitiveOne); }), CreateModel((properties, meshPrimitiveZero, meshPrimitiveOne) => { SetPrimitiveOneVertexUVZero(properties, meshPrimitiveOne); SetPrimitiveOneVertexUVOne(properties, meshPrimitiveOne); SetNullUV(meshPrimitiveZero); }), CreateModel((properties, meshPrimitiveZero, meshPrimitiveOne) => { SetPrimitiveZeroVertexUVZero(properties, meshPrimitiveZero); SetPrimitiveOneVertexUVZero(properties, meshPrimitiveOne); SetPrimitiveOneVertexUVOne(properties, meshPrimitiveOne); }), CreateModel((properties, meshPrimitiveZero, meshPrimitiveOne) => { SetPrimitiveZeroVertexUVZero(properties, meshPrimitiveZero); SetPrimitiveOneVertexUVZero(properties, meshPrimitiveOne); SetPrimitiveZeroVertexUVOne(properties, meshPrimitiveZero); }), CreateModel((properties, meshPrimitiveZero, meshPrimitiveOne) => { SetPrimitiveZeroVertexUVZero(properties, meshPrimitiveZero); SetPrimitiveOneVertexUVZero(properties, meshPrimitiveOne); SetPrimitiveZeroVertexUVOne(properties, meshPrimitiveZero); SetPrimitiveOneVertexUVOne(properties, meshPrimitiveOne); }), }; GenerateUsedPropertiesList(); }
public MeshPrimitive GenerateTriangleMesh(List <Vector3> positions, List <int> indices, IEnumerable <Vector4> colors = null, PBRTexture texture = null) { MeshPrimitive mesh = null; try { if (positions == null || !positions.Any()) { _logger?.LogWarning("Vertex list is empty."); } else { if (colors == null) { colors = positions.Select(pt => Vector4.One); } // Basic mesh declaration mesh = new MeshPrimitive() { Colors = colors , ColorComponentType = MeshPrimitive.ColorComponentTypeEnum.FLOAT , ColorType = MeshPrimitive.ColorTypeEnum.VEC3 , Mode = MeshPrimitive.ModeEnum.TRIANGLES , Positions = positions , Material = new Material() { DoubleSided = true } , Indices = indices }; //The number of the vertices int nV = positions.Count; //The number of the triangles int nT = indices.Count / 3; Vector3[] norm = new Vector3[nV]; //Array for the normals //Scan all the triangles. For each triangle add its //normal to norm's vectors of triangle's vertices Vector3 min = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue); Vector3 max = new Vector3(float.MinValue, float.MinValue, float.MinValue); for (int t = 0; t < nT; t++) { //Get indices of the triangle t int i1 = indices[3 * t]; int i2 = indices[3 * t + 1]; int i3 = indices[3 * t + 2]; //Get vertices of the triangle Vector3 v1 = positions[i1]; Vector3 v2 = positions[i2]; Vector3 v3 = positions[i3]; //Compute the triangle's normal Vector3 dir = Vector3.Normalize(Vector3.Cross(v2 - v1, v3 - v1)); //Accumulate it to norm array for i1, i2, i3 norm[i1] += dir; norm[i2] += dir; norm[i3] += dir; } for (int i = 0; i < nV; i++) { //Normalize the normal's length norm[i] = Vector3.Normalize(norm[i]); // Calculate bounds of UV mapping Vector3 pos = positions[i]; // for UV coords min.X = Math.Min(pos.X, min.X); min.Y = Math.Min(pos.Y, min.Y); min.Z = Math.Min(pos.Z, min.Z); max.X = Math.Max(pos.X, max.X); max.Y = Math.Max(pos.Y, max.Y); max.Z = Math.Max(pos.Z, max.Z); } mesh.Normals = norm; if (texture != null) { mesh.TextureCoordsComponentType = MeshPrimitive.TextureCoordsComponentTypeEnum.FLOAT; if (texture.TextureCoordSets == null) { mesh.TextureCoordSets = Enumerable.Range(0, 1).Select(i => positions.Select(pos => new Vector2( MathHelper.Map(min.X, max.X, 0, 1, pos.X, true) , MathHelper.Map(min.Z, max.Z, 0, 1, pos.Z, true) ))); } else { mesh.TextureCoordSets = Enumerable.Range(0, 1).Select(i => texture.TextureCoordSets); } mesh.Material.MetallicRoughnessMaterial = new PbrMetallicRoughness() { BaseColorFactor = Vector4.One, BaseColorTexture = GetTextureFromImage(texture.BaseColorTexture.FilePath), MetallicFactor = 0, RoughnessFactor = 1 }; if (texture.NormalTexture != null) { mesh.Material.NormalTexture = GetTextureFromImage(texture.NormalTexture.FilePath); } } } } catch (Exception ex) { _logger?.LogError(ex, ex.ToString()); throw; } return(mesh); }
protected virtual void CreateMeshPrimitive(MeshPrimitive primitive, string meshName, int meshID, int primitiveIndex) { var meshAttributes = BuildMeshAttributes(primitive, meshID, primitiveIndex); var vertexCount = primitive.Attributes[SemanticProperties.POSITION].Value.Count; UnityEngine.Mesh mesh = new UnityEngine.Mesh { vertices = primitive.Attributes.ContainsKey(SemanticProperties.POSITION) ? meshAttributes[SemanticProperties.POSITION].AccessorContent.AsVertices.ToUnityVector3() : null, normals = primitive.Attributes.ContainsKey(SemanticProperties.NORMAL) ? meshAttributes[SemanticProperties.NORMAL].AccessorContent.AsNormals.ToUnityVector3() : null, uv = primitive.Attributes.ContainsKey(SemanticProperties.TexCoord(0)) ? meshAttributes[SemanticProperties.TexCoord(0)].AccessorContent.AsTexcoords.ToUnityVector2() : null, uv2 = primitive.Attributes.ContainsKey(SemanticProperties.TexCoord(1)) ? meshAttributes[SemanticProperties.TexCoord(1)].AccessorContent.AsTexcoords.ToUnityVector2() : null, uv3 = primitive.Attributes.ContainsKey(SemanticProperties.TexCoord(2)) ? meshAttributes[SemanticProperties.TexCoord(2)].AccessorContent.AsTexcoords.ToUnityVector2() : null, uv4 = primitive.Attributes.ContainsKey(SemanticProperties.TexCoord(3)) ? meshAttributes[SemanticProperties.TexCoord(3)].AccessorContent.AsTexcoords.ToUnityVector2() : null, colors = primitive.Attributes.ContainsKey(SemanticProperties.Color(0)) ? meshAttributes[SemanticProperties.Color(0)].AccessorContent.AsColors.ToUnityColor() : null, triangles = primitive.Indices != null ? meshAttributes[SemanticProperties.INDICES].AccessorContent.AsTriangles : MeshPrimitive.GenerateTriangles(vertexCount), tangents = primitive.Attributes.ContainsKey(SemanticProperties.TANGENT) ? meshAttributes[SemanticProperties.TANGENT].AccessorContent.AsTangents.ToUnityVector4(true) : null }; if (primitive.Attributes.ContainsKey(SemanticProperties.JOINT) && primitive.Attributes.ContainsKey(SemanticProperties.WEIGHT)) { Vector4[] bones = new Vector4[1]; Vector4[] weights = new Vector4[1]; LoadSkinnedMeshAttributes(meshID, primitiveIndex, ref bones, ref weights); if (bones.Length != mesh.vertices.Length || weights.Length != mesh.vertices.Length) { Debug.LogError("Not enough skinning data (bones:" + bones.Length + " weights:" + weights.Length + " verts:" + mesh.vertices.Length + ")"); return; } BoneWeight[] bws = new BoneWeight[mesh.vertices.Length]; int maxBonesIndex = 0; for (int i = 0; i < bws.Length; ++i) { // Unity seems expects the the sum of weights to be 1. float[] normalizedWeights = GLTFUtils.normalizeBoneWeights(weights[i]); bws[i].boneIndex0 = (int)bones[i].x; bws[i].weight0 = normalizedWeights[0]; bws[i].boneIndex1 = (int)bones[i].y; bws[i].weight1 = normalizedWeights[1]; bws[i].boneIndex2 = (int)bones[i].z; bws[i].weight2 = normalizedWeights[2]; bws[i].boneIndex3 = (int)bones[i].w; bws[i].weight3 = normalizedWeights[3]; maxBonesIndex = (int)Mathf.Max(maxBonesIndex, bones[i].x, bones[i].y, bones[i].z, bones[i].w); } mesh.boneWeights = bws; // initialize inverseBindMatrix array with identity matrix in order to output a valid mesh object Matrix4x4[] bindposes = new Matrix4x4[maxBonesIndex + 1]; for (int j = 0; j <= maxBonesIndex; ++j) { bindposes[j] = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, Vector3.one); } mesh.bindposes = bindposes; } if (primitive.Targets != null && primitive.Targets.Count > 0) { for (int b = 0; b < primitive.Targets.Count; ++b) { Vector3[] deltaVertices = new Vector3[primitive.Targets[b]["POSITION"].Value.Count]; Vector3[] deltaNormals = new Vector3[primitive.Targets[b]["POSITION"].Value.Count]; Vector3[] deltaTangents = new Vector3[primitive.Targets[b]["POSITION"].Value.Count]; if (primitive.Targets[b].ContainsKey("POSITION")) { NumericArray num = new NumericArray(); deltaVertices = primitive.Targets[b]["POSITION"].Value.AsVector3Array(ref num, _assetCache.BufferCache[0], false).ToUnityVector3(true); } if (primitive.Targets[b].ContainsKey("NORMAL")) { NumericArray num = new NumericArray(); deltaNormals = primitive.Targets[b]["NORMAL"].Value.AsVector3Array(ref num, _assetCache.BufferCache[0], true).ToUnityVector3(true); } //if (primitive.Targets[b].ContainsKey("TANGENT")) //{ // deltaTangents = primitive.Targets[b]["TANGENT"].Value.AsVector3Array(ref num, _assetCache.BufferCache[0], true).ToUnityVector3(true); //} mesh.AddBlendShapeFrame(GLTFUtils.buildBlendShapeName(meshID, b), 1.0f, deltaVertices, deltaNormals, deltaTangents); } } mesh.RecalculateBounds(); mesh.RecalculateTangents(); mesh = _assetManager.saveMesh(mesh, meshName + "_" + meshID + "_" + primitiveIndex); UnityEngine.Material material = primitive.Material != null && primitive.Material.Id >= 0 ? getMaterial(primitive.Material.Id) : defaultMaterial; _assetManager.addPrimitiveMeshData(meshID, primitiveIndex, mesh, material); }
public Buffer_Misc(List <string> imageList) { Model CreateModel(Action <List <Property>, AnimationChannel, Node> setProperties) { var properties = new List <Property>(); // Apply the common properties to the glTF. var node = new Node { Mesh = new Runtime.Mesh { MeshPrimitives = new[] { MeshPrimitive.CreateSinglePlane(includeTextureCoords: false) } }, Scale = new Vector3(0.8f) }; var channel = new AnimationChannel(); // Apply the proerties that are specific to this glTF setProperties(properties, channel, node); // Create the glTF object GLTF gltf = CreateGLTF(() => new Scene { Nodes = new[] { node }, }); gltf.Animations = new[] { new Animation { Channels = new List <AnimationChannel> { channel } } }; return(new Model { Properties = properties, GLTF = gltf, Animated = true, SeparateBuffers = true, }); } void setTranslationChanneltarget(AnimationChannel channel, Node node) { channel.Target = new AnimationChannelTarget { Node = node, Path = AnimationChannelTargetPath.Translation, }; } 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), }), }; } Models = new List <Model> { CreateModel((properties, channel, node) => { setTranslationChanneltarget(channel, node); SetLinearSamplerForTranslation(channel); properties.Add(new Property(PropertyName.Description, "The mesh primitive and animation data are stored in separate buffers.")); }) }; GenerateUsedPropertiesList(); }
public Mesh_PrimitiveAttribute(List <string> imageList) { var baseColorTexture = new Texture { Source = UseTexture(imageList, "BaseColor_Plane") }; var normalTexture = new Texture { Source = UseTexture(imageList, "Normal_Plane") }; // Track the common properties for use in the readme. CommonProperties.Add(new Property(PropertyName.BaseColorTexture, baseColorTexture.Source.ToReadmeString())); Model CreateModel(Action <List <Property>, Runtime.MeshPrimitive> setProperties) { var properties = new List <Property>(); var meshPrimitive = MeshPrimitive.CreateSinglePlane(); meshPrimitive.Material = new Runtime.Material(); // Apply the common properties to the gltf. meshPrimitive.Material.PbrMetallicRoughness = new PbrMetallicRoughness { BaseColorTexture = new TextureInfo { Texture = baseColorTexture }, }; // Apply the properties that are specific to this gltf. setProperties(properties, meshPrimitive); // Create the gltf object. return(new Model { Properties = properties, GLTF = CreateGLTF(() => new Scene { Nodes = new List <Node> { new Node { Mesh = new Runtime.Mesh { MeshPrimitives = new List <Runtime.MeshPrimitive> { meshPrimitive } }, }, }, }), }); } void SetVertexUVFloat(List <Property> properties, Runtime.MeshPrimitive meshPrimitive) { meshPrimitive.TexCoords0.OutputType = DataType.Float; properties.Add(new Property(PropertyName.VertexUV0, meshPrimitive.TexCoords0.OutputType.ToReadmeString())); } void SetVertexUVByte(List <Property> properties, Runtime.MeshPrimitive meshPrimitive) { meshPrimitive.TexCoords0.OutputType = DataType.NormalizedUnsignedByte; properties.Add(new Property(PropertyName.VertexUV0, meshPrimitive.TexCoords0.OutputType.ToReadmeString())); } void SetVertexUVShort(List <Property> properties, Runtime.MeshPrimitive meshPrimitive) { meshPrimitive.TexCoords0.OutputType = DataType.NormalizedUnsignedShort; properties.Add(new Property(PropertyName.VertexUV0, meshPrimitive.TexCoords0.OutputType.ToReadmeString())); } void SetVertexNormal(List <Property> properties, Runtime.MeshPrimitive meshPrimitive) { var normals = MeshPrimitive.GetSinglePlaneNormals(); meshPrimitive.Normals = Data.Create(normals); properties.Add(new Property(PropertyName.VertexNormal, normals.ToReadmeString())); } void SetVertexTangent(List <Property> properties, Runtime.MeshPrimitive meshPrimitive) { var tangents = new[] { new Vector4(1.0f, 0.0f, 0.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f) }; meshPrimitive.Tangents = Data.Create(tangents); properties.Add(new Property(PropertyName.VertexTangent, tangents.ToReadmeString())); } void SetNormalTexture(List <Property> properties, Runtime.MeshPrimitive meshPrimitive) { meshPrimitive.Material.NormalTexture = new NormalTextureInfo { Texture = normalTexture }; properties.Add(new Property(PropertyName.NormalTexture, normalTexture.Source.ToReadmeString())); } Models = new List <Model> { CreateModel((properties, meshPrimitive) => { SetVertexUVFloat(properties, meshPrimitive); }), CreateModel((properties, meshPrimitive) => { SetVertexUVByte(properties, meshPrimitive); }), CreateModel((properties, meshPrimitive) => { SetVertexUVShort(properties, meshPrimitive); }), CreateModel((properties, meshPrimitive) => { SetVertexUVFloat(properties, meshPrimitive); SetVertexNormal(properties, meshPrimitive); }), CreateModel((properties, meshPrimitive) => { SetVertexUVFloat(properties, meshPrimitive); SetNormalTexture(properties, meshPrimitive); }), CreateModel((properties, meshPrimitive) => { SetVertexUVFloat(properties, meshPrimitive); SetVertexNormal(properties, meshPrimitive); SetNormalTexture(properties, meshPrimitive); }), CreateModel((properties, meshPrimitive) => { SetVertexUVFloat(properties, meshPrimitive); SetVertexNormal(properties, meshPrimitive); SetVertexTangent(properties, meshPrimitive); SetNormalTexture(properties, meshPrimitive); }), }; GenerateUsedPropertiesList(); }
/// <inheritdoc/> public override Material CreateMaterialForPrimitive(ContentManager contentManager, MeshPrimitive primitive) { Contract.Require(contentManager, nameof(contentManager)); Contract.Require(primitive, nameof(primitive)); return(new SkinnedMaterial { Alpha = GetMaterialAlpha(primitive.Material), DiffuseColor = GetMaterialDiffuseColor(primitive.Material), SpecularPower = GetMaterialSpecularPower(primitive.Material), SpecularColor = GetMaterialSpecularColor(primitive.Material), EmissiveColor = GetMaterialEmissiveColor(primitive.Material), Texture = GetMaterialTexture(contentManager, primitive.Material) ?? GetBlankTexture(), }); }
protected virtual void BuildMeshAttributes(MeshPrimitive primitive, int meshID, int primitiveIndex) { if (_assetCache.MeshCache[meshID][primitiveIndex].MeshAttributes.Count == 0) { Dictionary <string, AttributeAccessor> attributeAccessors = new Dictionary <string, AttributeAccessor>(primitive.Attributes.Count + 1); foreach (var attributePair in primitive.Attributes) { AttributeAccessor AttributeAccessor = new AttributeAccessor() { AccessorId = attributePair.Value, Buffer = _assetCache.BufferCache[attributePair.Value.Value.BufferView.Value.Buffer.Id] }; attributeAccessors[attributePair.Key] = AttributeAccessor; } if (primitive.Indices != null) { AttributeAccessor indexBuilder = new AttributeAccessor() { AccessorId = primitive.Indices, Buffer = _assetCache.BufferCache[primitive.Indices.Value.BufferView.Value.Buffer.Id] }; attributeAccessors[SemanticProperties.INDICES] = indexBuilder; } GLTFHelpers.BuildMeshAttributes(ref attributeAccessors); // Flip vectors and triangles to the Unity coordinate system. if (attributeAccessors.ContainsKey(SemanticProperties.POSITION)) { NumericArray resultArray = attributeAccessors[SemanticProperties.POSITION].AccessorContent; resultArray.AsVertices = GLTFUnityHelpers.FlipVectorArrayHandedness(resultArray.AsVertices); attributeAccessors[SemanticProperties.POSITION].AccessorContent = resultArray; } if (attributeAccessors.ContainsKey(SemanticProperties.INDICES)) { NumericArray resultArray = attributeAccessors[SemanticProperties.INDICES].AccessorContent; resultArray.AsTriangles = GLTFUnityHelpers.FlipFaces(resultArray.AsTriangles); attributeAccessors[SemanticProperties.INDICES].AccessorContent = resultArray; } if (attributeAccessors.ContainsKey(SemanticProperties.NORMAL)) { NumericArray resultArray = attributeAccessors[SemanticProperties.NORMAL].AccessorContent; resultArray.AsNormals = GLTFUnityHelpers.FlipVectorArrayHandedness(resultArray.AsNormals); attributeAccessors[SemanticProperties.NORMAL].AccessorContent = resultArray; } // TexCoord goes from 0 to 3 to match GLTFHelpers.BuildMeshAttributes for (int i = 0; i < 4; i++) { if (attributeAccessors.ContainsKey(SemanticProperties.TexCoord(i))) { NumericArray resultArray = attributeAccessors[SemanticProperties.TexCoord(i)].AccessorContent; resultArray.AsTexcoords = GLTFUnityHelpers.FlipTexCoordArrayV(resultArray.AsTexcoords); attributeAccessors[SemanticProperties.TexCoord(i)].AccessorContent = resultArray; } } if (attributeAccessors.ContainsKey(SemanticProperties.TANGENT)) { NumericArray resultArray = attributeAccessors[SemanticProperties.TANGENT].AccessorContent; resultArray.AsTangents = GLTFUnityHelpers.FlipVectorArrayHandedness(resultArray.AsTangents); attributeAccessors[SemanticProperties.TANGENT].AccessorContent = resultArray; } _assetCache.MeshCache[meshID][primitiveIndex].MeshAttributes = attributeAccessors; } }
public Compatibility(List <string> imageList) { NoSampleImages = true; // There are no common properties in this model group. Model CreateModel(Action <List <Property>, Asset, List <string>, List <string>, Runtime.MeshPrimitive> setProperties, Action <Schema.Gltf> postRuntimeChanges = null, Dictionary <Type, Type> schemaTypeMapping = null, bool?setLoadableTag = true) { var properties = new List <Property>(); var gltf = CreateGLTF(() => new Scene()); Runtime.MeshPrimitive meshPrimitive = MeshPrimitive.CreateSinglePlane(includeTextureCoords: false); var extensionsUsed = new List <string>(); var extensionsRequired = new List <string>(); // Apply the properties that are specific to this gltf. setProperties(properties, gltf.Asset, extensionsUsed, extensionsRequired, meshPrimitive); // Create the gltf object. if (extensionsUsed.Any()) { gltf.ExtensionsUsed = extensionsUsed; } if (extensionsRequired.Any()) { gltf.ExtensionsRequired = extensionsRequired; } gltf.Scenes.First().Nodes = new List <Node> { new Node { Mesh = new Runtime.Mesh { MeshPrimitives = new List <Runtime.MeshPrimitive> { meshPrimitive } }, }, }; var model = new Model { Properties = properties, GLTF = gltf }; model.Loadable = setLoadableTag; model.PostRuntimeChanges = postRuntimeChanges; if (schemaTypeMapping != null) { model.CreateSchemaInstance = type => { if (schemaTypeMapping.TryGetValue(type, out Type mappedType)) { type = mappedType; } return(Activator.CreateInstance(type)); }; } return(model); } Property SetMinVersion(Asset asset) { return(new Property(PropertyName.MinVersion, asset.MinVersion = "2.1")); } Property SetVersionCurrent(Asset asset) { return(new Property(PropertyName.Version, asset.Version = "2.0")); } Property SetVersionFuture(Asset asset) { return(new Property(PropertyName.Version, asset.Version = "2.1")); } void SetPostRuntimeAtRoot(Schema.Gltf gltf) { // Add an simulated feature at the root level. var experimentalGltf = (ExperimentalGltf)gltf; experimentalGltf.Lights = new[] { new ExperimentalLight { Color = new[] { 0.3f, 0.4f, 0.5f } } }; } void SetPostRuntimeInProperty(Schema.Gltf gltf) { // Add an simulated feature into an existing property. var experimentalNode = (ExperimentalNode)gltf.Nodes[0]; experimentalNode.Light = 0; } void SetPostRuntimeWithFallback(Schema.Gltf gltf) { // Add an simulated feature with a fallback option. gltf.Materials = new Schema.Material[] { new ExperimentalMaterial { AlphaMode = Schema.Material.AlphaModeEnum.BLEND, AlphaMode2 = ExperimentalAlphaMode2.QUANTUM, } }; } var experimentalSchemaTypeMapping = new Dictionary <Type, Type> { { typeof(Schema.Gltf), typeof(ExperimentalGltf) }, { typeof(Schema.Node), typeof(ExperimentalNode) }, { typeof(Schema.Material), typeof(ExperimentalMaterial) }, }; var shouldLoad = ":white_check_mark:"; Models = new List <Model> { CreateModel((properties, asset, extensionsUsed, extensionsRequired, meshPrimitive) => { properties.Add(SetVersionCurrent(asset)); properties.Add(new Property(PropertyName.ModelShouldLoad, shouldLoad)); }), CreateModel((properties, asset, extensionsUsed, extensionsRequired, meshPrimitive) => { properties.Add(SetVersionFuture(asset)); properties.Add(new Property(PropertyName.Description, "Light object added at root")); properties.Add(new Property(PropertyName.ModelShouldLoad, shouldLoad)); }, SetPostRuntimeAtRoot, experimentalSchemaTypeMapping), CreateModel((properties, asset, extensionsUsed, extensionsRequired, meshPrimitive) => { properties.Add(SetVersionFuture(asset)); properties.Add(new Property(PropertyName.Description, "Light property added to node object")); properties.Add(new Property(PropertyName.ModelShouldLoad, shouldLoad)); }, SetPostRuntimeInProperty, experimentalSchemaTypeMapping), CreateModel((properties, asset, extensionsUsed, extensionsRequired, meshPrimitive) => { properties.Add(SetVersionFuture(asset)); properties.Add(new Property(PropertyName.Description, "Alpha mode updated with a new enum value, and a fallback value")); properties.Add(new Property(PropertyName.ModelShouldLoad, shouldLoad)); }, SetPostRuntimeWithFallback, experimentalSchemaTypeMapping), CreateModel((properties, asset, extensionsUsed, extensionsRequired, meshPrimitive) => { properties.Add(SetMinVersion(asset)); properties.Add(SetVersionFuture(asset)); properties.Add(new Property(PropertyName.Description, "Requires a specific version or higher")); properties.Add(new Property(PropertyName.ModelShouldLoad, "Only in version 2.1 or higher")); }, null, null, setLoadableTag: false), CreateModel((properties, asset, extensionsUsed, extensionsRequired, meshPrimitive) => { properties.Add(SetVersionCurrent(asset)); var emptyTexture = new Texture(); var extension = new FAKE_materials_quantumRendering { PlanckFactor = new Vector4(0.2f, 0.2f, 0.2f, 0.8f), CopenhagenTexture = new TextureInfo { Texture = emptyTexture }, EntanglementFactor = new Vector3(0.4f, 0.4f, 0.4f), ProbabilisticFactor = 0.3f, SuperpositionCollapseTexture = new TextureInfo { Texture = emptyTexture }, }; meshPrimitive.Material = new Runtime.Material { Extensions = new List <Extension> { extension } }; extensionsUsed.Add(extension.Name); extensionsRequired.Add(extension.Name); properties.Add(new Property(PropertyName.Description, "Extension required")); properties.Add(new Property(PropertyName.ModelShouldLoad, ":x:")); }, null, null, setLoadableTag: false), CreateModel((properties, asset, extensionsUsed, extensionsRequired, meshPrimitive) => { properties.Add(SetVersionCurrent(asset)); var extension = new KHR_materials_pbrSpecularGlossiness { SpecularFactor = new Vector3(0.04f, 0.04f, 0.04f), GlossinessFactor = 0.0f, }; meshPrimitive.Material = new Runtime.Material { // Metallic-Roughness PbrMetallicRoughness = new PbrMetallicRoughness { MetallicFactor = 0.0f }, // Specular-Glossiness Extensions = new[] { extension }, }; extensionsUsed.Add(extension.Name); properties.Add(new Property(PropertyName.Description, "Specular Glossiness extension used but not required")); properties.Add(new Property(PropertyName.ModelShouldLoad, shouldLoad)); }), }; GenerateUsedPropertiesList(); }
// a mesh *might* decode to multiple prims if there are submeshes private MeshPrimitive[] ExportPrimitive(GameObject gameObject) { var filter = gameObject.GetComponent <MeshFilter>(); var meshObj = filter.sharedMesh; var renderer = gameObject.GetComponent <MeshRenderer>(); var materialsObj = renderer.sharedMaterials; var prims = new MeshPrimitive[meshObj.subMeshCount]; // don't export any more accessors if this mesh is already exported MeshPrimitive[] primVariations; if (_meshToPrims.TryGetValue(meshObj, out primVariations) && meshObj.subMeshCount == primVariations.Length) { for (var i = 0; i < primVariations.Length; i++) { prims[i] = primVariations[i].Clone(); prims[i].Material = ExportMaterial(materialsObj[i]); } return(prims); } AccessorId aPosition = null, aNormal = null, aTangent = null, aTexcoord0 = null, aTexcoord1 = null, aColor0 = null; aPosition = ExportAccessor(InvertZ(meshObj.vertices)); if (meshObj.normals.Length != 0) { aNormal = ExportAccessor(InvertZ(meshObj.normals)); } if (meshObj.tangents.Length != 0) { aTangent = ExportAccessor(InvertW(meshObj.tangents)); } if (meshObj.uv.Length != 0) { aTexcoord0 = ExportAccessor(InvertY(meshObj.uv)); } if (meshObj.uv2.Length != 0) { aTexcoord1 = ExportAccessor(InvertY(meshObj.uv2)); } if (meshObj.colors.Length != 0) { aColor0 = ExportAccessor(meshObj.colors); } MaterialId lastMaterialId = null; for (var submesh = 0; submesh < meshObj.subMeshCount; submesh++) { var primitive = new MeshPrimitive(); var triangles = meshObj.GetTriangles(submesh); primitive.Indices = ExportAccessor(FlipFaces(triangles), true); primitive.Attributes = new Dictionary <string, AccessorId>(); primitive.Attributes.Add(SemanticProperties.POSITION, aPosition); if (aNormal != null) { primitive.Attributes.Add(SemanticProperties.NORMAL, aNormal); } if (aTangent != null) { primitive.Attributes.Add(SemanticProperties.TANGENT, aTangent); } if (aTexcoord0 != null) { primitive.Attributes.Add(SemanticProperties.TexCoord(0), aTexcoord0); } if (aTexcoord1 != null) { primitive.Attributes.Add(SemanticProperties.TexCoord(1), aTexcoord1); } if (aColor0 != null) { primitive.Attributes.Add(SemanticProperties.Color(0), aColor0); } if (submesh < materialsObj.Length) { primitive.Material = ExportMaterial(materialsObj[submesh]); lastMaterialId = primitive.Material; } else { primitive.Material = lastMaterialId; } prims[submesh] = primitive; } _meshToPrims[meshObj] = prims; return(prims); }
public PrimitiveDemo(Layer layer) : base(layer) { // Primitives can only be drawn from instances. There are no static methods. _trianglefan = new TriangleFanPrimitive(); _trianglefan.Vertices = new List <Vertex> { new Vertex(new Vector2(0, 0)), new Vertex(new Vector2(16, 0)), new Vertex(new Vector2(40, 10)), new Vertex(new Vector2(64, 64)), new Vertex(new Vector2(0, 32)), }; _trianglestrip = new TriangleStripPrimitive(); _trianglestrip.Vertices = new List <Vertex> { new Vertex(new Vector2(0, 0), _mainColor), new Vertex(new Vector2(32, 32), _secondaryColor), new Vertex(new Vector2(64, 0), _secondaryColor2), new Vertex(new Vector2(96, 32), _secondaryColor), new Vertex(new Vector2(64 + 32, 0), _secondaryColor2), new Vertex(new Vector2(96 + 32, 32), _secondaryColor), new Vertex(new Vector2(64 + 64, 0), _secondaryColor2), new Vertex(new Vector2(96 + 64, 32), _mainColor), }; _mesh = new MeshPrimitive(16, 16); _mesh.Position = new Vector2(0, 100); // You can set the texture for a primitive. Preferrably it shouldn't be in texture atlas. // If in atlas, textures wouldn't be able to repeat. _mesh.SetTextureFromFrame(Default.AutismCat[0]); _mesh.Vertices = new List <Vertex>(8 * 8); for (var k = 0; k < _mesh.Height; k += 1) { for (var i = 0; i < _mesh.Width; i += 1) { _mesh.Vertices.Add( new Vertex( Vector2.Zero, // Positions will be set later. Color.White, new Vector2(i / (float)(_mesh.Width - 1), k / (float)(_mesh.Height - 1)) * _meshRepeat ) ); } } _linestrip = new LineStripPrimitive(); _linestrip.Vertices = new List <Vertex>(); for (var i = 0; i < 16; i += 1) { _linestrip.Vertices.Add(new Vertex(Vector2.Zero, new Color(16 * i, 8 * i, 4 * i))); } // You can make your own custom primitives. // CustomTrianglePrimitive and CustomLinePrimitive give you // access to the index array. Index array tells inwhat order vertices should be drawn. // One vertex can be used multiple times in an index array. _custom = new CustomTrianglePrimitive(); _custom.Vertices = new List <Vertex>() { new Vertex(new Vector2(0, 0), Color.Green), new Vertex(new Vector2(32, 0)), new Vertex(new Vector2(32, 32)), new Vertex(new Vector2(64, 32), Color.Blue), }; _custom.Indices = new short[] { 0, 1, 2, 1, 3, 2 }; }
private void ExportComponentMaterial(SeinCustomMaterial material, MeshPrimitive primitive, ExporterEntry entry) { primitive.Material = entry.SaveComponentMaterial(material); }
/// <summary> /// Creates a new <see cref="Material"/> instance for the specified primitve. /// </summary> /// <param name="contentManager">The content manager with which the model is being loaded.</param> /// <param name="primitive">The <see cref="MeshPrimitive"/> for which to create a material.</param> /// <returns>The <see cref="Material"/> instance which was created.</returns> public abstract Material CreateMaterialForPrimitive(ContentManager contentManager, MeshPrimitive primitive);
internal static int AddTriangleMesh(this Gltf gltf, string name, List <byte> buffer, double[] vertices, double[] normals, ushort[] indices, float[] colors, double[] vMin, double[] vMax, double[] nMin, double[] nMax, ushort iMin, ushort iMax, int materialId, float[] cMin, float[] cMax, int?parent_index, Transform transform = null) { var m = new glTFLoader.Schema.Mesh(); m.Name = name; var vBuff = gltf.AddBufferView(0, buffer.Count, vertices.Length * sizeof(float), null, null); var nBuff = gltf.AddBufferView(0, buffer.Count + vertices.Length * sizeof(float), normals.Length * sizeof(float), null, null); var iBuff = gltf.AddBufferView(0, buffer.Count + vertices.Length * sizeof(float) + normals.Length * sizeof(float), indices.Length * sizeof(ushort), null, null); foreach (var v in vertices) { buffer.AddRange(BitConverter.GetBytes((float)v)); } foreach (var n in normals) { buffer.AddRange(BitConverter.GetBytes((float)n)); } foreach (var i in indices) { buffer.AddRange(BitConverter.GetBytes(i)); } while (buffer.Count % 4 != 0) { // Console.WriteLine("Padding..."); buffer.Add(0); } var vAccess = gltf.AddAccessor(vBuff, 0, Accessor.ComponentTypeEnum.FLOAT, vertices.Length / 3, new[] { (float)vMin[0], (float)vMin[1], (float)vMin[2] }, new[] { (float)vMax[0], (float)vMax[1], (float)vMax[2] }, Accessor.TypeEnum.VEC3); var nAccess = gltf.AddAccessor(nBuff, 0, Accessor.ComponentTypeEnum.FLOAT, normals.Length / 3, new[] { (float)nMin[0], (float)nMin[1], (float)nMin[2] }, new[] { (float)nMax[0], (float)nMax[1], (float)nMax[2] }, Accessor.TypeEnum.VEC3); var iAccess = gltf.AddAccessor(iBuff, 0, Accessor.ComponentTypeEnum.UNSIGNED_SHORT, indices.Length, new[] { (float)iMin }, new[] { (float)iMax }, Accessor.TypeEnum.SCALAR); var prim = new MeshPrimitive(); prim.Indices = iAccess; prim.Material = materialId; prim.Mode = MeshPrimitive.ModeEnum.TRIANGLES; prim.Attributes = new Dictionary <string, int> { { "NORMAL", nAccess }, { "POSITION", vAccess } }; // TODO: Add to the buffer above instead of inside this block. // There's a chance the padding operation will put padding before // the color information. if (colors.Length > 0) { var cBuff = gltf.AddBufferView(0, buffer.Count, colors.Length * sizeof(float), null, null); foreach (var c in colors) { buffer.AddRange(BitConverter.GetBytes((float)c)); } var cAccess = gltf.AddAccessor(cBuff, 0, Accessor.ComponentTypeEnum.FLOAT, colors.Length / 3, cMin, cMax, Accessor.TypeEnum.VEC3); prim.Attributes.Add("COLOR_0", cAccess); } m.Primitives = new[] { prim }; // Add mesh to gltf if (gltf.Meshes != null) { // TODO: Get rid of this resizing. var meshes = gltf.Meshes.ToList(); meshes.Add(m); gltf.Meshes = meshes.ToArray(); } else { gltf.Meshes = new[] { m }; } var parentId = 0; if (transform != null) { var a = transform.XAxis; var b = transform.YAxis; var c = transform.ZAxis; var transNode = new Node(); transNode.Matrix = new[] { (float)a.X, (float)a.Y, (float)a.Z, 0.0f, (float)b.X, (float)b.Y, (float)b.Z, 0.0f, (float)c.X, (float)c.Y, (float)c.Z, 0.0f, (float)transform.Origin.X, (float)transform.Origin.Y, (float)transform.Origin.Z, 1.0f }; parentId = gltf.AddNode(transNode, 0); } // Add mesh node to gltf var node = new Node(); node.Mesh = gltf.Meshes.Length - 1; gltf.AddNode(node, parentId); return(gltf.Meshes.Length - 1); }
public Material_DoubleSided(List <string> imageList) { Runtime.Image baseColorTextureImage = UseTexture(imageList, "BaseColor_Plane"); Runtime.Image normalImage = UseTexture(imageList, "Normal_Plane"); // Track the common properties for use in the readme. var doubleSidedValue = true; CommonProperties.Add(new Property(PropertyName.DoubleSided, doubleSidedValue.ToString())); CommonProperties.Add(new Property(PropertyName.BaseColorTexture, baseColorTextureImage.ToReadmeString())); Model CreateModel(Action <List <Property>, Runtime.MeshPrimitive> setProperties) { var properties = new List <Property>(); var meshPrimitive = MeshPrimitive.CreateSinglePlane(); meshPrimitive.Material = new Runtime.Material(); meshPrimitive.Material.MetallicRoughnessMaterial = new Runtime.PbrMetallicRoughness(); // Apply the common properties to the gltf. meshPrimitive.Material.DoubleSided = doubleSidedValue; meshPrimitive.Material.MetallicRoughnessMaterial.BaseColorTexture = new Runtime.Texture { Source = baseColorTextureImage }; // Apply the properties that are specific to this gltf. setProperties(properties, meshPrimitive); // Create the gltf object. return(new Model { Properties = properties, GLTF = CreateGLTF(() => new Runtime.Scene { Nodes = new List <Runtime.Node> { new Runtime.Node { Mesh = new Runtime.Mesh { MeshPrimitives = new List <Runtime.MeshPrimitive> { meshPrimitive } }, }, }, }), }); } void SetVertexNormal(List <Property> properties, Runtime.MeshPrimitive meshPrimitive) { var planeNormalsValue = MeshPrimitive.GetSinglePlaneNormals(); meshPrimitive.Normals = planeNormalsValue; properties.Add(new Property(PropertyName.VertexNormal, planeNormalsValue.ToReadmeString())); } void SetVertexTangent(List <Property> properties, Runtime.MeshPrimitive meshPrimitive) { var planeTangentValue = MeshPrimitive.GetSinglePlaneTangents(); meshPrimitive.Tangents = planeTangentValue; properties.Add(new Property(PropertyName.VertexTangent, planeTangentValue.ToReadmeString())); } void SetNormalTexture(List <Property> properties, Runtime.MeshPrimitive meshPrimitive) { meshPrimitive.Material.NormalTexture = new Runtime.Texture { Source = normalImage }; properties.Add(new Property(PropertyName.NormalTexture, normalImage.ToReadmeString())); } Models = new List <Model> { CreateModel((properties, meshPrimitive) => { // There are no properties set on this model. }), CreateModel((properties, meshPrimitive) => { SetVertexNormal(properties, meshPrimitive); }), CreateModel((properties, meshPrimitive) => { SetVertexNormal(properties, meshPrimitive); SetNormalTexture(properties, meshPrimitive); }), CreateModel((properties, meshPrimitive) => { SetVertexNormal(properties, meshPrimitive); SetVertexTangent(properties, meshPrimitive); SetNormalTexture(properties, meshPrimitive); }), CreateModel((properties, meshPrimitive) => { SetNormalTexture(properties, meshPrimitive); }), }; GenerateUsedPropertiesList(); }
public Material_Mixed(List <string> imageList) { Runtime.Image baseColorTextureImage = UseTexture(imageList, "BaseColor_X"); UseFigure(imageList, "UVSpace2"); UseFigure(imageList, "UVSpace3"); // Track the common properties for use in the readme. CommonProperties.Add(new Property(PropertyName.ExtensionUsed, "Specular Glossiness")); CommonProperties.Add(new Property(PropertyName.BaseColorTexture, baseColorTextureImage)); Model CreateModel(Action <List <Property>, Runtime.Material, Runtime.Material> setProperties) { var properties = new List <Property>(); var meshPrimitives = MeshPrimitive.CreateMultiPrimitivePlane(); var baseColorTexture = new Runtime.Texture { Source = baseColorTextureImage }; meshPrimitives[0].Material = new Runtime.Material(); meshPrimitives[0].Material.MetallicRoughnessMaterial = new Runtime.PbrMetallicRoughness(); meshPrimitives[1].Material = new Runtime.Material(); meshPrimitives[1].Material.MetallicRoughnessMaterial = new Runtime.PbrMetallicRoughness(); // Apply the common properties to the gltf. meshPrimitives[0].Material.MetallicRoughnessMaterial.BaseColorTexture = baseColorTexture; meshPrimitives[1].Material.MetallicRoughnessMaterial.BaseColorTexture = baseColorTexture; // Apply the properties that are specific to this gltf. setProperties(properties, meshPrimitives[0].Material, meshPrimitives[1].Material); // Create the gltf object. return(new Model { Properties = properties, GLTF = CreateGLTF(() => new Runtime.Scene() { Nodes = new[] { new Runtime.Node { Mesh = new Runtime.Mesh { MeshPrimitives = meshPrimitives }, }, }, }, extensionsUsed: new List <string>() { "KHR_materials_pbrSpecularGlossiness" }), }); } void SetSpecularGlossiness0(List <Property> properties, Runtime.Material material0) { material0.Extensions = new List <Runtime.Extensions.Extension>() { new Runtime.Extensions.KHR_materials_pbrSpecularGlossiness() }; properties.Add(new Property(PropertyName.SpecularGlossinessOnMaterial0, ":white_check_mark:")); } void SetSpecularGlossiness1(List <Property> properties, Runtime.Material material1) { material1.Extensions = new List <Runtime.Extensions.Extension>() { new Runtime.Extensions.KHR_materials_pbrSpecularGlossiness() }; properties.Add(new Property(PropertyName.SpecularGlossinessOnMaterial1, ":white_check_mark:")); } void NoSpecularGlossiness0(List <Property> properties) { properties.Add(new Property(PropertyName.SpecularGlossinessOnMaterial0, ":x:")); } void NoSpecularGlossiness1(List <Property> properties) { properties.Add(new Property(PropertyName.SpecularGlossinessOnMaterial1, ":x:")); } Models = new List <Model> { CreateModel((properties, material0, material1) => { SetSpecularGlossiness0(properties, material0); SetSpecularGlossiness1(properties, material1); }), CreateModel((properties, material0, material1) => { NoSpecularGlossiness0(properties); NoSpecularGlossiness1(properties); }), CreateModel((properties, material0, material1) => { SetSpecularGlossiness0(properties, material0); NoSpecularGlossiness1(properties); }), }; GenerateUsedPropertiesList(); }
public Material_AlphaMask(List <string> imageList) { Runtime.Image baseColorTextureImage = UseTexture(imageList, "BaseColor_Plane"); // Track the common properties for use in the readme. var alphaModeValue = AlphaModeEnum.MASK; CommonProperties.Add(new Property(PropertyName.AlphaMode, alphaModeValue)); CommonProperties.Add(new Property(PropertyName.BaseColorTexture, baseColorTextureImage)); Model CreateModel(Action <List <Property>, Runtime.Material, Runtime.PbrMetallicRoughness> setProperties) { var properties = new List <Property>(); var meshPrimitive = MeshPrimitive.CreateSinglePlane(); meshPrimitive.Material = new Runtime.Material(); meshPrimitive.Material.MetallicRoughnessMaterial = new Runtime.PbrMetallicRoughness(); // Apply the common properties to the gltf. meshPrimitive.Material.AlphaMode = alphaModeValue; meshPrimitive.Material.MetallicRoughnessMaterial.BaseColorTexture = new Runtime.Texture { Source = baseColorTextureImage }; // Apply the properties that are specific to this gltf. setProperties(properties, meshPrimitive.Material, meshPrimitive.Material.MetallicRoughnessMaterial); // Create the gltf object. return(new Model { Properties = properties, GLTF = CreateGLTF(() => new Runtime.Scene() { Nodes = new[] { new Runtime.Node { Mesh = new Runtime.Mesh { MeshPrimitives = new List <Runtime.MeshPrimitive> { meshPrimitive } }, }, }, }), }); } void SetAlphaCutoff_Low(List <Property> properties, Runtime.Material material) { material.AlphaCutoff = 0.4f; properties.Add(new Property(PropertyName.AlphaCutoff, material.AlphaCutoff)); } void SetAlphaCutoff_High(List <Property> properties, Runtime.Material material) { material.AlphaCutoff = 0.7f; properties.Add(new Property(PropertyName.AlphaCutoff, material.AlphaCutoff)); } void SetAlphaCutoff_Multiplied(List <Property> properties, Runtime.Material material) { material.AlphaCutoff = 0.6f; properties.Add(new Property(PropertyName.AlphaCutoff, material.AlphaCutoff)); } void SetAlphaCutoff_All(List <Property> properties, Runtime.Material material) { material.AlphaCutoff = 1.1f; properties.Add(new Property(PropertyName.AlphaCutoff, material.AlphaCutoff)); } void SetAlphaCutoff_None(List <Property> properties, Runtime.Material material) { material.AlphaCutoff = 0.0f; properties.Add(new Property(PropertyName.AlphaCutoff, material.AlphaCutoff)); } void SetBaseColorFactor(List <Property> properties, Runtime.PbrMetallicRoughness metallicRoughness) { var baseColorFactorValue = new Vector4(1.0f, 1.0f, 1.0f, 0.7f); metallicRoughness.BaseColorFactor = baseColorFactorValue; properties.Add(new Property(PropertyName.BaseColorFactor, baseColorFactorValue)); } Models = new List <Model> { CreateModel((properties, material, metallicRoughness) => { // There are no properties set on this model. }), CreateModel((properties, material, metallicRoughness) => { SetAlphaCutoff_Low(properties, material); }), CreateModel((properties, material, metallicRoughness) => { SetAlphaCutoff_High(properties, material); }), CreateModel((properties, material, metallicRoughness) => { SetAlphaCutoff_All(properties, material); }), CreateModel((properties, material, metallicRoughness) => { SetAlphaCutoff_None(properties, material); }), CreateModel((properties, material, metallicRoughness) => { SetAlphaCutoff_Low(properties, material); SetBaseColorFactor(properties, metallicRoughness); }), CreateModel((properties, material, metallicRoughness) => { SetAlphaCutoff_Multiplied(properties, material); SetBaseColorFactor(properties, metallicRoughness); }), }; GenerateUsedPropertiesList(); }