Themabewertung:
  • 0 Bewertung(en) - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
Wasserspray Partikel Lastoptimiert
#1
Hallo zusammen,

um unsere Sims aufzuhübschen werden immer mehr Scripte eingesetzt um schöne Partikel zu erzeugen. Das ist auch so sehr gut. Nur leider  sind viele der frei erhältlichen Scipte nicht optimiert um bei größtmöglichen Effekt trotzdem die Serverlast gering zu halten.

Und Scripte laufen auf dem Server! Also auch wenn ihr nicht online seid!

Ich habe mir daher zum Ziel gesetzt hier verschiedene von mir erstellte, weiterentwickelte oder lastoptimierte Scripte zu veröffenlichen, die genau diese Problem bekämpfen.

Alle von mir veröffentlichen Partikel Scripte haben eine Avatar Erkennung, die die Partikel nur einschaltet wenn sie jemand auch sehen kann.
Nachdem die meist Zeit niemand in sichtweite ist, können wir so massiv Serverleistug sparen, die uns in form vom Perfomance Reserve auf den genutzten Sims zur Verfügung stellen. So wird das Grid hübsch und schnell.

Wichtiger Parameter in dem Zusammenhang ist die Intervalldauer in der nach Avataren gescannt wird. Diese sollte so niedrig wie akzeptabel sein. Daher sind meine Scripte in 2 Stati unterteilt: Standby und Aktiv. In beiden Stati wird unterschiedlich oft gescannt.

Eine Anmerkung noch: Partikel Scripte sind sehr abhängig von der verwendeten Simulator~ und Physik Engine Version. Die besten Ergebnisse erzielt man derzeit auf Opensimulator 0.8.2 mit Bulletsim Physik. Unter Arriba mit Bulletsim sieht das Ergebnis mit dagegen sehr mager aus (gefühlte 20% der Partikel). Noch schlimmer ist es unter OpenDynamicsEngine (ca 1% der Partikel).

das Script ist für Arriba eingestellt:       PSYS_SRC_BURST_PART_COUNT, (integer)500,
auf Opensimulator reichen auch 50 Partikel, was ich dringend Empfehle das auf einer Sim die Gesamtzahl der erzeugten Partikel einen Wert von ca. 4000 nicht überschreiten soll! Dabei sind alle Partikel erzeugenden Scripte sowie auch die Lebensdauer der Partikel zu Berücksichtigen.
Wird dieser Wert stark überschritten kann es zum Absturz der Sim kommen.

Das erste Script hier dient der Erzeugung von Wasserspray wie das typischerweise an Felsen im Brandungs Bereich vorkommt.

Wie immmer gilt: Wer mich inworld anspricht kann auch ein fertiges Prim bekommen.
Ich plane auch ein Shop mit fertigen Partikel Erzeugern und Scripten in meiner Venedig sim.


Viel Spaß damit


Tron



Code:
/* P107 Wasser Spray Partikel mit Bewegungsmeldung
*
* getestet auf Opensimulator 0.8.2 und Arriba: TJ/Tron 02.02.2016
*
* Grundzustand: Kein Wasserspray
*               Alle "scantimer" sekunden wird überprüft ob ein Avatar sich in "scandistance" Reichweite befindet.
*
* Befindet sich ein Ava in der Scanzone wird Wasserspray für "effektdauer" Sekunden erzeugt.
* Diese Periode wiederholt sich bis kein Ava gefunden wird.
*/

integer channel = -11000;          // Fernbedienungs Kanal ( gleich mit allen Prims der Funktionseinheit) festlegen.
                                  // Remote communication channel (shared for remote function group)
                                   
float efektdauer = 60.0;           // Dauer des Effekts bis auto Abschaltung
float scantimer  = 10.0;           // Interval der Avatar Suche in Reichweite
float scandistance = 100.0;        // Reichweite der Avatar Erkennung. Auch Höhe beachten!
integer debug = FALSE;             // Debugmodus  [FALSE,TRUE]                                
                                                           
                                                 

