示例#1
0
        public void HighlightStuff(MouseEventArgs e)
        {
            ModelPanel.Cursor = Cursors.Default;
            float depth = ModelPanel.GetDepth(e.X, e.Y);

            _hiX = _hiY = _hiZ = _hiCirc = _hiSphere = false;

            MDL0BoneNode bone = SelectedBone;
            //Vertex3 vertex = TargetVertex;
            MDL0ObjectNode poly = leftPanel.SelectedPolygon;

            if (bone != null)
            {
                //Get the location of the bone
                Vector3 center = BoneLoc;

                //Standard radius scaling snippet. This is used for orb scaling depending on camera distance.
                float radius = center.TrueDistance(ModelPanel._camera.GetPoint()) / _orbRadius * 0.1f;

                if (_editType == TransformType.Rotation)
                {
                    //Get point projected onto our orb.
                    Vector3 point = ModelPanel.ProjectCameraSphere(new Vector2(e.X, e.Y), center, radius, false);

                    //Get the distance of the mouse point from the bone
                    float distance = point.TrueDistance(center);

                    if (Math.Abs(distance - radius) < (radius * _selectOrbScale)) //Point lies within orb radius
                    {
                        _hiSphere = true;

                        //Determine axis snapping
                        Vector3 angles = (bone._inverseFrameMatrix * point).GetAngles() * Maths._rad2degf;
                        angles._x = (float)Math.Abs(angles._x);
                        angles._y = (float)Math.Abs(angles._y);
                        angles._z = (float)Math.Abs(angles._z);

                        if (Math.Abs(angles._y - 90.0f) <= _axisSnapRange)
                        {
                            _hiX = true;
                        }
                        else if (angles._x >= (180 - _axisSnapRange) || angles._x <= _axisSnapRange)
                        {
                            _hiY = true;
                        }
                        else if (angles._y >= (180 - _axisSnapRange) || angles._y <= _axisSnapRange)
                        {
                            _hiZ = true;
                        }
                    }
                    else if (Math.Abs(distance - (radius * _circOrbScale)) < (radius * _selectOrbScale)) //Point lies on circ line
                    {
                        _hiCirc = true;
                    }

                    if (_hiX || _hiY || _hiZ || _hiCirc)
                    {
                        ModelPanel.Cursor = Cursors.Hand;
                    }
                }
                else if (_editType == TransformType.Translation)
                {
                    Vector3 point = ModelPanel.UnProject(e.X, e.Y, depth);
                    Vector3 diff  = (point - center) / radius;

                    float halfDist = _axisHalfLDist;
                    if (diff._x > -_axisSelectRange && diff._x < (_axisLDist + 0.01f) &&
                        diff._y > -_axisSelectRange && diff._y < (_axisLDist + 0.01f) &&
                        diff._z > -_axisSelectRange && diff._z < (_axisLDist + 0.01f))
                    {
                        //Point lies within axes
                        if (diff._x < halfDist && diff._y < halfDist && diff._z < halfDist)
                        {
                            //Point lies inside the double drag areas
                            if (diff._x > _axisSelectRange)
                            {
                                _hiX = true;
                            }
                            if (diff._y > _axisSelectRange)
                            {
                                _hiY = true;
                            }
                            if (diff._z > _axisSelectRange)
                            {
                                _hiZ = true;
                            }

                            ModelPanel.Cursor = Cursors.Hand;
                        }
                        else
                        {
                            //Check if point lies on a specific axis
                            float errorRange = _axisSelectRange;

                            if (diff._x > halfDist && Math.Abs(diff._y) < errorRange && Math.Abs(diff._z) < errorRange)
                            {
                                _hiX = true;
                            }
                            if (diff._y > halfDist && Math.Abs(diff._x) < errorRange && Math.Abs(diff._z) < errorRange)
                            {
                                _hiY = true;
                            }
                            if (diff._z > halfDist && Math.Abs(diff._x) < errorRange && Math.Abs(diff._y) < errorRange)
                            {
                                _hiZ = true;
                            }

                            if (!_hiX && !_hiY && !_hiZ)
                            {
                                goto GetBone;
                            }
                            else
                            {
                                ModelPanel.Cursor = Cursors.Hand;
                            }
                        }
                    }
                    else
                    {
                        goto GetBone;
                    }
                }
                else if (_editType == TransformType.Scale)
                {
                    Vector3 point = ModelPanel.UnProject(e.X, e.Y, depth);
                    Vector3 diff  = (point - center) / radius;

                    if (diff._x > -_axisSelectRange && diff._x < (_axisLDist + 0.01f) &&
                        diff._y > -_axisSelectRange && diff._y < (_axisLDist + 0.01f) &&
                        diff._z > -_axisSelectRange && diff._z < (_axisLDist + 0.01f))
                    {
                        //Point lies within axes

                        //Check if point lies on a specific axis first
                        float errorRange = _axisSelectRange;

                        if (diff._x > errorRange && Math.Abs(diff._y) < errorRange && Math.Abs(diff._z) < errorRange)
                        {
                            _hiX = true;
                        }
                        if (diff._y > errorRange && Math.Abs(diff._x) < errorRange && Math.Abs(diff._z) < errorRange)
                        {
                            _hiY = true;
                        }
                        if (diff._z > errorRange && Math.Abs(diff._x) < errorRange && Math.Abs(diff._y) < errorRange)
                        {
                            _hiZ = true;
                        }

                        if (!_hiX && !_hiY && !_hiZ)
                        {
                            //Determine if the point is in the double or triple drag triangles
                            float halfDist   = _scaleHalf2LDist;
                            float centerDist = _scaleHalf1LDist;
                            if (IsInTriangle(diff, new Vector3(), new Vector3(halfDist, 0, 0), new Vector3(0, halfDist, 0)))
                            {
                                if (IsInTriangle(diff, new Vector3(), new Vector3(centerDist, 0, 0), new Vector3(0, centerDist, 0)))
                                {
                                    _hiX = _hiY = _hiZ = true;
                                }
                                else
                                {
                                    _hiX = _hiY = true;
                                }
                            }
                            else if (IsInTriangle(diff, new Vector3(), new Vector3(halfDist, 0, 0), new Vector3(0, 0, halfDist)))
                            {
                                if (IsInTriangle(diff, new Vector3(), new Vector3(centerDist, 0, 0), new Vector3(0, 0, centerDist)))
                                {
                                    _hiX = _hiY = _hiZ = true;
                                }
                                else
                                {
                                    _hiX = _hiZ = true;
                                }
                            }
                            else if (IsInTriangle(diff, new Vector3(), new Vector3(0, halfDist, 0), new Vector3(0, 0, halfDist)))
                            {
                                if (IsInTriangle(diff, new Vector3(), new Vector3(0, centerDist, 0), new Vector3(0, 0, centerDist)))
                                {
                                    _hiX = _hiY = _hiZ = true;
                                }
                                else
                                {
                                    _hiY = _hiZ = true;
                                }
                            }

                            if (!_hiX && !_hiY && !_hiZ)
                            {
                                goto GetBone;
                            }
                            else
                            {
                                ModelPanel.Cursor = Cursors.Hand;
                            }
                        }
                        else
                        {
                            ModelPanel.Cursor = Cursors.Hand;
                        }
                    }
                    else
                    {
                        goto GetBone;
                    }
                }
            }

            //modelPanel1.Invalidate();

GetBone:

            //Try selecting new bone
            //if (modelPanel._selecting)
            //{

            //}
            //else
            {
                if (!(_scaling || _rotating || _translating) && (depth < 1.0f) && (_targetModel != null) && (_targetModel._boneList != null))
                {
                    MDL0BoneNode o = null;

                    Vector3 point = ModelPanel.UnProject(e.X, e.Y, depth);

                    //Find orb near chosen point
                    if (_editingAll)
                    {
                        foreach (MDL0Node m in _targetModels)
                        {
                            foreach (MDL0BoneNode b in m._boneList)
                            {
                                if (CompareDistanceRecursive(b, point, ref o))
                                {
                                    break;
                                }
                            }
                        }
                    }
                    else
                    {
                        foreach (MDL0BoneNode b in _targetModel._boneList)
                        {
                            if (CompareDistanceRecursive(b, point, ref o))
                            {
                                break;
                            }
                        }
                    }

                    if (_hiBone != null && _hiBone != SelectedBone)
                    {
                        _hiBone._nodeColor = Color.Transparent;
                    }

                    if ((_hiBone = o) != null)
                    {
                        _hiBone._nodeColor = Color.FromArgb(255, 128, 0);
                        ModelPanel.Cursor  = Cursors.Hand;
                    }
                }
                else if (_hiBone != null)
                {
                    if (_hiBone != SelectedBone)
                    {
                        _hiBone._nodeColor = Color.Transparent;
                    }
                    _hiBone = null;
                }
            }

            if (VertexLoc != null && RenderVertices)
            {
                //Get the location of the vertex
                Vector3 center = ((Vector3)VertexLoc);

                //Standard radius scaling snippet. This is used for orb scaling depending on camera distance.
                float radius = center.TrueDistance(ModelPanel._camera.GetPoint()) / _orbRadius * 0.1f;

                //if (_editType == TransformType.Rotation)
                //{
                //    //Get point projected onto our orb.
                //    Vector3 point = ModelPanel.ProjectCameraSphere(new Vector2(e.X, e.Y), center, radius, false);

                //    //Get the distance of the mouse point from the bone
                //    float distance = point.TrueDistance(center);

                //    if (Math.Abs(distance - radius) < (radius * _selectOrbScale)) //Point lies within orb radius
                //    {
                //        _hiSphere = true;

                //        //Determine axis snapping
                //        Vector3 angles = center.LookatAngles(point) * Maths._rad2degf;
                //        angles._x = (float)Math.Abs(angles._x);
                //        angles._y = (float)Math.Abs(angles._y);
                //        angles._z = (float)Math.Abs(angles._z);

                //        if (Math.Abs(angles._y - 90.0f) <= _axisSnapRange)
                //            _hiZ = true;
                //        else if (angles._x >= (180 - _axisSnapRange) || angles._x <= _axisSnapRange)
                //            _hiY = true;
                //        else if (angles._y >= (180 - _axisSnapRange) || angles._y <= _axisSnapRange)
                //            _hiX = true;
                //    }
                //    else if (Math.Abs(distance - (radius * _circOrbScale)) < (radius * _selectOrbScale)) //Point lies on circ line
                //        _hiCirc = true;

                //    if (_hiX || _hiY || _hiZ || _hiCirc)
                //        ModelPanel.Cursor = Cursors.Hand;
                //}
                //else if (_editType == TransformType.Translation)
                //{
                Vector3 point = ModelPanel.UnProject(e.X, e.Y, depth);
                Vector3 diff  = (point - center) / radius;

                float halfDist = _axisHalfLDist;
                if (diff._x > -_axisSelectRange && diff._x < (_axisLDist + 0.01f) &&
                    diff._y > -_axisSelectRange && diff._y < (_axisLDist + 0.01f) &&
                    diff._z > -_axisSelectRange && diff._z < (_axisLDist + 0.01f))
                {
                    //Point lies within axes
                    if (diff._x < halfDist && diff._y < halfDist && diff._z < halfDist)
                    {
                        //Point lies inside the double drag areas
                        if (diff._x > _axisSelectRange)
                        {
                            _hiX = true;
                        }
                        if (diff._y > _axisSelectRange)
                        {
                            _hiY = true;
                        }
                        if (diff._z > _axisSelectRange)
                        {
                            _hiZ = true;
                        }

                        ModelPanel.Cursor = Cursors.Hand;
                    }
                    else
                    {
                        //Check if point lies on a specific axis
                        float errorRange = _axisSelectRange;

                        if (diff._x > halfDist && Math.Abs(diff._y) < errorRange && Math.Abs(diff._z) < errorRange)
                        {
                            _hiX = true;
                        }
                        if (diff._y > halfDist && Math.Abs(diff._x) < errorRange && Math.Abs(diff._z) < errorRange)
                        {
                            _hiY = true;
                        }
                        if (diff._z > halfDist && Math.Abs(diff._x) < errorRange && Math.Abs(diff._y) < errorRange)
                        {
                            _hiZ = true;
                        }

                        if (!_hiX && !_hiY && !_hiZ)
                        {
                            goto GetVertex;
                        }
                        else
                        {
                            ModelPanel.Cursor = Cursors.Hand;
                        }
                    }
                }
                //}
            }

GetVertex:

            //Try targeting a vertex
            if (RenderVertices)
            {
                if (ModelPanel._selecting)
                {
                    if (NotCtrlAlt)
                    {
                        ResetVertexColors();
                    }

                    if (TargetModel._polyIndex == -1)
                    {
                        foreach (MDL0ObjectNode o in TargetModel._objList)
                        {
                            if (o._render)
                            {
                                SelectVerts(o);
                            }
                        }
                    }
                    else
                    {
                        MDL0ObjectNode w = (MDL0ObjectNode)TargetModel._objList[TargetModel._polyIndex];
                        if (w._render)
                        {
                            SelectVerts(w);
                        }
                        else
                        {
                            foreach (MDL0ObjectNode h in TargetModel._objList)
                            {
                                if (h._render)
                                {
                                    SelectVerts(h);
                                }
                            }
                        }
                    }
                }
                else
                {
                    Vector3 point = ModelPanel.UnProject(e.X, e.Y, depth);
                    if ((depth < 1.0f) && (_targetModel != null) && (_targetModel._objList != null))
                    {
                        Vertex3 v = null;

                        CompareVertexDistance(point, ref v);

                        if (_hiVertex != null && !_hiVertex._selected)
                        {
                            _hiVertex._highlightColor    = Color.Transparent;
                            ModelPanel._forceNoSelection = false;
                        }
                        if ((_hiVertex = v) != null)
                        {
                            _hiVertex._highlightColor    = Color.Orange;
                            ModelPanel.Cursor            = Cursors.Cross;
                            ModelPanel._forceNoSelection = true;
                        }
                    }
                    else if (_hiVertex != null)
                    {
                        if (!_hiVertex._selected)
                        {
                            _hiVertex._highlightColor    = Color.Transparent;
                            ModelPanel._forceNoSelection = false;
                        }
                        _hiVertex = null;
                    }
                }
            }

            ModelPanel.Invalidate();
        }
