Exemplo n.º 1
0
        public void DrawDefaultWidget(DeviceContext context, Camera cam, Vector3 camrel, Quaternion ori, float size)
        {
            SetShader(context);
            SetInputLayout(context, VertexType.Default);

            SceneVars.Vars.Mode   = 0; //vertices mode
            SceneVars.Vars.CamRel = camrel;
            SetSceneVars(context, cam, null, null);

            Vector3 xdir    = ori.Multiply(Vector3.UnitX);
            Vector3 ydir    = ori.Multiply(Vector3.UnitY);
            Vector3 zdir    = ori.Multiply(Vector3.UnitZ);
            Color4  xcolour = new Color4(0.8f, 0.0f, 0.0f, 1.0f);
            Color4  ycolour = new Color4(0.8f, 0.0f, 0.0f, 1.0f);
            Color4  zcolour = new Color4(0.5f, 0.5f, 0.5f, 1.0f);

            Vector3[] axes    = { xdir, ydir, zdir };
            Vector3[] sides   = { ydir, xdir, xdir };
            Color4[]  colours = { xcolour, ycolour, zcolour };

            float linestart  = 0.0f * size;
            float lineend    = 1.0f * size;
            float arrowstart = 0.9f * size;
            float arrowend   = 1.0f * size;
            float arrowrad   = 0.05f * size;

            //draw lines...
            Vertices.Clear();

            for (int i = 0; i < 3; i++)
            {
                WidgetAxis sa    = (WidgetAxis)(1 << i);
                Color4     axcol = colours[i];

                //main axis lines
                Vertices.Add(new WidgetShaderVertex(axes[i] * linestart, axcol));
                Vertices.Add(new WidgetShaderVertex(axes[i] * lineend, axcol));

                //arrow heads
                Vector3 astart = axes[i] * arrowstart;
                Vector3 aend   = axes[i] * arrowend;
                Vector3 aside  = sides[i] * arrowrad;
                Vertices.Add(new WidgetShaderVertex(aend, axcol));
                Vertices.Add(new WidgetShaderVertex(astart + aside, axcol));
                Vertices.Add(new WidgetShaderVertex(aend, axcol));
                Vertices.Add(new WidgetShaderVertex(astart - aside, axcol));
            }

            Vertices.Update(context);
            Vertices.SetVSResource(context, 0);

            context.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.LineList;
            context.Draw(Vertices.CurrentCount, 0);

            UnbindResources(context);
        }
Exemplo n.º 2
0
        protected int GetAxisIndex(WidgetAxis axis)
        {
            switch (axis)
            {
            default:
            case WidgetAxis.X: return(0);

            case WidgetAxis.Y: return(1);

            case WidgetAxis.Z: return(2);
            }
        }
Exemplo n.º 3
0
        public override void Render(DeviceContext context, Camera cam, WidgetShader shader)
        {
            if (!Visible)
            {
                return;
            }

            Vector3 camrel = Position - cam.Position;
            float   dist   = camrel.Length();
            float   size   = GetWorldSize(Size, dist, cam);

            WidgetAxis ax = IsDragging ? DraggedAxis : MousedAxis;

            var ori = Rotation; //scale is always in object space.

            shader.DrawScaleWidget(context, cam, camrel, ori, size, ax);
        }
Exemplo n.º 4
0
        public override void Render(DeviceContext context, Camera cam, WidgetShader shader)
        {
            if (!Visible)
            {
                return;
            }

            Vector3 camrel = Position - cam.Position;
            float   dist   = camrel.Length();
            float   size   = GetWorldSize(Size, dist, cam);

            WidgetAxis ax = IsDragging ? DraggedAxis : MousedAxis;

            var ori = ObjectSpace ? Rotation : Quaternion.Identity;

            shader.DrawRotationWidget(context, cam, camrel, ori, size, ax, EnableAxes);
        }
