Example #1
0
 private static Transform GetMovieButtonTransform(int index, AaRectangle2 rect)
 {
     return(new Transform(ButtonHalfHeight, Quaternion.Identity, new Vector3(
                              rect.MinX + ButtonHalfHeight +
                              ((int)index) * ((rect.Width - 2 * ButtonHalfWidth) / (AllMovieButtons.Length - 1)),
                              rect.MinY - ButtonHalfHeight, 0)));
 }
        protected StoryFlowchartNodeGizmoComponent(IEmbeddedResources embeddedResources, IViewService viewService)
        {
            this.viewService = viewService;

            GlobalRectangle = new AaRectangle2(Vector2.Zero, 1, 1);

            var squareModel = embeddedResources.SimplePlaneXyModel();

            var material = StandardMaterial.New(this)
                           .SetDiffuseColor(x => x.DiffuseColorToUse())
                           .SetDiffuseMap(x => x.DiffuseMapToUse())
                           .SetIgnoreLighting(true)
                           .SetHighlightEffect(x =>
                                               x.viewService.SelectedNode == ReferencedNode ? HighlightEffect.RainbowBorder :
                                               x.viewService.ClosestStoryNode == ReferencedNode ? HighlightEffect.Pulsating :
                                               HighlightEffect.None);

            visualElement = new ModelVisualElement <StoryFlowchartNodeGizmoComponent>(this)
                            .SetModel(squareModel)
                            .SetMaterial(material)
                            .SetTransform(x => Transform.Translation(new Vector3(x.GlobalRectangle.Center, x.Depth * 0.1f)))
                            .SetNonUniformScale(x => new Vector3(x.GlobalRectangle.HalfWidth, -/*todo: correct text-coords*/ x.GlobalRectangle.HalfHeight, 1));

            hittable = new RectangleHittable <StoryFlowchartNodeGizmoComponent>(this,
                                                                                Transform.Identity,
                                                                                x => new AaRectangle2(Vector2.Zero, x.GlobalRectangle.HalfWidth, x.GlobalRectangle.HalfHeight),
                                                                                x => - x.Depth);
        }
 public DragRectangleInputLock(IUndoRedoService undoRedo, IRectangleComponent nodeRectAspect, IPlacementSurface space, Vector2 anchorPointOnRect)
 {
     this.undoRedo          = undoRedo;
     this.nodeRectAspect    = nodeRectAspect;
     this.space             = space;
     this.anchorPointOnRect = anchorPointOnRect;
     originalRect           = nodeRectAspect.Rectangle;
 }
 public PolylineCirclePackingBorder(IEnumerable <Vector2> rawPoints, float circleRadius)
 {
     points            = Normalize(rawPoints);
     this.circleRadius = circleRadius;
     circleRadiusSq    = circleRadius.Sq();
     BoundingRect      = AaRectangle2.BoundingRect(points);
     Area = CalculateArea(points);
 }
 public ResizeRectangleInputLock(IRectangleComponent nodeRectAspect, IUndoRedoService undoRedo, IPlacementSurface space, ResizeRectangleGizmoPlace place)
 {
     this.nodeRectAspect = nodeRectAspect;
     this.undoRedo       = undoRedo;
     this.space          = space;
     this.place          = place;
     originalRect        = nodeRectAspect.Rectangle;
 }
Example #6
0
        public CirclePackingCircleGrid(float circleRadius, AaRectangle2 boundingRect)
        {
            cellSize = CellSizeInRadii * circleRadius;
            var gridWidth  = (int)MathHelper.Ceiling(boundingRect.Width / cellSize);
            var gridHeight = (int)MathHelper.Ceiling(boundingRect.Height / cellSize);

            gridSize         = new IntSize2(gridWidth, gridHeight);
            cellCircleCounts = new int[gridSize.Area];
            circleIndices    = new int[gridSize.Area * MaxCirclesPerCell];
            minCorner        = boundingRect.MinMin;
        }
