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); }
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); }