Exemplo n.º 5
0
        public override void Update(Camera cam)
        {
            if (!Visible)
            {
                return;
            }

            var ori = Rotation;// : Quaternion.Identity;

            Vector3 xdir = Vector3.UnitX;
            Vector3 ydir = Vector3.UnitY;
            Vector3 zdir = Vector3.UnitZ;

            Vector3[]    axes    = { xdir, ydir, zdir };
            Vector3[]    sides1  = { ydir, zdir, xdir };
            Vector3[]    sides2  = { zdir, xdir, ydir };
            WidgetAxis[] sideax1 = { WidgetAxis.Y, WidgetAxis.Z, WidgetAxis.X };
            WidgetAxis[] sideax2 = { WidgetAxis.Z, WidgetAxis.X, WidgetAxis.Y };



            Quaternion iori   = Quaternion.Invert(ori);
            Vector3    camrel = iori.Multiply(Position - cam.Position);
            Vector3    cdir   = Vector3.Normalize(camrel);
            Ray        ray    = cam.MouseRay;

            ray.Position  = iori.Multiply(ray.Position);
            ray.Direction = iori.Multiply(ray.Direction);


            float dist = camrel.Length();
            float size = GetWorldSize(Size, dist, cam);

            float axhitrad   = 0.09f * size;
            float axhitstart = 0.4f * size;
            float axhitend   = 1.33f * size;
            float innertri   = 0.7f * size;
            float outertri   = 1.0f * size;

            //test for single and double axes hits
            BoundingBox bb   = new BoundingBox();
            float       hitd = float.MaxValue;
            float       d;
            Vector3     hitp;
            WidgetAxis  hitax = WidgetAxis.None;

            for (int i = 0; i < 3; i++)
            {
                WidgetAxis ax = (WidgetAxis)(1 << i);
                Vector3    s  = sides1[i] * axhitrad + sides2[i] * axhitrad;
                bb.Minimum = camrel - s + axes[i] * axhitstart;
                bb.Maximum = camrel + s + axes[i] * axhitend;
                if (ray.Intersects(ref bb, out d)) //single axis
                {
                    if (d < hitd)
                    {
                        hitd  = d;
                        hitax = ax;
                    }
                }

                Vector3 s1 = axes[i];
                Vector3 s2 = sides1[i];
                if (GetAxisRayHit(s1, s2, camrel, ray, out hitp))
                {
                    //test if hitp is within the inner triangle - uniform scale
                    //test if hitp is within the outer triangle - 2 axes scale
                    float hitpl = hitp.Length();
                    if (hitpl > hitd)
                    {
                        continue;
                    }
                    Vector3 hitrel = hitp - camrel;
                    float   d1     = Vector3.Dot(hitrel, s1);
                    float   d2     = Vector3.Dot(hitrel, s2);

                    if ((d1 > 0) && (d2 > 0))
                    {
                        if ((d1 < innertri) && (d2 < innertri) && ((d1 + d2) < innertri))
                        {
                            hitd  = hitpl;
                            hitax = WidgetAxis.XYZ;
                        }
                        else if ((d1 < outertri) && (d2 < outertri) && ((d1 + d2) < outertri))
                        {
                            hitd  = hitpl;
                            hitax = ax | sideax1[i];
                        }
                    }
                }
            }
            if (LockXY)
            {
                switch (hitax)
                {
                case WidgetAxis.X:
                case WidgetAxis.Y:
                    hitax = WidgetAxis.XY;
                    break;

                case WidgetAxis.XZ:
                case WidgetAxis.YZ:
                    hitax = WidgetAxis.XYZ;
                    break;
                }
            }


            MousedAxis = hitax;


            if (IsDragging && !WasDragging)
            {
                //drag start. mark the start vector and axes
                DraggedAxis        = MousedAxis;
                DragStartScale     = Scale;
                DraggedAxisDir     = axes[0];
                DraggedAxisSideDir = axes[1];

                switch (DraggedAxis)
                {
                case WidgetAxis.XZ: DraggedAxisSideDir = axes[2]; break;

                case WidgetAxis.YZ: DraggedAxisDir = axes[1]; DraggedAxisSideDir = axes[2]; break;

                case WidgetAxis.Y: DraggedAxisDir = axes[1]; break;

                case WidgetAxis.Z: DraggedAxisDir = axes[2]; break;
                }
                switch (DraggedAxis) //find the best second axis to use, for single axis motion only.
                {
                case WidgetAxis.X:
                case WidgetAxis.Y:
                case WidgetAxis.Z:
                    int   curax = GetAxisIndex(DraggedAxis);
                    int   minax = 0;
                    float mindp = float.MaxValue;
                    for (int i = 0; i < 3; i++)
                    {
                        if (i != curax)
                        {
                            float dp = Math.Abs(Vector3.Dot(cdir, axes[i]));
                            if (dp < mindp)
                            {
                                mindp = dp;
                                minax = i;
                            }
                        }
                    }
                    DraggedAxisSideDir = axes[minax];
                    break;
                }
                if (DraggedAxis == WidgetAxis.XYZ)
                {
                    //all axes, move in the screen plane
                    float ad1 = Math.Abs(Vector3.Dot(cdir, Vector3.UnitY));
                    float ad2 = Math.Abs(Vector3.Dot(cdir, Vector3.UnitZ));
                    DraggedAxisDir     = Vector3.Normalize(Vector3.Cross(cdir, (ad1 > ad2) ? Vector3.UnitY : Vector3.UnitZ));
                    DraggedAxisSideDir = Vector3.Normalize(Vector3.Cross(cdir, DraggedAxisDir));
                }


                bool hit = GetAxisRayHit(DraggedAxisDir, DraggedAxisSideDir, camrel, ray, out DragStartVec);
                if ((MousedAxis == WidgetAxis.None) || !hit)
                {
                    IsDragging = false;
                }
            }
            else if (IsDragging)
            {
                //continue drag.
                Vector3 newvec;
                bool    hit = GetAxisRayHit(DraggedAxisDir, DraggedAxisSideDir, camrel, ray, out newvec);
                if (hit)
                {
                    Vector3 diff = newvec - DragStartVec;
                    switch (DraggedAxis)
                    {
                    case WidgetAxis.X: diff.Y = 0; diff.Z = 0; break;

                    case WidgetAxis.Y: diff.X = 0; diff.Z = 0; break;

                    case WidgetAxis.Z: diff.X = 0; diff.Y = 0; break;
                    }

                    //diff = ori.Multiply(diff);
                    Vector3 ods = DragStartVec - camrel;                   // ori.Multiply(DragStartVec);
                    float   odl = Math.Max(ods.Length(), 0.0001f);         //don't divide by 0
                    float   ndl = Math.Max((ods + diff).Length(), 0.001f); //don't scale to 0 size
                    float   dl  = ndl / odl;

                    if (diff.Length() < 10000.0f) //limit movement in one go, to avoid crazy values...
                    {
                        Vector3 oldscale = Scale;
                        Vector3 sv       = Vector3.One;
                        switch (DraggedAxis)
                        {
                        case WidgetAxis.X: sv = new Vector3(dl, 1, 1); break;

                        case WidgetAxis.Y: sv = new Vector3(1, dl, 1); break;

                        case WidgetAxis.Z: sv = new Vector3(1, 1, dl); break;

                        case WidgetAxis.XY: sv = new Vector3(dl, dl, 1); break;

                        case WidgetAxis.YZ: sv = new Vector3(1, dl, dl); break;

                        case WidgetAxis.XZ: sv = new Vector3(dl, 1, dl); break;

                        case WidgetAxis.XYZ: sv = new Vector3(dl); break;
                        }
                        Scale = DragStartScale * sv;

                        if (Scale != oldscale)
                        {
                            OnScaleChange?.Invoke(Scale, oldscale);
                        }
                    }
                }
            }

            WasDragging = IsDragging;
        }
