Пример #1
0
        /// <summary>
        /// Returns the position of the tangent, in element's pixel space.
        /// </summary>
        /// <param name="keyFrame">Keyframe that the tangent belongs to.</param>
        /// <param name="type">Which tangent to retrieve the position for.</param>
        /// <returns>Position of the tangent, relative to the this GUI element's origin, in pixels.</returns>
        private Vector2I GetTangentPosition(KeyFrame keyFrame, TangentType type)
        {
            Vector2I position = CurveToPixelSpace(new Vector2(keyFrame.time, keyFrame.value));

            Vector2 normal;

            if (type == TangentType.In)
            {
                normal = -EdAnimationCurve.TangentToNormal(keyFrame.inTangent);
            }
            else
            {
                normal = EdAnimationCurve.TangentToNormal(keyFrame.outTangent);
            }

            // X/Y ranges aren't scaled 1:1, adjust normal accordingly
            normal.x /= GetRange();
            normal.y /= yRange;
            normal    = Vector2.Normalize(normal);

            // Convert normal (in percentage) to pixel values
            Vector2I offset = new Vector2I((int)(normal.x * TANGENT_LINE_DISTANCE),
                                           (int)(-normal.y * TANGENT_LINE_DISTANCE));

            return(position + offset);
        }
Пример #2
0
        /// <summary>
        /// Returns the tangents between the active CircularArc3d instance complete circle and another one.
        /// </summary>
        /// <remarks>
        /// Tangents start points are on the object to which this method applies, end points on the one passed as argument.
        /// Tangents are always returned in the same order: outer tangents before inner tangents, and for both,
        /// the tangent on the left side of the line from this circular arc center to the other one before the one on the right side. 
        /// </remarks>
        /// <param name="arc">The instance to which this method applies.</param>
        /// <param name="other">The CircularArc3d to which searched for tangents.</param>
        /// <param name="flags">An enum value specifying which type of tangent is returned.</param>
        /// <returns>An array of LineSegment3d representing the tangents (maybe 2 or 4) or null if there is none.</returns>
        /// <exception cref="Autodesk.AutoCAD.Runtime.Exception">
        /// eNonCoplanarGeometry is thrown if the objects do not lies on the same plane.</exception>
        public static LineSegment3d[] GetTangentsTo(this CircularArc3d arc, CircularArc3d other, TangentType flags)
        {
            // check if circles lies on the same plane
            Vector3d normal = arc.Normal;
            Matrix3d WCS2OCS = Matrix3d.WorldToPlane(normal);
            double elevation = arc.Center.TransformBy(WCS2OCS).Z;
            if (!(normal.IsParallelTo(other.Normal) &&
                Math.Abs(elevation - other.Center.TransformBy(WCS2OCS).Z) < Tolerance.Global.EqualPoint))
                throw new Autodesk.AutoCAD.Runtime.Exception(
                    Autodesk.AutoCAD.Runtime.ErrorStatus.NonCoplanarGeometry);

            Plane plane = new Plane(Point3d.Origin, normal);
            Matrix3d OCS2WCS = Matrix3d.PlaneToWorld(plane);
            CircularArc2d ca2d1 = new CircularArc2d(arc.Center.Convert2d(plane), arc.Radius);
            CircularArc2d ca2d2 = new CircularArc2d(other.Center.Convert2d(plane), other.Radius);
            LineSegment2d[] lines2d = ca2d1.GetTangentsTo(ca2d2, flags);

            if (lines2d == null)
                return null;

            LineSegment3d[] result = new LineSegment3d[lines2d.Length];
            for (int i = 0; i < lines2d.Length; i++)
            {
                LineSegment2d ls2d = lines2d[i];
                result[i] = new LineSegment3d(ls2d.StartPoint.Convert3d(normal, elevation), ls2d.EndPoint.Convert3d(normal, elevation));
            }
            return result;
        }
