/// <summary>
        ///  Helper function for transforming from world to window coordinates.
        ///  This only works if the cameraEntity has a valid LocalToWorld
        ///  component. Returns windowPos (window position) and windowSize (window size) in
        ///  the same coordinates.
        /// </summary>
        public static float2 WorldToWindow(ComponentSystem callingSystem, Entity cameraEntity, float3 worldPos, float2 windowSize)
        {
            var mgr = callingSystem.EntityManager;
            DisplayListCamera dlc = mgr.GetComponentData <DisplayListCamera>(cameraEntity);
            Camera2D          c2d = mgr.GetComponentData <Camera2D>(cameraEntity);

            float  aspect = windowSize.x / windowSize.y;
            float2 camsize;

            camsize.x = c2d.halfVerticalSize * aspect;
            camsize.y = c2d.halfVerticalSize;
            // transform from world to window
            float3 viewpos;

            viewpos = math.transform(dlc.inverseWorld, worldPos);
            // to normalized window
            float2 windowPos;

            windowPos.x = viewpos.x / camsize.x;
            windowPos.y = viewpos.y / camsize.y;
            // to output window
            windowPos.x = (windowPos.x * .5f + .5f) * windowSize.x;
            windowPos.y = (windowPos.y * .5f + .5f) * windowSize.y;
            return(windowPos);
        }
        /// <summary>
        ///  Helper function for transforming from window to world coordinates.
        ///  This only works if cameraEntity has a valid LocalToWorld
        ///  component. The windowPos (window position) and windowSize (window size) should be
        ///  in the same coordinates. The Z coordinate is set to 0.
        /// </summary>
        public static float3 WindowToWorld(ComponentSystem callingSystem, Entity cameraEntity, float2 windowPos, float2 windowSize)
        {
            var mgr = callingSystem.EntityManager;

            if (!mgr.HasComponent <DisplayListCamera>(cameraEntity) ||
                !mgr.HasComponent <Camera2D>(cameraEntity))
            {
                return(float3.zero);
            }

            DisplayListCamera dlc = mgr.GetComponentData <DisplayListCamera>(cameraEntity);
            Camera2D          c2d = mgr.GetComponentData <Camera2D>(cameraEntity);

            float  aspect = windowSize.x / windowSize.y;
            float2 camsize;

            camsize.x = c2d.halfVerticalSize * aspect;
            camsize.y = c2d.halfVerticalSize;
            float2 normalizedWindow;

            normalizedWindow.x = (windowPos.x / windowSize.x) * 2.0f - 1.0f;
            normalizedWindow.y = (windowPos.y / windowSize.y) * 2.0f - 1.0f;
            float3 viewpos;

            viewpos.x = normalizedWindow.x * camsize.x;
            viewpos.y = normalizedWindow.y * camsize.y;
            viewpos.z = 0;
            float3 worldPos = math.transform(dlc.world, viewpos);

            return(worldPos);
        }
示例#3
0
        protected bool FinishDisplayListEntry(ref DisplayListEntry de, ref DisplayListCamera dlc,
                                              ref LocalToWorld tx, ref PrivateTransformData ptd, bool doNotClip)
        {
            de.inSortingGroup = ptd.inSortingGroup;
#if UNITY_USE_TINYMATH
            de.finalMatrix = tinymath.mul(dlc.inverseWorld, tx.Value);
#else
            de.finalMatrix = math.mul(dlc.inverseWorld, tx.Value);
#endif
            if (doNotClip)
            {
                return(true);
            }
            // z-clip
            float z = de.finalMatrix[2][3];
            if (z < dlc.clipZNear || z > dlc.clipZFar)
            {
                return(false);
            }
            // bounds clip
#if DEBUG
            if (!(de.inBounds.width > 0.0f) || !(de.inBounds.height > 0.0f))
            {
                Debug.LogFormat("Entity {0} has zero or negative size ({1},{2})! This is checked in DEVELOPMENT builds only!", de.e, de.inBounds.width, de.inBounds.height);
                return(false);
            }
#endif
            return(true);
        }
示例#4
0
        protected void AddItemsToListByType(IExternalDisplayListEntryMaker dlm, DisplayListCamera dlc, Camera2D c2d,
                                            DynamicBuffer <DisplayListEntry> dest, DynamicBuffer <SortedEntity> destSorted)
        {
            var mgr = EntityManager;

            dlm.Update(this);
            var  cachedGetLayerSorting = GetComponentDataFromEntity <LayerSorting>(true);
            bool doNotClip             = dlm.DoNotClip();
            var  query = Entities;

            // build the query: Add base filter and dlm, then add per - camera filter
            dlm.Filter(ref query);
            // add camera 'layer' filter
            AddLayerFilter(ref query, c2d);

            // run query
            query.ForEach((Entity e, ref PrivateTransformData ptd, ref LocalToWorld tx) =>
            {
                DisplayListEntry de = default;
                de.e = e;
                if (!dlm.MakeEntry(mgr, ref de))
                {
                    return;
                }
                if (!FinishDisplayListEntry(ref de, ref dlc, ref tx, ref ptd, doNotClip))
                {
                    return;
                }
                float z         = math.dot(de.finalMatrix[3], dlc.sortingDot); // = Dot(de.finalMatrix.GetColumn(3), dlc.camSortingDot); TODO CHECK
                SortedEntity se = new SortedEntity {
                    e   = de.e,
                    idx = dest.Length
                };
                if (cachedGetLayerSorting.Exists(de.e))
                {
                    var sortEx = cachedGetLayerSorting[de.e];
                    se.CombineKey(z, sortEx.layer, sortEx.order);
                }
                else
                {
                    se.CombineKey(z);
                }
                se.e   = de.e;
                se.idx = dest.Length;
                dest.Add(de);
                destSorted.Add(se);
            });
        }