Exemplo n.º 6
0
        public override void Update(Camera cam)
        {
            if (!Visible)
            {
                return;
            }

            var     ori  = ObjectSpace ? Rotation : Quaternion.Identity;
            Vector3 xdir = ori.Multiply(Vector3.UnitX);
            Vector3 ydir = ori.Multiply(Vector3.UnitY);
            Vector3 zdir = ori.Multiply(Vector3.UnitZ);

            Vector3[] axes   = { xdir, ydir, zdir };
            Vector3[] sides1 = { ydir, zdir, xdir };
            Vector3[] sides2 = { zdir, xdir, ydir };

            Ray     ray        = cam.MouseRay;
            Vector3 camrel     = Position - cam.Position;
            float   dist       = camrel.Length();
            float   size       = GetWorldSize(Size, dist, cam);
            float   ocircsize  = 1.0f * size;  //outer ring radius
            float   icircsize  = 0.75f * size; //inner ring radius
            float   icircthick = 0.2f * size;  //inner ring hit width
            float   ocircthick = 0.13f * size; //outer ring hit width
            float   icirchiti  = icircsize - icircthick;
            float   icirchito  = icircsize + icircthick;
            float   ocirchiti  = ocircsize - ocircthick;
            float   ocirchito  = ocircsize + ocircthick;


            //test for the main axes hits
            float      cullvalue = -0.18f;
            float      hitd      = float.MaxValue;
            Vector3    hitp      = camrel;
            Vector3    hitrel    = Vector3.Zero;
            WidgetAxis hitax     = WidgetAxis.None;
            Vector3    hitaxd    = Vector3.UnitX;
            Vector3    hitax1    = Vector3.UnitY;
            Vector3    hitax2    = Vector3.UnitZ;

            for (int i = 0; i < 3; i++)
            {
                WidgetAxis ax = (WidgetAxis)(1 << i);
                if ((ax & EnableAxes) == 0)
                {
                    continue;
                }
                Vector3 s1 = sides1[i];
                Vector3 s2 = sides2[i];
                if (GetAxisRayHit(s1, s2, camrel, ray, out hitp))
                {
                    float hitdist = hitp.Length();
                    float hitreld = (camrel.Length() - hitdist) / size;
                    if (hitreld < cullvalue)
                    {
                        continue;                      //this hit was at the backside of the widget; ignore
                    }
                    Vector3 thitrel = hitp - camrel;
                    float   hitrad  = thitrel.Length();
                    if ((hitrad > icirchiti) && (hitrad < icirchito) && (hitdist < hitd))
                    {
                        hitd   = hitdist;
                        hitax  = ax;
                        hitax1 = s1;
                        hitax2 = s2;
                        hitrel = thitrel;
                        hitaxd = axes[i];
                    }
                }
            }

            //test for the outer ring hit
            if ((hitax == WidgetAxis.None) && (EnableAxes == WidgetAxis.XYZ))
            {
                Vector3 sdir = Vector3.Normalize(camrel);
                //if (cam.IsMapView || cam.IsOrthographic)
                //{
                //    sdir = cam.ViewDirection;
                //}
                float   ad1 = Math.Abs(Vector3.Dot(sdir, Vector3.UnitY));
                float   ad2 = Math.Abs(Vector3.Dot(sdir, Vector3.UnitZ));
                Vector3 ax1 = Vector3.Normalize(Vector3.Cross(sdir, (ad1 > ad2) ? Vector3.UnitY : Vector3.UnitZ));
                Vector3 ax2 = Vector3.Normalize(Vector3.Cross(sdir, ax1));
                if (GetAxisRayHit(ax1, ax2, camrel, ray, out hitp))
                {
                    Vector3 thitrel = hitp - camrel;
                    float   hitrad  = thitrel.Length();
                    if ((hitrad > ocirchiti) && (hitrad < ocirchito))
                    {
                        hitax  = WidgetAxis.XYZ;
                        hitax1 = ax1;
                        hitax2 = ax2;
                        hitrel = thitrel;
                        hitaxd = sdir;
                    }
                }
            }


            MousedAxis = hitax;


            if (IsDragging && !WasDragging)
            {
                //drag start. mark the start vector and axes
                DraggedAxis         = MousedAxis;
                DragStartRotation   = Rotation;
                DraggedAxisDir      = hitaxd;
                DraggedAxisSideDir1 = hitax1;
                DraggedAxisSideDir2 = hitax2;

                bool hit = GetAxisRayHit(DraggedAxisSideDir1, DraggedAxisSideDir2, camrel, ray, out DragStartVec);
                if ((MousedAxis == WidgetAxis.None) || !hit)
                {
                    IsDragging = false;
                }
            }
            else if (IsDragging)
            {
                //continue drag.
                Vector3 newvec;
                bool    hit = GetAxisRayHit(DraggedAxisSideDir1, DraggedAxisSideDir2, camrel, ray, out newvec);
                if (hit)
                {
                    Vector3 diff = newvec - DragStartVec;
                    if (diff.Length() < 10000.0f) //put some limit to the plane intersection...
                    {
                        Vector3    nv     = Vector3.Normalize(newvec - camrel);
                        Vector3    ov     = Vector3.Normalize(DragStartVec - camrel);
                        float      na     = AngleOnAxes(nv, DraggedAxisSideDir1, DraggedAxisSideDir2);
                        float      oa     = AngleOnAxes(ov, DraggedAxisSideDir1, DraggedAxisSideDir2);
                        float      a      = na - oa;
                        Quaternion rot    = Quaternion.RotationAxis(DraggedAxisDir, a);
                        Quaternion oldrot = Rotation;
                        Rotation = Quaternion.Normalize(Quaternion.Multiply(rot, DragStartRotation));
                        if (Rotation != oldrot)
                        {
                            OnRotationChange?.Invoke(Rotation, oldrot);
                        }
                    }
                }
            }


            WasDragging = IsDragging;
        }