Пример #3
0
        public override void Read(BinaryStream bs)
        {
            BinaryReader Read = bs.Read;

            Magic        = Read.String(5);
            Version      = Read.UShort();
            MeshUsage    = Read.Byte();
            Bounds       = Read.Type <Box3>();
            TangentType  = (TangentType)Read.Byte();
            TangentSplit = (Read.Byte() == 1);

            Vertices = bs.Read.TypeList <Vector3>(Read.Int());

            if (Read.Int() != 0)
            {
                throw new Exception("uh oh, this mesh has vertex lod positions");
            }

            Normals      = Read.TypeList <Normal>(Read.Int());
            TextureUVs   = Read.TypeList <UV>(Read.Int());
            NormalUVs    = Read.TypeList <UV>(Read.Int());
            Tangents     = Read.TypeList <Tangent>(Read.Int());
            VertexColors = Read.UIntList(Read.Int());
            FaceIndex    = Read.UIntList(Read.Int());
            Faces        = Read.TypeList <Face>(Read.Int());
            Bones        = Read.TypeList <Bone>(Read.Int());
            Links        = Read.TypeList <Link>(Read.Int());
            BoneWeights  = Read.TypeList <BoneWeight>(Read.Int());
            Hardpoints   = Read.TypeList <Hardpoint>(Read.Int());

            int referenceMeshFileNameLength = Read.Int();

            if (referenceMeshFileNameLength > 0)
            {
                ReferenceMeshFileName = Read.String();
            }

            ReferenceMeshFileTime = Read.ULong();
            ReferenceMeshType     = (MeshType)Read.Byte();

            BaseVariantDiffs = Read.TypeList <BaseVariantDiff>(Read.Int());
            ConformWeights   = Read.TypeList <ConformWeight>(Read.Int());
            MaterialSections = Read.TypeList <MaterialSection>(Read.Int());

            Console.WriteLine(Hardpoints.Count);
        }
Пример #4
0
        /// <summary>
        /// Checks if the tangent should be displayed, depending on the active tangent mode.
        /// </summary>
        /// <param name="mode">Tangent mode for the keyframe.</param>
        /// <param name="type">Which tangent to check for.</param>
        /// <returns>True if the tangent should be displayed.</returns>
        private bool IsTangentDisplayed(TangentMode mode, TangentType type)
        {
            if (mode == TangentMode.Auto)
            {
                return(false);
            }
            else if (mode == TangentMode.Free)
            {
                return(true);
            }

            if (type == TangentType.In)
            {
                return(mode.HasFlag(TangentMode.InFree));
            }
            else
            {
                return(mode.HasFlag(TangentMode.OutFree));
            }
        }
Пример #5
0
        /// <summary>
        /// Returns the tangents between the active CircularArc3d instance complete circle and another one.
        /// </summary>
        /// <remarks>
        /// Tangents start points are on the object to which this method applies, end points on the one passed as argument.
        /// Tangents are always returned in the same order: outer tangents before inner tangents, and for both,
        /// the tangent on the left side of the line from this circular arc center to the other one before the one on the right side.
        /// </remarks>
        /// <param name="arc">The instance to which this method applies.</param>
        /// <param name="other">The CircularArc3d to which searched for tangents.</param>
        /// <param name="flags">An enum value specifying which type of tangent is returned.</param>
        /// <returns>An array of LineSegment3d representing the tangents (maybe 2 or 4) or null if there is none.</returns>
        /// <exception cref="Autodesk.AutoCAD.Runtime.Exception">
        /// eNonCoplanarGeometry is thrown if the objects do not lies on the same plane.</exception>
        public static LineSegment3d[]? GetTangentsTo(
            [NotNull] this CircularArc3d arc,
            [NotNull] CircularArc3d other,
            TangentType flags)
        {
            // check if circles lies on the same plane
            var normal    = arc.Normal;
            var WCS2OCS   = Matrix3d.WorldToPlane(normal);
            var elevation = arc.Center.TransformBy(WCS2OCS).Z;

            if (!(normal.IsParallelTo(other.Normal) &&
                  Math.Abs(elevation - other.Center.TransformBy(WCS2OCS).Z) < Tolerance.Global.EqualPoint))
            {
                throw new Autodesk.AutoCAD.Runtime.Exception(
                          Autodesk.AutoCAD.Runtime.ErrorStatus.NonCoplanarGeometry);
            }

            var plane   = new Plane(Point3d.Origin, normal);
            var ca2d1   = new CircularArc2d(arc.Center.Convert2d(plane), arc.Radius);
            var ca2d2   = new CircularArc2d(other.Center.Convert2d(plane), other.Radius);
            var lines2d = ca2d1.GetTangentsTo(ca2d2, flags);

            if (lines2d == null)
            {
                return(null);
            }

            var result = new LineSegment3d[lines2d.Length];

            for (var i = 0; i < lines2d.Length; i++)
            {
                var ls2d = lines2d[i];
                result[i] = new LineSegment3d(ls2d.StartPoint.Convert3d(normal, elevation),
                                              ls2d.EndPoint.Convert3d(normal, elevation));
            }

            return(result);
        }