示例#2
0
        private bool GetVertexOrbPoint(Vector2 mousePoint, Vector3 center, out Vector3 point)
        {
            Vector3 lineStart = ModelPanel.UnProject(mousePoint._x, mousePoint._y, 0.0f);
            Vector3 lineEnd   = ModelPanel.UnProject(mousePoint._x, mousePoint._y, 1.0f);
            Vector3 camera    = ModelPanel._camera.GetPoint();
            Vector3 normal    = new Vector3();
            float   radius    = center.TrueDistance(camera) / _orbRadius * 0.1f;

            switch (_editType)
            {
            case TransformType.Scale:

                break;

            case TransformType.Rotation:
            //if (_snapX)
            //    normal = (new Vector3(1.0f, 0.0f, 0.0f)).Normalize(center);
            //else if (_snapY)
            //    normal = (new Vector3(0.0f, 1.0f, 0.0f)).Normalize(center);
            //else if (_snapZ)
            //    normal = (new Vector3(0.0f, 0.0f, 1.0f)).Normalize(center);
            //else if (_snapCirc)
            //{
            //    radius *= _circOrbScale;
            //    normal = camera.Normalize(center);
            //}
            //else if (Maths.LineSphereIntersect(lineStart, lineEnd, center, radius, out point))
            //    return true;
            //else
            //    normal = camera.Normalize(center);

            //if (Maths.LinePlaneIntersect(lineStart, lineEnd, center, normal, out point))
            //{
            //    point = Maths.PointAtLineDistance(center, point, radius);
            //    return true;
            //}

            //break;

            case TransformType.Translation:

                if (_snapX && _snapY)
                {
                    normal = new Vector3(0.0f, 0.0f, 1.0f);
                }
                else if (_snapX && _snapZ)
                {
                    normal = new Vector3(0.0f, 1.0f, 0.0f);
                }
                else if (_snapY && _snapZ)
                {
                    normal = new Vector3(1.0f, 0.0f, 0.0f);
                }
                else if (_snapX)
                {
                    normal = new Vector3(0.0f, 1.0f, 0.0f);
                }
                else if (_snapY)
                {
                    normal = new Vector3(1.0f, 0.0f, 0.0f);
                }
                else if (_snapZ)
                {
                    normal = new Vector3(0.0f, 1.0f, 0.0f);
                }

                break;
            }

            if (!Maths.LinePlaneIntersect(lineStart, lineEnd, center, normal, out point))
            {
                point = new Vector3();
                return(false);
            }
            return(true);
        }
        private void modelPanel1_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button != Forms.MouseButtons.Left)
            {
                return;
            }

            //Reset snap flags
            _snapX = _snapY = _snapZ = _snapCirc = false;

            MDL0BoneNode bone = pnlAssets.SelectedBone;

            //Re-target selected bone
            if (bone != null)
            {
                //Try to re-target selected node
                Vector3 center = bone._frameMatrix.GetPoint();

                //Standard radius scaling snippet. This is used for orb scaling depending on camera distance.
                float radius = center.TrueDistance(modelPanel1._camera.GetPoint()) / _orbRadius * 0.1f;

                //Get point projected onto our orb.
                Vector3 point = modelPanel1.ProjectCameraSphere(new Vector2(e.X, e.Y), center, radius, false);

                //Check distances
                float distance = point.TrueDistance(center);


                if (Math.Abs(distance - radius) < (radius * _selectOrbScale)) //Point lies within orb radius
                {
                    //Determine axis snapping
                    Vector3 angles = (bone._inverseFrameMatrix * point).GetAngles() * Maths._rad2degf;
                    angles._x = (float)Math.Abs(angles._x);
                    angles._y = (float)Math.Abs(angles._y);
                    angles._z = (float)Math.Abs(angles._z);

                    if (Math.Abs(angles._y - 90.0f) <= _axisSnapRange)
                    {
                        _snapX = true;
                    }
                    else if (angles._x >= (180 - _axisSnapRange) || angles._x <= _axisSnapRange)
                    {
                        _snapY = true;
                    }
                    else if (angles._y >= (180 - _axisSnapRange) || angles._y <= _axisSnapRange)
                    {
                        _snapZ = true;
                    }
                }
                else if (Math.Abs(distance - (radius * _circOrbScale)) < (radius * _selectOrbScale)) //Point lies on circ line
                {
                    _snapCirc = true;
                }
                else
                {
                    //Orb selection missed. Assign bone and move to next step.
                    pnlAssets.SelectedBone = bone = null;
                    goto Next;
                }

                //Bone re-targeted. Get angles and local point (aligned to snapping plane).
                if (GetOrbPoint(new Vector2(e.X, e.Y), out point))
                {
                    _rotating  = true;
                    _oldAngles = bone._frameState._rotate;
                    _lastPoint = bone._inverseFrameMatrix * point;
                }

                //Ensure a redraw so the snapping indicators are correct
                modelPanel1.Invalidate();
            }

