示例#1
0
        protected void RecalculateEditorShip(ShipConstruct ship)
        {
            if (ship != null)
            {
                for (int i = 0; i < allRadSources.Count; i++)
                {
                    UnregisterSource(allRadSources[i]);
                }
                for (int i = 0; i < allRadSinks.Count; i++)
                {
                    UnregisterSink(allRadSinks[i]);
                }

                for (int i = 0; i < ship.Parts.Count; i++)
                {
                    RadioactiveSource src = ship.Parts[i].gameObject.GetComponent <RadioactiveSource>();
                    RadioactiveSink   snk = ship.Parts[i].gameObject.GetComponent <RadioactiveSink>();

                    if (src != null)
                    {
                        RegisterSource(src);
                    }
                    if (snk != null)
                    {
                        RegisterSink(snk);
                    }
                }
            }
        }
        // Computes LOS between a source and a sink
        // Returns the list of parts between the two objects
        protected List <AttenuationZone> GetLineOfSight(RadioactiveSource src, RadioactiveSink target)
        {
            RaycastHit[] hits1;
            RaycastHit[] hits2;
            float        sep = Vector3.Distance(src.EmitterTransform.position, target.SinkTransform.position);
            // Only cast against Default and Terrain
            LayerMask mask;
            LayerMask maskA = 1 << LayerMask.NameToLayer("Default");
            LayerMask maskB = 1 << LayerMask.NameToLayer("TerrainColliders");
            LayerMask maskC = 1 << LayerMask.NameToLayer("Local Scenery");

            mask = maskA | maskB | maskC;

            // raycast from the source to target and vice versa
            hits1 = Physics.RaycastAll(src.EmitterTransform.position, target.SinkTransform.position - src.EmitterTransform.position, sep, mask);
            hits2 = Physics.RaycastAll(target.SinkTransform.position, src.EmitterTransform.position - target.SinkTransform.position, sep, mask);

            List <RaycastHit> hitsBackward = hits2.ToList();
            List <RaycastHit> hitsForward  = hits1.ToList();

            /// sort by distance, ascending
            if (hitsForward.Count > 0)
            {
                hitsForward = hitsForward.OrderBy(o => o.distance).ToList();
            }
            if (hitsBackward.Count > 0)
            {
                hitsBackward = hitsBackward.OrderByDescending(o => o.distance).ToList();
            }


            return(CreatePathway(hitsForward, hitsBackward, src, target, sep));
        }
示例#3
0
 // Build new link for a new sink in the network
 protected void BuildNewRadiationLink(RadioactiveSink snk)
 {
     for (int i = 0; i < allRadSources.Count; i++)
     {
         RadiationLink l = new RadiationLink(allRadSources[i], snk);
         allLinks.Add(l);
     }
 }
        public RadiationLink(RadioactiveSource src, RadioactiveSink snk)
        {
            fluxStart = RadioactivitySettings.defaultRaycastFluxStart;
            source = src;
            sink = snk;
            if (Radioactivity.Instance.RayOverlayShown)
                ShowOverlay();

            //ComputeConnection(src, snk);
        }
示例#5
0
 public void HideOverlay(RadioactiveSink snk)
 {
     for (int i = 0; i < allLinks.Count; i++)
     {
         if (allLinks[i].sink == snk)
         {
             allLinks[i].HideOverlay();
         }
     }
 }
示例#6
0
 public void ShowOverlay(RadioactiveSink snk)
 {
     for (int i = 0; i < allLinks.Count; i++)
     {
         if (allLinks[i].sink == snk && !allLinks[i].overlayShown)
         {
             allLinks[i].ShowOverlay();
         }
     }
 }
