Esempio n. 1
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)))
            });
        }
Esempio n. 2
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]
                });
            }
        }
 public WallDefaultViewpointMechanism(ISceneNode node, TargetedControlledCameraY.Props props)
 {
     this.node   = node;
     this.props  = props;
     FixedCamera = CreateControlledViewpoint();
 }