Example #7
0
        private AaRectangle2 CalculateButtonPanelRectangle()
        {
            var buttonPanelWidth = AllMovieButtons.Length * 2 * ButtonHalfWidth +
                                   (AllMovieButtons.Length - 1) * ButtonHorizontalMargin;
            var buttonPanelLeftX   = Rectangle.Center.X - buttonPanelWidth / 2;
            var buttonPanelBottomY = Rectangle.MinY - (ButtonHalfHeight * 2);
            var buttonPanelRect    =
                AaRectangle2.FromCornerAndDimensions(buttonPanelLeftX, buttonPanelBottomY, buttonPanelWidth, ButtonHalfHeight * 2);

            return(buttonPanelRect);
        }
Example #8
0
        private void AdjustRectangleAndSetCurve()
        {
            var entityRect        = rectangleAspect.Rectangle;
            var layoutBasedPoints = curve
                                    .Select(xy => entityRect.Center + new Vector2(xy.X * entityRect.HalfWidth, xy.Y * entityRect.HalfHeight))
                                    .ToArray();
            float minX = float.MaxValue;
            float minY = float.MaxValue;
            float maxX = float.MinValue;
            float maxY = float.MinValue;

            foreach (var point in layoutBasedPoints)
            {
                if (point.X < minX)
                {
                    minX = point.X;
                }
                if (point.X > maxX)
                {
                    maxX = point.X;
                }
                if (point.Y < minY)
                {
                    minY = point.Y;
                }
                if (point.Y > maxY)
                {
                    maxY = point.Y;
                }
            }
            var newRect       = new AaRectangle2(new Vector2(minX, minY), new Vector2(maxX, maxY));
            var adjustedCurve = layoutBasedPoints.Select(xy =>
            {
                var result = xy - newRect.Center;
                result.X  /= newRect.HalfWidth;
                result.Y  /= newRect.HalfHeight;
                return(result);
            }).ToArray();

            rectangleAspect.Rectangle        = newRect;
            richTextAspect.BorderCurve       = adjustedCurve;
            richTextAspect.VisualBorderCurve = adjustedCurve;
            undoRedo.OnChange();
        }
Example #9
0
        private static IEnumerable <Vector2> GenerateHoneycomb(AaRectangle2 boundingRect, float circleRadius)
        {
            var doubleRadius = 2 * circleRadius;
            var minIndexX    = (int)(boundingRect.MinX / doubleRadius) - 2;
            var maxIndexX    = (int)(boundingRect.MaxX / doubleRadius) + 2;
            var minIndexY    = (int)(boundingRect.MinY / doubleRadius) - 2;
            var maxIndexY    = (int)(boundingRect.MaxY / doubleRadius) + 2;
            var h            = doubleRadius * MathHelper.Cos(MathHelper.Pi / 6);

            for (var j = minIndexY; j <= maxIndexY; j++)
            {
                var zeroCircleCenter = j % 2 == 0
                    ? new Vector2(0, h * j)
                    : new Vector2(circleRadius, h * j);
                for (var i = minIndexX; i <= maxIndexX; i++)
                {
                    yield return(zeroCircleCenter + new Vector2(i * doubleRadius, 0));
                }
            }
        }