Пример #6
0
 public TangentRef(KeyframeRef keyframeRef, TangentType type)
 {
     this.keyframeRef = keyframeRef;
     this.type        = type;
 }
Пример #7
0
        public static LineSegment2d[] GetTangentsTo(
            [NotNull] this CircularArc2d arc,
            [NotNull] CircularArc2d other,
            TangentType flags)
        {
            // check if a circle is inside the other
            var dist = arc.Center.GetDistanceTo(other.Center);

            if (dist - Math.Abs(arc.Radius - other.Radius) <= Tolerance.Global.EqualPoint)
            {
                return(null);
            }

            // check if circles overlap
            var overlap = arc.Radius + other.Radius >= dist;

            if (overlap && flags == TangentType.Inner)
            {
                return(null);
            }

            CircularArc2d tmp1;

            Point2d[] inters;
            Vector2d  vec1, vec2, vec = other.Center - arc.Center;
            int       i, j;
            var       result = new LineSegment2d[(int)flags == 3 && !overlap ? 4 : 2];

            // outer tangents
            if ((flags & TangentType.Outer) > 0)
            {
                if (Math.Abs(arc.Radius - other.Radius) < 0.001)
                {
                    var perp = new Line2d(arc.Center, vec.GetPerpendicularVector());
                    inters = arc.IntersectWith(perp);
                    if (inters == null)
                    {
                        return(null);
                    }
                    vec1      = (inters[0] - arc.Center).GetNormal();
                    i         = vec.X * vec1.Y - vec.Y - vec1.X > 0 ? 0 : 1;
                    j         = i ^ 1;
                    result[i] = new LineSegment2d(inters[0], inters[0] + vec);
                    result[j] = new LineSegment2d(inters[1], inters[1] + vec);
                }
                else
                {
                    var center = arc.Radius < other.Radius ? other.Center : arc.Center;
                    tmp1 = new CircularArc2d(center, Math.Abs(arc.Radius - other.Radius));
                    var tmp2 = new CircularArc2d(arc.Center + vec / 2.0, dist / 2.0);
                    inters = tmp1.IntersectWith(tmp2);
                    if (inters == null)
                    {
                        return(null);
                    }
                    vec1      = (inters[0] - center).GetNormal();
                    vec2      = (inters[1] - center).GetNormal();
                    i         = vec.X * vec1.Y - vec.Y - vec1.X > 0 ? 0 : 1;
                    j         = i ^ 1;
                    result[i] = new LineSegment2d(arc.Center + vec1 * arc.Radius, other.Center + vec1 * other.Radius);
                    result[j] = new LineSegment2d(arc.Center + vec2 * arc.Radius, other.Center + vec2 * other.Radius);
                }
            }

            // inner tangents
            if ((flags & TangentType.Inner) > 0 && !overlap)
            {
                var ratio = arc.Radius / (arc.Radius + other.Radius) / 2.0;
                tmp1   = new CircularArc2d(arc.Center + vec * ratio, dist * ratio);
                inters = arc.IntersectWith(tmp1);
                if (inters == null)
                {
                    return(null);
                }
                vec1      = (inters[0] - arc.Center).GetNormal();
                vec2      = (inters[1] - arc.Center).GetNormal();
                i         = vec.X * vec1.Y - vec.Y - vec1.X > 0 ? 2 : 3;
                j         = i == 2 ? 3 : 2;
                result[i] = new LineSegment2d(arc.Center + vec1 * arc.Radius, other.Center + vec1.Negate() * other.Radius);
                result[j] = new LineSegment2d(arc.Center + vec2 * arc.Radius, other.Center + vec2.Negate() * other.Radius);
            }

            return(result);
        }
