Exemplo n.º 1
0
        public static IntersectTriangleResult?IntersectTriangle(this RayEntity rayEntity, Vector3 vertexA, Vector3 vertexB, Vector3 vertexC, Vector3 normal)
        {
            var denom = Vector3.Dot(rayEntity.Direction, normal);

            if (Math.Abs(denom) < double.Epsilon)
            {
                return(null);
            }
            var t = -(Vector3.Dot(vertexA, -normal) + Vector3.Dot(rayEntity.Origin, normal)) / denom;

            if (t < 0)
            {
                return(null);
            }

            var point = rayEntity.Origin + rayEntity.Direction * t;

            if (point.IntersectTriangle(vertexA, vertexB, vertexC))
            {
                return(new IntersectTriangleResult()
                {
                    Point = point,
                    Distance = t,
                });
            }

            return(null);
        }
Exemplo n.º 2
0
    /// <summary>
    /// override the border info
    /// </summary>
    /// <param name="_vertexBuffer"></param>
    protected override void AddCorner(ArrayList _vertexBuffer)
    {
        // target position
        Vector3 tartget = transform.position + transform.up * mRange;

        if (mSuperFit)
        {
            // calculate the fineness of each step
            float fineness = (float)mFineness / 10.0f;

            // current step and angle
            float currentDegree = -mSpotArea + fineness;

            // cast ray
            while (currentDegree < mSpotArea)
            {
                RayEntity ray = DetectRaybyOffset(new Vector3(transform.position.x, transform.position.y), new Vector3(tartget.x, tartget.y), currentDegree, mRelative);
                _vertexBuffer.Add(ray);
                currentDegree += fineness;
            }
        }


        // Add the border of the light , this will low the mistake
        RayEntity downBorder = DetectRaybyOffset(new Vector3(transform.position.x, transform.position.y), new Vector3(tartget.x, tartget.y), -mSpotArea, mRelative);
        RayEntity upBorder   = DetectRaybyOffset(new Vector3(transform.position.x, transform.position.y), new Vector3(tartget.x, tartget.y), mSpotArea, mRelative);

        _vertexBuffer.Add(downBorder);
        _vertexBuffer.Add(upBorder);
    }
Exemplo n.º 3
0
    /// <summary>
    /// Detect a line cast to the Obstacle in scene
    /// </summary>
    /// <param name="_org">start point</param>
    /// <param name="_target">target point</param>
    /// <param name="_angle">offset angle</param>
    /// <returns></returns>
    protected RayEntity DetectRaybyOffset(Vector3 _org, Vector3 _target, float _angle, Vector3 _relative)
    {
        // calculate the quaternion of the offset
        mQuatToward = Quaternion.AngleAxis(_angle, RayEntity.TOP_TOWORADS);

        // calculate new dir
        Vector3 towards = mQuatToward * (_target - _org).normalized;

        // get the hit of the ray
        mHit = Physics2D.Raycast(new Vector2(_org.x, _org.y), new Vector2(towards.x, towards.y), mRange, mObstacleLayers.value);

        // create rayEntity struct and return
        RayEntity rayEntity;

        if (mHit)
        {
            rayEntity = new RayEntity(mHit.point, _org, mHit, _relative);
        }
        else
        {
            // if not hitted ,return the range
            rayEntity = new RayEntity(_org + mRange * towards, _org, mHit, _relative);
        }

        //Debug.DrawLine(_org, rayEntity.vertex);
        return(rayEntity);
    }