示例#7
0
 // Add a radiation sink to the sink list
 public void RegisterSink(RadioactiveSink snk)
 {
     allRadSinks.Add(snk);
     BuildNewRadiationLink(snk);
     pointRadiationNetworkChanged = true;
     if (RadioactivitySettings.debugNetwork)
     {
         Utils.Log("Network: Adding radiation sink " + snk.SinkID + " on part " + snk.part.name + " to simulator");
     }
 }
        public RadiationLink(RadioactiveSource src, RadioactiveSink snk)
        {
            fluxStart = RadioactivitySettings.defaultRaycastFluxStart;
            source    = src;
            sink      = snk;
            if (Radioactivity.Instance.RayOverlayShown)
            {
                ShowOverlay();
            }

            //ComputeConnection(src, snk);
        }
示例#9
0
        // Remove a radiation sink from the sink list
        public void UnregisterSink(RadioactiveSink snk)
        {
            if (allRadSinks.Count > 0)
            {
                pointRadiationNetworkChanged = true;
                RemoveRadiationLink(snk);
                allRadSinks.Remove(snk);

                if (RadioactivitySettings.debugNetwork && snk != null)
                {
                    Utils.Log("Network: Removing radiation sink " + snk.SinkID + " on part " + snk.part.name + " from simulator");
                }
            }
        }
示例#10
0
        protected void TryAddSink(RadioactiveSink snk)
        {
            bool exists = false;

            for (int i = 0; i < allRadSinks.Count; i++)
            {
                if (allRadSinks[i] == snk)
                {
                    exists = true;
                }
            }
            if (!exists)
            {
                this.RegisterSink(snk);
            }
        }
        // Compute the ray path between the source and sink
        public void ComputeGeometry(RadioactiveSource src, RadioactiveSink target)
        {
            if (RadioactivitySettings.debugNetwork)
            {
                Utils.Log("Network: Creating connection from " + src.part.name + " to " + target.part.name);
            }

            // Store the relative position of both endpoints
            relPos = Utils.getRelativePosition(src.EmitterTransform, target.SinkTransform.position);//src.EmitterTransform.position - target.SinkTransform.position;

            // Gets parts between source and sink
            attenuationPath = GetLineOfSight(src, target);

            // Attenuate the ray between these
            fluxStart    = src.AttenuateShadowShields(target.SinkTransform.position - src.EmitterTransform.position);
            fluxEndScale = AttenuateFlux(attenuationPath, fluxStart);

            needsGeometricRecalculation = false;
        }
示例#12
0
        protected void AddEVARadioactivityTrackers(Part p)
        {
            if (p.GetComponent <RadioactiveSink>() != null)
            {
                Utils.Log("EVA: Module already exists");
            }
            else
            {
                Utils.Log("EVA: Adding modules");
                RadioactiveSink sink = p.gameObject.AddComponent <RadioactiveSink>();
                RadiationShieldedCrewContainer tracker = p.gameObject.AddComponent <RadiationShieldedCrewContainer>();

                sink.SinkID        = "Kerbal";
                sink.IconID        = 3;
                tracker.AbsorberID = "Kerbal";
                tracker.RadiationAttenuationFraction = 0.0f;
                evaModified = true;
            }
        }