Пример #8
0
        /// <summary>
        /// Returns the tangents between the active CircularArc2d instance complete circle and another one.
        /// </summary>
        /// <remarks>
        /// Tangents start points are on the object to which this method applies, end points on the one passed as argument.
        /// Tangents are always returned in the same order: outer tangents before inner tangents, and for both,
        /// the tangent on the left side of the line from this circular arc center to the other one before the other one.
        /// </remarks>
        /// <param name="arc">The instance to which this method applies.</param>
        /// <param name="other">The CircularArc2d to which searched for tangents.</param>
        /// <param name="flags">An enum value specifying which type of tangent is returned.</param>
        /// <returns>An array of LineSegment2d representing the tangents (maybe 2 or 4) or null if there is none.</returns>
        public static LineSegment2d[] GetTangentsTo(this CircularArc2d arc, CircularArc2d other, TangentType flags)
        {
            // check if a circle is inside the other
            double dist = arc.Center.GetDistanceTo(other.Center);
            if (dist - Math.Abs(arc.Radius - other.Radius) <= Tolerance.Global.EqualPoint)
                return null;

            // check if circles overlap
            bool overlap = arc.Radius + other.Radius >= dist;
            if (overlap && flags == TangentType.Inner)
                return null;

            CircularArc2d tmp1, tmp2;
            Point2d[] inters;
            Vector2d vec1, vec2, vec = other.Center - arc.Center;
            int i, j;
            LineSegment2d[] result = new LineSegment2d[(int)flags == 3 && !overlap ? 4 : 2];

            // outer tangents
            if ((flags & TangentType.Outer) > 0)
            {
                if (arc.Radius == other.Radius)
                {
                    Line2d perp = new Line2d(arc.Center, vec.GetPerpendicularVector());
                    inters = arc.IntersectWith(perp);
                    if (inters == null)
                        return null;
                    vec1 = (inters[0] - arc.Center).GetNormal();
                    vec2 = (inters[1] - arc.Center).GetNormal();
                    i = vec.X * vec1.Y - vec.Y - vec1.X > 0 ? 0 : 1;
                    j = i ^ 1;
                    result[i] = new LineSegment2d(inters[0], inters[0] + vec);
                    result[j] = new LineSegment2d(inters[1], inters[1] + vec);
                }
                else
                {
                    Point2d center = arc.Radius < other.Radius ? other.Center : arc.Center;
                    tmp1 = new CircularArc2d(center, Math.Abs(arc.Radius - other.Radius));
                    tmp2 = new CircularArc2d(arc.Center + vec / 2.0, dist / 2.0);
                    inters = tmp1.IntersectWith(tmp2);
                    if (inters == null)
                        return null;
                    vec1 = (inters[0] - center).GetNormal();
                    vec2 = (inters[1] - center).GetNormal();
                    i = vec.X * vec1.Y - vec.Y - vec1.X > 0 ? 0 : 1;
                    j = i ^ 1;
                    result[i] = new LineSegment2d(arc.Center + vec1 * arc.Radius, other.Center + vec1 * other.Radius);
                    result[j] = new LineSegment2d(arc.Center + vec2 * arc.Radius, other.Center + vec2 * other.Radius);
                }
            }

            // inner tangents
            if ((flags & TangentType.Inner) > 0 && !overlap)
            {
                double ratio = (arc.Radius / (arc.Radius + other.Radius)) / 2.0;
                tmp1 = new CircularArc2d(arc.Center + vec * ratio, dist * ratio);
                inters = arc.IntersectWith(tmp1);
                if (inters == null)
                    return null;
                vec1 = (inters[0] - arc.Center).GetNormal();
                vec2 = (inters[1] - arc.Center).GetNormal();
                i = vec.X * vec1.Y - vec.Y - vec1.X > 0 ? 2 : 3;
                j = i == 2 ? 3 : 2;
                result[i] = new LineSegment2d(arc.Center + vec1 * arc.Radius, other.Center + vec1.Negate() * other.Radius);
                result[j] = new LineSegment2d(arc.Center + vec2 * arc.Radius, other.Center + vec2.Negate() * other.Radius);
            }
            return result;
        }
