public void Update() { UI.PushSurface(_modelPose); _model.Draw(Matrix.Identity, new Color(0.5f, 0.5f, 0.5f)); UI.PushSurface( _surfaceNode.ModelTransform.Pose, _surfaceNode.ModelTransform.Scale.XY0 / 2, _surfaceNode.ModelTransform.Scale.XY); Vec3 center = Hierarchy.ToWorld(Vec3.Zero); UI.Label("UI on a Model node!"); UI.HSeparator(); UI.Button("Do Thing"); UI.PopSurface(); UI.PopSurface(); if (_model.Intersect(new Ray(V.XYZ(SKMath.Cos(Time.Totalf) * 0.15f, 1, 0), -Vec3.Up), out Ray at)) { Lines.Add(at, 0.3f, new Color32(0, 255, 0, 255), 0.005f); } Tests.Screenshot("Tests/NodeUI.jpg", 400, 400, center + Vec3.One * 0.15f, center); }
public void Initialize() { /// :CodeSample: Mesh.GenerateCube /// ![Procedural Geometry Demo]({{site.url}}/img/screenshots/ProceduralGeometry.jpg) /// Here's a quick example of generating a mesh! You can store it in just a /// Mesh, or you can attach it to a Model for easier rendering later on. Mesh cubeMesh = Mesh.GenerateCube(Vec3.One * 0.4f); Model cubeModel = Model.FromMesh(cubeMesh, Default.Material); /// :End: demoCubeMesh = cubeMesh; demoCubeModel = cubeModel; /// :CodeSample: Mesh.GenerateRoundedCube /// ![Procedural Geometry Demo]({{site.url}}/img/screenshots/ProceduralGeometry.jpg) /// Here's a quick example of generating a mesh! You can store it in just a /// Mesh, or you can attach it to a Model for easier rendering later on. Mesh roundedCubeMesh = Mesh.GenerateRoundedCube(Vec3.One * 0.4f, 0.05f); Model roundedCubeModel = Model.FromMesh(roundedCubeMesh, Default.Material); /// :End: demoRoundedCubeMesh = roundedCubeMesh; demoRoundedCubeModel = roundedCubeModel; /// :CodeSample: Mesh.GenerateSphere /// ![Procedural Geometry Demo]({{site.url}}/img/screenshots/ProceduralGeometry.jpg) /// Here's a quick example of generating a mesh! You can store it in just a /// Mesh, or you can attach it to a Model for easier rendering later on. Mesh sphereMesh = Mesh.GenerateSphere(0.4f); Model sphereModel = Model.FromMesh(sphereMesh, Default.Material); /// :End: demoSphereMesh = sphereMesh; demoSphereModel = sphereModel; /// :CodeSample: Mesh.GenerateCylinder /// ![Procedural Geometry Demo]({{site.url}}/img/screenshots/ProceduralGeometry.jpg) /// Here's a quick example of generating a mesh! You can store it in just a /// Mesh, or you can attach it to a Model for easier rendering later on. Mesh cylinderMesh = Mesh.GenerateCylinder(0.4f, 0.4f, Vec3.Up); Model cylinderModel = Model.FromMesh(cylinderMesh, Default.Material); /// :End: demoCylinderMesh = cylinderMesh; demoCylinderModel = cylinderModel; /// :CodeSample: Mesh.GeneratePlane /// ![Procedural Geometry Demo]({{site.url}}/img/screenshots/ProceduralGeometry.jpg) /// Here's a quick example of generating a mesh! You can store it in just a /// Mesh, or you can attach it to a Model for easier rendering later on. Mesh planeMesh = Mesh.GeneratePlane(Vec2.One * 0.4f); Model planeModel = Model.FromMesh(planeMesh, Default.Material); /// :End: demoPlaneMesh = planeMesh; demoPlaneModel = planeModel; /// :CodeSample: Mesh.SetVerts Mesh.SetInds /// ## Procedurally generating a wavy grid /// ![Wavy Grid]({{site.url}}/img/screenshots/ProceduralGrid.jpg) /// Here, we'll generate a grid mesh using Mesh.SetVerts and Mesh.SetInds! This /// is a common example of creating a grid using code, we're using a sin wave /// to make it more visually interesting, but you could also substitute this for /// something like sampling a heightmap, or a more interesting mathematical /// formula! /// /// Note: x+y*gridSize is the formula for 2D (x,y) access of a 1D array that represents /// a grid. const int gridSize = 8; Vertex[] verts = new Vertex[gridSize * gridSize]; uint [] inds = new uint [gridSize * gridSize * 6]; for (int y = 0; y < gridSize; y++) { for (int x = 0; x < gridSize; x++) { // Create a vertex on a grid, centered about the origin. The dimensions extends // from -0.5 to +0.5 on the X and Z axes. The Y value is then sampled from // a sin wave using the x and y values. // // The normal of the vertex is then calculated from the derivative of the Y // value! verts[x + y * gridSize] = new Vertex( new Vec3( x / (float)gridSize - 0.5f, SKMath.Sin((x + y) * 0.7f) * 0.1f, y / (float)gridSize - 0.5f), new Vec3( -SKMath.Cos((x + y) * 0.7f), 1, -SKMath.Cos((x + y) * 0.7f)).Normalized); // Create triangle face indices from the current vertex, and the vertices // on the next row and column! Since there is no 'next' row and column on // the last row and column, we guard this with a check for size-1. if (x < gridSize - 1 && y < gridSize - 1) { int ind = (x + y * gridSize) * 6; inds[ind] = (uint)((x + 1) + (y + 1) * gridSize); inds[ind + 1] = (uint)((x + 1) + (y) * gridSize); inds[ind + 2] = (uint)((x) + (y + 1) * gridSize); inds[ind + 3] = (uint)((x) + (y + 1) * gridSize); inds[ind + 4] = (uint)((x + 1) + (y) * gridSize); inds[ind + 5] = (uint)((x) + (y) * gridSize); } } } demoProcMesh = new Mesh(); demoProcMesh.SetVerts(verts); demoProcMesh.SetInds(inds); /// :End: }
public void Update() { Hierarchy.Push(Matrix.T(0, 0, -0.3f)); UI.WindowBegin("Alignment", ref alignWindow, new Vec2(20, 0) * Units.cm2m); Vec2 size = new Vec2(5 * Units.cm2m, UI.LineHeight); if (UI.Radio("Left", alignX == TextAlign.XLeft, size)) { alignX = TextAlign.XLeft; } UI.SameLine(); if (UI.Radio("CenterX", alignX == TextAlign.XCenter, size)) { alignX = TextAlign.XCenter; } UI.SameLine(); if (UI.Radio("Right", alignX == TextAlign.XRight, size)) { alignX = TextAlign.XRight; } if (UI.Radio("Top", alignY == TextAlign.YTop, size)) { alignY = TextAlign.YTop; } UI.SameLine(); if (UI.Radio("CenterY", alignY == TextAlign.YCenter, size)) { alignY = TextAlign.YCenter; } UI.SameLine(); if (UI.Radio("Bottom", alignY == TextAlign.YBottom, size)) { alignY = TextAlign.YBottom; } UI.WindowEnd(); Hierarchy.Push(Matrix.T(0.1f, 0, 0)); Text.Add("X Center", Matrix.TRS(new Vec3(0, .1f, 0), Quat.LookDir(0, 0, 1)), TextAlign.XCenter | TextAlign.YCenter, alignX | alignY); Text.Add("X Left", Matrix.TRS(new Vec3(0, .15f, 0), Quat.LookDir(0, 0, 1)), TextAlign.XLeft | TextAlign.YCenter, alignX | alignY); Text.Add("X Right", Matrix.TRS(new Vec3(0, .2f, 0), Quat.LookDir(0, 0, 1)), TextAlign.XRight | TextAlign.YCenter, alignX | alignY); Lines.Add(new Vec3(0, .05f, 0), new Vec3(0, .25f, 0), Color32.White, 0.001f); Hierarchy.Pop(); Hierarchy.Push(Matrix.T(-0.1f, 0, 0)); Text.Add("Y Center", Matrix.TRS(new Vec3(0, .1f, 0), Quat.LookDir(0, 0, 1)), TextAlign.YCenter | TextAlign.XCenter, alignX | alignY); Lines.Add(new Vec3(-0.05f, .1f, 0), new Vec3(.05f, .1f, 0), Color32.White, 0.001f); Text.Add("Y Top", Matrix.TRS(new Vec3(0, .15f, 0), Quat.LookDir(0, 0, 1)), TextAlign.YTop | TextAlign.XCenter, alignX | alignY); Lines.Add(new Vec3(-0.05f, .15f, 0), new Vec3(.05f, .15f, 0), Color32.White, 0.001f); Text.Add("Y Bottom", Matrix.TRS(new Vec3(0, .2f, 0), Quat.LookDir(0, 0, 1)), TextAlign.YBottom | TextAlign.XCenter, alignX | alignY); Lines.Add(new Vec3(-0.05f, .2f, 0), new Vec3(.05f, .2f, 0), Color32.White, 0.001f); Hierarchy.Pop(); Hierarchy.Push(Matrix.T(0, -0.1f, 0)); if (Tests.IsTesting) { Renderer.Screenshot(Hierarchy.ToWorld(new Vec3(0, 0, 0.09f)), Hierarchy.ToWorld(Vec3.Zero), 600, 300, "../../../docs/img/screenshots/BasicText.jpg"); } /// :CodeSample: Text.MakeStyle Font.FromFile Text.Add /// Then it's pretty trivial to just draw some text on the screen! Just call /// Text.Add on update. If you don't have a TextStyle available, calling it /// without one will just fall back on the default style. // Text with an explicit text style Text.Add( "Here's\nSome\nMulti-line\nText!!", Matrix.TRS(new Vec3(0.1f, 0, 0), Quat.LookDir(0, 0, 1)), style); // Text using the default text style Text.Add( "Here's\nSome\nMulti-line\nText!!", Matrix.TRS(new Vec3(-0.1f, 0, 0), Quat.LookDir(0, 0, 1))); /// :End: Hierarchy.Push(Matrix.T(0, -0.2f, 0)); Text.Add( "Here's Some Multi-line Text!!", Matrix.TRS(new Vec3(0, 0.0f, 0), Quat.LookDir(0, 0, 1)), new Vec2(SKMath.Cos(Time.Totalf) * 10 + 11, 20) * Units.cm2m, TextFit.Clip, style, TextAlign.Center, alignX | alignY); Hierarchy.Pop(); Hierarchy.Pop(); Hierarchy.Pop(); }
public void Update() { Color colIntersect = Color.HSV(0, 0.8f, 1); Color colTest = Color.HSV(0, 0.6f, 1); Color colObj = Color.HSV(0.05f, 0.7f, 1); Color active = new Color(1, 1, 1, 0.7f); Color notActive = new Color(1, 1, 1, 1); // Plane and Ray bool planeRayActive = UI.AffordanceBegin("PlaneRay", ref posePlaneRay, new Bounds(Vec3.One * 0.4f)); boundsMesh.Draw(boundsMat, Matrix.TS(Vec3.Zero, 0.4f), planeRayActive ? active:notActive); Plane ground = new Plane(Vec3.Zero, new Vec3(1, 2, 0)); Ray groundRay = new Ray(Vec3.Zero + new Vec3(0, 0.2f, 0), Vec3.AngleXZ(Time.Totalf * 90, -2).Normalized()); Lines.Add(groundRay.position, groundRay.position + groundRay.direction * 0.1f, new Color32(255, 0, 0, 255), 2 * Units.mm2m); planeMesh.Draw(material, Matrix.TRS(Vec3.Zero, Quat.LookDir(ground.normal), 0.25f), colObj); if (groundRay.Intersect(ground, out Vec3 groundAt)) { sphereMesh.Draw(material, Matrix.TS(groundAt, 0.02f), colIntersect); } UI.AffordanceEnd(); if (Demos.TestMode) { Renderer.Screenshot(posePlaneRay.position + new Vec3(0.0f, 0.3f, 0.15f), posePlaneRay.position + Vec3.Up * 0.1f, 400, 400, "../../../docs/img/screenshots/RayIntersectPlane.jpg"); } // Line and Plane bool linePlaneActive = UI.AffordanceBegin("LinePlane", ref poseLinePlane, new Bounds(Vec3.One * 0.4f)); boundsMesh.Draw(boundsMat, Matrix.TS(Vec3.Zero, 0.4f), linePlaneActive ? active : notActive); Plane groundLinePlane = new Plane(Vec3.Zero, new Vec3(1, 2, 0)); Ray groundLineRay = new Ray(Vec3.Zero + new Vec3(0, 0.25f, 0), Vec3.AngleXZ(Time.Totalf * 90, -2).Normalized()); Vec3 groundLineP1 = groundLineRay.position + groundLineRay.direction * (SKMath.Cos(Time.Totalf * 3) + 1) * 0.2f; Vec3 groundLineP2 = groundLineRay.position + groundLineRay.direction * ((SKMath.Cos(Time.Totalf * 3) + 1) * 0.2f + 0.1f); Lines.Add(groundLineP1, groundLineP2, colTest, 2 * Units.mm2m); sphereMesh.Draw(material, Matrix.TS(groundLineP1, 0.01f), colTest); sphereMesh.Draw(material, Matrix.TS(groundLineP2, 0.01f), colTest); bool groundLineIntersects = groundLinePlane.Intersect(groundLineP1, groundLineP2, out Vec3 groundLineAt); planeMesh.Draw(material, Matrix.TRS(Vec3.Zero, Quat.LookDir(groundLinePlane.normal), 0.25f), groundLineIntersects? colIntersect : colObj); if (groundLineIntersects) { sphereMesh.Draw(material, Matrix.TS(groundLineAt, 0.02f), colIntersect); } UI.AffordanceEnd(); if (Demos.TestMode) { Renderer.Screenshot(poseLinePlane.position + new Vec3(0.0f, 0.3f, 0.15f), poseLinePlane.position + Vec3.Up * 0.1f, 400, 400, "../../../docs/img/screenshots/LineIntersectPlane.jpg"); } // Sphere and Ray bool sphereRayActive = UI.AffordanceBegin("SphereRay", ref poseSphereRay, new Bounds(Vec3.One * 0.4f)); boundsMesh.Draw(boundsMat, Matrix.TS(Vec3.Zero, 0.4f), sphereRayActive ? active : notActive); Sphere sphere = new Sphere(Vec3.Zero, 0.25f); Vec3 sphereDir = Vec3.AngleXZ(Time.Totalf * 90, SKMath.Cos(Time.Totalf * 3) * 1.5f + 0.1f).Normalized(); Ray sphereRay = new Ray(sphere.center - sphereDir * 0.35f, sphereDir); Lines.Add(sphereRay.position, sphereRay.position + sphereRay.direction * 0.1f, colTest, 2 * Units.mm2m); if (sphereRay.Intersect(sphere, out Vec3 sphereAt)) { sphereMesh.Draw(material, Matrix.TS(sphereAt, 0.02f), colIntersect); } sphereMesh.Draw(material, Matrix.TS(sphere.center, 0.25f), colObj); UI.AffordanceEnd(); if (Demos.TestMode) { Renderer.Screenshot(poseSphereRay.position + new Vec3(0.0f, 0.3f, 0.15f), poseSphereRay.position, 400, 400, "../../../docs/img/screenshots/RayIntersectSphere.jpg"); } // Bounds and Ray bool boundsRayActive = UI.AffordanceBegin("BoundsRay", ref poseBoundsRay, new Bounds(Vec3.One * 0.4f)); boundsMesh.Draw(boundsMat, Matrix.TS(Vec3.Zero, 0.4f), boundsRayActive ? active : notActive); Bounds bounds = new Bounds(Vec3.Zero, Vec3.One * 0.25f); Vec3 boundsDir = Vec3.AngleXZ(Time.Totalf * 90, SKMath.Cos(Time.Totalf * 3) * 1.5f).Normalized(); Ray boundsRay = new Ray(bounds.center - boundsDir * 0.35f, boundsDir); Lines.Add(boundsRay.position, boundsRay.position + boundsRay.direction * 0.1f, colTest, 2 * Units.mm2m); if (boundsRay.Intersect(bounds, out Vec3 boundsAt)) { sphereMesh.Draw(material, Matrix.TS(boundsAt, 0.02f), colIntersect); } cubeMesh.Draw(material, Matrix.TS(bounds.center, 0.25f), colObj); UI.AffordanceEnd(); if (Demos.TestMode) { Renderer.Screenshot(poseBoundsRay.position + new Vec3(0.0f, 0.3f, 0.15f), poseBoundsRay.position, 400, 400, "../../../docs/img/screenshots/RayIntersectBounds.jpg"); } // Bounds and Line bool boundsLineActive = UI.AffordanceBegin("BoundsLine", ref poseBoundsLine, new Bounds(Vec3.One * 0.4f)); boundsMesh.Draw(boundsMat, Matrix.TS(Vec3.Zero, 0.4f), boundsLineActive ? active : notActive); Bounds boundsLine = new Bounds(Vec3.Zero, Vec3.One * 0.25f); Vec3 boundsLineP1 = boundsLine.center + Vec3.AngleXZ(Time.Totalf * 45, SKMath.Cos(Time.Totalf * 3)) * 0.35f; Vec3 boundsLineP2 = boundsLine.center + Vec3.AngleXZ(Time.Totalf * 90, SKMath.Cos(Time.Totalf * 6)) * SKMath.Cos(Time.Totalf) * 0.35f; Lines.Add(boundsLineP1, boundsLineP2, colTest, 2 * Units.mm2m); sphereMesh.Draw(material, Matrix.TS(boundsLineP1, 0.01f), colTest); sphereMesh.Draw(material, Matrix.TS(boundsLineP2, 0.01f), colTest); cubeMesh.Draw(material, Matrix.TS(boundsLine.center, 0.25f), boundsLine.Contains(boundsLineP1, boundsLineP2) ? colIntersect : colObj); UI.AffordanceEnd(); if (Demos.TestMode) { Renderer.Screenshot(poseBoundsLine.position + new Vec3(0.0f, 0.3f, 0.15f), poseBoundsLine.position, 400, 400, "../../../docs/img/screenshots/LineIntersectBounds.jpg"); } // Cross product bool crossActive = UI.AffordanceBegin("Cross", ref poseCross, new Bounds(Vec3.One * 0.4f)); boundsMesh.Draw(boundsMat, Matrix.TS(Vec3.Zero, 0.4f), crossActive ? active : notActive); Vec3 crossStart = Vec3.Zero; //Vec3 right = Vec3.Cross(Vec3.Forward, Vec3.Up); // These are the same! Vec3 right = Vec3.PerpendicularRight(Vec3.Forward, Vec3.Up); Lines.Add(crossStart, crossStart + Vec3.Up * 0.1f, new Color32(255, 255, 255, 255), 2 * Units.mm2m); Lines.Add(crossStart, crossStart + Vec3.Forward * 0.1f, new Color32(255, 255, 255, 255), 2 * Units.mm2m); Lines.Add(crossStart, crossStart + right * 0.1f, new Color32(0, 255, 0, 255), 2 * Units.mm2m); Text.Add("Up", Matrix.TRS(crossStart + Vec3.Up * 0.1f, Quat.LookDir(-Vec3.Forward), 1), TextAlign.XCenter | TextAlign.YBottom); Text.Add("Fwd", Matrix.TRS(crossStart + Vec3.Forward * 0.1f, Quat.LookDir(-Vec3.Forward), 1), TextAlign.XCenter | TextAlign.YBottom); Text.Add("Vec3.Cross(Fwd,Up)", Matrix.TRS(crossStart + right * 0.1f, Quat.LookDir(-Vec3.Forward), 1), TextAlign.XCenter | TextAlign.YBottom); UI.AffordanceEnd(); if (Demos.TestMode) { Renderer.Screenshot(poseCross.position + new Vec3(0.075f, 0.1f, 0.15f), poseCross.position + new Vec3(0.075f, 0, 0), 400, 400, "../../../docs/img/screenshots/CrossProduct.jpg"); } }