Example #1
0
        public bool IsIdentical(LaserSegment other)
        {
            if (ReferenceEquals(null, other))
            {
                return(false);
            }
            if (ReferenceEquals(this, other))
            {
                return(true);
            }
            if (!(Ray.Equals(other.Ray) &&
                  Depth == other.Depth &&
                  Equals(Color, other.Color) &&
                  EmissionNormal.Equals(other.EmissionNormal) &&
                  Length.Equals(other.Length) &&
                  ImpactNormal.Equals(other.ImpactNormal) &&
                  Children.Count == other.Children.Count
                  ))
            {
                return(false);
            }

            for (int i = 0; i < Children.Count; i++)
            {
                if (!Children[i].IsIdentical(other.Children[i]))
                {
                    return(false);
                }
            }

            return(true);
        }
Example #2
0
        public void EmitSegment(LaserSegment segment)
        {
            RaycastHit hitInfo;
            bool       hit;
            Ray        hitRay = segment.Ray;

            while (true)
            {
                hit = Physics.Raycast(hitRay, out hitInfo, Mathf.Infinity, (int)GameObjectLayer.LayerComponent);

                if (hit && hitInfo.collider.gameObject == gameObject) // self-collision
                {
                    hitRay.origin = hitInfo.point + hitRay.direction * 0.001f;
                }
                else
                {
                    break;
                }
            }
            if (hit)
            {
                // hitInfo.direction will be incorrect if there were self-collisions, so we calculate it
                segment.Length       = (hitInfo.point - segment.Ray.origin).magnitude;
                segment.ImpactNormal = hitInfo.normal;
                var lightComponent = hitInfo.collider.gameObject.GetComponent <LightComponent>();
                if (lightComponent && segment.Depth < 500)
                {
                    lightComponent.Propagate(segment, hitInfo.collider);
                }
            }
            else
            {
                segment.Length = Mathf.Infinity;
            }
        }
        private void DrawSegment(LaserSegment segment, float3 cameraLook,
                                 List <Vector3> vertices, List <Vector3> normals, List <Vector2> uvs, List <int> triangles)
        {
            var transform = this.transform;

            float3 start     = segment.Ray.origin;
            float3 direction = segment.Ray.direction;
            var    distance  = math.isinf(segment.Length) ? 1000 : segment.Length;
            var    end       = start + direction * distance;

            var up     = math.cross(direction, cameraLook);
            var top    = start + up * segment.Color.width / 2;
            var bottom = start - up * segment.Color.width / 2;

            var startTopDistance    = IntersectLinePlane(top, direction, start, segment.EmissionNormal);
            var startBottomDistance = IntersectLinePlane(bottom, direction, start, segment.EmissionNormal);
            var endTopDistance      = IntersectLinePlane(top, direction, end, segment.ImpactNormal);
            var endBottomDistance   = IntersectLinePlane(bottom, direction, end, segment.ImpactNormal);

            var startTop = math.isinf(startTopDistance)
                ? top
                : top + direction * startTopDistance;
            var startBottom = math.isinf(startBottomDistance)
                ? bottom
                : bottom + direction * startBottomDistance;
            var endTop = math.isinf(endTopDistance)
                ? top + direction * distance
                : top + direction * endTopDistance;
            var endBottom = math.isinf(endBottomDistance)
                ? bottom + direction * distance
                : bottom + direction * endBottomDistance;

            var normal = math.cross(up, direction);
            var index  = vertices.Count;

            vertices.Add(transform.InverseTransformPoint(startTop));
            vertices.Add(transform.InverseTransformPoint(startBottom));
            vertices.Add(transform.InverseTransformPoint(endTop));
            vertices.Add(transform.InverseTransformPoint(endBottom));

            normals.Add(normal);
            normals.Add(normal);
            normals.Add(normal);
            normals.Add(normal);

            uvs.Add(vec(0, 0));
            uvs.Add(vec(0, 1));
            uvs.Add(vec(1, 0));
            uvs.Add(vec(1, 1));

            triangles.Add(index + 1); // startBottom
            triangles.Add(index + 2); // endTop
            triangles.Add(index + 0); // startTop

            triangles.Add(index + 1); // startBottom
            triangles.Add(index + 3); // endBottom
            triangles.Add(index + 2); // endTop
        }
        /// <summary>
        ///
        /// </summary>
        /// <returns>true if the laser was updated, false if the segments are identical the current segments</returns>
        public bool UpdateSegment(LaserSegment rootSegment)
        {
            if (rootSegment.IsIdentical(_segment))
            {
                return(false);
            }
            _segment = rootSegment;
            var mesh = _meshFilter.mesh;

            mesh.Clear();

            var segments = new Dictionary <LaserColor, List <LaserSegment> >();

            AddSegments(rootSegment, segments);

            var segmentCount = segments.Sum(it => it.Value.Count);

            var vertices = new List <Vector3>(segmentCount * 4);
            var normals  = new List <Vector3>(segmentCount * 4);
            var uvs      = new List <Vector2>(segmentCount * 4);

            // var triangles = new List<int>(segmentCount * 6);

            mesh.subMeshCount = segments.Count;

            var entries = segments.Select(kp =>
                                          (Color: kp.Key, Segments: kp.Value, Triangles: new List <int>(kp.Value.Count * 6))
                                          ).ToList();

            var subTriangles = new List <List <int> >();
            var cameraLook   = Camera.main.transform.forward;

            for (var i = 0; i < entries.Count; i++)
            {
                var entry = entries[i];
                foreach (var segment in entry.Segments)
                {
                    DrawSegment(segment, cameraLook, vertices, normals, uvs, entry.Triangles);
                }
            }

            mesh.vertices = vertices.ToArray();
            mesh.normals  = normals.ToArray();
            mesh.uv       = uvs.ToArray();

            for (var i = 0; i < entries.Count; i++)
            {
                var entry = entries[i];
                mesh.SetTriangles(entry.Triangles.ToArray(), i);
            }

            _meshRenderer.materials = entries.Select(entry => entry.Color.material).ToArray();


            return(true);
        }
