Join us in Outworldz at www.outworldz.com:9000 or follow us:

Search dozens of selected web sites for OpenSim and LSL script

New! Script Meta-Search will search thousands of scripts here and at other sites for LSL or Opensim scripts.
Loading

Want to add a script or a project? Upload it and a half million people will see it and your name here this year.

Home   Show All
Category: Contributor: Creator
Clothing PrimSkirt Builder  

PrimSkirt Builder

Nice Prim Skirt builder for flexible prims

Category: Clothing
By : Dalien Talbot
Created: 2015-03-17 Edited: 2015-03-17
Worlds: Second Life

the Zip file

Download all files for PrimSkirt Builder
Contents are in zip format, with .LSL (text) source code and LSLEdit (text + Solution) formats.
Get file # 1. EULA.txt
Get file # 2. GNU License.txt
Get file # 3. Pose Stand Script.lsl
Get file # 4. [17284 bytes] waist.png
1 END-USER LICENSE AGREEMENT
2
3 I. Terms and Conditions:
4 Per the terms and conditions under the GNU General Public License, you may:
5
6 1) Freely modify the source code of this script, so long as those modifications are properly documented within the body of the source code up to and including derivative works based upon this script under the understanding that such works fall under the GPL license. Stand-alone works (animations, sounds, textures, prims, or precompiled modules) designed to operate in conjunction with this script do not fall under this agreement and are not subject to the GPL.
7
8 2) Freely distribute this script to any third party as deemed appropriate for public or private use so long as this notice and a copy of the GNU GPL are included.
9
10 Per the agreement, you may NOT:
11
12 1) Sell modified versions of this script without the express written permission of the original author unless the derivative work uses less than 20% of the original source code.
13
14
15 II. Warranty Information
16 This product comes "as-is" with no express or implied warranty. You may not hold the original author or any authors of derived work accountable for damages associated with the use or modification of this script unless those authors provide a statement of warranty in writing.
17
18 III. Retroactive License.
19 The terms and conditions of this script, upon entering into public domain, affect all prior versions of this script that carry the same name. All previous versions of this script, whether written by the original author or others who claim association with said author, now fall under the jurisdiction of the GPL and are subject to the terms and conditions contained therein.
20
21 Please refer to the included GNU GPL license notecard for additional information.

PrimSkirt Builder

Category: Clothing
By : Dalien Talbot
Created: 2015-03-17 Edited: 2015-03-17
Worlds: Second Life

1 Glad that you've got your copy of the prim skirt builder. First a couple of words why it appeared.
2
3 There's a person who makes my SL the most enjoyable experience, and her name is Vint Falken.
4
5 She is a great SL photo-artist (if you can afford the price for the services of a professional - then she's the right person to talk to), and a great person overall.
6
7 Looking at the LoopRez script which is used for these things, I said "what a boring work it must be!" and told her I can make something better than that.
8
9 And then I've decided to release this as full-mod under GPL license, for a few reasons:
10
11 1) I think it is a nice way to express myself to her
12
13 2) I am curious if anyone likes the tool enough that they would tip me without being required to do so :-)
14
15 3) other people (you!) can save some time not spent on boring things and spend it more productively.
16
17 4) Last but not least... I depend a lot on the GPL code IRL - and I wanted to contribute back, even in such a small extent.
18
19 Now that you've read the story and you know why - grab the manual (you can find a copy of it inside the posing stand) and look through it - and then... have fun!! :-)
20
21 Take also your time to read the EULA and the GPL license - before asking any questions or tweaking any of the permissions :-)
22
23 I will post the relevant news regarding this tool on my blog http://daltonic.blogspot.com/ under the tag "primskirtbuilder"
24
25 cheers,
26 Dalien
27
28 P.S. Be sure also to visit Vint's blog at http://www.vintfalken.com/ - she has quite a few nice tutorials
29
30 P.P.S. if someone sold you this build for anything other than L$0, or if you can not view the source of the scripts - please go and report them, they've been doing so in violation of GPL.

PrimSkirt Builder

Category: Clothing
By : Dalien Talbot
Created: 2015-03-17 Edited: 2015-03-17
Worlds: Second Life

1 0. Before you IM me.
2
3 I think it is important to mention it again in the very beginning - if you think this tool is useful, I would be interested to see how much,
4 and indeed the tips are much more appreciated than random IMs :-) I also do live music - and similar to live music, it is not *required* to tip the performer/author. However, your desire to share some of your cash does express the extent of your satisfaction with the product, so I am making this experiment to see if this works.
5
6 Once again - this tool is and has to be free as in beer and free as in speech. If someone charged you for getting it, they violated the GPL - please file an AR and get the
7 free copy from my location. Where - it is mentioned in the http://daltonic.blogspot.com/ in the entries with the tag "primskirtbuilder".
8
9 IMPORTANT: REQUESTS FOR HELP.
10
11 I do not have much time at all, and I prefer not to spend it on answering questions. if you have something specific to ask - drop me an email at dalienta@gmail.com - if the question/bug report is valid, it will be acted upon and answered on my blog - http://daltonic.blogspot.com, in an entry with the tag "primskirtbuilder". For those impatient that require the help "right now" - I probably can help, take a look at the last section of the manual for my consulting fees before IMing me to ensure that we are in full understanding. If you want an alternative form of licensing or want unrelated consulting help - drop me an email with the description of what you want, and I will reply as my time permits. Please do not consider it as any form of hostility - it is just to ensure my personal time is spent in the most efficient manner. Thanks for your understanding :-)
12
13 1. The contents of the package
14
15 The builder, which looks like a posing stand, contains:
16
17 - EULA
18 - GNU License (GPL) - read this before making any mods
19 - Introduction - first time read for the new owners
20 - pose stand script
21 - prim (used to create the skirts and control elements)
22 - Vint's prim skirt builder manual - the manual you are reading
23 - waist - the texture for the geometry control prim
24
25 Pay attention, that all the skirts it creates, have the same creator as the creator of the "prim" - that is, me,
26 Dalien Talbot (or the previous owner, if you grabbed a copy from someone). It may be ok if you build the clothes for yourself, but if you want to resell your creations,
27 you might want to change the creator to be you. How this is done is described in the section "Changing the creator".
28
29 At first feel free to practice, so you are familiar with how the tool works.
30
31
32 2. Getting started
33
34 Rez the stand onto the ground, and either click it or stand on it. If you stand on it, you will get into the "edit appearance" pose, which can be convenient if you want to see how the skirt looks on yourself. If you do not want that, clicking is exactly the same.
35
36 You will get a dialog, which will say how many prims will the skirt have, and three buttons: "More", "Less", and "Rez...".
37
38 The "More" and "Less" will increase or decrease the number of prims, and "Rez..." will create the skirt and control elements. You can go up to 60 prims in the skirt, but this is not very sim-friendly - some of the calculations are rather intensive, and it may make the things slow. (Also, wearing such a monster will create a lag for the others - so think twice before creating it).
39
40 Once you have hit "Rez...", wait until the rezzing finishes, it takes some time.
41
42 In the end, you will see the prims in the skirt shape above the platform, a green ball in the center of it, and two control prims - one on the left, which looks the same as the the prims making up the skirt - "appearance control" prim, and one on the right, with the circle and the "Waist size" written on it - "geometry control" prim.
43
44 IMPORTANT: never change the skirt prims directly! All the manipulations are to be done via the left and right control prims.
45
46 Also, be sure to not do the changes too fast - and especially do not touch anything while the skirt is being linked - this may have unpredictable effects!
47
48 Both of the control prims have a quick reference in the text above them, but below is a more verbose description.
49
50 3. Changing the appearance of the skirt prims (using the appearance control prim)
51
52 Simply edit the appearance control prim on the left, and most of the changes will be automatically replicated to all the skirt prims at once. The changes get replicated in 1-2 seconds - to speed up the editing, only the last state of the object is transferred.
53
54 "Most of the changes" includes:
55
56 - prim type (box/circle/cylinder/etc. - sculpted prims would NOT work.)
57 - prim scale (X/Y/Z size)
58 - flex characteristics - note that e.g. sphere can not be "flex"
59 - textures/colors/transparency on each of the sides or all of them - same as for "normal" editing.
60
61 One note about the flex objects and size replication - I have noticed that for the flex objects, changing the sizes on axis other than Z results in no visible effect - it may be a bug in the script, or, more probably the bug in SL (since when you click those prims subsequently, they get the correct sizes).
62
63 Another thing is that the flex parameters do not seem to take effect immediately if you change them - you might want to flip the "flex" setting off, wait for it to replicate, and then turn it on again. It may be a bug in SL or in the script - maybe I take a look at this later on.
64
65 Note, that also changing the position for the appearance control prim affects the position of the skirt - by moving it, you will move the whole set of the prims for the to-be skirt at the same distance. I tried to be smart about changing the size of the prim - since when you change it in the GUI, the center of the prim also drifts - these changes should not normally cause any movements of the skirt.
66
67 NOTE: the textures that you use, have to have the "copy" permission set!
68
69 4. Changing the waist size / flare / bend (using the geometry control prim)
70
71 The shape of the circle (or ellipse, in most cases :) with the text "waist size" is exactly the same as the shape of the imaginary ellipse on the waist line, from which the prims are hanging. The sizes are proportional - except the geometry control prim is a few times bigger for your convenience.
72 So, editing the Y-size or Z-size will allow you to change the shape of the ellipse along which the prims are positioned.
73
74 The Y-angle represents the flare - how much do the skirt prims ... umm... well... how much do they "flare" :) the angle is relative the vertical - i.e. "0" would mean they are vertical, "90" degrees would mean they "grow out" horizontally. Turning off the flex will make the things look more vivid.
75 When you rotate the geometry control prim using the "green" circle, you can go only up to angle of 90 degrees. If you manually stick in the bigger values into the editor box, you can get the skirts looking *upwards* :-) (Not sure why anyone would want to do that, but still thought I'd let you know.)
76
77 NOTE: the original LoopRez had both the coordinates and the radius and the rotation relative the center of the prims. I found it inconvenient, so in my scenario all of these are done relative to the waist line.
78
79 The X-size of the geometry control prim represents the "bend coefficient" - it changes the Z-position of the prims depending on their place on the virtual ellipse. Allosw for a fancier-looking skirts, I suppose :-)
80
81 5. Changing the number of prims
82
83 Midway through your work, you might realize that you have taken too few or too many prims - no problem! click on the stand or the skirt itself, and the menu will popup.
84 Use the already familiar "More" and "Less" buttons to set the number of prims you need, and then click "Rez..." - the current skirt will get wiped, and the one with the new number of prims will re-rez. Again, give it some time, do not hurry !
85
86 6. Finalizing your work
87
88 Once you are happy with how your skirt looks like, you will want to link it. While it can be done manually, I do think it is a boring exercise. So, I made the script such that it links it for you!
89
90 Click on the stand (or on the skirt itself) to get the menu. In the menu, click "Link...". You will see a popup asking you for a permission to link the objects - answer "Yes" (otherwise it would not work), and wait. When the linking process is finished, the resulting skirt will be moved to the left and front from the posing stand by 1 meter,
91 feel free to rename it as you like, take into the inventory and try wearing! :-)
92
93 The only thing you might want to adjust then is its position on your body - you can do it while hitting "edit" on the skirt itself while wearing it, and moving it up/down.
94 Since the green ball is the root prim of the linked set, besides the vertical adjustment, normally there should be no other quirks needed.
95
96 7. Cleaning up
97
98 You can delete all the rezzed prims by clicking the stand, and hitting the "Wipe all..." button. this will leave only the posing stand, which you can take back into the inventory.
99
100 Also, if you take away the posing stand, and leave the control prims hanging in the air - they will self-destruct in approximately 1 hour.
101
102 Have fun and enjoy your skirts!! :-)
103
104
105
106 --------------------------------------------------------------------------------------------------------------------------------------------------------------------------
107 Advanced/Commercial: Changing the creator for the skirt prims
108 --------------------------------------------------------------------------------------------------------------------------------------------------------------------------
109
110 Okay, this may be a difficult operation for some... read very very very carefully, and then follow step by step - PRECISELY.
111 If it does not work - then repeat it again. If it still does not work - you are probably doing something wrong. Reread and retry again.
112
113 DISCLAIMER (read carefully before IMing me for help with this part): You can hire me for help if I am online (no guarantees I will do it though - depends on my availability) - but since this is a boring activity (and since you will probably be making the money after it), be prepared that I will charge for this consulting.
114 L$1500 is the disturbance compensation which includes also 15 minutes of consulting time (it should not take more than that), all the time spent on top of that that it is L$900 for every other full 15 minutes spent. (Yeah, I am not cheap, but still it is way cheaper than I would cost IRL :) You can indeed also ask for the help of your friendly scripter - this operation is not complex at all for someone who has done it, I just want to avoid spending all the time in SL moving the scripts between the objects :-)
115
116 So, now that you have read the above scary passage, and are determined to save some money by doing it yourself, here is how to do it:
117
118 1) rez the posing stand from your inventory (since it is full-mod, you now have 2 objects - one in the inventory which will be the "backup copy", and one rezzed - which will be your working copy). If you have only one copy - means someone has reset the permissions on the objects - hence violating the GPL. Go and complain back to them! :)
119
120 2) Right-click on the stand and choose "Edit..." from the pie menu.
121
122 3) in the dialog with "General | Object | Features | Texture | Content" tabs, click on the tab named "Content"
123
124 4) drag the prim object named "prim" onto the ground.
125
126 5) you will see the dialog change, and in the "Content" tab there will be now the content of this prim - a single script called "positioning/control"
127
128 6) drag this script into your inventory
129
130 7) create a new prim, which would have the desired characteristics as a starting prim for the skirt (flex/textures/etc).
131 NOTE: any textures that you use in this prim HAVE to be copyable, as anyone who will grab a copy of the tool from you will be using them as a starting point for building.
132 Also - this prim has to have the full permissions!!!
133
134 8) right-click this prim, select "Edit...", then "Content" tab, and drop the script "positioning/control" from your inventory into the contents area of the new "prim" prim.
135
136 9) click on the "General" tab, and ensure that your prim is named "prim"
137
138 10) right-click your prim and select "Take" from the pie menu - this will take this new prim into your inventory
139
140 11) right-click the posing stand, choose "Edit...", then "Contents" tab to display the contents of the package again
141
142 12) select the "prim" object within the posing stand contents, and hit the "delete" key once (or right-click that piece, and choose the "Delete" menu item). The prim should disappear from the posing stand's contents.
143
144 13) find back the new "prim" prim that you have just created and taken into the inventory, drag it into the contents area of the posing stand, and drop there.
145
146 14) You are done! Close the edit box and test that everything is working.