Example #10
0
        private void FlushStrip(BuildingContext context, int paragraphIndex, float tabOffset, SubList <Subspan> subspans, bool isFirstStrip, bool isLastStrip)
        {
            // todo: consider direction
            var paragraph = context.Text.Paragraphs[paragraphIndex];
            //if (!isLastStrip)
            //    subspans = TrimEnd(subspans);
            var commonSize = MeasureSubspans(context, subspans);
            var stripSize  = new Size2(context.RemainingShape.Width, commonSize.Height);

            if (paragraph.Style.Alignment != RtParagraphAlignment.Justify || isLastStrip)
            {
                // todo: tabs
                var mergedSubspans = MergeSubspans(subspans);
                var newRectangles  = new RichTextBoxLayoutSpan[mergedSubspans.Count];
                var strip          = AaRectangle2.FromCornerAndDimensions(
                    context.StripStartPoint.X, context.StripStartPoint.Y,
                    commonSize.Width, commonSize.Height);
                var rectOffsetX = context.StripStartPoint.X + tabOffset;
                var charIndex   = 0;

                for (var i = 0; i < mergedSubspans.Count; i++)
                {
                    var subspan     = mergedSubspans[i];
                    var subspanSize = MeasureSubspan(subspan);

                    var charWidths = subspan.Text.Select(x => measurer.GetCharSize(x, subspan.Style).Width).ToArray();
                    var subspanWidthWithoutKerning = charWidths.Sum();
                    var kerningAdjustment          = subspanSize.Width / subspanWidthWithoutKerning;
                    var adjustedCharWidths         = charWidths.Select(x => x * kerningAdjustment).ToArray();
                    var charOffsets = Enumerable.Range(0, subspan.Text.Length).Select(x => adjustedCharWidths.Take(x).Sum()).ToArray();

                    newRectangles[i] = new RichTextBoxLayoutSpan
                    {
                        TextRelPosition = subspan.TextRelPosition,
                        TextAbsPosition = context.Text.GetGlobalIndex(subspan.TextRelPosition),
                        Bounds          = new AaRectangle2(
                            new Vector2(rectOffsetX, context.StripStartPoint.Y),
                            new Vector2(rectOffsetX + subspanSize.Width, context.StripStartPoint.Y + commonSize.Height)),
                        Strip            = strip,
                        CharOffsets      = charOffsets,
                        Text             = subspan.Text,
                        Style            = subspan.Style,
                        Embedding        = subspan.Embedding,
                        EmbeddingHandler = subspan.EmbeddingHandler,
                        EmbeddingImage   = subspan.EmbeddingImage
                    };

                    rectOffsetX += subspanSize.Width;
                    charIndex   += subspan.Text.Length;
                }

                var adjustment = 0f;
                switch (paragraph.Style.Alignment)
                {
                case RtParagraphAlignment.Left:
                    break;

                case RtParagraphAlignment.Center:
                    var leftCenterX = rectOffsetX / 2;
                    var stripCenter = stripSize.Width / 2;
                    adjustment = stripCenter - leftCenterX;
                    break;

                case RtParagraphAlignment.Right:
                    adjustment = stripSize.Width - rectOffsetX;
                    break;

                case RtParagraphAlignment.Justify:
                default:
                    throw new ArgumentOutOfRangeException();
                }
                for (var i = 0; i < newRectangles.Length; i++)
                {
                    newRectangles[i].Bounds.Center.X += adjustment;
                }
                context.LayoutSpans.AddRange(newRectangles);
                context.RemainingShape = new AaRectangle2(context.RemainingShape.MinMin + Vector2.UnitY * stripSize.Height,
                                                          context.RemainingShape.MaxMax);

                if (isFirstStrip)
                {
                    // todo: adjust for other directions
                    var bulletStr = paragraph.Style.ListStyle.GetIconFor(paragraph.Style.TabCount, /*todo*/ 0);
                    FlushBullet(context, new Vector2(tabOffset, strip.MaxY), bulletStr, subspans.First().Style);
                }
            }
            else
            {
                throw new NotImplementedException();
            }
        }
