clockwerk-opensim-stable – Blame information for rev 1

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