PrimSkirt Builder

Category: Clothing
By : Dalien Talbot
Created: 2015-03-17 Edited: 2015-03-17
Worlds: Second Life

1 GNU GENERAL PUBLIC LICENSE
2 Version 2, June 1991
3
4 Copyright (C) 1989, 1991 Free Software Foundation, Inc.
5 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
6 Everyone is permitted to copy and distribute verbatim copies
7 of this license document, but changing it is not allowed.
8
9 Preamble
10
11 The licenses for most software are designed to take away your
12 freedom to share and change it. By contrast, the GNU General Public
13 License is intended to guarantee your freedom to share and change free
14 software--to make sure the software is free for all its users. This
15 General Public License applies to most of the Free Software
16 Foundation's software and to any other program whose authors commit to
17 using it. (Some other Free Software Foundation software is covered by
18 the GNU Library General Public License instead.) You can apply it to
19 your programs, too.
20
21 When we speak of free software, we are referring to freedom, not
22 price. Our General Public Licenses are designed to make sure that you
23 have the freedom to distribute copies of free software (and charge for
24 this service if you wish), that you receive source code or can get it
25 if you want it, that you can change the software or use pieces of it
26 in new free programs; and that you know you can do these things.
27
28 To protect your rights, we need to make restrictions that forbid
29 anyone to deny you these rights or to ask you to surrender the rights.
30 These restrictions translate to certain responsibilities for you if you
31 distribute copies of the software, or if you modify it.
32
33 For example, if you distribute copies of such a program, whether
34 gratis or for a fee, you must give the recipients all the rights that
35 you have. You must make sure that they, too, receive or can get the
36 source code. And you must show them these terms so they know their
37 rights.
38
39 We protect your rights with two steps: (1) copyright the software, and
40 (2) offer you this license which gives you legal permission to copy,
41 distribute and/or modify the software.
42
43 Also, for each author's protection and ours, we want to make certain
44 that everyone understands that there is no warranty for this free
45 software. If the software is modified by someone else and passed on, we
46 want its recipients to know that what they have is not the original, so
47 that any problems introduced by others will not reflect on the original
48 authors' reputations.
49
50 Finally, any free program is threatened constantly by software
51 patents. We wish to avoid the danger that redistributors of a free
52 program will individually obtain patent licenses, in effect making the
53 program proprietary. To prevent this, we have made it clear that any
54 patent must be licensed for everyone's free use or not licensed at all.
55
56 The precise terms and conditions for copying, distribution and
57 modification follow.
58
59 GNU GENERAL PUBLIC LICENSE
60 TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61
62 0. This License applies to any program or other work which contains
63 a notice placed by the copyright holder saying it may be distributed
64 under the terms of this General Public License. The "Program", below,
65 refers to any such program or work, and a "work based on the Program"
66 means either the Program or any derivative work under copyright law:
67 that is to say, a work containing the Program or a portion of it,
68 either verbatim or with modifications and/or translated into another
69 language. (Hereinafter, translation is included without limitation in
70 the term "modification".) Each licensee is addressed as "you".
71
72 Activities other than copying, distribution and modification are not
73 covered by this License; they are outside its scope. The act of
74 running the Program is not restricted, and the output from the Program
75 is covered only if its contents constitute a work based on the
76 Program (independent of having been made by running the Program).
77 Whether that is true depends on what the Program does.
78
79 1. You may copy and distribute verbatim copies of the Program's
80 source code as you receive it, in any medium, provided that you
81 conspicuously and appropriately publish on each copy an appropriate
82 copyright notice and disclaimer of warranty; keep intact all the
83 notices that refer to this License and to the absence of any warranty;
84 and give any other recipients of the Program a copy of this License
85 along with the Program.
86
87 You may charge a fee for the physical act of transferring a copy, and
88 you may at your option offer warranty protection in exchange for a fee.
89
90 2. You may modify your copy or copies of the Program or any portion
91 of it, thus forming a work based on the Program, and copy and
92 distribute such modifications or work under the terms of Section 1
93 above, provided that you also meet all of these conditions:
94
95 a) You must cause the modified files to carry prominent notices
96 stating that you changed the files and the date of any change.
97
98 b) You must cause any work that you distribute or publish, that in
99 whole or in part contains or is derived from the Program or any
100 part thereof, to be licensed as a whole at no charge to all third
101 parties under the terms of this License.
102
103 c) If the modified program normally reads commands interactively
104 when run, you must cause it, when started running for such
105 interactive use in the most ordinary way, to print or display an
106 announcement including an appropriate copyright notice and a
107 notice that there is no warranty (or else, saying that you provide
108 a warranty) and that users may redistribute the program under
109 these conditions, and telling the user how to view a copy of this
110 License. (Exception: if the Program itself is interactive but
111 does not normally print such an announcement, your work based on
112 the Program is not required to print an announcement.)
113
114 These requirements apply to the modified work as a whole. If
115 identifiable sections of that work are not derived from the Program,
116 and can be reasonably considered independent and separate works in
117 themselves, then this License, and its terms, do not apply to those
118 sections when you distribute them as separate works. But when you
119 distribute the same sections as part of a whole which is a work based
120 on the Program, the distribution of the whole must be on the terms of
121 this License, whose permissions for other licensees extend to the
122 entire whole, and thus to each and every part regardless of who wrote it.
123
124 Thus, it is not the intent of this section to claim rights or contest
125 your rights to work written entirely by you; rather, the intent is to
126 exercise the right to control the distribution of derivative or
127 collective works based on the Program.
128
129 In addition, mere aggregation of another work not based on the Program
130 with the Program (or with a work based on the Program) on a volume of
131 a storage or distribution medium does not bring the other work under
132 the scope of this License.
133
134 3. You may copy and distribute the Program (or a work based on it,
135 under Section 2) in object code or executable form under the terms of
136 Sections 1 and 2 above provided that you also do one of the following:
137
138 a) Accompany it with the complete corresponding machine-readable
139 source code, which must be distributed under the terms of Sections
140 1 and 2 above on a medium customarily used for software interchange; or,
141
142 b) Accompany it with a written offer, valid for at least three
143 years, to give any third party, for a charge no more than your
144 cost of physically performing source distribution, a complete
145 machine-readable copy of the corresponding source code, to be
146 distributed under the terms of Sections 1 and 2 above on a medium
147 customarily used for software interchange; or,
148
149 c) Accompany it with the information you received as to the offer
150 to distribute corresponding source code. (This alternative is
151 allowed only for noncommercial distribution and only if you
152 received the program in object code or executable form with such
153 an offer, in accord with Subsection b above.)
154
155 The source code for a work means the preferred form of the work for
156 making modifications to it. For an executable work, complete source
157 code means all the source code for all modules it contains, plus any
158 associated interface definition files, plus the scripts used to
159 control compilation and installation of the executable. However, as a
160 special exception, the source code distributed need not include
161 anything that is normally distributed (in either source or binary
162 form) with the major components (compiler, kernel, and so on) of the
163 operating system on which the executable runs, unless that component
164 itself accompanies the executable.
165
166 If distribution of executable or object code is made by offering
167 access to copy from a designated place, then offering equivalent
168 access to copy the source code from the same place counts as
169 distribution of the source code, even though third parties are not
170 compelled to copy the source along with the object code.
171
172 4. You may not copy, modify, sublicense, or distribute the Program
173 except as expressly provided under this License. Any attempt
174 otherwise to copy, modify, sublicense or distribute the Program is
175 void, and will automatically terminate your rights under this License.
176 However, parties who have received copies, or rights, from you under
177 this License will not have their licenses terminated so long as such
178 parties remain in full compliance.
179
180 5. You are not required to accept this License, since you have not
181 signed it. However, nothing else grants you permission to modify or
182 distribute the Program or its derivative works. These actions are
183 prohibited by law if you do not accept this License. Therefore, by
184 modifying or distributing the Program (or any work based on the
185 Program), you indicate your acceptance of this License to do so, and
186 all its terms and conditions for copying, distributing or modifying
187 the Program or works based on it.
188
189 6. Each time you redistribute the Program (or any work based on the
190 Program), the recipient automatically receives a license from the
191 original licensor to copy, distribute or modify the Program subject to
192 these terms and conditions. You may not impose any further
193 restrictions on the recipients' exercise of the rights granted herein.
194 You are not responsible for enforcing compliance by third parties to
195 this License.
196
197 7. If, as a consequence of a court judgment or allegation of patent
198 infringement or for any other reason (not limited to patent issues),
199 conditions are imposed on you (whether by court order, agreement or
200 otherwise) that contradict the conditions of this License, they do not
201 excuse you from the conditions of this License. If you cannot
202 distribute so as to satisfy simultaneously your obligations under this
203 License and any other pertinent obligations, then as a consequence you
204 may not distribute the Program at all. For example, if a patent
205 license would not permit royalty-free redistribution of the Program by
206 all those who receive copies directly or indirectly through you, then
207 the only way you could satisfy both it and this License would be to
208 refrain entirely from distribution of the Program.
209
210 If any portion of this section is held invalid or unenforceable under
211 any particular circumstance, the balance of the section is intended to
212 apply and the section as a whole is intended to apply in other
213 circumstances.
214
215 It is not the purpose of this section to induce you to infringe any
216 patents or other property right claims or to contest validity of any
217 such claims; this section has the sole purpose of protecting the
218 integrity of the free software distribution system, which is
219 implemented by public license practices. Many people have made
220 generous contributions to the wide range of software distributed
221 through that system in reliance on consistent application of that
222 system; it is up to the author/donor to decide if he or she is willing
223 to distribute software through any other system and a licensee cannot
224 impose that choice.
225
226 This section is intended to make thoroughly clear what is believed to
227 be a consequence of the rest of this License.
228
229 8. If the distribution and/or use of the Program is restricted in
230 certain countries either by patents or by copyrighted interfaces, the
231 original copyright holder who places the Program under this License
232 may add an explicit geographical distribution limitation excluding
233 those countries, so that distribution is permitted only in or among
234 countries not thus excluded. In such case, this License incorporates
235 the limitation as if written in the body of this License.
236
237 9. The Free Software Foundation may publish revised and/or new versions
238 of the General Public License from time to time. Such new versions will
239 be similar in spirit to the present version, but may differ in detail to
240 address new problems or concerns.
241
242 Each version is given a distinguishing version number. If the Program
243 specifies a version number of this License which applies to it and "any
244 later version", you have the option of following the terms and conditions
245 either of that version or of any later version published by the Free
246 Software Foundation. If the Program does not specify a version number of
247 this License, you may choose any version ever published by the Free Software
248 Foundation.
249
250 10. If you wish to incorporate parts of the Program into other free
251 programs whose distribution conditions are different, write to the author
252 to ask for permission. For software which is copyrighted by the Free
253 Software Foundation, write to the Free Software Foundation; we sometimes
254 make exceptions for this. Our decision will be guided by the two goals
255 of preserving the free status of all derivatives of our free software and
256 of promoting the sharing and reuse of software generally.
257
258 NO WARRANTY
259
260 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261 FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262 OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263 PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264 OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266 TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267 PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268 REPAIR OR CORRECTION.
269
270 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271 WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272 REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273 INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274 OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275 TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276 YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277 PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278 POSSIBILITY OF SUCH DAMAGES.
279
280 END OF TERMS AND CONDITIONS
281
282 How to Apply These Terms to Your New Programs
283
284 If you develop a new program, and you want it to be of the greatest
285 possible use to the public, the best way to achieve this is to make it
286 free software which everyone can redistribute and change under these terms.
287
288 To do so, attach the following notices to the program. It is safest
289 to attach them to the start of each source file to most effectively
290 convey the exclusion of warranty; and each file should have at least
291 the "copyright" line and a pointer to where the full notice is found.
292
293 <one line to give the program's name and a brief idea of what it does.>
294 Copyright (C) <year> <name of author>
295
296 This program is free software; you can redistribute it and/or modify
297 it under the terms of the GNU General Public License as published by
298 the Free Software Foundation; either version 2 of the License, or
299 (at your option) any later version.
300
301 This program is distributed in the hope that it will be useful,
302 but WITHOUT ANY WARRANTY; without even the implied warranty of
303 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304 GNU General Public License for more details.
305
306 You should have received a copy of the GNU General Public License
307 along with this program; if not, write to the Free Software
308 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
309
310
311 Also add information on how to contact you by electronic and paper mail.
312
313 If the program is interactive, make it output a short notice like this
314 when it starts in an interactive mode:
315
316 Gnomovision version 69, Copyright (C) year name of author
317 Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
318 This is free software, and you are welcome to redistribute it
319 under certain conditions; type `show c' for details.
320
321 The hypothetical commands `show w' and `show c' should show the appropriate
322 parts of the General Public License. Of course, the commands you use may
323 be called something other than `show w' and `show c'; they could even be
324 mouse-clicks or menu items--whatever suits your program.
325
326 You should also get your employer (if you work as a programmer) or your
327 school, if any, to sign a "copyright disclaimer" for the program, if
328 necessary. Here is a sample; alter the names:
329
330 Yoyodyne, Inc., hereby disclaims all copyright interest in the program
331 `Gnomovision' (which makes passes at compilers) written by James Hacker.
332
333 <signature of Ty Coon>, 1 April 1989
334 Ty Coon, President of Vice
335
336 This General Public License does not permit incorporating your program into
337 proprietary programs. If your program is a subroutine library, you may
338 consider it more useful to permit linking proprietary applications with the
339 library. If this is what you want to do, use the GNU Lesser General
340 Public License instead of this License.

PrimSkirt Builder

Prim Skirt Builder

Category: Clothing
By : Dalien Talbot
Created: 2015-03-17 Edited: 2015-03-17
Worlds: Second Life

1 //
2 // Copyright (c) 2007 Dalien Talbot and few other folks thanks to whom this exists:
3 //
4 // Vint Falken, of course - the inspiration, pushing me to the idea, testing, and finding the software bugs :-)
5 // LSL wiki - the function reference
6 // Posing stand code - unknown author
7 // LoopRez v0.6, by Ged Larsen, 20 December 2006 - the math for placement of the skirt prims
8 //
9 // This work is distributed "as-is" with no warranty whatsoever.
10 //
11 //
12 // It is distributed under GPL license. Please have a look at the "EULA" and the "GNU License" notecards in the inventory
13 // to get familiar with the terms and conditions.
14 //
15 // All the derivatives of this work obviously have to comply with the GPL as well. Contact me (Dalien Talbot) if you require alternative licensing.
16 //
17 //
18
19 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
20 // NOTE:
21 // Unless you know what you are doing, do NOT change anything below !
22 //
23 // The standard consulting fees mentioned in the manual will apply for the works on fixing the breakages :-)
24 //
25 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
26
27
28
29 key mkLoungingAgentKey = NULL_KEY;
30 integer miPermissionsAcquired = FALSE;
31 vector vLoungeTarget = <0.00, 0.00, 1.50>;
32 vector myPos;
33
34 // prim constants
35 integer PRIM_FIRSTMISC = -10;
36
37 integer PRIM_CONTROL = -10;
38 integer PRIM_LINKCENTER = -11;
39 integer PRIM_GEOMETRY = -12;
40
41 // pseudo constant - this is the last misc prim number
42 integer PRIM_LASTMISC = -12;
43
44 ////////////////////////////////////////////////////////////////////////////////
45 // CONFIGURATION PARAMETERS for the looprez, these will be changed by the gui editor elements
46
47 string objectName = "prim"; // object to use; will need to be in the inventory of the prim containing this script
48 integer numObjects = 12; // how many objects
49 float xRadius = .05; // waist ellipse x-axis radius in meters
50 float yRadius = .07; // waist ellipse y-axis radius in meters
51 float flareAngle = 45.0; // how many DEGREES the bottom of object will flare outwards, the "poof" factor
52 float bendCoefficient = 0.0; // makes a "saddle shape", bends DOWN this number of meters at extremes of X-axis
53 vector rotOffset = <0.0, 180.0, 0.0>; // rotation offset in DEGREES -- fixes the rotation of ALL objects; for flexi prims, often you will want <180.0, 0.0, 0.0>
54 vector posOffset = <0.0, 0.0, 1.0>; // position offset
55
56 // channel to talk to the prims
57 integer commChannelBase = 0;
58
59
60 integer CHANNEL = 77; // dialog channel
61 list MENU_MAIN = ["More", "Less", "Rez...", "News..."]; // the main menu
62
63 // 0: default state, selecting the number of prims/allowing to rez
64 // 1: objects are rezzing
65 // 2: objects have rezzed, tweaking
66
67 integer script_state = 0;
68
69 // iterator - runs while rezzing through the whole range, to make the process sequential
70 integer current_rez_prim_num = 0;
71
72 // string with all the init parameters that are same for all the prims
73 string init_string = "";
74
75 show_main_dialog()
76 {
77 list menu = MENU_MAIN;
78 if(script_state == 2) {
79 menu = menu + [ "Wipe all...", "Link..." ];
80 }
81 llDialog(llGetOwner(), "Number of prims: " + (string)numObjects, menu, CHANNEL);
82 }
83
84 rez_one_prim()
85 {
86
87 vector pos = llGetPos() + posOffset;
88 // the master prim
89 if(current_rez_prim_num == PRIM_CONTROL) {
90 // control prim
91 pos = pos + <0., 1.5, 0.5>;
92 } else if(current_rez_prim_num == PRIM_LINKCENTER) {
93 // linkage prim
94 } else if(current_rez_prim_num == PRIM_GEOMETRY) {
95 // radius/tilt control prim - on the right
96 pos = pos + <0., -1.5, 0.5>;
97 }
98
99 llRezObject(objectName, pos, ZERO_VECTOR, ZERO_ROTATION, commChannelBase);
100 }
101
102
103 make_init_string()
104 {
105 init_string = llDumpList2String([myPos, numObjects, xRadius, yRadius, flareAngle, bendCoefficient, rotOffset, posOffset], ":");
106 }
107
108 reposition_all()
109 {
110 integer i;
111 make_init_string();
112 //for(i=0; i<numObjects; i++) {
113 // llSay(commChannelBase + 1 + i, "bulk:" + init_string);
114 //}
115 llSay(commChannelBase - 1, "bulk:" + init_string);
116 }
117
118 // tell something unicast to a rezzed prim on its channel
119 unicast(integer child, string message)
120 {
121 llSay(commChannelBase + 1 + child, message);
122 }
123
124 // try to ping the prim, and set up the watchdog
125 check_or_rez_next_misc_prim()
126 {
127 unicast(current_rez_prim_num, "echo");
129 }
130
131 // rez a next misc prim
132 make_next_misc_prim()
133 {
134 current_rez_prim_num = current_rez_prim_num - 1;
135 if(current_rez_prim_num >= PRIM_LASTMISC) {
136 check_or_rez_next_misc_prim();
137
138 } else {
139 // done with rezzing all the prims
141 llOwnerSay("Rezzed all " + (string)numObjects + " prims, please edit the prims on the left and right to edit the skirt, when done, click the stand and hit 'Link...'");
142 script_state = 2;
143 // ask the control prims to push their config - in case they were already there...
144 llSay(commChannelBase - 1, "repost");
145 // start sending the keepalives every minute, so the control prims do not die
147
148 }
149 }
150
151 wipe_all() {
152 llSay(commChannelBase - 1, "die");
153 script_state = 0;
154 llOwnerSay("Wiped all elements... touch the platform to get the menu again.");
155 }
156
157 // check the replies from the dialog
158 integer check_dialog_replies(string message)
159 {
160 if(message == "More") {
161 if(numObjects < 30) {
162 numObjects = numObjects + 2;
163 }
164 show_main_dialog();
165 return 1;
166 } else if(message == "Less") {
167 if(numObjects > 2) {
168 numObjects = numObjects - 2;
169 }
170 show_main_dialog();
171 return 1;
172 } else if(message == "Rez...") {
173 script_state = 1;
174 myPos = llGetPos();
175 // wipe all the skirt prims
176 llSay(commChannelBase - 1, "die_skirt");
177 llOwnerSay("Rezzing " + (string)numObjects + " prims...");
178 llListen(commChannelBase, "", "", "");
179 // start with the first prim - the rest will go in a loop
180 current_rez_prim_num = 0;
181 make_init_string();
182 rez_one_prim();
183 return 1;
184 } else if(message == "Wipe all...") {
185 wipe_all();
186 llOwnerSay("Resetting the script...");
188 return 1;
189 } else if(message == "Link...") {
190 unicast(PRIM_LINKCENTER, "link");
191 } else if(message == "News...") {
192 llLoadURL(llGetOwner(),"Prim skirt builder news @Daltonic blog", "http://daltonic.blogspot.com/search/label/primskirtbuilder");
193 }
194 return 0;
195 }
196
197
198 // we use the description as a "one time run" flag
199 // it stores the hash of the key of the last owner that ran the script
200 // if the owner changes - the hash changes too.
201 run_once()
202 {
203 string hash = llMD5String((string)llGetOwner(), 777);
204 if(llGetObjectDesc() != hash) {
205 llOwnerSay("Please read through the Introduction, the license, and the manual before asking any questions.");
206 llOwnerSay("The author is available for consulting help, the rates are mentioned in the manual.");
207 llSetObjectDesc(hash);
208 llGiveInventory(llGetOwner(), "Introduction");
209 }
210 }
211
212
213 default
214 {
216 {
217 //overriden sit target
218 //lower them a bit
219
220
221 rotation rX;
222 rotation rY;
223 rotation rZ;
224 rotation r;
225
226 vector size;
227
228 size = llGetAgentSize(llGetOwner());
229
230 // approximation.. but still better than nothing
231 vLoungeTarget.z = size.z / 2.0;
232
233
234 //build rotations
235 //Note: this is broken out like this to simplify the
236 // process of finding the correct sit angle. I
237 // use the following form until I have the rotation
238 // that I want perfect, and then I simply
239 // hardcode the perfected quaterion and remove
240 // this mess.
241 //
242 rX = llAxisAngle2Rot( <1,0,0>, 0 * DEG_TO_RAD); //cartwheel
243 rY = llAxisAngle2Rot( <0,1,0>, 0 * DEG_TO_RAD); //sumersault
244 rZ = llAxisAngle2Rot( <0,0,1>, 0 * DEG_TO_RAD); //turn in place
245
246 //combine rotations
247 r = rX * rY * rZ;
248
249 //override 'sit' on pie menu
250 llSetSitText( "Stand" );
251
252 //override default sit target and rotation on prim
253 llSitTarget( vLoungeTarget, r );
254 llSetRot(ZERO_ROTATION); // align to global coordinates
255
256 llListen(CHANNEL, "", llGetOwner(), "");
257 commChannelBase = 100000 + (integer)llFrand(100000000);
258 // run the stuff that needs to be run once...
259 run_once();
260
261 // testing
262 //mkLoungingAgentKey = llGetOwner();
263 //commChannelBase = 123456;
264
265 }
267 {
269 }
270 timer()
271 {
272 if(script_state == 1) {
273 // rezzing on timeout - no echo reply
275 rez_one_prim();
276 }
277 // send a keepalive so the others know we are still here
278 llSay(commChannelBase - 1, "keepalive");
279 }
280
281
282 changed(integer change)
283 {
284 if(change & CHANGED_LINK)
285 {
286 key agent = llAvatarOnSitTarget();
287 if( mkLoungingAgentKey == NULL_KEY && agent != NULL_KEY )
288 {
289
290 //changed user
291 //cache new user key and request their permissions
292 mkLoungingAgentKey = agent;
294 // show the dialog
295 if(agent == llGetOwner()) {
296 show_main_dialog();
297 } else {
298 llInstantMessage(agent, "The owner now should rez/edit the skirt. You can take your own copy by buying it for L$0.");
299 }
300 }
301 else if( mkLoungingAgentKey != NULL_KEY && agent == NULL_KEY)
302 {
303
304 //user is getting up
305 if( miPermissionsAcquired )
306 {
307
308 //restore anims
309 llStopAnimation("turn_180");
310
311 }
312 mkLoungingAgentKey = NULL_KEY;
313 //reset the script to release permissions
314 //llResetScript();
315 }
316 }
317 }
318
320 {
322 {
323
324 //set permission flag
325 miPermissionsAcquired = TRUE;
326
327 //cancel the sit anim
328 llStopAnimation("sit");
329
330 llStartAnimation("turn_180");
331 }
332 }
333
334 touch_start(integer total_number)
335 {
336 key who = llDetectedKey(0);
337 if(who == llGetOwner())
338 {
339 show_main_dialog();
340 } else {
341 llInstantMessage(who, "Only the owner can edit the skirt. Right-click and buy your copy for L$0 to try it yourself");
342 }
343
344 }
345
346
347 listen(integer channel, string name, key id, string message)
348 {
349 integer i;
350
351 if(script_state == 0) {
352 if(channel == CHANNEL) {
353 check_dialog_replies(message);
354 }
355 } else if(script_state == 1) {
356 if(channel == commChannelBase) {
357 // newly awaken child comes back to us
358 if(message == "boot") {
359 string msg = "init:" + (string)current_rez_prim_num + ":" + init_string;
360 // need to supply this little boy with his parameters, once it replies - we rez a new one
361 llSay(commChannelBase, msg);
362 // debug to see what exactly is in bootmsg
363 //llOwnerSay("bootmsg: " + msg);
364
365 } else if(message == "echo_reply") {
366 // one of the control prims we have pinged already exists - so we can just decrement
367 // to the next one
368 //llOwnerSay("echo reply!");
369 make_next_misc_prim();
370 } else if(message == "init_ok") {
371 // this guy has acked our parameters, has stopped listening on the base channel,
372 // renamed itself into its number
373 // and is listening on the commChannelBase + 1 + childNumber
374 if(current_rez_prim_num >= 0) {
375 // rezzing normal prims
376 current_rez_prim_num = current_rez_prim_num + 1;
377 if(current_rez_prim_num < numObjects) {
378 rez_one_prim();
379 } else {
380 // start rezzing misc prims
381 current_rez_prim_num = PRIM_FIRSTMISC;
382 check_or_rez_next_misc_prim();
383 }
384
385
386 } else {
387 // supply misc parameters to control prims...
388 if(current_rez_prim_num == PRIM_LINKCENTER) {
389 // turn it into a small ball...
390 // set shape
391 unicast(PRIM_LINKCENTER, "lc_prim_params:9:3:0:<0.000000, 1.000000, 0.000000>:0.000000:<0.000000, 0.000000, 0.000000>:<0.000000, 1.000000, 0.000000>");
392 // reset flex and set size
393 unicast(PRIM_LINKCENTER, "lc_prim_params:21:0:2:0.300000:2.000000:0.000000:1.000000:<0.000000, 0.000000, 0.000000>:7:<0.050000, 0.050000, 0.050000>");
394 // set texture (none)
395 unicast(PRIM_LINKCENTER, "lc_prim_params:17:0:5748decc-f629-461c-9a36-a35a221fe21f:<1.000000, 1.000000, 0.000000>:<0.000000, 0.000000, 0.000000>:0.000000");
396 }
397
398 if(current_rez_prim_num == PRIM_GEOMETRY) {
399 string cmds = "";
400 integer i;
401 // set shape
402 unicast(PRIM_GEOMETRY, "gc_prim_params:9:0:0:<0.000000, 1.000000, 0.000000>:0.000000:<0.000000, 0.000000, 0.000000>:<1.000000, 1.000000, 0.000000>:<0.000000, 0.000000, 0.000000>");
403 // reset flex
404 unicast(PRIM_GEOMETRY, "gc_prim_params:21:0:2:0.300000:2.000000:0.000000:1.000000:<0.000000, 0.000000, 0.000000>");
405 // size is set at boot...
406 // :7:<0.010000, 0.600000, 0.400000>");
407 // all textures to white
408 unicast(PRIM_GEOMETRY, "gc_prim_params:17:-1:5748decc-f629-461c-9a36-a35a221fe21f:<1.000000, 1.000000, 0.000000>:<0.000000, 0.000000, 0.000000>:0.000000");
409 // waist size texture
410 unicast(PRIM_GEOMETRY, "gc_prim_params:17:4:3515e3e5-f7c3-ffbe-8eb1-f7ede3bbc831:<1.000000, 1.000000, 0.000000>:<0.000000, 0.000000, 0.000000>:0.000000");
411 }
412 // rezzing misc prims - descending
413 make_next_misc_prim();
414 }
415 } else {
416 llOwnerSay("Unknown message '" + message + "'");
417 }
418
419 }
420 } else if(script_state == 2) {
421 if(channel == commChannelBase) {
422 list aList = llParseString2List(message, [":"], []);
423 string command = llList2String(aList, 0);
424 if(command == "move") {
425 posOffset = posOffset + (vector)llList2String(aList, 1);
426 //llOwnerSay("moving by " + llList2String(aList, 1));
427 reposition_all();
428 } else if(command == "geometry") {
429 // waist size / bend coeff
430 vector v = (vector)llList2String(aList, 1);
431 bendCoefficient = v.x;
432 yRadius = v.y;
433 xRadius = v.z;
434 reposition_all();
435 } else if(command == "flare") {
436 //llOwnerSay("flare set: " + message);
437 flareAngle = (float)llList2String(aList, 1);
438 reposition_all();
439 } else if(command == "menu") {
440 show_main_dialog();
441 }
442
443 } else if(channel == CHANNEL) {
444 list aList = llParseString2List(message, [" "], []);
445 string command = llList2String(aList, 0);
446
447 if(check_dialog_replies(message)) {
448 // already done all
449 //llOwnerSay("dialog reply!");
450 // the below commands are for debug via the command line
451
452 } else if(command == "reset") {
453 wipe_all();
454 } else if(command == "dz") {
455 posOffset.z = posOffset.z + (float)llList2String(aList, 1);
456 reposition_all();
457 } else if(command == "dx") {
458 posOffset.x = posOffset.x + (float)llList2String(aList, 1);
459 reposition_all();
460 } else if(command == "dy") {
461 posOffset.y = posOffset.y + (float)llList2String(aList, 1);
462 reposition_all();
463 } else if(command == "z") {
464 posOffset.z = (float)llList2String(aList, 1);
465 reposition_all();
466 } else if(command == "x") {
467 posOffset.x = (float)llList2String(aList, 1);
468 reposition_all();
469 } else if(command == "y") {
470 posOffset.y = (float)llList2String(aList, 1);
471 reposition_all();
472 } else if(command == "flare") {
473 flareAngle = (float)llList2String(aList, 1);
474 reposition_all();
475 } else if(command == "xradius") {
476 xRadius = (float)llList2String(aList, 1);
477 reposition_all();
478 } else if(command == "yradius") {
479 yRadius = (float)llList2String(aList, 1);
480 reposition_all();
481 } else if(command == "bend") {
482 bendCoefficient = (float)llList2String(aList, 1);
483 reposition_all();
484
485 }
486
487
488 }
489 }
490
491 }
492
493 }

PrimSkirt Builder

PrimSkirt Builder

Category: Clothing
By : Dalien Talbot
Created: 2015-03-17 Edited: 2015-03-17
Worlds: Second Life

1
2 //
3 // Copyright (c) 2007 Dalien Talbot and few other folks thanks to whom this exists:
4 //
5 // Vint Falken, of course - the inspiration, pushing me to the idea, testing, and finding the software bugs :-)
6 // LSL wiki - the function reference
7 // Posing stand code - unknown author
8 // LoopRez v0.6, by Ged Larsen, 20 December 2006 - the math for placement of the skirt prims
9 //
10 // This work is distributed "as-is" with no warranty whatsoever.
11 //
12 //
13 // It is distributed under GPL license. Please have a look at the "EULA" and the "GNU License" notecards in the inventory
14 // to get familiar with the terms and conditions.
15 //
16 // All the derivatives of this work obviously have to comply with the GPL as well. Contact me (Dalien Talbot) if you require alternative licensing.
17 //
18 //
19
20 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
21 // NOTE:
22 // Unless you know what you are doing, do NOT change anything below !
23 //
24 // The standard consulting fees mentioned in the manual will apply for the works on fixing the breakages :-)
25 //
26 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
27
28
29
30
31
32
33 // CONFIGURATION PARAMETERS, they get reset from the main script!!!
34
35 integer myNumber = 0; // number of the prim
36 vector standPos; // position of the mothership
37 integer numObjects = 12; // how many objects
38 float xRadius = .16; // ellipse x-axis radius in meters
39 float yRadius = .22; // ellipse y-axis radius in meters
40 float flareAngle = 45.0; // how many DEGREES the bottom of object will flare outwards, the "poof" factor
41 float bendCoefficient = 0.0; // makes a "saddle shape", bends DOWN this number of meters at extremes of X-axis
42 vector rotOffset = <0.0, 180.0, 0.0>; // rotation offset in DEGREES -- fixes the rotation of ALL objects; for flexi prims, often you will want <180.0, 0.0, 0.0>
43 vector posOffset = <0.0, 0.0, 1.0>; // position offset
44
45 string prompt = "Edit/move this prim\nto edit/move the skirt";
46
47 // linking permission acquired
48 integer miPermissionsAcquired = FALSE;
49 // current object being linked, when linked...
50 integer currObject = 0;
51
52 // idle counter - when it increments to 1000, we clean up the control prims.
53 integer idleCounter = 0;
54
55
56 ////////////////////////////////////////////////////////////////////////////////
57 // No need to mess with anything below here
58
59
60 adjust_flare (vector currentPos, rotation currentRot, float flareAngle) {
61 float rotateAngle = flareAngle; // how much to rotate per iteration (in degrees)
62 rotation rot = currentRot;
63 vector scale = llGetScale(); // return the size of the object
64 vector offset = <0, 0, -scale.z/2>; // rotate the object around the center of its top
65 vector offsetPosition = <0, 0, -scale.z/2>; // the position should be that of the top
66 // the two values being the same is a bit coincidental..
67
68
69 vector euler = <0, -1*rotateAngle*DEG_TO_RAD, 0>; // delta rotation expressed as a vector in radians
70 rotation deltarot = llEuler2Rot(euler); // delta rotation expressed as a rotation
71 rotation newrot = deltarot * rot; // new rotation for the object
72
73 vector vvv = offset * rot; // current offset of the rotation point vs. the prim center
74 vector vvv2 = offset * newrot; // new offset of the rotation point vs. the prim center
75
76 //vector currentPos = llGetPos(); // current position
77 //vector rotPoint = llGetPos() + vvv; // current rotation point, not needed except for visualization
78
79 vector newPos; // new position for the prim
80
81 newPos = currentPos + (vvv - vvv2); // is a current position offsetted by a difference between the rotation point offsets
82
83 //llRezObject("ball", rotPoint, ZERO_VECTOR, ZERO_ROTATION, 0); // visualize the rotation point
84
85 // now we also need to adjust the position - so that the top is always at the same place..
86 // the position that we have got is calculated for the center of the prim.
87 newPos = newPos + offsetPosition;
88
89 llSetPos(newPos); // set the new position
90 llSetRot(newrot); // and the new rotation
91 }
92
93
94 makeLoop(integer n, vector standPos, integer numObjects, float xRadius, float yRadius,
95 float flareAngle, float bendCoefficient, vector rotOffset, vector posOffset)
96 {
97 //integer n; // which object is being placed
98 float theta; // angle in radians
99 vector pos; // position
100 rotation rot; // rotation in quaternionformat
101
102 //for(n = 0; n < numObjects; n++) {
103
104 theta = TWO_PI * ( (float)n / (float)numObjects );
105
106 pos.x = xRadius * llCos(theta); // ellipse: 2x xRadius meters wide
107 pos.y = yRadius * llSin(theta); // ellipse: 2x yRadius meters wide
108 pos.z = -bendCoefficient*llCos(theta)*llCos(theta); // saddle shape, bending downwards on X-axis
109 pos = pos + standPos + posOffset;
110
111 rot = llEuler2Rot(<rotOffset.x*DEG_TO_RAD, rotOffset.y*DEG_TO_RAD, rotOffset.z*DEG_TO_RAD>); // user-chosen rotation offset correction
112
113
114 // the following make the objects face outwards properly for an ellipse; using theta alone is only correct for a circle
115 // the scary formula calculates a unit vector TANGENTIAL to the ellipse, and llRotBetween is used to figure out how much the object needs to rotate to lie parallel to the tangent
116 rot = rot * llRotBetween(<0.0,1.0,0.0>, <-1.0 * xRadius * llSin(theta) / ( llSqrt( (yRadius*yRadius * llCos(theta) * llCos(theta)) + (xRadius*xRadius * llSin(theta) * llSin(theta))) ),yRadius * llCos(theta) / ( llSqrt( (yRadius*yRadius * llCos(theta) * llCos(theta)) + (xRadius*xRadius * llSin(theta) * llSin(theta))) ),0.0>);
117 if( n== (numObjects/2) ) // LSL's implementation of llRotBetween at theta = pi radians is reversed at 180 degrees, so this manually corrects it
118 rot = rot * llEuler2Rot( <0,PI,0> );
119
120
121 //rot = rot * llEuler2Rot(<0, -1*flareAngle*DEG_TO_RAD, 0>); // flare generation (poof)
122
123 //llRezObject(objectName, pos, ZERO_VECTOR, rot, 0);
124 //llSetPos(pos);
125 //llSetRot(rot);
126
127 // it will rotate the pieces and set their positions...
128 adjust_flare(pos, rot, flareAngle);
129 //}
130 }
131
132 // are we a control prim (texture/shape/etc.) ?
133 integer isControlPrim = 0;
134 // a ball for skirt linkage
135 integer isLinkCenterPrim = 0;
136
137 // are we a geometry control prim (xradius/yradius/flare/z) ?
138 integer isGeomControlPrim = 0;
139 // how much the "real" waist size is different from the geometry control prim
140 float waistSizeDivizor = 5.0;
141
142
143 integer listenHandle = 0;
144 integer listenHandle2 = 0;
145 integer commChannelBase = 0;
146
147
148 position_geometry_prim()
149 {
150 rotation rot = llEuler2Rot(<0., flareAngle * DEG_TO_RAD, 0. >);
151 vector scale;
152 scale.x = 0.01 + bendCoefficient;
153 scale.y = yRadius * waistSizeDivizor;
154 scale.z = xRadius * waistSizeDivizor;
155 llSetRot(rot);
156 llSetScale(scale);
157 }
158
159 new_position()
160 {
161 // do the fancy math foobar only for the "normal" prims
162 if( (isControlPrim + isLinkCenterPrim + isGeomControlPrim) == 0) {
163 makeLoop(myNumber, standPos, numObjects, xRadius, yRadius, flareAngle, bendCoefficient, rotOffset, posOffset);
164 }
165 if(isLinkCenterPrim) {
166 // link center prim will need to be in the center (surprise surprize!)
167 // since the Z is actually the top of the prims,
168 // nothing much more to be done here
169 // we position it here, since it needs to move with the "normal" prims.
170 vector linkerPos = standPos + posOffset;
171 llSetPos(linkerPos);
172 }
173 }
174
175 position_master_prim()
176 {
177 rotation rot;
178 vector rotOffset = <180.,0.,0.>;
179 rot = llEuler2Rot(<rotOffset.x*DEG_TO_RAD, rotOffset.y*DEG_TO_RAD, rotOffset.z*DEG_TO_RAD>);
180 // flare angle belongs to the flare control...
181 //rot = rot * llEuler2Rot(<0, -1*flareAngle*DEG_TO_RAD, 0>);
182 llSetRot(rot);
183
184 }
185
186
187
188 //------------------ prim mod slave
189
190
191 setParams(list alist)
192 {
193 list res = [ ];
194 integer i;
196 //string aStart = elapsed("");
197 //string aElapsed;
198 string token;
199 integer slen;
200 float f;
201 integer int;
202 // skip the first token - so start from 1
203 for(i=1; i<len; i++) {
204 token = llList2String(alist, i);
205 slen = llStringLength(token);
206 //llOwnerSay("i:" + (string)i + ", slen: " + (string)slen + ", '" + token + "'");
207
208 if(slen == 36) {
209 // for length of 36 we assume key
210 res = res + [ token ];
211 } else if(slen >= 30 && slen <= 33) {
212 // assume vector
213 res = res + (vector)token;
214 } else {
215 // assume integer or float
216 int = (integer)token;
217 if(token == (string) int) {
218 res = res + [ int ];
219 } else {
220 res = res + [ (float) token ];
221 }
222 }
223
224 }
225 //aElapsed = elapsed(aStart);
226
227 //llOwnerSay("result:" + llDumpList2String(res, ":"));
228 //llOwnerSay("Time taken: " + aElapsed);
230 }
231
232
233
234
235 // ------------------------- prim mod master
236
237 list sideTextures = [ ];
238 list sideTexgen = [ ];
239 list sideColors = [ ];
240 list sideAlphas = [ ];
241
242
243 list tokens = [ ];
244
245 // saved position/rotation for the timer events
246 vector myLastPos;
247 vector myLastRot;
248
249
250 // the mask for the delayed update processing
251 // the values are similar to "mask" in the change event
252
253 integer mask = 0;
254
255
256 sendCommand(string cmd)
257 {
258 //llOwnerSay(cmd);
259 llSay(commChannelBase - 1, cmd);
260 }
261
262 resetSideCaches()
263 {
264 sideTextures = [ ];
265 sideTexgen = [ ];
266 sideColors = [ ];
267 sideAlphas = [ ];
268 }
269
270
271
272 checkTextures()
273 {
274 integer i;
277 list newTextures = [ ];
278
279 for(i=0;i<num; i++) {
280 list param = llList2List(result, num + i*4, num + i*4+3);
281 list currparam = llList2List(sideTextures, i*4, i*4+3);
282 integer currparam_len = llGetListLength(currparam);
283
284 if(currparam_len == 0 || llListFindList(param, currparam) == -1) {
285 tokens = tokens + [ PRIM_TEXTURE, i ] + param;
286 }
287 if(llList2Integer(result, i) != llList2Integer(sideTexgen, i)) {
288 tokens = tokens + [ PRIM_TEXGEN, i, llList2Integer(result, i) ];
289 }
290
291 }
292 sideTexgen = llList2List(result, 0, num - 1);
293 sideTextures = llList2List(result, num, -1);
294 //llOwnerSay("!checkTextures end");
295
296 }
297
298
299
300 checkColor()
301 {
302 integer i;
304 list newColors;
305 string cmd = "color";
306 for(i=0;i<num; i++) {
307 vector color = llGetColor(i);
308 newColors = newColors + [ color ];
309
310 if((vector)llList2String(sideColors, i) != color) {
311 cmd = cmd + ":" + (string)i + ":" + (string)color;
312 }
313 }
314 sideColors = newColors;
315 sendCommand(cmd);
316
317 }
318
319 checkAlpha()
320 {
321 integer i;
323 list newAlphas;
324 string cmd = "alpha";
325 for(i=0;i<num; i++) {
326 float alpha = llGetAlpha(i);
327 newAlphas = newAlphas + [ alpha ];
328
329 if((float)llList2String(sideAlphas, i) != alpha) {
330 cmd = cmd + ":" + (string)i + ":" + (string)alpha;
331 }
332 }
333 sideAlphas = newAlphas;
334 sendCommand(cmd);
335
336 }
337
338 checkShape()
339 {
341 sendCommand("prim_params:" + llDumpList2String([ PRIM_TYPE ] + llList2List(result, 7, -1), ":"));
342
343
344 //tokens = tokens + [ PRIM_TYPE ] + llList2List(result, 7, -1) + [ PRIM_FLEXIBLE ] + llList2List(result, 0, 6);
345 tokens = tokens + [ PRIM_FLEXIBLE ] + llList2List(result, 0, 6);
346 }
347
348 checkScale()
349 {
350 vector scale = llGetScale();
351 vector scale0 = scale;
352 scale0.z = scale0.z - 0.01;
353 // workaround against the flex objects not rendering if z size not changed...
354 sendCommand("prim_params:" + llDumpList2String([ PRIM_SIZE, scale0 ], ":"));
355
356 tokens = tokens + [ PRIM_SIZE, scale ];
357 return;
358 }
359
360
361
362 // this function gets called from the timer, and fires up the commands to the
363 // other prims to adjust themselves
364 // the reason for calling it from timer is to make the processing
365 // a little bit lighter... (LSL's string/list parsing is a pain in the butt and
366 // is a main reason for slowness...)
367 check_changed()
368 {
369 if(isControlPrim) {
370 // prim's characteristics replicate to others
371 tokens = [ ];
372 if(mask & CHANGED_SHAPE){
373 // changing the prim type can change everything
374 checkShape();
376
377 }
378 if(mask & CHANGED_COLOR){
379 checkColor();
380 checkAlpha();
381 }
382
383
384 if(mask & CHANGED_TEXTURE){
385 checkTextures();
386 }
387 if(mask & CHANGED_SCALE){
388 checkScale();
389 }
390 if(llGetListLength(tokens) > 0) {
391 sendCommand("prim_params:" + llDumpList2String(tokens, ":"));
392 if(mask & CHANGED_SHAPE || mask & CHANGED_SCALE) {
393 // changing shapes involves recalculation of the position
394 sendCommand("reposition");
395 }
396
397 }
398 }
399
400 if(isGeomControlPrim) {
401 // z scale = xradius
402 // y scale = yradius
403 // y axis tilt (handled elsewhere) = flare
404 // x scale - 0.01 = bend coefficient
405 vector scale = llGetScale();
406 scale.x = scale.x - 0.01;
407 scale.y = scale.y / waistSizeDivizor;
408 scale.z = scale.z / waistSizeDivizor;
409 if(mask & CHANGED_SCALE) {
410 llSay(commChannelBase, "geometry:" + (string)scale);
411 }
412 }
413
414
415 // reset all the changed notifications - we've done what we had to do...
416 mask = 0;
417
418 }
419
420 restart_timer()
421 {
422 // stop the timer and restart it
425 }
426
427 // ugggly hack - but since i am reusing the list of global vars...
428 set_globals_from_list(list aList, integer i)
429 {
430 standPos = (vector)llList2String(aList, i); i=i+1;
431 numObjects = llList2Integer(aList, i); i=i+1;
432 xRadius = llList2Float(aList, i); i=i+1;
433 yRadius = llList2Float(aList, i); i=i+1;
434 flareAngle = llList2Float(aList, i); i=i+1;
435 bendCoefficient = llList2Float(aList, i); i=i+1;
436 rotOffset = (vector)llList2String(aList, i); i=i+1;
437 posOffset = (vector)llList2String(aList, i); i=i+1;
438 }
439
440 // tell child to tell back its id so we could link it...
441 ask_child_to_link()
442 {
443 llSay(commChannelBase + 1 + currObject, "link");
444 }
445
446 default
447 {
448 touch_start(integer channel)
449 {
450 // ask the stand prim to show the menu, and avoid the spam in the chat
451 if(commChannelBase != 0) {
452 if(llDetectedKey(0) == llGetOwner()) {
453 llSay(commChannelBase, "menu");
454 } else {
455 llInstantMessage(llDetectedKey(0), "Only owner can modify the skirt - get your free copy - right-click the posing stand and buy it for L$0");
456 }
457 }
458
459 }
460 on_rez(integer channel) {
461 if(channel == 0) {
462 if(llGetNumberOfPrims() > 1) {
463 // need to check if we are linked and if yes - then delete the script...
465 }
466 // if channel = 0 means we have been rezzed by the user - so do not do anything...
467 return;
468 }
469 commChannelBase = channel;
470 listenHandle = llListen(channel, "", "", "");
471 // request the boot parameters
472 llSay(channel, "boot");
473 }
475 {
477 {
478
479 //set permission flag
480 miPermissionsAcquired = TRUE;
481 // reset any pending events...
483 // start the linking...
484 currObject = 0;
485 llOwnerSay("Linking will take some time, please be patient...");
486 ask_child_to_link();
487 } else {
488 llOwnerSay("ERROR: permission was not acquired, can not link...");
489 }
490 }
491
492
493 changed(integer changed_mask)
494 {
495 if((changed_mask & CHANGED_LINK) && (!isLinkCenterPrim) && (!isControlPrim) && (!isGeomControlPrim) ) {
496 if(llGetNumberOfPrims() > 1) {
497 // need to check if we are linked and if yes - then delete the script...
498 // the link centre prim will remove the script from itself,
499 // either on next rez, or when it finishes linking us.
501 }
502
503 } else {
504 if(isControlPrim || isGeomControlPrim) {
505 // set the appropriate flags
506 // so that timer event would fix it.
507 restart_timer();
508 mask = mask | changed_mask;
509 }
510 }
511
512 }
513 timer() {
514 idleCounter = idleCounter + 1;
515
516 if(isControlPrim || isGeomControlPrim) {
517 if(idleCounter > 1000) {
518 // the stand is gone and did not remind about itself... go away then.
519 llOwnerSay("Did not hear from the stand - so it must have been taken away - self-destroying...");
520 llDie();
521 }
522 } else {
523 if(idleCounter > 20) {
524 // the stand is gone and did not remind about itself... go away then.
525 llOwnerSay("Did not hear from the stand - so it must have been taken away - self-destroying...");
526 llDie();
527 }
528 }
529 if(isControlPrim) {
530 // control prim
531 vector myCurrentPos = llGetPos();
532 vector delta = myCurrentPos - myLastPos;
533
534 if( (mask & CHANGED_SCALE) == 0) {
535 // if both the scale AND position is changed - do not move
536 // since when the scale changes via the mouse, the center drifts away...
537
538 if(llVecDist(myLastPos, myCurrentPos) > 0) {
539 llSay(commChannelBase, "move:" + (string)delta);
540 //llOwnerSay("moved!");
541 }
542 }
543 myLastPos = myCurrentPos;
544 }
545 if(isGeomControlPrim) {
546 // geometry control prim - check the tilt, the scale is checked elsewhere
547 vector myCurrentRot = llRot2Euler(llGetRot());
548 if(llVecDist(myLastRot, myCurrentRot) > 0) {
549 llSay(commChannelBase, "flare:" + (string)(myCurrentRot.y / DEG_TO_RAD));
550 }
551 myLastRot = myCurrentRot;
552 }
553
554 if(mask != 0) {
555 // naive attempt at optimization...
556 check_changed();
557 }
558 }
559
560
561
562 listen(integer channel, string name, key id, string message)
563 {
564 integer i = 1; // first parameter;
565 //llOwnerSay("message: '" + message + "'");
566 if(channel == commChannelBase) {
567 // init string
568 // init:myNumber:boot_string
569 // where boot string is:
570 // [myPos, numObjects, xRadius, yRadius, flareAngle, bendCoefficient, rotOffset, posOffset]
571 list aList = llParseString2List(message, [":"], []);
572 if(llList2String(aList, 0) == "init") {
573
574 llListenRemove(listenHandle);
575 myNumber = llList2Integer(aList, i); i=i+1;
576 llSetObjectName((string)myNumber);
577
578
579 // object number ranges from 0 to numObjects-1
580 // if we have got the number "numObjects" then we are the "control" prim - should not react to position change requests.
581
582 // start listening for mothership only
583 listenHandle = llListen(commChannelBase + 1 + myNumber, "", "", "");
584 listenHandle = llListen(commChannelBase - 1, "", "", "");
585
586
587 // report back to mothership that we are ok to fly on our own so it continues to generate the prims
588 llSay(commChannelBase, "init_ok");
589
590 // set the global parameters from the list
591 set_globals_from_list(aList, i);
592
593 isControlPrim = 0;
594 isLinkCenterPrim = 0;
595 isGeomControlPrim = 0;
596
597 // set the keepalive timer for the precaution self-destruction
598 // in the skirt prims - for the special prims the timer will be faster...
599 llSetTimerEvent(120);
600
601
602 if(myNumber == -10) {
603 // control prim - change its appearance and it replicates...
604 isControlPrim = 1;
605 llSetObjectName("Primskirt builder control prim");
606
607 llSetText(prompt, <0., 1., 0.>, 1.0);
608
609 position_master_prim();
610 myLastPos = llGetPos();
611 // for move/rotate and delayed prim replication
612 restart_timer();
613 } else if(myNumber == -11) {
614 // link center prim - a ball to use as a root for the skirt
615 isLinkCenterPrim = 1;
616 llSetObjectName("Prim Skirt");
617
618
619 } else if(myNumber == -12) {
620 // geometry control prim
621 isGeomControlPrim = 1;
622 llSetObjectName("Waist size/flare/bend control prim");
623 llSetText("X size: bend\nY size: yradius\nZ size: xradius\nY rotate: flare", <0., 1., 0.>, 1.0);
624 // the new position
625 position_geometry_prim();
626 }
627
628 // notify the owner (debug)
629 //llOwnerSay("got:" + llDumpList2String([myNumber, standPos, numObjects, xRadius, yRadius, flareAngle, bendCoefficient, rotOffset, posOffset], ":"));
630 // and position ourselves properly
631 new_position();
632
633 } else {
634 llOwnerSay("Unknown init message:'" + message + "'");
635 }
636 } else {
637 // control messages from the mothership or the control prim
638 list aList = llParseString2List(message, [":"], []);
639 string command = llList2String(aList, 0);
640 integer len = llGetListLength(aList);
641 integer i = 1;
642 // reset the idle counter
643 idleCounter = 0;
644 if(command == "echo") {
645 // reply to those that care
646 llSay(commChannelBase, "echo_reply");
647 } else if(command == "die") {
648 llDie();
649 } else if(isControlPrim == 1) {
650 // do not respond to change position and all
651 if(command == "repost") {
652 // we need to push the prim characteristics
653 mask = mask | CHANGED_SHAPE | CHANGED_COLOR | CHANGED_SCALE | CHANGED_TEXTURE;
654 resetSideCaches();
655 restart_timer();
656 }
657 } else if(isGeomControlPrim == 1) {
658 // only allow to modify the shape
659 // special kind of prim_params
660 if(command == "gc_prim_params") {
661 setParams(aList);
662 } else if(command == "bulk") {
663 // "bulk" is essentially the same as init, except "myNumber" is not sent.
664 set_globals_from_list(aList, i);
665 // position sets the box according to current parameters
666 new_position();
667 } else if(command == "repost") {
668 // we need to push the prim characteristics
669 mask = mask | CHANGED_SHAPE | CHANGED_COLOR | CHANGED_SCALE | CHANGED_TEXTURE;
670 myLastRot = myLastRot * <1.,1.,1.,0.5>; // just to "touch" the rotation so timer updates the things
671 restart_timer();
672 }
673 } else if(isLinkCenterPrim == 1) {
674 if(command == "die_skirt") {
675 // only the ball and the skirt prims obey this
676 llDie();
677 } else if(command == "bulk") {
678 // bulk works for linkcenter too, but most of it is ignored in processing...
679 set_globals_from_list(aList, i);
680 // and position ourselves properly
681 new_position();
682 } else if(command == "lc_prim_params") {
683 // special kind of prim_params
684 setParams(aList);
685 } else if(command == "link") {
687 } else if(command == "linkme") {
688 // someone wants to be linked...
689 //llOwnerSay("linkme rcvd!");
690 if(miPermissionsAcquired) {
691 integer num = currObject + 1;
692 llOwnerSay("Linking prim " + (string)num + " of " + (string)numObjects + ", please wait...");
693 llCreateLink(id, TRUE);
694 currObject = currObject + 1;
695 if(currObject < numObjects) {
696 ask_child_to_link();
697 } else {
698 vector pos = llGetPos() + <-1.0, 1.0, 0.0>;
699 llSetPos(pos);
700 llOwnerSay("Finished linking, please pick up your skirt!");
701 llOwnerSay("If you enjoy using this tool, feel free to tip the creator Dalien Talbot according to the level of your enjoyment :-)");
702 // clean up the script...
704 }
705 } else {
706 llOwnerSay("ERROR: permissions not acquired, can not link...");
707 }
708
709 }
710
711 } else {
712 if(command == "die_skirt") {
713 // only the ball and the skirt prims obey this
714 llDie();
715 } else if(command == "link") {
716 // kind of echo, but for linking...
717 llSay(commChannelBase + 1 - 11, "linkme");
718 //llOwnerSay("linkme!");
719 } else if(command == "bulk") {
720 // "bulk" is essentially the same as init, except "myNumber" is not sent.
721 set_globals_from_list(aList, i);
722 // notify the owner (debug)
723 //llOwnerSay("got:" + llDumpList2String([myNumber, standPos, numObjects, xRadius, yRadius, flareAngle, bendCoefficient, rotOffset, posOffset], ":"));
724 // and position ourselves properly
725 new_position();
726 } else if(command == "prim_params") {
727 setParams(aList);
728 } else if(command == "reposition") {
729 new_position();
730 } else if(command == "scale") {
731 vector scale = (vector)llList2String(aList, 1);
732 llSetScale(scale);
733 } else if(command == "color") {
734 while(i < len) {
735 integer side = (integer)llList2String(aList, i);
736 vector color = (vector)llList2String(aList, i+1);
737 llSetColor(color, side);
738 i = i+2;
739 }
740 } else if(command == "alpha") {
741 while(i < len) {
742 integer side = (integer)llList2String(aList, i);
743 float alpha = (float)llList2String(aList, i+1);
744 llSetAlpha(alpha, side);
745 i = i+2;
746 }
747 }
748 }
749
750 }
751 }
752
753 }

PrimSkirt Builder

PrimSkirt Builder

Category: Clothing
By : Dalien Talbot
Created: 2015-03-17 Edited: 2015-03-17
Worlds: Second Life

1 // Prim size .010 X .350 X .250
2 // add textures with circle
3 //
4 // Copyright (c) 2007 Dalien Talbot and few other folks thanks to whom this exists:
5 //
6 // Vint Falken, of course - the inspiration, pushing me to the idea, testing, and finding the software bugs :-)
7 // LSL wiki - the function reference
8 // Posing stand code - unknown author
9 // LoopRez v0.6, by Ged Larsen, 20 December 2006 - the math for placement of the skirt prims
10 //
11 // This work is distributed "as-is" with no warranty whatsoever.
12 //
13 //
14 // It is distributed under GPL license. Please have a look at the "EULA" and the "GNU License" notecards in the inventory
15 // to get familiar with the terms and conditions.
16 //
17 // All the derivatives of this work obviously have to comply with the GPL as well. Contact me (Dalien Talbot) if you require alternative licensing.
18 //
19 //
20
21 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
22 // NOTE:
23 // Unless you know what you are doing, do NOT change anything below !
24 //
25 // The standard consulting fees mentioned in the manual will apply for the works on fixing the breakages :-)
26 //
27 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
28
29
30
31
32
33
34 // CONFIGURATION PARAMETERS, they get reset from the main script!!!
35
36 integer myNumber = 0; // number of the prim
37 vector standPos; // position of the mothership
38 integer numObjects = 12; // how many objects
39 float xRadius = .16; // ellipse x-axis radius in meters
40 float yRadius = .22; // ellipse y-axis radius in meters
41 float flareAngle = 45.0; // how many DEGREES the bottom of object will flare outwards, the "poof" factor
42 float bendCoefficient = 0.0; // makes a "saddle shape", bends DOWN this number of meters at extremes of X-axis
43 vector rotOffset = <0.0, 180.0, 0.0>; // rotation offset in DEGREES -- fixes the rotation of ALL objects; for flexi prims, often you will want <180.0, 0.0, 0.0>
44 vector posOffset = <0.0, 0.0, 1.0>; // position offset
45
46 string prompt = "Edit/move this prim\nto edit/move the skirt";
47
48 // linking permission acquired
49 integer miPermissionsAcquired = FALSE;
50 // current object being linked, when linked...
51 integer currObject = 0;
52
53 // idle counter - when it increments to 1000, we clean up the control prims.
54 integer idleCounter = 0;
55
56
57 ////////////////////////////////////////////////////////////////////////////////
58 // No need to mess with anything below here
59
60
61 adjust_flare (vector currentPos, rotation currentRot, float flareAngle) {
62 float rotateAngle = flareAngle; // how much to rotate per iteration (in degrees)
63 rotation rot = currentRot;
64 vector scale = llGetScale(); // return the size of the object
65 vector offset = <0, 0, -scale.z/2>; // rotate the object around the center of its top
66 vector offsetPosition = <0, 0, -scale.z/2>; // the position should be that of the top
67 // the two values being the same is a bit coincidental..
68
69
70 vector euler = <0, -1*rotateAngle*DEG_TO_RAD, 0>; // delta rotation expressed as a vector in radians
71 rotation deltarot = llEuler2Rot(euler); // delta rotation expressed as a rotation
72 rotation newrot = deltarot * rot; // new rotation for the object
73
74 vector vvv = offset * rot; // current offset of the rotation point vs. the prim center
75 vector vvv2 = offset * newrot; // new offset of the rotation point vs. the prim center
76
77 //vector currentPos = llGetPos(); // current position
78 //vector rotPoint = llGetPos() + vvv; // current rotation point, not needed except for visualization
79
80 vector newPos; // new position for the prim
81
82 newPos = currentPos + (vvv - vvv2); // is a current position offsetted by a difference between the rotation point offsets
83
84 //llRezObject("ball", rotPoint, ZERO_VECTOR, ZERO_ROTATION, 0); // visualize the rotation point
85
86 // now we also need to adjust the position - so that the top is always at the same place..
87 // the position that we have got is calculated for the center of the prim.
88 newPos = newPos + offsetPosition;
89
90 llSetPos(newPos); // set the new position
91 llSetRot(newrot); // and the new rotation
92 }
93
94
95 makeLoop(integer n, vector standPos, integer numObjects, float xRadius, float yRadius,
96 float flareAngle, float bendCoefficient, vector rotOffset, vector posOffset)
97 {
98 //integer n; // which object is being placed
99 float theta; // angle in radians
100 vector pos; // position
101 rotation rot; // rotation in quaternionformat
102
103 //for(n = 0; n < numObjects; n++) {
104
105 theta = TWO_PI * ( (float)n / (float)numObjects );
106
107 pos.x = xRadius * llCos(theta); // ellipse: 2x xRadius meters wide
108 pos.y = yRadius * llSin(theta); // ellipse: 2x yRadius meters wide
109 pos.z = -bendCoefficient*llCos(theta)*llCos(theta); // saddle shape, bending downwards on X-axis
110 pos = pos + standPos + posOffset;
111
112 rot = llEuler2Rot(<rotOffset.x*DEG_TO_RAD, rotOffset.y*DEG_TO_RAD, rotOffset.z*DEG_TO_RAD>); // user-chosen rotation offset correction
113
114
115 // the following make the objects face outwards properly for an ellipse; using theta alone is only correct for a circle
116 // the scary formula calculates a unit vector TANGENTIAL to the ellipse, and llRotBetween is used to figure out how much the object needs to rotate to lie parallel to the tangent
117 rot = rot * llRotBetween(<0.0,1.0,0.0>, <-1.0 * xRadius * llSin(theta) / ( llSqrt( (yRadius*yRadius * llCos(theta) * llCos(theta)) + (xRadius*xRadius * llSin(theta) * llSin(theta))) ),yRadius * llCos(theta) / ( llSqrt( (yRadius*yRadius * llCos(theta) * llCos(theta)) + (xRadius*xRadius * llSin(theta) * llSin(theta))) ),0.0>);
118 if( n== (numObjects/2) ) // LSL's implementation of llRotBetween at theta = pi radians is reversed at 180 degrees, so this manually corrects it
119 rot = rot * llEuler2Rot( <0,PI,0> );
120
121
122 //rot = rot * llEuler2Rot(<0, -1*flareAngle*DEG_TO_RAD, 0>); // flare generation (poof)
123
124 //llRezObject(objectName, pos, ZERO_VECTOR, rot, 0);
125 //llSetPos(pos);
126 //llSetRot(rot);
127
128 // it will rotate the pieces and set their positions...
129 adjust_flare(pos, rot, flareAngle);
130 //}
131 }
132
133 // are we a control prim (texture/shape/etc.) ?
134 integer isControlPrim = 0;
135 // a ball for skirt linkage
136 integer isLinkCenterPrim = 0;
137
138 // are we a geometry control prim (xradius/yradius/flare/z) ?
139 integer isGeomControlPrim = 0;
140 // how much the "real" waist size is different from the geometry control prim
141 float waistSizeDivizor = 5.0;
142
143
144 integer listenHandle = 0;
145 integer listenHandle2 = 0;
146 integer commChannelBase = 0;
147
148
149 position_geometry_prim()
150 {
151 rotation rot = llEuler2Rot(<0., flareAngle * DEG_TO_RAD, 0. >);
152 vector scale;
153 scale.x = 0.01 + bendCoefficient;
154 scale.y = yRadius * waistSizeDivizor;
155 scale.z = xRadius * waistSizeDivizor;
156 llSetRot(rot);
157 llSetScale(scale);
158 }
159
160 new_position()
161 {
162 // do the fancy math foobar only for the "normal" prims
163 if( (isControlPrim + isLinkCenterPrim + isGeomControlPrim) == 0) {
164 makeLoop(myNumber, standPos, numObjects, xRadius, yRadius, flareAngle, bendCoefficient, rotOffset, posOffset);
165 }
166 if(isLinkCenterPrim) {
167 // link center prim will need to be in the center (surprise surprize!)
168 // since the Z is actually the top of the prims,
169 // nothing much more to be done here
170 // we position it here, since it needs to move with the "normal" prims.
171 vector linkerPos = standPos + posOffset;
172 llSetPos(linkerPos);
173 }
174 }
175
176 position_master_prim()
177 {
178 rotation rot;
179 vector rotOffset = <180.,0.,0.>;
180 rot = llEuler2Rot(<rotOffset.x*DEG_TO_RAD, rotOffset.y*DEG_TO_RAD, rotOffset.z*DEG_TO_RAD>);
181 // flare angle belongs to the flare control...
182 //rot = rot * llEuler2Rot(<0, -1*flareAngle*DEG_TO_RAD, 0>);
183 llSetRot(rot);
184
185 }
186
187
188
189 //------------------ prim mod slave
190
191
192 setParams(list alist)
193 {
194 list res = [ ];
195 integer i;
197 //string aStart = elapsed("");
198 //string aElapsed;
199 string token;
200 integer slen;
201 float f;
202 integer int;
203 // skip the first token - so start from 1
204 for(i=1; i<len; i++) {
205 token = llList2String(alist, i);
206 slen = llStringLength(token);
207 //llOwnerSay("i:" + (string)i + ", slen: " + (string)slen + ", '" + token + "'");
208
209 if(slen == 36) {
210 // for length of 36 we assume key
211 res = res + [ token ];
212 } else if(slen >= 30 && slen <= 33) {
213 // assume vector
214 res = res + (vector)token;
215 } else {
216 // assume integer or float
217 int = (integer)token;
218 if(token == (string) int) {
219 res = res + [ int ];
220 } else {
221 res = res + [ (float) token ];
222 }
223 }
224
225 }
226 //aElapsed = elapsed(aStart);
227
228 //llOwnerSay("result:" + llDumpList2String(res, ":"));
229 //llOwnerSay("Time taken: " + aElapsed);
231 }
232
233
234
235
236 // ------------------------- prim mod master
237
238 list sideTextures = [ ];
239 list sideTexgen = [ ];
240 list sideColors = [ ];
241 list sideAlphas = [ ];
242
243
244 list tokens = [ ];
245
246 // saved position/rotation for the timer events
247 vector myLastPos;
248 vector myLastRot;
249
250
251 // the mask for the delayed update processing
252 // the values are similar to "mask" in the change event
253
254 integer mask = 0;
255
256
257 sendCommand(string cmd)
258 {
259 //llOwnerSay(cmd);
260 llSay(commChannelBase - 1, cmd);
261 }
262
263 resetSideCaches()
264 {
265 sideTextures = [ ];
266 sideTexgen = [ ];
267 sideColors = [ ];
268 sideAlphas = [ ];
269 }
270
271
272
273 checkTextures()
274 {
275 integer i;
278 list newTextures = [ ];
279
280 for(i=0;i<num; i++) {
281 list param = llList2List(result, num + i*4, num + i*4+3);
282 list currparam = llList2List(sideTextures, i*4, i*4+3);
283 integer currparam_len = llGetListLength(currparam);
284
285 if(currparam_len == 0 || llListFindList(param, currparam) == -1) {
286 tokens = tokens + [ PRIM_TEXTURE, i ] + param;
287 }
288 if(llList2Integer(result, i) != llList2Integer(sideTexgen, i)) {
289 tokens = tokens + [ PRIM_TEXGEN, i, llList2Integer(result, i) ];
290 }
291
292 }
293 sideTexgen = llList2List(result, 0, num - 1);
294 sideTextures = llList2List(result, num, -1);
295 //llOwnerSay("!checkTextures end");
296
297 }
298
299
300
301 checkColor()
302 {
303 integer i;
305 list newColors;
306 string cmd = "color";
307 for(i=0;i<num; i++) {
308 vector color = llGetColor(i);
309 newColors = newColors + [ color ];
310
311 if((vector)llList2String(sideColors, i) != color) {
312 cmd = cmd + ":" + (string)i + ":" + (string)color;
313 }
314 }
315 sideColors = newColors;
316 sendCommand(cmd);
317
318 }
319
320 checkAlpha()
321 {
322 integer i;
324 list newAlphas;
325 string cmd = "alpha";
326 for(i=0;i<num; i++) {
327 float alpha = llGetAlpha(i);
328 newAlphas = newAlphas + [ alpha ];
329
330 if((float)llList2String(sideAlphas, i) != alpha) {
331 cmd = cmd + ":" + (string)i + ":" + (string)alpha;
332 }
333 }
334 sideAlphas = newAlphas;
335 sendCommand(cmd);
336
337 }
338
339 checkShape()
340 {
342 sendCommand("prim_params:" + llDumpList2String([ PRIM_TYPE ] + llList2List(result, 7, -1), ":"));
343
344
345 //tokens = tokens + [ PRIM_TYPE ] + llList2List(result, 7, -1) + [ PRIM_FLEXIBLE ] + llList2List(result, 0, 6);
346 tokens = tokens + [ PRIM_FLEXIBLE ] + llList2List(result, 0, 6);
347 }
348
349 checkScale()
350 {
351 vector scale = llGetScale();
352 vector scale0 = scale;
353 scale0.z = scale0.z - 0.01;
354 // workaround against the flex objects not rendering if z size not changed...
355 sendCommand("prim_params:" + llDumpList2String([ PRIM_SIZE, scale0 ], ":"));
356
357 tokens = tokens + [ PRIM_SIZE, scale ];
358 return;
359 }
360
361
362
363 // this function gets called from the timer, and fires up the commands to the
364 // other prims to adjust themselves
365 // the reason for calling it from timer is to make the processing
366 // a little bit lighter... (LSL's string/list parsing is a pain in the butt and
367 // is a main reason for slowness...)
368 check_changed()
369 {
370 if(isControlPrim) {
371 // prim's characteristics replicate to others
372 tokens = [ ];
373 if(mask & CHANGED_SHAPE){
374 // changing the prim type can change everything
375 checkShape();
377
378 }
379 if(mask & CHANGED_COLOR){
380 checkColor();
381 checkAlpha();
382 }
383
384
385 if(mask & CHANGED_TEXTURE){
386 checkTextures();
387 }
388 if(mask & CHANGED_SCALE){
389 checkScale();
390 }
391 if(llGetListLength(tokens) > 0) {
392 sendCommand("prim_params:" + llDumpList2String(tokens, ":"));
393 if(mask & CHANGED_SHAPE || mask & CHANGED_SCALE) {
394 // changing shapes involves recalculation of the position
395 sendCommand("reposition");
396 }
397
398 }
399 }
400
401 if(isGeomControlPrim) {
402 // z scale = xradius
403 // y scale = yradius
404 // y axis tilt (handled elsewhere) = flare
405 // x scale - 0.01 = bend coefficient
406 vector scale = llGetScale();
407 scale.x = scale.x - 0.01;
408 scale.y = scale.y / waistSizeDivizor;
409 scale.z = scale.z / waistSizeDivizor;
410 if(mask & CHANGED_SCALE) {
411 llSay(commChannelBase, "geometry:" + (string)scale);
412 }
413 }
414
415
416 // reset all the changed notifications - we've done what we had to do...
417 mask = 0;
418
419 }
420
421 restart_timer()
422 {
423 // stop the timer and restart it
426 }
427
428 // ugggly hack - but since i am reusing the list of global vars...
429 set_globals_from_list(list aList, integer i)
430 {
431 standPos = (vector)llList2String(aList, i); i=i+1;
432 numObjects = llList2Integer(aList, i); i=i+1;
433 xRadius = llList2Float(aList, i); i=i+1;
434 yRadius = llList2Float(aList, i); i=i+1;
435 flareAngle = llList2Float(aList, i); i=i+1;
436 bendCoefficient = llList2Float(aList, i); i=i+1;
437 rotOffset = (vector)llList2String(aList, i); i=i+1;
438 posOffset = (vector)llList2String(aList, i); i=i+1;
439 }
440
441 // tell child to tell back its id so we could link it...
442 ask_child_to_link()
443 {
444 llSay(commChannelBase + 1 + currObject, "link");
445 }
446
447 default
448 {
449 touch_start(integer channel)
450 {
451 // ask the stand prim to show the menu, and avoid the spam in the chat
452 if(commChannelBase != 0) {
453 if(llDetectedKey(0) == llGetOwner()) {
454 llSay(commChannelBase, "menu");
455 } else {
456 llInstantMessage(llDetectedKey(0), "Only owner can modify the skirt - get your free copy - right-click the posing stand and buy it for L$0");
457 }
458 }
459
460 }
461 on_rez(integer channel) {
462 if(channel == 0) {
463 if(llGetNumberOfPrims() > 1) {
464 // need to check if we are linked and if yes - then delete the script...
466 }
467 // if channel = 0 means we have been rezzed by the user - so do not do anything...
468 return;
469 }
470 commChannelBase = channel;
471 listenHandle = llListen(channel, "", "", "");
472 // request the boot parameters
473 llSay(channel, "boot");
474 }
476 {
478 {
479
480 //set permission flag
481 miPermissionsAcquired = TRUE;
482 // reset any pending events...
484 // start the linking...
485 currObject = 0;
486 llOwnerSay("Linking will take some time, please be patient...");
487 ask_child_to_link();
488 } else {
489 llOwnerSay("ERROR: permission was not acquired, can not link...");
490 }
491 }
492
493
494 changed(integer changed_mask)
495 {
496 if((changed_mask & CHANGED_LINK) && (!isLinkCenterPrim) && (!isControlPrim) && (!isGeomControlPrim) ) {
497 if(llGetNumberOfPrims() > 1) {
498 // need to check if we are linked and if yes - then delete the script...
499 // the link centre prim will remove the script from itself,
500 // either on next rez, or when it finishes linking us.
502 }
503
504 } else {
505 if(isControlPrim || isGeomControlPrim) {
506 // set the appropriate flags
507 // so that timer event would fix it.
508 restart_timer();
509 mask = mask | changed_mask;
510 }
511 }
512
513 }
514 timer() {
515 idleCounter = idleCounter + 1;
516
517 if(isControlPrim || isGeomControlPrim) {
518 if(idleCounter > 1000) {
519 // the stand is gone and did not remind about itself... go away then.
520 llOwnerSay("Did not hear from the stand - so it must have been taken away - self-destroying...");
521 llDie();
522 }
523 } else {
524 if(idleCounter > 20) {
525 // the stand is gone and did not remind about itself... go away then.
526 llOwnerSay("Did not hear from the stand - so it must have been taken away - self-destroying...");
527 llDie();
528 }
529 }
530 if(isControlPrim) {
531 // control prim
532 vector myCurrentPos = llGetPos();
533 vector delta = myCurrentPos - myLastPos;
534
535 if( (mask & CHANGED_SCALE) == 0) {
536 // if both the scale AND position is changed - do not move
537 // since when the scale changes via the mouse, the center drifts away...
538
539 if(llVecDist(myLastPos, myCurrentPos) > 0) {
540 llSay(commChannelBase, "move:" + (string)delta);
541 //llOwnerSay("moved!");
542 }
543 }
544 myLastPos = myCurrentPos;
545 }
546 if(isGeomControlPrim) {
547 // geometry control prim - check the tilt, the scale is checked elsewhere
548 vector myCurrentRot = llRot2Euler(llGetRot());
549 if(llVecDist(myLastRot, myCurrentRot) > 0) {
550 llSay(commChannelBase, "flare:" + (string)(myCurrentRot.y / DEG_TO_RAD));
551 }
552 myLastRot = myCurrentRot;
553 }
554
555 if(mask != 0) {
556 // naive attempt at optimization...
557 check_changed();
558 }
559 }
560
561
562
563 listen(integer channel, string name, key id, string message)
564 {
565 integer i = 1; // first parameter;
566 //llOwnerSay("message: '" + message + "'");
567 if(channel == commChannelBase) {
568 // init string
569 // init:myNumber:boot_string
570 // where boot string is:
571 // [myPos, numObjects, xRadius, yRadius, flareAngle, bendCoefficient, rotOffset, posOffset]
572 list aList = llParseString2List(message, [":"], []);
573 if(llList2String(aList, 0) == "init") {
574
575 llListenRemove(listenHandle);
576 myNumber = llList2Integer(aList, i); i=i+1;
577 llSetObjectName((string)myNumber);
578
579
580 // object number ranges from 0 to numObjects-1
581 // if we have got the number "numObjects" then we are the "control" prim - should not react to position change requests.
582
583 // start listening for mothership only
584 listenHandle = llListen(commChannelBase + 1 + myNumber, "", "", "");
585 listenHandle = llListen(commChannelBase - 1, "", "", "");
586
587
588 // report back to mothership that we are ok to fly on our own so it continues to generate the prims
589 llSay(commChannelBase, "init_ok");
590
591 // set the global parameters from the list
592 set_globals_from_list(aList, i);
593
594 isControlPrim = 0;
595 isLinkCenterPrim = 0;
596 isGeomControlPrim = 0;
597
598 // set the keepalive timer for the precaution self-destruction
599 // in the skirt prims - for the special prims the timer will be faster...
600 llSetTimerEvent(120);
601
602
603 if(myNumber == -10) {
604 // control prim - change its appearance and it replicates...
605 isControlPrim = 1;
606 llSetObjectName("Primskirt builder control prim");
607
608 llSetText(prompt, <0., 1., 0.>, 1.0);
609
610 position_master_prim();
611 myLastPos = llGetPos();
612 // for move/rotate and delayed prim replication
613 restart_timer();
614 } else if(myNumber == -11) {
615 // link center prim - a ball to use as a root for the skirt
616 isLinkCenterPrim = 1;
617 llSetObjectName("Prim Skirt");
618
619
620 } else if(myNumber == -12) {
621 // geometry control prim
622 isGeomControlPrim = 1;
623 llSetObjectName("Waist size/flare/bend control prim");
624 llSetText("X size: bend\nY size: yradius\nZ size: xradius\nY rotate: flare", <0., 1., 0.>, 1.0);
625 // the new position
626 position_geometry_prim();
627 }
628
629 // notify the owner (debug)
630 //llOwnerSay("got:" + llDumpList2String([myNumber, standPos, numObjects, xRadius, yRadius, flareAngle, bendCoefficient, rotOffset, posOffset], ":"));
631 // and position ourselves properly
632 new_position();
633
634 } else {
635 llOwnerSay("Unknown init message:'" + message + "'");
636 }
637 } else {
638 // control messages from the mothership or the control prim
639 list aList = llParseString2List(message, [":"], []);
640 string command = llList2String(aList, 0);
641 integer len = llGetListLength(aList);
642 integer i = 1;
643 // reset the idle counter
644 idleCounter = 0;
645 if(command == "echo") {
646 // reply to those that care
647 llSay(commChannelBase, "echo_reply");
648 } else if(command == "die") {
649 llDie();
650 } else if(isControlPrim == 1) {
651 // do not respond to change position and all
652 if(command == "repost") {
653 // we need to push the prim characteristics
654 mask = mask | CHANGED_SHAPE | CHANGED_COLOR | CHANGED_SCALE | CHANGED_TEXTURE;
655 resetSideCaches();
656 restart_timer();
657 }
658 } else if(isGeomControlPrim == 1) {
659 // only allow to modify the shape
660 // special kind of prim_params
661 if(command == "gc_prim_params") {
662 setParams(aList);
663 } else if(command == "bulk") {
664 // "bulk" is essentially the same as init, except "myNumber" is not sent.
665 set_globals_from_list(aList, i);
666 // position sets the box according to current parameters
667 new_position();
668 } else if(command == "repost") {
669 // we need to push the prim characteristics
670 mask = mask | CHANGED_SHAPE | CHANGED_COLOR | CHANGED_SCALE | CHANGED_TEXTURE;
671 myLastRot = myLastRot * <1.,1.,1.,0.5>; // just to "touch" the rotation so timer updates the things
672 restart_timer();
673 }
674 } else if(isLinkCenterPrim == 1) {
675 if(command == "die_skirt") {
676 // only the ball and the skirt prims obey this
677 llDie();
678 } else if(command == "bulk") {
679 // bulk works for linkcenter too, but most of it is ignored in processing...
680 set_globals_from_list(aList, i);
681 // and position ourselves properly
682 new_position();
683 } else if(command == "lc_prim_params") {
684 // special kind of prim_params
685 setParams(aList);
686 } else if(command == "link") {
688 } else if(command == "linkme") {
689 // someone wants to be linked...
690 //llOwnerSay("linkme rcvd!");
691 if(miPermissionsAcquired) {
692 integer num = currObject + 1;
693 llOwnerSay("Linking prim " + (string)num + " of " + (string)numObjects + ", please wait...");
694 llCreateLink(id, TRUE);
695 currObject = currObject + 1;
696 if(currObject < numObjects) {
697 ask_child_to_link();
698 } else {
699 vector pos = llGetPos() + <-1.0, 1.0, 0.0>;
700 llSetPos(pos);
701 llOwnerSay("Finished linking, please pick up your skirt!");
702 llOwnerSay("If you enjoy using this tool, feel free to tip the creator Dalien Talbot according to the level of your enjoyment :-)");
703 // clean up the script...
705 }
706 } else {
707 llOwnerSay("ERROR: permissions not acquired, can not link...");
708 }
709
710 }
711
712 } else {
713 if(command == "die_skirt") {
714 // only the ball and the skirt prims obey this
715 llDie();
716 } else if(command == "link") {
717 // kind of echo, but for linking...
718 llSay(commChannelBase + 1 - 11, "linkme");
719 //llOwnerSay("linkme!");
720 } else if(command == "bulk") {
721 // "bulk" is essentially the same as init, except "myNumber" is not sent.
722 set_globals_from_list(aList, i);
723 // notify the owner (debug)
724 //llOwnerSay("got:" + llDumpList2String([myNumber, standPos, numObjects, xRadius, yRadius, flareAngle, bendCoefficient, rotOffset, posOffset], ":"));
725 // and position ourselves properly
726 new_position();
727 } else if(command == "prim_params") {
728 setParams(aList);
729 } else if(command == "reposition") {
730 new_position();
731 } else if(command == "scale") {
732 vector scale = (vector)llList2String(aList, 1);
733 llSetScale(scale);
734 } else if(command == "color") {
735 while(i < len) {
736 integer side = (integer)llList2String(aList, i);
737 vector color = (vector)llList2String(aList, i+1);
738 llSetColor(color, side);
739 i = i+2;
740 }
741 } else if(command == "alpha") {
742 while(i < len) {
743 integer side = (integer)llList2String(aList, i);
744 float alpha = (float)llList2String(aList, i+1);
745 llSetAlpha(alpha, side);
746 i = i+2;
747 }
748 }
749 }
750
751 }
752 }
753
754 }

Back to the Best Free Tools in Second Life and OpenSim.