Example #5
0
        public override void Propagate(LaserSegment inputSegment, Collider collider)
        {
            var transformedNormal = transform.TransformDirection(normal);
            var outputDirection   = math.reflect(inputSegment.Ray.direction, transformedNormal);
            var outSegment        = new LaserSegment(
                new Ray(inputSegment.End, outputDirection),
                inputSegment.Depth + 1,
                colorOverride ? colorOverride : inputSegment.Color
                )
            {
                EmissionNormal = math.dot(outputDirection, transformedNormal) >= 0 ? transformedNormal : -transformedNormal
            };

            inputSegment.Add(outSegment);
            EmitSegment(outSegment);
        }
        private void AddSegments(LaserSegment segment, Dictionary <LaserColor, List <LaserSegment> > segments)
        {
            if (segment.Color)
            {
                if (!segments.ContainsKey(segment.Color))
                {
                    segments[segment.Color] = new List <LaserSegment>();
                }
                segments[segment.Color].Add(segment);
            }

            foreach (var child in segment.Children)
            {
                AddSegments(child, segments);
            }
        }
Example #7
0
        public override void Propagate(LaserSegment inputSegment, Collider collider)
        {
            var transformedNormal = transform.TransformDirection(normal);
            var colors            = ColorRegistry.SplitColor(inputSegment.Color);

            if (math.dot(inputSegment.Ray.direction, transformedNormal) >= 0)
            {
                colors = (colors.Item2, colors.Item1);
            }
            {
                var outputDirection = math.reflect(inputSegment.Ray.direction, transformedNormal);
                var outSegment      = new LaserSegment(
                    new Ray(inputSegment.End, outputDirection),
                    inputSegment.Depth + 1,
                    colors.Item1
                    )
                {
                    EmissionNormal = math.dot(outputDirection, transformedNormal) >= 0 ? transformedNormal : -transformedNormal
                };
                inputSegment.Add(outSegment);
                EmitSegment(outSegment);
            }
            {
                var outputDirection = inputSegment.Ray.direction;
                var outSegment      = new LaserSegment(
                    new Ray(inputSegment.End, outputDirection),
                    inputSegment.Depth + 1,
                    colors.Item2
                    )
                {
                    EmissionNormal = math.dot(outputDirection, transformedNormal) >= 0
                        ? transformedNormal
                        : -transformedNormal
                };
                inputSegment.Add(outSegment);
                EmitSegment(outSegment);
            }
        }
Example #8
0
 public override void Propagate(LaserSegment inputSegment, Collider collider)
 {
     realComponent.Propagate(inputSegment, collider);
 }
Example #9
0
 public void Add(LaserSegment segment)
 {
     Children.Add(segment);
 }
 public override void Propagate(LaserSegment inputSegment, Collider collider)
 {
     GetComponent <FXRequests>().requests.Add("laser_wall_sizzle");
 }
Example #11
0
 /**
  * Get a set of output rays given an input ray
  */
 public abstract void Propagate(LaserSegment inputSegment, Collider collider);