clockwerk-opensim-stable – Blame information for rev 1
?pathlinks?
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 | } |