Exemplo n.º 1
0
    //////////////////////

    public void Init()
    {
        Material floorMat = new Material(Shader.FromFile("floor_shader.hlsl"));

        floorMat.Transparency = Transparency.Blend;
        floorMat.SetVector("radius", new Vec4(5, 10, 0, 0));
        floorMat.QueueOffset = -11;

        floorMesh = Model.FromMesh(Mesh.GeneratePlane(new Vec2(40, 40), Vec3.Up, Vec3.Forward), floorMat);
        floorTr   = Matrix.TR(new Vec3(0, -1.5f, 0), Quat.Identity);

        demoSelectPose.position    = new Vec3(0, 0, -0.6f);
        demoSelectPose.orientation = Quat.LookDir(-Vec3.Forward);

        Tests.FindTests();
        Tests.SetTestActive(startTest);
        Tests.Initialize();
        for (int i = 0; i < Tests.DemoCount; i++)
        {
            demoNames.Add(Tests.GetDemoName(i).Substring("Demo".Length));
        }

        if (!Tests.IsTesting)
        {
            SK.AddStepper(new RenderCamera(new Pose(0.3f, 0, .5f, Quat.FromAngles(0, -90, 0)), 1000, 1000));
        }
    }
Exemplo n.º 2
0
        void DrawMenu()
        {
            UI.AffordanceBegin("PaletteMenu", ref palettePose, paletteModel.Bounds);
            paletteModel.Draw(Matrix.Identity);

            Pose p = new Pose(Vec3.Zero, Quat.FromAngles(90, 0, 0));

            UI.AffordanceBegin("LineSlider", ref p, new Bounds());
            UI.HSliderAt("Size", ref lineSize, 0.001f, 0.02f, 0, new Vec3(6, -1, 0) * Units.cm2m, new Vec2(8, 2) * Units.cm2m);
            Lines.Add(new Vec3(6, 1, -1) * Units.cm2m, new Vec3(-2, 1, -1) * Units.cm2m, activeColor, lineSize);
            UI.AffordanceEnd();

            if (UI.VolumeAt("White", new Bounds(new Vec3(4, 0, 7) * Units.cm2m, new Vec3(4, 2, 4) * Units.cm2m)))
            {
                SetColor(Color.White);
            }
            if (UI.VolumeAt("Red", new Bounds(new Vec3(9, 0, 3) * Units.cm2m, new Vec3(4, 2, 4) * Units.cm2m)))
            {
                SetColor(new Color(1, 0, 0));
            }
            if (UI.VolumeAt("Green", new Bounds(new Vec3(9, 0, -3) * Units.cm2m, new Vec3(4, 2, 4) * Units.cm2m)))
            {
                SetColor(new Color(0, 1, 0));
            }
            if (UI.VolumeAt("Blue", new Bounds(new Vec3(3, 0, -6) * Units.cm2m, new Vec3(4, 2, 4) * Units.cm2m)))
            {
                SetColor(new Color(0, 0, 1));
            }

            UI.AffordanceEnd();
        }
Exemplo n.º 3
0
    /// Once you have that information, it's simply a matter of placing a
    /// window off to the side of the hand! The palm pose Right direction
    /// points to different sides of each hand, so a different X offset
    /// is required for each hand.
    public static void DrawHandMenu(Handed handed)
    {
        if (!HandFacingHead(handed))
        {
            return;
        }

        // Decide the size and offset of the menu
        Vec2  size   = new Vec2(4, 16);
        float offset = handed == Handed.Left ? -2 - size.x : 2 + size.x;

        // Position the menu relative to the side of the hand
        Hand hand   = Input.Hand(handed);
        Vec3 at     = hand[FingerId.Little, JointId.KnuckleMajor].position;
        Vec3 down   = hand[FingerId.Little, JointId.Root].position;
        Vec3 across = hand[FingerId.Index, JointId.KnuckleMajor].position;

        Pose menuPose = new Pose(
            at,
            Quat.LookAt(at, across, at - down) * Quat.FromAngles(0, handed == Handed.Left ? 90 : -90, 0));

        menuPose.position += menuPose.Right * offset * U.cm;
        menuPose.position += menuPose.Up * (size.y / 2) * U.cm;

        // And make a menu!
        UI.WindowBegin("HandMenu", ref menuPose, size * U.cm, UIWin.Empty);
        UI.Button("Test");
        UI.Button("That");
        UI.Button("Hand");
        UI.WindowEnd();
    }
Exemplo n.º 4
0
        public void Render()
        {
            if (!this.IsVisible)
            {
                return;
            }

            var material = this.GetMaterialGroup(-1).GetMaterial();

            if (material != null)
            {
                this.Node?.Draw(
                    SK.Matrix.TRS(this.WorldPosition.ToSKVec3(),
                                  Quat.FromAngles(
                                      this.WorldRotation.X,
                                      this.WorldRotation.Y,
                                      this.WorldRotation.Z),
                                  this.WorldSize.ToSKVec3()),
                    material.Diffuse.ToSKColor(material.Opacity));
            }
            else
            {
                this.Node?.Draw(
                    SK.Matrix.TRS(this.WorldPosition.ToSKVec3(),
                                  Quat.FromAngles(
                                      this.WorldRotation.X,
                                      this.WorldRotation.Y,
                                      this.WorldRotation.Z),
                                  this.WorldSize.ToSKVec3()));
            }
        }
