public Point3d(Point3d pnt) { x = pnt.x; y = pnt.y; z = pnt.z; }
public int Intersect(Point3d startp, Point3d endp, ref Point3d isect) { float SMALL_NUM = 0.00000001f; Vector3d u = endp - startp; Vector3d w = startp - _pnt; float D = (float)_normal.Dot(u); float N = (float)-_normal.Dot(w); if (Math.Abs(D) < SMALL_NUM) { if (N == 0) { return 2; // segment lies on plane } else { return 0; // no intersection } } // they are not parallel // compute intersect param float sI = N / D; if (sI < 0 || sI > 1) return 0; // no intersection isect = startp + sI* u; // compute segment intersect point return 1; }
public void FillObjectInfo(Object3d selobj) { List<Object3d> objects; if (buttScene.Checked) { objects = UVDLPApp.Instance().Engine3D.m_objects; } else { objects = new List<Object3d>(); if (selobj != null) objects.Add(selobj); } if (objects.Count == 0) { foreach (Control ctl in layoutPanel.Controls) { if (ctl.GetType() == typeof(ctlInfoItem)) ((ctlInfoItem)ctl).DataText = ""; } tName.Text = ""; return; } tName.Text = buttScene.Checked ? "Scene" : selobj.Name; Point3d min = new Point3d(99999999,99999999,99999999); Point3d max = new Point3d(-99999999,-99999999,-99999999); int points = 0; int polys = 0; double vol = 0; foreach (Object3d obj in objects) { if (obj.tag != Object3d.OBJ_NORMAL && obj.tag != Object3d.OBJ_SUPPORT && obj.tag != Object3d.OBJ_SUPPORT_BASE) continue; obj.FindMinMax(); points += obj.NumPoints; polys += obj.NumPolys; if (obj.m_min.x < min.x) min.x = obj.m_min.x; if (obj.m_min.y < min.y) min.y = obj.m_min.y; if (obj.m_min.z < min.z) min.z = obj.m_min.z; if (obj.m_max.x > max.x) max.x = obj.m_max.x; if (obj.m_max.y > max.y) max.y = obj.m_max.y; if (obj.m_max.z > max.z) max.z = obj.m_max.z; vol += obj.Volume; } tPoints.DataText = points.ToString(); tPolys.DataText = polys.ToString(); tMin.DataText = String.Format("{0:0.00}, {1:0.00}, {2:0.00}", min.x, min.y, min.z); tMax.DataText = String.Format("{0:0.00}, {1:0.00}, {2:0.00}", max.x, max.y, max.z); double xs, ys, zs; xs = max.x - min.x; ys = max.y - min.y; zs = max.z - min.z; tSize.DataText = String.Format("{0:0.00}, {1:0.00}, {2:0.00}", xs, ys, zs); vol /= 1000.0; // convert to cm^3 tVolume.DataText = string.Format("{0:0.000} cm^3", vol); double cost = vol * (UVDLPApp.Instance().m_buildparms.m_resinprice / 1000.0); tCost.DataText = string.Format("{0:0.000}", cost); }
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; }
/// <summary> /// This is an epsilon-based match /// </summary> /// <param name="pnt"></param> /// <returns></returns> public bool Matches(Point3d pnt) { if (pnt.x >= (x - epsilon) && pnt.x <= (x + epsilon)) { if (pnt.y >= (y - epsilon) && pnt.y <= (y + epsilon)) { if (pnt.z >= (z - epsilon) && pnt.z <= (z + epsilon)) { return true; } } } return false; }
static void Initvecs() { vecinit = true; u = new Vector3d(); v = new Vector3d(); n = new Vector3d(); dir = new Vector3d(); w0 = new Vector3d(); w = new Vector3d(); V = new Vector3d(); temp = new Vector3d(); IOendp = new Point3d(); IOintersect = new Point3d(); GPendp = new Point3d(); GPintersect = new Point3d(); m_isectlst = new List<ISectData>(); }
/// <summary> /// this function tests for an exact match of points /// </summary> /// <param name="pnt"></param> /// <returns></returns> public bool IsEqual(Point3d pnt) { if (x == pnt.x && y == pnt.y && z == pnt.z) return true; return false; }
public void Set(Point3d pnt) { Set(pnt.x, pnt.y, pnt.z); }
public Plane3d(Vector3d normal, Point3d pnt) { _normal = new Vector3d(normal.x, normal.y, normal.z); _pnt = new Point3d(pnt); }
private static void CreateGroundPlane() { m_gp = new Object3d(); m_gp.Name = "GroundPlane"; Point3d p0=new Point3d(-500,-500,0); Point3d p1=new Point3d(500,-500,0); Point3d p2=new Point3d(500,500,0); Point3d p3=new Point3d(-500,500,0); m_gp.m_lstpoints.Add(p0); m_gp.m_lstpoints.Add(p1); m_gp.m_lstpoints.Add(p2); m_gp.m_lstpoints.Add(p3); Polygon ply0 = new Polygon(); ply0.m_points = new Point3d[3]; ply0.m_points[0] = p0; ply0.m_points[1] = p1; ply0.m_points[2] = p2; Polygon ply1 = new Polygon(); ply1.m_points = new Point3d[3]; ply1.m_points[0] = p0; ply1.m_points[1] = p2; ply1.m_points[2] = p3; m_gp.m_lstpolys.Add(ply0); m_gp.m_lstpolys.Add(ply1); m_gp.tag = Object3d.OBJ_GROUND; // groundplane tag m_gp.Update(); // p1.m }
public static bool IntersectPoly(Polygon poly, Point3d start, Point3d end,ref Point3d intersection) { if (intersect3D_RayTriangle(start, end, poly, ref intersection) == 1) return true; return false; }
private void glControl1_MouseMove(object sender, MouseEventArgs e) { double dx = 0, dy = 0; if (lmdown || rmdown || mmdown) { dx = e.X - mdx; dy = e.Y - mdy; mdx = e.X; mdy = e.Y; } dx /= 2; dy /= 2; if (lmdown) { m_camera.RotateRightFlat((float)dx); m_camera.RotateUp((float)dy); m_axisCam.RotateRightFlat((float)dx); m_axisCam.RotateUp((float)dy); UpdateView(); } else if (mmdown) { m_camera.MoveForward((float)dy); UpdateView(); } else if (rmdown) { m_camera.Move((float)dx, (float)dy); UpdateView(); } if (UVDLPApp.Instance().SelectedObject != null) { if (m_movingobjectmode) // if we're moving an object { List<ISectData> hits = TestHitTest(e.X, e.Y); // really only need to hit-test ground // examine the last isect data foreach (ISectData dat in hits) { if (dat.obj.tag == Object3d.OBJ_GROUND) //found the ground plane { UVDLPApp.Instance().SelectedObject.Translate( (float)(dat.intersect.x - UVDLPApp.Instance().SelectedObject.m_center.x), (float)(dat.intersect.y - UVDLPApp.Instance().SelectedObject.m_center.y), 0.0f); //UVDLPApp.Instance().Engine3D.UpdateLists(); //UpdateView(); } } if (UVDLPApp.Instance().SelectedObject.tag == Object3d.OBJ_SUPPORT) // if the current selected object is a support { Support tmpsup = (Support)UVDLPApp.Instance().SelectedObject; Point3d pnt = new Point3d(); pnt.Set(tmpsup.m_center.x, tmpsup.m_center.y, 0); Engine3D.Vector3d vec = new Engine3D.Vector3d(); vec.Set(0, 0, 1); // create a vector striaght up // hit test from the selected objects center x/y/0 position straight up //see if it hits any object in the scene, // if it does, scale the object from the ground plane to the closest intersection point List<ISectData> iss = RTUtils.IntersectObjects(vec, pnt, UVDLPApp.Instance().Engine3D.m_objects, false); bool foundObject = false; foreach (ISectData htd in iss) { if (htd.obj.tag == Object3d.OBJ_NORMAL) // if this is not another support or the ground { // this should be it... tmpsup.ScaleToHeight(htd.intersect.z); //set the parent object tmpsup.m_supporting = htd.obj; htd.obj.AddSupport(tmpsup); foundObject = true; break; } } if (!foundObject && (tmpsup.m_parrent != null)) { tmpsup.m_parrent.RemoveSupport(tmpsup); } } UpdateView(); } } //UpdateView(false); }
public static bool IntersectPoly(Polygon poly, Point3d start, Point3d end,ref Point3d intersection) { //intersect a Polygon with a ray in world space bool retval = false; double deltaX, deltaY, deltaZ, t, T, S; double A, B, C, D;//the Polygon plane double denom; if (TstPnt[0] == null) // create if not created already { TstPnt[0] = new TestPoint(); TstPnt[1] = new TestPoint(); TstPnt[2] = new TestPoint(); TstPnt[3] = new TestPoint(); } A = poly.plane.a; B = poly.plane.b; C = poly.plane.c; D = poly.plane.d; deltaX = end.x - start.x; deltaY = end.y - start.y; deltaZ = end.z - start.z; denom = (A * deltaX + B * deltaY + C * deltaZ); if (denom == 0.0)//ray is parallel, no intersection { retval = false; return retval; } T = (-1) / denom; S = (A * start.x + B * start.y + C * start.z); t = (S + D) * T; //at this point we have a possible intersection //project to a major world axis and test for containment in the poly intersection.x = (float)(start.x + (t * deltaX)); intersection.y = (float)(start.y + (t * deltaY)); intersection.z = (float)(start.z + (t * deltaZ)); numTstPnt = poly.m_points.Length; // test the X/Y plane for (long counter = 0; counter < poly.m_points.Length; counter++) { TstPnt[counter].X = poly.m_points[counter].x; TstPnt[counter].Y = poly.m_points[counter].y; } if (CrossingsTest(intersection.x, intersection.y) == 1) { retval = true; return retval; } // Test the X/Z plane for (long counter = 0; counter < poly.m_points.Length; counter++) { TstPnt[counter].X = poly.m_points[counter].x; TstPnt[counter].Y = poly.m_points[counter].z; } if (CrossingsTest(intersection.x, intersection.y) == 1) { retval = true; } return retval; }
void ParseVertex(XmlNode xVert) { XmlNode xcoor = xVert["coordinates"]; float x = float.Parse(xcoor["x"].InnerText) * m_scaleFactor; float y = float.Parse(xcoor["y"].InnerText) * m_scaleFactor; float z = float.Parse(xcoor["z"].InnerText) * m_scaleFactor; Point3d pt = new Point3d(x, y, z); PointAmf pamf= new PointAmf(); pamf.pt = pt; // add normal if exists XmlNode xnorm = xVert["normal"]; if (xnorm != null) { m_smoothObj = true; x = float.Parse(xnorm["nx"].InnerText); y = float.Parse(xnorm["ny"].InnerText); z = float.Parse(xnorm["nz"].InnerText); pamf.normal = new Vector3d(x, y, z); } m_pointList.Add(pamf); }
public void Set(Vector3d normal, Point3d pnt) { _normal.Set(normal.x, normal.y, normal.z); _pnt.Set(pnt); }
/* The object selection plane is used to help move objects around * This is a plane is centered at the object center and faces the center of the view * This is used to determine an intersection along the plane to help move the object * This is created by picking a center point, and using the camera's forward and right vectors to generate * 2 polygons that form a forward-facing plane at a distance of the camera to the point along the forward vector * parameters: * center is the center of the currently selected object * fromcamera is the vector from the camera to the center of the selected object * cameraup is the up vector of the camera */ public static void UpdateObjectSelectionPlane(Point3d center, Vector3d cameraup, Vector3d cameraright) { //get the currently selected object //create 2 polygons //forward facing towards the camera /* p0 p1 *------ |\ | | \ | | * | object center | \ | | \| ------| p3 p2 */ Point3d p0; Point3d p1; Point3d p2; Point3d p3; if (m_selplane == null) { m_selplane = new Object3d(); m_selplane.Name = "Selection Plane"; p0 = new Point3d(); p1 = new Point3d(); p2 = new Point3d(); p3 = new Point3d(); // add the points m_selplane.m_lstpoints.Add(p0); m_selplane.m_lstpoints.Add(p1); m_selplane.m_lstpoints.Add(p2); m_selplane.m_lstpoints.Add(p3); //new polygon Polygon ply0 = new Polygon(); ply0.m_points = new Point3d[3]; //set poly points ply0.m_points[0] = p0; ply0.m_points[1] = p1; ply0.m_points[2] = p2; //add the polygon to the model m_selplane.m_lstpolys.Add(ply0); Polygon ply1 = new Polygon(); ply1.m_points = new Point3d[3]; ply1.m_points[0] = p0; ply1.m_points[1] = p2; ply1.m_points[2] = p3; m_selplane.m_lstpolys.Add(ply1); m_selplane.tag = Object3d.OBJ_SEL_PLANE; // groundplane tag } else { //references to already created points p0 = m_selplane.m_lstpoints[0]; p1 = m_selplane.m_lstpoints[1]; p2 = m_selplane.m_lstpoints[2]; p3 = m_selplane.m_lstpoints[3]; } float scaler = 100.0f; p0.Set((cameraup.x / 2) - (cameraright.x / 2), (cameraup.y / 2) - (cameraright.y / 2), (cameraup.z/2) - (cameraright.z/2)); p1.Set((cameraup.x / 2) + (cameraright.x / 2), (cameraup.y / 2) + (cameraright.y / 2), (cameraup.z / 2) + (cameraright.z / 2)); p2.Set((-cameraup.x / 2) + (cameraright.x / 2), (-cameraup.y / 2) + (cameraright.y / 2), (-cameraup.z / 2) + (cameraright.z / 2)); p3.Set((-cameraup.x / 2) - (cameraright.x / 2), (-cameraup.y / 2) - (cameraright.y / 2), (-cameraup.z / 2) - (cameraright.z / 2)); p0.x *= scaler; p0.y *= scaler; p0.z *= scaler; p1.x *= scaler; p1.y *= scaler; p1.z *= scaler; p2.x *= scaler; p2.y *= scaler; p2.z *= scaler; p3.x *= scaler; p3.y *= scaler; p3.z *= scaler; // initial positions m_selplane.Update(); // center it on the object m_selplane.Translate(center.x, center.y, center.z); }
private List<ISectData> TestHitTest(int X, int Y) { if (!loaded) return null; // String mess = ""; // mess = "Screen X,Y = (" + X.ToString() + "," + Y.ToString() + ")\r\n"; /* (Note that most window systems place the mouse coordinate origin in the upper left of the window instead of the lower left. That's why window_y is calculated the way it is in the above code. When using a glViewport() that doesn't match the window height, the viewport height and viewport Y are used to determine the values for window_y and norm_y.) The variables norm_x and norm_y are scaled between -1.0 and 1.0. Use them to find the mouse location on your zNear clipping plane like so: float y = near_height * norm_y; float x = near_height * aspect * norm_x; Now your pick ray vector is (x, y, -zNear). */ int w = glControl1.Width; int h = glControl1.Height; // mess += "Screen Width/Height = " + w.ToString() + "," + h.ToString() + "\r\n"; float aspect = ((float)glControl1.Width) / ((float)glControl1.Height); //mess += "Screen Aspect = " + aspect.ToString() + "\r\n"; int window_y = (h - Y) - h / 2; double norm_y = (double)(window_y) / (double)(h / 2); int window_x = X - w / 2; double norm_x = (double)(window_x) / (double)(w / 2); float near_height = .2825f; // no detectable error float y = (float)(near_height * norm_y); float x = (float)(near_height * aspect * norm_x); /* To transform this eye coordinate pick ray into object coordinates, multiply it by the inverse of the ModelView matrix in use when the scene was rendered. When performing this multiplication, remember that the pick ray is made up of a vector and a point, and that vectors and points transform differently. You can translate and rotate points, but vectors only rotate. The way to guarantee that this is working correctly is to define your point and vector as four-element arrays, as the following pseudo-code shows: float ray_pnt[4] = {0.f, 0.f, 0.f, 1.f}; float ray_vec[4] = {x, y, -near_distance, 0.f}; The one and zero in the last element determines whether an array transforms as a point or a vector when multiplied by the inverse of the ModelView matrix.*/ Vector4 ray_pnt = new Vector4(0.0f, 0.0f, 0.0f, 1.0f); //Vector4 ray_vec = new Vector4((float)norm_x, (float)norm_y, -1.0f, 0); Vector4 ray_vec = new Vector4((float)x, (float)y, -1f, 0); ray_vec.Normalize(); //mess += "Eye Pick Vec = (" + String.Format("{0:0.00}", ray_vec.X) + ", " + String.Format("{0:0.00}", ray_vec.Y) + "," + String.Format("{0:0.00}", ray_vec.Z) + ")\r\n"; Matrix4 modelViewMatrix; GL.GetFloat(GetPName.ModelviewMatrix, out modelViewMatrix); Matrix4 viewInv = Matrix4.Invert(modelViewMatrix); Vector4 t_ray_pnt = new Vector4(); Vector4 t_ray_vec = new Vector4(); Vector4.Transform(ref ray_vec, ref viewInv, out t_ray_vec); Vector4.Transform(ref ray_pnt, ref viewInv, out t_ray_pnt); //mess += "World Pick Vec = (" + String.Format("{0:0.00}", t_ray_vec.X) + ", " + String.Format("{0:0.00}", t_ray_vec.Y) + "," + String.Format("{0:0.00}", t_ray_vec.Z) + ")\r\n"; //mess += "World Pick Pnt = (" + String.Format("{0:0.00}", t_ray_pnt.X) + ", " + String.Format("{0:0.00}", t_ray_pnt.Y) + "," + String.Format("{0:0.00}", t_ray_pnt.Z) + ")\r\n"; Point3d origin = new Point3d(); Point3d intersect = new Point3d(); Engine3D.Vector3d dir = new Engine3D.Vector3d(); origin.Set(t_ray_pnt.X, t_ray_pnt.Y, t_ray_pnt.Z); dir.Set(t_ray_vec.X, t_ray_vec.Y, t_ray_vec.Z); // should this be scaled? List<ISectData> isects = RTUtils.IntersectObjects(dir, origin, UVDLPApp.Instance().Engine3D.m_objects, true); if (isects.Count > 0) { foreach (ISectData isect in isects) { if (!float.IsNaN(isect.intersect.x)) // check for NaN { m_ix = (float)isect.intersect.x; // show the closest m_iy = (float)isect.intersect.y; m_iz = (float)isect.intersect.z; isect.poly.CalcNormal(); m_isectnormal.x = isect.poly.m_normal.x; m_isectnormal.y = isect.poly.m_normal.y; m_isectnormal.z = isect.poly.m_normal.z; break; } } //ISectData isect = (ISectData)isects[0]; // get the first // check for NaN } return isects; }
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; }
private Object3d ConvertFrom(List<csgjs_polygon> lstply) { Object3d obj = new Object3d(); for (int i = 0; i < lstply.Count; i++) { csgjs_polygon poly = lstply[i]; for (int j = 2; j < poly.vertices.Count; j++) { Polygon ply = new Polygon(); // create a new polygon ply.m_points = new Point3d[3]; obj.m_lstpolys.Add(ply); //add it to the list Point3d p0 = new Point3d(); Point3d p1 = new Point3d(); Point3d p2 = new Point3d(); p0.Set(poly.vertices[0].pos.x, poly.vertices[0].pos.y, poly.vertices[0].pos.z); p1.Set(poly.vertices[j - 1].pos.x, poly.vertices[j - 1].pos.y, poly.vertices[j - 1].pos.z); p2.Set(poly.vertices[j].pos.x, poly.vertices[j].pos.y, poly.vertices[j].pos.z); ply.m_points[0] = p0; ply.m_points[1] = p1; ply.m_points[2] = p2; obj.m_lstpoints.Add(p0); obj.m_lstpoints.Add(p1); obj.m_lstpoints.Add(p2); } } obj.Update(); return obj; }
private void glControl1_MouseMove(object sender, MouseEventArgs e) { double dx = 0, dy = 0; if (lmdown || rmdown || mmdown) { dx = e.X - mdx; dy = e.Y - mdy; mdx = e.X; mdy = e.Y; } dx /= 2; dy /= 2; if (lmdown) { m_camera.RotateRightFlat((float)dx); m_camera.RotateUp((float)dy); m_axisCam.RotateRightFlat((float)dx); m_axisCam.RotateUp((float)dy); UpdateView(); } else if (mmdown) { m_camera.MoveForward((float)dy); UpdateView(); } else if (rmdown) { m_camera.Move((float)dx, (float)dy); UpdateView(); } // if no object selected, bail if (UVDLPApp.Instance().SelectedObject == null) return; if (m_movingobjectmode) // if we're moving an object - shift key down { List<ISectData> hits = TestHitTest(e.X, e.Y); // hit-test all // examine the last isect data foreach (ISectData dat in hits) { //remember to break out of this foreach loop after executing a movement. // either we're moving a support if (UVDLPApp.Instance().SelectedObject.tag == Object3d.OBJ_SUPPORT) { // if it's the base we're moving, //allow the base to change types // see if it intersects with the ground, or an object //cast as a support object Support sup = (Support)UVDLPApp.Instance().SelectedObject; if (sup.SelectionType == Support.eSelType.eWhole) { // we're in modify mode, but we're still moving the whole support if (dat.obj.tag == Object3d.OBJ_SEL_PLANE) { //we should really try a top/ bottom intersection / scale to hieg // move the support sup.Translate( (float)(dat.intersect.x - UVDLPApp.Instance().SelectedObject.m_center.x), (float)(dat.intersect.y - UVDLPApp.Instance().SelectedObject.m_center.y), 0.0f); // now we've moved the object approximately to where it needs to be //turn it back into a base sup.SubType = Support.eSubType.eBase; //get the center location Point3d centroid = sup.Centroid(); Engine3D.Vector3d upvec = new Engine3D.Vector3d(); upvec.Set(0, 0, 1); Point3d origin = new Point3d(); origin.Set(centroid.x, centroid.y, .001f);// above the ground plane List<ISectData> isects = RTUtils.IntersectObjects(upvec, origin, UVDLPApp.Instance().Engine3D.m_objects, false); foreach (ISectData isd in isects) { if (isd.obj.tag == Object3d.OBJ_NORMAL)// if we've intersected a normal object upwards { sup.SelectionType = Support.eSelType.eTip; sup.MoveFromTip(isd); sup.SelectionType = Support.eSelType.eWhole; break; } } //starting at the x/y ground plane, hittest upward break; } } else if (sup.SelectionType == Support.eSelType.eBase) { //going to change this to test for intersection with object, or ground plane // if intersected with an object, change to intra type // and set the base on the object // if intersected with ground, change to base type and put on ground if (dat.obj.tag == Object3d.OBJ_GROUND) { // make sure we're a base tip sup.SubType = Support.eSubType.eBase; // position the bottom to the intersection point sup.PositionBottom(dat); break; } else if (dat.obj.tag == Object3d.OBJ_NORMAL) // intersected with an object { //should check with the normal of the object to see if it's facing upwards sup.SubType = Support.eSubType.eIntra; // position the bottom to the intersection point sup.PositionBottom(dat); break; } } else if (sup.SelectionType == Support.eSelType.eTip) { if (dat.obj.tag == Object3d.OBJ_NORMAL) // intersected with an object { sup.MoveFromTip(dat); UpdateView(); break; } } } else // or a normal object based on object selection plane { if (dat.obj.tag == Object3d.OBJ_SEL_PLANE) { UVDLPApp.Instance().SelectedObject.Translate( (float)(dat.intersect.x - UVDLPApp.Instance().SelectedObject.m_center.x), (float)(dat.intersect.y - UVDLPApp.Instance().SelectedObject.m_center.y), 0.0f); } break; } } UpdateView(); } }
public static bool IntersectSphere(Point3d start,Point3d end,ref Point3d intersect, Point3d center,float radius) { bool retval = false; float EO;//EO is distance from start of ray to center of sphere float d,disc,raylen;//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); EO = temp.Mag(); // unnormalized length V.Set(end.x - start.x,end.y - start.y,end.z - start.z); raylen = V.Mag();// magnitude of direction vector V.Normalize();// normalize the direction vector disc = (radius*radius) - ((EO*EO) - (raylen*raylen)); if(disc < 0.0f) { retval = false;// no intersection } else { // compute the intersection point retval = true; d = (float)Math.Sqrt(disc); intersect.x = start.x + ((raylen-d)*V.x); intersect.y = start.y + ((raylen-d)*V.y); intersect.z = start.z + ((raylen-d)*V.z); } return retval; }
// draw the intersection of the current mouse point into the scene private void DrawISect() { // draw some lines GL.LineWidth(2); GL.Color3(Color.Red); GL.Begin(PrimitiveType.Lines); GL.Vertex3(m_ix - 5, m_iy, m_iz); GL.Vertex3(m_ix + 5, m_iy, m_iz); GL.End(); GL.Begin(PrimitiveType.Lines); GL.Vertex3(m_ix, m_iy - 5, m_iz); GL.Vertex3(m_ix, m_iy + 5, m_iz); GL.End(); // Point3d spnt = new Point3d(); Point3d epnt = new Point3d(); spnt.x = m_ix; spnt.y = m_iy; spnt.z = m_iz; Engine3D.Vector3d tvec = new Engine3D.Vector3d(); tvec.x = m_isectnormal.x; tvec.y = m_isectnormal.y; tvec.z = m_isectnormal.z; tvec.Scale(5.0f); epnt.x = spnt.x + tvec.x; epnt.y = spnt.y + tvec.y; epnt.z = spnt.z + tvec.z; GL.LineWidth(2); GL.Color3(Color.Red); GL.Begin(PrimitiveType.Lines); GL.Vertex3(spnt.x, spnt.y, spnt.z); GL.Vertex3(epnt.x, epnt.y, epnt.z); GL.End(); GL.LineWidth(1); }
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; }
public static Point3d operator +(Point3d c1, Vector3d c2) { Point3d ret = new Point3d(); ret.Set(c1.x + c2.x, c1.y + c2.y, c1.z + c2.z); return ret; }
// intersect3D_RayTriangle(): find the 3D intersection of a ray with a triangle // Input: a ray R, and a triangle T // Output: *I = intersection point (when it exists) // Return: -1 = triangle is degenerate (a segment or point) // 0 = disjoint (no intersect) // 1 = intersect in unique point I1 // 2 = are in the same plane static int intersect3D_RayTriangle(Point3d startp, Point3d endp, Polygon T,ref Point3d I) { // Vector3d u, v, n; // triangle vectors // Vector3d dir, w0, w; // ray vectors float r, a, b; // params to calc ray-plane intersect // get triangle edge vectors and plane normal //u = T.m_points[1] - T.m_points[0]; u.Set(T.m_points[1].x - T.m_points[0].x, T.m_points[1].y - T.m_points[0].y, T.m_points[1].z - T.m_points[0].z); //v = T.m_points[2] - T.m_points[0]; v.Set(T.m_points[2].x - T.m_points[0].x, T.m_points[2].y - T.m_points[0].y, T.m_points[2].z - T.m_points[0].z); n = Vector3d.cross(u , v); // cross product //n = T.m_normal; //if (n == 0) // triangle is degenerate // return -1; // do not deal with this case //dir = endp - startp;//dir = R.P1 - R.P0; // ray direction vector dir.Set(endp.x - startp.x, endp.y - startp.y, endp.z - startp.z); //w0 = startp - T.m_points[0];//w0 = R.P0 - T.V0; w0.Set(startp.x - T.m_points[0].x, startp.y - T.m_points[0].y, startp.z - T.m_points[0].z); a = (float)-Vector3d.dot(n, w0); //a = -dot(n, w0); b = (float)Vector3d.dot(n, dir);//b = dot(n, dir); if(Math.Abs(b) < .0001) { // ray is parallel to triangle plane if (a == 0) // ray lies in triangle plane return 2; else return 0; // ray disjoint from plane } // get intersect point of ray with triangle plane r = a / b; if (r < 0.0) // ray goes away from triangle return 0; // => no intersect // for a segment, also test if (r > 1.0) => no intersect //*I = R.P0 + r * dir; // intersect point of ray and plane I.x = startp.x + r * dir.x; I.y = startp.y + r * dir.y; I.z = startp.z + r * dir.z; if (float.IsNaN(I.x)) { // what's going on here? I.x = -1.0f; } // is I inside T? double uu, uv, vv, wu, wv, D; uu = Vector3d.dot(u, u); uv = Vector3d.dot(u, v); vv = Vector3d.dot(v, v); //w = I - T.m_points[0];// V0; w.Set(I.x - T.m_points[0].x,I.y - T.m_points[0].y,I.z - T.m_points[0].z);// V0; wu = Vector3d.dot(w, u); wv = Vector3d.dot(w, v); D = uv * uv - uu * vv; // get and test parametric coords double s, t; s = (uv * wv - vv * wu) / D; if (s < 0.0 || s > 1.0) // I is outside T return 0; t = (uv * wu - uu * wv) / D; if (t < 0.0 || (s + t) > 1.0) // I is outside T return 0; return 1; // I is in T }
public csgjs_vertex(Point3d pnt) { pos = new csgjs_vector((float)pnt.x,(float)pnt.y,(float)pnt.z); normal = new csgjs_vector(); uv = new csgjs_vector(); }