public void OnMouseMove(Point new_pos) { if (selected == null) { return; } if (moving) { TRay world_ray = render.ToWorld(new_pos); if (rotating) { Vector3 temp = Vector3.Cross(world_ray.dir, moving_dir); float new_proj = Vector3.Dot(world_ray.pos, temp); Matrix new_orient = start_orient * Matrix.RotationAxis(moving_dir, new_proj); selected.SetRotation(new_orient); } else { float curr_proj = 0;; (new TRay(start_pos, moving_dir)).PointNearestToOtherRay(world_ray, ref curr_proj); selected.SetPos(start_pos + moving_dir * (curr_proj - start_proj)); } } else { TestAxises(new_pos); } }
public void PointNearestToOtherRay(TRay r, ref float point) { Vector3 t = Vector3.Cross(dir, r.dir); TPlane p = new TPlane(Vector3.Cross(t, r.dir), r.pos); Inters(p, ref point); }
public bool Overlaps(TRay ray) { float b; Vector3 t; t = ray.pos - pos; b = (Vector3.Dot(ray.dir, t)) * 2.0f; return(b * b - 4 * Vector3.Dot(ray.dir, ray.dir) * (Vector3.Dot(t, t) - radius * radius) >= 0); }
public void RayQuery(TVector <int> result, TRay ray) { result.Pop(result.Length); if (nodes[root].dims.Overlaps(ray)) { RayQuery(nodes[root], result, ray); } DeleteRepeatingValues(result); }
public bool Overlaps(TRay ray) { Matrix m = orient; m.Invert();//TODO можно лишь транспонировать матрицу 3x3,а смещение вычислять вручную TRay modified_ray = new TRay(Vector3.TransformCoordinate(ray.pos, m), Vector3.TransformNormal(ray.dir, m)); return(aabb.Overlaps(modified_ray)); }
void TestAxises(Point new_pos) { float size = size_mul * Vector3.Length(selected.GetPos() - cam.GetPos()); Vector3 pos = selected.GetPos(); Matrix m; Vector3 bx, by, bz; if (world_movement) { m = Matrix.Translation(selected.GetPos()); bx = new Vector3(1, 0, 0); by = new Vector3(0, 1, 0); bz = new Vector3(0, 0, 1); } else { m = selected.GetOrient(); bx = new Vector3(m.M11, m.M12, m.M13); by = new Vector3(m.M21, m.M22, m.M23); bz = new Vector3(m.M31, m.M32, m.M33); } TOBB x, y, z; TOBB xy, yz, zx;//TODO перемещение в плоскости //создаем OBB's на месте направляющих осей для определения пересечения x = new TOBB(new Vector3(1, 0, 0) * size * 0.5f, new Vector3(size, aabb_size_mul * size, aabb_size_mul * size)); x.SetOrient(m); y = new TOBB(new Vector3(0, 1, 0) * size * 0.5f, new Vector3(aabb_size_mul * size, size, aabb_size_mul * size)); y.SetOrient(m); z = new TOBB(new Vector3(0, 0, 1) * size * 0.5f, new Vector3(aabb_size_mul * size, aabb_size_mul * size, size)); z.SetOrient(m); TRay world_ray = render.ToWorld(new_pos); x_selected = false; y_selected = false; z_selected = false; x_selected = x.Overlaps(world_ray); if (x_selected) { return; } y_selected = y.Overlaps(world_ray); if (x_selected || y_selected) { return; } z_selected = z.Overlaps(world_ray); }
public bool Overlaps(TRay ray) { // float max_length = 10000; Vector3 mid = ray.pos + ray.dir * (max_length / 2.0f); Vector3 dir = ray.dir; float hl = (max_length / 2.0f); Vector3 T = pos - mid; Vector3 E = widths; E.Multiply(0.5f); float r; // проверяем, является ли одна из осей X,Y,Z разделяющей if ((Math.Abs(T.X) > E.X + hl * Math.Abs(dir.X)) || (Math.Abs(T.Y) > E.Y + hl * Math.Abs(dir.Y)) || (Math.Abs(T.Z) > E.Z + hl * Math.Abs(dir.Z))) { return(false); } // проверяем X ^ dir r = E.Y * Math.Abs(dir.Z) + E.Z * Math.Abs(dir.Y); if (Math.Abs(T.Y * dir.Z - T.Z * dir.Y) > r) { return(false); } // проверяем Y ^ dir r = E.X * Math.Abs(dir.Z) + E.Z * Math.Abs(dir.X); if (Math.Abs(T.Z * dir.X - T.X * dir.Z) > r) { return(false); } // проверяем Z ^ dir r = E.X * Math.Abs(dir.Y) + E.Y * Math.Abs(dir.X); if (Math.Abs(T.X * dir.Y - T.Y * dir.X) > r) { return(false); } return(true); }
void RayQuery(TOctreeNode node, TVector <int> result, TRay ray) { if (node.is_end != -1) { result.Add(items[node.is_end]); } else { for (int i = 0; i < 8; i++) { if (node.child[i] != -1) { if (nodes[node.child[i]].dims.Overlaps(ray)) { RayQuery(nodes[node.child[i]], result, ray); } } } } }
public void OnMouseDown(Point new_pos) { if (selected == null) { return; } x_selected = false; y_selected = false; z_selected = false; TestAxises(new_pos); if (x_selected) { moving_dir = bx; } else if (y_selected) { moving_dir = by; } else if (z_selected) { moving_dir = bz; } if (x_selected || y_selected || z_selected) { TRay world_ray = render.ToWorld(new_pos); moving = true; if (rotating) { start_orient = selected.GetOrient(); Vector3 temp = Vector3.Cross(world_ray.dir, moving_dir); start_proj = Vector3.Dot(world_ray.pos, temp); } else { start_pos = selected.GetPos(); (new TRay(start_pos, moving_dir)).PointNearestToOtherRay(world_ray, ref start_proj); } } }