Exemplo n.º 5
0
 public static SK.Quat ToSKQuat(this Imml.Numerics.Vector3 vector3)
 {
     //StereoKit is using a coordinate system where:
     // X increases to the right
     // Y increases up
     // Z increases towards the viewer
     return(Quat.FromAngles(
                vector3.X,
                vector3.Y,
                vector3.Z));
 }
Exemplo n.º 6
0
 /// Now all we need to do is show the QR codes! In this case,
 /// we're just displaying an axis widget, and the contents of
 /// the QR code as text.
 ///
 /// With the text, all we're doing is squeezing the text into
 /// the bounds of the QR code, and shifting it to be a little
 /// forward, in front of the code!
 public void Update()
 {
     foreach (QRData d in poses.Values)
     {
         Lines.AddAxis(d.pose, d.size);
         Text.Add(
             d.text,
             Matrix.TRS(
                 d.pose.position + d.pose.Forward * d.size * 0.1f,
                 Quat.FromAngles(0, 0, 180) * d.pose.orientation),
             Vec2.One * d.size,
             TextFit.Squeeze,
             TextAlign.XLeft | TextAlign.YTop);
     }
 }
Exemplo n.º 7
0
    bool TestMatrixDecompose()
    {
        Vec3   translate = new Vec3(1, 2, 3);
        Quat   rotate    = Quat.FromAngles(0, 90, 0);
        Vec3   scale     = new Vec3(1, 2, 1);
        Matrix mat       = Matrix.TRS(translate, rotate, scale);

        Vec3 exTranslate = mat.Translation;
        Quat exRotate    = mat.Rotation;
        Vec3 exScale     = mat.Scale;

        Log.Info($"Transform matrix:     {translate  } {rotate  } {scale  }");
        Log.Info($"Matrix sep decompose: {exTranslate} {exRotate} {exScale}");

        if (Vec3.Distance(exTranslate, translate) > tolerance)
        {
            return(false);
        }
        if (Vec3.Distance(exScale, scale) > tolerance)
        {
            return(false);
        }

        if (!mat.Decompose(out exTranslate, out exRotate, out exScale))
        {
            return(false);
        }
        Log.Info($"Matrix decompose:     {exTranslate} {exRotate} {exScale}");

        if (Vec3.Distance(exTranslate, translate) > tolerance)
        {
            return(false);
        }
        if (Vec3.Distance(exScale, scale) > tolerance)
        {
            return(false);
        }

        return(true);
    }
Exemplo n.º 8
0
    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();
    }
Exemplo n.º 9
0
    /// :End:

    public static void DrawHandSize()
    {
        for (int h = 0; h < (int)Handed.Max; h++)
        {
            Hand hand = Input.Hand((Handed)h);
            if (!hand.IsTracked)
            {
                continue;
            }

            HandJoint at  = hand[FingerId.Middle, JointId.Tip];
            Vec3      pos = at.position + at.Pose.Forward * at.radius;
            Quat      rot = at.orientation * Quat.FromAngles(-90, 0, 0);
            if (!HandFacingHead((Handed)h))
            {
                rot = rot * Quat.FromAngles(0, 180, 0);
            }

            Text.Add(
                (hand.size * 100).ToString(".0") + "cm",
                Matrix.TRS(pos, rot, 0.3f),
                TextAlign.XCenter | TextAlign.YBottom);
        }
    }