示例#13
0
        // Removes a link to a given radiation sink
        protected void RemoveRadiationLink(RadioactiveSink snk)
        {
            List <RadiationLink> toRm = new List <RadiationLink>();

            for (int i = 0; i < allLinks.Count; i++)
            {
                if (allLinks[i].sink == snk)
                {
                    toRm.Add(allLinks[i]);
                }
            }
            if (toRm.Count > 0)
            {
                for (int i = 0; i < toRm.Count; i++)
                {
                    toRm[i].HideOverlay();
                    toRm[i].CleanupSink();
                    allLinks.Remove(toRm[i]);
                }
            }
        }
 protected void TryAddSink(RadioactiveSink snk)
 {
     bool exists = false;
     for (int i=0; i< allRadSinks.Count; i++)
     {
     if (allRadSinks[i] == snk)
         exists = true;
     }
     if (!exists)
     this.RegisterSink(snk);
 }
 // Removes a link to a given radiation sink
 protected void RemoveRadiationLink(RadioactiveSink snk)
 {
     List <RadiationLink> toRm = new List<RadiationLink>();
     for (int i = 0; i < allLinks.Count; i++)
     {
     if (allLinks[i].sink == snk)
     {
         toRm.Add(allLinks[i]);
     }
     }
     if (toRm.Count> 0)
     {
     for (int i = 0; i < toRm.Count; i++)
     {
         toRm[i].HideOverlay();
         toRm[i].CleanupSink();
         allLinks.Remove(toRm[i]);
     }
     }
 }
        // Build new link for a new sink in the network
        protected void BuildNewRadiationLink(RadioactiveSink snk)
        {
            for (int i=0; i< allRadSources.Count; i++)
            {
               RadiationLink l = new RadiationLink(allRadSources[i], snk);
               allLinks.Add(l);

            }
        }
        // Remove a radiation sink from the sink list
        public void UnregisterSink(RadioactiveSink snk)
        {
            if (allRadSinks.Count > 0)
            {
            pointRadiationNetworkChanged = true;
            RemoveRadiationLink(snk);
            allRadSinks.Remove(snk);

            if (RadioactivitySettings.debugNetwork && snk != null)
                Utils.Log("Network: Removing radiation sink " + snk.SinkID + " on part " + snk.part.name + " from simulator");
            }
        }
 public void ShowOverlay(RadioactiveSink snk)
 {
     for (int i = 0; i < allLinks.Count; i++)
       {
       if (allLinks[i].sink == snk && !allLinks[i].overlayShown)
     {
       allLinks[i].ShowOverlay();
     }
       }
 }
 // Add a radiation sink to the sink list
 public void RegisterSink(RadioactiveSink snk)
 {
     allRadSinks.Add(snk);
       BuildNewRadiationLink(snk);
       pointRadiationNetworkChanged = true;
       if (RadioactivitySettings.debugNetwork)
       Utils.Log("Network: Adding radiation sink "+ snk.SinkID +" on part " + snk.part.name + " to simulator");
 }
 public void HideOverlay(RadioactiveSink snk)
 {
     for (int i = 0; i < allLinks.Count; i++)
       {
     if (allLinks[i].sink == snk)
     {
       allLinks[i].HideOverlay();
     }
       }
 }
        // Compute the ray path between the source and sink
        public void ComputeGeometry(RadioactiveSource src, RadioactiveSink target)
        {
            if (RadioactivitySettings.debugNetwork)
                Utils.Log("Network: Creating connection from " + src.part.name + " to " + target.part.name);

            // Store the relative position of both endpoints
            relPos = Utils.getRelativePosition(src.EmitterTransform, target.SinkTransform.position);//src.EmitterTransform.position - target.SinkTransform.position;

            // Gets parts between source and sink
            attenuationPath = GetLineOfSight(src, target);

            // Attenuate the ray between these
            fluxStart = src.AttenuateShadowShields(target.SinkTransform.position- src.EmitterTransform.position);
            fluxEndScale = AttenuateFlux(attenuationPath, fluxStart);

            needsGeometricRecalculation = false;
        }
        // Computes LOS between a source and a sink
        // Returns the list of parts between the two objects
        protected List<AttenuationZone> GetLineOfSight(RadioactiveSource src, RadioactiveSink target)
        {
            RaycastHit[] hits1;
            RaycastHit[] hits2;
            float sep = Vector3.Distance(src.EmitterTransform.position, target.SinkTransform.position);
            // Only cast against Default and Terrain
            LayerMask mask;
            LayerMask maskA = 1 << LayerMask.NameToLayer("Default");
            LayerMask maskB = 1 << LayerMask.NameToLayer("TerrainColliders");
            LayerMask maskC = 1 << LayerMask.NameToLayer("Local Scenery");

            mask = maskA | maskB | maskC;

            // raycast from the source to target and vice versa
            hits1 = Physics.RaycastAll(src.EmitterTransform.position, target.SinkTransform.position - src.EmitterTransform.position, sep, mask);
            hits2 = Physics.RaycastAll(target.SinkTransform.position, src.EmitterTransform.position - target.SinkTransform.position, sep, mask);

            List<RaycastHit> hitsBackward = hits2.ToList();
            List<RaycastHit> hitsForward = hits1.ToList();

            /// sort by distance, ascending
            if (hitsForward.Count > 0)
            {

                hitsForward = hitsForward.OrderBy(o => o.distance).ToList();
            }
            if (hitsBackward.Count > 0)
            {

                hitsBackward = hitsBackward.OrderByDescending(o => o.distance).ToList();
            }

            return CreatePathway(hitsForward, hitsBackward, src, target, sep);
        }
        // Go through raycast results (both ways) in order to create the attenuation path
        protected List<AttenuationZone> CreatePathway(List<RaycastHit> outgoing, List<RaycastHit> incoming, RadioactiveSource src, RadioactiveSink target, float totalPathLength)
        {
            List<AttenuationZone> attens = new List<AttenuationZone>();
            if (RadioactivitySettings.debugRaycasting)
                Utils.Log("Raycaster: Looking along a distance of " +totalPathLength.ToString() + " with "+ outgoing.Count +  " hits");
            float curZoneStartDistance = RadioactivitySettings.defaultSourceFluxDistance;
            float curZoneEndDistance = 0.01f;
            Vector3 curZoneStartPoint = src.EmitterTransform.position + (target.SinkTransform.position - src.EmitterTransform.position).normalized*curZoneStartDistance;
            Vector3 curZoneEndPoint = target.SinkTransform.position;

            int hitNum = 0;
            // for each object we hit outgoing, see if we found it incoming
            for (int i=0; i < outgoing.Count; i++)
            {
                if (RadioactivitySettings.debugRaycasting)
                    Utils.Log("Raycaster: Looking for incoming rayhits with " + outgoing[i].collider.name);

                RaycastHit found = incoming.Find(item => item.collider == outgoing[i].collider);

                // If there is a matching collider
                if (found.collider != null)
                {
                    curZoneEndDistance = outgoing[i].distance;
                    curZoneEndPoint = outgoing[i].point;

                    if (curZoneEndDistance - curZoneStartDistance > 0f)
                    {
                        attens.Add(new AttenuationZone(curZoneStartDistance, curZoneEndDistance, curZoneStartPoint, curZoneEndPoint));
                        curZoneStartPoint = curZoneEndPoint;
                        curZoneStartDistance = curZoneEndDistance;
                    }

                    int layer = found.collider.gameObject.layer;
                    if (RadioactivitySettings.debugRaycasting)
                        Utils.Log("Raycaster: Hit on layer " + LayerMask.LayerToName(layer));

                    if (layer == LayerMask.NameToLayer("Default"))
                    {
                        Part associatedPart = outgoing[i].collider.GetComponentInParent<Part>();
                        if (RadioactivitySettings.debugRaycasting)
                            Utils.Log("Raycaster: Located 2-way hit! Path through is of L: " + (totalPathLength - outgoing[i].distance - found.distance).ToString() + " and part is " + associatedPart.ToString());
                        if (associatedPart != target.part)
                        {

                            curZoneStartPoint = outgoing[i].point;
                            curZoneEndPoint = found.point;
                            curZoneStartDistance = outgoing[i].distance;
                            curZoneEndDistance = totalPathLength - found.distance;

                            attens.Add(new AttenuationZone(curZoneStartDistance, curZoneEndDistance, associatedPart, curZoneStartPoint, curZoneEndPoint));
                        }
                    }
                    if (found.collider.gameObject.layer == LayerMask.NameToLayer("TerrainColliders"))
                    {
                        if (RadioactivitySettings.debugRaycasting)
                            Utils.Log("Raycaster: Located 2-way hit! Path through is of L: " + (totalPathLength - outgoing[i].distance - found.distance).ToString() + " on terraincolliders layer");
                        curZoneStartPoint = outgoing[i].point;
                        curZoneEndPoint = found.point;
                        curZoneStartDistance = outgoing[i].distance;
                        curZoneEndDistance = totalPathLength - found.distance;
                        attens.Add(new AttenuationZone(outgoing[i].distance, totalPathLength - found.distance, AttenuationType.Terrain, outgoing[i].point, found.point));
                    }
                    if (found.collider.gameObject.layer == LayerMask.NameToLayer("Local Scenery"))
                    {
                        if (RadioactivitySettings.debugRaycasting)
                            Utils.Log("Raycaster: Located 2-way hit! Path through is of L: " + (totalPathLength - outgoing[i].distance - found.distance).ToString() + " on LocalScenery layer");
                        curZoneStartPoint = outgoing[i].point;
                        curZoneEndPoint = found.point;
                        curZoneStartDistance = outgoing[i].distance;
                        curZoneEndDistance = totalPathLength - found.distance;
                        attens.Add(new AttenuationZone(outgoing[i].distance, totalPathLength - found.distance, AttenuationType.Terrain, outgoing[i].point, found.point));
                    }
                    hitNum++;
                }
                else
                {
                    if (RadioactivitySettings.debugRaycasting)
                        Utils.Log("Raycaster: No incoming hits with " + outgoing[i].collider.name + ", discarding...");
                }

            }

            curZoneEndPoint = target.SinkTransform.position;
            if (hitNum > 0)
                curZoneStartDistance = curZoneEndDistance;
            curZoneEndDistance = totalPathLength;
            attens.Add(new AttenuationZone(curZoneStartDistance, curZoneEndDistance, curZoneStartPoint, curZoneEndPoint));

            // TODO: Need to add another AttenuationZone if we start inside a part. probably take the last hit in the incoming array to do this (not the best assumption)
            // TODO: Need to add another AttenuationZone to account for the target part. probably take the last hit in the outgoing array to do this (good assumption)

            // Add the empty space as a single zone
            //if (totalPathLength > 0f)
            //    attens.Add(new AttenuationZone(totalPathLength, src.EmitterTransform.position, target.SinkTransform.position));

            return attens;
        }
        // Go through raycast results (both ways) in order to create the attenuation path
        protected List <AttenuationZone> CreatePathway(List <RaycastHit> outgoing, List <RaycastHit> incoming, RadioactiveSource src, RadioactiveSink target, float totalPathLength)
        {
            List <AttenuationZone> attens = new List <AttenuationZone>();

            if (RadioactivitySettings.debugRaycasting)
            {
                Utils.Log("Raycaster: Looking along a distance of " + totalPathLength.ToString() + " with " + outgoing.Count + " hits");
            }
            float   curZoneStartDistance = RadioactivitySettings.defaultSourceFluxDistance;
            float   curZoneEndDistance   = 0.01f;
            Vector3 curZoneStartPoint    = src.EmitterTransform.position + (target.SinkTransform.position - src.EmitterTransform.position).normalized * curZoneStartDistance;
            Vector3 curZoneEndPoint      = target.SinkTransform.position;

            int hitNum = 0;

            // for each object we hit outgoing, see if we found it incoming
            for (int i = 0; i < outgoing.Count; i++)
            {
                if (RadioactivitySettings.debugRaycasting)
                {
                    Utils.Log("Raycaster: Looking for incoming rayhits with " + outgoing[i].collider.name);
                }

                RaycastHit found = incoming.Find(item => item.collider == outgoing[i].collider);

                // If there is a matching collider
                if (found.collider != null)
                {
                    curZoneEndDistance = outgoing[i].distance;
                    curZoneEndPoint    = outgoing[i].point;

                    if (curZoneEndDistance - curZoneStartDistance > 0f)
                    {
                        attens.Add(new AttenuationZone(curZoneStartDistance, curZoneEndDistance, curZoneStartPoint, curZoneEndPoint));
                        curZoneStartPoint    = curZoneEndPoint;
                        curZoneStartDistance = curZoneEndDistance;
                    }

                    int layer = found.collider.gameObject.layer;
                    if (RadioactivitySettings.debugRaycasting)
                    {
                        Utils.Log("Raycaster: Hit on layer " + LayerMask.LayerToName(layer));
                    }

                    if (layer == LayerMask.NameToLayer("Default"))
                    {
                        Part associatedPart = outgoing[i].collider.GetComponentInParent <Part>();
                        if (RadioactivitySettings.debugRaycasting)
                        {
                            Utils.Log("Raycaster: Located 2-way hit! Path through is of L: " + (totalPathLength - outgoing[i].distance - found.distance).ToString() + " and part is " + associatedPart.ToString());
                        }
                        if (associatedPart != target.part)
                        {
                            curZoneStartPoint    = outgoing[i].point;
                            curZoneEndPoint      = found.point;
                            curZoneStartDistance = outgoing[i].distance;
                            curZoneEndDistance   = totalPathLength - found.distance;

                            attens.Add(new AttenuationZone(curZoneStartDistance, curZoneEndDistance, associatedPart, curZoneStartPoint, curZoneEndPoint));
                        }
                    }
                    if (found.collider.gameObject.layer == LayerMask.NameToLayer("TerrainColliders"))
                    {
                        if (RadioactivitySettings.debugRaycasting)
                        {
                            Utils.Log("Raycaster: Located 2-way hit! Path through is of L: " + (totalPathLength - outgoing[i].distance - found.distance).ToString() + " on terraincolliders layer");
                        }
                        curZoneStartPoint    = outgoing[i].point;
                        curZoneEndPoint      = found.point;
                        curZoneStartDistance = outgoing[i].distance;
                        curZoneEndDistance   = totalPathLength - found.distance;
                        attens.Add(new AttenuationZone(outgoing[i].distance, totalPathLength - found.distance, AttenuationType.Terrain, outgoing[i].point, found.point));
                    }
                    if (found.collider.gameObject.layer == LayerMask.NameToLayer("Local Scenery"))
                    {
                        if (RadioactivitySettings.debugRaycasting)
                        {
                            Utils.Log("Raycaster: Located 2-way hit! Path through is of L: " + (totalPathLength - outgoing[i].distance - found.distance).ToString() + " on LocalScenery layer");
                        }
                        curZoneStartPoint    = outgoing[i].point;
                        curZoneEndPoint      = found.point;
                        curZoneStartDistance = outgoing[i].distance;
                        curZoneEndDistance   = totalPathLength - found.distance;
                        attens.Add(new AttenuationZone(outgoing[i].distance, totalPathLength - found.distance, AttenuationType.Terrain, outgoing[i].point, found.point));
                    }
                    hitNum++;
                }
                else
                {
                    if (RadioactivitySettings.debugRaycasting)
                    {
                        Utils.Log("Raycaster: No incoming hits with " + outgoing[i].collider.name + ", discarding...");
                    }
                }
            }

            curZoneEndPoint = target.SinkTransform.position;
            if (hitNum > 0)
            {
                curZoneStartDistance = curZoneEndDistance;
            }
            curZoneEndDistance = totalPathLength;
            attens.Add(new AttenuationZone(curZoneStartDistance, curZoneEndDistance, curZoneStartPoint, curZoneEndPoint));

            // TODO: Need to add another AttenuationZone if we start inside a part. probably take the last hit in the incoming array to do this (not the best assumption)
            // TODO: Need to add another AttenuationZone to account for the target part. probably take the last hit in the outgoing array to do this (good assumption)

            // Add the empty space as a single zone
            //if (totalPathLength > 0f)
            //    attens.Add(new AttenuationZone(totalPathLength, src.EmitterTransform.position, target.SinkTransform.position));

            return(attens);
        }