Exemple #1
0
        /// <summary>
        /// For now this is the editing mode for the currently selected support
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void glControl1_Click(object sender, EventArgs e)
        {
            // single click on GL Control
            Object3d obj = UVDLPApp.Instance().SelectedObject;

            if (obj == null)
            {
                return;
            }
            if (ctrldown == false)
            {
                return;                    // ctrl need to be held down
            }
            // this object is a support
            if (obj.tag == Object3d.OBJ_SUPPORT)
            {
                Support sup = (Support)obj;// we can cast safely
                // now we have to see if we clicked on an object
                MouseEventArgs   me           = e as MouseEventArgs;
                MouseButtons     buttonPushed = me.Button;
                int              xPos         = me.X;
                int              yPos         = me.Y;
                List <ISectData> isects       = TestHitTest(xPos, yPos);
                if (isects.Count == 0)
                {
                    return;                    // no intersections
                }
                ISectData isd1 = null;
                foreach (ISectData isd in isects)
                {
                    // find the closest object we clicked
                    if (isd.obj.tag == Object3d.OBJ_NORMAL)
                    {
                        isd1 = isd; //  save it
                        break;
                    }
                }
                if (isd1 == null)
                {
                    return;               // no object intersection
                }
                isd1.poly.CalcNormal();
                m_isectnormal.x = isd1.poly.m_normal.x;
                m_isectnormal.y = isd1.poly.m_normal.y;
                m_isectnormal.z = isd1.poly.m_normal.z;
                // ok, we've got the normal, we know where we've intersected
                // my best guess is that we should move the support 5mm in the direction of the camera
                // the tip of the support should touch the intersection point
                // let's start with scaling the height...
                //sup.ScaleToHeight(isd1.intersect.z);
                //m_camera.m_eye
                Engine3D.Vector3d towardseye = new Engine3D.Vector3d();
                towardseye = m_isectnormal; // -m_camera.m_eye;
                towardseye.Normalize();     // make the unit length of 1
                towardseye.Scale(4.0f);     // scale to 5 mm
                sup.MoveFromTip(isd1.intersect, towardseye);
                UpdateView();
                //sup.
            }
        }
Exemple #2
0
 public void RotateRight(float deg)
 {
     Rotate(m_up, deg);
     // update target and up
     m_target = m_lookat - m_eye;    // The "look-at" unit vector.
     m_target.Normalize();
     m_right = Vector3d.cross(m_target, m_up);
     UpdateView();
 }
        public static List<ISectData> IntersectObjects(Vector3d direction, Point3d origin, List<Object3d> objects, bool supports)
        {
            //List<ISectData> m_isectlst = new List<ISectData>();

            try
            {
                if (!vecinit)
                {
                    Initvecs();
                }
                m_isectlst.Clear();
                direction.Normalize();
                direction.Scale(10000.0f);

                IOendp.Set(origin);
                IOendp.x += direction.x;
                IOendp.y += direction.y;
                IOendp.z += direction.z;
                lock (lck)
                {
                    foreach (Object3d obj in objects)
                    {
                        if (obj.tag == Object3d.OBJ_SUPPORT && !supports)
                            continue;
                        // try a less- costly sphere intersect here
                        if (IntersectSphere(origin, IOendp, ref IOintersect, obj.m_center, obj.m_radius))
                        {
                            foreach (Polygon p in obj.m_lstpolys)
                            {
                                //IOintersect = new Point3d();
                                // try a less- costly sphere intersect here
                                if (IntersectSphere(origin, IOendp, ref IOintersect, p.m_center, p.m_radius))
                                {
                                    // if it intersects,
                                    if (RTUtils.IntersectPoly(p, origin, IOendp, ref IOintersect))
                                    {
                                        m_isectlst.Add(new ISectData(obj, p, IOintersect, origin, direction));
                                    }
                                }
                            }
                        }
                    }
                }
                ISectData gp = ISectGroundPlane(direction, origin);
                if (gp != null)
                {
                    m_isectlst.Add(gp);
                }
                m_isectlst.Sort();
            }
            catch (Exception ex)
            {
                DebugLogger.Instance().LogError(ex.Message);
            }
            return m_isectlst;
        }
        // calc a split point normal from 2 edge normal and center tanget
        Vector3d CalcCenterNormal(Vector3d norm1, Vector3d norm2, Vector3d tanget)
        {
            Vector3d tvec = (norm1 * 0.5f) + (norm2 * 0.5f);

            tvec = Vector3d.cross(tvec, tanget);
            Vector3d res = Vector3d.cross(tanget, tvec);

            res.Normalize();
            return(res);
        }
