opensim – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | eva | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ |
||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
||
4 | * |
||
5 | * Redistribution and use in source and binary forms, with or without |
||
6 | * modification, are permitted provided that the following conditions are met: |
||
7 | * * Redistributions of source code must retain the above copyright |
||
8 | * notice, this list of conditions and the following disclaimer. |
||
9 | * * Redistributions in binary form must reproduce the above copyright |
||
10 | * notice, this list of conditions and the following disclaimer in the |
||
11 | * documentation and/or other materials provided with the distribution. |
||
12 | * * Neither the name of the OpenSimulator Project nor the |
||
13 | * names of its contributors may be used to endorse or promote products |
||
14 | * derived from this software without specific prior written permission. |
||
15 | * |
||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||
26 | */ |
||
27 | |||
28 | using System; |
||
29 | using System.Collections.Generic; |
||
30 | using System.Drawing; |
||
31 | using System.Drawing.Imaging; |
||
32 | using System.IO; |
||
33 | using System.Reflection; |
||
34 | using System.Xml; |
||
35 | using System.Xml.Schema; |
||
36 | using System.Xml.Serialization; |
||
37 | using log4net; |
||
38 | using OpenMetaverse; |
||
39 | using OpenMetaverse.StructuredData; |
||
40 | |||
41 | namespace OpenSim.Framework |
||
42 | { |
||
43 | public enum ProfileShape : byte |
||
44 | { |
||
45 | Circle = 0, |
||
46 | Square = 1, |
||
47 | IsometricTriangle = 2, |
||
48 | EquilateralTriangle = 3, |
||
49 | RightTriangle = 4, |
||
50 | HalfCircle = 5 |
||
51 | } |
||
52 | |||
53 | public enum HollowShape : byte |
||
54 | { |
||
55 | Same = 0, |
||
56 | Circle = 16, |
||
57 | Square = 32, |
||
58 | Triangle = 48 |
||
59 | } |
||
60 | |||
61 | public enum PCodeEnum : byte |
||
62 | { |
||
63 | Primitive = 9, |
||
64 | Avatar = 47, |
||
65 | Grass = 95, |
||
66 | NewTree = 111, |
||
67 | ParticleSystem = 143, |
||
68 | Tree = 255 |
||
69 | } |
||
70 | |||
71 | public enum Extrusion : byte |
||
72 | { |
||
73 | Straight = 16, |
||
74 | Curve1 = 32, |
||
75 | Curve2 = 48, |
||
76 | Flexible = 128 |
||
77 | } |
||
78 | |||
79 | [Serializable] |
||
80 | public class PrimitiveBaseShape |
||
81 | { |
||
82 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
||
83 | |||
84 | private static readonly byte[] DEFAULT_TEXTURE = new Primitive.TextureEntry(new UUID("89556747-24cb-43ed-920b-47caed15465f")).GetBytes(); |
||
85 | |||
86 | private byte[] m_textureEntry; |
||
87 | |||
88 | private ushort _pathBegin; |
||
89 | private byte _pathCurve; |
||
90 | private ushort _pathEnd; |
||
91 | private sbyte _pathRadiusOffset; |
||
92 | private byte _pathRevolutions; |
||
93 | private byte _pathScaleX; |
||
94 | private byte _pathScaleY; |
||
95 | private byte _pathShearX; |
||
96 | private byte _pathShearY; |
||
97 | private sbyte _pathSkew; |
||
98 | private sbyte _pathTaperX; |
||
99 | private sbyte _pathTaperY; |
||
100 | private sbyte _pathTwist; |
||
101 | private sbyte _pathTwistBegin; |
||
102 | private byte _pCode; |
||
103 | private ushort _profileBegin; |
||
104 | private ushort _profileEnd; |
||
105 | private ushort _profileHollow; |
||
106 | private Vector3 _scale; |
||
107 | private byte _state; |
||
108 | private byte _lastattach; |
||
109 | private ProfileShape _profileShape; |
||
110 | private HollowShape _hollowShape; |
||
111 | |||
112 | // Sculpted |
||
113 | [XmlIgnore] private UUID _sculptTexture; |
||
114 | [XmlIgnore] private byte _sculptType; |
||
115 | [XmlIgnore] private byte[] _sculptData = Utils.EmptyBytes; |
||
116 | |||
117 | // Flexi |
||
118 | [XmlIgnore] private int _flexiSoftness; |
||
119 | [XmlIgnore] private float _flexiTension; |
||
120 | [XmlIgnore] private float _flexiDrag; |
||
121 | [XmlIgnore] private float _flexiGravity; |
||
122 | [XmlIgnore] private float _flexiWind; |
||
123 | [XmlIgnore] private float _flexiForceX; |
||
124 | [XmlIgnore] private float _flexiForceY; |
||
125 | [XmlIgnore] private float _flexiForceZ; |
||
126 | |||
127 | //Bright n sparkly |
||
128 | [XmlIgnore] private float _lightColorR; |
||
129 | [XmlIgnore] private float _lightColorG; |
||
130 | [XmlIgnore] private float _lightColorB; |
||
131 | [XmlIgnore] private float _lightColorA = 1.0f; |
||
132 | [XmlIgnore] private float _lightRadius; |
||
133 | [XmlIgnore] private float _lightCutoff; |
||
134 | [XmlIgnore] private float _lightFalloff; |
||
135 | [XmlIgnore] private float _lightIntensity = 1.0f; |
||
136 | [XmlIgnore] private bool _flexiEntry; |
||
137 | [XmlIgnore] private bool _lightEntry; |
||
138 | [XmlIgnore] private bool _sculptEntry; |
||
139 | |||
140 | // Light Projection Filter |
||
141 | [XmlIgnore] private bool _projectionEntry; |
||
142 | [XmlIgnore] private UUID _projectionTextureID; |
||
143 | [XmlIgnore] private float _projectionFOV; |
||
144 | [XmlIgnore] private float _projectionFocus; |
||
145 | [XmlIgnore] private float _projectionAmb; |
||
146 | |||
147 | public byte ProfileCurve |
||
148 | { |
||
149 | get { return (byte)((byte)HollowShape | (byte)ProfileShape); } |
||
150 | |||
151 | set |
||
152 | { |
||
153 | // Handle hollow shape component |
||
154 | byte hollowShapeByte = (byte)(value & 0xf0); |
||
155 | |||
156 | if (!Enum.IsDefined(typeof(HollowShape), hollowShapeByte)) |
||
157 | { |
||
158 | m_log.WarnFormat( |
||
159 | "[SHAPE]: Attempt to set a ProfileCurve with a hollow shape value of {0}, which isn't a valid enum. Replacing with default shape.", |
||
160 | hollowShapeByte); |
||
161 | |||
162 | this._hollowShape = HollowShape.Same; |
||
163 | } |
||
164 | else |
||
165 | { |
||
166 | this._hollowShape = (HollowShape)hollowShapeByte; |
||
167 | } |
||
168 | |||
169 | // Handle profile shape component |
||
170 | byte profileShapeByte = (byte)(value & 0xf); |
||
171 | |||
172 | if (!Enum.IsDefined(typeof(ProfileShape), profileShapeByte)) |
||
173 | { |
||
174 | m_log.WarnFormat( |
||
175 | "[SHAPE]: Attempt to set a ProfileCurve with a profile shape value of {0}, which isn't a valid enum. Replacing with square.", |
||
176 | profileShapeByte); |
||
177 | |||
178 | this._profileShape = ProfileShape.Square; |
||
179 | } |
||
180 | else |
||
181 | { |
||
182 | this._profileShape = (ProfileShape)profileShapeByte; |
||
183 | } |
||
184 | } |
||
185 | } |
||
186 | |||
187 | /// <summary> |
||
188 | /// Entries to store media textures on each face |
||
189 | /// </summary> |
||
190 | /// Do not change this value directly - always do it through an IMoapModule. |
||
191 | /// Lock before manipulating. |
||
192 | public MediaList Media { get; set; } |
||
193 | |||
194 | public PrimitiveBaseShape() |
||
195 | { |
||
196 | PCode = (byte)PCodeEnum.Primitive; |
||
197 | m_textureEntry = DEFAULT_TEXTURE; |
||
198 | } |
||
199 | |||
200 | /// <summary> |
||
201 | /// Construct a PrimitiveBaseShape object from a OpenMetaverse.Primitive object |
||
202 | /// </summary> |
||
203 | /// <param name="prim"></param> |
||
204 | public PrimitiveBaseShape(Primitive prim) |
||
205 | { |
||
206 | // m_log.DebugFormat("[PRIMITIVE BASE SHAPE]: Creating from {0}", prim.ID); |
||
207 | |||
208 | PCode = (byte)prim.PrimData.PCode; |
||
209 | |||
210 | State = prim.PrimData.State; |
||
211 | LastAttachPoint = prim.PrimData.State; |
||
212 | PathBegin = Primitive.PackBeginCut(prim.PrimData.PathBegin); |
||
213 | PathEnd = Primitive.PackEndCut(prim.PrimData.PathEnd); |
||
214 | PathScaleX = Primitive.PackPathScale(prim.PrimData.PathScaleX); |
||
215 | PathScaleY = Primitive.PackPathScale(prim.PrimData.PathScaleY); |
||
216 | PathShearX = (byte)Primitive.PackPathShear(prim.PrimData.PathShearX); |
||
217 | PathShearY = (byte)Primitive.PackPathShear(prim.PrimData.PathShearY); |
||
218 | PathSkew = Primitive.PackPathTwist(prim.PrimData.PathSkew); |
||
219 | ProfileBegin = Primitive.PackBeginCut(prim.PrimData.ProfileBegin); |
||
220 | ProfileEnd = Primitive.PackEndCut(prim.PrimData.ProfileEnd); |
||
221 | Scale = prim.Scale; |
||
222 | PathCurve = (byte)prim.PrimData.PathCurve; |
||
223 | ProfileCurve = (byte)prim.PrimData.ProfileCurve; |
||
224 | ProfileHollow = Primitive.PackProfileHollow(prim.PrimData.ProfileHollow); |
||
225 | PathRadiusOffset = Primitive.PackPathTwist(prim.PrimData.PathRadiusOffset); |
||
226 | PathRevolutions = Primitive.PackPathRevolutions(prim.PrimData.PathRevolutions); |
||
227 | PathTaperX = Primitive.PackPathTaper(prim.PrimData.PathTaperX); |
||
228 | PathTaperY = Primitive.PackPathTaper(prim.PrimData.PathTaperY); |
||
229 | PathTwist = Primitive.PackPathTwist(prim.PrimData.PathTwist); |
||
230 | PathTwistBegin = Primitive.PackPathTwist(prim.PrimData.PathTwistBegin); |
||
231 | |||
232 | m_textureEntry = prim.Textures.GetBytes(); |
||
233 | |||
234 | if (prim.Sculpt != null) |
||
235 | { |
||
236 | SculptEntry = (prim.Sculpt.Type != OpenMetaverse.SculptType.None); |
||
237 | SculptData = prim.Sculpt.GetBytes(); |
||
238 | SculptTexture = prim.Sculpt.SculptTexture; |
||
239 | SculptType = (byte)prim.Sculpt.Type; |
||
240 | } |
||
241 | else |
||
242 | { |
||
243 | SculptType = (byte)OpenMetaverse.SculptType.None; |
||
244 | } |
||
245 | } |
||
246 | |||
247 | [XmlIgnore] |
||
248 | public Primitive.TextureEntry Textures |
||
249 | { |
||
250 | get |
||
251 | { |
||
252 | // m_log.DebugFormat("[SHAPE]: get m_textureEntry length {0}", m_textureEntry.Length); |
||
253 | try { return new Primitive.TextureEntry(m_textureEntry, 0, m_textureEntry.Length); } |
||
254 | catch { } |
||
255 | |||
256 | m_log.Warn("[SHAPE]: Failed to decode texture, length=" + ((m_textureEntry != null) ? m_textureEntry.Length : 0)); |
||
257 | return new Primitive.TextureEntry(UUID.Zero); |
||
258 | } |
||
259 | |||
260 | set { m_textureEntry = value.GetBytes(); } |
||
261 | } |
||
262 | |||
263 | public byte[] TextureEntry |
||
264 | { |
||
265 | get { return m_textureEntry; } |
||
266 | |||
267 | set |
||
268 | { |
||
269 | if (value == null) |
||
270 | m_textureEntry = new byte[1]; |
||
271 | else |
||
272 | m_textureEntry = value; |
||
273 | } |
||
274 | } |
||
275 | |||
276 | public static PrimitiveBaseShape Default |
||
277 | { |
||
278 | get |
||
279 | { |
||
280 | PrimitiveBaseShape boxShape = CreateBox(); |
||
281 | |||
282 | boxShape.SetScale(0.5f); |
||
283 | |||
284 | return boxShape; |
||
285 | } |
||
286 | } |
||
287 | |||
288 | public static PrimitiveBaseShape Create() |
||
289 | { |
||
290 | PrimitiveBaseShape shape = new PrimitiveBaseShape(); |
||
291 | return shape; |
||
292 | } |
||
293 | |||
294 | public static PrimitiveBaseShape CreateBox() |
||
295 | { |
||
296 | PrimitiveBaseShape shape = Create(); |
||
297 | |||
298 | shape._pathCurve = (byte) Extrusion.Straight; |
||
299 | shape._profileShape = ProfileShape.Square; |
||
300 | shape._pathScaleX = 100; |
||
301 | shape._pathScaleY = 100; |
||
302 | |||
303 | return shape; |
||
304 | } |
||
305 | |||
306 | public static PrimitiveBaseShape CreateSphere() |
||
307 | { |
||
308 | PrimitiveBaseShape shape = Create(); |
||
309 | |||
310 | shape._pathCurve = (byte) Extrusion.Curve1; |
||
311 | shape._profileShape = ProfileShape.HalfCircle; |
||
312 | shape._pathScaleX = 100; |
||
313 | shape._pathScaleY = 100; |
||
314 | |||
315 | return shape; |
||
316 | } |
||
317 | |||
318 | public static PrimitiveBaseShape CreateCylinder() |
||
319 | { |
||
320 | PrimitiveBaseShape shape = Create(); |
||
321 | |||
322 | shape._pathCurve = (byte) Extrusion.Curve1; |
||
323 | shape._profileShape = ProfileShape.Square; |
||
324 | |||
325 | shape._pathScaleX = 100; |
||
326 | shape._pathScaleY = 100; |
||
327 | |||
328 | return shape; |
||
329 | } |
||
330 | |||
331 | public void SetScale(float side) |
||
332 | { |
||
333 | _scale = new Vector3(side, side, side); |
||
334 | } |
||
335 | |||
336 | public void SetHeigth(float height) |
||
337 | { |
||
338 | _scale.Z = height; |
||
339 | } |
||
340 | |||
341 | public void SetRadius(float radius) |
||
342 | { |
||
343 | _scale.X = _scale.Y = radius * 2f; |
||
344 | } |
||
345 | |||
346 | // TODO: void returns need to change of course |
||
347 | public virtual void GetMesh() |
||
348 | { |
||
349 | } |
||
350 | |||
351 | public PrimitiveBaseShape Copy() |
||
352 | { |
||
353 | return (PrimitiveBaseShape) MemberwiseClone(); |
||
354 | } |
||
355 | |||
356 | public static PrimitiveBaseShape CreateCylinder(float radius, float heigth) |
||
357 | { |
||
358 | PrimitiveBaseShape shape = CreateCylinder(); |
||
359 | |||
360 | shape.SetHeigth(heigth); |
||
361 | shape.SetRadius(radius); |
||
362 | |||
363 | return shape; |
||
364 | } |
||
365 | |||
366 | public void SetPathRange(Vector3 pathRange) |
||
367 | { |
||
368 | _pathBegin = Primitive.PackBeginCut(pathRange.X); |
||
369 | _pathEnd = Primitive.PackEndCut(pathRange.Y); |
||
370 | } |
||
371 | |||
372 | public void SetPathRange(float begin, float end) |
||
373 | { |
||
374 | _pathBegin = Primitive.PackBeginCut(begin); |
||
375 | _pathEnd = Primitive.PackEndCut(end); |
||
376 | } |
||
377 | |||
378 | public void SetSculptProperties(byte sculptType, UUID SculptTextureUUID) |
||
379 | { |
||
380 | _sculptType = sculptType; |
||
381 | _sculptTexture = SculptTextureUUID; |
||
382 | } |
||
383 | |||
384 | public void SetProfileRange(Vector3 profileRange) |
||
385 | { |
||
386 | _profileBegin = Primitive.PackBeginCut(profileRange.X); |
||
387 | _profileEnd = Primitive.PackEndCut(profileRange.Y); |
||
388 | } |
||
389 | |||
390 | public void SetProfileRange(float begin, float end) |
||
391 | { |
||
392 | _profileBegin = Primitive.PackBeginCut(begin); |
||
393 | _profileEnd = Primitive.PackEndCut(end); |
||
394 | } |
||
395 | |||
396 | public byte[] ExtraParams |
||
397 | { |
||
398 | get |
||
399 | { |
||
400 | return ExtraParamsToBytes(); |
||
401 | } |
||
402 | set |
||
403 | { |
||
404 | ReadInExtraParamsBytes(value); |
||
405 | } |
||
406 | } |
||
407 | |||
408 | public ushort PathBegin { |
||
409 | get { |
||
410 | return _pathBegin; |
||
411 | } |
||
412 | set { |
||
413 | _pathBegin = value; |
||
414 | } |
||
415 | } |
||
416 | |||
417 | public byte PathCurve { |
||
418 | get { |
||
419 | return _pathCurve; |
||
420 | } |
||
421 | set { |
||
422 | _pathCurve = value; |
||
423 | } |
||
424 | } |
||
425 | |||
426 | public ushort PathEnd { |
||
427 | get { |
||
428 | return _pathEnd; |
||
429 | } |
||
430 | set { |
||
431 | _pathEnd = value; |
||
432 | } |
||
433 | } |
||
434 | |||
435 | public sbyte PathRadiusOffset { |
||
436 | get { |
||
437 | return _pathRadiusOffset; |
||
438 | } |
||
439 | set { |
||
440 | _pathRadiusOffset = value; |
||
441 | } |
||
442 | } |
||
443 | |||
444 | public byte PathRevolutions { |
||
445 | get { |
||
446 | return _pathRevolutions; |
||
447 | } |
||
448 | set { |
||
449 | _pathRevolutions = value; |
||
450 | } |
||
451 | } |
||
452 | |||
453 | public byte PathScaleX { |
||
454 | get { |
||
455 | return _pathScaleX; |
||
456 | } |
||
457 | set { |
||
458 | _pathScaleX = value; |
||
459 | } |
||
460 | } |
||
461 | |||
462 | public byte PathScaleY { |
||
463 | get { |
||
464 | return _pathScaleY; |
||
465 | } |
||
466 | set { |
||
467 | _pathScaleY = value; |
||
468 | } |
||
469 | } |
||
470 | |||
471 | public byte PathShearX { |
||
472 | get { |
||
473 | return _pathShearX; |
||
474 | } |
||
475 | set { |
||
476 | _pathShearX = value; |
||
477 | } |
||
478 | } |
||
479 | |||
480 | public byte PathShearY { |
||
481 | get { |
||
482 | return _pathShearY; |
||
483 | } |
||
484 | set { |
||
485 | _pathShearY = value; |
||
486 | } |
||
487 | } |
||
488 | |||
489 | public sbyte PathSkew { |
||
490 | get { |
||
491 | return _pathSkew; |
||
492 | } |
||
493 | set { |
||
494 | _pathSkew = value; |
||
495 | } |
||
496 | } |
||
497 | |||
498 | public sbyte PathTaperX { |
||
499 | get { |
||
500 | return _pathTaperX; |
||
501 | } |
||
502 | set { |
||
503 | _pathTaperX = value; |
||
504 | } |
||
505 | } |
||
506 | |||
507 | public sbyte PathTaperY { |
||
508 | get { |
||
509 | return _pathTaperY; |
||
510 | } |
||
511 | set { |
||
512 | _pathTaperY = value; |
||
513 | } |
||
514 | } |
||
515 | |||
516 | public sbyte PathTwist { |
||
517 | get { |
||
518 | return _pathTwist; |
||
519 | } |
||
520 | set { |
||
521 | _pathTwist = value; |
||
522 | } |
||
523 | } |
||
524 | |||
525 | public sbyte PathTwistBegin { |
||
526 | get { |
||
527 | return _pathTwistBegin; |
||
528 | } |
||
529 | set { |
||
530 | _pathTwistBegin = value; |
||
531 | } |
||
532 | } |
||
533 | |||
534 | public byte PCode { |
||
535 | get { |
||
536 | return _pCode; |
||
537 | } |
||
538 | set { |
||
539 | _pCode = value; |
||
540 | } |
||
541 | } |
||
542 | |||
543 | public ushort ProfileBegin { |
||
544 | get { |
||
545 | return _profileBegin; |
||
546 | } |
||
547 | set { |
||
548 | _profileBegin = value; |
||
549 | } |
||
550 | } |
||
551 | |||
552 | public ushort ProfileEnd { |
||
553 | get { |
||
554 | return _profileEnd; |
||
555 | } |
||
556 | set { |
||
557 | _profileEnd = value; |
||
558 | } |
||
559 | } |
||
560 | |||
561 | public ushort ProfileHollow { |
||
562 | get { |
||
563 | return _profileHollow; |
||
564 | } |
||
565 | set { |
||
566 | _profileHollow = value; |
||
567 | } |
||
568 | } |
||
569 | |||
570 | public Vector3 Scale { |
||
571 | get { |
||
572 | return _scale; |
||
573 | } |
||
574 | set { |
||
575 | _scale = value; |
||
576 | } |
||
577 | } |
||
578 | |||
579 | public byte State { |
||
580 | get { |
||
581 | return _state; |
||
582 | } |
||
583 | set { |
||
584 | _state = value; |
||
585 | } |
||
586 | } |
||
587 | |||
588 | public byte LastAttachPoint { |
||
589 | get { |
||
590 | return _lastattach; |
||
591 | } |
||
592 | set { |
||
593 | _lastattach = value; |
||
594 | } |
||
595 | } |
||
596 | |||
597 | public ProfileShape ProfileShape { |
||
598 | get { |
||
599 | return _profileShape; |
||
600 | } |
||
601 | set { |
||
602 | _profileShape = value; |
||
603 | } |
||
604 | } |
||
605 | |||
606 | public HollowShape HollowShape { |
||
607 | get { |
||
608 | return _hollowShape; |
||
609 | } |
||
610 | set { |
||
611 | _hollowShape = value; |
||
612 | } |
||
613 | } |
||
614 | |||
615 | public UUID SculptTexture { |
||
616 | get { |
||
617 | return _sculptTexture; |
||
618 | } |
||
619 | set { |
||
620 | _sculptTexture = value; |
||
621 | } |
||
622 | } |
||
623 | |||
624 | public byte SculptType |
||
625 | { |
||
626 | get |
||
627 | { |
||
628 | return _sculptType; |
||
629 | } |
||
630 | set |
||
631 | { |
||
632 | _sculptType = value; |
||
633 | } |
||
634 | } |
||
635 | |||
636 | // This is only used at runtime. For sculpties this holds the texture data, and for meshes |
||
637 | // the mesh data. |
||
638 | public byte[] SculptData |
||
639 | { |
||
640 | get |
||
641 | { |
||
642 | return _sculptData; |
||
643 | } |
||
644 | set |
||
645 | { |
||
646 | // m_log.DebugFormat("[PRIMITIVE BASE SHAPE]: Setting SculptData to data with length {0}", value.Length); |
||
647 | _sculptData = value; |
||
648 | } |
||
649 | } |
||
650 | |||
651 | public int FlexiSoftness |
||
652 | { |
||
653 | get |
||
654 | { |
||
655 | return _flexiSoftness; |
||
656 | } |
||
657 | set |
||
658 | { |
||
659 | _flexiSoftness = value; |
||
660 | } |
||
661 | } |
||
662 | |||
663 | public float FlexiTension { |
||
664 | get { |
||
665 | return _flexiTension; |
||
666 | } |
||
667 | set { |
||
668 | _flexiTension = value; |
||
669 | } |
||
670 | } |
||
671 | |||
672 | public float FlexiDrag { |
||
673 | get { |
||
674 | return _flexiDrag; |
||
675 | } |
||
676 | set { |
||
677 | _flexiDrag = value; |
||
678 | } |
||
679 | } |
||
680 | |||
681 | public float FlexiGravity { |
||
682 | get { |
||
683 | return _flexiGravity; |
||
684 | } |
||
685 | set { |
||
686 | _flexiGravity = value; |
||
687 | } |
||
688 | } |
||
689 | |||
690 | public float FlexiWind { |
||
691 | get { |
||
692 | return _flexiWind; |
||
693 | } |
||
694 | set { |
||
695 | _flexiWind = value; |
||
696 | } |
||
697 | } |
||
698 | |||
699 | public float FlexiForceX { |
||
700 | get { |
||
701 | return _flexiForceX; |
||
702 | } |
||
703 | set { |
||
704 | _flexiForceX = value; |
||
705 | } |
||
706 | } |
||
707 | |||
708 | public float FlexiForceY { |
||
709 | get { |
||
710 | return _flexiForceY; |
||
711 | } |
||
712 | set { |
||
713 | _flexiForceY = value; |
||
714 | } |
||
715 | } |
||
716 | |||
717 | public float FlexiForceZ { |
||
718 | get { |
||
719 | return _flexiForceZ; |
||
720 | } |
||
721 | set { |
||
722 | _flexiForceZ = value; |
||
723 | } |
||
724 | } |
||
725 | |||
726 | public float LightColorR { |
||
727 | get { |
||
728 | return _lightColorR; |
||
729 | } |
||
730 | set { |
||
731 | _lightColorR = value; |
||
732 | } |
||
733 | } |
||
734 | |||
735 | public float LightColorG { |
||
736 | get { |
||
737 | return _lightColorG; |
||
738 | } |
||
739 | set { |
||
740 | _lightColorG = value; |
||
741 | } |
||
742 | } |
||
743 | |||
744 | public float LightColorB { |
||
745 | get { |
||
746 | return _lightColorB; |
||
747 | } |
||
748 | set { |
||
749 | _lightColorB = value; |
||
750 | } |
||
751 | } |
||
752 | |||
753 | public float LightColorA { |
||
754 | get { |
||
755 | return _lightColorA; |
||
756 | } |
||
757 | set { |
||
758 | _lightColorA = value; |
||
759 | } |
||
760 | } |
||
761 | |||
762 | public float LightRadius { |
||
763 | get { |
||
764 | return _lightRadius; |
||
765 | } |
||
766 | set { |
||
767 | _lightRadius = value; |
||
768 | } |
||
769 | } |
||
770 | |||
771 | public float LightCutoff { |
||
772 | get { |
||
773 | return _lightCutoff; |
||
774 | } |
||
775 | set { |
||
776 | _lightCutoff = value; |
||
777 | } |
||
778 | } |
||
779 | |||
780 | public float LightFalloff { |
||
781 | get { |
||
782 | return _lightFalloff; |
||
783 | } |
||
784 | set { |
||
785 | _lightFalloff = value; |
||
786 | } |
||
787 | } |
||
788 | |||
789 | public float LightIntensity { |
||
790 | get { |
||
791 | return _lightIntensity; |
||
792 | } |
||
793 | set { |
||
794 | _lightIntensity = value; |
||
795 | } |
||
796 | } |
||
797 | |||
798 | public bool FlexiEntry { |
||
799 | get { |
||
800 | return _flexiEntry; |
||
801 | } |
||
802 | set { |
||
803 | _flexiEntry = value; |
||
804 | } |
||
805 | } |
||
806 | |||
807 | public bool LightEntry { |
||
808 | get { |
||
809 | return _lightEntry; |
||
810 | } |
||
811 | set { |
||
812 | _lightEntry = value; |
||
813 | } |
||
814 | } |
||
815 | |||
816 | public bool SculptEntry { |
||
817 | get { |
||
818 | return _sculptEntry; |
||
819 | } |
||
820 | set { |
||
821 | _sculptEntry = value; |
||
822 | } |
||
823 | } |
||
824 | |||
825 | public bool ProjectionEntry { |
||
826 | get { |
||
827 | return _projectionEntry; |
||
828 | } |
||
829 | set { |
||
830 | _projectionEntry = value; |
||
831 | } |
||
832 | } |
||
833 | |||
834 | public UUID ProjectionTextureUUID { |
||
835 | get { |
||
836 | return _projectionTextureID; |
||
837 | } |
||
838 | set { |
||
839 | _projectionTextureID = value; |
||
840 | } |
||
841 | } |
||
842 | |||
843 | public float ProjectionFOV { |
||
844 | get { |
||
845 | return _projectionFOV; |
||
846 | } |
||
847 | set { |
||
848 | _projectionFOV = value; |
||
849 | } |
||
850 | } |
||
851 | |||
852 | public float ProjectionFocus { |
||
853 | get { |
||
854 | return _projectionFocus; |
||
855 | } |
||
856 | set { |
||
857 | _projectionFocus = value; |
||
858 | } |
||
859 | } |
||
860 | |||
861 | public float ProjectionAmbiance { |
||
862 | get { |
||
863 | return _projectionAmb; |
||
864 | } |
||
865 | set { |
||
866 | _projectionAmb = value; |
||
867 | } |
||
868 | } |
||
869 | |||
870 | public ulong GetMeshKey(Vector3 size, float lod) |
||
871 | { |
||
872 | ulong hash = 5381; |
||
873 | |||
874 | hash = djb2(hash, this.PathCurve); |
||
875 | hash = djb2(hash, (byte)((byte)this.HollowShape | (byte)this.ProfileShape)); |
||
876 | hash = djb2(hash, this.PathBegin); |
||
877 | hash = djb2(hash, this.PathEnd); |
||
878 | hash = djb2(hash, this.PathScaleX); |
||
879 | hash = djb2(hash, this.PathScaleY); |
||
880 | hash = djb2(hash, this.PathShearX); |
||
881 | hash = djb2(hash, this.PathShearY); |
||
882 | hash = djb2(hash, (byte)this.PathTwist); |
||
883 | hash = djb2(hash, (byte)this.PathTwistBegin); |
||
884 | hash = djb2(hash, (byte)this.PathRadiusOffset); |
||
885 | hash = djb2(hash, (byte)this.PathTaperX); |
||
886 | hash = djb2(hash, (byte)this.PathTaperY); |
||
887 | hash = djb2(hash, this.PathRevolutions); |
||
888 | hash = djb2(hash, (byte)this.PathSkew); |
||
889 | hash = djb2(hash, this.ProfileBegin); |
||
890 | hash = djb2(hash, this.ProfileEnd); |
||
891 | hash = djb2(hash, this.ProfileHollow); |
||
892 | |||
893 | // TODO: Separate scale out from the primitive shape data (after |
||
894 | // scaling is supported at the physics engine level) |
||
895 | byte[] scaleBytes = size.GetBytes(); |
||
896 | for (int i = 0; i < scaleBytes.Length; i++) |
||
897 | hash = djb2(hash, scaleBytes[i]); |
||
898 | |||
899 | // Include LOD in hash, accounting for endianness |
||
900 | byte[] lodBytes = new byte[4]; |
||
901 | Buffer.BlockCopy(BitConverter.GetBytes(lod), 0, lodBytes, 0, 4); |
||
902 | if (!BitConverter.IsLittleEndian) |
||
903 | { |
||
904 | Array.Reverse(lodBytes, 0, 4); |
||
905 | } |
||
906 | for (int i = 0; i < lodBytes.Length; i++) |
||
907 | hash = djb2(hash, lodBytes[i]); |
||
908 | |||
909 | // include sculpt UUID |
||
910 | if (this.SculptEntry) |
||
911 | { |
||
912 | scaleBytes = this.SculptTexture.GetBytes(); |
||
913 | for (int i = 0; i < scaleBytes.Length; i++) |
||
914 | hash = djb2(hash, scaleBytes[i]); |
||
915 | } |
||
916 | |||
917 | return hash; |
||
918 | } |
||
919 | |||
920 | private ulong djb2(ulong hash, byte c) |
||
921 | { |
||
922 | return ((hash << 5) + hash) + (ulong)c; |
||
923 | } |
||
924 | |||
925 | private ulong djb2(ulong hash, ushort c) |
||
926 | { |
||
927 | hash = ((hash << 5) + hash) + (ulong)((byte)c); |
||
928 | return ((hash << 5) + hash) + (ulong)(c >> 8); |
||
929 | } |
||
930 | |||
931 | public byte[] ExtraParamsToBytes() |
||
932 | { |
||
933 | // m_log.DebugFormat("[EXTRAPARAMS]: Called ExtraParamsToBytes()"); |
||
934 | |||
935 | ushort FlexiEP = 0x10; |
||
936 | ushort LightEP = 0x20; |
||
937 | ushort SculptEP = 0x30; |
||
938 | ushort ProjectionEP = 0x40; |
||
939 | |||
940 | int i = 0; |
||
941 | uint TotalBytesLength = 1; // ExtraParamsNum |
||
942 | |||
943 | uint ExtraParamsNum = 0; |
||
944 | if (_flexiEntry) |
||
945 | { |
||
946 | ExtraParamsNum++; |
||
947 | TotalBytesLength += 16;// data |
||
948 | TotalBytesLength += 2 + 4; // type |
||
949 | } |
||
950 | |||
951 | if (_lightEntry) |
||
952 | { |
||
953 | ExtraParamsNum++; |
||
954 | TotalBytesLength += 16;// data |
||
955 | TotalBytesLength += 2 + 4; // type |
||
956 | } |
||
957 | |||
958 | if (_sculptEntry) |
||
959 | { |
||
960 | ExtraParamsNum++; |
||
961 | TotalBytesLength += 17;// data |
||
962 | TotalBytesLength += 2 + 4; // type |
||
963 | } |
||
964 | |||
965 | if (_projectionEntry) |
||
966 | { |
||
967 | ExtraParamsNum++; |
||
968 | TotalBytesLength += 28;// data |
||
969 | TotalBytesLength += 2 + 4;// type |
||
970 | } |
||
971 | |||
972 | byte[] returnbytes = new byte[TotalBytesLength]; |
||
973 | |||
974 | // uint paramlength = ExtraParamsNum; |
||
975 | |||
976 | // Stick in the number of parameters |
||
977 | returnbytes[i++] = (byte)ExtraParamsNum; |
||
978 | |||
979 | if (_flexiEntry) |
||
980 | { |
||
981 | byte[] FlexiData = GetFlexiBytes(); |
||
982 | |||
983 | returnbytes[i++] = (byte)(FlexiEP % 256); |
||
984 | returnbytes[i++] = (byte)((FlexiEP >> 8) % 256); |
||
985 | |||
986 | returnbytes[i++] = (byte)(FlexiData.Length % 256); |
||
987 | returnbytes[i++] = (byte)((FlexiData.Length >> 8) % 256); |
||
988 | returnbytes[i++] = (byte)((FlexiData.Length >> 16) % 256); |
||
989 | returnbytes[i++] = (byte)((FlexiData.Length >> 24) % 256); |
||
990 | Array.Copy(FlexiData, 0, returnbytes, i, FlexiData.Length); |
||
991 | i += FlexiData.Length; |
||
992 | } |
||
993 | |||
994 | if (_lightEntry) |
||
995 | { |
||
996 | byte[] LightData = GetLightBytes(); |
||
997 | |||
998 | returnbytes[i++] = (byte)(LightEP % 256); |
||
999 | returnbytes[i++] = (byte)((LightEP >> 8) % 256); |
||
1000 | |||
1001 | returnbytes[i++] = (byte)(LightData.Length % 256); |
||
1002 | returnbytes[i++] = (byte)((LightData.Length >> 8) % 256); |
||
1003 | returnbytes[i++] = (byte)((LightData.Length >> 16) % 256); |
||
1004 | returnbytes[i++] = (byte)((LightData.Length >> 24) % 256); |
||
1005 | Array.Copy(LightData, 0, returnbytes, i, LightData.Length); |
||
1006 | i += LightData.Length; |
||
1007 | } |
||
1008 | |||
1009 | if (_sculptEntry) |
||
1010 | { |
||
1011 | byte[] SculptData = GetSculptBytes(); |
||
1012 | |||
1013 | returnbytes[i++] = (byte)(SculptEP % 256); |
||
1014 | returnbytes[i++] = (byte)((SculptEP >> 8) % 256); |
||
1015 | |||
1016 | returnbytes[i++] = (byte)(SculptData.Length % 256); |
||
1017 | returnbytes[i++] = (byte)((SculptData.Length >> 8) % 256); |
||
1018 | returnbytes[i++] = (byte)((SculptData.Length >> 16) % 256); |
||
1019 | returnbytes[i++] = (byte)((SculptData.Length >> 24) % 256); |
||
1020 | Array.Copy(SculptData, 0, returnbytes, i, SculptData.Length); |
||
1021 | i += SculptData.Length; |
||
1022 | } |
||
1023 | |||
1024 | if (_projectionEntry) |
||
1025 | { |
||
1026 | byte[] ProjectionData = GetProjectionBytes(); |
||
1027 | |||
1028 | returnbytes[i++] = (byte)(ProjectionEP % 256); |
||
1029 | returnbytes[i++] = (byte)((ProjectionEP >> 8) % 256); |
||
1030 | returnbytes[i++] = (byte)((ProjectionData.Length) % 256); |
||
1031 | returnbytes[i++] = (byte)((ProjectionData.Length >> 16) % 256); |
||
1032 | returnbytes[i++] = (byte)((ProjectionData.Length >> 20) % 256); |
||
1033 | returnbytes[i++] = (byte)((ProjectionData.Length >> 24) % 256); |
||
1034 | Array.Copy(ProjectionData, 0, returnbytes, i, ProjectionData.Length); |
||
1035 | i += ProjectionData.Length; |
||
1036 | } |
||
1037 | |||
1038 | if (!_flexiEntry && !_lightEntry && !_sculptEntry && !_projectionEntry) |
||
1039 | { |
||
1040 | byte[] returnbyte = new byte[1]; |
||
1041 | returnbyte[0] = 0; |
||
1042 | return returnbyte; |
||
1043 | } |
||
1044 | |||
1045 | return returnbytes; |
||
1046 | } |
||
1047 | |||
1048 | public void ReadInUpdateExtraParam(ushort type, bool inUse, byte[] data) |
||
1049 | { |
||
1050 | const ushort FlexiEP = 0x10; |
||
1051 | const ushort LightEP = 0x20; |
||
1052 | const ushort SculptEP = 0x30; |
||
1053 | const ushort ProjectionEP = 0x40; |
||
1054 | |||
1055 | switch (type) |
||
1056 | { |
||
1057 | case FlexiEP: |
||
1058 | if (!inUse) |
||
1059 | { |
||
1060 | _flexiEntry = false; |
||
1061 | return; |
||
1062 | } |
||
1063 | ReadFlexiData(data, 0); |
||
1064 | break; |
||
1065 | |||
1066 | case LightEP: |
||
1067 | if (!inUse) |
||
1068 | { |
||
1069 | _lightEntry = false; |
||
1070 | return; |
||
1071 | } |
||
1072 | ReadLightData(data, 0); |
||
1073 | break; |
||
1074 | |||
1075 | case SculptEP: |
||
1076 | if (!inUse) |
||
1077 | { |
||
1078 | _sculptEntry = false; |
||
1079 | return; |
||
1080 | } |
||
1081 | ReadSculptData(data, 0); |
||
1082 | break; |
||
1083 | case ProjectionEP: |
||
1084 | if (!inUse) |
||
1085 | { |
||
1086 | _projectionEntry = false; |
||
1087 | return; |
||
1088 | } |
||
1089 | ReadProjectionData(data, 0); |
||
1090 | break; |
||
1091 | } |
||
1092 | } |
||
1093 | |||
1094 | public void ReadInExtraParamsBytes(byte[] data) |
||
1095 | { |
||
1096 | if (data == null || data.Length == 1) |
||
1097 | return; |
||
1098 | |||
1099 | const ushort FlexiEP = 0x10; |
||
1100 | const ushort LightEP = 0x20; |
||
1101 | const ushort SculptEP = 0x30; |
||
1102 | const ushort ProjectionEP = 0x40; |
||
1103 | |||
1104 | bool lGotFlexi = false; |
||
1105 | bool lGotLight = false; |
||
1106 | bool lGotSculpt = false; |
||
1107 | bool lGotFilter = false; |
||
1108 | |||
1109 | int i = 0; |
||
1110 | byte extraParamCount = 0; |
||
1111 | if (data.Length > 0) |
||
1112 | { |
||
1113 | extraParamCount = data[i++]; |
||
1114 | } |
||
1115 | |||
1116 | for (int k = 0; k < extraParamCount; k++) |
||
1117 | { |
||
1118 | ushort epType = Utils.BytesToUInt16(data, i); |
||
1119 | |||
1120 | i += 2; |
||
1121 | // uint paramLength = Helpers.BytesToUIntBig(data, i); |
||
1122 | |||
1123 | i += 4; |
||
1124 | switch (epType) |
||
1125 | { |
||
1126 | case FlexiEP: |
||
1127 | ReadFlexiData(data, i); |
||
1128 | i += 16; |
||
1129 | lGotFlexi = true; |
||
1130 | break; |
||
1131 | |||
1132 | case LightEP: |
||
1133 | ReadLightData(data, i); |
||
1134 | i += 16; |
||
1135 | lGotLight = true; |
||
1136 | break; |
||
1137 | |||
1138 | case SculptEP: |
||
1139 | ReadSculptData(data, i); |
||
1140 | i += 17; |
||
1141 | lGotSculpt = true; |
||
1142 | break; |
||
1143 | case ProjectionEP: |
||
1144 | ReadProjectionData(data, i); |
||
1145 | i += 28; |
||
1146 | lGotFilter = true; |
||
1147 | break; |
||
1148 | } |
||
1149 | } |
||
1150 | |||
1151 | if (!lGotFlexi) |
||
1152 | _flexiEntry = false; |
||
1153 | if (!lGotLight) |
||
1154 | _lightEntry = false; |
||
1155 | if (!lGotSculpt) |
||
1156 | _sculptEntry = false; |
||
1157 | if (!lGotFilter) |
||
1158 | _projectionEntry = false; |
||
1159 | } |
||
1160 | |||
1161 | public void ReadSculptData(byte[] data, int pos) |
||
1162 | { |
||
1163 | UUID SculptUUID; |
||
1164 | byte SculptTypel; |
||
1165 | |||
1166 | if (data.Length-pos >= 17) |
||
1167 | { |
||
1168 | _sculptEntry = true; |
||
1169 | byte[] SculptTextureUUID = new byte[16]; |
||
1170 | SculptTypel = data[16 + pos]; |
||
1171 | Array.Copy(data, pos, SculptTextureUUID,0, 16); |
||
1172 | SculptUUID = new UUID(SculptTextureUUID, 0); |
||
1173 | } |
||
1174 | else |
||
1175 | { |
||
1176 | _sculptEntry = false; |
||
1177 | SculptUUID = UUID.Zero; |
||
1178 | SculptTypel = 0x00; |
||
1179 | } |
||
1180 | |||
1181 | if (_sculptEntry) |
||
1182 | { |
||
1183 | if (_sculptType != (byte)1 && _sculptType != (byte)2 && _sculptType != (byte)3 && _sculptType != (byte)4) |
||
1184 | _sculptType = 4; |
||
1185 | } |
||
1186 | |||
1187 | _sculptTexture = SculptUUID; |
||
1188 | _sculptType = SculptTypel; |
||
1189 | //m_log.Info("[SCULPT]:" + SculptUUID.ToString()); |
||
1190 | } |
||
1191 | |||
1192 | public byte[] GetSculptBytes() |
||
1193 | { |
||
1194 | byte[] data = new byte[17]; |
||
1195 | |||
1196 | _sculptTexture.GetBytes().CopyTo(data, 0); |
||
1197 | data[16] = (byte)_sculptType; |
||
1198 | |||
1199 | return data; |
||
1200 | } |
||
1201 | |||
1202 | public void ReadFlexiData(byte[] data, int pos) |
||
1203 | { |
||
1204 | if (data.Length-pos >= 16) |
||
1205 | { |
||
1206 | _flexiEntry = true; |
||
1207 | _flexiSoftness = ((data[pos] & 0x80) >> 6) | ((data[pos + 1] & 0x80) >> 7); |
||
1208 | |||
1209 | _flexiTension = (float)(data[pos++] & 0x7F) / 10.0f; |
||
1210 | _flexiDrag = (float)(data[pos++] & 0x7F) / 10.0f; |
||
1211 | _flexiGravity = (float)(data[pos++] / 10.0f) - 10.0f; |
||
1212 | _flexiWind = (float)data[pos++] / 10.0f; |
||
1213 | Vector3 lForce = new Vector3(data, pos); |
||
1214 | _flexiForceX = lForce.X; |
||
1215 | _flexiForceY = lForce.Y; |
||
1216 | _flexiForceZ = lForce.Z; |
||
1217 | } |
||
1218 | else |
||
1219 | { |
||
1220 | _flexiEntry = false; |
||
1221 | _flexiSoftness = 0; |
||
1222 | |||
1223 | _flexiTension = 0.0f; |
||
1224 | _flexiDrag = 0.0f; |
||
1225 | _flexiGravity = 0.0f; |
||
1226 | _flexiWind = 0.0f; |
||
1227 | _flexiForceX = 0f; |
||
1228 | _flexiForceY = 0f; |
||
1229 | _flexiForceZ = 0f; |
||
1230 | } |
||
1231 | } |
||
1232 | |||
1233 | public byte[] GetFlexiBytes() |
||
1234 | { |
||
1235 | byte[] data = new byte[16]; |
||
1236 | int i = 0; |
||
1237 | |||
1238 | // Softness is packed in the upper bits of tension and drag |
||
1239 | data[i] = (byte)((_flexiSoftness & 2) << 6); |
||
1240 | data[i + 1] = (byte)((_flexiSoftness & 1) << 7); |
||
1241 | |||
1242 | data[i++] |= (byte)((byte)(_flexiTension * 10.01f) & 0x7F); |
||
1243 | data[i++] |= (byte)((byte)(_flexiDrag * 10.01f) & 0x7F); |
||
1244 | data[i++] = (byte)((_flexiGravity + 10.0f) * 10.01f); |
||
1245 | data[i++] = (byte)(_flexiWind * 10.01f); |
||
1246 | Vector3 lForce = new Vector3(_flexiForceX, _flexiForceY, _flexiForceZ); |
||
1247 | lForce.GetBytes().CopyTo(data, i); |
||
1248 | |||
1249 | return data; |
||
1250 | } |
||
1251 | |||
1252 | public void ReadLightData(byte[] data, int pos) |
||
1253 | { |
||
1254 | if (data.Length - pos >= 16) |
||
1255 | { |
||
1256 | _lightEntry = true; |
||
1257 | Color4 lColor = new Color4(data, pos, false); |
||
1258 | _lightIntensity = lColor.A; |
||
1259 | _lightColorA = 1f; |
||
1260 | _lightColorR = lColor.R; |
||
1261 | _lightColorG = lColor.G; |
||
1262 | _lightColorB = lColor.B; |
||
1263 | |||
1264 | _lightRadius = Utils.BytesToFloat(data, pos + 4); |
||
1265 | _lightCutoff = Utils.BytesToFloat(data, pos + 8); |
||
1266 | _lightFalloff = Utils.BytesToFloat(data, pos + 12); |
||
1267 | } |
||
1268 | else |
||
1269 | { |
||
1270 | _lightEntry = false; |
||
1271 | _lightColorA = 1f; |
||
1272 | _lightColorR = 0f; |
||
1273 | _lightColorG = 0f; |
||
1274 | _lightColorB = 0f; |
||
1275 | _lightRadius = 0f; |
||
1276 | _lightCutoff = 0f; |
||
1277 | _lightFalloff = 0f; |
||
1278 | _lightIntensity = 0f; |
||
1279 | } |
||
1280 | } |
||
1281 | |||
1282 | public byte[] GetLightBytes() |
||
1283 | { |
||
1284 | byte[] data = new byte[16]; |
||
1285 | |||
1286 | // Alpha channel in color is intensity |
||
1287 | Color4 tmpColor = new Color4(_lightColorR,_lightColorG,_lightColorB,_lightIntensity); |
||
1288 | |||
1289 | tmpColor.GetBytes().CopyTo(data, 0); |
||
1290 | Utils.FloatToBytes(_lightRadius).CopyTo(data, 4); |
||
1291 | Utils.FloatToBytes(_lightCutoff).CopyTo(data, 8); |
||
1292 | Utils.FloatToBytes(_lightFalloff).CopyTo(data, 12); |
||
1293 | |||
1294 | return data; |
||
1295 | } |
||
1296 | |||
1297 | public void ReadProjectionData(byte[] data, int pos) |
||
1298 | { |
||
1299 | byte[] ProjectionTextureUUID = new byte[16]; |
||
1300 | |||
1301 | if (data.Length - pos >= 28) |
||
1302 | { |
||
1303 | _projectionEntry = true; |
||
1304 | Array.Copy(data, pos, ProjectionTextureUUID,0, 16); |
||
1305 | _projectionTextureID = new UUID(ProjectionTextureUUID, 0); |
||
1306 | |||
1307 | _projectionFOV = Utils.BytesToFloat(data, pos + 16); |
||
1308 | _projectionFocus = Utils.BytesToFloat(data, pos + 20); |
||
1309 | _projectionAmb = Utils.BytesToFloat(data, pos + 24); |
||
1310 | } |
||
1311 | else |
||
1312 | { |
||
1313 | _projectionEntry = false; |
||
1314 | _projectionTextureID = UUID.Zero; |
||
1315 | _projectionFOV = 0f; |
||
1316 | _projectionFocus = 0f; |
||
1317 | _projectionAmb = 0f; |
||
1318 | } |
||
1319 | } |
||
1320 | |||
1321 | public byte[] GetProjectionBytes() |
||
1322 | { |
||
1323 | byte[] data = new byte[28]; |
||
1324 | |||
1325 | _projectionTextureID.GetBytes().CopyTo(data, 0); |
||
1326 | Utils.FloatToBytes(_projectionFOV).CopyTo(data, 16); |
||
1327 | Utils.FloatToBytes(_projectionFocus).CopyTo(data, 20); |
||
1328 | Utils.FloatToBytes(_projectionAmb).CopyTo(data, 24); |
||
1329 | |||
1330 | return data; |
||
1331 | } |
||
1332 | |||
1333 | |||
1334 | /// <summary> |
||
1335 | /// Creates a OpenMetaverse.Primitive and populates it with converted PrimitiveBaseShape values |
||
1336 | /// </summary> |
||
1337 | /// <returns></returns> |
||
1338 | public Primitive ToOmvPrimitive() |
||
1339 | { |
||
1340 | // position and rotation defaults here since they are not available in PrimitiveBaseShape |
||
1341 | return ToOmvPrimitive(new Vector3(0.0f, 0.0f, 0.0f), |
||
1342 | new Quaternion(0.0f, 0.0f, 0.0f, 1.0f)); |
||
1343 | } |
||
1344 | |||
1345 | |||
1346 | /// <summary> |
||
1347 | /// Creates a OpenMetaverse.Primitive and populates it with converted PrimitiveBaseShape values |
||
1348 | /// </summary> |
||
1349 | /// <param name="position"></param> |
||
1350 | /// <param name="rotation"></param> |
||
1351 | /// <returns></returns> |
||
1352 | public Primitive ToOmvPrimitive(Vector3 position, Quaternion rotation) |
||
1353 | { |
||
1354 | OpenMetaverse.Primitive prim = new OpenMetaverse.Primitive(); |
||
1355 | |||
1356 | prim.Scale = this.Scale; |
||
1357 | prim.Position = position; |
||
1358 | prim.Rotation = rotation; |
||
1359 | |||
1360 | if (this.SculptEntry) |
||
1361 | { |
||
1362 | prim.Sculpt = new Primitive.SculptData(); |
||
1363 | prim.Sculpt.Type = (OpenMetaverse.SculptType)this.SculptType; |
||
1364 | prim.Sculpt.SculptTexture = this.SculptTexture; |
||
1365 | } |
||
1366 | |||
1367 | prim.PrimData.PathShearX = this.PathShearX < 128 ? (float)this.PathShearX * 0.01f : (float)(this.PathShearX - 256) * 0.01f; |
||
1368 | prim.PrimData.PathShearY = this.PathShearY < 128 ? (float)this.PathShearY * 0.01f : (float)(this.PathShearY - 256) * 0.01f; |
||
1369 | prim.PrimData.PathBegin = (float)this.PathBegin * 2.0e-5f; |
||
1370 | prim.PrimData.PathEnd = 1.0f - (float)this.PathEnd * 2.0e-5f; |
||
1371 | |||
1372 | prim.PrimData.PathScaleX = (200 - this.PathScaleX) * 0.01f; |
||
1373 | prim.PrimData.PathScaleY = (200 - this.PathScaleY) * 0.01f; |
||
1374 | |||
1375 | prim.PrimData.PathTaperX = this.PathTaperX * 0.01f; |
||
1376 | prim.PrimData.PathTaperY = this.PathTaperY * 0.01f; |
||
1377 | |||
1378 | prim.PrimData.PathTwistBegin = this.PathTwistBegin * 0.01f; |
||
1379 | prim.PrimData.PathTwist = this.PathTwist * 0.01f; |
||
1380 | |||
1381 | prim.PrimData.ProfileBegin = (float)this.ProfileBegin * 2.0e-5f; |
||
1382 | prim.PrimData.ProfileEnd = 1.0f - (float)this.ProfileEnd * 2.0e-5f; |
||
1383 | prim.PrimData.ProfileHollow = (float)this.ProfileHollow * 2.0e-5f; |
||
1384 | |||
1385 | prim.PrimData.profileCurve = this.ProfileCurve; |
||
1386 | prim.PrimData.ProfileHole = (HoleType)this.HollowShape; |
||
1387 | |||
1388 | prim.PrimData.PathCurve = (PathCurve)this.PathCurve; |
||
1389 | prim.PrimData.PathRadiusOffset = 0.01f * this.PathRadiusOffset; |
||
1390 | prim.PrimData.PathRevolutions = 1.0f + 0.015f * this.PathRevolutions; |
||
1391 | prim.PrimData.PathSkew = 0.01f * this.PathSkew; |
||
1392 | |||
1393 | prim.PrimData.PCode = OpenMetaverse.PCode.Prim; |
||
1394 | prim.PrimData.State = 0; |
||
1395 | |||
1396 | if (this.FlexiEntry) |
||
1397 | { |
||
1398 | prim.Flexible = new Primitive.FlexibleData(); |
||
1399 | prim.Flexible.Drag = this.FlexiDrag; |
||
1400 | prim.Flexible.Force = new Vector3(this.FlexiForceX, this.FlexiForceY, this.FlexiForceZ); |
||
1401 | prim.Flexible.Gravity = this.FlexiGravity; |
||
1402 | prim.Flexible.Softness = this.FlexiSoftness; |
||
1403 | prim.Flexible.Tension = this.FlexiTension; |
||
1404 | prim.Flexible.Wind = this.FlexiWind; |
||
1405 | } |
||
1406 | |||
1407 | if (this.LightEntry) |
||
1408 | { |
||
1409 | prim.Light = new Primitive.LightData(); |
||
1410 | prim.Light.Color = new Color4(this.LightColorR, this.LightColorG, this.LightColorB, this.LightColorA); |
||
1411 | prim.Light.Cutoff = this.LightCutoff; |
||
1412 | prim.Light.Falloff = this.LightFalloff; |
||
1413 | prim.Light.Intensity = this.LightIntensity; |
||
1414 | prim.Light.Radius = this.LightRadius; |
||
1415 | } |
||
1416 | |||
1417 | prim.Textures = this.Textures; |
||
1418 | |||
1419 | prim.Properties = new Primitive.ObjectProperties(); |
||
1420 | prim.Properties.Name = "Primitive"; |
||
1421 | prim.Properties.Description = ""; |
||
1422 | prim.Properties.CreatorID = UUID.Zero; |
||
1423 | prim.Properties.GroupID = UUID.Zero; |
||
1424 | prim.Properties.OwnerID = UUID.Zero; |
||
1425 | prim.Properties.Permissions = new Permissions(); |
||
1426 | prim.Properties.SalePrice = 10; |
||
1427 | prim.Properties.SaleType = new SaleType(); |
||
1428 | |||
1429 | return prim; |
||
1430 | } |
||
1431 | |||
1432 | /// <summary> |
||
1433 | /// Encapsulates a list of media entries. |
||
1434 | /// </summary> |
||
1435 | /// This class is necessary because we want to replace auto-serialization of MediaEntry with something more |
||
1436 | /// OSD like and less vulnerable to change. |
||
1437 | public class MediaList : List<MediaEntry>, IXmlSerializable |
||
1438 | { |
||
1439 | public const string MEDIA_TEXTURE_TYPE = "sl"; |
||
1440 | |||
1441 | public MediaList() : base() {} |
||
1442 | public MediaList(IEnumerable<MediaEntry> collection) : base(collection) {} |
||
1443 | public MediaList(int capacity) : base(capacity) {} |
||
1444 | |||
1445 | public XmlSchema GetSchema() |
||
1446 | { |
||
1447 | return null; |
||
1448 | } |
||
1449 | |||
1450 | public string ToXml() |
||
1451 | { |
||
1452 | lock (this) |
||
1453 | { |
||
1454 | using (StringWriter sw = new StringWriter()) |
||
1455 | { |
||
1456 | using (XmlTextWriter xtw = new XmlTextWriter(sw)) |
||
1457 | { |
||
1458 | xtw.WriteStartElement("OSMedia"); |
||
1459 | xtw.WriteAttributeString("type", MEDIA_TEXTURE_TYPE); |
||
1460 | xtw.WriteAttributeString("version", "0.1"); |
||
1461 | |||
1462 | OSDArray meArray = new OSDArray(); |
||
1463 | foreach (MediaEntry me in this) |
||
1464 | { |
||
1465 | OSD osd = (null == me ? new OSD() : me.GetOSD()); |
||
1466 | meArray.Add(osd); |
||
1467 | } |
||
1468 | |||
1469 | xtw.WriteStartElement("OSData"); |
||
1470 | xtw.WriteRaw(OSDParser.SerializeLLSDXmlString(meArray)); |
||
1471 | xtw.WriteEndElement(); |
||
1472 | |||
1473 | xtw.WriteEndElement(); |
||
1474 | |||
1475 | xtw.Flush(); |
||
1476 | return sw.ToString(); |
||
1477 | } |
||
1478 | } |
||
1479 | } |
||
1480 | } |
||
1481 | |||
1482 | public void WriteXml(XmlWriter writer) |
||
1483 | { |
||
1484 | writer.WriteRaw(ToXml()); |
||
1485 | } |
||
1486 | |||
1487 | public static MediaList FromXml(string rawXml) |
||
1488 | { |
||
1489 | MediaList ml = new MediaList(); |
||
1490 | ml.ReadXml(rawXml); |
||
1491 | return ml; |
||
1492 | } |
||
1493 | |||
1494 | public void ReadXml(string rawXml) |
||
1495 | { |
||
1496 | using (StringReader sr = new StringReader(rawXml)) |
||
1497 | { |
||
1498 | using (XmlTextReader xtr = new XmlTextReader(sr)) |
||
1499 | { |
||
1500 | xtr.MoveToContent(); |
||
1501 | |||
1502 | string type = xtr.GetAttribute("type"); |
||
1503 | //m_log.DebugFormat("[MOAP]: Loaded media texture entry with type {0}", type); |
||
1504 | |||
1505 | if (type != MEDIA_TEXTURE_TYPE) |
||
1506 | return; |
||
1507 | |||
1508 | xtr.ReadStartElement("OSMedia"); |
||
1509 | |||
1510 | OSDArray osdMeArray = (OSDArray)OSDParser.DeserializeLLSDXml(xtr.ReadInnerXml()); |
||
1511 | foreach (OSD osdMe in osdMeArray) |
||
1512 | { |
||
1513 | MediaEntry me = (osdMe is OSDMap ? MediaEntry.FromOSD(osdMe) : new MediaEntry()); |
||
1514 | Add(me); |
||
1515 | } |
||
1516 | |||
1517 | xtr.ReadEndElement(); |
||
1518 | } |
||
1519 | } |
||
1520 | } |
||
1521 | |||
1522 | public void ReadXml(XmlReader reader) |
||
1523 | { |
||
1524 | if (reader.IsEmptyElement) |
||
1525 | return; |
||
1526 | |||
1527 | ReadXml(reader.ReadInnerXml()); |
||
1528 | } |
||
1529 | } |
||
1530 | } |
||
1531 | } |