Beispiel #1
0
        private void UpdateAnnotationOffsets(SceneNodeContainer sncAnnotation, UIInput input)
        {
            if (input.CircleCanvasPos.x <= _canvasWidth / 2)
            {
                //LEFT
                sncAnnotation.GetComponent <RectTransformComponent>().Anchors = UIElementPosition.GetAnchors(AnchorPos.DOWN_DOWN_LEFT);

                sncAnnotation.GetComponent <RectTransformComponent>().Offsets = UIElementPosition.CalcOffsets(
                    AnchorPos.DOWN_DOWN_LEFT, input.AnnotationCanvasPos,
                    UIHelper.CanvasHeightInit, UIHelper.CanvasWidthInit, UIHelper.AnnotationDim);
            }
            else
            {
                //RIGHT
                sncAnnotation.GetComponent <RectTransformComponent>().Anchors = UIElementPosition.GetAnchors(AnchorPos.DOWN_DOWN_RIGHT);

                sncAnnotation.GetComponent <RectTransformComponent>().Offsets = UIElementPosition.CalcOffsets(
                    AnchorPos.DOWN_DOWN_RIGHT, input.AnnotationCanvasPos,
                    UIHelper.CanvasHeightInit, UIHelper.CanvasWidthInit, UIHelper.AnnotationDim);
            }
        }
Beispiel #2
0
        private void CalculateNonIntersectingAnnotationPositions(ref UIInput input, ref Dictionary <int, float2> intersectedAnnotations, ref int iterations)
        {
            if (!input.IsVisible)
            {
                return;
            }

            var intersectionCount = 0;

            for (var i = 0; i < _uiInput.Count; i++)
            {
                var counterpart = _uiInput[i];

                if (counterpart.Identifier == input.Identifier || !counterpart.IsVisible || intersectedAnnotations.ContainsKey(counterpart.Identifier))
                {
                    continue;
                }

                var halfAnnotationHeight = (UIHelper.AnnotationDim.y / 2f);
                var buffer = halfAnnotationHeight - (halfAnnotationHeight / 100f * 10f);
                //If we do not multiply by the resize scale factor the intersction test will return wrong results because AnnotationCanvasPos is in the range of the size of the initial canvas.
                var intersect = UIHelper.DoesAnnotationIntersectWithAnnotation(input.AnnotationCanvasPos, _uiInput[i].AnnotationCanvasPos, new float2(0, buffer));

                if (!intersect || intersectedAnnotations.ContainsKey(counterpart.Identifier))
                {
                    continue;
                }

                intersectedAnnotations.Add(counterpart.Identifier, _uiInput[i].AnnotationCanvasPos);
                intersectionCount++;
            }

            if (intersectionCount == 0)
            {
                return;
            }

            if (intersectedAnnotations.Count >= 1)
            {
                if (!intersectedAnnotations.ContainsKey(input.Identifier))
                {
                    intersectedAnnotations.Add(input.Identifier, input.AnnotationCanvasPos); //add pos that is just being checked
                }
                var orderedBy = intersectedAnnotations.OrderBy(item => item.Value.y).ToList();

                intersectedAnnotations = new Dictionary <int, float2>();
                foreach (var keyValue in orderedBy) //JSIL not implemented exception: ToDictionary
                {
                    intersectedAnnotations.Add(keyValue.Key, keyValue.Value);
                }

                var middleIndex = (intersectedAnnotations.Count) / 2;
                var averagePos  = new float2();

                for (var i = 0; i < intersectedAnnotations.Count; i++)
                {
                    averagePos += intersectedAnnotations.ElementAt(i).Value;
                }

                averagePos /= intersectedAnnotations.Count;

                for (var i = 0; i < intersectedAnnotations.Count; i++)
                {
                    var identifier = intersectedAnnotations.ElementAt(i).Key;
                    var thisInput  = _uiInput[identifier];
                    thisInput.AnnotationCanvasPos = averagePos;

                    var multiplier = System.Math.Abs(i - middleIndex);

                    //Distance between annotations is 0.5* AnnotationDim.y
                    if (intersectedAnnotations.Count % 2 == 0) //even
                    {
                        if (i == middleIndex - 1)
                        {
                            thisInput.AnnotationCanvasPos.y -= 0.75f * UIHelper.AnnotationDim.y;
                        }

                        else if (i == middleIndex)
                        {
                            thisInput.AnnotationCanvasPos.y += 0.75f * UIHelper.AnnotationDim.y;
                        }

                        else if (i > middleIndex)
                        {
                            thisInput.AnnotationCanvasPos.y += (0.75f * UIHelper.AnnotationDim.y) + (multiplier * (UIHelper.AnnotationDim.y + UIHelper.AnnotationDim.y / 2));
                        }

                        else if (i < middleIndex)
                        {
                            thisInput.AnnotationCanvasPos.y -= (0.75f * UIHelper.AnnotationDim.y) + ((multiplier - 1) * (UIHelper.AnnotationDim.y + UIHelper.AnnotationDim.y / 2));
                        }
                    }
                    else //odd
                    {
                        if (i > middleIndex)
                        {
                            thisInput.AnnotationCanvasPos.y += 0.5f * multiplier * UIHelper.AnnotationDim.y + (UIHelper.AnnotationDim.y * multiplier);
                        }

                        else if (i < middleIndex)
                        {
                            thisInput.AnnotationCanvasPos.y -= 0.5f * multiplier * UIHelper.AnnotationDim.y + (UIHelper.AnnotationDim.y * multiplier);
                        }
                    }

                    _uiInput[identifier] = thisInput;
                }
            }

            //Recursively check all annotations that where involved in this intersection
            for (var i = 0; i < intersectedAnnotations.Count; i++)
            {
                if (i != 0 && i != intersectedAnnotations.Count - 1)
                {
                    continue;
                }
                iterations++;
                var identifier = intersectedAnnotations.ElementAt(i).Key;
                var uiInput    = _uiInput[identifier];

                CalculateNonIntersectingAnnotationPositions(ref uiInput, ref intersectedAnnotations, ref iterations);
            }
        }