Example #11
0
        private void ArrangeAndDecorateRoot(IStoryGraph sg, int nodeIndex)
        {
            var cStory      = sg.Aspects[nodeIndex];
            var node        = sg.NodeObjects[nodeIndex];
            var children    = sg.Children[nodeIndex];
            var numChildren = children.Count;

            if (numChildren < 2)
            {
                var viewpointProps = new TargetedControlledCameraY.Props
                {
                    Target      = Vector3.Zero,
                    Distance    = MathHelper.FrustumDistance,
                    FieldOfView = MathHelper.PiOver4,
                    ZNear       = 0.1f,
                    ZFar        = 100.0f
                };

                cStory.SetDynamicParts(new StoryNodeDynamicParts
                {
                    DefaultViewpointMechanism = new WallDefaultViewpointMechanism(node, viewpointProps),
                    Hittable       = new DummyHittable(),
                    VisualElements = new IVisualElement[0]
                });

                foreach (var child in children)
                {
                    ArrangeAndDecorateRoot(sg, child);
                }
            }
            else
            {
                var distr  = CalculateDistribution(numChildren);
                var radius = distr.RelativeRadius;

                var oneMore = children.SelectMany(x => sg.Children[x]).Any();

                for (int i = 0; i < numChildren; i++)
                {
                    var pitch = distr.Angles[i].Pitch;
                    var yaw   = distr.Angles[i].Yaw;

                    if (oneMore)
                    {
                        //var internalRadius = radius / 2;
                        ArrangeAndDecorateRoot(sg, children[i]);

                        //var yaw = yawPitchBounds.Center.X;
                        //var pitch = yawPitchBounds.Center.Y;
                        var pos      = ToCartesian(yaw, pitch, radius * 20);
                        var zAxis    = (-pos).Normalize();
                        var xAxis    = Vector3.Cross(Vector3.UnitY, zAxis).Normalize();
                        var yAxis    = Vector3.Cross(zAxis, xAxis);
                        var rotation = Quaternion.RotationToFrame(xAxis, yAxis);
                        sg.NodeObjects[children[i]].Transform = new Transform(1, rotation, pos);

                        //ArrangeAndDecorateInternal(sg, children[i],
                        //    AaRectangle2.FromCenter(new Vector2(yaw, pitch), HalfWidth / radius, HalfHeight / radius),
                        //    radius);
                    }
                    else
                    {
                        ArrangeAndDecorateInternal(sg, children[i],
                                                   AaRectangle2.FromCenter(new Vector2(yaw, pitch), HalfWidth / radius, HalfHeight / radius),
                                                   radius);
                    }
                }

                var viewpointProps = new LookAroundCamera.Props
                {
                    Distance    = distr.RelativeRadius,
                    FieldOfView = 0.75f * MathHelper.Pi,
                    ZNear       = 0.1f,
                    ZFar        = 100.0f,
                    Pitch       = 0//MathHelper.PiOver2 + 0.1f
                };

                cStory.SetDynamicParts(new StoryNodeDynamicParts
                {
                    DefaultViewpointMechanism = new SphereDefaultViewpointMechanism(node, viewpointProps),
                    Hittable       = new DummyHittable(),
                    VisualElements = new IVisualElement[0]
                });
            }
        }
