Ejemplo n.º 1
0
        public void OnPointerEnter(PointerEventData eventData)
        {
            if (TouchRayEnterLists.ContainsKey(eventData.pointerId))
            {
                return;
            }
            List <RaycastResult> UI_List = SS_Ray.UIRayCast(canvas, eventData.position, InterceptTag, IgnoreLayer);//提取物体列表

            if (UI_List.Count < 1)
            {
                return;
            }
            UI_List.RemoveAt(0);//顶层为自己,剔除。

            if (!TouchRayEnterLists.ContainsKey(eventData.pointerId))
            {
                TouchRayEnterLists.Add(eventData.pointerId, UI_List);                                                      //停留UI集合池添加
            }
            //触摸事件通知:停留
            SS_Ray.UISendEvent(UI_List, eventData, ExecuteEvents.pointerEnterHandler);

            if (!TouchEnterPool.ContainsKey(eventData.pointerId))
            {
                TouchEnterPool.Add(eventData.pointerId, eventData);                                                  //停留池添加
            }
        }
Ejemplo n.º 2
0
        public void OnPointerUp(PointerEventData eventData)//抬起事件
        {
            if (!TouchRayDownLists.ContainsKey(eventData.pointerId))
            {
                return;
            }
            //抬起事件

            //触摸事件通知:停止拖拽,抬起
            SS_Ray.UISendEvent(TouchRayDownLists[eventData.pointerId], eventData, ExecuteEvents.pointerUpHandler);

            //点击事件

            List <RaycastResult> UI_List = SS_Ray.UIRayCast(canvas, eventData.position, InterceptTag, IgnoreLayer);//提取物体列表

            if (UI_List.Count > 0)
            {
                UI_List.RemoveAt(0);                   //顶层为自己,剔除。
            }
            List <RaycastResult> Click_List = SS_GameObject.List_Intersect(TouchRayDownLists[eventData.pointerId], UI_List, (RaycastResult a, RaycastResult b) => { return(object.ReferenceEquals(a.gameObject, b.gameObject)); });

            SS_Ray.UISendEvent(Click_List, eventData, ExecuteEvents.pointerClickHandler);

            if (TouchRayDownLists.ContainsKey(eventData.pointerId))
            {
                TouchRayDownLists.Remove(eventData.pointerId);                                                      //去除物体列表
            }
        }
Ejemplo n.º 3
0
 public void OnDrag(PointerEventData eventData)//拖拽事件
 {
     if (!TouchRayDragLists.ContainsKey(eventData.pointerId))
     {
         return;
     }
     //触摸事件通知:拖拽
     SS_Ray.UISendEvent(TouchRayDownLists[eventData.pointerId], eventData, ExecuteEvents.dragHandler);
 }
Ejemplo n.º 4
0
        public void OnScroll(PointerEventData eventData)
        {
            List <RaycastResult> UI_List = SS_Ray.UIRayCast(canvas, eventData.position, InterceptTag, IgnoreLayer);//提取物体列表

            if (UI_List.Count < 1)
            {
                return;
            }
            UI_List.RemoveAt(0);//顶层为自己,剔除。

            //触摸事件通知:滚轮
            SS_Ray.UISendEvent(UI_List, eventData, ExecuteEvents.scrollHandler);
        }
Ejemplo n.º 5
0
 public void OnEndDrag(PointerEventData eventData)
 {
     if (!TouchRayDragLists.ContainsKey(eventData.pointerId))
     {
         return;
     }
     //触摸事件通知:拖拽结束
     SS_Ray.UISendEvent(TouchRayDragLists[eventData.pointerId], eventData, ExecuteEvents.endDragHandler);
     if (TouchRayDragLists.ContainsKey(eventData.pointerId))
     {
         TouchRayDragLists.Remove(eventData.pointerId);                                                      //去除物体列表
     }
 }