Exemplo n.º 10
0
        /// :CodeSample: Controller Input.Controller TrackState Input.ControllerMenuButton Controller.IsTracked Controller.trackedPos Controller.trackedRot Controller.IsX1Pressed Controller.IsX2Pressed Controller.IsStickClicked Controller.stick Controller.aim Controller.grip Controller.trigger Controller.pose
        /// ### Controller Debug Visualizer
        /// This function shows a debug visualization of the current state of
        /// the controller! It's not something you'd show to users, but it's
        /// nice for just seeing how the API works, or as a temporary
        /// visualization.
        void ShowController(Handed hand)
        {
            Controller c = Input.Controller(hand);

            if (!c.IsTracked)
            {
                return;
            }

            Hierarchy.Push(c.pose.ToMatrix());
            // Pick the controller color based on trackin info state
            Color color = Color.Black;

            if (c.trackedPos == TrackState.Inferred)
            {
                color.g = 0.5f;
            }
            if (c.trackedPos == TrackState.Known)
            {
                color.g = 1;
            }
            if (c.trackedRot == TrackState.Inferred)
            {
                color.b = 0.5f;
            }
            if (c.trackedRot == TrackState.Known)
            {
                color.b = 1;
            }
            Default.MeshCube.Draw(Default.Material, Matrix.S(new Vec3(3, 3, 8) * U.cm), color);

            // Show button info on the back of the controller
            Hierarchy.Push(Matrix.TR(0, 1.6f * U.cm, 0, Quat.LookAt(Vec3.Zero, new Vec3(0, 1, 0), new Vec3(0, 0, -1))));

            // Show the tracking states as text
            Text.Add(c.trackedPos == TrackState.Known?"(pos)":(c.trackedPos == TrackState.Inferred?"~pos~":"pos"), Matrix.TS(0, -0.03f, 0, 0.25f));
            Text.Add(c.trackedRot == TrackState.Known?"(rot)":(c.trackedRot == TrackState.Inferred?"~rot~":"rot"), Matrix.TS(0, -0.02f, 0, 0.25f));

            // Show the controller's buttons
            Text.Add(Input.ControllerMenuButton.IsActive()?"(menu)":"menu", Matrix.TS(0, -0.01f, 0, 0.25f));
            Text.Add(c.IsX1Pressed?"(X1)":"X1", Matrix.TS(0, 0.00f, 0, 0.25f));
            Text.Add(c.IsX2Pressed?"(X2)":"X2", Matrix.TS(0, 0.01f, 0, 0.25f));

            // Show the analog stick's information
            Vec3 stickAt = new Vec3(0, 0.03f, 0);

            Lines.Add(stickAt, stickAt + c.stick.XY0 * 0.01f, Color.White, 0.001f);
            if (c.IsStickClicked)
            {
                Text.Add("O", Matrix.TS(stickAt, 0.25f));
            }

            // And show the trigger and grip buttons
            Default.MeshCube.Draw(Default.Material, Matrix.TS(0, -0.015f, -0.005f, new Vec3(0.01f, 0.04f, 0.01f)) * Matrix.TR(new Vec3(0, 0.02f, 0.03f), Quat.FromAngles(-45 + c.trigger * 40, 0, 0)));
            Default.MeshCube.Draw(Default.Material, Matrix.TS(0.0149f * (hand == Handed.Right?1:-1), 0, 0.015f, new Vec3(0.01f * (1 - c.grip), 0.04f, 0.01f)));

            Hierarchy.Pop();
            Hierarchy.Pop();

            // And show the pointer
            Default.MeshCube.Draw(Default.Material, c.aim.ToMatrix(new Vec3(1, 1, 4) * U.cm), Color.HSV(0, 0.5f, 0.8f).ToLinear());
        }