Beispiel #3
0
        // Init is called on startup.
        public override void Init()
        {
            if (_canvasRenderMode == CanvasRenderMode.SCREEN)
            {
                UIHelper.CanvasWidthInit  = Width / 100f;
                UIHelper.CanvasHeightInit = Height / 100f;
            }
            else
            {
                UIHelper.CanvasHeightInit = 16;
                UIHelper.CanvasWidthInit  = 9;
            }

            _canvasHeight = UIHelper.CanvasHeightInit;
            _canvasWidth  = UIHelper.CanvasWidthInit;

            _uiInput = new List <UIInput>();

            _initWidth   = Width;
            _initHeight  = Height;
            _aspectRatio = Width / (float)Height;

            //_scene = BuildScene();
            _scene = AssetStorage.Get <SceneContainer>("Monkey.fus");
            var monkey            = _scene.Children[0].GetComponent <Mesh>();
            var rnd               = new Random();
            var numberOfTriangles = monkey.Triangles.Length / 3;

            var projComp = _scene.Children[0].GetComponent <ProjectionComponent>();

            AddResizeDelegate(delegate { projComp.Resize(Width, Height); });

            //Create dummy positions on model
            for (var i = 0; i < NumberOfAnnotations; i++)
            {
                var triangleNumber = rnd.Next(1, numberOfTriangles);
                var triIndex       = (triangleNumber - 1) * 3;

                var triVert0 = monkey.Vertices[monkey.Triangles[triIndex]];
                var triVert1 = monkey.Vertices[monkey.Triangles[triIndex + 1]];
                var triVert2 = monkey.Vertices[monkey.Triangles[triIndex + 2]];

                var middle = (triVert0 + triVert1 + triVert2) / 3;

                var circleCanvasPos      = new float2(middle.x, middle.y);
                var circleCanvasPosCache = new float2(0, 0);

                var prob = (float)rnd.NextDouble();
                prob = (float)System.Math.Round(prob, 3);
                var dummyClass = UIHelper.DummySegmentationClasses[rnd.Next(0, UIHelper.DummySegmentationClasses.Count - 1)];

                var annotationKind = (UIHelper.AnnotationKind)rnd.Next(0, Enum.GetNames(typeof(UIHelper.AnnotationKind)).Length);

                var input = new UIInput(annotationKind, middle, new float2(0.65f, 0.65f), dummyClass, prob)
                {
                    Identifier           = i,
                    CircleCanvasPos      = circleCanvasPos,
                    CircleCanvasPosCache = circleCanvasPosCache
                };

                input.AffectedTriangles.Add(triIndex);
                _uiInput.Add(input);
            }

            _gui = CreateGui();

            // Create the interaction handler
            _sih = new SceneInteractionHandler(_gui);

            //Create a scene picker for performing visibility tests
            _scenePicker = new ScenePicker(_scene);

            // Set the clear color for the back buffer to white (100% intensity in all color channels R, G, B, A).
            RC.ClearColor = new float4(0.1f, 0.1f, 0.1f, 1);

            // Wrap a SceneRenderer around the model.
            _sceneRenderer = new SceneRenderer(_scene);
            _guiRenderer   = new SceneRenderer(_gui);
        }