Пример #9
0
        /// <summary>
        ///     Returns the tangents between the active CircularArc3d instance complete circle and another one.
        /// </summary>
        /// <remarks>
        ///     Tangents start points are on the object to which this method applies, end points on the one passed as argument.
        ///     Tangents are always returned in the same order: outer tangents before inner tangents, and for both,
        ///     the tangent on the left side of the line from this circular arc center to the other one before the one on the right
        ///     side.
        /// </remarks>
        /// <param name="arc">The instance to which this method applies.</param>
        /// <param name="other">The CircularArc3d to which searched for tangents.</param>
        /// <param name="flags">An enum value specifying which type of tangent is returned.</param>
        /// <returns>An array of LineSegment3d representing the tangents (maybe 2 or 4) or null if there is none.</returns>
        /// <exception cref="Autodesk.AutoCAD.Runtime.Exception">
        ///     eNonCoplanarGeometry is thrown if the objects do not lies on the same plane.
        /// </exception>
        public static LineSegment3d[] GetTangentsTo(this CircularArc3d arc, CircularArc3d other, TangentType flags)
        {
            // check if circles lies on the same plane
            var normal    = arc.Normal;
            var wcs2Ocs   = Matrix3d.WorldToPlane(normal);
            var elevation = arc.Center.TransformBy(wcs2Ocs).Z;

            if (!(normal.IsParallelTo(other.Normal) &&
                  Math.Abs(elevation - other.Center.TransformBy(wcs2Ocs).Z) < Tolerance.Global.EqualPoint))
            {
                throw new Exception(
                          ErrorStatus.NonCoplanarGeometry);
            }

            var plane = new Plane(Point3d.Origin, normal);

            _ = Matrix3d.PlaneToWorld(plane);
            var ca2D1   = new CircularArc2d(arc.Center.Convert2d(plane), arc.Radius);
            var ca2D2   = new CircularArc2d(other.Center.Convert2d(plane), other.Radius);
            var lines2D = ca2D1.GetTangentsTo(ca2D2, flags);

            if (lines2D == null)
            {
                return(null);
            }

            var result = new LineSegment3d[lines2D.Length];

            for (var i = 0; i < lines2D.Length; i++)
            {
                var ls2D = lines2D[i];
                result[i] = new LineSegment3d(ls2D.StartPoint.Convert3D(normal, elevation),
                                              ls2D.EndPoint.Convert3D(normal, elevation));
            }

            return(result);
        }
Пример #10
0
        /// <summary>
        /// Checks if the tangent should be displayed, depending on the active tangent mode.
        /// </summary>
        /// <param name="mode">Tangent mode for the keyframe.</param>
        /// <param name="type">Which tangent to check for.</param>
        /// <returns>True if the tangent should be displayed.</returns>
        private bool IsTangentDisplayed(TangentMode mode, TangentType type)
        {
            if (mode == TangentMode.Auto)
                return false;
            else if (mode == TangentMode.Free)
                return true;

            if (type == TangentType.In)
                return mode.HasFlag(TangentMode.InFree);
            else
                return mode.HasFlag(TangentMode.OutFree);
        }
Пример #11
0
        /// <summary>
        /// Returns the position of the tangent, in element's pixel space.
        /// </summary>
        /// <param name="keyFrame">Keyframe that the tangent belongs to.</param>
        /// <param name="type">Which tangent to retrieve the position for.</param>
        /// <returns>Position of the tangent, relative to the this GUI element's origin, in pixels.</returns>
        private Vector2I GetTangentPosition(KeyFrame keyFrame, TangentType type)
        {
            Vector2I position = CurveToPixelSpace(new Vector2(keyFrame.time, keyFrame.value));

            Vector2 normal;
            if (type == TangentType.In)
                normal = -EdAnimationCurve.TangentToNormal(keyFrame.inTangent);
            else
                normal = EdAnimationCurve.TangentToNormal(keyFrame.outTangent);

            // X/Y ranges aren't scaled 1:1, adjust normal accordingly
            normal.x /= GetRange();
            normal.y /= yRange;
            normal = Vector2.Normalize(normal);

            // Convert normal (in percentage) to pixel values
            Vector2I offset = new Vector2I((int)(normal.x * TANGENT_LINE_DISTANCE),
                    (int)(-normal.y * TANGENT_LINE_DISTANCE));

            return position + offset;
        }