Exemplo n.º 11
0
    public void Update()
    {
        Hierarchy.Push(Matrix.T(0, 2, 0));
        Mesh.Sphere.Draw(wireframeMaterial, Matrix.TS(-0.07f, 0, 0, 0.1f));
        Mesh.Sphere.Draw(Material.Default, Matrix.TS(0.07f, 0, 0, 0.1f));
        Tests.Screenshot("Drawing_MeshLooksLike.jpg", 600, 400, Hierarchy.ToWorld(V.XYZ(0, 0, 0.12f)), Hierarchy.ToWorld(Vec3.Zero));
        Hierarchy.Pop();

        /// :CodeDoc: Guides Drawing
        /// At its core, drawing things in 3D is done through a combination of
        /// [`Mesh`]({{site.url}}/Pages/Reference/Mesh.html)es and
        /// [`Material`]({{site.url}}/Pages/Reference/Material.html)s. A Mesh
        /// is a collection of triangles in 3D space that describe where the
        /// surface of that 3D object is. And a Material is then a collection
        /// of parameters, [`Tex`]({{site.url}}/Pages/Reference/Tex.html)tures
        /// (2d images), and Shader code that are combined to describe the
        /// visual properties of the Mesh's surface!
        ///
        /// ![Meshes are made from triangles!]({{site.screen_url}}/Drawing_MeshLooksLike.jpg)
        /// _Meshes are made from triangles!_
        ///
        /// And in addition to that, you'll need to know a little bit about
        /// matrices, which are a math construct used to describe the location,
        /// orientation and scale of geometry within the 3D space! A [`Matrix`]({{site.url}}/Pages/Reference/Matrix.html)
        /// isn't difficult the way we're using it, so don't worry if math
        /// isn't your thing.
        ///
        /// And then StereoKit also has a [`Model`]({{site.url}}/Pages/Reference/Model.html),
        /// which is a high level combination of Meshes, Material, Matrices,
        /// and a few more things! Most of the time, you'll probably be drawing
        /// Models loaded from file, but it's important to have options.
        ///
        /// Then lastly, StereoKit has easy systems for drawing [`Line`]({{site.url}}/Pages/Reference/Lines.html)s,
        /// [`Text`]({{site.url}}/Pages/Reference/Text.html), [`Sprite`]({{site.url}}/Pages/Reference/Sprite.html)s
        /// and various other things! These are still based on Meshes and
        /// Materials under the hood, but have some complex features that can
        /// make them difficult to build from scratch.
        ///
        /// ## Meshes and Materials
        ///
        /// To simplify things here, we're going to use the built-in assets,
        /// [`Mesh.Sphere`]({{site.url}}/Pages/Reference/Mesh/Sphere.html)
        /// and [`Material.Default`]({{site.url}}/Pages/Reference/Material/Default.html).
        /// Mesh.Sphere is a built-in mesh generated using math when StereoKit
        /// starts up, and Material.Default is a high performance simple
        /// Material that serves as StereoKit's default Material. (For more
        /// built-in assets, see the [`Default`]({{site.url}}/Pages/Reference/Default.html)s)
        ///
        Mesh.Sphere.Draw(Material.Default, Matrix.Identity);
        ///
        /// ![Default sphere and material]({{site.screen_url}}/Drawing_Defaults.jpg)
        /// _Drawing the default sphere Mesh with the default Material._
        ///
        /// [`Matrix.Identity`]({{site.url}}/Pages/Reference/Matrix/Identity.html)
        /// can be though of as a 'No transform' Matrix, so this is drawing the
        /// sphere at the origin of the 3D space.
        ///
        /// That's pretty straightforward! StereoKit will get this Mesh/Material
        /// pair onto the screen this frame. Remember that StereoKit is
        /// generally an immediate mode API, so this won't show up for more
        /// than the current frame. If you want it to draw every frame, you'll
        /// have to call Draw every frame!
        ///
        /// So how do you get a Mesh to begin with? In most cases you'll just
        /// be working with Models, but you can get a Mesh directly from a few
        /// places:
        ///  - [`Mesh.Sphere`]({{site.url}}/Pages/Reference/Mesh/Sphere.html), [`Mesh.Cube`]({{site.url}}/Pages/Reference/Mesh/Cube.html), and [`Mesh.Quad`]({{site.url}}/Pages/Reference/Mesh/Quad.html) are built-in mesh assets that are handy to have around.
        ///  - [`Mesh`]({{site.url}}/Pages/Reference/Mesh.html) has a number of static methods for generating procedural shapes, such as [`Mesh.GenerateRoundedCube`]({{site.url}}/Pages/Reference/Mesh/GenerateRoundedCube.html) or [`Mesh.GeneratePlane`]({{site.url}}/Pages/Reference/Mesh/GeneratePlane.html).
        ///  - A Mesh can be extracted from one of a [Model's nodes]({{site.url}}/Pages/Reference/ModelNode/Mesh.html).
        ///  - You can create a Mesh from a list of vertices and indices. This is more advanced, but [check the sample here]({{site.url}}/Pages/Reference/Mesh/SetVerts.html).
        ///
        /// And where do you get a Material? Well,
        ///  - See built-in Materials like [`Material.PBR`]({{site.url}}/Pages/Reference/Default/MaterialPBR.html) for high-quality surface or [`Material.Unlit`]({{site.url}}/Pages/Reference/Default/MaterialUnlit.html) for fast/stylisic surfaces.
        ///  - A Material [constructor]({{site.url}}/Pages/Reference/Material/Material.html) can be called with a Shader. Check out [the Material guide]({{site.url}}/Pages/Guides/Materials-and-Shaders.html) for in-depth usage (Materials and Shaders are a lot of fun!).
        ///  - You can call [`Material.Copy`]({{site.url}}/Pages/Reference/Material/Copy.html) to create a duplicate of an existing Material.
        ///
        /// ## Matrix basics
        ///
        /// If you like math, this explanation is not really for you! But if
        /// you like results, this will get you going where you need to go. The
        /// important thing to know about a [`Matrix`]({{site.url}}/Pages/Reference/Matrix.html),
        /// is that it's a good way to represent an object's transform (Translation,
        /// Rotation, and Scale).
        ///
        /// StereoKit provides a number of Matrix creation methods that allow
        /// you to easily create Translation/Rotation/Scale matrices.

        // The identity matrix is the matrix equivalent of '1'. You can also
        // think of it as a 'no-transform' matrix.
        Matrix transform = Matrix.Identity;

        // Translates points 1 meter up the Y axis
        transform = Matrix.T(0, 1, 0);

        // Scales a point by (2,2,2), rotates it 180 on the X axis, and
        // then translates it up 1 meter up the Y axis.
        transform = Matrix.TRS(
            new Vec3(0, 1, 0),
            Quat.FromAngles(180, 0, 0),
            new Vec3(2, 2, 2));

        // To draw a cube at (0,-10,0) that's rotated 45 degrees around its Y
        // axis:
        Mesh.Cube.Draw(Material.Default, Matrix.TR(0, -10, 0, Quat.FromAngles(0, 45, 0)));
        ///
        /// The TRS methods have a lot of permutations that can help make your
        /// matrix creation code a bit shorter. Like, if you don't need to add
        /// scale to your TRS matrix, there's the TR variant! No rotation? Try
        /// TS! Etc. etc.
        ///
        /// Now. Even _more_ interesting, is that many Matrices can be combined
        /// into a single Matrix representing multiple transforms! This is done
        /// via multiplication, and an important note here is that matrix
        /// multiplication is not commutative, that is: `A*B != B*A`, so the
        /// order in which you combine your matrices is important.
        ///
        /// This can let you do things like, rotate around a pivot point, or
        /// build a hierarchy of transforms! A parent/child position hierarchy
        /// can be described pretty easily this way:

        Matrix parentTransform = Matrix.TR(10, 0, 0, Quat.FromAngles(0, 45, 0));
        Matrix childTransform  = Matrix.TS(1, 1, 0, 0.2f);

        Mesh.Cube.Draw(Material.Default, parentTransform);
        Mesh.Cube.Draw(Material.Default, childTransform * parentTransform);
        ///
        /// ![Combining matrices]({{site.screen_url}}/Drawing_MatrixCombine.jpg)
        /// _The smaller `childTransform` is relative to `parentTransform` via multiplication._
        ///
        /// ## Models
        ///
        /// The easiest way to draw complex content is through a Model! A Model
        /// is basically a small scene of Mesh/Material pairs at positions with
        /// hierarchical relationships to eachother. If you're creating art in
        /// a 3D modeling tool such as Blender, then this is basically a full
        /// representation of the scene you've created there.
        ///
        /// Since a model already has all its information within it, all you
        /// need to do is provide it with a location!
        model.Draw(Matrix.T(10, 10, 0));
        /// ![Drawing a model]({{site.screen_url}}/Drawing_Model.jpg)
        /// _StereoKit's main format is the .gltf file._
        ///
        /// So... that was also pretty simple! The only real trick with Models
        /// is getting one in the first place, but even that's not too hard.
        /// There's a lot you can do with a Model beyond just drawing it, so
        /// for more details on that, check out [the Model guide]({{site.url}}/Pages/Guides/Working-with-Models.html)!
        ///
        /// But here's the quick list of where you can get a Model to begin
        /// with:
        ///  - [`Model.FromFile`]({{site.url}}/Pages/Reference/Model/FromFile.html) is the easiest, most common way to get a Model!
        ///  - [`Model.FromMesh`]({{site.url}}/Pages/Reference/Model/FromMesh.html) will let you create a very simple Model with a single function call.
        ///  - The [Model constructor]({{site.url}}/Pages/Reference/Model/Model.html) lets you create an empty Model, which you can then fill with ModelNodes via [`Model.AddNode`]({{site.url}}/Pages/Reference/Model/AddNode.html)
        ///  - You can call [`Model.Copy`]({{site.url}}/Pages/Reference/Model/Copy.html) to create a duplicate of an existing Model.
        ///
        /// ## Lines
        ///
        /// Being able to easily draw a line is incredibly useful for
        /// debugging, and generally quite practical for many other purposes as
        /// well! StereoKit has the [`Lines`]({{site.url}}/Pages/Reference/Lines.html)
        /// class to assist with this, and is pretty straightforward to use.
        /// There's a few variations, but at it's simplest, it's a few points,
        /// a color, and a thickness.
        Lines.Add(
            new Vec3(2, 2, 0),
            new Vec3(3, 2.5f, 0),
            Color.Black, 1 * U.cm);
        /// ![Drawing a line]({{site.screen_url}}/Drawing_Lines.jpg)
        /// _You can also draw Rays, Poses, and multicolored lists of lines!_
        ///
        /// ## Text
        ///
        /// Text is drawn with a collection of rectangular quads, each mapped
        /// to a character glyph on a texture. StereoKit supports rendering any
        /// unicode glyphs yout throw at it, as long as the active Font has
        /// that glyph defined in it! This means you can work with all sorts of
        /// different languages right away, without any baking or preparation.
        ///
        /// To draw text with the default Font, you can do this!
        Text.Add("こんにちは", Matrix.T(-10, 10, 0));
        ///
        /// ![Drawing text]({{site.screen_url}}/Drawing_Text.jpg)
        /// _'Hello' in Japanese, I'm pretty sure._
        ///
        /// You can create additional font styles and fonts to use with text
        /// drawing, and there are a number of overloads for [`Text.Add`]({{site.url}}/Pages/Reference/Text/Add.html)
        /// that allow you to change the layout or constrain to a particular
        /// area. Check the docs for the method for more information about that!
        ///
        /// ## Cool!
        ///
        /// So that's the highlights! There's plenty more to draw and more
        /// tricks to be learned, but this is a great start! There's treasures
        /// in the documentation, so hunt around in there for more samples. You
        /// may also be interested in the [Materials guide]({{site.url}}/Pages/Guides/Working-with-Materials.html)
        /// for advanced rendering code, or [the Model guide]({{site.url}}/Pages/Guides/Working-with-Models.html)
        /// for managing your visible content!
        ///
        /// If you'd like to see all the code for this document,
        /// [check it out here!](https://github.com/maluoi/StereoKit/blob/master/Examples/StereoKitTest/Guides/GuideDrawing.cs)
        /// :End:
        Tests.Screenshot("Drawing_Defaults.jpg", 600, 600, V.XYZ(0, 0, 1.2f), Vec3.Zero);
        Tests.Screenshot("Drawing_MatrixCombine.jpg", 600, 600, V.XYZ(10, 0, 2), V.XYZ(10, 0, 0));
        Tests.Screenshot("Drawing_Model.jpg", 600, 600, 60, V.XYZ(10, 10, -3f), V.XYZ(10, 10, 0));
        Tests.Screenshot("Drawing_Lines.jpg", 600, 600, V.XYZ(2.5f, 2.25f, 0.8f), V.XYZ(2.5f, 2.25f, 0));
        Tests.Screenshot("Drawing_Text.jpg", 600, 600, V.XYZ(-10, 10, -0.1f), V.XYZ(-10, 10, 0));
    }