Exemplo n.º 4
0
    void Update()
    {
        // if the light did not on , return
        if (!on)
        {
            mMeshFilter.gameObject.SetActive(false);
            return;
        }
        else if (!mMeshFilter.gameObject.activeSelf)
        {
            mMeshFilter.gameObject.SetActive(true);
        }

        // get the vertexBuufer if dynamic draw shadow
        GetVertexsBuffer();

        // light world poition
        Vector3 lightPoint = transform.position;

        // light world position2D
        Vector2 lightPoint2D = new Vector2(lightPoint.x, lightPoint.y);

        // light world position3D ,this was cut the z axis
        Vector3 lightPoint3D = new Vector3(lightPoint2D.x, lightPoint2D.y);

        // the vertexArray wait to be sorted
        ArrayList entityList = new ArrayList();

        for (int i = 0; i < mVertexSet.Length; i++)
        {
            // get current vertex data
            Vector2 vertex = new Vector2(mVertexSet[i].x, mVertexSet[i].y);

            // check whether the vertex is the edge or not
            // and cast ray and add sort Array
            // ..
            // ..
            //
            RayEntity entity      = DetectRaybyOffset(lightPoint3D, new Vector3(vertex.x, vertex.y), 0);
            RayEntity entityLeft  = DetectRaybyOffset(lightPoint3D, new Vector3(vertex.x, vertex.y), -OFFSET_ANGLE);
            RayEntity entityRight = DetectRaybyOffset(lightPoint3D, new Vector3(vertex.x, vertex.y), OFFSET_ANGLE);

            entityList.Add(entity);
            entityList.Add(entityLeft);
            entityList.Add(entityRight);
        }

        // add corner
        AddCorner(entityList);

        // sort the vertexs
        entityList.Sort(mComaparer);

        // update mesh
        UpdateMesh(entityList, lightPoint3D, true);
    }
Exemplo n.º 5
0
        /// <summary>
        /// Picks a ray.
        /// </summary>
        private void PickRay()
        {
            float     entityCount = this._backgroundEnvironment.Count;
            RayEntity ray         = this._backgroundEnvironment
                                    .OfType <RayEntity>()
                                    .FirstOrDefault(r => this._random.NextBoolean(1.0f / entityCount));

            if (ray != null)
            {
                ray.Pick();
            }
        }
Exemplo n.º 6
0
    public int Compare(object x, object y)
    {
        RayEntity a = (RayEntity)x;
        RayEntity b = (RayEntity)y;

        if (a.angle > b.angle)
        {
            return(1);
        }
        else if (a.angle < b.angle)
        {
            return(-1);
        }
        else
        {
            return(0);
        }
    }
Exemplo n.º 7
0
        private SceneIntersectResult SceneIntersect(RayEntity rayEntity, float?distanceMax = null)
        {
            CollisionResult collisionRef = null;
            float?          distanceMin  = null;
            IEssence        essenceRef   = null;

            foreach (var essence in essences)
            {
                var collision = essence.CheckCollision(rayEntity);

                if (collision == null)
                {
                    continue;
                }

                var distance = (rayEntity.Origin - collision.Point).Length();
                if (distanceMax != null && distanceMax < distance)
                {
                    continue;
                }

                if (distanceMin == null ^ distanceMin > distance)
                {
                    distanceMin  = distance;
                    essenceRef   = essence;
                    collisionRef = collision;
                }
            }

            if (essenceRef == null)
            {
                return(null);
            }

            return(new SceneIntersectResult()
            {
                Essence = essenceRef,
                Collision = collisionRef
            });
        }