Ejemplo n.º 6
0
        public void OnPointerExit(PointerEventData eventData)
        {
            if (!TouchRayEnterLists.ContainsKey(eventData.pointerId))
            {
                return;
            }
            if (TouchEnterPool.ContainsKey(eventData.pointerId))
            {
                TouchEnterPool.Remove(eventData.pointerId);                                                 //停留池删除
            }
            //触摸事件通知:离开
            SS_Ray.UISendEvent(TouchRayEnterLists[eventData.pointerId], eventData, ExecuteEvents.pointerExitHandler);

            if (TouchRayEnterLists.ContainsKey(eventData.pointerId))
            {
                TouchRayEnterLists.Remove(eventData.pointerId);                                                       //停留UI集合池剔除
            }
        }
Ejemplo n.º 7
0
        public void OnBeginDrag(PointerEventData eventData)
        {
            if (TouchRayDragLists.ContainsKey(eventData.pointerId))
            {
                return;
            }
            List <RaycastResult> UI_List = SS_Ray.UIRayCast(canvas, eventData.position, InterceptTag, IgnoreLayer);//提取物体列表

            if (UI_List.Count < 1)
            {
                return;
            }
            UI_List.RemoveAt(0);//顶层为自己,剔除。
            if (!TouchRayDragLists.ContainsKey(eventData.pointerId))
            {
                TouchRayDragLists.Add(eventData.pointerId, UI_List);                                                     //添加物体列表到字典
            }
            //触摸事件通知:拖拽开始
            SS_Ray.UISendEvent(TouchRayDragLists[eventData.pointerId], eventData, ExecuteEvents.beginDragHandler);
        }
Ejemplo n.º 8
0
        public void OnPointerDown(PointerEventData eventData)//按下事件
        {
            if (TouchRayDownLists.ContainsKey(eventData.pointerId))
            {
                return;
            }

            List <RaycastResult> UI_List = SS_Ray.UIRayCast(canvas, eventData.position, InterceptTag, IgnoreLayer);//提取物体列表

            if (UI_List.Count < 1)
            {
                return;
            }
            UI_List.RemoveAt(0);//顶层为自己,剔除。
            if (!TouchRayDownLists.ContainsKey(eventData.pointerId))
            {
                TouchRayDownLists.Add(eventData.pointerId, UI_List);                                                     //添加物体列表到字典
            }
            //触摸事件通知:按下,开始拖拽
            SS_Ray.UISendEvent(UI_List, eventData, ExecuteEvents.pointerDownHandler);
        }
Ejemplo n.º 9
0
        public void OnStay(PointerEventData eventData)
        {
            List <RaycastResult> UI_List = SS_Ray.UIRayCast(canvas, eventData.position, InterceptTag, IgnoreLayer);//提取物体列表

            if (UI_List.Count < 1)
            {
                return;
            }
            UI_List.RemoveAt(0);//顶层为自己,剔除。

            List <RaycastResult> Enter_List = SS_GameObject.List_Except(UI_List, TouchRayEnterLists[eventData.pointerId], (RaycastResult a, RaycastResult b) => { return(object.ReferenceEquals(a.gameObject, b.gameObject)); });
            List <RaycastResult> Exit_List  = SS_GameObject.List_Except(TouchRayEnterLists[eventData.pointerId], UI_List, (RaycastResult a, RaycastResult b) => { return(object.ReferenceEquals(a.gameObject, b.gameObject)); });

            //触摸事件通知:停留
            SS_Ray.UISendEvent(Enter_List, eventData, ExecuteEvents.pointerEnterHandler);

            //触摸事件通知:离开
            SS_Ray.UISendEvent(Exit_List, eventData, ExecuteEvents.pointerExitHandler);

            TouchRayEnterLists[eventData.pointerId] = new List <RaycastResult>(UI_List);
        }