Exemplo n.º 12
0
    public void Update()
    {
        Tests.Screenshot("Tests/LineRenderer.jpg", 600, 600, V.XYZ(0, 0, 0.5f), Vec3.Zero);

        // A ring of lines that goes out past the edge of the screen
        Color32 c = Color32.White;

        for (int i = 0; i < 16; i++)
        {
            Vec3 at = Vec3.AngleXY((i / 16.0f) * 360.0f) * 0.5f;
            Lines.Add(at - V.XYZ(0, 0, 0.2f), at + V.XYZ(0, 0, 0.2f), c, 0.01f);
        }

        // A Circle
        c = new Color(1, .5f, .5f, 1).ToLinear();
        LinePoint[] points = new LinePoint[17];
        for (int i = 0; i < points.Length; i++)
        {
            points[i] = new LinePoint(
                Vec3.AngleXY((i / (float)(points.Length - 1)) * 360.0f) * 0.4f,
                c, 0.01f);
        }
        Lines.Add(points);

        // A square, worst case for this system
        c = new Color(.5f, 1, .5f, 1).ToLinear();
        Lines.Add(new LinePoint[] {
            new LinePoint(V.XY0(-0.25f, 0.25f), c, 0.01f),
            new LinePoint(V.XY0(0.25f, 0.25f), c, 0.01f),
            new LinePoint(V.XY0(0.25f, -0.25f), c, 0.01f),
            new LinePoint(V.XY0(-0.25f, -0.25f), c, 0.01f),
            new LinePoint(V.XY0(-0.25f, 0.25f), c, 0.01f),
        });

        // A beveled square
        c = new Color(.5f, .5f, 1, 1).ToLinear();
        Lines.Add(new LinePoint[] {
            new LinePoint(V.XY0(-0.2f, 0.19f), c, 0.01f),
            new LinePoint(V.XY0(-0.19f, 0.2f), c, 0.01f),
            new LinePoint(V.XY0(0.19f, 0.2f), c, 0.01f),
            new LinePoint(V.XY0(0.2f, 0.19f), c, 0.01f),
            new LinePoint(V.XY0(0.2f, -0.19f), c, 0.01f),
            new LinePoint(V.XY0(0.19f, -0.2f), c, 0.01f),
            new LinePoint(V.XY0(-0.19f, -0.2f), c, 0.01f),
            new LinePoint(V.XY0(-0.2f, -0.19f), c, 0.01f),
            new LinePoint(V.XY0(-0.2f, 0.19f), c, 0.01f),
        });

        // an Icosohedron
        float t  = (1.0f + SKMath.Sqrt(5.0f)) / 2.0f;
        float s  = 0.08f;
        float s2 = 0.3f;
        int   h  = 0;
        Vec3  v;

        Hierarchy.Push(Matrix.R(Quat.FromAngles(10, 10, 10)));
        v = V.XYZ(-1, t, 0) * s; Lines.Add(v, v * s2, Color.HSV((h++) / 12.0f, 0.8f, 0.8f).ToLinear(), 0.01f);
        v = V.XYZ(1, t, 0) * s; Lines.Add(v, v * s2, Color.HSV((h++) / 12.0f, 0.8f, 0.8f).ToLinear(), 0.01f);
        v = V.XYZ(-1, -t, 0) * s; Lines.Add(v, v * s2, Color.HSV((h++) / 12.0f, 0.8f, 0.8f).ToLinear(), 0.01f);
        v = V.XYZ(1, -t, 0) * s; Lines.Add(v, v * s2, Color.HSV((h++) / 12.0f, 0.8f, 0.8f).ToLinear(), 0.01f);
        v = V.XYZ(0, -1, t) * s; Lines.Add(v, v * s2, Color.HSV((h++) / 12.0f, 0.8f, 0.8f).ToLinear(), 0.01f);
        v = V.XYZ(0, 1, t) * s; Lines.Add(v, v * s2, Color.HSV((h++) / 12.0f, 0.8f, 0.8f).ToLinear(), 0.01f);
        v = V.XYZ(0, -1, -t) * s; Lines.Add(v, v * s2, Color.HSV((h++) / 12.0f, 0.8f, 0.8f).ToLinear(), 0.01f);
        v = V.XYZ(0, 1, -t) * s; Lines.Add(v, v * s2, Color.HSV((h++) / 12.0f, 0.8f, 0.8f).ToLinear(), 0.01f);
        v = V.XYZ(t, 0, -1) * s; Lines.Add(v, v * s2, Color.HSV((h++) / 12.0f, 0.8f, 0.8f).ToLinear(), 0.01f);
        v = V.XYZ(t, 0, 1) * s; Lines.Add(v, v * s2, Color.HSV((h++) / 12.0f, 0.8f, 0.8f).ToLinear(), 0.01f);
        v = V.XYZ(-t, 0, -1) * s; Lines.Add(v, v * s2, Color.HSV((h++) / 12.0f, 0.8f, 0.8f).ToLinear(), 0.01f);
        v = V.XYZ(-t, 0, 1) * s; Lines.Add(v, v * s2, Color.HSV((h++) / 12.0f, 0.8f, 0.8f).ToLinear(), 0.01f);
        Hierarchy.Pop();
    }
