Example #1
0
        protected void ShowCore(FrameEventArgs e)
        {
            // workspace viewport
            GL.Viewport((int)(0.25 * Width), 0, (int)(0.75 * Width), Height);

            GL.Enable(EnableCap.DepthTest);  // TODO: fix depth test so that it doesn't hide objects behind alpha-fragments

            // clearing viewport
            GL.Enable(EnableCap.ScissorTest);
            GL.Scissor((int)(0.25 * Width), 0, (int)(0.75 * Width), Height);
            GL.ClearColor(0.2f, 0.3f, 0.3f, 1.0f);
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit | ClearBufferMask.StencilBufferBit);
            GL.Disable(EnableCap.ScissorTest);

            // attaching shader
            _shader.Use();

            // set view and projection matrices;
            // these matrices come pre-transposed, so there's no need to transpose them again (see VertexShader file)
            _shader.SetMatrix4("view", _camera.GetViewMatrix(), false);
            _shader.SetMatrix4("projection", _camera.GetProjectionMatrix(), false);

            // set general properties
            _shader.SetVector3("viewPos", _camera.Position);

            // set directional light properties
            _shader.SetVector3("dirLight[0].direction", new Vector3(1.0f, 0.0f, 0.0f));
            _shader.SetVector3("dirLight[1].direction", new Vector3(0.0f, -1.0f, 0.0f));
            _shader.SetVector3("dirLight[2].direction", new Vector3(0.0f, 0.0f, -1.0f));
            for (int i = 0; i < 3; i++)
            {
                _shader.SetVector3($"dirLight[{i}].ambient", new Vector3(0.05f, 0.05f, 0.05f));
                _shader.SetVector3($"dirLight[{i}].diffuse", new Vector3(0.75f, 0.75f, 0.75f));
                _shader.SetVector3($"dirLight[{i}].specular", new Vector3(0.5f, 0.5f, 0.5f));
            }

            // setup line shader
            lineShader.Use();
            lineShader.SetMatrix4("view", _camera.GetViewMatrix(), false);
            lineShader.SetMatrix4("projection", _camera.GetProjectionMatrix(), false);
            lineShader.SetVector3("color", Vector3.One);

            Matrix4 model;

            if (ManipLoaded)
            {
                // obstacles & colliders
                if (obstacles.Contains(null))
                {
                    for (int i = 0; i < obstacles.Length; i++)
                    {
                        obstacles[i] = new Entity(lineShader, GL_Convert(Manager.Obstacles[i].Data, Vector4.One));

                        switch (Manager.Obstacles[i].Collider.Shape)
                        {
                        case ColliderShape.Box:
                            boundings[i] = new Entity(lineShader, GL_Convert(Manager.Obstacles[i].Collider.Data, new Vector4(Vector3.UnitY, 1.0f)), new uint[]
                            {
                                0, 1, 2, 3, 0, 4, 5, 1, 5, 6, 2, 6, 7, 3, 7, 4
                            });
                            break;

                        case ColliderShape.Sphere:
                            boundings[i] = new Entity(lineShader, GL_Convert(Manager.Obstacles[i].Collider.Data, new Vector4(Vector3.UnitY, 1.0f)));
                            lon[i]       = new Entity(lineShader, GL_Convert(Manager.Obstacles[i].Collider.Data, new Vector4(Vector3.UnitY, 1.0f)), ((Sphere)Manager.Obstacles[i].Collider).indicesLongitude);
                            break;
                        }
                    }
                }
                else
                {
                    float dt;
                    if (forward)
                    {
                        dt = (float)e.Time;
                        if (time > 1)
                        {
                            forward = false;
                        }
                    }
                    else
                    {
                        dt = -(float)e.Time;
                        if (time < -1)
                        {
                            forward = true;
                        }
                    }
                    time += dt;

                    model = Matrix4.Identity * Matrix4.CreateTranslation(time, 0, 0);
                    for (int i = 0; i < obstacles.Length; i++)
                    {
                        Manager.Obstacles[i].Move(Vector3.UnitX, dt);

                        obstacles[i].Display(model, () =>
                        {
                            GL.DrawArrays(PrimitiveType.Points, 0, Manager.Obstacles[i].Data.Length);
                        });

                        if (Dispatcher.WorkspaceBuffer.ObstBuffer[i].ShowBounding)
                        {
                            boundings[i].Display(model, Manager.Obstacles[i].Collider.Draw);
                            lon[i].Display(model, ((Sphere)Manager.Obstacles[i].Collider).DrawLongitudes);
                        }
                    }
                }

                for (int j = 0; j < Manager.Manipulators.Length; j++)
                {
                    Manipulator manip = Manager.Manipulators[j];

                    // goal
                    if (goal[j] == null)
                    {
                        if (manip.States["Goal"])
                        {
                            List <Vector3> MainAttr = new List <Vector3> {
                                manip.GoodAttractors[0].Center
                            };
                            MainAttr.AddRange(manip.GoodAttractors[0].Area);
                            goal[j] = new Entity(lineShader, GL_Convert(MainAttr.ToArray(), new Vector4(1.0f, 1.0f, 0.0f, 1.0f)));
                        }
                    }
                    else
                    {
                        model = Matrix4.Identity;
                        goal[j].Display(model, () =>
                        {
                            GL.PointSize(5);
                            GL.DrawArrays(PrimitiveType.Points, 0, 1);
                            GL.PointSize(1);
                            GL.DrawArrays(PrimitiveType.Points, 1, manip.GoodAttractors[0].Area.Length);
                        });
                    }

                    // path
                    if (manip.States["Path"] && manip.Path != null)
                    {
                        int count = manip.Path.Count;
                        path[j] = new Entity(lineShader, GL_Convert(manip.Path.ToArray(), new Vector4(Vector3.UnitX, 1.0f)));

                        model = Matrix4.Identity;
                        path[j].Display(model, () =>
                        {
                            GL.DrawArrays(PrimitiveType.LineStrip, 0, count);
                        });
                    }

                    // random tree
                    if (manip.Tree != null)
                    {
                        // block the manager thread while updating tree
                        Dispatcher.ThreadHandle.Reset();

                        // add all elements from addition buffer to the hash set
                        var add = new List <Logic.PathPlanning.Tree.Node>(manip.Tree.AddBuffer);
                        tree[j].UnionWith(add);
                        manip.Tree.AddBuffer.Clear();

                        // delete all elements contained in deletion buffer from the hash set
                        var del = new List <Logic.PathPlanning.Tree.Node>(manip.Tree.DelBuffer);
                        tree[j].ExceptWith(del);
                        manip.Tree.DelBuffer.Clear();

                        // unblock the manager thread to continue calculations
                        Dispatcher.ThreadHandle.Set();
                    }

                    if (Dispatcher.WorkspaceBuffer.JointBuffer[j].ShowTree)
                    {
                        model = Matrix4.Identity;
                        foreach (var node in tree[j])
                        {
                            if (node.Entity == null)
                            {
                                node.Entity = CreateTreeBranch(node.p, node.Parent.p);
                            }

                            node.Entity.Display(model, () =>
                            {
                                GL.DrawArrays(PrimitiveType.LineStrip, 0, 2);
                            });
                        }
                    }

                    // draw manipulator configuration if its model is loaded properly
                    if (ManipLoaded)
                    {
                        manip.Draw(_shader);
                    }
                }
            }

            // workspace grid
            model = Matrix4.Identity;
            grid.Display(model, () =>
            {
                GL.DrawArrays(PrimitiveType.LineStrip, 0, 2);
                GL.DrawArrays(PrimitiveType.LineStrip, 2, 2);
            });
            for (int i = 1; i < 11; i++)
            {
                model = Matrix4.CreateTranslation(Vector3.UnitZ * i);
                grid.Display(model, () => { GL.DrawArrays(PrimitiveType.LineStrip, 0, 2); });
                model = Matrix4.CreateTranslation(Vector3.UnitZ * -i);
                grid.Display(model, () => { GL.DrawArrays(PrimitiveType.LineStrip, 0, 2); });

                model = Matrix4.CreateTranslation(Vector3.UnitX * i);
                grid.Display(model, () => { GL.DrawArrays(PrimitiveType.LineStrip, 2, 2); });
                model = Matrix4.CreateTranslation(Vector3.UnitX * -i);
                grid.Display(model, () => { GL.DrawArrays(PrimitiveType.LineStrip, 2, 2); });
            }

            model = Matrix4.Identity;
            gridFloor.Display(model, () =>
            {
                // the workspace grid rendering is done lastly, because it's common to render all transparent objects at last
                //
                // the blending function is determined as follows:
                // Color = SourceColor * SourceFactor + DestColor * DestFactor,
                // where
                //     SourceColor - color of the currently rendering fragment,
                //     SourceFactor - its factor,
                //     DestColor - color of the already rendered fragment (the one in the color buffer),
                //     DestFactor - its factor.
                //
                // so, to render transparent floor, we take SourceFactor as source's alpha (floor's alpha) and DestFactor as the remainder of the source's alpha
                // (the visible amount of the opaque object behind the floor)
                GL.Enable(EnableCap.Blend);
                GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);

                GL.DrawElements(BeginMode.Triangles, 7, DrawElementsType.UnsignedInt, 0);

                GL.Disable(EnableCap.Blend);
            });

            //ImGui.ShowDemoWindow();

            base.OnRenderFrame(e);
        }