Beispiel #4
0
        // RenderAFrame is called once a frame
        public override void RenderAFrame()
        {
            // Clear the backbuffer
            RC.Clear(ClearFlags.Color | ClearFlags.Depth);

            RC.Viewport(0, 0, Width, Height);

            #region Controls

            // Mouse and keyboard movement
            if (Input.Keyboard.LeftRightAxis != 0 || Input.Keyboard.UpDownAxis != 0)
            {
                _keys = true;
            }

            if (Input.Mouse.LeftButton)
            {
                _keys         = false;
                _angleVelHorz = -RotationSpeed * Input.Mouse.XVel * Time.DeltaTime * 0.0005f;
                _angleVelVert = -RotationSpeed * Input.Mouse.YVel * Time.DeltaTime * 0.0005f;
            }
            else if (Input.Touch.GetTouchActive(TouchPoints.Touchpoint_0))
            {
                _keys = false;
                float2 touchVel = Input.Touch.GetVelocity(TouchPoints.Touchpoint_0);
                _angleVelHorz = -RotationSpeed * touchVel.x * Time.DeltaTime * 0.0005f;
                _angleVelVert = -RotationSpeed * touchVel.y * Time.DeltaTime * 0.0005f;
            }
            else
            {
                if (_keys)
                {
                    _angleVelHorz = -RotationSpeed * Input.Keyboard.LeftRightAxis * Time.DeltaTime;
                    _angleVelVert = -RotationSpeed * Input.Keyboard.UpDownAxis * Time.DeltaTime;
                }
                else
                {
                    float curDamp = (float)System.Math.Exp(-Damping * Time.DeltaTime);
                    _angleVelHorz *= curDamp;
                    _angleVelVert *= curDamp;
                }
            }

            _angleHorz += _angleVelHorz;
            _angleVert += _angleVelVert;

            // Create the camera matrix and set it as the current ModelView transformation
            float4x4 mtxRot = float4x4.CreateRotationX(_angleVert) * float4x4.CreateRotationY(_angleHorz);
            float4x4 mtxCam = float4x4.LookAt(0, 0, -5, 0, 0, 0, 0, 1, 0);

            float4x4 view         = mtxCam * mtxRot;
            float4x4 perspective  = float4x4.CreatePerspectiveFieldOfView(_fovy, (float)Width / Height, ZNear, ZFar);
            float4x4 orthographic = float4x4.CreateOrthographic(Width, Height, ZNear, ZFar);


            RC.View       = view;
            RC.Projection = _canvasRenderMode == CanvasRenderMode.Screen ? orthographic : perspective;
            // Constantly check for interactive objects.
            if (!Input.Mouse.Desc.Contains("Android"))
            {
                _sih.CheckForInteractiveObjects(RC, Input.Mouse.Position, Width, Height);
            }

            if (Input.Touch.GetTouchActive(TouchPoints.Touchpoint_0) && !Input.Touch.TwoPoint)
            {
                _sih.CheckForInteractiveObjects(RC, Input.Touch.GetPosition(TouchPoints.Touchpoint_0), Width, Height);
            }

            #endregion Controls

            //Annotations will be updated according to circle positions.
            //Lines will be updated according to circle and annotation positions.

            RC.View       = view;
            RC.Projection = perspective;
            SceneNode canvas = _gui.Children[0];

            foreach (SceneNode child in canvas.Children)
            {
                if (!child.Name.Contains("MarkModelContainer"))
                {
                    continue;
                }

                //1. Calculate the circles canvas position.
                for (int k = 0; k < child.Children.Count; k++)
                {
                    SceneNode container = child.Children[k];

                    SceneNode circle  = container.Children[0];
                    UIInput   uiInput = _uiInput[k];

                    //the monkey's matrices
                    SceneNode monkey     = _scene.Children[0];
                    float4x4  model      = monkey.GetGlobalTransformation();
                    float4x4  projection = perspective;

                    float4x4 mvpMonkey = projection * view * model;

                    float3 clipPos         = float4x4.TransformPerspective(mvpMonkey, uiInput.Position); //divides by 2
                    float2 canvasPosCircle = new float2(clipPos.x, clipPos.y) * 0.5f + 0.5f;

                    canvasPosCircle.x      *= _canvasWidth;
                    canvasPosCircle.y      *= _canvasHeight;
                    uiInput.CircleCanvasPos = canvasPosCircle;

                    var pos = new float2(uiInput.CircleCanvasPos.x - (uiInput.Size.x / 2), uiInput.CircleCanvasPos.y - (uiInput.Size.y / 2)); //we want the lower left point of the rect that encloses the
                    circle.GetComponent <RectTransform>().Offsets = UIElementPosition.CalcOffsets(AnchorPos.Middle, pos, _canvasHeight, _canvasWidth, uiInput.Size);

                    //1.1   Check if circle is visible

                    PickResult newPick = _scenePicker.Pick(RC, new float2(clipPos.x, clipPos.y)).ToList().OrderBy(pr => pr.ClipPos.z).FirstOrDefault();

                    if (newPick != null && uiInput.AffectedTriangles[0] == newPick.Triangle) //VISIBLE
                    {
                        uiInput.IsVisible = true;

                        var effect = circle.GetComponent <DefaultSurfaceEffect>();
                        effect.SetDiffuseAlphaInShaderEffect(UIHelper.alphaVis);
                    }
                    else
                    {
                        uiInput.IsVisible = false;
                        var effect = circle.GetComponent <DefaultSurfaceEffect>();
                        effect.SetDiffuseAlphaInShaderEffect(UIHelper.alphaInv);
                    }

                    //1.2   Calculate annotation positions without intersections.
                    if (!uiInput.CircleCanvasPos.Equals(uiInput.CircleCanvasPosCache))
                    {
                        float yPosScale = uiInput.CircleCanvasPos.y / _canvasHeight;
                        yPosScale = (yPosScale - 0.5f) * 2f;
                        uiInput.AnnotationCanvasPos.y = uiInput.CircleCanvasPos.y - (UIHelper.AnnotationDim.y / 2) + (2 * UIHelper.AnnotationDim.y * yPosScale);

                        if (uiInput.CircleCanvasPos.x > _canvasWidth / 2) //RIGHT
                        {
                            uiInput.AnnotationCanvasPos.x = UIHelper.CanvasWidthInit - UIHelper.AnnotationDim.x - UIHelper.AnnotationDistToLeftOrRightEdge;
                        }
                        else
                        {
                            uiInput.AnnotationCanvasPos.x = UIHelper.AnnotationDistToLeftOrRightEdge;
                        }
                    }
                    _uiInput[k] = uiInput;
                }

                // 2.   Find intersecting annotations and correct their position in _uiInput.
                //      Disable rendering of annotation if its corresponding circle is not visible.
                for (int k = 0; k < child.Children.Count; k++)
                {
                    SceneNode container  = child.Children[k];
                    SceneNode annotation = container.Children[1];
                    UIInput   uiInput    = _uiInput[k];

                    if (uiInput.IsVisible)
                    {
                        if (!uiInput.CircleCanvasPos.Equals(uiInput.CircleCanvasPosCache))
                        {
                            Dictionary <int, float2> intersectedAnnotations = new Dictionary <int, float2>();
                            int iterations = 0;
                            CalculateNonIntersectingAnnotationPositions(ref uiInput, ref intersectedAnnotations, ref iterations);
                        }

                        annotation.GetComponent <NineSlicePlane>().Active = true;
                        foreach (Mesh comp in annotation.GetComponentsInChildren <Mesh>())
                        {
                            comp.Active = true;
                        }
                    }
                    else
                    {
                        annotation.GetComponent <NineSlicePlane>().Active = false;
                        foreach (Mesh comp in annotation.GetComponentsInChildren <Mesh>())
                        {
                            comp.Active = false;
                        }
                    }
                }

                // 3.   Update annotation positions on canvas and draw line
                for (int k = 0; k < child.Children.Count; k++)
                {
                    SceneNode container = child.Children[k];

                    SceneNode line    = container.Children[2];
                    UIInput   uiInput = _uiInput[k];

                    if (uiInput.IsVisible)
                    {
                        if (!uiInput.CircleCanvasPos.Equals(uiInput.CircleCanvasPosCache))
                        {
                            UpdateAnnotationOffsets(child.Children[uiInput.Identifier].Children[1], uiInput);
                            DrawLine(child.Children[uiInput.Identifier].Children[2], uiInput);
                        }
                    }

                    DrawLine(line, uiInput);

                    uiInput.CircleCanvasPosCache = uiInput.CircleCanvasPos;
                    _uiInput[k] = uiInput;
                }
            }

            _sceneRenderer.Render(RC);

            RC.Projection = _canvasRenderMode == CanvasRenderMode.Screen ? orthographic : perspective;
            _guiRenderer.Render(RC);

            Present();
        }