示例#5
0
        protected int UpdateOneDisplayListCamera(Entity e, ref Camera2D cam, ref DisplayListCamera dlcCam, ref LocalToWorld tx, float primaryAspect)
        {
            var mgr = EntityManager;

            // get list and sorted list buffers
            DynamicBuffer <DisplayListEntry> dest       = mgr.GetBuffer <DisplayListEntry>(e);
            DynamicBuffer <SortedEntity>     destSorted = mgr.GetBuffer <SortedEntity>(e);

            dest.Clear();
            destSorted.Clear();
#if DEBUG
            if (!(cam.rect.x >= 0.0f && cam.rect.y >= 0.0f && cam.rect.x + cam.rect.width <= 1.0f &&
                  cam.rect.y + cam.rect.height <= 1.0f))
            {
                Debug.LogFormat("The camera {0} has an invalid rect field ({1},{2},{3},{4}). Fixing by clamping it to the unit rectangle (0,0,1,1) in DEVELOPMENT build only.",
                                e, cam.rect.x, cam.rect.y, cam.rect.width, cam.rect.height);
                cam.rect.Clamp(new Rect(0, 0, 1, 1));
            }
            if (cam.rect.IsEmpty())
            {
                Debug.LogFormat("The camera {0} has an empty rect field. Fixing by setting it to identity in DEVELOPMENT build only.", e);
                cam.rect = new Rect(0, 0, 1, 1);
            }
            if (cam.halfVerticalSize <= 0)
            {
                Debug.LogFormat("The camera {0} has an invalid halfVerticalSize size of {1}. Nothing will render for it.", e, cam.halfVerticalSize);
                return(0);
            }
            float mas = MaxAbsScale(tx.Value);
            if (!(mas > .99f && mas < 1.01f))
            {
                Debug.LogFormat("The entity {0} with a Camera2D has a maximum absolute scaling factor of {1}. Cameras can not be scaled for rendering. Rendering and picking with this camera will likely be wrong.",
                                e, mas);
            }
#endif
            // get camera sorting axis
            if (mgr.HasComponent <Camera2DAxisSort>(e))
            {
                var axissort = mgr.GetComponentData <Camera2DAxisSort>(e);
                dlcCam.sortingDot.xyz = -axissort.axis;
                dlcCam.sortingDot.w   = 0;
            }
            else
            {
                dlcCam.sortingDot.x = 0.0f;
                dlcCam.sortingDot.y = 0.0f;
                dlcCam.sortingDot.z = -1.0f;
                dlcCam.sortingDot.w = 0.0f;
            }
            // copy transform matrix
            dlcCam.world        = tx.Value;
            dlcCam.inverseWorld = math.inverse(dlcCam.world);

            // initialize 2d clipping
            if (mgr.HasComponent <Camera2DRenderToTexture>(e))
            {
                var   rtt         = mgr.GetComponentData <Camera2DRenderToTexture>(e);
                float localAspect = (float)rtt.width / (float)rtt.height;
                dlcCam.clip2D.x = cam.halfVerticalSize * localAspect;
                dlcCam.clip2D.y = cam.halfVerticalSize;
            }
            else
            {
                dlcCam.clip2D.x = cam.halfVerticalSize * primaryAspect;
                dlcCam.clip2D.y = cam.halfVerticalSize;
            }

            // initialize near/far clipping
            if (mgr.HasComponent <Camera2DClippingPlanes>(e))
            {
                var clipz = mgr.GetComponentData <Camera2DClippingPlanes>(e);
                dlcCam.clipZNear = clipz.near;
                dlcCam.clipZFar  = clipz.far;
            }
            else
            {
                dlcCam.clipZNear = float.MinValue;
                dlcCam.clipZFar  = float.MaxValue;
            }

#if DEBUG
            if (dlcCam.clipZNear >= dlcCam.clipZFar)
            {
                Debug.LogFormat("The camera {0} has an invalid z clip range [{1}...{2}]. Nothing will render for it.", e, dlcCam.clipZNear, dlcCam.clipZFar);
                return(0);
            }
#endif

            // add all items
            for (int i = 0; i < dlMakerReg.Count; i++)
            {
                AddItemsToListByType(dlMakerReg[i], dlcCam, cam, dest, destSorted);
            }

            // sort in c++
            unsafe {
                SortExternal(dest.GetUnsafePtr(), destSorted.GetUnsafePtr(), dest.Length);
            }

            return(dest.Length);
        }