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); }
/// <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); }
/// <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); }
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); }
/// <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(); } }
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); } }
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 }); }
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); }
public static IntersectTriangleResult?IntersectTriangle(this RayEntity rayEntity, TriangleEntity polygon) { return(rayEntity.IntersectTriangle(polygon.VertexA, polygon.VertexB, polygon.VertexC, polygon.Normal)); }
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); }