Exemplo n.º 7
0
        public override void Update(Camera cam)
        {
            if (!Visible)
            {
                return;
            }

            var ori = ObjectSpace ? Rotation : Quaternion.Identity;

            Vector3 xdir = Vector3.UnitX;
            Vector3 ydir = Vector3.UnitY;
            Vector3 zdir = Vector3.UnitZ;

            Vector3[]    axes    = { xdir, ydir, zdir };
            Vector3[]    sides1  = { ydir, zdir, xdir };
            Vector3[]    sides2  = { zdir, xdir, ydir };
            WidgetAxis[] sideax1 = { WidgetAxis.Y, WidgetAxis.Z, WidgetAxis.X };
            WidgetAxis[] sideax2 = { WidgetAxis.Z, WidgetAxis.X, WidgetAxis.Y };



            Quaternion iori   = Quaternion.Invert(ori);
            Vector3    camrel = iori.Multiply(Position - cam.Position);
            Vector3    cdir   = Vector3.Normalize(camrel);
            Ray        ray    = cam.MouseRay;

            ray.Position  = iori.Multiply(ray.Position);
            ray.Direction = iori.Multiply(ray.Direction);


            float dist         = camrel.Length();
            float size         = GetWorldSize(Size, dist, cam);
            float linestart    = 0.2f * size;
            float lineend      = 1.0f * size;
            float sideval      = 0.4f * size;
            float arrowstart   = 1.0f * size;
            float arrowend     = 1.33f * size;
            float arrowrad     = 0.06f * size;
            float axhitrad     = 0.07f * size;
            float axhitstart   = 0.2f * size;
            float axhitend     = 1.33f * size;
            float sidehitend   = 0.5f * size;
            float sidehitstart = 0.25f * size;
            float allhitrad    = 0.07f * size;

            //test for single and double axes hits
            BoundingBox bb = new BoundingBox();
            BoundingBox bb2 = new BoundingBox();
            float       hitd = float.MaxValue;
            float       d, d2;
            WidgetAxis  hitax = WidgetAxis.None;

            for (int i = 0; i < 3; i++)
            {
                WidgetAxis ax = (WidgetAxis)(1 << i);
                Vector3    s  = sides1[i] * axhitrad + sides2[i] * axhitrad;
                bb.Minimum = camrel - s + axes[i] * axhitstart;
                bb.Maximum = camrel + s + axes[i] * axhitend;
                if (ray.Intersects(ref bb, out d)) //single axis
                {
                    if (d < hitd)
                    {
                        hitd  = d;
                        hitax = ax;
                    }
                }
                for (int n = i + 1; n < 3; n++)
                {
                    //double axis hit test - don't hit if in the central area (L shape hit area)
                    WidgetAxis ax2 = (WidgetAxis)(1 << n);
                    bb.Minimum  = camrel;
                    bb.Maximum  = camrel + axes[i] * sidehitend + axes[n] * sidehitend;
                    bb2.Minimum = camrel;
                    bb2.Maximum = camrel + axes[i] * sidehitstart + axes[n] * sidehitstart;
                    if (ray.Intersects(ref bb, out d) && !ray.Intersects(ref bb2, out d2))
                    {
                        if (d < hitd)
                        {
                            hitd  = d;
                            hitax = ax | ax2;
                        }
                    }
                }
            }

            //small box at the center for all axes hit.
            Vector3 ss = (axes[0] + axes[1] + axes[2]) * allhitrad;

            bb.Minimum = camrel - ss;
            bb.Maximum = camrel + ss;
            if (ray.Intersects(ref bb, out d))
            {
                if (d < hitd)
                {
                    hitd  = d;
                    hitax = WidgetAxis.XYZ;
                }
            }

            MousedAxis = hitax;


            if (IsDragging && !WasDragging)
            {
                //drag start. mark the start vector and axes
                DraggedAxis        = MousedAxis;
                DragStartPosition  = Position;
                DraggedAxisDir     = axes[0];
                DraggedAxisSideDir = axes[1];

                switch (DraggedAxis)
                {
                case WidgetAxis.XZ: DraggedAxisSideDir = axes[2]; break;

                case WidgetAxis.YZ: DraggedAxisDir = axes[1]; DraggedAxisSideDir = axes[2]; break;

                case WidgetAxis.Y: DraggedAxisDir = axes[1]; break;

                case WidgetAxis.Z: DraggedAxisDir = axes[2]; break;
                }
                switch (DraggedAxis) //find the best second axis to use, for single axis motion only.
                {
                case WidgetAxis.X:
                case WidgetAxis.Y:
                case WidgetAxis.Z:
                    int   curax = GetAxisIndex(DraggedAxis);
                    int   minax = 0;
                    float mindp = float.MaxValue;
                    for (int i = 0; i < 3; i++)
                    {
                        if (i != curax)
                        {
                            float dp = Math.Abs(Vector3.Dot(cdir, axes[i]));
                            if (dp < mindp)
                            {
                                mindp = dp;
                                minax = i;
                            }
                        }
                    }
                    DraggedAxisSideDir = axes[minax];
                    break;
                }
                if (DraggedAxis == WidgetAxis.XYZ)
                {
                    //all axes, move in the screen plane
                    float ad1 = Math.Abs(Vector3.Dot(cdir, Vector3.UnitY));
                    float ad2 = Math.Abs(Vector3.Dot(cdir, Vector3.UnitZ));
                    DraggedAxisDir     = Vector3.Normalize(Vector3.Cross(cdir, (ad1 > ad2) ? Vector3.UnitY : Vector3.UnitZ));
                    DraggedAxisSideDir = Vector3.Normalize(Vector3.Cross(cdir, DraggedAxisDir));
                }


                bool hit = GetAxisRayHit(DraggedAxisDir, DraggedAxisSideDir, camrel, ray, out DragStartVec);
                if ((MousedAxis == WidgetAxis.None) || !hit)
                {
                    IsDragging = false;
                }
            }
            else if (IsDragging)
            {
                //continue drag.
                Vector3 newvec;
                bool    hit = GetAxisRayHit(DraggedAxisDir, DraggedAxisSideDir, camrel, ray, out newvec);
                if (hit)
                {
                    Vector3 diff = newvec - DragStartVec;
                    switch (DraggedAxis)
                    {
                    case WidgetAxis.X: diff.Y = 0; diff.Z = 0; break;

                    case WidgetAxis.Y: diff.X = 0; diff.Z = 0; break;

                    case WidgetAxis.Z: diff.X = 0; diff.Y = 0; break;
                    }

                    if (ObjectSpace)
                    {
                        diff = ori.Multiply(diff);
                    }

                    if (diff.Length() < 10000.0f) //limit movement in one go, to avoid losing the widget...
                    {
                        Vector3 oldpos = Position;
                        Position = DragStartPosition + diff;
                        if (Position != oldpos)
                        {
                            OnPositionChange?.Invoke(Position, oldpos);
                        }
                    }
                }
            }



            WasDragging = IsDragging;
        }
