static void CommonUpdate() { Renderer.Add(floorMesh, floorTr, Color.White); // Skip selection window if we're in test mode if (Demos.TestMode) { return; } // Make a window for demo selection UI.WindowBegin("Demos", ref demoSelectPose, new Vec2(50 * Units.cm2m, 0)); for (int i = 0; i < Demos.Count; i++) { // Chop off the "Demo" part of any demo name that has it string name = Demos.GetName(i); if (name.StartsWith("Demo")) { name = name.Substring("Demo".Length); } if (UI.ButtonRound(name, 4 * Units.cm2m)) { Demos.SetActive(i); } UI.SameLine(); } UI.WindowEnd(); }
static void CommonUpdate() { // If we can't see the world, we'll draw a floor! if (StereoKitApp.System.displayType == Display.Opaque) { Renderer.Add(floorMesh, floorTr, Color.White); } // Skip selection window if we're in test mode if (Demos.TestMode) { return; } // Make a window for demo selection UI.WindowBegin("Demos", ref demoSelectPose, new Vec2(50 * Units.cm2m, 0)); for (int i = 0; i < Demos.Count; i++) { string name = Demos.GetName(i); // No Doc demos if (name.StartsWith("Doc")) { continue; } // Chop off the "Demo" part of any demo name that has it if (name.StartsWith("Demo")) { name = name.Substring("Demo".Length); } if (UI.Button(name)) { Demos.SetActive(i); } UI.SameLine(); } UI.WindowEnd(); RulerWindow(); /// :CodeSample: Log.Subscribe Log /// And in your Update loop, you can draw the window. LogWindow(); /// And that's it! /// :End: // Take a screenshot on the first frame both hands are gripped bool valid = Input.Hand(Handed.Left).IsTracked&& Input.Hand(Handed.Right).IsTracked; BtnState right = Input.Hand(Handed.Right).grip; BtnState left = Input.Hand(Handed.Left).grip; if (valid && left.IsActive() && right.IsActive() && (left.IsJustActive() || right.IsJustActive())) { Renderer.Screenshot(Input.Head.position, Input.Head.Forward, 1920 * 2, 1080 * 2, "Screenshot" + screenshotId + ".jpg"); screenshotId += 1; } }
public void Update() { Pose solidPose; for (int i = 0; i < objects.Count; i++) { objects[i].GetPose(out solidPose); Renderer.Add(gltf, solidPose.ToMatrix(0.25f), Color.White); } for (int i = 0; i < (int)Handed.Max; i++) { Hand h = Input.Hand((Handed)i); if (h.IsJustGripped) { Input.HandSolid((Handed)i, true); } if (h.IsJustUngripped) { Input.HandSolid((Handed)i, false); } } UI.WindowBegin("Options", ref optionsPose); if (UI.Button("Add")) { objects.Add(new Solid(new Vec3(0, 3, 0), Quat.Identity)); objects.Last().AddSphere(.45f, 40); objects.Last().AddBox(Vec3.One * .35f, 40); } if (UI.Button("Clear")) { objects.Clear(); } UI.WindowEnd(); }
private void SpawnObject() { Hand rightHand = Input.Hand(Handed.Right); Vec3 position; if (rightHand.IsJustPinched) { position = rightHand[FingerId.Index, JointId.Tip].position; position.y -= 0.2f; if (whichObject == "cube") { SpawnCube(position); } else if (whichObject == "sphere") { SpawnSphere(position); } } Pose solidPose; float c; for (int i = 0; i < objects.Count; i++) { c = i / (float)objects.Count; objects[i].GetPose(out solidPose); Renderer.Add(spawnedModels[i], solidPose.ToMatrix(objectScale), new Color(c, c, c)); } }
public EditTileMapState(TilePaletteWindow tilePalette, InputSystem inputSystem, Renderer renderer) { _tilePalette = tilePalette; _inputSystem = inputSystem; _renderer = renderer; _renderer.Add(this); }
private void OnObjectAdded(object?sender, ItemEventArgs <IGameObject> e) { switch (e.Item) { case Terrain terrain: terrain.AppearanceChanged += OnTerrainAppearanceChanged; OnTerrainAppearanceChanged(terrain, EventArgs.Empty); break; case Entity entity: _entityRenderer?.Add(entity); break; } }
/// /// :End: void ShowClipboard() { /// :CodeDoc: Guides User Interface /// And, similar to the window previously, here's how you would turn it into a grabbable /// interface! This behaves the same, except we're defining where the grabbable region is /// specifically, and then drawing our own model instead of a plain bar. You'll also notice /// we're drawing using an identity matrix. This takes advantage of how AffordanceBegin /// pushes the affordance's pose onto the Hierarchy transform stack! /// UI.AffordanceBegin("Clip", ref clipPose, clipboard.Bounds); Renderer.Add(clipboard, Matrix.Identity); /// /// Once we've done that, we also need to define the layout area of the model, where UI /// elements will go. This is different for each model, so you'll need to plan this around /// the size of your object! /// UI.LayoutArea(new Vec3(12, 13, 0) * Units.cm2m, new Vec2(24, 30) * Units.cm2m); /// /// Then after that? We can just add UI elements like normal! /// UI.Image(clipLogoSprite, new Vec2(22, 0) * Units.cm2m); UI.Toggle("Toggle", ref clipToggle); UI.HSlider("Slide", ref clipSlider, 0, 1, 0, 22 * Units.cm2m); /// /// And while we're at it, here's a quick example of doing a radio button group! Not much /// 'radio' actually happening, but it's still pretty simple. Pair it with an enum, or an /// integer, and have fun! /// if (UI.Radio("Radio1", clipOption == 1)) { clipOption = 1; } UI.SameLine(); if (UI.Radio("Radio2", clipOption == 2)) { clipOption = 2; } UI.SameLine(); if (UI.Radio("Radio3", clipOption == 3)) { clipOption = 3; } /// /// As with windows, Affordances need an End call. /// UI.AffordanceEnd(); /// :End: }
public void Update() { if (Input.Hand(Handed.Right).IsJustPinched) { objects.Add(new Solid(new Vec3(0, 3, 0), Quat.Identity)); objects.Last().AddSphere(.45f, 40); objects.Last().AddBox(Vec3.One * .35f, 40); } for (int i = 0; i < objects.Count; i++) { objects[i].GetTransform(ref solidTr); Renderer.Add(gltf, solidTr, Color.White); } }
public void Update() { if (Input.Hand(Handed.Right).IsJustPinched) { objects.Add(new Solid(new Vec3(0, 3, 0), Quat.Identity)); objects.Last().AddSphere(.45f, 40); objects.Last().AddBox(Vec3.One * .35f, 40); } Pose solidPose; for (int i = 0; i < objects.Count; i++) { objects[i].GetPose(out solidPose); Renderer.Add(gltf, solidPose.ToMatrix(0.25f), Color.White); } }
static void Main(string[] args) { if (!StereoKitApp.Initialize("StereoKit C#", Runtime.MixedReality, true)) { Environment.Exit(1); } Model cube = new Model(Mesh.GenerateRoundedCube(Vec3.One, 0.1f), Material.Find("default/material")); while (StereoKitApp.Step(() => { Renderer.Add(cube, Matrix.Identity, Color.White); })) { ; } StereoKitApp.Shutdown(); }
static void CommonUpdate() { if (Input.Key(Key.Esc).IsJustActive()) { StereoKitApp.Quit(); } // If we can't see the world, we'll draw a floor! if (StereoKitApp.System.displayType == Display.Opaque) { Renderer.Add(floorMesh, floorTr, Color.White); } // Skip selection window if we're in test mode if (Tests.IsTesting) { return; } // Make a window for demo selection UI.WindowBegin("Demos", ref demoSelectPose, new Vec2(50 * U.cm, 0)); for (int i = 0; i < Tests.DemoCount; i++) { string name = Tests.GetDemoName(i).Substring("Demo".Length); if (UI.Button(name)) { Tests.SetDemoActive(i); } UI.SameLine(); } UI.WindowEnd(); RulerWindow(); DebugToolWindow.Step(); /// :CodeSample: Log.Subscribe Log /// And in your Update loop, you can draw the window. LogWindow(); /// And that's it! /// :End: }
public void Update() { Pose solidPose; for (int i = 0; i < objects.Count; i++) { objects[i].GetPose(out solidPose); Renderer.Add(gltf, solidPose.ToMatrix(0.25f), Color.White); } for (int i = 0; i < (int)Handed.Max; i++) { Hand h = Input.Hand((Handed)i); if (h.IsJustGripped) { Input.HandSolid((Handed)i, true); Default.MaterialHand[MatParamName.ColorTint] = new Color(1, 1, 1, 1); } if (h.IsJustUngripped) { Input.HandSolid((Handed)i, false); Default.MaterialHand[MatParamName.ColorTint] = new Color(1, 1, 1, 0.4f); } } UI.WindowBegin("Objects", ref optionsPose); if (UI.Button("Add")) { objects.Add(new Solid(new Vec3(0, 3, -.6f), Quat.LookDir(0, 0, 1))); objects.Last().AddSphere(.45f, 40, V.XYZ(0, 0, 0.05f)); objects.Last().AddBox(Vec3.One * .35f, 40, V.XYZ(0, 0, 0.05f)); } if (UI.Button("Clear")) { objects.Clear(); } UI.WindowEnd(); Text.Add(title, titlePose); Text.Add(description, descPose, V.XY(0.4f, 0), TextFit.Wrap, TextAlign.TopCenter, TextAlign.TopLeft); }
/// <summary> /// Creates the PC plot given /// </summary> /// <param name="panel"></param> /// <param name="filter"></param> /// <param name="columnIndex">the column index for which we're clustering the data /// in case we're using K-Means</param> /// <param name="headers"></param> /// <returns></returns> private ParallelCoordinatesPlot InitializeParallelCoordinatesPlot(Panel panel, IDataCubeProvider <float> filter, int columnIndex, List <string> headers) { ParallelCoordinatesPlot filterPlot = new ParallelCoordinatesPlot(); filterPlot.Input = filter; filterPlot.Headers = headers; // to color according to clusters if (columnIndex != -1) { iColorMap.Index = columnIndex; iDoc.iFilteredSelectedColorMap.Index = columnIndex; } filterPlot.ColorMap = iColorMap; filterPlot.Enabled = true; renderer.Add(filterPlot, panel); return(filterPlot); }
public void Update() { Tests.Screenshot(1024, 1024, "PBRBalls.jpg", new Vec3(0, 0, -0.1f), new Vec3(0, 0, -1)); Hierarchy.Push(Matrix.T(0, 0, -1)); if (!Tests.IsTesting) { UI.HandleBegin("Model", ref modelPose, pbrModel.Bounds * .2f); pbrModel.Draw(Matrix.TRS(Vec3.Zero, Quat.FromAngles(0, 180, 0), 0.2f)); UI.HandleEnd(); } for (int y = 0; y < materialGrid; y++) { for (int x = 0; x < materialGrid; x++) { Renderer.Add(sphereMesh, pbrMaterials[x + y * materialGrid], Matrix.TS(new Vec3(x - materialGrid / 2.0f + 0.5f, y - materialGrid / 2.0f + 0.5f, -1) / 4.0f, 0.2f)); } } Text.Add("Metallic -->", Matrix.TRS(new Vec3(0, materialGrid / 8.0f + 0.2f, -0.25f), Quat.FromAngles(0, 180, 0), 4)); Text.Add("Roughness -->", Matrix.TRS(new Vec3(materialGrid / -8.0f - 0.2f, 0, -0.25f), Quat.FromAngles(0, 180, -90), 4)); Hierarchy.Pop(); }
public void Update() { Hierarchy.Push(Matrix.TRS(V.XYZ(0.5f, -0.25f, -0.5f), Quat.LookDir(-1, 0, 1), 0.2f)); Tests.Screenshot("ProceduralGeometry.jpg", 600, 600, V.XYZ(0.3f, -0.25f, -0.3f), V.XYZ(0.5f, -0.25f, -0.5f)); Tests.Screenshot("ProceduralGrid.jpg", 600, 600, Hierarchy.ToWorld(V.X0Z(-2, -0.7f)), Hierarchy.ToWorld(V.X0Z(-2, 0))); // Plane! Mesh planeMesh = demoPlaneMesh; Model planeModel = demoPlaneModel; /// :CodeSample: Mesh.GeneratePlane /// Drawing both a Mesh and a Model generated this way is reasonably simple, /// here's a short example! For the Mesh, you'll need to create your own material, /// we just loaded up the default Material here. Matrix planeTransform = Matrix.T(-.5f, -1, 0); Renderer.Add(planeMesh, Default.Material, planeTransform); planeTransform = Matrix.T(.5f, -1, 0); Renderer.Add(planeModel, planeTransform); /// :End: // Cube! Mesh cubeMesh = demoCubeMesh; Model cubeModel = demoCubeModel; /// :CodeSample: Mesh.GenerateCube /// Drawing both a Mesh and a Model generated this way is reasonably simple, /// here's a short example! For the Mesh, you'll need to create your own material, /// we just loaded up the default Material here. Matrix cubeTransform = Matrix.T(-.5f, -.5f, 0); Renderer.Add(cubeMesh, Default.Material, cubeTransform); cubeTransform = Matrix.T(.5f, -.5f, 0); Renderer.Add(cubeModel, cubeTransform); /// :End: // Rounded Cube! Mesh roundedCubeMesh = demoRoundedCubeMesh; Model roundedCubeModel = demoRoundedCubeModel; /// :CodeSample: Mesh.GenerateRoundedCube /// Drawing both a Mesh and a Model generated this way is reasonably simple, /// here's a short example! For the Mesh, you'll need to create your own material, /// we just loaded up the default Material here. Matrix roundedCubeTransform = Matrix.T(-.5f, 0, 0); Renderer.Add(roundedCubeMesh, Default.Material, roundedCubeTransform); roundedCubeTransform = Matrix.T(.5f, 0, 0); Renderer.Add(roundedCubeModel, roundedCubeTransform); /// :End: // Rounded Sphere! Mesh sphereMesh = demoSphereMesh; Model sphereModel = demoSphereModel; /// :CodeSample: Mesh.GenerateSphere /// Drawing both a Mesh and a Model generated this way is reasonably simple, /// here's a short example! For the Mesh, you'll need to create your own material, /// we just loaded up the default Material here. Matrix sphereTransform = Matrix.T(-.5f, .5f, 0); Renderer.Add(sphereMesh, Default.Material, sphereTransform); sphereTransform = Matrix.T(.5f, .5f, 0); Renderer.Add(sphereModel, sphereTransform); /// :End: // Cylinder! Mesh cylinderMesh = demoCylinderMesh; Model cylinderModel = demoCylinderModel; /// :CodeSample: Mesh.GenerateCylinder /// Drawing both a Mesh and a Model generated this way is reasonably simple, /// here's a short example! For the Mesh, you'll need to create your own material, /// we just loaded up the default Material here. Matrix cylinderTransform = Matrix.T(-.5f, 1, 0); Renderer.Add(cylinderMesh, Default.Material, cylinderTransform); cylinderTransform = Matrix.T(.5f, 1, 0); Renderer.Add(cylinderModel, cylinderTransform); /// :End: demoProcMesh.Draw(Default.Material, Matrix.TR(-2, 0, 0, Quat.FromAngles(-90, 0, 0))); Hierarchy.Pop(); Text.Add(title, titlePose); Text.Add(description, descPose, V.XY(0.4f, 0), TextFit.Wrap, TextAlign.TopCenter, TextAlign.TopLeft); }
public void Update() { // Cube! Mesh cubeMesh = demoCubeMesh; Model cubeModel = demoCubeModel; if (Demos.TestMode) { Renderer.Screenshot(new Vec3(0.25f, 1.5f, 2f) * 0.75f, Vec3.Zero, 600, 400, "../../../docs/img/screenshots/ProceduralGeometry.jpg"); } /// :CodeSample: Mesh.GenerateCube /// Drawing both a Mesh and a Model generated this way is reasonably simple, /// here's a short example! For the Mesh, you'll need to create your own material, /// we just loaded up the default Material here. Matrix cubeTransform = Matrix.T(-1.0f, 0, 1); Renderer.Add(cubeMesh, Default.Material, cubeTransform); cubeTransform = Matrix.T(-1.0f, 0, -1); Renderer.Add(cubeModel, cubeTransform); /// :End: // Rounded Cube! Mesh roundedCubeMesh = demoRoundedCubeMesh; Model roundedCubeModel = demoRoundedCubeModel; /// :CodeSample: Mesh.GenerateRoundedCube /// Drawing both a Mesh and a Model generated this way is reasonably simple, /// here's a short example! For the Mesh, you'll need to create your own material, /// we just loaded up the default Material here. Matrix roundedCubeTransform = Matrix.T(-0.5f, 0, 1); Renderer.Add(roundedCubeMesh, Default.Material, roundedCubeTransform); roundedCubeTransform = Matrix.T(-0.5f, 0, -1); Renderer.Add(roundedCubeModel, roundedCubeTransform); /// :End: // Rounded Sphere! Mesh sphereMesh = demoSphereMesh; Model sphereModel = demoSphereModel; /// :CodeSample: Mesh.GenerateSphere /// Drawing both a Mesh and a Model generated this way is reasonably simple, /// here's a short example! For the Mesh, you'll need to create your own material, /// we just loaded up the default Material here. Matrix sphereTransform = Matrix.T(0.0f, 0, 1); Renderer.Add(sphereMesh, Default.Material, sphereTransform); sphereTransform = Matrix.T(0.0f, 0, -1); Renderer.Add(sphereModel, sphereTransform); /// :End: // Cylinder! Mesh cylinderMesh = demoCylinderMesh; Model cylinderModel = demoCylinderModel; /// :CodeSample: Mesh.GenerateCylinder /// Drawing both a Mesh and a Model generated this way is reasonably simple, /// here's a short example! For the Mesh, you'll need to create your own material, /// we just loaded up the default Material here. Matrix cylinderTransform = Matrix.T(0.5f, 0, 1); Renderer.Add(cylinderMesh, Default.Material, cylinderTransform); cylinderTransform = Matrix.T(0.5f, 0, -1); Renderer.Add(cylinderModel, cylinderTransform); /// :End: // Plane! Mesh planeMesh = demoPlaneMesh; Model planeModel = demoPlaneModel; /// :CodeSample: Mesh.GeneratePlane /// Drawing both a Mesh and a Model generated this way is reasonably simple, /// here's a short example! For the Mesh, you'll need to create your own material, /// we just loaded up the default Material here. Matrix planeTransform = Matrix.T(1.0f, 0, 1); Renderer.Add(planeMesh, Default.Material, planeTransform); planeTransform = Matrix.T(1.0f, 0, -1); Renderer.Add(planeModel, planeTransform); /// :End: }
static void CommonUpdate() { Renderer.Add(floorMesh, floorTr, Color.White); }
public void Update() { if (Demos.TestMode) { Renderer.Screenshot(new Vec3(-0.325f, -0.00f, .075f), new Vec3(-.4f, -0.05f, 0), 600, 400, "../../../docs/img/screenshots/GuideUserInterface.jpg"); Renderer.Screenshot(new Vec3(0.225f, 0.0f, .175f), new Vec3(.4f, 0.0f, 0), 400, 600, "../../../docs/img/screenshots/GuideUserInterfaceCustom.jpg"); } /// :CodeDoc: Guides User Interface /// Then we'll move over to the application step where we'll do the rest of the UI code! /// /// We'll start with a window titled "Window" that's 20cm wide, and auto-resizes on the /// y-axis. The Units class is pretty helpful here, as it allows us to reason more visually /// about the units we're using! StereoKit uses meters as its base unit, which look a little /// awkward, especially in the millimeter range. /// /// We'll also use a toggle to turn the window's header on and off! The value from that toggle /// is passed in here via the showHeader field. /// UI.WindowBegin("Window", ref windowPose, new Vec2(20, 0) * Units.cm2m, showHeader); /// /// When you begin a window, all visual elements are now relative to that window! UI takes advantage /// of the Hierarchy class and pushes the window's pose onto the Hierarchy stack. Ending the window /// will pop the pose off the hierarchy stack, and return things to normal! /// /// Here's that toggle button! You'll also notice our use of 'ref' values in a lot of the UI /// code. UI functions typically follow the pattern of returning true/false to indicate they've /// been interacted with during the frame, so you can nicely wrap them in 'if' statements to /// react to change! /// /// Then with the 'ref' parameter, we let you pass in the current state of the UI element. The UI /// element will update that value for you based on user interaction, but you can also change it /// yourself whenever you want to! /// UI.Toggle("Show Header", ref showHeader); /// /// Here's an example slider! We start off with a label element, and tell the UI to /// keep the next item on the same line. The slider clamps to the range [0,1], and /// will step at intervals of 0.2. If you want it to slide continuously, you can just set /// the `step` value to 0! /// UI.Label("Slide"); UI.SameLine(); UI.HSlider("slider", ref slider, 0, 1, 0.2f, 72 * Units.mm2m); /// /// Here's how you use a simple button! Just check it with an 'if'. Any UI method /// will return true on the frame when their value or state has changed. /// if (UI.ButtonRound("Exit", powerSprite)) { StereoKitApp.Quit(); } /// /// And for every begin, there must also be an end! StereoKit will log errors when this /// occurs, so keep your eyes peeled for that! /// UI.WindowEnd(); /// /// ## Custom Windows /// /// ![Simple UI]({{site.url}}/img/screenshots/GuideUserInterfaceCustom.jpg) /// /// Mixed Reality also provides us with the opportunity to turn objects into interfaces! /// Instead of using the old 'window' paradigm, we can create 3D models and apply UI /// elements to their surface! StereoKit uses 'affordances' to accomplish this, a grabbable /// area that behaves much like a window, but with a few more options for customizing /// layout and size. /// /// We'll load up a clipboard, so we can attach an interface to that! /// /// ```csharp /// Model clipboard = Model.FromFile("Clipboard.glb"); /// ``` /// /// And, similar to the window previously, here's how you would turn it into a grabbable /// interface! This behaves the same, except we're defining where the grabbable region is /// specifically, and then drawing our own model instead of a plain bar. You'll also notice /// we're drawing using an identity matrix. This takes advantage of how AffordanceBegin /// pushes the affordance's pose onto the Hierarchy transform stack! /// UI.AffordanceBegin("Clip", ref clipboardPose, clipboard.Bounds); Renderer.Add(clipboard, Matrix.Identity); /// /// Once we've done that, we also need to define the layout area of the model, where UI /// elements will go. This is different for each model, so you'll need to plan this around /// the size of your object! /// UI.LayoutArea(new Vec3(12, 13, 0) * Units.cm2m, new Vec2(24, 30) * Units.cm2m); /// /// Then after that? We can just add UI elements like normal! /// UI.Image(logoSprite, new Vec2(22, 0) * Units.cm2m); UI.Toggle("Toggle", ref clipToggle); UI.HSlider("Slide", ref clipSlider, 0, 1, 0, 22 * Units.cm2m); /// /// And while we're at it, here's a quick example of doing a radio button group! Not much /// 'radio' actually happening, but it's still pretty simple. Pair it with an enum, or an /// integer, and have fun! /// if (UI.Radio("Radio 1", clipOption == 1)) { clipOption = 1; } UI.SameLine(); if (UI.Radio("Radio 2", clipOption == 2)) { clipOption = 2; } UI.SameLine(); if (UI.Radio("Radio 3", clipOption == 3)) { clipOption = 3; } /// /// As with windows, Affordances need an End call. /// UI.AffordanceEnd(); /// /// And there you go! That's how UI works in StereoKit, pretty simple, huh? /// For further reference, and more UI methods, check out the /// [UI class documentation]({{site.url}}/Pages/Reference/UI.html). /// /// If you'd like to see the complete code for this sample, /// [check it out on Github](https://github.com/maluoi/StereoKit/blob/master/Examples/StereoKitTest/DemoUI.cs)! /// :End: }
private void SetupMapLayers() { string dir = Directory.GetCurrentDirectory(); string dataPath = "\\..\\..\\..\\data\\geodata\\maps\\"; string fileName = "europe_nation"; ShapeFileReader shapeReader = new ShapeFileReader(); iMapData = shapeReader.Read(dir + dataPath + fileName + ".shp" , dir + dataPath + fileName + ".dbf" , dir + dataPath + fileName + ".shx"); // Border Layer borderLayer = new MapPolygonBorderLayer(); borderLayer.MapData = iMapData; // Polygon Layer polygonLayer = new MapPolygonLayer(); polygonLayer.MapData = iMapData; polygonLayer.ColorMap = iColorMap; polygonLayer.IndexVisibilityHandler = iPcPlot.IndexVisibilityHandler; iPcPlot.FilterChanged += new EventHandler(iPcPlot_FilterChanged); polygonSelectionLayer = new MapPolygonLayer(); polygonSelectionLayer.MapData = iMapData; polygonSelectionLayer.PolygonColor = Color.FromArgb(220, 220, 220); polygonSelectionLayer.Alpha = 120; borderSelectionLayer = new MapPolygonBorderLayer(); borderSelectionLayer.MapData = iMapData; borderSelectionLayer.BorderColor = Color.Black; borderSelectionLayer.Translation = new Vector3(0.6f, 0.6f, 0); // borderSelectionLayer.Translation.X; iSelectedInVisibility = new IndexVisibilityHandler(iMapData.RegionList.Count); iSelectedVisibility = new IndexVisibilityHandler(iMapData.RegionList.Count); iSelectedInVisibility.Clear(); iInVisibilityList = iSelectedInVisibility.CreateVisibilityList(); iVisibilityList = iSelectedVisibility.CreateVisibilityList(); for (int i = 0, endI = iMapData.RegionList.Count; i < endI; i++) { iVisibilityList.SetVisibility(i, 0, false); } polygonSelectionLayer.IndexVisibilityHandler = iSelectedInVisibility; borderSelectionLayer.IndexVisibilityHandler = iSelectedVisibility; // polygonSelectionLayer.SelectedPolygonColor = Color.Transparent; // Glyph Layer glyphLayer = new CountryGlyphLayer(iPanel); glyphLayer.ActiveGlyphPositioner = new CenterGlyphPositioner(); glyphLayer.ActiveGlyphPositioner.MapData = iMapData; glyphLayer.Input = iDataCube; glyphLayer.IndexVisibilityHandler = iPcPlot.IndexVisibilityHandler; // Choropleth Map choroMap = new ChoroplethMap(); choroMap.VizComponentMouseDown += new EventHandler <VizComponentMouseEventArgs>(MouseDown); choroMap.VizComponentMouseUp += new EventHandler <VizComponentMouseEventArgs>(MouseUp); // Add layers on the proper order choroMap.AddLayer(polygonLayer); choroMap.AddLayer(borderLayer); choroMap.AddLayer(polygonSelectionLayer); choroMap.AddLayer(borderSelectionLayer); choroMap.AddLayer(glyphLayer); Invalidate(); //iSelectedColorLegend = new InteractiveColorLegend(); //iSelectedColorLegend.ColorMap = iLegendColorMap; //iSelectedColorLegend.BorderColor = Color.Black; //iSelectedColorLegend.ShowMinMaxValues = false; //iSelectedColorLegend.SetLegendSize(10, 200); //iSelectedColorLegend.SetPosition(50F, 10F); //iSelectedColorLegend.SetLegendSize(0.02f, 0.2f); //iSelectedColorLegend.ShowColorEdgeSliders = false; //iSelectedColorLegend.ShowColorEdgeSliderValue = false; ////iSelectedColorLegend.ColorEdgeValuesChanged += new EventHandler(ColorLegendChanged); //choroMap.AddSubComponent(iSelectedColorLegend); iColorLegend = new InteractiveColorLegend(); iColorLegend.ColorMap = iColorMap; //iColorLegend.BorderColor = Color.Black; //iColorLegend.SliderTextColor = Color.Black; //iColorLegend.ShowMinMaxValues = true; iColorLegend.SetPosition(10, 10); iColorLegend.SetLegendSize(15, 200); iColorLegend.ShowColorEdgeSliders = true; iColorLegend.ShowColorEdgeSliderValue = false; iColorLegend.ColorEdgeValuesChanged += new EventHandler(ColorLegendChanged); //iColorLegend.ShowValueSliders = true; //iColorLegend.ShowValueSliderValue = true; //iColorLegend.ValueSliderValuesChanged += new EventHandler(ColorLegendChanged); //iColorLegend.SetEdgeSliders(InteractiveColorLegend.SliderLinePosition.Center, InteractiveColorLegend.TextPosition.RightOrBottom, true); choroMap.AddSubComponent(iColorLegend); renderer.Add(choroMap, iPanel); }
////////////////////// public void Step() { Tests.Update(); if (Input.Key(Key.Esc).IsJustActive()) { SK.Quit(); } // If we can't see the world, we'll draw a floor! if (SK.System.displayType == Display.Opaque) { Renderer.Add(floorMesh, World.HasBounds ? World.BoundsPose.ToMatrix() : floorTr, Color.White); } // Skip selection window if we're in test mode if (Tests.IsTesting) { return; } /// :CodeSample: World.HasBounds World.BoundsSize World.BoundsPose // Here's some quick and dirty lines for the play boundary rectangle! if (World.HasBounds) { Vec2 s = World.BoundsSize / 2; Matrix pose = World.BoundsPose.ToMatrix(); Vec3 tl = pose.Transform(new Vec3(s.x, 0, s.y)); Vec3 br = pose.Transform(new Vec3(-s.x, 0, -s.y)); Vec3 tr = pose.Transform(new Vec3(-s.x, 0, s.y)); Vec3 bl = pose.Transform(new Vec3(s.x, 0, -s.y)); Lines.Add(tl, tr, Color.White, 1.5f * U.cm); Lines.Add(bl, br, Color.White, 1.5f * U.cm); Lines.Add(tl, bl, Color.White, 1.5f * U.cm); Lines.Add(tr, br, Color.White, 1.5f * U.cm); } /// :End: // Make a window for demo selection UI.WindowBegin("Demos", ref demoSelectPose, new Vec2(50 * U.cm, 0)); for (int i = 0; i < demoNames.Count; i++) { if (UI.Button(demoNames[i])) { Tests.SetDemoActive(i); } UI.SameLine(); } UI.NextLine(); UI.HSeparator(); if (UI.Button("Exit")) { SK.Quit(); } UI.WindowEnd(); RulerWindow(); DebugToolWindow.Step(); /// :CodeSample: Log.Subscribe Log /// And in your Update loop, you can draw the window. LogWindow(); /// And that's it! /// :End: }
public void Update() { // Cube! Mesh cubeMesh = demoCubeMesh; Model cubeModel = demoCubeModel; Tests.Screenshot(600, 400, "ProceduralGeometry.jpg", new Vec3(0.25f, 1.5f, 2f) * 0.75f, Vec3.Zero); Tests.Screenshot(600, 400, "ProceduralGrid.jpg", new Vec3(0.358f, -0.013f, 0.222f), new Vec3(1.012f, -0.682f, -0.131f)); /// :CodeSample: Mesh.GenerateCube /// Drawing both a Mesh and a Model generated this way is reasonably simple, /// here's a short example! For the Mesh, you'll need to create your own material, /// we just loaded up the default Material here. Matrix cubeTransform = Matrix.T(-1.0f, 0, 1); Renderer.Add(cubeMesh, Default.Material, cubeTransform); cubeTransform = Matrix.T(-1.0f, 0, -1); Renderer.Add(cubeModel, cubeTransform); /// :End: // Rounded Cube! Mesh roundedCubeMesh = demoRoundedCubeMesh; Model roundedCubeModel = demoRoundedCubeModel; /// :CodeSample: Mesh.GenerateRoundedCube /// Drawing both a Mesh and a Model generated this way is reasonably simple, /// here's a short example! For the Mesh, you'll need to create your own material, /// we just loaded up the default Material here. Matrix roundedCubeTransform = Matrix.T(-0.5f, 0, 1); Renderer.Add(roundedCubeMesh, Default.Material, roundedCubeTransform); roundedCubeTransform = Matrix.T(-0.5f, 0, -1); Renderer.Add(roundedCubeModel, roundedCubeTransform); /// :End: // Rounded Sphere! Mesh sphereMesh = demoSphereMesh; Model sphereModel = demoSphereModel; /// :CodeSample: Mesh.GenerateSphere /// Drawing both a Mesh and a Model generated this way is reasonably simple, /// here's a short example! For the Mesh, you'll need to create your own material, /// we just loaded up the default Material here. Matrix sphereTransform = Matrix.T(0.0f, 0, 1); Renderer.Add(sphereMesh, Default.Material, sphereTransform); sphereTransform = Matrix.T(0.0f, 0, -1); Renderer.Add(sphereModel, sphereTransform); /// :End: // Cylinder! Mesh cylinderMesh = demoCylinderMesh; Model cylinderModel = demoCylinderModel; /// :CodeSample: Mesh.GenerateCylinder /// Drawing both a Mesh and a Model generated this way is reasonably simple, /// here's a short example! For the Mesh, you'll need to create your own material, /// we just loaded up the default Material here. Matrix cylinderTransform = Matrix.T(0.5f, 0, 1); Renderer.Add(cylinderMesh, Default.Material, cylinderTransform); cylinderTransform = Matrix.T(0.5f, 0, -1); Renderer.Add(cylinderModel, cylinderTransform); /// :End: // Plane! Mesh planeMesh = demoPlaneMesh; Model planeModel = demoPlaneModel; /// :CodeSample: Mesh.GeneratePlane /// Drawing both a Mesh and a Model generated this way is reasonably simple, /// here's a short example! For the Mesh, you'll need to create your own material, /// we just loaded up the default Material here. Matrix planeTransform = Matrix.T(1.0f, 0, 1); Renderer.Add(planeMesh, Default.Material, planeTransform); planeTransform = Matrix.T(1.0f, 0, -1); Renderer.Add(planeModel, planeTransform); /// :End: demoProcMesh.Draw(Default.Material, Matrix.T(1, -.3f, 0)); }
public void Update() { Tests.Screenshot("GuideUserInterface.jpg", 600, 400, new Vec3(-0.363f, 0.010f, 0.135f), new Vec3(-0.743f, -0.414f, -0.687f)); Tests.Screenshot("GuideUserInterfaceCustom.jpg", 400, 600, new Vec3(0.225f, 0.0f, .175f), new Vec3(.4f, 0.0f, 0)); /// :CodeDoc: Guides User Interface /// Then we'll move over to the application step where we'll do the /// rest of the UI code! /// /// We'll start with a window titled "Window" that's 20cm wide, and /// auto-resizes on the y-axis. The U class is pretty helpful here, /// as it allows us to reason more visually about the units we're /// using! StereoKit uses meters as its base unit, which look a /// little awkward as raw floats, especially in the millimeter range. /// /// We'll also use a toggle to turn the window's header on and off! /// The value from that toggle is passed in here via the showHeader /// field. /// UI.WindowBegin("Window", ref windowPose, new Vec2(20, 0) * U.cm, showHeader?UIWin.Normal:UIWin.Body); /// /// When you begin a window, all visual elements are now relative to /// that window! UI takes advantage of the Hierarchy class and pushes /// the window's pose onto the Hierarchy stack. Ending the window /// will pop the pose off the hierarchy stack, and return things to /// normal! /// /// Here's that toggle button! You'll also notice our use of 'ref' /// values in a lot of the UI code. UI functions typically follow the /// pattern of returning true/false to indicate they've been /// interacted with during the frame, so you can nicely wrap them in /// 'if' statements to react to change! /// /// Then with the 'ref' parameter, we let you pass in the current /// state of the UI element. The UI element will update that value /// for you based on user interaction, but you can also change it /// yourself whenever you want to! /// UI.Toggle("Show Header", ref showHeader); /// /// Here's an example slider! We start off with a label element, and /// tell the UI to keep the next item on the same line. The slider /// clamps to the range [0,1], and will step at intervals of 0.2. If /// you want it to slide continuously, you can just set the `step` /// value to 0! /// UI.Label("Slide"); UI.SameLine(); UI.HSlider("slider", ref slider, 0, 1, 0.2f, 72 * U.mm); /// /// Here's how you use a simple button! Just check it with an 'if'. /// Any UI method will return true on the frame when their value or /// state has changed. /// if (UI.ButtonRound("Exit", powerSprite)) { SK.Quit(); } /// /// And for every begin, there must also be an end! StereoKit will /// log errors when this occurs, so keep your eyes peeled for that! /// UI.WindowEnd(); /// /// ## Custom Windows /// /// ![Simple UI]({{site.url}}/img/screenshots/GuideUserInterfaceCustom.jpg) /// /// Mixed Reality also provides us with the opportunity to turn /// objects into interfaces! Instead of using the old 'window' /// paradigm, we can create 3D models and apply UI elements to their /// surface! StereoKit uses 'handles' to accomplish this, a grabbable /// area that behaves much like a window, but with a few more options /// for customizing layout and size. /// /// We'll load up a clipboard, so we can attach an interface to that! /// /// ```csharp /// Model clipboard = Model.FromFile("Clipboard.glb"); /// ``` /// /// And, similar to the window previously, here's how you would turn /// it into a grabbable interface! This behaves the same, except /// we're defining where the grabbable region is specifically, and /// then drawing our own model instead of a plain bar. You'll also /// notice we're drawing using an identity matrix. This takes /// advantage of how HandleBegin pushes the handle's pose onto the /// Hierarchy transform stack! /// UI.HandleBegin("Clip", ref clipboardPose, clipboard.Bounds); Renderer.Add(clipboard, Matrix.Identity); /// /// Once we've done that, we also need to define the layout area of /// the model, where UI elements will go. This is different for each /// model, so you'll need to plan this around the size of your /// object! /// UI.LayoutArea(new Vec3(12, 15, 0) * U.cm, new Vec2(24, 30) * U.cm); /// /// Then after that? We can just add UI elements like normal! /// UI.Image(logoSprite, new Vec2(22, 0) * U.cm); UI.Toggle("Toggle", ref clipToggle); UI.HSlider("Slide", ref clipSlider, 0, 1, 0, 22 * U.cm); /// /// And while we're at it, here's a quick example of doing a radio /// button group! Not much 'radio' actually happening, but it's still /// pretty simple. Pair it with an enum, or an integer, and have fun! /// if (UI.Radio("Radio1", clipOption == 1)) { clipOption = 1; } UI.SameLine(); if (UI.Radio("Radio2", clipOption == 2)) { clipOption = 2; } UI.SameLine(); if (UI.Radio("Radio3", clipOption == 3)) { clipOption = 3; } /// /// As with windows, Handles need an End call. /// UI.HandleEnd(); /// :End: // Just moving this UI out of the way so it doesn't show in // screenshots or anything. UI.PushSurface(new Pose(0, 1000, 0, Quat.Identity)); /// :CodeDoc: Guides User Interface /// /// ## An Important Note About IDs /// /// StereoKit does store a small amount of information about the UI's /// state behind the scenes, like which elements are active and for /// how long. This internal data is attached to the UI elements via /// a combination of their own ids, and the parent Window/Handle's /// id! /// /// This means you should be careful to NOT re-use ids within a /// Window/Handle, otherwise you may find ghost interactions with /// elements that share the same ids. If you need to have elements /// with the same id, or if perhaps you don't know in advance that /// all your elements will certainly be unique, UI.PushId and /// UI.PopId can be used to mitigate the issue by using the same /// hierarchy id mixing that the Windows use to prevent collisions /// with the same ids in other Windows/Handles. /// /// Here's the same set of radio options, but all of them have the /// same name/id! /// UI.PushId(1); if (UI.Radio("Radio", clipOption == 1)) { clipOption = 1; } UI.PopId(); UI.SameLine(); UI.PushId(2); if (UI.Radio("Radio", clipOption == 2)) { clipOption = 2; } UI.PopId(); UI.SameLine(); UI.PushId(3); if (UI.Radio("Radio", clipOption == 3)) { clipOption = 3; } UI.PopId(); /// :End: UI.PopSurface(); /// :CodeDoc: Guides User Interface /// ## What's Next? /// /// And there you go! That's how UI works in StereoKit, pretty /// simple, huh? For further reference, and more UI methods, check /// out the [UI class documentation]({{site.url}}/Pages/Reference/UI.html). /// /// If you'd like to see the complete code for this sample, /// [check it out on Github](https://github.com/maluoi/StereoKit/blob/master/Examples/StereoKitTest/Demos/DemoUI.cs)! /// :End: /// :CodeSample: UI.VolumeAt /// This code will draw an axis at the index finger's location when /// the user pinches while inside a VolumeAt. /// /// ![UI.InteractVolume]({{site.screen_url}}/InteractVolume.jpg) /// // Draw a transparent volume so the user can see this space Vec3 volumeAt = new Vec3(0, 0.2f, -0.4f); float volumeSize = 0.2f; Default.MeshCube.Draw(Default.MaterialUIBox, Matrix.TS(volumeAt, volumeSize)); BtnState volumeState = UI.VolumeAt("Volume", new Bounds(volumeAt, Vec3.One * volumeSize), UIConfirm.Pinch, out Handed hand); if (volumeState != BtnState.Inactive) { // If it just changed interaction state, make it jump in size float scale = volumeState.IsChanged() ? 0.1f : 0.05f; Lines.AddAxis(Input.Hand(hand)[FingerId.Index, JointId.Tip].Pose, scale); } /// :End: Tests.Screenshot("InteractVolume.jpg", 1, 600, 600, 90, new Vec3(-0.102f, 0.306f, -0.240f), new Vec3(0.410f, -0.248f, -0.897f)); }
public EntityLiteConsole() : base(80, 23, 160, 46) { var fadeEffect = new SadConsole.Effects.Fade { AutoReverse = true, DestinationForeground = new ColorGradient(Color.Blue, Color.Yellow), FadeForeground = true, UseCellForeground = false, Repeat = true, FadeDuration = 0.7f, RemoveOnFinished = true, CloneOnAdd = true }; player = new Entity(Color.Yellow, Color.Black, 1, 100) { //Position = new Point(Surface.BufferWidth / 2, Surface.BufferHeight / 2) Position = new Point(0, 0), UsePixelPositioning = usePixelPositioning, }; // If we're allowing smooth movements, add the component if (useSmoothMovements) { player.SadComponents.Add(new SadConsole.Components.SmoothMove(FontSize, new TimeSpan(0, 0, 0, 0, 300))); } Surface.DefaultBackground = Color.DarkGray; Surface.Clear(); playerPreviousPosition = player.Position; SadComponents.Add(new SadConsole.Components.SurfaceComponentFollowTarget() { Target = player }); entityManager = new Renderer(); //SadComponents.Add(new SadConsole.Components.SurfaceComponentEntityOffsets()); SadComponents.Add(entityManager); //player.Components.Add(new SadConsole.Components.EntityViewSync()); entityManager.Add(player); //Children.Add(player); others = new List <Entity>(); for (int i = 0; i < 1000; i++) { var item = new Entity(Color.Red.GetRandomColor(SadConsole.Game.Instance.Random), Color.Black, Game.Instance.Random.Next(0, 60), 0) { Position = GetRandomPosition(), UsePixelPositioning = usePixelPositioning, }; if (useSmoothMovements) { item.SadComponents.Add(new SadConsole.Components.SmoothMove(FontSize, new TimeSpan(0, 0, 0, 0, 300))); } if (Game.Instance.Random.Next(0, 500) < 50) { item.Effect = fadeEffect; } entityManager.Add(item); others.Add(item); } // Setup this console to accept keyboard input. UseKeyboard = true; IsVisible = false; }
private void LoadShaderToyFile(string filepath) { int displayOutputBufferId = 1; renderer.Clear(); using (ZipArchive zip = ZipFile.OpenRead(filepath)) { renderer.SharedFragmentCode = zip.GetEntry("common.glsl")?.ReadToEnd(); string vertexShader = zip.GetEntry("shared.vs.glsl").ReadToEnd(); foreach (ZipArchiveEntry entry in zip.Entries) { if (entry.Name.StartsWith("rp") && entry.Name.EndsWith(".json")) { JObject jRenderPass = JObject.Parse(entry.ReadToEnd()); if (jRenderPass["type"].Value <string>() == "image") { displayOutputBufferId = jRenderPass["outputs"].Values <int>().First(); } ZipArchiveEntry shaderEntry = zip.GetEntry(jRenderPass["code"].Value <string>()); string shaderCode = shaderEntry.ReadToEnd(); RenderPassBuilder rpb = RenderPassBuilder.FromString(jRenderPass["name"].Value <string>(), vertexShader, shaderCode); foreach (JObject obj in jRenderPass["inputs"]) { string type = obj["type"].Value <string>(); if (type == "buffer") { rpb.AddBufferInput(obj["channel"].Value <int>(), obj["id"].Value <int>()); } else if (type == "texture") { string src = obj["src"].Value <string>(); ZipArchiveEntry e = zip.Entries.FirstOrDefault(x => src.EndsWith(x.Name)); rpb.AddTextureInput(obj["channel"].Value <int>(), e.Name, e.ReadAllBytes()); } } foreach (int bufferId in jRenderPass["outputs"].Values <int>()) { rpb.AddOutput(bufferId); } RenderPass rp = rpb.Create(); renderer.Add(rp); } } } renderer.DisplayOutputBufferId = displayOutputBufferId; renderer.InitPasses(); }
private static void Create300Sprites(Content content, Renderer renderer) { const int Columns = 20; const int Rows = 15; var screen = renderer.Screen; var size = new Size(screen.Viewport.Width / Columns, screen.Viewport.Height / Rows); var corner = screen.TopLeft; var logo = content.Load<Image>("DeltaEngineLogo"); for (int x = 0; x < Columns; x++) for (int y = 0; y < Rows; y++) renderer.Add(new Sprite(logo, new Rectangle(new Point(corner.X + x * size.Width, corner.Y + y * size.Height), size))); }