updateParticles()                    // Partikelsystem initialisieren und Partikelerzeugung starten
{
  list particle_parameters =
       [          
          PSYS_SRC_TEXTURE, llGetInventoryName(INVENTORY_TEXTURE, 0),
          PSYS_PART_START_SCALE, <1, 1, TRUE>,
          PSYS_PART_END_SCALE, <2, 2, TRUE>,
          PSYS_PART_START_COLOR, <1,1,1>,    
          PSYS_PART_END_COLOR, <0.9,0.9,.9>,
          PSYS_PART_START_ALPHA,  (float)0.1,            
          PSYS_PART_END_ALPHA, (float)0.0,  
          PSYS_SRC_BURST_PART_COUNT, (integer)500,
          PSYS_SRC_BURST_RATE, (float) 2.6,  
          PSYS_PART_MAX_AGE, (float)3.5,
          PSYS_SRC_MAX_AGE,(float) 0.0,  
          PSYS_SRC_PATTERN, (integer)2,
          PSYS_SRC_BURST_SPEED_MIN, (float)1,  
          PSYS_SRC_BURST_SPEED_MAX, (float)1.4,
          PSYS_SRC_BURST_RADIUS, 2.5,
          PSYS_SRC_ANGLE_BEGIN, (float) 0.08*PI,    
          PSYS_SRC_ANGLE_END, (float)0.08*PI,  
          PSYS_SRC_ACCEL, <0.0,0, - 1 >,    
          PSYS_PART_FLAGS, (integer)( 0          
                               | PSYS_PART_INTERP_COLOR_MASK  
                               | PSYS_PART_INTERP_SCALE_MASK  
                               | PSYS_PART_EMISSIVE_MASK    
                           )                    
       ];
   llParticleSystem( particle_parameters );   // Partikelerzeugung starten
}



feedback(integer status)
{
   if(status)      
       {
           updateParticles();                                // Partikel Erzeugung starten
         //  llRegionSay(channel, "Spray");                  // Fernbedienungs Kommando "Aktiviert" regionsweit abschicken
           if(debug) llSay(PUBLIC_CHANNEL, "Spray an");    // User benachrichtigen
       }  
   else
       {
           llParticleSystem( [ ] );                        //Partikel Stoppen
         //  llRegionSay(channel, "keinSpray");            // Fernbedienungs Kommando "Standbye" regionsweit abschicken
           if(debug) llSay(PUBLIC_CHANNEL, "Spray aus");   // User benachrichtigen
       }    
}    



integer avacheck()
{
   list avatars = llGetAgentList(AGENT_LIST_PARCEL, []);     // Avatarliste holen
   integer anzahl;
       
   for (anzahl = 0; anzahl < llGetListLength(avatars); anzahl++) // Avatarabstand durchtesten
       {
           if (llVecDist(llList2Vector(llGetObjectDetails(llList2Key(avatars, anzahl), [OBJECT_POS]),0), llGetPos()) <= scandistance)  
               { return (TRUE);}                              // Schleife beenden, Avatar in Reichweite gefunden            
       }  
   return (FALSE);                                            // kein Avatar gefunden
}



state aktiv                                                 // Status: Partikelerzeugung
{
   state_entry()
   {
       llSetTimerEvent(efektdauer);                        // Zeitdauer setzten in der überprüft wird ob noch ein Avatar in Sichtweite ist  
       feedback(TRUE);                                     // Partikelerzeugung starten
   }

   timer()                                                 // Schleife für Überprüfung ob Avatar noch in Reichweite
   {
       if ( !avacheck()) { state default;}                 // Niemand mehr da, abschalten
   }
   
   changed(integer changebits)                             // Reset nach Region restart
   {
       if(CHANGED_REGION_START & changebits) { llResetScript(); }  
   }
}



default                                                     // Status: Scannen in standby Modus
{
   state_entry()
   {
       llSetTimerEvent(scantimer);                         // Standby Überprüfungs Intervall setzten  
       feedback(FALSE);                                     // Partikelerzeugung abschalten
   }
   
   timer()                                                 // periodicher Check ob Ava in Nähe
   {                
       if ( avacheck()) { state aktiv;}
   }
   
   changed(integer changebits)                             // Reset nach Region restart
   {
       if(CHANGED_REGION_START & changebits) { llResetScript(); }  
   }
}
Antworten }
Thanks given by: Achim
#2
Update zur Reduktion von Scriptlast wenn mehrere Wasser Spray Partikel Rezzer in einer Sim verwendet werden.


Platziere an jeder Stelle der Sim wo ein Wasser Spray hin soll, ein leeres Prim. Verlinke diese, und wähle das Master Prim aus, mit Bearbeiten - Teile .
Das Master Prim ist das Prim das zuletzt zu dem Linkset hinzugefügt wurde, und im Bearbeitungs Fenster die Linknummer 1 trägt.

Hier füge das Script ein, und resette es.