Exemple #5
0
        public void MoveFromTip(ISectData dat)
        {
            Point3d center;

            center = Centroid(); // get the centroid of the selected portion of the object
            Vector3d isectnorm = new Vector3d();

            //save the polygon intersection normal
            isectnorm.x = dat.poly.m_normal.x;
            isectnorm.y = dat.poly.m_normal.y;
            isectnorm.z = dat.poly.m_normal.z;

            MinMax mm   = CalcMinMaxRange(s4i, m_lstpoints.Count);
            float  dist = (float)((mm.m_max - mm.m_min));

            ResetTip();
            Matrix3D tMat = new Matrix3D();
            Vector3d vup  = new Vector3d(0, 1, 0);

            //always make sure the z is heading downward
            if (isectnorm.z > 0)
            {
                isectnorm.z *= -1.0f;
            }
            // limit the z down to 45 degrees
            if (isectnorm.z > -.75)
            {
                isectnorm.z = -.75f;
            }
            //reverse the direction to get the reflection
            Vector3d dir = new Vector3d(-isectnorm.x, -isectnorm.y, -isectnorm.z);

            dir.Normalize();
            //create a matrix transform
            tMat.LookAt(dir, vup);
            Transform(tMat);
            Translate(
                (float)(dat.intersect.x),
                (float)(dat.intersect.y),
                (float)(dat.intersect.z));

            //now, get the center of s4i to s5i
            Point3d cnt = CalcCentroid(s4i, s5i);

            //translate to 0
            TranslateRange(-cnt.x, -cnt.y, -cnt.z, s4i, s5i);
            //reset the points,
            ReGenSegmentPoints(mSC.hbrad, mSC.cdivs, s4i, 0, false); // bottom of head
            //move back
            TranslateRange(cnt.x, cnt.y, cnt.z, s4i, s5i);
            Update();

            //
        }
        Vector3d GetTangetFromNormal(Vector3d norm, Vector3d dir)
        {
            Vector3d normxdir = Vector3d.cross(norm, dir);
            Vector3d res      = Vector3d.cross(normxdir, norm);

            if ((Math.Abs(res.x) < Epsilon) && (Math.Abs(res.y) < Epsilon) && (Math.Abs(res.z) < Epsilon))
            {
                res = dir.clone();
            }
            res.Normalize();
            //res = res * dir.Mag();
            return(res);
        }
        Vector3d GetNormalFromTanget(Vector3d norm, Vector3d tanget)
        {
            Vector3d normtang = Vector3d.cross(norm, tanget);
            Vector3d res      = Vector3d.cross(tanget, normtang);

            if ((Math.Abs(res.x) < Epsilon) && (Math.Abs(res.y) < Epsilon) && (Math.Abs(res.z) < Epsilon))
            {
                return(null);
            }
            res.Normalize();
            //res = res * dir.Mag();
            return(res);
        }
        // split edge v1-v2. v3 is the last corner in the triangle and is used for computing normals