Example #12
0
        private void ArrangeAndDecorateInternal(IStoryGraph sg, int nodeId, AaRectangle2 yawPitchBounds, float radius)
        {
            var cStory      = sg.Aspects[nodeId];
            var node        = sg.NodeObjects[nodeId];
            var children    = sg.Children[nodeId];
            var numChildren = children.Count;

            var yaw      = yawPitchBounds.Center.X;
            var pitch    = yawPitchBounds.Center.Y;
            var pos      = ToCartesian(yaw, pitch, radius);
            var zAxis    = (-pos).Normalize();
            var xAxis    = Vector3.Cross(Vector3.UnitY, zAxis).Normalize();
            var yAxis    = Vector3.Cross(zAxis, xAxis);
            var rotation = Quaternion.RotationToFrame(xAxis, yAxis);

            node.Transform = new Transform(1, rotation, pos);

            var numRows             = (int)Math.Ceiling(MathHelper.Sqrt(numChildren));
            var numCols             = (int)Math.Ceiling((float)numChildren / numRows);
            var totalHeightRequired = MinVerticalDistance * numRows;
            var totalWidthRequired  = MinHorizontalDistance * numRows;
            var minChildrenRadius   = Math.Max(totalWidthRequired / yawPitchBounds.Width, totalHeightRequired / yawPitchBounds.Height);
            var childRadius         = Math.Max(radius + MinRadiusDistance, minChildrenRadius);

            for (var i = 0; i < numChildren; i++)
            {
                var child               = children[i];
                var row                 = i / numCols;
                var col                 = i % numCols;
                var childYawWidth       = yawPitchBounds.Width / numCols;
                var childYawHeight      = yawPitchBounds.Height / numRows;
                var childYaw            = yawPitchBounds.MinX + childYawWidth * (row + 0.5f);
                var childPitch          = yawPitchBounds.MinY + childYawHeight * (col * 0.5f);
                var childYawPitchBounds = AaRectangle2.FromCenter(new Vector2(childYaw, childPitch), HalfWidth / childRadius, HalfHeight / childRadius);
                ArrangeAndDecorateInternal(sg, child, childYawPitchBounds, childRadius);
            }

            var visuals = new []
            {
                ModelVisualElement.New(sg.Aspects[sg.Root])
                .SetModel(frustumModel)
                .SetMaterial(frustumMaterial)
                .SetTransform(new Transform(0.5f, Quaternion.Identity, new Vector3(0, 0, 0.5f * MathHelper.FrustumDistance)))
                .SetHide(x => !x.ShowAux1)
            };

            var viewpointProps = new TargetedControlledCameraY.Props
            {
                Target      = Vector3.Zero,
                Distance    = MathHelper.FrustumDistance,
                FieldOfView = MathHelper.PiOver4,
                ZNear       = 0.1f,
                ZFar        = 100.0f
            };

            var transform2D = new Transform(2, Quaternion.Identity, -MathHelper.FrustumDistance * Vector3.UnitZ);

            cStory.SetDynamicParts(new StoryNodeDynamicParts
            {
                DefaultViewpointMechanism = new WallDefaultViewpointMechanism(node, viewpointProps),
                Hittable           = GetHittableComponent(node, transform2D),
                VisualElements     = visuals,
                PlacementSurface2D = new PlanarPlacementSurface(node, Transform.Identity),
                PlacementSurface3D = new PlanarPlacementSurface(node, new Transform(0.05f, Quaternion.Identity, new Vector3(0, 0, 0.5f * MathHelper.FrustumDistance)))
            });
        }
        private static void GetExternalPart(LineSegment3 segment, BuildingPrimitive primitive, List <LineSegment3> results)
        {
            var invTransform   = primitive.Transform.Invert();
            var transformedSeg = new LineSegment3(segment.Point1 * invTransform, segment.Point2 * invTransform);
            var seg            = new LineSegment2(transformedSeg.Point1.Xz, transformedSeg.Point2.Xz);

            if (primitive.Type == BuildingPrimitiveType.Rectangle)
            {
                var rect     = new AaRectangle2(Vector2.Zero, primitive.Scale.X, primitive.Scale.Z);
                var conains1 = rect.ContainsPoint(seg.Point1);
                var conains2 = rect.ContainsPoint(seg.Point2);
                if (conains1 && conains2)
                {
                    return;
                }
                if (!conains1 && !conains2)
                {
                    var p = Vector2.Zero;
                    int c = 0;
                    foreach (var rectSegment in rect.GetSegments())
                    {
                        var rsi = rectSegment.Intersect(seg);
                        if (rsi.HasValue)
                        {
                            p += rsi.Value;
                            c++;
                        }
                    }

                    if (c > 0)
                    {
                        var t = ((p / c) - seg.Point1).Length() / (seg.Point2 - seg.Point1).Length();
                        var m = segment.Point1 + (segment.Point2 - segment.Point1) * t;
                        GetExternalPart(new LineSegment3(segment.Point1, m), primitive, results);
                        GetExternalPart(new LineSegment3(m, segment.Point2), primitive, results);
                        return;
                    }

                    results.Add(segment);
                    return;
                }

                var swap = conains1;
                if (swap)
                {
                    CodingHelper.Swap(ref seg.Point1, ref seg.Point2);
                }
                var inter = seg.Intersect(new LineSegment2(
                                              new Vector2(-primitive.Scale.X, -primitive.Scale.Z),
                                              new Vector2(-primitive.Scale.X, primitive.Scale.Z)));
                if (inter.HasValue)
                {
                    var rs1 = To3(seg.Point1, inter.Value, primitive.Transform, swap);
                    results.Add(rs1);
                    return;
                }
                inter = seg.Intersect(new LineSegment2(
                                          new Vector2(primitive.Scale.X, -primitive.Scale.Z),
                                          new Vector2(primitive.Scale.X, primitive.Scale.Z)));
                if (inter.HasValue)
                {
                    var rs1 = To3(seg.Point1, inter.Value, primitive.Transform, swap);
                    results.Add(rs1);
                    return;
                }
                inter = seg.Intersect(new LineSegment2(
                                          new Vector2(-primitive.Scale.X, primitive.Scale.Z),
                                          new Vector2(primitive.Scale.X, primitive.Scale.Z)));
                if (inter.HasValue)
                {
                    var rs1 = To3(seg.Point1, inter.Value, primitive.Transform, swap);
                    results.Add(rs1);
                    return;
                }
                inter = seg.Intersect(new LineSegment2(
                                          new Vector2(-primitive.Scale.X, -primitive.Scale.Z),
                                          new Vector2(primitive.Scale.X, -primitive.Scale.Z)));
                if (inter.HasValue)
                {
                    var rs1 = To3(seg.Point1, inter.Value, primitive.Transform, swap);
                    results.Add(rs1);
                    return;
                }

                var rs2 = segment;
                results.Add(rs2);
                return;
            }
            else
            {
                var circle = new Circle2(Vector2.Zero, primitive.Scale.X);

                var conains1 = circle.Contains(seg.Point1);
                var conains2 = circle.Contains(seg.Point2);
                if (conains1 && conains2)
                {
                    return;
                }
                if (!conains1 && !conains2)
                {
                    var rs1 = segment;
                    results.Add(rs1);
                    return;
                }

                var swap = conains1;
                if (swap)
                {
                    CodingHelper.Swap(ref seg.Point1, ref seg.Point2);
                }

                var dpp   = seg.Point2 - seg.Point1;
                var dpc   = seg.Point1;
                var a     = dpp.LengthSquared();
                var b     = Vector2.Dot(dpp, dpc);
                var c     = dpc.LengthSquared() - circle.Radius.Sq();
                var discr = b * b - a * c;
                if (discr < 0)
                {
                    results.Add(segment);
                    return;
                }
                if (discr < MathHelper.Eps5)
                {
                    results.Add(segment);
                    return;
                    //var l = -b / a;
                    //if (0 <= l && l <= 1)
                }
                {
                    var sqrdscr = MathHelper.Sqrt(discr);
                    var l1      = (-b + sqrdscr) / a;
                    var l2      = (-b - sqrdscr) / a;
                    if (0 <= l1 && l1 <= 1)
                    {
                        var rs1 = To3(seg.Point1, Vector2.Lerp(seg.Point1, seg.Point2, l1), primitive.Transform, swap);
                        results.Add(rs1);
                    }

                    if (0 <= l2 && l2 <= 1)
                    {
                        var rs1 = To3(seg.Point1, Vector2.Lerp(seg.Point1, seg.Point2, l2), primitive.Transform, swap);
                        results.Add(rs1);
                    }
                }
            }
        }
Example #14
0
 private static Transform GetMovieSpeedTransform(AaRectangle2 rect)
 {
     return(new Transform(ButtonHalfHeight, Quaternion.Identity, new Vector3(
                              rect.MinX + ButtonHalfHeight,
                              rect.MaxY - ButtonHalfHeight, 0)));
 }