Exemplo n.º 8
0
        public void DrawScaleWidget(DeviceContext context, Camera cam, Vector3 camrel, Quaternion ori, float size, WidgetAxis selax)
        {
            SetShader(context);
            SetInputLayout(context, VertexType.Default);

            SceneVars.Vars.Mode   = 0; //vertices mode
            SceneVars.Vars.CamRel = camrel;
            SetSceneVars(context, cam, null, null);

            Vector3 xdir     = ori.Multiply(Vector3.UnitX);
            Vector3 ydir     = ori.Multiply(Vector3.UnitY);
            Vector3 zdir     = ori.Multiply(Vector3.UnitZ);
            Color4  xcolour  = new Color4(1.0f, 0.0f, 0.0f, 1.0f);
            Color4  ycolour  = new Color4(0.0f, 1.0f, 0.0f, 1.0f);
            Color4  zcolour  = new Color4(0.0f, 0.0f, 1.0f, 1.0f);
            Color4  selaxcol = new Color4(1.0f, 1.0f, 0.0f, 1.0f);
            Color4  selplcol = new Color4(1.0f, 1.0f, 0.0f, 0.5f);

            Vector3[]    axes        = { xdir, ydir, zdir };
            Vector3[]    sides1      = { ydir, zdir, xdir };
            Vector3[]    sides2      = { zdir, xdir, ydir };
            WidgetAxis[] sideax1     = { WidgetAxis.Y, WidgetAxis.Z, WidgetAxis.X };
            WidgetAxis[] sideax2     = { WidgetAxis.Z, WidgetAxis.X, WidgetAxis.Y };
            Color4[]     colours     = { xcolour, ycolour, zcolour };
            Color4[]     coloursn    = { ycolour, zcolour, xcolour };
            Color4[]     coloursdark = { xcolour * 0.5f, ycolour * 0.5f, zcolour * 0.5f };
            for (int i = 0; i < 3; i++)
            {
                coloursdark[i].Alpha = 1.0f;
            }

            float linestart = 0.0f * size;
            float lineend   = 1.33f * size;
            float innertri  = 0.7f * size;
            float outertri  = 1.0f * size;
            float cubestart = 1.28f * size;
            float cubeend   = 1.33f * size;
            float cubesize  = 0.025f * size;

            //draw lines...
            Vertices.Clear();

            for (int i = 0; i < 3; i++)
            {
                WidgetAxis sa    = (WidgetAxis)(1 << i);
                bool       axsel = ((selax & sa) > 0);
                Color4     axcol = axsel ? selaxcol : colours[i];

                WidgetAxis triaxn  = sideax1[i];
                bool       trisel  = axsel && ((selax & triaxn) > 0);
                Color4     tricol  = trisel ? selaxcol : colours[i];
                Color4     trincol = trisel ? selaxcol : coloursn[i];

                Vector3 inner1 = axes[i] * innertri;
                Vector3 inner2 = sides1[i] * innertri;
                Vector3 innera = (inner1 + inner2) * 0.5f;
                Vector3 outer1 = axes[i] * outertri;
                Vector3 outer2 = sides1[i] * outertri;
                Vector3 outera = (outer1 + outer2) * 0.5f;

                //triangle axis lines
                Vertices.Add(new WidgetShaderVertex(inner1, tricol));
                Vertices.Add(new WidgetShaderVertex(innera, tricol));
                Vertices.Add(new WidgetShaderVertex(innera, trincol));
                Vertices.Add(new WidgetShaderVertex(inner2, trincol));
                Vertices.Add(new WidgetShaderVertex(outer1, tricol));
                Vertices.Add(new WidgetShaderVertex(outera, tricol));
                Vertices.Add(new WidgetShaderVertex(outera, trincol));
                Vertices.Add(new WidgetShaderVertex(outer2, trincol));

                //main axis lines - draw after side lines to be on top
                Vertices.Add(new WidgetShaderVertex(axes[i] * linestart, axcol));
                Vertices.Add(new WidgetShaderVertex(axes[i] * lineend, axcol));
            }

            Vertices.Update(context);
            Vertices.SetVSResource(context, 0);


            context.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.LineList;
            context.Draw(Vertices.CurrentCount, 0);



            //draw triangles...
            Vertices.Clear();

            for (int i = 0; i < 3; i++)
            {
                //axis end cubes - kind of inefficient, but meh
                Vector3 cend   = axes[i] * cubeend;
                Vector3 cstart = axes[i] * cubestart;
                Vector3 cside1 = sides1[i] * cubesize;
                Vector3 cside2 = sides2[i] * cubesize;
                Vector3 cv1    = cstart + cside1 - cside2;
                Vector3 cv2    = cstart - cside1 - cside2;
                Vector3 cv3    = cend + cside1 - cside2;
                Vector3 cv4    = cend - cside1 - cside2;
                Vector3 cv5    = cstart + cside1 + cside2;
                Vector3 cv6    = cstart - cside1 + cside2;
                Vector3 cv7    = cend + cside1 + cside2;
                Vector3 cv8    = cend - cside1 + cside2;
                Color4  col    = colours[i];
                Color4  cold   = coloursdark[i];
                Vertices.Add(new WidgetShaderVertex(cv1, cold));
                Vertices.Add(new WidgetShaderVertex(cv2, cold));
                Vertices.Add(new WidgetShaderVertex(cv5, cold));
                Vertices.Add(new WidgetShaderVertex(cv5, cold));
                Vertices.Add(new WidgetShaderVertex(cv2, cold));
                Vertices.Add(new WidgetShaderVertex(cv6, cold));
                Vertices.Add(new WidgetShaderVertex(cv3, col));
                Vertices.Add(new WidgetShaderVertex(cv4, col));
                Vertices.Add(new WidgetShaderVertex(cv7, col));
                Vertices.Add(new WidgetShaderVertex(cv7, col));
                Vertices.Add(new WidgetShaderVertex(cv4, col));
                Vertices.Add(new WidgetShaderVertex(cv8, col));
                Vertices.Add(new WidgetShaderVertex(cv1, col));
                Vertices.Add(new WidgetShaderVertex(cv2, col));
                Vertices.Add(new WidgetShaderVertex(cv3, col));
                Vertices.Add(new WidgetShaderVertex(cv3, col));
                Vertices.Add(new WidgetShaderVertex(cv2, col));
                Vertices.Add(new WidgetShaderVertex(cv4, col));
                Vertices.Add(new WidgetShaderVertex(cv5, col));
                Vertices.Add(new WidgetShaderVertex(cv6, col));
                Vertices.Add(new WidgetShaderVertex(cv7, col));
                Vertices.Add(new WidgetShaderVertex(cv7, col));
                Vertices.Add(new WidgetShaderVertex(cv6, col));
                Vertices.Add(new WidgetShaderVertex(cv8, col));
                Vertices.Add(new WidgetShaderVertex(cv1, col));
                Vertices.Add(new WidgetShaderVertex(cv5, col));
                Vertices.Add(new WidgetShaderVertex(cv3, col));
                Vertices.Add(new WidgetShaderVertex(cv3, col));
                Vertices.Add(new WidgetShaderVertex(cv5, col));
                Vertices.Add(new WidgetShaderVertex(cv7, col));
                Vertices.Add(new WidgetShaderVertex(cv2, col));
                Vertices.Add(new WidgetShaderVertex(cv6, col));
                Vertices.Add(new WidgetShaderVertex(cv4, col));
                Vertices.Add(new WidgetShaderVertex(cv4, col));
                Vertices.Add(new WidgetShaderVertex(cv6, col));
                Vertices.Add(new WidgetShaderVertex(cv8, col));


                //selection triangles
                if (selax == WidgetAxis.XYZ)
                {
                    //all axes - just draw inner triangle
                    Vertices.Add(new WidgetShaderVertex(Vector3.Zero, selplcol));
                    Vertices.Add(new WidgetShaderVertex(axes[i] * innertri, selplcol));
                    Vertices.Add(new WidgetShaderVertex(sides1[i] * innertri, selplcol));
                }
                else
                {
                    WidgetAxis sa = (WidgetAxis)(1 << i);
                    WidgetAxis na = sideax1[i];
                    if (((selax & sa) > 0) && ((selax & na) > 0))
                    {
                        Vertices.Add(new WidgetShaderVertex(axes[i] * innertri, selplcol));
                        Vertices.Add(new WidgetShaderVertex(sides1[i] * innertri, selplcol));
                        Vertices.Add(new WidgetShaderVertex(axes[i] * outertri, selplcol));
                        Vertices.Add(new WidgetShaderVertex(axes[i] * outertri, selplcol));
                        Vertices.Add(new WidgetShaderVertex(sides1[i] * innertri, selplcol));
                        Vertices.Add(new WidgetShaderVertex(sides1[i] * outertri, selplcol));
                    }
                }
            }

            Vertices.Update(context);
            Vertices.SetVSResource(context, 0);

            context.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.TriangleList;
            context.Draw(Vertices.CurrentCount, 0);



            UnbindResources(context);
        }