Ejemplo n.º 10
0
    public RecalculateShadowResult RecalculateShadow(Plane[] frustumPlanes, bool force)
    {
        _isVisible = _isStatic;

        // Determine whether the owner GameObject changed the active state
        // and react correspondingly
        bool isGameObjectActive = SS_Extensions.IsActiveInHierarchy(gameObject);

        if (isGameObjectActive != _isGameObjectActivePrev)
        {
            _isGameObjectActivePrev = isGameObjectActive;
            if (isGameObjectActive)
            {
                RegisterShadow();
                return(RecalculateShadowResult.ChangedManager);
            }
            else
            {
                UnregisterShadow();
                return(RecalculateShadowResult.ChangedManager);
            }
        }

        _isGameObjectActivePrev = isGameObjectActive;
        if (!isGameObjectActive)
        {
            return(RecalculateShadowResult.Skipped);
        }

        // Updating the transform state (position and forward vectors)
        // Determine whether the transform has moved
        Vector3 transformPosition = _transform.position;
        Vector3 transformForward  = _transform.forward;

        bool transformChanged = false;

        if (_autoStaticTime > 0)
        {
            if (transformPosition.x != _transformPositionPrev.x ||
                transformPosition.y != _transformPositionPrev.y ||
                transformPosition.z != _transformPositionPrev.z ||
                transformForward.x != _transformForwardPrev.x ||
                transformForward.y != _transformForwardPrev.y ||
                transformForward.z != _transformForwardPrev.z
                )
            {
                _autoStaticTimeCounter = 0f;
                transformChanged       = true;
            }

            _transformPositionPrev = transformPosition;
            _transformForwardPrev  = transformForward;
        }

        if (!_isFirstCalculation)
        {
            // If we have AutoStatic
            if (_autoStaticTime > 0f)
            {
                // If the object has moved - remove the shadow
                // from static manager and move to non-static
                if (_isStatic && transformChanged)
                {
                    UnregisterShadow();
                    _isStatic = false;
                    RegisterShadow();
                    return(RecalculateShadowResult.ChangedManager);
                }

                // If the object hasn't moved for AutoStaticTime seconds,
                // then mark it as static
                _autoStaticTimeCounter += Time.deltaTime;
                if (!_isStatic && _autoStaticTimeCounter > _autoStaticTime)
                {
                    UnregisterShadow();
                    _isStatic = true;
                    RegisterShadow();
                    return(RecalculateShadowResult.ChangedManager);
                }
            }

            // Do not update static shadows by default
            if (_isStatic && !force)
            {
                return(RecalculateShadowResult.Skipped);
            }

            // Return if the time hasn't come yet
            if (_frameSkip != 0)
            {
                if (_frameSkipCounter < _frameSkip)
                {
                    _frameSkipCounter++;
                    return(RecalculateShadowResult.Skipped);
                }

                _frameSkipCounter = 0;
            }
        }

        // Is this our first update?
        _isFirstCalculation = false;

        // Determine the light source position
        bool    useLightSource      = _lightVectorSource == LightVectorSourceEnum.GameObject && _lightSourceObject != null;
        Vector3 lightSourcePosition = useLightSource ? _lightSourceObject.transform.position : new Vector3();

        // The actual light direction vector that'll be used
        Vector3 actualLightVector;

        if (_lightVectorSource == LightVectorSourceEnum.GameObject && _lightSourceObject != null)
        {
            if (_lightSourceObjectIsDirectionalLight)
            {
                actualLightVector = _lightSourceObject.rotation * Vector3.forward;
            }
            else
            {
                actualLightVector.x = transformPosition.x - lightSourcePosition.x;
                actualLightVector.y = transformPosition.y - lightSourcePosition.y;
                actualLightVector.z = transformPosition.z - lightSourcePosition.z;
                actualLightVector   = actualLightVector.FastNormalized();
            }
        }
        else
        {
            actualLightVector = _lightVector;
        }

        _actualLightVectorPrev = actualLightVector;

        // Do a raycast from transform.position to the center of the shadow
        RaycastHit hitInfo;
        bool       raycastResult = Physics.Raycast(transformPosition, actualLightVector, out hitInfo, _projectionDistance, _layerMask);

        if (raycastResult)
        {
            // Scale the shadow respectively
            Vector3 lossyScale             = transform.lossyScale;
            float   scaledDoubleShadowSize = Mathf.Max(Mathf.Max(lossyScale.x, lossyScale.y), lossyScale.z) * ShadowSize;

            if (!_isStatic && _cullInvisible)
            {
                // We can calculate approximate bounds for orthographic shadows easily
                // and cull shadows based on these bounds and camera frustum
                if (!_isPerspectiveProjection)
                {
                    Bounds bounds = new Bounds(hitInfo.point, new Vector3(scaledDoubleShadowSize, scaledDoubleShadowSize, scaledDoubleShadowSize));
                    _isVisible = GeometryUtility.TestPlanesAABB(frustumPlanes, bounds);
                    if (!_isVisible)
                    {
                        return(RecalculateShadowResult.Skipped);
                    }
                }
                else
                {
                    // For perspective shadows, we can at least try to
                    // not draw shadows that fall on invisible objects
                    Transform hitTransform = hitInfo.collider.transform;
                    if (frustumPlanes != null)
                    {
                        Renderer hitRenderer = hitTransform != null ? hitTransform.renderer : null;
                        if (hitRenderer != null)
                        {
                            _isVisible = GeometryUtility.TestPlanesAABB(frustumPlanes, hitRenderer.bounds);
                            if (!_isVisible)
                            {
                                return(RecalculateShadowResult.Skipped);
                            }
                        }
                    }
                }
            }

            // Calculate angle from light direction vector to surface normal
            _normal = hitInfo.normal;
            float angleToNormal = SS_Math.FastAcos(-Vector3.Dot(actualLightVector, _normal)) * Mathf.Rad2Deg;
            if (angleToNormal > _angleFadeMax)
            {
                // Skip shadows that fall with extreme angles
                _isVisible = false;
                return(RecalculateShadowResult.Skipped);
            }

            // Determine the forward direction of shadow base quad
            Vector3 forward;
            float   dot = Vector3.Dot(transformForward, actualLightVector);
            if (Mathf.Abs(dot) < 1f - Vector3.kEpsilon)
            {
                forward = (transformForward - dot * actualLightVector).FastNormalized();
            }
            else
            {
                // If the forward direction matches the light direction vector somehow
                Vector3 transformUp = _transform.up;
                forward = (transformUp - Vector3.Dot(transformUp, actualLightVector) * actualLightVector).FastNormalized();
            }

            // Rotation of shadow base quad
            Quaternion rotation = Quaternion.LookRotation(forward, -actualLightVector);

            // Optimized version of
            // Vector3 right = rotation * Vector3.right;
            float   num2  = rotation.y * 2f;
            float   num3  = rotation.z * 2f;
            float   num5  = rotation.y * num2;
            float   num6  = rotation.z * num3;
            float   num7  = rotation.x * num2;
            float   num8  = rotation.x * num3;
            float   num11 = rotation.w * num2;
            float   num12 = rotation.w * num3;
            Vector3 right;
            right.x = 1f - (num5 + num6);
            right.y = num7 + num12;
            right.z = num8 - num11;

            // Base vertices calculation
            float scaledShadowSize = scaledDoubleShadowSize * 0.5f;
            float aspectRatioInv   = 1f / _aspectRatio;

            Vector3 diff;
            diff.x = (forward.x - right.x * aspectRatioInv) * scaledShadowSize;
            diff.y = (forward.y - right.y * aspectRatioInv) * scaledShadowSize;
            diff.z = (forward.z - right.z * aspectRatioInv) * scaledShadowSize;
            Vector3 sum;
            sum.x = (forward.x + right.x * aspectRatioInv) * scaledShadowSize;
            sum.y = (forward.y + right.y * aspectRatioInv) * scaledShadowSize;
            sum.z = (forward.z + right.z * aspectRatioInv) * scaledShadowSize;

            Vector3 baseVertex;
            baseVertex.x     = transformPosition.x - sum.x;
            baseVertex.y     = transformPosition.y - sum.y;
            baseVertex.z     = transformPosition.z - sum.z;
            _baseVertices[0] = baseVertex;

            baseVertex.x     = transformPosition.x + diff.x;
            baseVertex.y     = transformPosition.y + diff.y;
            baseVertex.z     = transformPosition.z + diff.z;
            _baseVertices[1] = baseVertex;

            baseVertex.x     = transformPosition.x + sum.x;
            baseVertex.y     = transformPosition.y + sum.y;
            baseVertex.z     = transformPosition.z + sum.z;
            _baseVertices[2] = baseVertex;

            baseVertex.x     = transformPosition.x - diff.x;
            baseVertex.y     = transformPosition.y - diff.y;
            baseVertex.z     = transformPosition.z - diff.z;
            _baseVertices[3] = baseVertex;

            // Calculate a plane from normal and position
            SS_Plane shadowPlane = new SS_Plane();
            shadowPlane.SetNormalAndPosition(_normal, hitInfo.point + _normal * _shadowOffset);

            float  distanceToPlane;
            SS_Ray ray = new SS_Ray();

            // Calculate the shadow vertices
            if (_isPerspectiveProjection && useLightSource)
            {
                ray.direction = lightSourcePosition - _baseVertices[0];
                ray.origin    = _baseVertices[0];
                shadowPlane.Raycast(ref ray, out distanceToPlane);
                _shadowVertices[0] = ray.origin + ray.direction * distanceToPlane;

                ray.direction = lightSourcePosition - _baseVertices[1];
                ray.origin    = _baseVertices[1];
                shadowPlane.Raycast(ref ray, out distanceToPlane);
                _shadowVertices[1] = ray.origin + ray.direction * distanceToPlane;

                ray.direction = lightSourcePosition - _baseVertices[2];
                ray.origin    = _baseVertices[2];
                shadowPlane.Raycast(ref ray, out distanceToPlane);
                _shadowVertices[2] = ray.origin + ray.direction * distanceToPlane;

                ray.direction = lightSourcePosition - _baseVertices[3];
                ray.origin    = _baseVertices[3];
                shadowPlane.Raycast(ref ray, out distanceToPlane);
                _shadowVertices[3] = ray.origin + ray.direction * distanceToPlane;
            }
            else
            {
                ray.direction = actualLightVector;

                ray.origin = _baseVertices[0];
                shadowPlane.Raycast(ref ray, out distanceToPlane);
                _shadowVertices[0] = ray.origin + ray.direction * distanceToPlane;

                ray.origin = _baseVertices[1];
                shadowPlane.Raycast(ref ray, out distanceToPlane);
                _shadowVertices[1] = ray.origin + ray.direction * distanceToPlane;

                ray.origin = _baseVertices[2];
                shadowPlane.Raycast(ref ray, out distanceToPlane);
                _shadowVertices[2] = ray.origin + ray.direction * distanceToPlane;

                ray.origin = _baseVertices[3];
                shadowPlane.Raycast(ref ray, out distanceToPlane);
                _shadowVertices[3] = ray.origin + ray.direction * distanceToPlane;
            }

            // Calculate the shadow alpha
            float shadowAlpha = _initialAlpha;

            // Alpha base on distance to the surface
            float distance = hitInfo.distance;
            if (distance > _fadeDistance)
            {
                shadowAlpha = shadowAlpha - (distance - _fadeDistance) / (_projectionDistance - _fadeDistance) * shadowAlpha;
            }

            // Alpha based on shadow fall angle
            if (angleToNormal > _angleFadeMin)
            {
                shadowAlpha = shadowAlpha - (angleToNormal - _angleFadeMin) / (_angleFadeMax - _angleFadeMin) * shadowAlpha;
            }

            // Convert float alpha to byte
            _color.a   = shadowAlpha;
            _color32.a = (byte)(shadowAlpha * 255f);

            _isVisible = true;
        }

        return(RecalculateShadowResult.Recalculated);
    }