private void ArrangeAndDecorateInternal(int nodeIndex, int level, NestedCirclesStorySpringModel springModel, IStoryGraph sg)
        {
            var node   = sg.NodeObjects[nodeIndex];
            var aspect = sg.Aspects[nodeIndex];
            var index  = node.Id;

            var dynamicParts = new StoryNodeDynamicParts();
            var scale        = springModel.GetVisualRadius(index);
            var visualElems  = new List <IVisualElement>
            {
                new ModelVisualElement <object>(null)
                .SetModel(circleModel)
                .SetMaterial(circleMaterials[level % circleMaterials.Length])
                .SetRenderState(circleRenderState)
                .SetTransform(Transform.Scaling(scale))
                .SetTransformSpace(TransformSpace.ScreenAlighned)
            };

            var transform = Transform.Translation(new Vector3(springModel.GetPosition(index), 0));

            node.Transform = transform;

            if (level == 0)
            {
                var edgeVisuals = sg.Edges.Select(edge => CreateEdgeVisualElement(node, sg.NodeObjects[edge.First], sg.NodeObjects[edge.Second]));
                visualElems.AddRange(edgeVisuals);
            }

            if (sg.Children[index].Any())
            {
                foreach (var childIndex in sg.Children[index])
                {
                    ArrangeAndDecorateInternal(childIndex, level + 1, springModel, sg);
                }
            }

            dynamicParts.VisualElements            = visualElems;
            dynamicParts.Hittable                  = new CircleHittable <ISceneNode>(node, Transform.Identity, x => new Circle2(Vector2.Zero, scale), x => - 0.01f * level);
            dynamicParts.DefaultViewpointMechanism = new OrthoDefaultViewpointMechanism(node, new PlaneOrthoBoundControlledCamera.Props
            {
                Target   = Vector2.Zero,
                Distance = 1.5f * scale,
                ZNear    = 0.1f,
                ZFar     = 1000f
            });
            aspect.SetDynamicParts(dynamicParts);
        }
