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]
                });
            }
        }
Exemple #2
0
        private void ArrangeAndDecorateRoot(IStoryGraph sg)
        {
            var nodeIndex        = sg.Root;
            var aStory           = sg.Aspects[nodeIndex];
            var node             = sg.NodeObjects[nodeIndex];
            var adaptiveChildren = sg.Children[nodeIndex];
            var numChildren      = adaptiveChildren.Count;

            var visuals = new List <IVisualElement>();

            // todo: refactor to CenterLayout struct
            var wallRadius = 1f;

            var alpha = MathHelper.PiOver2;

            if (numChildren > 2)
            {
                alpha      = MathHelper.TwoPi / (2 * numChildren);
                wallRadius = corridorHalfWidth / MathHelper.Tan(alpha / 2f);
            }

            for (int i = 0; i < numChildren; i++)
            {
                var centerAngle = alpha * (1 + 2 * i);
                var pos         = new Vector3(
                    wallRadius * MathHelper.Cos(centerAngle),
                    wallRadius * MathHelper.Sin(centerAngle),
                    0);
                var rotation = Quaternion.RotationZ(-centerAngle + MathHelper.PiOver2);
                visuals.Add(CorridorWall(rotation, pos));
            }

            for (int i = 0; i < numChildren; i++)
            {
                var child = adaptiveChildren[i];

                var centerAngle = alpha * (2 * i);
                var doorPos     = new Vector3(
                    wallRadius * MathHelper.Cos(centerAngle),
                    wallRadius * MathHelper.Sin(centerAngle),
                    0);

                var forward  = doorPos.Normalize();
                var rotation = Quaternion.RotationZ(-centerAngle + MathHelper.PiOver2);
                if (sg.Children[child].Any())
                {
                    sg.NodeObjects[child].Transform = new Transform(1, rotation, doorPos);
                    ArrangeAndDecorateIntermediate(child, sg);
                }
                else
                {
                    sg.NodeObjects[child].Transform = new Transform(1, rotation, doorPos - forward * FrustumDistance);
                    ArrangeAndDecorateLeaf(child, sg);
                }
            }

            // floor
            visuals.Add(ModelVisualElement.New()
                        .SetModel(floorModel)
                        .SetMaterial(floorMaterial)
                        .SetRenderState(StandardRenderState.New()
                                        .SetCullFace(CullFace.Back)
                                        .FromGlobalCache())
                        .SetTransform(new Transform(1, Quaternion.Identity, new Vector3(0, 0, centerHeight - ceilingHalfHeight))));

            // ceiling
            visuals.Add(ModelVisualElement.New()
                        .SetModel(ceilingModel)
                        .SetMaterial(ceilingMaterial)
                        .SetRenderState(StandardRenderState.New()
                                        .SetCullFace(CullFace.Back)
                                        .FromGlobalCache())
                        .SetTransform(new Transform(1, Quaternion.Identity, new Vector3(0, 0, centerHeight + ceilingHalfHeight))));

            var viewpointProps = new LookAroundCamera.Props
            {
                Distance    = 24,
                FieldOfView = MathHelper.PiOver2,
                ZNear       = 0.1f,
                ZFar        = 100.0f,
                Pitch       = 0
            };

            aStory.SetDynamicParts(new StoryNodeDynamicParts
            {
                DefaultViewpointMechanism = new SphereDefaultViewpointMechanism(node, viewpointProps),
                Hittable       = new DummyHittable(),
                VisualElements = visuals
            });
        }
 public SphereDefaultViewpointMechanism(ISceneNode node, LookAroundCamera.Props props)
 {
     this.node   = node;
     this.props  = props;
     FixedCamera = CreateControlledViewpoint();
 }