/*        int SplitEdge(int v1, int v2, int v3)
 *      {
 *          Vector3d norm1 = CalcNormal(v1, v2, v3);
 *          Vector3d norm2 = CalcNormal(v2, v3, v1);
 *          EdgeAmf edge = m_pointList[v1].FindEdge(v2);
 *          if (edge == null)
 *          {
 *              edge = m_pointList[v2].FindEdge(v1);
 *              if (edge != null)
 *              {
 *                  // swap verteces tomatch edge
 *                  int tv = v1;
 *                  v1 = v2;
 *                  v2 = tv;
 *                  Vector3d tnorm = norm1;
 *                  norm1 = norm2;
 *                  norm2 = tnorm;
 *              }
 *          }
 *
 *          Vector3d t1, t2;
 *          PointAmf pamf1 = m_pointList[v1];
 *          PointAmf pamf2 = m_pointList[v2];
 *          Point3d pt1 = pamf1.pt;
 *          Point3d pt2 = pamf2.pt;
 *          PointAmf pamf;
 *          float x, y, z;
 *
 *          // calculate edge vector
 *          x = pt2.x - pt1.x;
 *          y = pt2.y - pt1.y;
 *          z = pt2.z - pt1.z;
 *          Vector3d edgeDir = new Vector3d(x, y, z);
 *
 *          // first see if we have an edge for this segment
 *          if (edge != null)
 *          {
 *              // if this edge was already split, return result
 *              if (edge.v12 >= 0)
 *                  return edge.v12;
 *              t1 = edge.t1;
 *              t2 = edge.t2;
 *          }
 *          /*else if ((pamf1.normal == null) && (pamf2.normal == null))
 *          {
 *              // its a linear line, return the center
 *              x = (pamf1.pt.x + pamf2.pt.x) / 2.0f;
 *              y = (pamf1.pt.y + pamf2.pt.y) / 2.0f;
 *              z = (pamf1.pt.z + pamf2.pt.z) / 2.0f;
 *              pamf = new PointAmf();
 *              pamf.pt = new Point3d(x, y, z);
 *              m_pointList.Add(pamf);
 *              return m_pointList.Count - 1;
 *          }
 *          else
 *          {
 *              // calculate tangets from normals.
 *              //edgeDir.Normalize();
 *              t1 = GetTangetFromNormal(norm1, edgeDir);
 *              t2 = GetTangetFromNormal(norm2, edgeDir);
 *              /*if (pamf1.normal == null)
 *                  pamf1.normal = norm1;
 *              if (pamf2.normal == null)
 *                  pamf2.normal = norm2;
 *          }
 *
 *          float d = edgeDir.Mag();
 *
 *          // calculate mid point using Hermite interpolation
 *          x = 0.5f * pt1.x + 0.125f * t1.x * d + 0.5f * pt2.x - 0.125f * t2.x * d;
 *          y = 0.5f * pt1.y + 0.125f * t1.y * d + 0.5f * pt2.y - 0.125f * t2.y * d;
 *          z = 0.5f * pt1.z + 0.125f * t1.z * d + 0.5f * pt2.z - 0.125f * t2.z * d;
 *
 *          pamf = new PointAmf();
 *          pamf.pt = new Point3d(x, y, z);
 *          int v = m_pointList.Count;
 *          m_pointList.Add(pamf);
 *
 *          // calculate new tanget and new normal
 *          x = -1.5f * pt1.x - 0.25f * t1.x * d + 1.5f * pt2.x - 0.25f * t2.x * d;
 *          y = -1.5f * pt1.y - 0.25f * t1.y * d + 1.5f * pt2.y - 0.25f * t2.y * d;
 *          z = -1.5f * pt1.z - 0.25f * t1.z * d + 1.5f * pt2.z - 0.25f * t2.z * d;
 *          Vector3d tanget = new Vector3d(x, y, z);
 *          tanget.Normalize();
 *
 *          Vector3d tvec = (norm1 * 0.5f) + (norm2 * 0.5f);
 *          tvec = Vector3d.cross(tvec, tanget);
 *          pamf.normal = Vector3d.cross(tanget, tvec);
 *
 *          if (edge == null)
 *          {
 *              //pamf.normal = GetNormalFromTanget(norm1, tanget);
 *              // create an edge for this segment
 *              edge = new EdgeAmf();
 *              edge.v1 = v1;
 *              edge.v2 = v2;
 *              edge.t1 = t1;
 *              edge.t2 = t2;
 *              pamf1.AddEdge(edge);
 *          }
 *          edge.v12 = m_pointList.Count - 1; // saves double computation
 *
 *          //tanget.Normalize();
 *          // save 2 split edges
 *          EdgeAmf edge1 = new EdgeAmf();
 *          edge1.v1 = v1;
 *          edge1.v2 = v;
 *          edge1.t1 = t1;
 *          edge1.t2 = tanget;
 *          pamf1.AddEdge(edge1);
 *
 *          EdgeAmf edge2 = new EdgeAmf();
 *          edge2.v1 = v;
 *          edge2.v2 = v2;
 *          edge2.t1 = tanget;
 *          edge2.t2 = t2;
 *          pamf.AddEdge(edge2);
 *
 *          return v;
 *      }*/

        // calc normal at corner v (looking at the triangle when corner v is at the bottom, v1 at top right, and v2 is at to left
        Vector3d CalcNormal(int v, int v1, int v2)
        {
            PointAmf pamf = m_pointList[v];

            if (pamf.normal != null)
            {
                return(pamf.normal);
            }
            Vector3d t1     = GetTanget(v, v1);
            Vector3d t2     = GetTanget(v, v2);
            Vector3d normal = Vector3d.cross(t1, t2);

            normal.Normalize();
            return(normal);
        }
Exemple #9
0
        // create a look-at rotation matrix
        public void LookAt(Vector3d dir, Vector3d up)
        {
            //Vector3d dir = new Vector3d(direction.x, direction.y, direction.z);
            //dir.Normalize();
            Vector3d vx = up.Cross(dir);

            vx.Normalize();
            Vector3d vy = dir.Cross(vx);

            vy.Normalize();
            Matrix[0, 0] = vx.x;  Matrix[0, 1] = vx.y;  Matrix[0, 2] = vx.z;  Matrix[0, 3] = 0;
            Matrix[1, 0] = vy.x;  Matrix[1, 1] = vy.y;  Matrix[1, 2] = vy.z;  Matrix[1, 3] = 0;
            Matrix[2, 0] = dir.x; Matrix[2, 1] = dir.y; Matrix[2, 2] = dir.z; Matrix[2, 3] = 0;
            Matrix[3, 0] = 0;     Matrix[3, 1] = 0;     Matrix[3, 2] = 0;     Matrix[3, 3] = 1;
        }
        /*
        public class Config
        {
            int xres, yres;
           // double
        }
         * */
        public static bool FindIntersection(Vector3d direction, Point3d origin, ref Point3d intersect)
        {
            UVDLPApp.Instance().CalcScene();
            //bool intersected = false;

              //  Point3d bpoint, tpoint;
              //  Point3d lowest = new Point3d(); // the lowest point of intersection on the z axis
            direction.Normalize();
            direction.Scale(100.0);
            Point3d endp = new Point3d();
            endp.Set(origin);
            endp.x += direction.x;
            endp.y += direction.y;
            endp.z += direction.z;
            /*
            intersect = new Point3d();
            intersect.x = 0.0d;
            intersect.y = 0.0d;
            intersect.z = 0.0d;
            */
            //intersect the scene with a ray

               // intersected = false;
            foreach (Polygon p in UVDLPApp.Instance().Scene.m_lstpolys)
            {
                intersect = new Point3d();
                // try a less- costly sphere intersect here
                if (RTUtils.IntersectSphere(origin, endp, ref intersect, p.m_center, p.m_radius))
                {
                    // if it intersects,
                    if (RTUtils.IntersectPoly(p, origin, endp, ref intersect))
                    {
                        return true;
                        /*
                        // and it's the lowest one
                        if (intersect.z <= lowest.z)
                        {
                            //save this point
                            intersected = true;
                            lowest.Set(intersect);
                        }
                         * */
                    }
                }
            }

            return false;
        }