Exemplo n.º 13
0
    bool TestMatrixTransform()
    {
        Vec3   translate = new Vec3(10, 0, 0);
        Vec3   rotate    = new Vec3(0, 90, 0);
        Vec3   scale     = new Vec3(2, 2, 2);
        Matrix mat       = Matrix.TRS(translate, Quat.FromAngles(rotate), scale);

        Log.Info($"Transform matrix: {translate} {rotate} {scale}");

        // Check ray transforms
        Ray ray1 = new Ray(Vec3.Zero, V.XYZ(0, 0, 1));
        Ray ray2 = new Ray(V.XYZ(1, 0, 0), V.XYZ(0, 0, 1));

        Ray tRay1 = mat.Transform(ray1);
        Ray tRay2 = mat * ray2;

        Log.Info($"Ray {ray1} -> {tRay1}");
        Log.Info($"Ray {ray2} -> {tRay2}");

        if (Vec3.Distance(tRay1.position, V.XYZ(10, 0, 0)) > tolerance)
        {
            return(false);
        }
        if (Vec3.Distance(tRay1.direction, V.XYZ(2, 0, 0)) > tolerance)
        {
            return(false);
        }
        if (Vec3.Distance(tRay2.position, V.XYZ(10, 0, -2)) > tolerance)
        {
            return(false);
        }
        if (Vec3.Distance(tRay2.direction, V.XYZ(2, 0, 0)) > tolerance)
        {
            return(false);
        }

        // Check pose transforms
        Pose pose1 = Pose.Identity;
        Pose pose2 = new Pose(V.XYZ(1, 0, 0), Quat.FromAngles(0, 90, 0));

        Pose tPose1 = mat.Transform(pose1);
        Pose tPose2 = mat * pose2;

        Log.Info($"Pose {pose1} -> {tPose1}");
        Log.Info($"Pose {pose2} -> {tPose2}");

        if (Vec3.Distance(tPose1.position, V.XYZ(10, 0, 0)) > tolerance)
        {
            return(false);
        }
        if (Vec3.Distance(tPose1.Forward, V.XYZ(-1, 0, 0)) > tolerance)
        {
            return(false);
        }
        if (Vec3.Distance(tPose2.position, V.XYZ(10, 0, -2)) > tolerance)
        {
            return(false);
        }
        if (Vec3.Distance(tPose2.Forward, V.XYZ(0, 0, 1)) > tolerance)
        {
            return(false);
        }

        return(true);
    }
