├── .editorconfig ├── .gitignore ├── BonVision.sln ├── BonVision ├── AngleProperty.cs ├── BonVision.csproj ├── BonVision.svg ├── Collections │ ├── CreateGratingTrial.cs │ ├── GratingSequence.bonsai │ ├── GratingsSpecification.cs │ └── SparseNoise.bonsai ├── CreateSparseNoiseGrid.cs ├── CreateSphereGrid.cs ├── CreateTextureScale.cs ├── CreateTextureShift.cs ├── CreateVertexGrid.cs ├── DegreeConverter.cs ├── Environment │ ├── CubemapView.bonsai │ ├── DrawViewport.bonsai │ ├── GammaCorrection.bonsai │ ├── HmdView.bonsai │ ├── MeshMapping.bonsai │ ├── NormalizedView.bonsai │ ├── OrthographicView.bonsai │ ├── PerspectiveMapping.bonsai │ ├── PerspectiveView.bonsai │ ├── RenderHmd.bonsai │ ├── SphereMapping.bonsai │ ├── ViewMapping.bonsai │ └── ViewWindow.bonsai ├── FieldOfViewProperty.cs ├── Logging │ ├── EventLogger.bonsai │ ├── FrameEventLogger.bonsai │ └── LogEvent.bonsai ├── Models │ ├── Plane.obj │ └── Quad.obj ├── OptionalFloatProperty.cs ├── Primitives │ ├── BonVisionResources.bonsai │ ├── DrawCheckerboard.bonsai │ ├── DrawCircle.bonsai │ ├── DrawCircleArray.bonsai │ ├── DrawGratings.bonsai │ ├── DrawImage.bonsai │ ├── DrawModel.bonsai │ ├── DrawModelArray.bonsai │ ├── DrawQuad.bonsai │ ├── DrawSceneModel.bonsai │ ├── DrawText.bonsai │ ├── DrawTexturedModel.bonsai │ ├── DrawTexturedModelArray.bonsai │ ├── DrawVideo.bonsai │ ├── ParameterRange.bonsai │ └── RangeAnimation.bonsai ├── Properties │ ├── AssemblyInfo.cs │ └── launchSettings.json ├── RotationConverter.cs ├── RotationProperty.cs ├── SampleMany.cs └── Shaders │ ├── Checkerboard.frag │ ├── Circle.frag │ ├── Color.frag │ ├── Gamma.frag │ ├── Gratings.frag │ ├── Gratings.vert │ ├── Image.frag │ ├── MeshMap.frag │ ├── MeshMap.vert │ ├── Model.frag │ ├── Model.vert │ ├── ModelArray.vert │ ├── PerspectiveMap.frag │ ├── PerspectiveMap.vert │ ├── Quad.vert │ ├── QuadArray.vert │ ├── SphereMap.frag │ ├── SphereMap.vert │ ├── TexturedModel.frag │ ├── TexturedModel.vert │ ├── TexturedModelArray.vert │ └── ViewMap.frag ├── Extensions.csproj ├── LICENSE ├── README.md └── Resources ├── BonVision-Logo.png ├── BonVision-Logo.svg └── BonVision.svg /.editorconfig: -------------------------------------------------------------------------------- 1 | # To learn more about .editorconfig see https://aka.ms/editorconfigdocs 2 | ############################### 3 | # Core EditorConfig Options # 4 | ############################### 5 | # All files 6 | [*] 7 | indent_style = space 8 | 9 | # XML project files 10 | [*.{csproj,vcxproj,vcxproj.filters,proj,projitems,shproj}] 11 | indent_size = 2 12 | 13 | # XML config files 14 | [*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}] 15 | indent_size = 2 16 | 17 | # Code files 18 | [*.{cs,csx}] 19 | indent_size = 4 20 | insert_final_newline = true 21 | charset = utf-8-bom 22 | ############################### 23 | # .NET Coding Conventions # 24 | ############################### 25 | [*.{cs}] 26 | # Organize usings 27 | dotnet_sort_system_directives_first = true -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vs 2 | bin 3 | obj 4 | packages -------------------------------------------------------------------------------- /BonVision.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.27004.2006 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BonVision", "BonVision\BonVision.csproj", "{A94600D8-1B43-4F69-9176-E2DE45FFF352}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {A94600D8-1B43-4F69-9176-E2DE45FFF352}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {A94600D8-1B43-4F69-9176-E2DE45FFF352}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {A94600D8-1B43-4F69-9176-E2DE45FFF352}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {A94600D8-1B43-4F69-9176-E2DE45FFF352}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {9A2E604C-F64B-4153-959A-B558DC69BEFB} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /BonVision/AngleProperty.cs: -------------------------------------------------------------------------------- 1 | using Bonsai; 2 | using System; 3 | using System.ComponentModel; 4 | using System.Linq; 5 | using System.Reactive.Linq; 6 | using System.Xml.Serialization; 7 | 8 | namespace BonVision 9 | { 10 | [Combinator] 11 | [DisplayName("Angle")] 12 | [Description("Represents a workflow property specifying a single-precision angle.")] 13 | [WorkflowElementCategory(ElementCategory.Source)] 14 | public class AngleProperty 15 | { 16 | float value; 17 | event Action ValueChanged; 18 | 19 | [XmlIgnore] 20 | [Range(-Math.PI, Math.PI)] 21 | [TypeConverter(typeof(DegreeConverter))] 22 | [Description("The value of the angle.")] 23 | [Editor(DesignTypes.SliderEditor, DesignTypes.UITypeEditor)] 24 | public float Value 25 | { 26 | get { return value; } 27 | set 28 | { 29 | this.value = value; 30 | OnValueChanged(this.value); 31 | } 32 | } 33 | 34 | [Browsable(false)] 35 | [XmlElement("Value")] 36 | public float ValueXml 37 | { 38 | get { return DegreeConverter.RadianToDegree(value); } 39 | set { this.value = DegreeConverter.DegreeToRadian(value); } 40 | } 41 | 42 | void OnValueChanged(float value) 43 | { 44 | ValueChanged?.Invoke(value); 45 | } 46 | 47 | public IObservable Process() 48 | { 49 | return Observable 50 | .Defer(() => Observable.Return(value)) 51 | .Concat(Observable.FromEvent( 52 | handler => ValueChanged += handler, 53 | handler => ValueChanged -= handler)); 54 | } 55 | 56 | public IObservable Process(IObservable source) 57 | { 58 | return source.Select(x => value); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /BonVision/BonVision.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | BonVision 5 | A visual stimulus generator and environmental mapping package for Bonsai. 6 | Aman Saleem 7 | Copyright © Aman Saleem 2020 8 | https://bonvision.github.io 9 | https://raw.githubusercontent.com/bonvision/BonVision/main/LICENSE 10 | https://github.com/bonvision/BonVision/raw/main/Resources/BonVision-Logo.png 11 | ..\bin\$(Configuration) 12 | Dependency;BonsaiLibrary 13 | Bonsai Rx BonVision Visual Environment Psychophysics Stimulus 14 | true 15 | true 16 | net462 17 | strict 18 | 0.12.0 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /BonVision/BonVision.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /BonVision/Collections/CreateGratingTrial.cs: -------------------------------------------------------------------------------- 1 | using Bonsai; 2 | using System; 3 | using System.ComponentModel; 4 | using System.Linq; 5 | using System.Reactive.Linq; 6 | using System.Xml.Serialization; 7 | 8 | namespace BonVision.Collections 9 | { 10 | public class GratingTrial 11 | { 12 | public float Id { get; set; } 13 | public float Delay { get; set; } 14 | public float Duration { get; set; } 15 | public float Diameter { get; set; } 16 | public float X { get; set; } 17 | public float Y { get; set; } 18 | public float Contrast { get; set; } 19 | public float SpatialFrequency { get; set; } 20 | public float TemporalFrequency { get; set; } 21 | public float Orientation { get; set; } 22 | 23 | public override string ToString() 24 | { 25 | return string.Join(",", 26 | nameof(Id), Id, 27 | nameof(Delay), Delay, 28 | nameof(Duration), Duration, 29 | nameof(Diameter), Diameter, 30 | nameof(X), X, 31 | nameof(Y), Y, 32 | nameof(Contrast), Contrast, 33 | nameof(SpatialFrequency), SpatialFrequency, 34 | nameof(TemporalFrequency), TemporalFrequency, 35 | nameof(Orientation), Orientation); 36 | } 37 | } 38 | 39 | [Description("Creates a sequence of grating trials used for stimulus presentation.")] 40 | public class CreateGratingTrial : Transform 41 | { 42 | public CreateGratingTrial() 43 | { 44 | Duration = 1; 45 | Diameter = 1; 46 | Contrast = 1; 47 | SpatialFrequency = 10; 48 | } 49 | 50 | [Description("The default pre-stimulus interval, in seconds.")] 51 | public float Delay { get; set; } 52 | 53 | [Description("The default duration of the trial, in seconds.")] 54 | public float Duration { get; set; } 55 | 56 | [Description("The default diameter of the grating stimulus, in degrees.")] 57 | public float Diameter { get; set; } 58 | 59 | [Description("The default position of the gratings along the x-axis, in degrees.")] 60 | public float X { get; set; } 61 | 62 | [Description("The default position of the gratings along the y-axis, in degrees.")] 63 | public float Y { get; set; } 64 | 65 | [Description("The default contrast of the grating stimulus, where zero is no contrast, and one is maximum contrast.")] 66 | public float Contrast { get; set; } 67 | 68 | [Description("The default spatial frequency of the gratings, in cycles per degree.")] 69 | public float SpatialFrequency { get; set; } 70 | 71 | [Description("The default sliding speed of the grating stimulus, in cycles per second.")] 72 | public float TemporalFrequency { get; set; } 73 | 74 | [XmlIgnore] 75 | [Range(-Math.PI, Math.PI)] 76 | [TypeConverter(typeof(DegreeConverter))] 77 | [Editor(DesignTypes.SliderEditor, DesignTypes.UITypeEditor)] 78 | [Description("The default angle of the grating stimulus.")] 79 | public float Orientation { get; set; } 80 | 81 | [Browsable(false)] 82 | [XmlElement(nameof(Orientation))] 83 | public float OrientationXml 84 | { 85 | get { return DegreeConverter.RadianToDegree(Orientation); } 86 | set { Orientation = DegreeConverter.DegreeToRadian(value); } 87 | } 88 | 89 | public IObservable Process(IObservable source) 90 | { 91 | return source.Select((element, index) => new GratingTrial 92 | { 93 | Id = index, 94 | Delay = Delay, 95 | Duration = Duration, 96 | Diameter = Diameter, 97 | X = X, 98 | Y = Y, 99 | Contrast = Contrast, 100 | SpatialFrequency = SpatialFrequency, 101 | TemporalFrequency = TemporalFrequency, 102 | Orientation = Orientation 103 | }); 104 | } 105 | 106 | public override IObservable Process(IObservable source) 107 | { 108 | return source.Select((parameters, index) => new GratingTrial 109 | { 110 | Id = index, 111 | Delay = parameters.Delay.GetValueOrDefault(Delay), 112 | Duration = parameters.Duration.GetValueOrDefault(Duration), 113 | Diameter = parameters.Diameter.GetValueOrDefault(Diameter), 114 | X = parameters.X.GetValueOrDefault(X), 115 | Y = parameters.Y.GetValueOrDefault(Y), 116 | Contrast = parameters.Contrast.GetValueOrDefault(Contrast), 117 | SpatialFrequency = parameters.SpatialFrequency.GetValueOrDefault(SpatialFrequency), 118 | TemporalFrequency = parameters.TemporalFrequency.GetValueOrDefault(TemporalFrequency), 119 | Orientation = parameters.Orientation.GetValueOrDefault(Orientation) 120 | }); 121 | } 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /BonVision/Collections/GratingSequence.bonsai: -------------------------------------------------------------------------------- 1 |  2 | 8 | Presents a sequence of predefined grating stimuli. 9 | 10 | 11 | 12 | Source1 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | Source1 26 | 27 | 28 | Parameters 29 | 30 | 31 | Draw 32 | 33 | 34 | Parameters 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | Parameters 50 | 51 | 52 | TimeSpan.FromSeconds(Duration) 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | PT1S 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 0 76 | 0 77 | 0 78 | 0 79 | 10 80 | 0 81 | 0 82 | false 83 | 1 84 | 85 | 1 86 | 0 87 | 1 88 | 1 89 | 1 90 | 91 | 92 | 93 | 94 | 95 | Parameters 96 | 97 | 98 | TimeSpan.FromSeconds(Delay) 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | PT0S 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | -------------------------------------------------------------------------------- /BonVision/Collections/GratingsSpecification.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bonvision/BonVision/785fa61d355c2a2fadc441d96012767273260db9/BonVision/Collections/GratingsSpecification.cs -------------------------------------------------------------------------------- /BonVision/Collections/SparseNoise.bonsai: -------------------------------------------------------------------------------- 1 |  2 | 10 | Generates and draws a non-overlapping discrete sparse grid of randomly activated quads. 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | PT0S 19 | PT0.2S 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | Size 30 | 31 | 10 32 | 10 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | Size 42 | 43 | 10 44 | 10 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | Source1 55 | 56 | 57 | 58 | 10 59 | 10 60 | 5 61 | 62 | 63 | 64 | 65 | 66 | 10 67 | 10 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /BonVision/CreateSparseNoiseGrid.cs: -------------------------------------------------------------------------------- 1 | using Bonsai; 2 | using System; 3 | using System.ComponentModel; 4 | using System.Linq; 5 | using System.Reactive.Linq; 6 | using MathNet.Numerics.Distributions; 7 | using MathNet.Numerics; 8 | 9 | namespace BonVision 10 | { 11 | [Combinator] 12 | [Description("Generates a non-overlapping distribution of values in a grid.")] 13 | [WorkflowElementCategory(ElementCategory.Transform)] 14 | public class CreateSparseNoiseGrid 15 | { 16 | [Description("The number of rows in the sparse noise grid.")] 17 | public int Rows { get; set; } 18 | 19 | [Description("The number of columns in the sparse noise grid.")] 20 | public int Columns { get; set; } 21 | 22 | [Description("The number of active quads in the generated grid.")] 23 | public int ActiveQuads { get; set; } 24 | 25 | public IObservable Process(IObservable source) 26 | { 27 | return Process(source, Observable.Return(new Random())); 28 | } 29 | 30 | public IObservable Process(IObservable source, IObservable randomSource) 31 | { 32 | var distributionSource = randomSource.Select(random => new DiscreteUniform(0, 1, random)); 33 | return source.CombineLatest( 34 | distributionSource, 35 | (input, distribution) => 36 | { 37 | var result = new byte[Rows * Columns]; 38 | for (int i = 0; i < result.Length; i++) 39 | { 40 | if (i < ActiveQuads) result[i] = (byte)(distribution.Sample() * byte.MaxValue); 41 | else result[i] = 128; 42 | } 43 | 44 | Combinatorics.SelectPermutationInplace(result, distribution.RandomSource); 45 | return result; 46 | }); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /BonVision/CreateSphereGrid.cs: -------------------------------------------------------------------------------- 1 | using Bonsai; 2 | using System; 3 | using System.ComponentModel; 4 | using System.Linq; 5 | using System.Reactive.Linq; 6 | using OpenTK; 7 | 8 | namespace BonVision 9 | { 10 | [Combinator] 11 | [Description("Creates a UV-mapped spherical vertex grid, with the specified degree boundaries.")] 12 | [WorkflowElementCategory(ElementCategory.Source)] 13 | public class CreateSphereGrid 14 | { 15 | public CreateSphereGrid() 16 | { 17 | Left = -180; 18 | Right = 180; 19 | Bottom = -90; 20 | Top = 90; 21 | } 22 | 23 | [Description("The left edge of the sphere grid, in degrees.")] 24 | public float Left { get; set; } 25 | 26 | [Description("The right edge of the sphere grid, in degrees.")] 27 | public float Right { get; set; } 28 | 29 | [Description("The bottom edge of the sphere grid, in degrees.")] 30 | public float Bottom { get; set; } 31 | 32 | [Description("The top edge of the sphere grid, in degrees.")] 33 | public float Top { get; set; } 34 | 35 | Tuple CreateMeshData() 36 | { 37 | const int Rings = 180; 38 | const int Segments = 360; 39 | const float LatitudeStep = MathHelper.Pi / Rings; 40 | const float LongitudeStep = MathHelper.TwoPi / Segments; 41 | var latitudeMin = MathHelper.Clamp((int)Math.Min(Top, Bottom) + Rings / 2, 0, Rings); 42 | var latitudeMax = MathHelper.Clamp((int)Math.Max(Top, Bottom) + Rings / 2, 0, Rings); 43 | var longitudeMin = MathHelper.Clamp((int)Math.Min(Left, Right) + Segments / 2, 0, Segments); 44 | var longitudeMax = MathHelper.Clamp((int)Math.Max(Left, Right) + Segments / 2, 0, Segments); 45 | 46 | var vid = 0; 47 | var iid = 0; 48 | var vertices = new Matrix2x3[(Rings - 1) * (Segments + 1) + 2 * Segments]; 49 | var indices = new int[3 * (2 * (Rings - 2) * Segments + 2 * Segments)]; 50 | for (int i = 0; i <= Rings; i++) 51 | { 52 | var pole = i == 0 || i == Rings; 53 | var latitude = (Rings - i) * LatitudeStep; 54 | 55 | for (int j = 0; j <= Segments; j++) 56 | { 57 | if (pole && j == Segments) break; 58 | var longitude = j * LongitudeStep + MathHelper.PiOver2; 59 | 60 | var x = (float)(Math.Sin(latitude) * Math.Cos(longitude)); 61 | var y = (float)(Math.Cos(latitude)); 62 | var z = (float)(Math.Sin(latitude) * Math.Sin(longitude)); 63 | var u = (j - longitudeMin) / (float)(longitudeMax - longitudeMin); 64 | var v = (i - latitudeMin) / (float)(latitudeMax - latitudeMin); 65 | vertices[vid++] = new Matrix2x3(x, y, z, u, v, 1); 66 | if (i <= latitudeMin || i > latitudeMax || j < longitudeMin || j >= longitudeMax) 67 | { 68 | // clamp spherical grid 69 | continue; 70 | } 71 | 72 | // generate north pole faces 73 | if (i == 1 && j > 0) 74 | { 75 | indices[iid++] = j - 1; 76 | indices[iid++] = Segments + (j - 1); 77 | indices[iid++] = Segments + j; 78 | } 79 | 80 | // generate equatorial faces 81 | if (i > 1 && !pole && j < Segments) 82 | { 83 | indices[iid++] = vid - Segments - 1; 84 | indices[iid++] = vid - Segments - 2; 85 | indices[iid++] = vid - 1; 86 | 87 | indices[iid++] = vid - 1; 88 | indices[iid++] = vid; 89 | indices[iid++] = vid - Segments - 1; 90 | } 91 | 92 | // generate south pole faces 93 | if (i == Rings - 1 && j > 0) 94 | { 95 | indices[iid++] = vertices.Length - 2 * Segments + (j - 2); 96 | indices[iid++] = vertices.Length - Segments + (j - 1); 97 | indices[iid++] = vertices.Length - 2 * Segments + (j - 1); 98 | } 99 | } 100 | } 101 | 102 | return Tuple.Create(vertices, indices); 103 | } 104 | 105 | public IObservable> Process() 106 | { 107 | return Observable.Defer(() => Observable.Return(CreateMeshData())); 108 | } 109 | 110 | public IObservable> Process(IObservable source) 111 | { 112 | return source.Select(input => CreateMeshData()); 113 | } 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /BonVision/CreateTextureScale.cs: -------------------------------------------------------------------------------- 1 | using Bonsai; 2 | using OpenTK; 3 | using System; 4 | using System.ComponentModel; 5 | using System.Linq; 6 | using System.Reactive.Linq; 7 | 8 | namespace BonVision 9 | { 10 | [Description("Creates a texture scale vector.")] 11 | public class CreateTextureScale : Source 12 | { 13 | public CreateTextureScale() 14 | { 15 | X = Y = 1; 16 | } 17 | 18 | [Range(0, 2)] 19 | [Editor(DesignTypes.SliderEditor, DesignTypes.UITypeEditor)] 20 | [Description("The texture scale factor on the x-axis.")] 21 | public float X { get; set; } 22 | 23 | [Range(0, 2)] 24 | [Editor(DesignTypes.SliderEditor, DesignTypes.UITypeEditor)] 25 | [Description("The texture scale factor on the y-axis.")] 26 | public float Y { get; set; } 27 | 28 | public override IObservable Generate() 29 | { 30 | return Observable.Defer(() => Observable.Return(new Vector2(X, Y))); 31 | } 32 | 33 | public IObservable Generate(IObservable source) 34 | { 35 | return source.Select(input => new Vector2(X, Y)); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /BonVision/CreateTextureShift.cs: -------------------------------------------------------------------------------- 1 | using Bonsai; 2 | using OpenTK; 3 | using System; 4 | using System.ComponentModel; 5 | using System.Linq; 6 | using System.Reactive.Linq; 7 | 8 | namespace BonVision 9 | { 10 | [Description("Creates a texture shift vector.")] 11 | public class CreateTextureShift : Source 12 | { 13 | [Range(-1, 1)] 14 | [Editor(DesignTypes.SliderEditor, DesignTypes.UITypeEditor)] 15 | [Description("The texture shift on the x-axis.")] 16 | public float X { get; set; } 17 | 18 | [Range(-1, 1)] 19 | [Editor(DesignTypes.SliderEditor, DesignTypes.UITypeEditor)] 20 | [Description("The texture shift on the y-axis.")] 21 | public float Y { get; set; } 22 | 23 | public override IObservable Generate() 24 | { 25 | return Observable.Defer(() => Observable.Return(new Vector2(X, Y))); 26 | } 27 | 28 | public IObservable Generate(IObservable source) 29 | { 30 | return source.Select(input => new Vector2(X, Y)); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /BonVision/CreateVertexGrid.cs: -------------------------------------------------------------------------------- 1 | using Bonsai; 2 | using System; 3 | using System.ComponentModel; 4 | using System.Linq; 5 | using System.Reactive.Linq; 6 | using OpenTK; 7 | 8 | namespace BonVision 9 | { 10 | [Combinator] 11 | [Description("Converts a sequence of vertices in the format (x,y,u,v,b) into a quad vertex grid.")] 12 | [WorkflowElementCategory(ElementCategory.Transform)] 13 | public class CreateVertexGrid 14 | { 15 | public IObservable Process(IObservable source) 16 | { 17 | return source.ToArray().Select(value => 18 | { 19 | // The number of rows in the grid is equal to the number of distinct values of 'v' 20 | var rows = value.Select(row => row[3]).Distinct().Count(); 21 | var cols = value.Length / rows; 22 | 23 | var i = 0; 24 | var result = new Matrix2x3[(rows - 1) * (cols - 1) * 4]; 25 | for (int j = 0; j < rows - 1; j++) 26 | { 27 | for (int k = 0; k < cols - 1; k++) 28 | { 29 | // Skip quads at the transition between vertical rings 30 | if (k % rows == rows - 1) continue; 31 | 32 | // Compute the indices for each vertex in the quad 33 | var v0 = j * cols + k; 34 | var v1 = j * cols + k + 1; 35 | var v2 = (j + 1) * cols + k + 1; 36 | var v3 = (j + 1) * cols + k; 37 | 38 | // Invert y-axis in both position and tex coordinates 39 | result[i++] = new Matrix2x3(value[v0][0], -value[v0][1], 0, value[v0][2], 1 - value[v0][3], value[v0][4]); 40 | result[i++] = new Matrix2x3(value[v1][0], -value[v1][1], 0, value[v1][2], 1 - value[v1][3], value[v1][4]); 41 | result[i++] = new Matrix2x3(value[v2][0], -value[v2][1], 0, value[v2][2], 1 - value[v2][3], value[v2][4]); 42 | result[i++] = new Matrix2x3(value[v3][0], -value[v3][1], 0, value[v3][2], 1 - value[v3][3], value[v3][4]); 43 | } 44 | } 45 | return result; 46 | }); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /BonVision/DegreeConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.Globalization; 4 | 5 | namespace BonVision 6 | { 7 | class DegreeConverter : SingleConverter 8 | { 9 | public static double RadianToDegree(double value) 10 | { 11 | return value * (180.0 / Math.PI); 12 | } 13 | 14 | public static double DegreeToRadian(double value) 15 | { 16 | return value * (Math.PI / 180.0); 17 | } 18 | 19 | public static float RadianToDegree(float value) 20 | { 21 | return (float)RadianToDegree((double)value); 22 | } 23 | 24 | public static float DegreeToRadian(float value) 25 | { 26 | return (float)DegreeToRadian((double)value); 27 | } 28 | 29 | public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) 30 | { 31 | if (value is string) 32 | { 33 | value = ((string)value).TrimEnd('°'); 34 | } 35 | 36 | value = base.ConvertFrom(context, culture, value); 37 | return DegreeToRadian((float)value); 38 | } 39 | 40 | public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) 41 | { 42 | value = RadianToDegree(Convert.ToSingle(value)); 43 | var result = base.ConvertTo(context, culture, value, destinationType); 44 | if (destinationType == typeof(string)) 45 | { 46 | return (string)result + "°"; 47 | } 48 | 49 | return result; 50 | } 51 | } 52 | 53 | class NullableDegreeConverter : NullableConverter 54 | { 55 | readonly TypeConverter degreeConverter; 56 | 57 | public NullableDegreeConverter(Type type) 58 | : base(type) 59 | { 60 | degreeConverter = new DegreeConverter(); 61 | } 62 | 63 | public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) 64 | { 65 | if (string.IsNullOrEmpty((string)value)) return base.ConvertFrom(context, culture, value); 66 | else return degreeConverter.ConvertFrom(context, culture, value); 67 | } 68 | 69 | public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) 70 | { 71 | if (value != null) return degreeConverter.ConvertTo(context, culture, value, destinationType); 72 | return base.ConvertTo(context, culture, value, destinationType); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /BonVision/Environment/CubemapView.bonsai: -------------------------------------------------------------------------------- 1 |  2 | 9 | Specifies multiple views used to render the six different faces of a cubemap texture. 10 | 11 | 12 | 13 | Source1 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 0 24 | 0 25 | 0 26 | 27 | 0.1 28 | 1000 29 | 30 | 31 | 32 | 33 | 34 | 35 | Eye 36 | 37 | 0 38 | 0 39 | 0 40 | 41 | 42 | 43 | 44 | 45 | 46 | new( 47 | Item1.ViewMatrix as ViewMatrix, 48 | Item1.ProjectionMatrix as ProjectionMatrix, 49 | Item2 as Light) 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /BonVision/Environment/DrawViewport.bonsai: -------------------------------------------------------------------------------- 1 |  2 | 6 | Renders all currently stored draw commands to the specified viewport. 7 | 8 | 9 | 10 | Source1 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 0 21 | 0 22 | 1 23 | 1 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /BonVision/Environment/GammaCorrection.bonsai: -------------------------------------------------------------------------------- 1 |  2 | 8 | Renders the current scene to a texture and applies gamma correction as a post-processing effect. 9 | 10 | 11 | 12 | Source1 13 | 14 | 15 | 16 | 0 17 | 0 18 | 1 19 | 1 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | Gray 29 | DepthBufferBit ColorBufferBit 30 | 31 | 32 | Rgb 33 | ClampToEdge 34 | ClampToEdge 35 | Linear 36 | Linear 37 | 38 | 39 | 40 | 41 | Texture0 42 | Gamma 43 | Texture2D 44 | 45 | 46 | 47 | 48 | 49 | 50 | FileName 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | Rgba 63 | ClampToEdge 64 | ClampToEdge 65 | Linear 66 | Linear 67 | 68 | Unchanged 69 | Vertical 70 | 71 | 72 | 73 | 74 | 75 | 76 | Item2 77 | 78 | 79 | 80 | Texture1 81 | Gamma 82 | Texture2D 83 | 84 | 85 | 86 | 87 | Gamma 88 | ViewportQuad 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /BonVision/Environment/HmdView.bonsai: -------------------------------------------------------------------------------- 1 |  2 | 10 | Specifies stereo views used to render head-mounted display environments. 11 | 12 | 13 | 14 | 15 | Source1 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 0.1 24 | 100 25 | 26 | 27 | 28 | LeftViewMatrix,LeftProjectionMatrix 29 | 30 | 31 | RightViewMatrix,RightProjectionMatrix 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | Eye 41 | 42 | 0 43 | 1 44 | 1 45 | 46 | 47 | 48 | 49 | 50 | 51 | new( 52 | Item1.Item1 as ViewMatrix, 53 | Item1.Item2 as ProjectionMatrix, 54 | Item2 as Light) 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /BonVision/Environment/MeshMapping.bonsai: -------------------------------------------------------------------------------- 1 |  2 | 8 | Renders the current scene to a texture and applies mesh mapping and brightness correction as a post-processing effect. 9 | 10 | 11 | 12 | Source1 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | Gray 21 | DepthBufferBit ColorBufferBit 22 | 23 | 24 | Rgba 25 | ClampToEdge 26 | ClampToEdge 27 | Linear 28 | Linear 29 | 30 | 31 | 32 | 33 | Texture0 34 | MeshMap 35 | Texture2D 36 | 37 | 38 | 39 | 40 | MeshMap 41 | MeshMap 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | , 51 | %f 52 | 0 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | MeshMap 63 | Quads 64 | DynamicDraw 65 | 66 | 67 | 3 68 | false 69 | Float 70 | 71 | 72 | 3 73 | false 74 | Float 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /BonVision/Environment/NormalizedView.bonsai: -------------------------------------------------------------------------------- 1 |  2 | 6 | Specifies an orthographic view with normalized screen coordinates for rapid prototyping of 2D environments. 7 | 8 | 9 | 10 | Source1 11 | 12 | 13 | 14 | 15 | 16 | 17 | 2 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 4 28 | 2 29 | -500 30 | 500 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /BonVision/Environment/OrthographicView.bonsai: -------------------------------------------------------------------------------- 1 |  2 | 6 | Specifies an orthographic view, commonly used for 2D stimulus environments. 7 | 8 | 9 | 10 | Source1 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -180 21 | 180 22 | -90 23 | 90 24 | -500 25 | 500 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /BonVision/Environment/PerspectiveMapping.bonsai: -------------------------------------------------------------------------------- 1 |  2 | 6 | Renders the current scene to a texture and applies perspective mapping as a post-processing effect. 7 | 8 | 9 | 10 | Source1 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | Gray 19 | DepthBufferBit ColorBufferBit 20 | 21 | 22 | Rgba 23 | ClampToEdge 24 | ClampToEdge 25 | Linear 26 | Linear 27 | 28 | 29 | 30 | 31 | Texture0 32 | PerspectiveMap 33 | Texture2D 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | transform 45 | PerspectiveMap 46 | 47 | 48 | 49 | 50 | PerspectiveMap 51 | ViewportQuad 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /BonVision/Environment/PerspectiveView.bonsai: -------------------------------------------------------------------------------- 1 |  2 | 10 | Specifies a perspective view, commonly used for 3D stimulus environments. 11 | 12 | 13 | 14 | Source1 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 90 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 1.57079637 52 | 1.33333337 53 | 0.1 54 | 1000 55 | 56 | 57 | 58 | 59 | 60 | 1 61 | 1 62 | 2 63 | 64 | 65 | -0 66 | -0 67 | -1 68 | 69 | 70 | 0 71 | 1 72 | 0 73 | 74 | 75 | 76 | 77 | Eye 78 | 79 | 0 80 | 1 81 | 1 82 | 83 | 84 | 85 | 86 | 87 | 88 | new( 89 | Item1 as ViewMatrix, 90 | Item2 as ProjectionMatrix, 91 | Item3 as Light) 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | -------------------------------------------------------------------------------- /BonVision/Environment/RenderHmd.bonsai: -------------------------------------------------------------------------------- 1 |  2 | 7 | Renders all currently stored draw commands into a head-mounted display. Each pass renders one eye of the stereo display. 8 | 9 | 10 | 11 | Source1 12 | 13 | 14 | 15 | 0 16 | 2 17 | 18 | 19 | 20 | 21 | 22 | 23 | Black 24 | DepthBufferBit ColorBufferBit 25 | 26 | 27 | 28 | 29 | 1 30 | 2 31 | 32 | 33 | 34 | 35 | 36 | 37 | Black 38 | DepthBufferBit ColorBufferBit 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /BonVision/Environment/SphereMapping.bonsai: -------------------------------------------------------------------------------- 1 |  2 | 9 | Renders the current viewport to a cubemap texture which can be used for environmental mapping of physical screens around the origin. 10 | 11 | 12 | 13 | 14 | Source1 15 | 16 | 17 | UpdateSphereGrid 18 | 19 | 20 | 21 | Source1 22 | 23 | 24 | (-1 - M41) / M11 25 | 26 | 27 | (1 - M41) / M11 28 | 29 | 30 | (-1 - M42) / M22 31 | 32 | 33 | (1 - M42) / M22 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -180 52 | 180 53 | -90 54 | 90 55 | 56 | 57 | 58 | 59 | SphereMap 60 | Triangles 61 | StaticDraw 62 | 63 | 64 | 3 65 | false 66 | Float 67 | 68 | 69 | 3 70 | false 71 | Float 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 0 98 | 0 99 | 1 100 | 1 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | Gray 117 | DepthBufferBit ColorBufferBit 118 | 119 | 120 | Rgba 121 | Repeat 122 | Repeat 123 | Linear 124 | Linear 125 | 126 | 127 | 128 | 129 | Texture0 130 | MeshMap 131 | Texture2D 132 | 133 | 134 | 135 | 136 | 137 | 0 138 | 0 139 | 0 140 | 141 | 0.1 142 | 1000 143 | 144 | 145 | 146 | ViewMatrix 147 | 148 | 149 | 150 | 151 | 152 | 153 | 0 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | Prepend 164 | 0 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 0 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | Prepend 183 | 0 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 0 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | Prepend 202 | 0 203 | 204 | 205 | 206 | 207 | modelview 208 | MeshMap 209 | 210 | 211 | 212 | ProjectionMatrix 213 | 214 | 215 | 216 | projection 217 | MeshMap 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | MeshMap 226 | SphereMap 227 | 228 | 229 | 230 | 231 | 232 | Gray 233 | DepthBufferBit ColorBufferBit 234 | 235 | Rgb 236 | Linear 237 | Linear 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | -------------------------------------------------------------------------------- /BonVision/Environment/ViewMapping.bonsai: -------------------------------------------------------------------------------- 1 |  2 | 7 | Renders the environment using a view direction vector map for each fragment in the current viewport. 8 | 9 | 10 | 11 | Source1 12 | 13 | 14 | 15 | Texture0 16 | ViewMap 17 | TextureCubeMap 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | Rgb32f 28 | Repeat 29 | Repeat 30 | Linear 31 | Linear 32 | 33 | Unchanged 34 | Vertical 35 | 36 | 37 | 38 | 39 | 40 | 41 | Item2 42 | 43 | 44 | 45 | Texture1 46 | ViewMap 47 | Texture2D 48 | 49 | 50 | 51 | 52 | ViewMap 53 | ViewportQuad 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /BonVision/Environment/ViewWindow.bonsai: -------------------------------------------------------------------------------- 1 |  2 | 8 | Renders the environment from the perspective of a view window of the specified size, position and orientation relative to the origin. 9 | 10 | 11 | 12 | Source1 13 | 14 | 15 | 16 | Texture0 17 | SphereMap 18 | TextureCubeMap 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 20 28 | 15 29 | 30 | 31 | 32 | 33 | scale 34 | SphereMap 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 0 44 | 0 45 | 0 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 0 61 | 0 62 | 0 63 | 64 | 65 | 0 66 | 0 67 | -10 68 | 69 | 70 | 71 | 72 | Rotation,Translation 73 | 74 | 75 | 76 | 77 | 78 | 79 | transform 80 | SphereMap 81 | 82 | 83 | 84 | 85 | SphereMap 86 | ViewportQuad 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | -------------------------------------------------------------------------------- /BonVision/FieldOfViewProperty.cs: -------------------------------------------------------------------------------- 1 | using Bonsai; 2 | using System; 3 | using System.ComponentModel; 4 | using System.Linq; 5 | using System.Reactive.Linq; 6 | using System.Xml.Serialization; 7 | 8 | namespace BonVision 9 | { 10 | [Combinator] 11 | [DisplayName("FieldOfView")] 12 | [Description("Represents a workflow property specifying a camera field of view angle.")] 13 | [WorkflowElementCategory(ElementCategory.Source)] 14 | public class FieldOfViewProperty 15 | { 16 | float value; 17 | event Action ValueChanged; 18 | 19 | public FieldOfViewProperty() 20 | { 21 | Value = 90; 22 | } 23 | 24 | [XmlIgnore] 25 | [Range(0.00174532924, 3.13984728)] 26 | [TypeConverter(typeof(DegreeConverter))] 27 | [Description("The value of the camera field of view.")] 28 | [Editor(DesignTypes.SliderEditor, DesignTypes.UITypeEditor)] 29 | public float Value 30 | { 31 | get { return value; } 32 | set 33 | { 34 | this.value = value; 35 | OnValueChanged(this.value); 36 | } 37 | } 38 | 39 | [Browsable(false)] 40 | [XmlElement("Value")] 41 | public float ValueXml 42 | { 43 | get { return DegreeConverter.RadianToDegree(value); } 44 | set { this.value = DegreeConverter.DegreeToRadian(value); } 45 | } 46 | 47 | void OnValueChanged(float value) 48 | { 49 | var handler = ValueChanged; 50 | if (handler != null) 51 | { 52 | handler(value); 53 | } 54 | } 55 | 56 | public IObservable Process() 57 | { 58 | return Observable 59 | .Defer(() => Observable.Return((float)value)) 60 | .Concat(Observable.FromEvent( 61 | handler => ValueChanged += handler, 62 | handler => ValueChanged -= handler)); 63 | } 64 | 65 | public IObservable Process(IObservable source) 66 | { 67 | return source.Select(x => (float)value); 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /BonVision/Logging/EventLogger.bonsai: -------------------------------------------------------------------------------- 1 |  2 | 9 | Creates and initializes a CSV file, and matching behavior subject, on which to log events. 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Events 23 | 24 | 25 | 26 | 27 | 28 | GenerateFileName 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | Events 37 | 38 | 39 | 40 | 41 | 42 | 43 | FileName 44 | 45 | 46 | 47 | 48 | 49 | 50 | !string.IsNullOrEmpty(Item2) ? Item2 : Item1 + ".csv" 51 | 52 | 53 | 54 | 1 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | Events 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | Events.csv 85 | , 86 | false 87 | false 88 | None 89 | false 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /BonVision/Logging/FrameEventLogger.bonsai: -------------------------------------------------------------------------------- 1 |  2 | 9 | Creates and initializes a CSV file, and matching behavior subject, used to log events with frame timing. 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Events 23 | 24 | 25 | Source1 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | CsvLogger 35 | 36 | 37 | 38 | Source1 39 | 40 | 41 | TimeStep.ElapsedRealTime 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | Events 57 | 58 | 59 | 60 | 61 | 62 | new( 63 | Item2.Index as Frame, 64 | Item2.Value as Timestamp, 65 | Item1 as Value) 66 | 67 | 68 | 69 | 70 | 71 | GenerateFileName 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | Events 80 | 81 | 82 | 83 | 84 | 85 | 86 | FileName 87 | 88 | 89 | 90 | 91 | 92 | 93 | !string.IsNullOrEmpty(Item2) ? Item2 : Item1 + ".csv" 94 | 95 | 96 | 97 | 1 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | , 121 | false 122 | false 123 | None 124 | true 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | -------------------------------------------------------------------------------- /BonVision/Logging/LogEvent.bonsai: -------------------------------------------------------------------------------- 1 |  2 | 6 | Logs a value into the specified common event stream. 7 | 8 | 9 | 10 | Source1 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | FormatLog 23 | 24 | 25 | 26 | Source1 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | Events 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /BonVision/Models/Plane.obj: -------------------------------------------------------------------------------- 1 | o Plane 2 | v -0.5 -0.5 0.0 3 | v 0.5 -0.5 0.0 4 | v 0.5 0.5 0.0 5 | v -0.5 0.5 0.0 6 | vt 0.0 0.0 7 | vt 1.0 0.0 8 | vt 1.0 1.0 9 | vt 0.0 1.0 10 | vn 0.0 1.0 0.0 11 | s off 12 | f 1/1/1 2/2/1 3/3/1 4/4/1 13 | -------------------------------------------------------------------------------- /BonVision/Models/Quad.obj: -------------------------------------------------------------------------------- 1 | o Quad 2 | v -0.5 -0.5 0.0 3 | v 0.5 -0.5 0.0 4 | v 0.5 0.5 0.0 5 | v -0.5 0.5 0.0 6 | vt 0.0 0.0 7 | vt 1.0 0.0 8 | vt 1.0 1.0 9 | vt 0.0 1.0 10 | s off 11 | f 1/1 2/2 3/3 4/4 12 | -------------------------------------------------------------------------------- /BonVision/OptionalFloatProperty.cs: -------------------------------------------------------------------------------- 1 | using Bonsai; 2 | using System; 3 | using System.ComponentModel; 4 | using System.Linq; 5 | using System.Reactive.Linq; 6 | 7 | namespace BonVision 8 | { 9 | [Combinator] 10 | [DisplayName("OptionalFloat")] 11 | [Description("Represents a workflow property specifying an optional single-precision floating-point number.")] 12 | [WorkflowElementCategory(ElementCategory.Source)] 13 | public class OptionalFloatProperty 14 | { 15 | float? value; 16 | event Action ValueChanged; 17 | 18 | [Range(0, 1)] 19 | [Description("The optional value of the property.")] 20 | [Editor(DesignTypes.SliderEditor, DesignTypes.UITypeEditor)] 21 | public float? Value 22 | { 23 | get { return value; } 24 | set 25 | { 26 | this.value = value; 27 | ValueChanged?.Invoke(this.value); 28 | } 29 | } 30 | 31 | public bool HasValue 32 | { 33 | get { return value.HasValue; } 34 | set 35 | { 36 | if (value) 37 | { 38 | if (!this.value.HasValue) 39 | { 40 | this.value = 0.5f; 41 | } 42 | } 43 | else this.value = null; 44 | } 45 | } 46 | 47 | public IObservable Process() 48 | { 49 | return Observable 50 | .Defer(() => Observable.Return(value)) 51 | .Concat(Observable.FromEvent( 52 | handler => ValueChanged += handler, 53 | handler => ValueChanged -= handler)); 54 | } 55 | 56 | public IObservable Process(IObservable source) 57 | { 58 | return source.Select(x => value); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /BonVision/Primitives/BonVisionResources.bonsai: -------------------------------------------------------------------------------- 1 |  2 | 7 | Loads mesh and shader resources for rendering primitive stimuli. 8 | 9 | 10 | 11 | Source1 12 | 13 | 14 | 15 | 16 | 17 | Blend 18 | 19 | 20 | DepthTest 21 | 22 | 23 | SrcAlpha 24 | OneMinusSrcAlpha 25 | 26 | 27 | Lequal 28 | 29 | 30 | 31 | 32 | 33 | InternalResources 34 | 35 | 36 | 37 | Source1 38 | 39 | 40 | 41 | 42 | 43 | Quad 44 | BonVision:Models.Quad.obj 45 | 46 | 47 | ViewportQuad 48 | None 49 | 50 | 51 | MeshMap 52 | 53 | 54 | SphereMap 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | Plane 72 | BonVision:Models.Plane.obj 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | Checkerboard 82 | 83 | 84 | 85 | 86 | BonVision:Shaders.Quad.vert 87 | BonVision:Shaders.Checkerboard.frag 88 | 89 | 90 | Image 91 | 92 | 93 | 94 | 95 | tex 96 | Texture0 97 | Texture2D 98 | 99 | 100 | 101 | BonVision:Shaders.Quad.vert 102 | BonVision:Shaders.Image.frag 103 | 104 | 105 | Color 106 | 107 | 108 | 109 | 110 | BonVision:Shaders.Quad.vert 111 | BonVision:Shaders.Color.frag 112 | 113 | 114 | Gratings 115 | 116 | 117 | 118 | 119 | BonVision:Shaders.Gratings.vert 120 | BonVision:Shaders.Gratings.frag 121 | 122 | 123 | Circle 124 | 125 | 126 | 127 | 128 | BonVision:Shaders.Quad.vert 129 | BonVision:Shaders.Circle.frag 130 | 131 | 132 | CircleArray 133 | 134 | 135 | 136 | 137 | BonVision:Shaders.QuadArray.vert 138 | BonVision:Shaders.Circle.frag 139 | 140 | 141 | Model 142 | 143 | 144 | 145 | 146 | BonVision:Shaders.Model.vert 147 | BonVision:Shaders.Model.frag 148 | 149 | 150 | ModelArray 151 | 152 | 153 | 154 | 155 | BonVision:Shaders.ModelArray.vert 156 | BonVision:Shaders.Model.frag 157 | 158 | 159 | TexturedModel 160 | 161 | 162 | 163 | 164 | textureDiffuse 165 | Texture0 166 | Texture2D 167 | 168 | 169 | 170 | BonVision:Shaders.TexturedModel.vert 171 | BonVision:Shaders.TexturedModel.frag 172 | 173 | 174 | TexturedModelArray 175 | 176 | 177 | 178 | 179 | textureDiffuse 180 | Texture0 181 | Texture2D 182 | 183 | 184 | 185 | BonVision:Shaders.TexturedModelArray.vert 186 | BonVision:Shaders.TexturedModel.frag 187 | 188 | 189 | MeshMap 190 | 191 | 192 | 193 | 194 | BonVision:Shaders.MeshMap.vert 195 | BonVision:Shaders.MeshMap.frag 196 | 197 | 198 | PerspectiveMap 199 | 200 | 201 | 202 | 203 | tex 204 | Texture0 205 | Texture2D 206 | 207 | 208 | 209 | BonVision:Shaders.PerspectiveMap.vert 210 | BonVision:Shaders.PerspectiveMap.frag 211 | 212 | 213 | SphereMap 214 | 215 | 216 | 217 | 218 | tex 219 | Texture0 220 | TextureCubeMap 221 | 222 | 223 | 224 | BonVision:Shaders.SphereMap.vert 225 | BonVision:Shaders.SphereMap.frag 226 | 227 | 228 | ViewMap 229 | 230 | 231 | 232 | 233 | tex 234 | Texture0 235 | TextureCubeMap 236 | 237 | 238 | viewMap 239 | Texture1 240 | Texture2D 241 | 242 | 243 | 244 | BonVision:Shaders.Quad.vert 245 | BonVision:Shaders.ViewMap.frag 246 | 247 | 248 | Gamma 249 | 250 | 251 | 252 | 253 | tex 254 | Texture0 255 | Texture2D 256 | 257 | 258 | lut 259 | Texture1 260 | Texture2D 261 | 262 | 263 | 264 | BonVision:Shaders.Quad.vert 265 | BonVision:Shaders.Gamma.frag 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | -------------------------------------------------------------------------------- /BonVision/Primitives/DrawCheckerboard.bonsai: -------------------------------------------------------------------------------- 1 |  2 | 7 | Draws a parameterized checkerboard stimulus. 8 | 9 | 10 | 11 | Source1 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 0 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | Transform 44 | 45 | 46 | 47 | Source1 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | Prepend 57 | 0 58 | 0 59 | 0 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | Prepend 72 | 0 73 | 74 | 75 | 76 | 77 | Prepend 78 | 1 79 | 1 80 | 1 81 | 82 | 83 | 84 | 85 | transform 86 | Checkerboard 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | PhaseFrequency 105 | 106 | 107 | 108 | Source1 109 | 110 | 111 | 112 | 113 | 114 | 115 | 3 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 3 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 3 139 | 3 140 | 141 | 142 | 143 | 144 | frequency 145 | Checkerboard 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 0 154 | 155 | 156 | 157 | 158 | phase 159 | Checkerboard 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | Checkerboard 183 | Quad 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | -------------------------------------------------------------------------------- /BonVision/Primitives/DrawCircle.bonsai: -------------------------------------------------------------------------------- 1 |  2 | 7 | Draws a single colored circle. 8 | 9 | 10 | 11 | Source1 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | X 23 | 0.1 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | Transform 33 | 34 | 35 | 36 | Source1 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | Prepend 46 | 0 47 | 0 48 | 0 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | Prepend 58 | 0.1 59 | 0.1 60 | 1 61 | 62 | 63 | 64 | 65 | transform 66 | Circle 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 1 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 1 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 1 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 1 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 1 136 | 1 137 | 1 138 | 1 139 | 140 | 141 | 142 | 143 | color 144 | Circle 145 | 146 | 147 | 148 | 149 | Circle 150 | Quad 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | -------------------------------------------------------------------------------- /BonVision/Primitives/DrawCircleArray.bonsai: -------------------------------------------------------------------------------- 1 |  2 | 8 | Draws multiple colored circles using the specified position data array. 9 | 10 | 11 | 12 | Source1 13 | 14 | 15 | 16 | projection 17 | CircleArray 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | X 30 | 0.04 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | Transform 40 | 41 | 42 | 43 | Source1 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 0 53 | 0 54 | 0 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | Prepend 64 | 0.04 65 | 0.04 66 | 1 67 | 68 | 69 | 70 | 71 | transform 72 | CircleArray 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 1 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 1 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 1 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 1 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 1 142 | 1 143 | 1 144 | 1 145 | 146 | 147 | 148 | 149 | color 150 | CircleArray 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | Item1 167 | 168 | 169 | 170 | CircleArray 171 | Quad 172 | DynamicDraw 173 | 174 | 175 | 2 176 | false 177 | Float 178 | 1 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | -------------------------------------------------------------------------------- /BonVision/Primitives/DrawImage.bonsai: -------------------------------------------------------------------------------- 1 |  2 | 7 | Draws an affine transformed 2D image. 8 | 9 | 10 | 11 | Source1 12 | 13 | 14 | 15 | 16 | 17 | 18 | 0 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | Texture0 32 | Image 33 | 34 | Texture2D 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | Transform 46 | 47 | 48 | 49 | Source1 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | Prepend 59 | 0 60 | 0 61 | 0 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | Prepend 74 | 0 75 | 76 | 77 | 78 | 79 | Prepend 80 | 1 81 | 1 82 | 1 83 | 84 | 85 | 86 | 87 | transform 88 | Image 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | ScaleShift 113 | 114 | 115 | 116 | Source1 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 1 125 | 1 126 | 127 | 128 | 129 | 130 | scale 131 | Image 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 0 141 | 0 142 | 143 | 144 | 145 | 146 | shift 147 | Image 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | Image 166 | Quad 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | -------------------------------------------------------------------------------- /BonVision/Primitives/DrawModel.bonsai: -------------------------------------------------------------------------------- 1 |  2 | 9 | Draws a transformed 3D model stimulus. 10 | 11 | 12 | 13 | Source1 14 | 15 | 16 | ViewMatrix 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | Prepend 26 | 0 27 | 0 28 | 0 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 0 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | Prepend 61 | 0 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 0 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | Prepend 80 | 0 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 0 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | Prepend 99 | 0 100 | 101 | 102 | 103 | 104 | Prepend 105 | 1 106 | 1 107 | 1 108 | 109 | 110 | 111 | 112 | modelview 113 | Model 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | normalMatrix 122 | Model 123 | 124 | 125 | 126 | ProjectionMatrix 127 | 128 | 129 | 130 | projection 131 | Model 132 | 133 | 134 | 135 | Light 136 | 137 | 138 | 139 | light 140 | Model 141 | 142 | 143 | 144 | 145 | 146 | 147 | UpdateMaterial 148 | 149 | 150 | 151 | Source1 152 | 153 | 154 | 155 | 156 | 157 | Eye 158 | 159 | 0.2 160 | 0.2 161 | 0.2 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 0.2 174 | 0.2 175 | 0.2 176 | 1 177 | 178 | 179 | 180 | 181 | colorAmbient 182 | Model 183 | 184 | 185 | 186 | 187 | 188 | 189 | Eye 190 | 191 | 0.8 192 | 0.8 193 | 0.8 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 0.8 206 | 0.8 207 | 0.8 208 | 1 209 | 210 | 211 | 212 | 213 | colorDiffuse 214 | Model 215 | 216 | 217 | 218 | 219 | 220 | 221 | Eye 222 | 223 | 0.8 224 | 0.8 225 | 0.8 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 0.8 238 | 0.8 239 | 0.8 240 | 1 241 | 242 | 243 | 244 | 245 | colorSpecular 246 | Model 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 10 255 | 256 | 257 | 258 | 259 | shininess 260 | Model 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | Model 291 | Plane 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | -------------------------------------------------------------------------------- /BonVision/Primitives/DrawQuad.bonsai: -------------------------------------------------------------------------------- 1 |  2 | 7 | Draws a single colored quad. 8 | 9 | 10 | 11 | Source1 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 0 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | Transform 35 | 36 | 37 | 38 | Source1 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | Prepend 48 | 0 49 | 0 50 | 0 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | Prepend 63 | 0 64 | 65 | 66 | 67 | 68 | Prepend 69 | 1 70 | 1 71 | 1 72 | 73 | 74 | 75 | 76 | transform 77 | Color 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 1 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 1 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 1 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 1 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 1 149 | 1 150 | 1 151 | 1 152 | 153 | 154 | 155 | 156 | color 157 | Color 158 | 159 | 160 | 161 | 162 | Color 163 | Quad 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | -------------------------------------------------------------------------------- /BonVision/Primitives/DrawSceneModel.bonsai: -------------------------------------------------------------------------------- 1 |  2 | 9 | Draws a transformed 3D scene stimulus. 10 | 11 | 12 | 13 | Source1 14 | 15 | 16 | ViewMatrix 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | Prepend 26 | 0 27 | 0 28 | 0 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 0 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | Prepend 52 | 0 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 0 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | Prepend 71 | 0 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 0 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | Prepend 90 | 0 91 | 92 | 93 | 94 | 95 | Prepend 96 | 1 97 | 1 98 | 1 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | ProjectionMatrix 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | -------------------------------------------------------------------------------- /BonVision/Primitives/DrawVideo.bonsai: -------------------------------------------------------------------------------- 1 |  2 | 7 | Draw and update an affine transformed 2D video texture. 8 | 9 | 10 | 11 | Source1 12 | 13 | 14 | Source2 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 0 24 | false 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | Source1 35 | 36 | 37 | Item2.Value 38 | 39 | 40 | 41 | Texture0 42 | Image 43 | Texture2D 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | Item1 57 | 58 | 59 | Index 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 0 76 | 77 | 1 78 | 1 79 | 0 80 | 0 81 | 0 82 | 1 83 | 1 84 | 0 85 | 0 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /BonVision/Primitives/ParameterRange.bonsai: -------------------------------------------------------------------------------- 1 |  2 | 8 | Generates a linear range of values between min and max. 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | Count 20 | 10 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 0 30 | 10 31 | 32 | 33 | 34 | 35 | 1 36 | 37 | 38 | 39 | Count 40 | 10 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 1 50 | 10 51 | 0 52 | 1 53 | Linear 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /BonVision/Primitives/RangeAnimation.bonsai: -------------------------------------------------------------------------------- 1 |  2 | 9 | Animates a linear range of values between min and max at the specified cycles per second. 10 | 11 | 12 | 13 | 14 | 15 | 16 | TimeStep.ElapsedTime 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 0 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 1 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | Source1 47 | 48 | 49 | single(it) 50 | 51 | 52 | 53 | 1 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 0 68 | 1 69 | -1 70 | 1 71 | Linear 72 | 73 | 74 | 75 | single(it) 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /BonVision/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using Bonsai; 2 | 3 | // General Information about an assembly is controlled through the following 4 | // set of attributes. Change these attribute values to modify the information 5 | // associated with an assembly. 6 | [assembly: XmlNamespacePrefix("clr-namespace:BonVision", "bv")] 7 | -------------------------------------------------------------------------------- /BonVision/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "Bonsai": { 4 | "commandName": "Executable", 5 | "executablePath": "$(registry:HKEY_CURRENT_USER\\Software\\Goncalo Lopes\\Bonsai@InstallDir)Bonsai.exe", 6 | "commandLineArgs": "--lib:$(TargetDir)." 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /BonVision/RotationConverter.cs: -------------------------------------------------------------------------------- 1 | using Bonsai; 2 | using OpenCV.Net; 3 | using System; 4 | using System.ComponentModel; 5 | using System.Globalization; 6 | 7 | namespace BonVision 8 | { 9 | class RotationConverter : NumericRecordConverter 10 | { 11 | public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) 12 | { 13 | var rotation = (Point3d)base.ConvertFrom(context, culture, value); 14 | return new Point3d( 15 | DegreeConverter.DegreeToRadian(rotation.X), 16 | DegreeConverter.DegreeToRadian(rotation.Y), 17 | DegreeConverter.DegreeToRadian(rotation.Z)); 18 | } 19 | 20 | public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) 21 | { 22 | var rotation = (Point3d)value; 23 | value = new Point3d( 24 | DegreeConverter.RadianToDegree(rotation.X), 25 | DegreeConverter.RadianToDegree(rotation.Y), 26 | DegreeConverter.RadianToDegree(rotation.Z)); 27 | return base.ConvertTo(context, culture, value, destinationType); 28 | } 29 | 30 | public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes) 31 | { 32 | var baseProperties = base.GetProperties(context, value, attributes); 33 | 34 | var converterAttribute = new TypeConverterAttribute(typeof(DegreeConverter)); 35 | var editorAttribute = new EditorAttribute(DesignTypes.SliderEditor, DesignTypes.UITypeEditor); 36 | var angleAttributes = new Attribute[] { new RangeAttribute(-Math.PI, Math.PI), converterAttribute, editorAttribute }; 37 | 38 | var properties = new PropertyDescriptor[3]; 39 | properties[0] = new PropertyDescriptorWrapper("X", baseProperties["X"], angleAttributes); 40 | properties[1] = new PropertyDescriptorWrapper("Y", baseProperties["Y"], angleAttributes); 41 | properties[2] = new PropertyDescriptorWrapper("Z", baseProperties["Z"], angleAttributes); 42 | return new PropertyDescriptorCollection(properties); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /BonVision/RotationProperty.cs: -------------------------------------------------------------------------------- 1 | using Bonsai; 2 | using OpenCV.Net; 3 | using System; 4 | using System.ComponentModel; 5 | using System.Linq; 6 | using System.Reactive.Linq; 7 | using System.Xml.Serialization; 8 | 9 | namespace BonVision 10 | { 11 | [Combinator] 12 | [DisplayName("Rotation")] 13 | [Description("Represents a workflow property specifying a rotation in euler angle format.")] 14 | [WorkflowElementCategory(ElementCategory.Source)] 15 | public class RotationProperty 16 | { 17 | Point3d value; 18 | event Action ValueChanged; 19 | 20 | [XmlIgnore] 21 | [TypeConverter(typeof(RotationConverter))] 22 | [Description("The value of the rotation vector, in euler angle format.")] 23 | public Point3d Value 24 | { 25 | get { return value; } 26 | set 27 | { 28 | this.value = value; 29 | OnValueChanged(this.value); 30 | } 31 | } 32 | 33 | [Browsable(false)] 34 | [XmlElement("Value")] 35 | public Point3d ValueXml 36 | { 37 | get 38 | { 39 | var x = DegreeConverter.RadianToDegree(value.X); 40 | var y = DegreeConverter.RadianToDegree(value.Y); 41 | var z = DegreeConverter.RadianToDegree(value.Z); 42 | return new Point3d(x, y, z); 43 | } 44 | set 45 | { 46 | var x = DegreeConverter.DegreeToRadian(value.X); 47 | var y = DegreeConverter.DegreeToRadian(value.Y); 48 | var z = DegreeConverter.DegreeToRadian(value.Z); 49 | this.value = new Point3d(x, y, z); 50 | } 51 | } 52 | 53 | void OnValueChanged(Point3d value) 54 | { 55 | ValueChanged?.Invoke(value); 56 | } 57 | 58 | public IObservable Process() 59 | { 60 | return Observable 61 | .Defer(() => Observable.Return(value)) 62 | .Concat(Observable.FromEvent( 63 | handler => ValueChanged += handler, 64 | handler => ValueChanged -= handler)); 65 | } 66 | 67 | public IObservable Process(IObservable source) 68 | { 69 | return source.Select(x => value); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /BonVision/SampleMany.cs: -------------------------------------------------------------------------------- 1 | using Bonsai; 2 | using System; 3 | using System.ComponentModel; 4 | using System.Linq; 5 | using System.Reactive.Linq; 6 | using MathNet.Numerics.Distributions; 7 | 8 | namespace BonVision 9 | { 10 | [Obsolete] 11 | [Combinator] 12 | [Description("Draws multiple random samples from the input distribution.")] 13 | [WorkflowElementCategory(ElementCategory.Combinator)] 14 | public class SampleMany 15 | { 16 | public SampleMany() 17 | { 18 | Count = 1; 19 | } 20 | 21 | [Description("The number of random samples to draw.")] 22 | public int Count { get; set; } 23 | 24 | public IObservable Process(IObservable source) 25 | { 26 | return source.SelectMany(distribution => distribution.Samples().Take(Count)); 27 | } 28 | 29 | public IObservable Process(IObservable source) 30 | { 31 | return source.SelectMany(distribution => distribution.Samples().Take(Count)); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /BonVision/Shaders/Checkerboard.frag: -------------------------------------------------------------------------------- 1 | #version 400 2 | uniform vec2 frequency = vec2(1,1); 3 | uniform int phase; 4 | in vec2 texCoord; 5 | out vec4 fragColor; 6 | 7 | void main() 8 | { 9 | float bitH = uint(texCoord.x * frequency.x + phase) % 2; 10 | float bitV = uint(texCoord.y * frequency.y) % 2; 11 | bitH = bitV != 0 ? uint(bitH + 1) % 2 : bitH; 12 | float color = bitH != 0 ? 1 : 0; 13 | fragColor = vec4(color, color, color, 1); 14 | } 15 | -------------------------------------------------------------------------------- /BonVision/Shaders/Circle.frag: -------------------------------------------------------------------------------- 1 | #version 400 2 | uniform vec4 color = vec4(1); 3 | in vec2 texCoord; 4 | out vec4 fragColor; 5 | 6 | void main() 7 | { 8 | if (length(2 * texCoord - 1) > 1) 9 | discard; 10 | fragColor = color; 11 | } 12 | -------------------------------------------------------------------------------- /BonVision/Shaders/Color.frag: -------------------------------------------------------------------------------- 1 | #version 400 2 | uniform vec4 color; 3 | out vec4 fragColor; 4 | 5 | void main() 6 | { 7 | fragColor = color; 8 | } 9 | -------------------------------------------------------------------------------- /BonVision/Shaders/Gamma.frag: -------------------------------------------------------------------------------- 1 | #version 400 2 | uniform sampler2D tex; 3 | uniform sampler2D lut; 4 | in vec2 texCoord; 5 | out vec4 fragColor; 6 | 7 | void main() 8 | { 9 | vec4 texel = texture(tex, texCoord); 10 | texel.r = texture(lut, vec2(texel.r, 0.5)).r; 11 | texel.g = texture(lut, vec2(texel.g, 0.5)).g; 12 | texel.b = texture(lut, vec2(texel.b, 0.5)).b; 13 | fragColor = texel; 14 | } 15 | -------------------------------------------------------------------------------- /BonVision/Shaders/Gratings.frag: -------------------------------------------------------------------------------- 1 | #version 400 2 | const float pi = 3.1415926535897932384626433832795; 3 | const float sqrtTwoPi = sqrt(2 * pi); 4 | uniform vec2 frequency; 5 | uniform float radius = 1; 6 | uniform float aperture = 0; 7 | uniform float contrast = 1; 8 | uniform float phase = 0; 9 | uniform float opacity = 1; 10 | uniform float threshold = -1; 11 | in vec2 texCoord; 12 | out vec4 fragColor; 13 | 14 | void main() 15 | { 16 | float value = (texCoord.x - 0.5) * frequency.x + (texCoord.y - 0.5) * frequency.y + phase; 17 | if (threshold < 0) value = sin(value * 2 * pi); // sinewave 18 | else value = mod(value, 1) > threshold ? -1 : 1; // square modulation 19 | 20 | float envelope; 21 | float dist = length(texCoord * 2 - 1) / radius; // distance to the edge 22 | if (aperture == 0) envelope = dist < 1 ? 1 : 0; // square envelope 23 | else 24 | { 25 | // gaussian envelope 26 | dist = dist / aperture; 27 | envelope = exp(-0.5 * dist * dist); 28 | } 29 | value = value * contrast * envelope * 0.5 + 0.5; // contrast modulation 30 | fragColor = vec4(value, value, value, opacity * envelope); 31 | } 32 | -------------------------------------------------------------------------------- /BonVision/Shaders/Gratings.vert: -------------------------------------------------------------------------------- 1 | #version 400 2 | uniform mat4 transform = mat4(1); 3 | layout(location = 0) in vec2 vp; 4 | layout(location = 1) in vec2 vt; 5 | out vec2 texCoord; 6 | 7 | void main() 8 | { 9 | gl_Position = transform * vec4(vp, 0.0, 1.0); 10 | texCoord = vt; 11 | } 12 | -------------------------------------------------------------------------------- /BonVision/Shaders/Image.frag: -------------------------------------------------------------------------------- 1 | #version 400 2 | uniform vec2 shift; 3 | uniform vec2 scale = vec2(1, 1); 4 | uniform sampler2D tex; 5 | in vec2 texCoord; 6 | out vec4 fragColor; 7 | 8 | void main() 9 | { 10 | vec4 texel = texture(tex, texCoord * scale + shift); 11 | fragColor = texel; 12 | } 13 | -------------------------------------------------------------------------------- /BonVision/Shaders/MeshMap.frag: -------------------------------------------------------------------------------- 1 | #version 400 2 | uniform sampler2D tex; 3 | in vec3 texCoord; 4 | out vec4 fragColor; 5 | 6 | void main() 7 | { 8 | vec4 texel = texture(tex, texCoord.xy); 9 | fragColor = vec4(texel.rgb * texCoord.z, texel.a); 10 | } 11 | -------------------------------------------------------------------------------- /BonVision/Shaders/MeshMap.vert: -------------------------------------------------------------------------------- 1 | #version 400 2 | uniform mat4 modelview = mat4(1); 3 | uniform mat4 projection = mat4(1); 4 | layout(location = 0) in vec3 vp; 5 | layout(location = 1) in vec3 vt; 6 | out vec3 texCoord; 7 | 8 | void main() 9 | { 10 | gl_Position = projection * modelview * vec4(vp, 1.0); 11 | texCoord = vt; 12 | } 13 | -------------------------------------------------------------------------------- /BonVision/Shaders/Model.frag: -------------------------------------------------------------------------------- 1 | #version 400 2 | uniform vec4 colorAmbient; 3 | uniform vec4 colorDiffuse; 4 | uniform vec4 colorSpecular; 5 | uniform float shininess = 1.0; 6 | uniform vec3 light; 7 | in vec3 position; 8 | in vec3 normal; 9 | out vec4 fragColor; 10 | 11 | void main() 12 | { 13 | vec3 L = normalize(light - position); 14 | vec3 R = normalize(-reflect(L, normal)); 15 | vec3 V = normalize(-position); 16 | 17 | vec4 Iamb = colorAmbient; 18 | vec4 Idiff = vec4(colorDiffuse.rgb * max(dot(normal, L), 0.0), colorDiffuse.a); 19 | vec4 Ispec = colorSpecular * pow(max(dot(R, V), 0.0), shininess); 20 | 21 | fragColor = Iamb + Idiff + Ispec; 22 | } 23 | -------------------------------------------------------------------------------- /BonVision/Shaders/Model.vert: -------------------------------------------------------------------------------- 1 | #version 400 2 | uniform mat4 modelview; 3 | uniform mat4 projection; 4 | uniform mat4 normalMatrix; 5 | layout(location = 0) in vec3 vp; 6 | layout(location = 1) in vec3 vn; 7 | out vec3 position; 8 | out vec3 normal; 9 | 10 | void main() 11 | { 12 | vec4 v = modelview * vec4(vp, 1.0); 13 | gl_Position = projection * v; 14 | position = vec3(v); 15 | normal = normalize(vec3(normalMatrix * vec4(vn, 0.0))); 16 | } 17 | -------------------------------------------------------------------------------- /BonVision/Shaders/ModelArray.vert: -------------------------------------------------------------------------------- 1 | #version 400 2 | uniform mat4 modelview; 3 | uniform mat4 projection; 4 | uniform mat4 normalMatrix; 5 | layout(location = 0) in vec3 vp; 6 | layout(location = 1) in vec3 vn; 7 | layout(location = 2) in vec3 mr0; 8 | layout(location = 3) in vec3 mr1; 9 | layout(location = 4) in vec3 mr2; 10 | layout(location = 5) in vec3 mt; 11 | out vec3 position; 12 | out vec3 normal; 13 | 14 | void main() 15 | { 16 | mat3 mr = mat3(mr0, mr1, mr2); 17 | vec4 v = modelview * vec4(mr * vp + mt, 1.0); 18 | gl_Position = projection * v; 19 | position = vec3(v); 20 | normal = normalize(vec3(normalMatrix * vec4(mr * vn, 0.0))); 21 | } 22 | -------------------------------------------------------------------------------- /BonVision/Shaders/PerspectiveMap.frag: -------------------------------------------------------------------------------- 1 | #version 400 2 | uniform sampler2D tex; 3 | in vec2 texCoord; 4 | out vec4 fragColor; 5 | 6 | void main() 7 | { 8 | vec4 texel = texture(tex, texCoord); 9 | fragColor = texel; 10 | } 11 | -------------------------------------------------------------------------------- /BonVision/Shaders/PerspectiveMap.vert: -------------------------------------------------------------------------------- 1 | #version 400 2 | uniform mat4 transform = mat4(1); 3 | layout(location = 0) in vec2 vp; 4 | layout(location = 1) in vec2 vt; 5 | out vec2 texCoord; 6 | 7 | void main() 8 | { 9 | gl_Position = vec4(vp, 0.0, 1.0) * transform; 10 | texCoord = vt; 11 | } 12 | -------------------------------------------------------------------------------- /BonVision/Shaders/Quad.vert: -------------------------------------------------------------------------------- 1 | #version 400 2 | uniform mat4 transform = mat4(1); 3 | layout(location = 0) in vec2 vp; 4 | layout(location = 1) in vec2 vt; 5 | out vec2 texCoord; 6 | 7 | void main() 8 | { 9 | gl_Position = transform * vec4(vp, 0.0, 1.0); 10 | texCoord = vt; 11 | } 12 | -------------------------------------------------------------------------------- /BonVision/Shaders/QuadArray.vert: -------------------------------------------------------------------------------- 1 | #version 400 2 | uniform mat4 transform = mat4(1); 3 | uniform mat4 projection = mat4(1); 4 | layout(location = 0) in vec2 vp; 5 | layout(location = 1) in vec2 vt; 6 | layout(location = 2) in vec2 vo; 7 | out vec2 texCoord; 8 | 9 | void main() 10 | { 11 | vec4 position = transform * vec4(vp, 0.0, 1.0); 12 | gl_Position = projection * vec4(position.xy + vo, 0.0, 1.0); 13 | texCoord = vt; 14 | } 15 | -------------------------------------------------------------------------------- /BonVision/Shaders/SphereMap.frag: -------------------------------------------------------------------------------- 1 | #version 400 2 | uniform samplerCube tex; 3 | in vec4 texCoord; 4 | out vec4 fragColor; 5 | 6 | void main() 7 | { 8 | vec4 texel = texture(tex, texCoord.xyz); 9 | fragColor = texel; 10 | } 11 | -------------------------------------------------------------------------------- /BonVision/Shaders/SphereMap.vert: -------------------------------------------------------------------------------- 1 | #version 400 2 | uniform mat4 transform = mat4(1); 3 | uniform vec2 scale = vec2(1, 1); 4 | uniform vec2 shift; 5 | layout(location = 0) in vec2 vp; 6 | layout(location = 1) in vec2 vt; 7 | out vec4 texCoord; 8 | 9 | void main() 10 | { 11 | vec2 v = 0.5 * vp * scale + shift; 12 | texCoord = transform * vec4(v, 0.0, 1.0); 13 | gl_Position = vec4(vp, 0.0, 1.0); 14 | } 15 | -------------------------------------------------------------------------------- /BonVision/Shaders/TexturedModel.frag: -------------------------------------------------------------------------------- 1 | #version 400 2 | uniform vec4 colorAmbient; 3 | uniform vec4 colorDiffuse; 4 | uniform vec4 colorSpecular; 5 | uniform float shininess = 1.0; 6 | uniform sampler2D textureDiffuse; 7 | uniform vec3 light; 8 | in vec3 position; 9 | in vec2 texCoord; 10 | in vec3 normal; 11 | out vec4 fragColor; 12 | 13 | void main() 14 | { 15 | vec3 L = normalize(light - position); 16 | vec3 R = normalize(-reflect(L, normal)); 17 | vec3 V = normalize(-position); 18 | vec4 texel = texture(textureDiffuse, texCoord); 19 | 20 | vec4 Iamb = colorAmbient * texel; 21 | vec4 Idiff = colorDiffuse * vec4(texel.rgb * max(dot(normal, L), 0.0), texel.a); 22 | vec4 Ispec = vec4(colorSpecular.rgb * pow(max(dot(R, V), 0.0), shininess), colorSpecular.a * texel.a); 23 | 24 | fragColor = Iamb + Idiff + Ispec; 25 | } 26 | -------------------------------------------------------------------------------- /BonVision/Shaders/TexturedModel.vert: -------------------------------------------------------------------------------- 1 | #version 400 2 | uniform mat4 modelview; 3 | uniform mat4 projection; 4 | uniform mat4 normalMatrix; 5 | layout(location = 0) in vec3 vp; 6 | layout(location = 1) in vec2 vt; 7 | layout(location = 2) in vec3 vn; 8 | out vec3 position; 9 | out vec2 texCoord; 10 | out vec3 normal; 11 | 12 | void main() 13 | { 14 | vec4 v = modelview * vec4(vp, 1.0); 15 | gl_Position = projection * v; 16 | position = vec3(v); 17 | texCoord = vt; 18 | normal = normalize(vec3(normalMatrix * vec4(vn, 0.0))); 19 | } 20 | -------------------------------------------------------------------------------- /BonVision/Shaders/TexturedModelArray.vert: -------------------------------------------------------------------------------- 1 | #version 400 2 | uniform mat4 modelview; 3 | uniform mat4 projection; 4 | uniform mat4 normalMatrix; 5 | layout(location = 0) in vec3 vp; 6 | layout(location = 1) in vec2 vt; 7 | layout(location = 2) in vec3 vn; 8 | layout(location = 3) in vec3 mr0; 9 | layout(location = 4) in vec3 mr1; 10 | layout(location = 5) in vec3 mr2; 11 | layout(location = 6) in vec3 mt; 12 | out vec3 position; 13 | out vec2 texCoord; 14 | out vec3 normal; 15 | 16 | void main() 17 | { 18 | mat3 mr = mat3(mr0, mr1, mr2); 19 | vec4 v = modelview * vec4(mr * vp + mt, 1.0); 20 | gl_Position = projection * v; 21 | position = vec3(v); 22 | texCoord = vt; 23 | normal = normalize(vec3(normalMatrix * vec4(mr * vn, 0.0))); 24 | } 25 | -------------------------------------------------------------------------------- /BonVision/Shaders/ViewMap.frag: -------------------------------------------------------------------------------- 1 | #version 400 2 | uniform samplerCube tex; 3 | uniform sampler2D viewMap; 4 | in vec2 texCoord; 5 | out vec4 fragColor; 6 | 7 | void main() 8 | { 9 | vec4 vector = texture(viewMap, texCoord); 10 | vec4 texel = texture(tex, vector.xyz); 11 | fragColor = vec4(texel.rgb * vector.a, texel.a); 12 | } 13 | -------------------------------------------------------------------------------- /Extensions.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Aman Saleem 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [BonVision website](https://bonvision.github.io/) 2 | 3 | 4 | MIT License 5 | 6 | Copyright (c) 2019 Aman Saleem 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in all 16 | copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | SOFTWARE. -------------------------------------------------------------------------------- /Resources/BonVision-Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bonvision/BonVision/785fa61d355c2a2fadc441d96012767273260db9/Resources/BonVision-Logo.png -------------------------------------------------------------------------------- /Resources/BonVision.svg: -------------------------------------------------------------------------------- 1 | 2 | 16 | 18 | 19 | 21 | image/svg+xml 22 | 24 | 25 | 26 | 27 | 28 | 30 | 33 | 37 | 38 | 39 | 59 | 64 | 69 | 75 | 76 | --------------------------------------------------------------------------------