Exemple #11
0
        public void ResetView(float x, float y, float z, float updeg, float lookz)
        {
            m_eye    = new Vector3d(x, y, z);
            m_lookat = new Vector3d(0, 0, 0);
            m_up     = new Vector3d(0, 0, 1);
            m_dz     = lookz;
            m_dx     = m_dy = 0;
            //m_right = new Vector3d(1, 0, 0);
            m_target = m_lookat - m_eye;    // The "look-at" unit vector.
            m_target.Normalize();
            m_right = Vector3d.cross(m_target, m_up);
            RotateUp(updeg);
            UpdateView();

            //Vector3d xaxis = Vector3d.cross(up, zaxis);// The "right" vector.
            //xaxis.Normalize();
            //Vector3d yaxis = Vector3d.cross(zaxis, xaxis);     // The "up" vector.
        }
Exemple #12
0
        public void MoveForward(float dist, float factor)
        {
            if (factor < 0.3)
            {
                factor = 0.3f;
            }
            dist = dist * factor;
            Vector3d diff = (m_eye - m_lookat);
            float    len  = Vector3d.length(diff) - dist;

            if ((len <= 0) || (len >= 1000))
            {
                return;
            }
            diff.Normalize();
            diff  = diff * (float)dist;
            m_eye = m_eye - diff;
            UpdateView();
        }
        private static ISectData ISectObjSelPlane(Vector3d direction, Point3d origin)
        {
            ISectData isect = null;
            if (m_selplane == null)
                return null;
            direction.Normalize();
            direction.Scale(10000.0f);

            ObSelendp.Set(origin);
            ObSelendp.x += direction.x;
            ObSelendp.y += direction.y;
            ObSelendp.z += direction.z;
            // intersect with the imaginary object selection plane
            if (IntersectSphere(origin, ObSelendp, ref ObSelintersect, m_selplane.m_center, m_selplane.m_radius))
            {
                foreach (Polygon p in m_selplane.m_lstpolys)
                {
                    // try a less- costly sphere intersect here
                    if (IntersectSphere(origin, ObSelendp, ref ObSelintersect, p.m_center, p.m_radius))
                    {
                        // if it intersects,
                        if (RTUtils.IntersectPoly(p, origin, ObSelendp, ref ObSelintersect))
                        {
                            isect = new ISectData(m_selplane, p, ObSelendp, origin, direction);
                        }
                    }
                }
            }
            return isect;
        }
 public void RotateUp(float deg)
 {
     Rotate(m_right, deg);
     // update target and up
     m_target = m_lookat - m_eye;    // The "look-at" unit vector.
     m_target.Normalize();
     m_up = Vector3d.cross(m_right, m_target);
     UpdateView();
 }
        public void ResetView(float x, float y, float z, float updeg, float lookz)
        {
            m_eye = new Vector3d(x, y, z);
            m_lookat = new Vector3d(0, 0, 0);
            m_up = new Vector3d(0, 0, 1);
            m_dz = lookz;
            m_dx = m_dy = 0;
            //m_right = new Vector3d(1, 0, 0);
            m_target = m_lookat - m_eye;    // The "look-at" unit vector.
            m_target.Normalize();
            m_right = Vector3d.cross(m_target, m_up);
            RotateUp(updeg);
            UpdateView();

            //Vector3d xaxis = Vector3d.cross(up, zaxis);// The "right" vector.
            //xaxis.Normalize();
            //Vector3d yaxis = Vector3d.cross(zaxis, xaxis);     // The "up" vector.
        }
        public void MoveFromTip(ISectData dat)
        {
            Point3d center;
            center = Centroid(); // get the centroid of the selected portion of the object
            Vector3d isectnorm = new Vector3d();
            //save the polygon intersection normal
            isectnorm.x = dat.poly.m_normal.x;
            isectnorm.y = dat.poly.m_normal.y;
            isectnorm.z = dat.poly.m_normal.z;

            MinMax mm = CalcMinMaxRange(s4i, m_lstpoints.Count);
            float dist = (float)((mm.m_max - mm.m_min) );
            ResetTip();
            Matrix3D tMat = new Matrix3D();
            Vector3d vup = new Vector3d(0,1,0);
            //always make sure the z is heading downward
            if (isectnorm.z > 0)
            {
                isectnorm.z *= -1.0f;
            }
            // limit the z down to 45 degrees
            if (isectnorm.z > -.75)
            {
                isectnorm.z = -.75f;
            }
            //reverse the direction to get the reflection
            Vector3d dir = new Vector3d(-isectnorm.x, -isectnorm.y, -isectnorm.z);
            dir.Normalize();
            //create a matrix transform
            tMat.LookAt(dir, vup);
            Transform(tMat);
            Translate(
                (float)(dat.intersect.x),
                (float)(dat.intersect.y),
                (float)(dat.intersect.z));

            //now, get the center of s4i to s5i
            Point3d cnt = CalcCentroid(s4i, s5i);
            //translate to 0
            TranslateRange(-cnt.x, -cnt.y, -cnt.z, s4i, s5i);
            //reset the points,
            ReGenSegmentPoints(mSC.hbrad, mSC.cdivs, s4i, 0, false); // bottom of head
            //move back
            TranslateRange(cnt.x, cnt.y, cnt.z, s4i, s5i);
            Update();

            //
        }
        /// <summary>
        /// This functiuon positions the base at the location 'intersect'
        /// The idir is the direction that was used to intersect
        /// </summary>
        /// <param name="intersect"></param>
        /// <param name="idir"></param>
        /// <param name="inorm"></param>
        public void PositionBottom(ISectData dat)
        {
            // the bottom could be a tip or base
            // need to orient the bottom and position it.
            Point3d center;
            // for a base support, just slide it around
            if (m_subtype == eSubType.eBase)
            {
                center = Centroid(); // get the centroid of the selected portion of the object
                MinMax mm = CalcMinMaxRange(s1i, s4i);
                float dist = (float)((mm.m_max - mm.m_min) / 2);
                Translate(
                    (float)(dat.intersect.x - center.x),
                    (float)(dat.intersect.y - center.y),
                    (float)(dat.intersect.z - center.z + dist));
            }
            else if (m_subtype == eSubType.eIntra)  // bottom tip
            {
                // for a base tip, find the angle and angle it in
                Vector3d isectnorm = new Vector3d();
                //save the polygon intersection normal
                isectnorm.x = dat.poly.m_normal.x;
                isectnorm.y = dat.poly.m_normal.y;
                isectnorm.z = dat.poly.m_normal.z;
                isectnorm.Normalize();

                if (isectnorm.z < 0)
                {
                    isectnorm.z *= -1.0f;
                }
                // limit the z down to 45 degrees
                if (isectnorm.z < .75)
                {
                    isectnorm.z = .75f;
                }

                // re-genrate the points on the bottom of the foot
                ReGenSegmentPoints(mSC.htrad, mSC.cdivs, s1i, 0, true); // bottom of foot is the tip radius
                Matrix3D tMat = new Matrix3D();
                Vector3d vup = new Vector3d(0, 1, 0);
                Vector3d dir = new Vector3d(isectnorm.x, isectnorm.y, isectnorm.z);
                dir.Normalize();

                //direction should be upward at this point.
                //create a matrix transform
                tMat.LookAt(dir, vup);
                //transform the si1-s2i points to look at the vector
                TransformRange(tMat, s1i, s2i);
                //move the range of points to be touching the intersection point
                STranslateRange(dat.intersect.x, dat.intersect.y, dat.intersect.z, s1i, s2i);

                //now, get the center of s4i to s5i
                Point3d cnt = CalcCentroid(s2i, s4i);
                //translate to 0,0,0
                STranslateRange(-cnt.x, -cnt.y, -cnt.z, s2i, s4i);
                //reset the points,
                ReGenSegmentPoints(mSC.hbrad, mSC.cdivs, s2i, 0, false); // top of foot
                ReGenSegmentPoints(mSC.hbrad, mSC.cdivs, s3i, 0, false); // top of foot
                Point3d newp = new Point3d();
                newp.x = dat.intersect.x + (isectnorm.x * 2);
                newp.y = dat.intersect.y + (isectnorm.y * 2);
                newp.z = dat.intersect.z + (isectnorm.z * 2);
                STranslateRange(newp.x,newp.y,newp.z, s2i, s4i);

                Update();
            }
            //Update();
        }
        public static bool IntersectSphere(Point3d start,Point3d end,ref Point3d intersect, Point3d center,double radius)
        {
            bool retval = false;
            double EO;//EO is distance from start of ray to center of sphere
            double d,disc,v;//v is length of direction ray
            Vector3d V,temp;//V is unit vector of the ray
            temp =new Vector3d();
            V = new Vector3d();

            temp.Set(center.x - start.x,center.y - start.y,	center.z - start.z,0);

            EO = temp.Mag(); // unnormalized length
            V.Set(end.x - start.x,end.y - start.y,end.z - start.z,0);
            v = V.Mag();// magnitude of direction vector
            V.Normalize();// normalize the direction vector
            disc = (radius*radius) - ((EO*EO) - (v*v));
            if(disc < 0.0f)
            {
                retval = false;// no intersection
            }
            else
            { // compute the intersection point
                retval = true;
                d = Math.Sqrt(disc);
                intersect.x = start.x + ((v-d)*V.x);
                intersect.y = start.y + ((v-d)*V.y);
                intersect.z = start.z + ((v-d)*V.z);
            }
            return retval;
        }
        /// <summary>
        /// For now this is the editing mode for the currently selected support
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void glControl1_Click(object sender, EventArgs e)
        {
            // single click on GL Control
            Object3d obj = UVDLPApp.Instance().SelectedObject;
            if (obj == null) return;
            if (ctrldown == false) return; // ctrl need to be held down

            // this object is a support
            if (obj.tag == Object3d.OBJ_SUPPORT) 
            {
                Support sup = (Support)obj;// we can cast safely
                // now we have to see if we clicked on an object
                MouseEventArgs me = e as MouseEventArgs;
                MouseButtons buttonPushed = me.Button;
                int xPos = me.X;
                int yPos = me.Y;
                List<ISectData> isects = TestHitTest(xPos, yPos);
                if (isects.Count == 0) return; // no intersections
                ISectData isd1 =null;
                foreach (ISectData isd in isects) 
                {
                    // find the closest object we clicked
                    if (isd.obj.tag == Object3d.OBJ_NORMAL) 
                    {
                        isd1 = isd; //  save it
                        break;
                    }
                }
                if (isd1 == null) return; // no object intersection
                isd1.poly.CalcNormal();
                m_isectnormal.x = isd1.poly.m_normal.x;
                m_isectnormal.y = isd1.poly.m_normal.y;
                m_isectnormal.z = isd1.poly.m_normal.z;
                // ok, we've got the normal, we know where we've intersected
                // my best guess is that we should move the support 5mm in the direction of the camera
                // the tip of the support should touch the intersection point
                // let's start with scaling the height...
                //sup.ScaleToHeight(isd1.intersect.z);
                //m_camera.m_eye
                Engine3D.Vector3d towardseye = new Engine3D.Vector3d();
                towardseye = m_isectnormal;// -m_camera.m_eye;
                towardseye.Normalize(); // make the unit length of 1
                towardseye.Scale(4.0f); // scale to 5 mm
                sup.MoveFromTip(isd1.intersect, towardseye);
                UpdateView();
                //sup.
            }
        }