Code:
/* P107L Wasser Spray Partikel für Linkset mit Bewegungsmeldung
*
* getestet auf Opensimulator 0.8.2 und Arriba: TJ/Tron 07.02.2017
*
* Grundzustand: Kein Wasserspray
*               Alle "scantimer" sekunden wird überprüft ob ein Avatar sich in "scandistance" Reichweite befindet.
*
* Befindet sich ein Ava in der Scanzone wird Wasserspray für "effektdauer" Sekunden erzeugt.
* Diese Periode wiederholt sich bis kein Ava gefunden wird.
*/

                                 
float efektdauer = 60.0;           // Dauer des Effekts bis auto Abschaltung
float scantimer  = 10.0;           // Interval der Avatar Suche in Reichweite
float scandistance = 100.0;        // Reichweite der Avatar Erkennung. Auch Höhe beachten!
integer debug = FALSE;             // Debugmodus  [FALSE,TRUE]                                
                                                         
                                               

updateParticles()                    // Partikelsystem initialisieren und Partikelerzeugung starten
{
 list particle_parameters =
      [          
         PSYS_SRC_TEXTURE, llGetInventoryName(INVENTORY_TEXTURE, 0),
         PSYS_PART_START_SCALE, <1, 1, TRUE>,
         PSYS_PART_END_SCALE, <2, 2, TRUE>,
         PSYS_PART_START_COLOR, <1,1,1>,    
         PSYS_PART_END_COLOR, <0.9,0.9,.9>,
         PSYS_PART_START_ALPHA,  (float)0.1,            
         PSYS_PART_END_ALPHA, (float)0.0,  
         PSYS_SRC_BURST_PART_COUNT, (integer)500,
         PSYS_SRC_BURST_RATE, (float) 2.6,  
         PSYS_PART_MAX_AGE, (float)3.5,
         PSYS_SRC_MAX_AGE,(float) 0.0,  
         PSYS_SRC_PATTERN, (integer)2,
         PSYS_SRC_BURST_SPEED_MIN, (float)1,  
         PSYS_SRC_BURST_SPEED_MAX, (float)1.4,
         PSYS_SRC_BURST_RADIUS, 2.5,
         PSYS_SRC_ANGLE_BEGIN, (float) 0.08*PI,    
         PSYS_SRC_ANGLE_END, (float)0.08*PI,  
         PSYS_SRC_ACCEL, <0.0,0, - 1 >,    
         PSYS_PART_FLAGS, (integer)( 0          
                              | PSYS_PART_INTERP_COLOR_MASK  
                              | PSYS_PART_INTERP_SCALE_MASK  
                              | PSYS_PART_EMISSIVE_MASK    
                          )                    
      ];
     llLinkParticleSystem(LINK_SET,particle_parameters);   // Partikelerzeugung starten
}



feedback(integer status)
{
  if(status)      
      {
          updateParticles();                                // Partikel Erzeugung starten
          if(debug) llSay(PUBLIC_CHANNEL, "Spray an");      // User benachrichtigen
      }  
  else
      {
          llLinkParticleSystem(LINK_SET, [ ] );           //Partikel Stoppen
          if(debug) llSay(PUBLIC_CHANNEL, "Spray aus");   // User benachrichtigen
      }    
}    



integer avacheck()
{
  list avatars = llGetAgentList(AGENT_LIST_PARCEL, []);     // Avatarliste holen
  integer anzahl;
     
  for (anzahl = 0; anzahl < llGetListLength(avatars); anzahl++) // Avatarabstand durchtesten
      {
          if (llVecDist(llList2Vector(llGetObjectDetails(llList2Key(avatars, anzahl), [OBJECT_POS]),0), llGetPos()) <= scandistance)  
              { return (TRUE);}                              // Schleife beenden, Avatar in Reichweite gefunden            
      }  
  return (FALSE);                                            // kein Avatar gefunden
}



state aktiv                                                 // Status: Partikelerzeugung
{
  state_entry()
  {
      llSetTimerEvent(efektdauer);                        // Zeitdauer setzten in der überprüft wird ob noch ein Avatar in Sichtweite ist  
      feedback(TRUE);                                     // Partikelerzeugung starten
  }

  timer()                                                 // Schleife für Überprüfung ob Avatar noch in Reichweite
  {
      if ( !avacheck()) { state default;}                 // Niemand mehr da, abschalten
  }
 
  changed(integer changebits)                             // Reset nach Region restart
  {
      if(CHANGED_REGION_START & changebits) { llResetScript(); }  
  }
}



default                                                     // Status: Scannen in standby Modus
{
  state_entry()
  {
      llSetTimerEvent(scantimer);                         // Standby Überprüfungs Intervall setzten  
      feedback(FALSE);                                     // Partikelerzeugung abschalten
  }
 
  timer()                                                 // periodicher Check ob Ava in Nähe
  {                
      if ( avacheck()) { state aktiv;}
  }
 
  changed(integer changebits)                             // Reset nach Region restart
  {
      if(CHANGED_REGION_START & changebits) { llResetScript(); }  
  }
}
Antworten }
Thanks given by: Achim


Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste