public static double GetRotationAngle(Vector3D axis, Vector3D startNormal, Vector3D endNormal)
 {
     if (startNormal.IsSame(endNormal))
     return 0;
      if (startNormal.IsSame(-endNormal))
     return 180;
      var cross = startNormal.Cross(axis);
      return cross.IsSame(endNormal) ? 90 : -90;
 }
 public static double GetRotationAngle(Vector3D axis, Vector3D startNormal, Vector3D endNormal)
 {
     if (startNormal.IsSame(endNormal))
     return Direction.Zero;
      if (startNormal.IsSame(-endNormal))
     return Direction.Twice;
      var cross = startNormal.Cross(axis);
      return cross.IsSame(endNormal) ? Direction.Clockwise : Direction.CounterClockwise;
 }
 public Direction(Vector3D front, Vector3D up)
 {
     Origin = new Point3D(0, 0, 0);
      Front = front;
      Back = -Front;
      Up = up;
      Down = -Up;
      Right = up.Cross(front);
      Left = -Right;
      All = new[] { Front, Back, Right, Left, Up, Down };
 }
Beispiel #4
0
        /// <summary>
        /// The three points p0, p0 + u and p0 + v make up a triangle. If 'divisions' is 1 and 'doQuad' is false,<para/>
        /// exactly this triangle will be added to the mesh. If 'divisions' is larger than 1, the triangle will be subdivided.<para/>
        /// If 'doQuad' is true, the triangle is expanded to a parallelogram using the fourth point p0 + u + v.
        /// </summary>
        public static void AddTriangles(MeshGeometry3D mesh, int divisions, Point3D p0, Vector3D u, Vector3D v, double tu0, double tu1, bool doQuad = true)
        {
            TextureTransform tt = new TextureTransform(0, divisions, tu0, tu1, 1, 0);
            Vector3D du = u / (double)divisions;
            Vector3D dv = v / (double)divisions;
            Vector3D n = u.Cross(v);
            n.Normalize();

            for (int iv = 0; iv < divisions; iv++)
            {
                int iuMax = doQuad ? divisions : divisions - iv;
                for (int iu = 0; iu < iuMax; iu++)
                {
                    Point3D p1 = p0 + iu * du + iv * dv;
                    Point3D p2 = p1 + du;
                    Point3D p3 = p1 + dv;
                    Point3D p4 = p2 + dv;

                    mesh.Positions.Add(p1);
                    mesh.Normals.Add(n);
                    mesh.TextureCoordinates.Add(tt.Transform(iu, iv));

                    mesh.Positions.Add(p2);
                    mesh.Normals.Add(n);
                    mesh.TextureCoordinates.Add(tt.Transform(iu + 1, iv));

                    mesh.Positions.Add(p3);
                    mesh.Normals.Add(n);
                    mesh.TextureCoordinates.Add(tt.Transform(iu, iv + 1));

                    int i = mesh.Positions.Count - 3;
                    AddTriangleIndices(mesh, i, i + 1, i + 2);

                    bool doUpperTriangle = doQuad ? true : iu < iuMax - 1;
                    if (doUpperTriangle)
                    {
                        mesh.Positions.Add(p4);
                        mesh.Normals.Add(n);
                        mesh.TextureCoordinates.Add(tt.Transform(iu + 1, iv + 1));

                        AddTriangleIndices(mesh, i + 1, i + 3, i + 2);
                        continue;
                    }
                }
            }
        }
 public static Transform3D Rotate(Vector3D axis, Point3D point, Vector3D startNormal, Vector3D endNormal)
 {
     var angle = GetRotationAngle(axis, startNormal, endNormal);
      var cross = startNormal.Cross(axis);
      return Rotate(axis, point, angle);
 }
 public static Transform3D GetRotationTransform(Point3D point, Vector3D startNormal, Vector3D endNormal)
 {
     var axis = startNormal.Cross(endNormal);
      return GetRotationTransform(axis, point, startNormal, endNormal);
 }
Beispiel #7
0
        public static List<double> RayMeshIntersections(Point3D orig, Vector3D dir, MeshGeometry3D mesh, bool frontFacesOnly)
        {
            List<double> result = new List<double>();

            if (mesh == null || !dir.IsValid())
                return result;

            double epsilon = 1E-9;
            Int32Collection indices = mesh.TriangleIndices;
            Point3DCollection positions = mesh.Positions;

            for (int i = 0; i < indices.Count; i += 3)
            {
                Point3D vert0 = positions[indices[i]];
                Point3D vert1 = positions[indices[i + 1]];
                Point3D vert2 = positions[indices[i + 2]];

                //--- find vectors for two edges sharing vert0
                Vector3D edge1 = vert1 - vert0;
                Vector3D edge2 = vert2 - vert0;

                //--- begin calculating determinant  also used to calculate U parameter
                Vector3D pvec = dir.Cross(edge2);

                //--- if determinant is near zero ray lies in plane of triangle
                double det = edge1.Dot(pvec);
                if (det < epsilon)
                {
                    if (frontFacesOnly)
                        continue;

                    else if (det > -epsilon)
                        continue;
                }
                double inv_det = 1.0 / det;

                //--- calculate distance from vert0 to ray origin
                Vector3D tvec = orig - vert0;

                //--- calculate U parameter and test bounds
                double u = tvec.Dot(pvec) * inv_det;
                if (u < 0.0 || u > 1.0)
                    continue;

                //--- prepare to test V parameter
                Vector3D qvec = tvec.Cross(edge1);

                //--- calculate V parameter and test bounds
                double v = dir.Dot(qvec) * inv_det;
                if (v < 0.0 || u + v > 1.0)
                    continue;

                //--- calculate t scale parameters, ray intersects triangle
                double t = edge2.Dot(qvec) * inv_det;

                result.Add(t);
            }

            return result;
        }