Exemplo n.º 14
0
    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);

        planeMesh.Draw(Default.Material, planeTransform);

        planeTransform = Matrix.T(.5f, -1, 0);
        planeModel.Draw(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.
        // Call this code every Step

        Matrix cubeTransform = Matrix.T(-.5f, -.5f, 0);

        cubeMesh.Draw(Default.Material, cubeTransform);

        cubeTransform = Matrix.T(.5f, -.5f, 0);
        cubeModel.Draw(cubeTransform);
        /// :End:


        // Rounded Cube!
        Mesh  roundedCubeMesh  = demoRoundedCubeMesh;
        Model roundedCubeModel = demoRoundedCubeModel;

        /// :CodeSample: Mesh Mesh.GenerateRoundedCube Mesh.Draw
        /// 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.
        // Call this code every Step

        Matrix roundedCubeTransform = Matrix.T(-.5f, 0, 0);

        roundedCubeMesh.Draw(Default.Material, roundedCubeTransform);

        roundedCubeTransform = Matrix.T(.5f, 0, 0);
        roundedCubeModel.Draw(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.
        // Call this code every Step

        Matrix sphereTransform = Matrix.T(-.5f, .5f, 0);

        sphereMesh.Draw(Default.Material, sphereTransform);

        sphereTransform = Matrix.T(.5f, .5f, 0);
        sphereModel.Draw(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.
        // Call this code every Step

        Matrix cylinderTransform = Matrix.T(-.5f, 1, 0);

        cylinderMesh.Draw(Default.Material, cylinderTransform);

        cylinderTransform = Matrix.T(.5f, 1, 0);
        cylinderModel.Draw(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);
    }
Exemplo n.º 15
0
        void StepMenu(Hand hand)
        {
            // Animate the menu a bit
            float time = (Time.Elapsedf * 24);

            menuPose.position    = Vec3.Lerp(menuPose.position, destPose.position, time);
            menuPose.orientation = Quat.Slerp(menuPose.orientation, destPose.orientation, time);
            activation           = SKMath.Lerp(activation, 1, time);

            // Pre-calculate some circle traversal values
            HandRadialLayer layer    = layers[activeLayer];
            int             count    = layer.items.Length;
            float           step     = 360 / count;
            float           halfStep = step / 2;

            // Push the Menu's pose onto the stack, so we can draw, and work
            // in local space.
            Hierarchy.Push(menuPose.ToMatrix(activation));

            // Calculate the status of the menu!
            Vec3  tipWorld = hand[FingerId.Index, JointId.Tip].position;
            Vec3  tipLocal = Hierarchy.ToLocal(tipWorld);
            float magSq    = tipLocal.MagnitudeSq;
            bool  onMenu   = tipLocal.z > -0.02f && tipLocal.z < 0.02f;
            bool  focused  = onMenu && magSq > minDist * minDist;
            bool  selected = onMenu && magSq > midDist * midDist;
            bool  cancel   = magSq > maxDist * maxDist;

            // Find where our finger is pointing to, and draw that
            float fingerAngle = (float)Math.Atan2(tipLocal.y, tipLocal.x) * Units.rad2deg - (layer.startAngle + angleOffset);

            while (fingerAngle < 0)
            {
                fingerAngle += 360;
            }
            int angleId = (int)(fingerAngle / step);

            Lines.Add(Vec3.Zero, new Vec3(tipLocal.x, tipLocal.y, 0), Color.White * 0.5f, 0.001f);

            // Draw the menu inner and outer circles
            Lines.Add(circle);
            Lines.Add(innerCircle);

            // Now draw each of the menu items!
            for (int i = 0; i < count; i++)
            {
                float currAngle     = i * step + layer.startAngle + angleOffset;
                bool  highlightText = focused && angleId == i;
                bool  highlightLine = highlightText || (focused && (angleId + 1) % count == i);
                Vec3  dir           = Vec3.AngleXY(currAngle);
                Lines.Add(dir * minDist, dir * maxDist, highlightLine ? Color.White : Color.White * 0.5f, highlightLine?0.002f:0.001f);
                Text.Add(layer.items[i].name, Matrix.TRS(Vec3.AngleXY(currAngle + halfStep) * midDist, Quat.FromAngles(0, 0, currAngle + halfStep - 90), highlightText?1.2f:1), TextAlign.XCenter | TextAlign.YBottom);
            }

            // Done with local work
            Hierarchy.Pop();

            // Execute any actions that were discovered

            // But not if we're still in the process of animating, interaction values
            // could be pretty incorrect when we're still lerping around.
            if (activation < 0.95f)
            {
                return;
            }
            if (selected)
            {
                SelectItem(layer.items[angleId], tipWorld, (angleId + 0.5f) * step);
            }
            if (cancel)
            {
                Close();
            }
        }
Exemplo n.º 16
0
    public void Initialize()
    {
        /// :CodeSample: Model Model.AddNode Model.FindNode ModelNode.AddChild
        /// ### Assembling a Model
        /// While normally you'll load Models from file, you can also assemble
        /// them yourself procedurally! This example shows assembling a simple
        /// hierarchy of visual and empty nodes.
        Model model = new Model();

        model
        .AddNode("Root", Matrix.S(0.2f), Mesh.Cube, Material.Default)
        .AddChild("Sub", Matrix.TR(V.XYZ(0.5f, 0, 0), Quat.FromAngles(0, 0, 45)), Mesh.Cube, Material.Default)
        .AddChild("Surface", Matrix.TRS(V.XYZ(0.5f, 0, 0), Quat.LookDir(V.XYZ(1, 0, 0)), V.XYZ(1, 1, 1)));

        ModelNode surfaceNode = model.FindNode("Surface");

        surfaceNode.AddChild("UnitX", Matrix.T(Vec3.UnitX));
        surfaceNode.AddChild("UnitY", Matrix.T(Vec3.UnitY));
        surfaceNode.AddChild("UnitZ", Matrix.T(Vec3.UnitZ));
        /// :End:

        Tests.Test(() => model.FindNode("NotPresent") == null);

        /// :CodeSample: Model Model.Nodes
        /// ### Simple iteration
        /// Walking through the Model's list of nodes is pretty
        /// straightforward! This will touch every ModelNode in the Model,
        /// in the order they were defined, regardless of hierarchy position
        /// or contents.
        Log.Info("Iterate nodes:");
        foreach (ModelNode node in model.Nodes)
        {
            Log.Info("  " + node.Name);
        }
        /// :End:

        /// :CodeSample: Model Model.Visuals
        /// ### Simple iteration of visual nodes
        /// This will iterate through every ModelNode in the Model with visual
        /// data attached to it!
        Log.Info("Iterate visuals:");
        foreach (ModelNode node in model.Visuals)
        {
            Log.Info("  " + node.Name);
        }
        /// :End:

        /// :CodeSample: Model Model.Visuals Model.Nodes
        /// ### Tagged Nodes
        /// You can search through Visuals and Nodes
        var nodes = model.Visuals
                    .Where(n => n.Name.StartsWith("[Wire]"));

        foreach (var node in nodes)
        {
            node.Material           = node.Material.Copy();
            node.Material.Wireframe = true;
        }
        /// :End:

        Log.Info("Recursive ModelNode traversal:");
        RecursiveTraversal(model.RootNode);

        Log.Info("Depth first ModelNode traversal:");
        DepthFirstTraversal(model);

        for (int i = 0; i < model.Nodes.Count; i++)
        {
            Log.Info($"{model.Nodes[i].Name} using shader {model.Nodes[i].Material?.Shader.Name}");
        }


        _model       = model;
        _surfaceNode = surfaceNode;
    }