Next:

            //Try selecting new bone
            if (bone == null)
            {
                float depth = modelPanel1.GetDepth(e.X, e.Y);
                if ((depth < 1.0f) && (_targetModel != null) && (_targetModel._boneList != null))
                {
                    Vector3 point = modelPanel1.UnProject(e.X, e.Y, depth);

                    //Find orb near chosen point
                    foreach (MDL0BoneNode b in _targetModel._boneList)
                    {
                        if (CompareDistanceRecursive(b, point, ref bone))
                        {
                            break;
                        }
                    }

                    //Assign new bone
                    if (bone != null)
                    {
                        pnlAssets.SelectedBone = bone;
                    }

                    //No need to redraw.
                }
            }
        }
示例#4
0
        /// <summary>
        /// Gets world-point of specified mouse point projected onto the selected bone's local space if rotating or in world space if translating or scaling.
        /// Intersects the projected ray with the appropriate plane using the snap flags.
        /// </summary>
        public bool GetOrbPoint(Vector2 mousePoint, out Vector3 point)
        {
            MDL0BoneNode bone = SelectedBone;

            if (bone == null)
            {
                point = new Vector3();
                return(false);
            }

            Vector3 lineStart = ModelPanel.UnProject(mousePoint._x, mousePoint._y, 0.0f);
            Vector3 lineEnd   = ModelPanel.UnProject(mousePoint._x, mousePoint._y, 1.0f);
            Vector3 center    = bone._frameMatrix.GetPoint();
            Vector3 camera    = ModelPanel._camera.GetPoint();
            Vector3 normal    = new Vector3();
            float   radius    = center.TrueDistance(camera) / _orbRadius * 0.1f;

            switch (_editType)
            {
            case TransformType.Rotation:

                if (_snapX)
                {
                    normal = (bone._frameMatrix * new Vector3(1.0f, 0.0f, 0.0f)).Normalize(center);
                }
                else if (_snapY)
                {
                    normal = (bone._frameMatrix * new Vector3(0.0f, 1.0f, 0.0f)).Normalize(center);
                }
                else if (_snapZ)
                {
                    normal = (bone._frameMatrix * new Vector3(0.0f, 0.0f, 1.0f)).Normalize(center);
                }
                else if (_snapCirc)
                {
                    radius *= _circOrbScale;
                    normal  = camera.Normalize(center);
                }
                else if (Maths.LineSphereIntersect(lineStart, lineEnd, center, radius, out point))
                {
                    return(true);
                }
                else
                {
                    normal = camera.Normalize(center);
                }

                if (Maths.LinePlaneIntersect(lineStart, lineEnd, center, normal, out point))
                {
                    point = Maths.PointAtLineDistance(center, point, radius);
                    return(true);
                }

                break;

            case TransformType.Translation:
            case TransformType.Scale:

                if (_snapX && _snapY)
                {
                    normal = new Vector3(0.0f, 0.0f, 1.0f);
                }
                else if (_snapX && _snapZ)
                {
                    normal = new Vector3(0.0f, 1.0f, 0.0f);
                }
                else if (_snapY && _snapZ)
                {
                    normal = new Vector3(1.0f, 0.0f, 0.0f);
                }
                else if (_snapX)
                {
                    normal = new Vector3(0.0f, 1.0f, 0.0f);
                }
                else if (_snapY)
                {
                    normal = new Vector3(1.0f, 0.0f, 0.0f);
                }
                else if (_snapZ)
                {
                    normal = new Vector3(0.0f, 1.0f, 0.0f);
                }
                else if (_editType == TransformType.Scale && _snapX && _snapY && _snapZ)
                {
                    normal = camera.Normalize(center);
                }

                break;
            }

            return(Maths.LinePlaneIntersect(lineStart, lineEnd, center, normal, out point));
        }