Пример #1
0
 public int GetClosestNodeId(CameraProps cameraProps)
 {
     return(sg.Leaves.Minimal(x => (placementAlgorithm.GetGlobalTransform(x).Offset - cameraProps.Target).LengthSquared()));
 }
Пример #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);
        }