Exemplo n.º 9
0
        public void DrawRotationWidget(DeviceContext context, Camera cam, Vector3 camrel, Quaternion ori, float size, WidgetAxis selax, WidgetAxis drawax)
        {
            SetShader(context);
            SetInputLayout(context, VertexType.Default);


            SceneVars.Vars.Mode   = 0; //vertices mode
            SceneVars.Vars.CamRel = camrel;
            SetSceneVars(context, cam, null, null);

            Vector3 xdir    = ori.Multiply(Vector3.UnitX);
            Vector3 ydir    = ori.Multiply(Vector3.UnitY);
            Vector3 zdir    = ori.Multiply(Vector3.UnitZ);
            Color4  xcolour = new Color4(1.0f, 0.0f, 0.0f, 1.0f);
            Color4  ycolour = new Color4(0.0f, 1.0f, 0.0f, 1.0f);
            Color4  zcolour = new Color4(0.0f, 0.0f, 1.0f, 1.0f);
            Color4  icolour = new Color4(0.5f, 0.5f, 0.5f, 1.0f);
            Color4  ocolour = new Color4(0.7f, 0.7f, 0.7f, 1.0f);
            Color4  scolour = new Color4(1.0f, 1.0f, 0.0f, 1.0f);

            Vector3[] axes    = { xdir, ydir, zdir };
            Vector3[] sides   = { ydir, xdir, xdir };
            Color4[]  colours = { xcolour, ycolour, zcolour };

            float linestart = 0.0f * size;
            float lineend   = 0.3f * size;
            float ocircsize = 1.0f * size;
            float icircsize = 0.75f * size;

            //draw lines...
            Vertices.Clear();

            for (int i = 0; i < 3; i++)
            {
                WidgetAxis sa    = (WidgetAxis)(1 << i);
                bool       axsel = ((selax & sa) > 0);
                Color4     axcol = axsel ? colours[i] : icolour;

                //main axis lines
                Vertices.Add(new WidgetShaderVertex(axes[i] * linestart, axcol));
                Vertices.Add(new WidgetShaderVertex(axes[i] * lineend, axcol));
            }

            Vertices.Update(context);
            Vertices.SetVSResource(context, 0);

            context.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.LineList;
            context.Draw(Vertices.CurrentCount, 0);



            //linestrip for arcs and circles
            context.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.LineStrip;

            Vector3 sdir = Vector3.Normalize(camrel);
            //if (cam.IsMapView || cam.IsOrthographic)
            //{
            //    sdir = cam.ViewDirection;
            //}
            float   ad1 = Math.Abs(Vector3.Dot(sdir, Vector3.UnitY));
            float   ad2 = Math.Abs(Vector3.Dot(sdir, Vector3.UnitZ));
            Vector3 ax1 = Vector3.Normalize(Vector3.Cross(sdir, (ad1 > ad2) ? Vector3.UnitY : Vector3.UnitZ));
            Vector3 ax2 = Vector3.Normalize(Vector3.Cross(sdir, ax1));

            //drawing circles
            int segcount  = 40;
            int vertcount = segcount + 1;

            SceneVars.Vars.Mode      = 1;                                  //arc mode
            SceneVars.Vars.SegScale  = ((float)Math.PI) * 2.0f / segcount; //arc angle / number of segments
            SceneVars.Vars.SegOffset = 0.0f;                               //angle offset of arc
            SceneVars.Vars.Axis1     = ax1;                                //axis 1 of arc
            SceneVars.Vars.Axis2     = ax2;                                //axis 2 of arc
            SceneVars.Vars.CullBack  = 0;                                  //culls pixels behind 0,0,0

            //outer circle
            if (drawax == WidgetAxis.XYZ)
            {
                SceneVars.Vars.Size   = ocircsize;                                     //world units
                SceneVars.Vars.Colour = (selax == WidgetAxis.XYZ) ? scolour : ocolour; //colour for arc
                SetSceneVars(context, cam, null, null);
                context.Draw(vertcount, 0);
            }

            //inner circle
            SceneVars.Vars.Size   = icircsize; //world units
            SceneVars.Vars.Colour = icolour;   //colour for arc
            SetSceneVars(context, cam, null, null);
            context.Draw(vertcount, 0);


            //drawing arcs - culling done in PS
            SceneVars.Vars.Size     = icircsize; //world units
            SceneVars.Vars.CullBack = 1;         //culls pixels behind 0,0,0

            if ((drawax & WidgetAxis.X) != 0)
            {
                SceneVars.Vars.SegOffset = 0.0f;                                        //angle offset of arc
                SceneVars.Vars.Axis1     = ydir;                                        //axis 1 of arc
                SceneVars.Vars.Axis2     = zdir;                                        //axis 2 of arc
                SceneVars.Vars.Colour    = (selax == WidgetAxis.X) ? scolour : xcolour; //colour for arc
                SetSceneVars(context, cam, null, null);
                context.Draw(vertcount, 0);
            }

            if ((drawax & WidgetAxis.Y) != 0)
            {
                SceneVars.Vars.SegOffset = 0.0f;                                        //angle offset of arc
                SceneVars.Vars.Axis1     = xdir;                                        //axis 1 of arc
                SceneVars.Vars.Axis2     = zdir;                                        //axis 2 of arc
                SceneVars.Vars.Colour    = (selax == WidgetAxis.Y) ? scolour : ycolour; //colour for arc
                SetSceneVars(context, cam, null, null);
                context.Draw(vertcount, 0);
            }

            if ((drawax & WidgetAxis.Z) != 0)
            {
                SceneVars.Vars.SegOffset = 0.0f;                                        //angle offset of arc
                SceneVars.Vars.Axis1     = xdir;                                        //axis 1 of arc
                SceneVars.Vars.Axis2     = ydir;                                        //axis 2 of arc
                SceneVars.Vars.Colour    = (selax == WidgetAxis.Z) ? scolour : zcolour; //colour for arc
                SetSceneVars(context, cam, null, null);
                context.Draw(vertcount, 0);
            }



            UnbindResources(context);
        }