Exemple #20
0
        /// <summary>
        /// This functiuon positions the base at the location 'intersect'
        /// The idir is the direction that was used to intersect
        /// </summary>
        /// <param name="intersect"></param>
        /// <param name="idir"></param>
        /// <param name="inorm"></param>
        public void PositionBottom(ISectData dat)
        {
            // the bottom could be a tip or base
            // need to orient the bottom and position it.
            Point3d center;

            // for a base support, just slide it around
            if (m_subtype == eSubType.eBase)
            {
                center = Centroid(); // get the centroid of the selected portion of the object
                MinMax mm   = CalcMinMaxRange(s1i, s4i);
                float  dist = (float)((mm.m_max - mm.m_min) / 2);
                Translate(
                    (float)(dat.intersect.x - center.x),
                    (float)(dat.intersect.y - center.y),
                    (float)(dat.intersect.z - center.z + dist));
            }
            else if (m_subtype == eSubType.eIntra)  // bottom tip
            {
                // for a base tip, find the angle and angle it in
                Vector3d isectnorm = new Vector3d();
                //save the polygon intersection normal
                isectnorm.x = dat.poly.m_normal.x;
                isectnorm.y = dat.poly.m_normal.y;
                isectnorm.z = dat.poly.m_normal.z;
                isectnorm.Normalize();

                if (isectnorm.z < 0)
                {
                    isectnorm.z *= -1.0f;
                }
                // limit the z down to 45 degrees
                if (isectnorm.z < .75)
                {
                    isectnorm.z = .75f;
                }

                // re-genrate the points on the bottom of the foot
                ReGenSegmentPoints(mSC.htrad, mSC.cdivs, s1i, 0, true); // bottom of foot is the tip radius
                Matrix3D tMat = new Matrix3D();
                Vector3d vup  = new Vector3d(0, 1, 0);
                Vector3d dir  = new Vector3d(isectnorm.x, isectnorm.y, isectnorm.z);
                dir.Normalize();


                //direction should be upward at this point.
                //create a matrix transform
                tMat.LookAt(dir, vup);
                //transform the si1-s2i points to look at the vector
                TransformRange(tMat, s1i, s2i);
                //move the range of points to be touching the intersection point
                STranslateRange(dat.intersect.x, dat.intersect.y, dat.intersect.z, s1i, s2i);

                //now, get the center of s4i to s5i
                Point3d cnt = CalcCentroid(s2i, s4i);
                //translate to 0,0,0
                STranslateRange(-cnt.x, -cnt.y, -cnt.z, s2i, s4i);
                //reset the points,
                ReGenSegmentPoints(mSC.hbrad, mSC.cdivs, s2i, 0, false); // top of foot
                ReGenSegmentPoints(mSC.hbrad, mSC.cdivs, s3i, 0, false); // top of foot
                Point3d newp = new Point3d();
                newp.x = dat.intersect.x + (isectnorm.x * 2);
                newp.y = dat.intersect.y + (isectnorm.y * 2);
                newp.z = dat.intersect.z + (isectnorm.z * 2);
                STranslateRange(newp.x, newp.y, newp.z, s2i, s4i);

                Update();
            }
            //Update();
        }
        // split edge v1-v2. v3 is the last corner in the triangle and is used for computing normals
        int SplitEdge(int v1, int v2, Vector3d norm1, Vector3d norm2, out Vector3d norm12)
        {
            EdgeAmf edge = m_pointList[v1].FindEdge(v2);

            if (edge == null)
            {
                edge = m_pointList[v2].FindEdge(v1);
                if (edge != null)
                {
                    // swap verteces to match edge
                    int tv = v1;
                    v1 = v2;
                    v2 = tv;
                    Vector3d tnorm = norm1;
                    norm1 = norm2;
                    norm2 = tnorm;
                }
            }

            Vector3d t1, t2;
            PointAmf pamf1 = m_pointList[v1];
            PointAmf pamf2 = m_pointList[v2];
            Point3d  pt1   = pamf1.pt;
            Point3d  pt2   = pamf2.pt;
            PointAmf pamf;
            float    x, y, z;

            // calculate edge vector
            x = pt2.x - pt1.x;
            y = pt2.y - pt1.y;
            z = pt2.z - pt1.z;
            Vector3d edgeDir = new Vector3d(x, y, z);

            // first see if we have an edge for this segment
            if (edge != null)
            {
                // if this edge was already split, return result
                if (edge.v12 >= 0)
                {
                    norm12 = CalcCenterNormal(norm1, norm2, edge.t12);
                    return(edge.v12);
                }
                t1 = edge.t1;
                t2 = edge.t2;
            }
            else
            {
                t1 = GetTangetFromNormal(norm1, edgeDir);
                t2 = GetTangetFromNormal(norm2, edgeDir);
            }

            float d = edgeDir.Mag();

            // calculate mid point using Hermite interpolation
            x = 0.5f * pt1.x + 0.125f * t1.x * d + 0.5f * pt2.x - 0.125f * t2.x * d;
            y = 0.5f * pt1.y + 0.125f * t1.y * d + 0.5f * pt2.y - 0.125f * t2.y * d;
            z = 0.5f * pt1.z + 0.125f * t1.z * d + 0.5f * pt2.z - 0.125f * t2.z * d;

            pamf    = new PointAmf();
            pamf.pt = new Point3d(x, y, z);
            int v = m_pointList.Count;

            m_pointList.Add(pamf);

            // calculate new tanget and new normal
            x = -1.5f * pt1.x - 0.25f * t1.x * d + 1.5f * pt2.x - 0.25f * t2.x * d;
            y = -1.5f * pt1.y - 0.25f * t1.y * d + 1.5f * pt2.y - 0.25f * t2.y * d;
            z = -1.5f * pt1.z - 0.25f * t1.z * d + 1.5f * pt2.z - 0.25f * t2.z * d;
            Vector3d tanget = new Vector3d(x, y, z);

            tanget.Normalize();

            norm12 = CalcCenterNormal(norm1, norm2, tanget);

            if (edge == null)
            {
                //pamf.normal = GetNormalFromTanget(norm1, tanget);
                // create an edge for this segment
                edge    = new EdgeAmf();
                edge.v1 = v1;
                edge.v2 = v2;
                edge.t1 = t1;
                edge.t2 = t2;
                pamf1.AddEdge(edge);
            }
            edge.t12 = tanget;
            edge.v12 = m_pointList.Count - 1; // saves double computation

            //tanget.Normalize();
            // save 2 split edges
            EdgeAmf edge1 = new EdgeAmf();

            edge1.v1 = v1;
            edge1.v2 = v;
            edge1.t1 = t1;
            edge1.t2 = tanget;
            pamf1.AddEdge(edge1);

            EdgeAmf edge2 = new EdgeAmf();

            edge2.v1 = v;
            edge2.v2 = v2;
            edge2.t1 = tanget;
            edge2.t2 = t2;
            pamf.AddEdge(edge2);

            return(v);
        }
        private static ISectData ISectGroundPlane(Vector3d direction, Point3d origin)
        {
            ISectData isect = null;
            direction.Normalize();
            direction.Scale(10000.0f);

            GPendp.Set(origin);
            GPendp.x += direction.x;
            GPendp.y += direction.y;
            GPendp.z += direction.z;
            // intersect with the imaginary groundplane object;
            if (m_gp == null) 
            {
                CreateGroundPlane();
            }
            if (IntersectSphere(origin, GPendp, ref GPintersect, m_gp.m_center, m_gp.m_radius))
            {
                foreach (Polygon p in m_gp.m_lstpolys)
                {
                    //GPintersect = new Point3d();
                    // try a less- costly sphere intersect here   
                    if (IntersectSphere(origin, GPendp, ref GPintersect, p.m_center, p.m_radius))
                    {
                        // if it intersects,
                        if (RTUtils.IntersectPoly(p, origin, GPendp, ref GPintersect))
                        {
                           isect = new ISectData(m_gp, p, GPintersect, origin, direction);
                        }
                    }
                }
            }
            return isect;
        }
        // split edge v1-v2. v3 is the last corner in the triangle and is used for computing normals
        int SplitEdge(int v1, int v2, Vector3d norm1, Vector3d norm2, out Vector3d norm12)
        {
            EdgeAmf edge = m_pointList[v1].FindEdge(v2);
            if (edge == null)
            {
                edge = m_pointList[v2].FindEdge(v1);
                if (edge != null)
                {
                    // swap verteces to match edge
                    int tv = v1;
                    v1 = v2;
                    v2 = tv;
                    Vector3d tnorm = norm1;
                    norm1 = norm2;
                    norm2 = tnorm;
                }
            }

            Vector3d t1, t2;
            PointAmf pamf1 = m_pointList[v1];
            PointAmf pamf2 = m_pointList[v2];
            Point3d pt1 = pamf1.pt;
            Point3d pt2 = pamf2.pt;
            PointAmf pamf;
            float x, y, z;

            // calculate edge vector
            x = pt2.x - pt1.x;
            y = pt2.y - pt1.y;
            z = pt2.z - pt1.z;
            Vector3d edgeDir = new Vector3d(x, y, z);

            // first see if we have an edge for this segment
            if (edge != null)
            {
                // if this edge was already split, return result
                if (edge.v12 >= 0)
                {
                    norm12 = CalcCenterNormal(norm1, norm2, edge.t12);
                    return edge.v12;
                }
                t1 = edge.t1;
                t2 = edge.t2;
            }
             else
            {
                t1 = GetTangetFromNormal(norm1, edgeDir);
                t2 = GetTangetFromNormal(norm2, edgeDir);
            }

            float d = edgeDir.Mag();

            // calculate mid point using Hermite interpolation
            x = 0.5f * pt1.x + 0.125f * t1.x * d + 0.5f * pt2.x - 0.125f * t2.x * d;
            y = 0.5f * pt1.y + 0.125f * t1.y * d + 0.5f * pt2.y - 0.125f * t2.y * d;
            z = 0.5f * pt1.z + 0.125f * t1.z * d + 0.5f * pt2.z - 0.125f * t2.z * d;

            pamf = new PointAmf();
            pamf.pt = new Point3d(x, y, z);
            int v = m_pointList.Count;
            m_pointList.Add(pamf);

            // calculate new tanget and new normal
            x = -1.5f * pt1.x - 0.25f * t1.x * d + 1.5f * pt2.x - 0.25f * t2.x * d;
            y = -1.5f * pt1.y - 0.25f * t1.y * d + 1.5f * pt2.y - 0.25f * t2.y * d;
            z = -1.5f * pt1.z - 0.25f * t1.z * d + 1.5f * pt2.z - 0.25f * t2.z * d;
            Vector3d tanget = new Vector3d(x, y, z);
            tanget.Normalize();

            norm12 = CalcCenterNormal(norm1, norm2, tanget);
            
            if (edge == null)
            {
                //pamf.normal = GetNormalFromTanget(norm1, tanget);
                // create an edge for this segment
                edge = new EdgeAmf();
                edge.v1 = v1;
                edge.v2 = v2;
                edge.t1 = t1;
                edge.t2 = t2;
                pamf1.AddEdge(edge);
            }
            edge.t12 = tanget;
            edge.v12 = m_pointList.Count - 1; // saves double computation 

            //tanget.Normalize();
            // save 2 split edges
            EdgeAmf edge1 = new EdgeAmf();
            edge1.v1 = v1;
            edge1.v2 = v;
            edge1.t1 = t1;
            edge1.t2 = tanget;
            pamf1.AddEdge(edge1);

            EdgeAmf edge2 = new EdgeAmf();
            edge2.v1 = v;
            edge2.v2 = v2;
            edge2.t1 = tanget;
            edge2.t2 = t2;
            pamf.AddEdge(edge2);

            return v;
        }