Ejemplo n.º 2
0
        private void ArrangeAndDecorateInternal(int subtreeRoot, BuildingStoryLayoutPlacementAlgorithm placementAlgorithm, List <BuildingWallSegment> globalWallSegments)
        {
            var sg       = placementAlgorithm.StoryGraph;
            var node     = sg.NodeObjects[subtreeRoot];
            var aspect   = sg.Aspects[subtreeRoot];
            var index    = node.Id;
            var children = sg.Children[index];

            foreach (var child in children)
            {
                ArrangeAndDecorateInternal(child, placementAlgorithm, globalWallSegments);
            }

            var depth = sg.Depths[subtreeRoot];

            var hasChildren = children.Any();

            var halfSize = placementAlgorithm.HalfSizes[index];

            node.Transform = hasChildren
                ? placementAlgorithm.RelativeTransforms[index]
                : placementAlgorithm.RelativeTransforms[index] * Transform.Translation(0, BuildingConstants.EyeHeight, 0);

            var dynamicParts = new StoryNodeDynamicParts();
            var visualElems  = new List <IVisualElement>();

            var corridorDigger = new BuildingCorridorDigger();
            var digResult      = corridorDigger.Dig(placementAlgorithm, index);

            var globalTransform = placementAlgorithm.GetGlobalTransform(index);

            var rootStoryComponent = sg.Aspects[sg.Root];

            if (digResult.WallSegments.Any())
            {
                var wallModel = BuildWallModel(digResult.WallSegments);
                visualElems.Add(new ModelVisualElement <IStoryComponent>(rootStoryComponent)
                                .SetModel(wallModel)
                                .SetMaterial(wallMaterial)
                                .SetRenderState(StandardRenderState.New()
                                                .SetCullFace(CullFace.Back)
                                                .FromGlobalCache())
                                .SetHide(x => x.HideMain));
                foreach (var wallSegment in digResult.WallSegments)
                {
                    globalWallSegments.Add(new BuildingWallSegment
                    {
                        Basement = new LineSegment3(
                            wallSegment.Basement.Point1 * globalTransform,
                            wallSegment.Basement.Point2 * globalTransform),
                        Height = wallSegment.Height
                    });
                }

                var wallPrimitivesModel = BuildWallModel4(digResult.RawWallSegments);
                visualElems.Add(new ModelVisualElement <IStoryComponent>(rootStoryComponent)
                                .SetModel(wallPrimitivesModel)
                                .SetMaterial(rawWallMaterial)
                                .SetHide(x => !x.ShowAux3));

                var filteredWallPrimitivesModel = BuildWallModel4(digResult.WallSegments);
                visualElems.Add(new ModelVisualElement <IStoryComponent>(rootStoryComponent)
                                .SetModel(filteredWallPrimitivesModel)
                                .SetMaterial(rawWallMaterial)
                                .SetHide(x => !x.ShowAux4));
            }

            foreach (var flooring in digResult.Floorings)
            {
                visualElems.Add(new ModelVisualElement <IStoryComponent>(rootStoryComponent)
                                .SetModel(BuildFloorOrCeiling(new Size3(flooring.HalfWidth, 0, flooring.HalfHeight), PlaneModelSourceNormalDirection.Positive))
                                .SetMaterial(floorMaterial)
                                .SetRenderState(StandardRenderState.New()
                                                .SetCullFace(CullFace.Back)
                                                .FromGlobalCache())
                                .SetTransform(Transform.Translation(flooring.Center.X, 0, flooring.Center.Y))
                                .SetHide(x => x.HideMain));
            }

            if (index == sg.Root)
            {
                foreach (var lane in placementAlgorithm.Lanes.Values)
                {
                    var laneLoc           = lane;
                    var navigationService = navigationServiceLazy.Value;
                    var model             = BuildLaneModel(lane);
                    visualElems.Add(ModelVisualElement.New()
                                    .SetModel(model)
                                    .SetMaterial(x => new UnorderedPair <int>(navigationService.Previous.Id, navigationService.Current.Id) == new UnorderedPair <int>(laneLoc.Edge.First, laneLoc.Edge.Second) ? currentLineMaterial : lineMaterial)
                                    .SetRenderState(StandardRenderState.New()
                                                    // todo: remove *5
                                                    .SetZOffset(GraphicsHelper.MinZOffset * 5)
                                                    .SetLineWidth(3)
                                                    .FromGlobalCache()));
                }
            }

            dynamicParts.Hittable = hasChildren
                ? new RectangleHittable <ISceneNode>(node, Transform.Rotate(Quaternion.RotationToFrame(Vector3.UnitX, Vector3.UnitZ)), x => new AaRectangle2(Vector2.Zero, halfSize.Width, halfSize.Height), x => - 0.01f * depth)
                : new RectangleHittable <ISceneNode>(node, new Transform(1, Quaternion.RotationToFrame(Vector3.UnitX, Vector3.UnitZ), new Vector3(0, -BuildingConstants.EyeHeight, 0)), x => new AaRectangle2(Vector2.Zero, halfSize.Width, halfSize.Height), x => - 0.01f * depth);

            if (depth == 1)
            {
                visualElems.Add(new ModelVisualElement <IStoryComponent>(rootStoryComponent)
                                .SetModel(BuildFloorOrCeiling(halfSize, PlaneModelSourceNormalDirection.Negative))
                                .SetMaterial(ceilingMaterial)
                                .SetRenderState(StandardRenderState.New()
                                                .SetCullFace(CullFace.Back)
                                                .FromGlobalCache())
                                .SetTransform(Transform.Translation(0, BuildingConstants.CeilingHeight, 0))
                                .SetHide(x => x.HideMain));
            }

            if (hasChildren)
            {
                var size = halfSize.ToVector().Length();
                dynamicParts.DefaultViewpointMechanism =
                    new WallDefaultViewpointMechanism(node, new TargetedControlledCameraY.Props
                {
                    Target      = Vector3.Zero,
                    Distance    = size,
                    FieldOfView = MathHelper.PiOver4,
                    Pitch       = MathHelper.PiOver4,
                    Yaw         = -MathHelper.PiOver4,
                    ZNear       = 0.01f,
                    ZFar        = 1000f
                });
            }
            else
            {
                dynamicParts.DefaultViewpointMechanism =
                    new WallDefaultViewpointMechanism(node, new TargetedControlledCameraY.Props
                {
                    Distance    = FrustumDistance,
                    FieldOfView = MathHelper.PiOver4,
                    Pitch       = 0,
                    Yaw         = 0,
                    ZNear       = 0.01f,
                    ZFar        = 1000f
                });

                visualElems.Add(new ModelVisualElement <IStoryComponent>(rootStoryComponent)
                                .SetModel(frustumModel)
                                .SetMaterial(frustumMaterial)
                                .SetRenderState(StandardRenderState.New()
                                                .SetZOffset(GraphicsHelper.MinZOffset * (depth + 1))
                                                .FromGlobalCache())
                                .SetHide(x => !x.ShowAux1));

                dynamicParts.PlacementSurface2D = new PlanarPlacementSurface(node, new Transform(2f, Quaternion.Identity, new Vector3(0, 0, -MathHelper.FrustumDistance)));
                dynamicParts.PlacementSurface3D = new PlanarPlacementSurface(node, Transform.Scaling(0.1f));
            }

            dynamicParts.VisualElements = visualElems;

            aspect.SetDynamicParts(dynamicParts);
        }
        private void ArrangeAndDecorateInternal(int nodeIndex, int level, NestedSpheresStorySpringModel springModel, IStoryGraph sg)
        {
            var node   = sg.NodeObjects[nodeIndex];
            var aspect = sg.Aspects[nodeIndex];
            var index  = node.Id;

            var dynamicParts = new StoryNodeDynamicParts();
            var scale        = springModel.GetVisualRadius(index);
            var visualElems  = new List <IVisualElement>
            {
                new ModelVisualElement <IStoryComponent>(sg.Aspects[sg.Root])
                .SetModel(mainModel)
                .SetMaterial(sphereMaterials[level % sphereMaterials.Length])
                .SetRenderState(sphereRenderState)
                .SetTransform(new Transform(scale, Quaternion.Identity, Vector3.Zero))
                //.SetTransformSpace(TransformSpace.ScreenAlighned)
                .SetGetDistanceToCameraSq((o, t, c) => ((t.Offset - c.GetEye()).Length() + scale).Sq())
                .SetHide(x => !x.ShowAux1)
            };

            node.Transform = new Transform(1, Quaternion.RotationY(springModel.GetRotation(index)), springModel.GetPosition(index));

            if (level == 0)
            {
                var edgeVisuals = sg.Edges.Select(edge => CreateEdgeVisualElement(node, sg.NodeObjects[edge.First], sg.NodeObjects[edge.Second]));
                visualElems.AddRange(edgeVisuals);
            }

            var visualEffects = new[]
            {
                new FocusVisualEffect()
            };

            if (sg.Children[index].Any())
            {
                foreach (var childIndex in sg.Children[index])
                {
                    ArrangeAndDecorateInternal(childIndex, level + 1, springModel, sg);
                }
                dynamicParts.DefaultViewpointMechanism = new WallDefaultViewpointMechanism(node, new TargetedControlledCameraY.Props
                {
                    Yaw         = MathHelper.PiOver4,
                    Pitch       = MathHelper.PiOver4,
                    ZNear       = 0.01f,
                    ZFar        = 1000f,
                    FieldOfView = MathHelper.PiOver4,
                    Distance    = 2f * scale,
                });
            }
            else
            {
                dynamicParts.DefaultViewpointMechanism = new WallDefaultViewpointMechanism(node, new TargetedControlledCameraY.Props
                {
                    ZNear       = 0.01f,
                    ZFar        = 1000f,
                    FieldOfView = MathHelper.PiOver4,
                    Distance    = GraphicsHelper.FrustumDistance,
                });
                dynamicParts.PlacementSurface2D = new PlanarPlacementSurface(node, new Transform(2f, Quaternion.Identity, new Vector3(0, 0, -MathHelper.FrustumDistance)));
                dynamicParts.PlacementSurface3D = new PlanarPlacementSurface(node, Transform.Scaling(0.1f));
            }
            dynamicParts.Hittable       = new SphereHittable <ISceneNode>(node, x => new Common.Numericals.Geometry.Sphere(x.GlobalTransform.Offset, scale), true);
            dynamicParts.VisualElements = visualElems;

            dynamicParts.GetVisualEffects = n => viewServiceLazy.Value.MainView.FocusNode == n
                ? focusVisualEffect.EnumSelf()
                : Enumerable.Empty <IVisualEffect>();

            aspect.SetDynamicParts(dynamicParts);
        }