Exemplo n.º 10
0
        public void DrawPositionWidget(DeviceContext context, Camera cam, Vector3 camrel, Quaternion ori, float size, WidgetAxis selax)
        {
            SetShader(context);
            SetInputLayout(context, VertexType.Default);

            SceneVars.Vars.Mode   = 0; //vertices mode
            SceneVars.Vars.CamRel = camrel;
            SetSceneVars(context, cam, null, null);

            Vector3 xdir     = ori.Multiply(Vector3.UnitX);
            Vector3 ydir     = ori.Multiply(Vector3.UnitY);
            Vector3 zdir     = ori.Multiply(Vector3.UnitZ);
            Color4  xcolour  = new Color4(1.0f, 0.0f, 0.0f, 1.0f);
            Color4  ycolour  = new Color4(0.0f, 1.0f, 0.0f, 1.0f);
            Color4  zcolour  = new Color4(0.0f, 0.0f, 1.0f, 1.0f);
            Color4  selaxcol = new Color4(1.0f, 1.0f, 0.0f, 1.0f);
            Color4  selplcol = new Color4(1.0f, 1.0f, 0.0f, 0.5f);

            Vector3[]    axes        = { xdir, ydir, zdir };
            Vector3[]    sides1      = { ydir, zdir, xdir };
            Vector3[]    sides2      = { zdir, xdir, ydir };
            WidgetAxis[] sideax1     = { WidgetAxis.Y, WidgetAxis.Z, WidgetAxis.X };
            WidgetAxis[] sideax2     = { WidgetAxis.Z, WidgetAxis.X, WidgetAxis.Y };
            Color4[]     colours     = { xcolour, ycolour, zcolour };
            Color4[]     coloursdark = { xcolour * 0.5f, ycolour * 0.5f, zcolour * 0.5f };
            for (int i = 0; i < 3; i++)
            {
                coloursdark[i].Alpha = 1.0f;
            }

            float linestart  = 0.2f * size;
            float lineend    = 1.0f * size;
            float sideval    = 0.4f * size;
            float arrowstart = 1.0f * size;
            float arrowend   = 1.33f * size;
            float arrowrad   = 0.06f * size;

            float hexx = 0.5f;
            float hexy = 0.86602540378443864676372317075294f; //sqrt(0.75)

            Vector2[] arrowv =
            {
                new Vector2(-1,        0) * arrowrad,
                new Vector2(-hexx, hexy) * arrowrad,
                new Vector2(hexx,  hexy) * arrowrad,
                new Vector2(1,         0) * arrowrad,
                new Vector2(hexx,  -hexy) * arrowrad,
                new Vector2(-hexx, -hexy) * arrowrad,
                new Vector2(-1, 0) * arrowrad
            };



            //draw lines...
            Vertices.Clear();

            for (int i = 0; i < 3; i++)
            {
                WidgetAxis sa    = (WidgetAxis)(1 << i);
                bool       axsel = ((selax & sa) > 0);
                Color4     axcol = axsel ? selaxcol : colours[i];

                //axis side square lines
                Vector3 ax  = axes[i] * sideval;
                Vector3 s1  = sides1[i] * sideval;
                Vector3 s2  = sides2[i] * sideval;
                Color4  sc1 = (axsel && ((selax & sideax1[i]) > 0)) ? selaxcol : colours[i];
                Color4  sc2 = (axsel && ((selax & sideax2[i]) > 0)) ? selaxcol : colours[i];
                Vertices.Add(new WidgetShaderVertex(ax, sc1));
                Vertices.Add(new WidgetShaderVertex(ax + s1, sc1));
                Vertices.Add(new WidgetShaderVertex(ax, sc2));
                Vertices.Add(new WidgetShaderVertex(ax + s2, sc2));

                //main axis lines - draw after side lines to be on top
                Vertices.Add(new WidgetShaderVertex(axes[i] * linestart, axcol));
                Vertices.Add(new WidgetShaderVertex(axes[i] * lineend, axcol));
            }

            Vertices.Update(context);
            Vertices.SetVSResource(context, 0);

            context.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.LineList;
            context.Draw(Vertices.CurrentCount, 0);



            //draw triangles...
            Vertices.Clear();

            for (int i = 0; i < 3; i++)
            {
                //axis arrows - kind of inefficient, but meh
                Vector3 aend   = axes[i] * arrowend;
                Vector3 astart = axes[i] * arrowstart;
                for (int n = 0; n < 6; n++)
                {
                    Vector2 a1  = arrowv[n];
                    Vector2 a2  = arrowv[n + 1];
                    Vector3 ap1 = astart + sides1[i] * a1.Y + sides2[i] * a1.X;
                    Vector3 ap2 = astart + sides1[i] * a2.Y + sides2[i] * a2.X;
                    Vertices.Add(new WidgetShaderVertex(aend, colours[i]));
                    Vertices.Add(new WidgetShaderVertex(ap1, colours[i]));
                    Vertices.Add(new WidgetShaderVertex(ap2, colours[i]));
                    Vertices.Add(new WidgetShaderVertex(astart, coloursdark[i]));
                    Vertices.Add(new WidgetShaderVertex(ap2, coloursdark[i]));
                    Vertices.Add(new WidgetShaderVertex(ap1, coloursdark[i]));
                }

                //selection planes
                WidgetAxis sa = (WidgetAxis)(1 << i);
                if (((selax & sa) > 0))
                {
                    Vector3 ax = axes[i] * sideval;
                    for (int n = i + 1; n < 3; n++)
                    {
                        WidgetAxis tsa = (WidgetAxis)(1 << n);
                        if (((selax & tsa) > 0))
                        {
                            Vector3 tax = axes[n] * sideval;
                            Vertices.Add(new WidgetShaderVertex(Vector3.Zero, selplcol));
                            Vertices.Add(new WidgetShaderVertex(ax, selplcol));
                            Vertices.Add(new WidgetShaderVertex(tax, selplcol));
                            Vertices.Add(new WidgetShaderVertex(tax + ax, selplcol));
                            Vertices.Add(new WidgetShaderVertex(tax, selplcol));
                            Vertices.Add(new WidgetShaderVertex(ax, selplcol));
                        }
                    }
                }
            }

            Vertices.Update(context);
            Vertices.SetVSResource(context, 0);

            context.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.TriangleList;
            context.Draw(Vertices.CurrentCount, 0);

            UnbindResources(context);
        }