Exemplo n.º 8
0
    void Update()
    {
        // if the light did not on , return
        if (!on)
        {
            mMeshFilter.gameObject.SetActive(false);
            return;
        }
        else if (!mMeshFilter.gameObject.activeSelf)
        {
            mMeshFilter.gameObject.SetActive(true);
        }

        // get the vertexBuufer if dynamic draw shadow
        GetVertexsBuffer();

        // calculate the relative
        mRelative = Quaternion.AngleAxis(-mSpotArea, RayEntity.TOP_TOWORADS) * transform.up;

        // light world poition
        Vector3 lightPoint = transform.position;

        // light world position2D
        Vector2 lightPoint2D = new Vector2(lightPoint.x, lightPoint.y);

        // light world position3D ,this was cut the z axis
        Vector3 lightPoint3D = new Vector3(lightPoint2D.x, lightPoint2D.y);

        // the vertexArray wait to be sorted
        ArrayList entityList = new ArrayList();

        for (int i = 0; i < mVertexSet.Length; i++)
        {
            // if the light out of the area , the cut the light
            if (Vector3.Angle(new Vector3(mVertexSet[i].x, mVertexSet[i].y) - lightPoint3D, transform.up) >= mSpotArea)
            {
                continue;
            }

            // get current vertex data
            Vector2 vertex = new Vector2(mVertexSet[i].x, mVertexSet[i].y);

            // check whether the vertex is the edge or not
            // and cast ray and add sort Array
            // ..
            // ..
            //
            RayEntity entity      = DetectRaybyOffset(lightPoint3D, new Vector3(vertex.x, vertex.y), 0, mRelative);
            RayEntity entityLeft  = DetectRaybyOffset(lightPoint3D, new Vector3(vertex.x, vertex.y), -OFFSET_ANGLE, mRelative);
            RayEntity entityRight = DetectRaybyOffset(lightPoint3D, new Vector3(vertex.x, vertex.y), OFFSET_ANGLE, mRelative);

            entityList.Add(entity);
            entityList.Add(entityLeft);
            entityList.Add(entityRight);
        }

        // add corner
        this.AddCorner(entityList);

        // sort the vertexs
        entityList.Sort(mComaparer);

        // update mesh
        UpdateMesh(entityList, lightPoint3D, false);

        // Update Shader
        UpdateShader(lightPoint, mRange);
    }
Exemplo n.º 9
0
 public static IntersectTriangleResult?IntersectTriangle(this RayEntity rayEntity, TriangleEntity polygon)
 {
     return(rayEntity.IntersectTriangle(polygon.VertexA, polygon.VertexB, polygon.VertexC, polygon.Normal));
 }
Exemplo n.º 10
0
        private ColorEntity CastRay(RayEntity rayEntity, int depth = 0)
        {
            if (depth > maxDepthReflect)
            {
                return(backgroundColor);
            }

            var intersect = SceneIntersect(rayEntity);

            if (intersect?.Collision == null)
            {
                return(backgroundColor);
            }

            var diffuseLightIntensity  = 0.0f;
            var specularLightIntensity = 0.0f;

            foreach (var light in lights)
            {
                var vectorToLight    = light.Position - intersect.Collision.Point;
                var directionToLight = vectorToLight.Normalize();
                var distanceToLight  = vectorToLight.Length();

                var rayToLight = new RayEntity()
                {
                    Origin = Vector3.Dot(directionToLight, intersect.Collision.Normal) < 0
                        ? intersect.Collision.Point - directionToLight * epsilon
                        : intersect.Collision.Point + directionToLight * epsilon,
                    Direction = directionToLight
                };

                var castRayToLight = SceneIntersect(rayToLight, distanceToLight);

                if (castRayToLight?.Collision == null)
                {
                    diffuseLightIntensity  += (light.Intensity / distanceToLight * distanceToLight) * Math.Max(0.0f, Vector3.Dot(directionToLight, intersect.Collision.Normal));
                    specularLightIntensity += (float)Math.Pow(Math.Max(0.0f, -Vector3.Dot((-directionToLight).Reflect(intersect.Collision.Normal), rayEntity.Direction)), intersect.Essence.Material.Specular) * light.Intensity;
                }
            }

            var reflectColor = new ColorEntity(0.0f, 0.0f, 0.0f);

            if (intersect.Essence.Material.ReflectComponent > 0.0f)
            {
                var reflectDirection = rayEntity.Direction.Reflect(intersect.Collision.Normal).Normalize();
                var reflectionRay    = new RayEntity()
                {
                    Origin = Vector3.Dot(reflectDirection, intersect.Collision.Normal) < 0
                        ? intersect.Collision.Point - intersect.Collision.Normal * epsilon
                        : intersect.Collision.Point + intersect.Collision.Normal * epsilon,
                    Direction = reflectDirection
                };
                reflectColor = CastRay(reflectionRay, depth + 1);
            }

            var result = intersect.Essence.Material.Color * diffuseLightIntensity * intersect.Essence.Material.DiffuseComponent
                         + new ColorEntity(1.0f, 1.0f, 1.0f) * specularLightIntensity * intersect.Essence.Material.SpecularComponent
                         + reflectColor * intersect.Essence.Material.ReflectComponent;

            return(result);
        }