PrimitiveBaseShape.cs 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169
  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. using System;
  28. using System.Drawing;
  29. using System.Drawing.Imaging;
  30. using System.Reflection;
  31. using System.Xml.Serialization;
  32. using log4net;
  33. using OpenMetaverse;
  34. namespace OpenSim.Framework
  35. {
  36. public enum ProfileShape : byte
  37. {
  38. Circle = 0,
  39. Square = 1,
  40. IsometricTriangle = 2,
  41. EquilateralTriangle = 3,
  42. RightTriangle = 4,
  43. HalfCircle = 5
  44. }
  45. public enum HollowShape : byte
  46. {
  47. Same = 0,
  48. Circle = 16,
  49. Square = 32,
  50. Triangle = 48
  51. }
  52. public enum PCodeEnum : byte
  53. {
  54. Primitive = 9,
  55. Avatar = 47,
  56. Grass = 95,
  57. NewTree = 111,
  58. ParticleSystem = 143,
  59. Tree = 255
  60. }
  61. public enum Extrusion : byte
  62. {
  63. Straight = 16,
  64. Curve1 = 32,
  65. Curve2 = 48,
  66. Flexible = 128
  67. }
  68. [Serializable]
  69. public class PrimitiveBaseShape
  70. {
  71. private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
  72. private static readonly byte[] DEFAULT_TEXTURE = new Primitive.TextureEntry(new UUID("89556747-24cb-43ed-920b-47caed15465f")).GetBytes();
  73. private byte[] m_textureEntry;
  74. private ushort _pathBegin;
  75. private byte _pathCurve;
  76. private ushort _pathEnd;
  77. private sbyte _pathRadiusOffset;
  78. private byte _pathRevolutions;
  79. private byte _pathScaleX;
  80. private byte _pathScaleY;
  81. private byte _pathShearX;
  82. private byte _pathShearY;
  83. private sbyte _pathSkew;
  84. private sbyte _pathTaperX;
  85. private sbyte _pathTaperY;
  86. private sbyte _pathTwist;
  87. private sbyte _pathTwistBegin;
  88. private byte _pCode;
  89. private ushort _profileBegin;
  90. private ushort _profileEnd;
  91. private ushort _profileHollow;
  92. private Vector3 _scale;
  93. private byte _state;
  94. private ProfileShape _profileShape;
  95. private HollowShape _hollowShape;
  96. // Sculpted
  97. [XmlIgnore] private UUID _sculptTexture;
  98. [XmlIgnore] private byte _sculptType;
  99. [XmlIgnore] private byte[] _sculptData = Utils.EmptyBytes;
  100. // Flexi
  101. [XmlIgnore] private int _flexiSoftness;
  102. [XmlIgnore] private float _flexiTension;
  103. [XmlIgnore] private float _flexiDrag;
  104. [XmlIgnore] private float _flexiGravity;
  105. [XmlIgnore] private float _flexiWind;
  106. [XmlIgnore] private float _flexiForceX;
  107. [XmlIgnore] private float _flexiForceY;
  108. [XmlIgnore] private float _flexiForceZ;
  109. //Bright n sparkly
  110. [XmlIgnore] private float _lightColorR;
  111. [XmlIgnore] private float _lightColorG;
  112. [XmlIgnore] private float _lightColorB;
  113. [XmlIgnore] private float _lightColorA = 1.0f;
  114. [XmlIgnore] private float _lightRadius;
  115. [XmlIgnore] private float _lightCutoff;
  116. [XmlIgnore] private float _lightFalloff;
  117. [XmlIgnore] private float _lightIntensity = 1.0f;
  118. [XmlIgnore] private bool _flexiEntry;
  119. [XmlIgnore] private bool _lightEntry;
  120. [XmlIgnore] private bool _sculptEntry;
  121. public byte ProfileCurve
  122. {
  123. get { return (byte)((byte)HollowShape | (byte)ProfileShape); }
  124. set
  125. {
  126. // Handle hollow shape component
  127. byte hollowShapeByte = (byte)(value & 0xf0);
  128. if (!Enum.IsDefined(typeof(HollowShape), hollowShapeByte))
  129. {
  130. m_log.WarnFormat(
  131. "[SHAPE]: Attempt to set a ProfileCurve with a hollow shape value of {0}, which isn't a valid enum. Replacing with default shape.",
  132. hollowShapeByte);
  133. this._hollowShape = HollowShape.Same;
  134. }
  135. else
  136. {
  137. this._hollowShape = (HollowShape)hollowShapeByte;
  138. }
  139. // Handle profile shape component
  140. byte profileShapeByte = (byte)(value & 0xf);
  141. if (!Enum.IsDefined(typeof(ProfileShape), profileShapeByte))
  142. {
  143. m_log.WarnFormat(
  144. "[SHAPE]: Attempt to set a ProfileCurve with a profile shape value of {0}, which isn't a valid enum. Replacing with square.",
  145. profileShapeByte);
  146. this._profileShape = ProfileShape.Square;
  147. }
  148. else
  149. {
  150. this._profileShape = (ProfileShape)profileShapeByte;
  151. }
  152. }
  153. }
  154. public PrimitiveBaseShape()
  155. {
  156. PCode = (byte) PCodeEnum.Primitive;
  157. ExtraParams = new byte[1];
  158. m_textureEntry = DEFAULT_TEXTURE;
  159. }
  160. public PrimitiveBaseShape(bool noShape)
  161. {
  162. if (noShape)
  163. return;
  164. PCode = (byte)PCodeEnum.Primitive;
  165. ExtraParams = new byte[1];
  166. m_textureEntry = DEFAULT_TEXTURE;
  167. }
  168. [XmlIgnore]
  169. public Primitive.TextureEntry Textures
  170. {
  171. get
  172. {
  173. //m_log.DebugFormat("[PRIMITIVE BASE SHAPE]: get m_textureEntry length {0}", m_textureEntry.Length);
  174. return new Primitive.TextureEntry(m_textureEntry, 0, m_textureEntry.Length);
  175. }
  176. set { m_textureEntry = value.GetBytes(); }
  177. }
  178. public byte[] TextureEntry
  179. {
  180. get { return m_textureEntry; }
  181. set
  182. {
  183. if (value == null)
  184. m_textureEntry = new byte[1];
  185. else
  186. m_textureEntry = value;
  187. }
  188. }
  189. public static PrimitiveBaseShape Default
  190. {
  191. get
  192. {
  193. PrimitiveBaseShape boxShape = CreateBox();
  194. boxShape.SetScale(0.5f);
  195. return boxShape;
  196. }
  197. }
  198. public static PrimitiveBaseShape Create()
  199. {
  200. PrimitiveBaseShape shape = new PrimitiveBaseShape();
  201. return shape;
  202. }
  203. public static PrimitiveBaseShape CreateBox()
  204. {
  205. PrimitiveBaseShape shape = Create();
  206. shape._pathCurve = (byte) Extrusion.Straight;
  207. shape._profileShape = ProfileShape.Square;
  208. shape._pathScaleX = 100;
  209. shape._pathScaleY = 100;
  210. return shape;
  211. }
  212. public static PrimitiveBaseShape CreateSphere()
  213. {
  214. PrimitiveBaseShape shape = Create();
  215. shape._pathCurve = (byte) Extrusion.Curve1;
  216. shape._profileShape = ProfileShape.HalfCircle;
  217. shape._pathScaleX = 100;
  218. shape._pathScaleY = 100;
  219. return shape;
  220. }
  221. public static PrimitiveBaseShape CreateCylinder()
  222. {
  223. PrimitiveBaseShape shape = Create();
  224. shape._pathCurve = (byte) Extrusion.Curve1;
  225. shape._profileShape = ProfileShape.Square;
  226. shape._pathScaleX = 100;
  227. shape._pathScaleY = 100;
  228. return shape;
  229. }
  230. public void SetScale(float side)
  231. {
  232. _scale = new Vector3(side, side, side);
  233. }
  234. public void SetHeigth(float heigth)
  235. {
  236. _scale.Z = heigth;
  237. }
  238. public void SetRadius(float radius)
  239. {
  240. _scale.X = _scale.Y = radius * 2f;
  241. }
  242. // TODO: void returns need to change of course
  243. public virtual void GetMesh()
  244. {
  245. }
  246. public PrimitiveBaseShape Copy()
  247. {
  248. return (PrimitiveBaseShape) MemberwiseClone();
  249. }
  250. public static PrimitiveBaseShape CreateCylinder(float radius, float heigth)
  251. {
  252. PrimitiveBaseShape shape = CreateCylinder();
  253. shape.SetHeigth(heigth);
  254. shape.SetRadius(radius);
  255. return shape;
  256. }
  257. public void SetPathRange(Vector3 pathRange)
  258. {
  259. _pathBegin = Primitive.PackBeginCut(pathRange.X);
  260. _pathEnd = Primitive.PackEndCut(pathRange.Y);
  261. }
  262. public void SetPathRange(float begin, float end)
  263. {
  264. _pathBegin = Primitive.PackBeginCut(begin);
  265. _pathEnd = Primitive.PackEndCut(end);
  266. }
  267. public void SetSculptData(byte sculptType, UUID SculptTextureUUID)
  268. {
  269. _sculptType = sculptType;
  270. _sculptTexture = SculptTextureUUID;
  271. }
  272. public void SetProfileRange(Vector3 profileRange)
  273. {
  274. _profileBegin = Primitive.PackBeginCut(profileRange.X);
  275. _profileEnd = Primitive.PackEndCut(profileRange.Y);
  276. }
  277. public void SetProfileRange(float begin, float end)
  278. {
  279. _profileBegin = Primitive.PackBeginCut(begin);
  280. _profileEnd = Primitive.PackEndCut(end);
  281. }
  282. public byte[] ExtraParams
  283. {
  284. get
  285. {
  286. return ExtraParamsToBytes();
  287. }
  288. set
  289. {
  290. ReadInExtraParamsBytes(value);
  291. }
  292. }
  293. public ushort PathBegin {
  294. get {
  295. return _pathBegin;
  296. }
  297. set {
  298. _pathBegin = value;
  299. }
  300. }
  301. public byte PathCurve {
  302. get {
  303. return _pathCurve;
  304. }
  305. set {
  306. _pathCurve = value;
  307. }
  308. }
  309. public ushort PathEnd {
  310. get {
  311. return _pathEnd;
  312. }
  313. set {
  314. _pathEnd = value;
  315. }
  316. }
  317. public sbyte PathRadiusOffset {
  318. get {
  319. return _pathRadiusOffset;
  320. }
  321. set {
  322. _pathRadiusOffset = value;
  323. }
  324. }
  325. public byte PathRevolutions {
  326. get {
  327. return _pathRevolutions;
  328. }
  329. set {
  330. _pathRevolutions = value;
  331. }
  332. }
  333. public byte PathScaleX {
  334. get {
  335. return _pathScaleX;
  336. }
  337. set {
  338. _pathScaleX = value;
  339. }
  340. }
  341. public byte PathScaleY {
  342. get {
  343. return _pathScaleY;
  344. }
  345. set {
  346. _pathScaleY = value;
  347. }
  348. }
  349. public byte PathShearX {
  350. get {
  351. return _pathShearX;
  352. }
  353. set {
  354. _pathShearX = value;
  355. }
  356. }
  357. public byte PathShearY {
  358. get {
  359. return _pathShearY;
  360. }
  361. set {
  362. _pathShearY = value;
  363. }
  364. }
  365. public sbyte PathSkew {
  366. get {
  367. return _pathSkew;
  368. }
  369. set {
  370. _pathSkew = value;
  371. }
  372. }
  373. public sbyte PathTaperX {
  374. get {
  375. return _pathTaperX;
  376. }
  377. set {
  378. _pathTaperX = value;
  379. }
  380. }
  381. public sbyte PathTaperY {
  382. get {
  383. return _pathTaperY;
  384. }
  385. set {
  386. _pathTaperY = value;
  387. }
  388. }
  389. public sbyte PathTwist {
  390. get {
  391. return _pathTwist;
  392. }
  393. set {
  394. _pathTwist = value;
  395. }
  396. }
  397. public sbyte PathTwistBegin {
  398. get {
  399. return _pathTwistBegin;
  400. }
  401. set {
  402. _pathTwistBegin = value;
  403. }
  404. }
  405. public byte PCode {
  406. get {
  407. return _pCode;
  408. }
  409. set {
  410. _pCode = value;
  411. }
  412. }
  413. public ushort ProfileBegin {
  414. get {
  415. return _profileBegin;
  416. }
  417. set {
  418. _profileBegin = value;
  419. }
  420. }
  421. public ushort ProfileEnd {
  422. get {
  423. return _profileEnd;
  424. }
  425. set {
  426. _profileEnd = value;
  427. }
  428. }
  429. public ushort ProfileHollow {
  430. get {
  431. return _profileHollow;
  432. }
  433. set {
  434. _profileHollow = value;
  435. }
  436. }
  437. public Vector3 Scale {
  438. get {
  439. return _scale;
  440. }
  441. set {
  442. _scale = value;
  443. }
  444. }
  445. public byte State {
  446. get {
  447. return _state;
  448. }
  449. set {
  450. _state = value;
  451. }
  452. }
  453. public ProfileShape ProfileShape {
  454. get {
  455. return _profileShape;
  456. }
  457. set {
  458. _profileShape = value;
  459. }
  460. }
  461. public HollowShape HollowShape {
  462. get {
  463. return _hollowShape;
  464. }
  465. set {
  466. _hollowShape = value;
  467. }
  468. }
  469. public UUID SculptTexture {
  470. get {
  471. return _sculptTexture;
  472. }
  473. set {
  474. _sculptTexture = value;
  475. }
  476. }
  477. public byte SculptType {
  478. get {
  479. return _sculptType;
  480. }
  481. set {
  482. _sculptType = value;
  483. }
  484. }
  485. public byte[] SculptData {
  486. get {
  487. return _sculptData;
  488. }
  489. set {
  490. _sculptData = value;
  491. }
  492. }
  493. public int FlexiSoftness {
  494. get {
  495. return _flexiSoftness;
  496. }
  497. set {
  498. _flexiSoftness = value;
  499. }
  500. }
  501. public float FlexiTension {
  502. get {
  503. return _flexiTension;
  504. }
  505. set {
  506. _flexiTension = value;
  507. }
  508. }
  509. public float FlexiDrag {
  510. get {
  511. return _flexiDrag;
  512. }
  513. set {
  514. _flexiDrag = value;
  515. }
  516. }
  517. public float FlexiGravity {
  518. get {
  519. return _flexiGravity;
  520. }
  521. set {
  522. _flexiGravity = value;
  523. }
  524. }
  525. public float FlexiWind {
  526. get {
  527. return _flexiWind;
  528. }
  529. set {
  530. _flexiWind = value;
  531. }
  532. }
  533. public float FlexiForceX {
  534. get {
  535. return _flexiForceX;
  536. }
  537. set {
  538. _flexiForceX = value;
  539. }
  540. }
  541. public float FlexiForceY {
  542. get {
  543. return _flexiForceY;
  544. }
  545. set {
  546. _flexiForceY = value;
  547. }
  548. }
  549. public float FlexiForceZ {
  550. get {
  551. return _flexiForceZ;
  552. }
  553. set {
  554. _flexiForceZ = value;
  555. }
  556. }
  557. public float LightColorR {
  558. get {
  559. return _lightColorR;
  560. }
  561. set {
  562. _lightColorR = value;
  563. }
  564. }
  565. public float LightColorG {
  566. get {
  567. return _lightColorG;
  568. }
  569. set {
  570. _lightColorG = value;
  571. }
  572. }
  573. public float LightColorB {
  574. get {
  575. return _lightColorB;
  576. }
  577. set {
  578. _lightColorB = value;
  579. }
  580. }
  581. public float LightColorA {
  582. get {
  583. return _lightColorA;
  584. }
  585. set {
  586. _lightColorA = value;
  587. }
  588. }
  589. public float LightRadius {
  590. get {
  591. return _lightRadius;
  592. }
  593. set {
  594. _lightRadius = value;
  595. }
  596. }
  597. public float LightCutoff {
  598. get {
  599. return _lightCutoff;
  600. }
  601. set {
  602. _lightCutoff = value;
  603. }
  604. }
  605. public float LightFalloff {
  606. get {
  607. return _lightFalloff;
  608. }
  609. set {
  610. _lightFalloff = value;
  611. }
  612. }
  613. public float LightIntensity {
  614. get {
  615. return _lightIntensity;
  616. }
  617. set {
  618. _lightIntensity = value;
  619. }
  620. }
  621. public bool FlexiEntry {
  622. get {
  623. return _flexiEntry;
  624. }
  625. set {
  626. _flexiEntry = value;
  627. }
  628. }
  629. public bool LightEntry {
  630. get {
  631. return _lightEntry;
  632. }
  633. set {
  634. _lightEntry = value;
  635. }
  636. }
  637. public bool SculptEntry {
  638. get {
  639. return _sculptEntry;
  640. }
  641. set {
  642. _sculptEntry = value;
  643. }
  644. }
  645. public byte[] ExtraParamsToBytes()
  646. {
  647. ushort FlexiEP = 0x10;
  648. ushort LightEP = 0x20;
  649. ushort SculptEP = 0x30;
  650. int i = 0;
  651. uint TotalBytesLength = 1; // ExtraParamsNum
  652. uint ExtraParamsNum = 0;
  653. if (_flexiEntry)
  654. {
  655. ExtraParamsNum++;
  656. TotalBytesLength += 16;// data
  657. TotalBytesLength += 2 + 4; // type
  658. }
  659. if (_lightEntry)
  660. {
  661. ExtraParamsNum++;
  662. TotalBytesLength += 16;// data
  663. TotalBytesLength += 2 + 4; // type
  664. }
  665. if (_sculptEntry)
  666. {
  667. ExtraParamsNum++;
  668. TotalBytesLength += 17;// data
  669. TotalBytesLength += 2 + 4; // type
  670. }
  671. byte[] returnbytes = new byte[TotalBytesLength];
  672. // uint paramlength = ExtraParamsNum;
  673. // Stick in the number of parameters
  674. returnbytes[i++] = (byte)ExtraParamsNum;
  675. if (_flexiEntry)
  676. {
  677. byte[] FlexiData = GetFlexiBytes();
  678. returnbytes[i++] = (byte)(FlexiEP % 256);
  679. returnbytes[i++] = (byte)((FlexiEP >> 8) % 256);
  680. returnbytes[i++] = (byte)(FlexiData.Length % 256);
  681. returnbytes[i++] = (byte)((FlexiData.Length >> 8) % 256);
  682. returnbytes[i++] = (byte)((FlexiData.Length >> 16) % 256);
  683. returnbytes[i++] = (byte)((FlexiData.Length >> 24) % 256);
  684. Array.Copy(FlexiData, 0, returnbytes, i, FlexiData.Length);
  685. i += FlexiData.Length;
  686. }
  687. if (_lightEntry)
  688. {
  689. byte[] LightData = GetLightBytes();
  690. returnbytes[i++] = (byte)(LightEP % 256);
  691. returnbytes[i++] = (byte)((LightEP >> 8) % 256);
  692. returnbytes[i++] = (byte)(LightData.Length % 256);
  693. returnbytes[i++] = (byte)((LightData.Length >> 8) % 256);
  694. returnbytes[i++] = (byte)((LightData.Length >> 16) % 256);
  695. returnbytes[i++] = (byte)((LightData.Length >> 24) % 256);
  696. Array.Copy(LightData, 0, returnbytes, i, LightData.Length);
  697. i += LightData.Length;
  698. }
  699. if (_sculptEntry)
  700. {
  701. byte[] SculptData = GetSculptBytes();
  702. returnbytes[i++] = (byte)(SculptEP % 256);
  703. returnbytes[i++] = (byte)((SculptEP >> 8) % 256);
  704. returnbytes[i++] = (byte)(SculptData.Length % 256);
  705. returnbytes[i++] = (byte)((SculptData.Length >> 8) % 256);
  706. returnbytes[i++] = (byte)((SculptData.Length >> 16) % 256);
  707. returnbytes[i++] = (byte)((SculptData.Length >> 24) % 256);
  708. Array.Copy(SculptData, 0, returnbytes, i, SculptData.Length);
  709. i += SculptData.Length;
  710. }
  711. if (!_flexiEntry && !_lightEntry && !_sculptEntry)
  712. {
  713. byte[] returnbyte = new byte[1];
  714. returnbyte[0] = 0;
  715. return returnbyte;
  716. }
  717. return returnbytes;
  718. //m_log.Info("[EXTRAPARAMS]: Length = " + m_shape.ExtraParams.Length.ToString());
  719. }
  720. public void ReadInUpdateExtraParam(ushort type, bool inUse, byte[] data)
  721. {
  722. const ushort FlexiEP = 0x10;
  723. const ushort LightEP = 0x20;
  724. const ushort SculptEP = 0x30;
  725. switch (type)
  726. {
  727. case FlexiEP:
  728. if (!inUse)
  729. {
  730. _flexiEntry = false;
  731. return;
  732. }
  733. ReadFlexiData(data, 0);
  734. break;
  735. case LightEP:
  736. if (!inUse)
  737. {
  738. _lightEntry = false;
  739. return;
  740. }
  741. ReadLightData(data, 0);
  742. break;
  743. case SculptEP:
  744. if (!inUse)
  745. {
  746. _sculptEntry = false;
  747. return;
  748. }
  749. ReadSculptData(data, 0);
  750. break;
  751. }
  752. }
  753. public void ReadInExtraParamsBytes(byte[] data)
  754. {
  755. if (data == null || data.Length == 1)
  756. return;
  757. const ushort FlexiEP = 0x10;
  758. const ushort LightEP = 0x20;
  759. const ushort SculptEP = 0x30;
  760. bool lGotFlexi = false;
  761. bool lGotLight = false;
  762. bool lGotSculpt = false;
  763. int i = 0;
  764. byte extraParamCount = 0;
  765. if (data.Length > 0)
  766. {
  767. extraParamCount = data[i++];
  768. }
  769. for (int k = 0; k < extraParamCount; k++)
  770. {
  771. ushort epType = Utils.BytesToUInt16(data, i);
  772. i += 2;
  773. // uint paramLength = Helpers.BytesToUIntBig(data, i);
  774. i += 4;
  775. switch (epType)
  776. {
  777. case FlexiEP:
  778. ReadFlexiData(data, i);
  779. i += 16;
  780. lGotFlexi = true;
  781. break;
  782. case LightEP:
  783. ReadLightData(data, i);
  784. i += 16;
  785. lGotLight = true;
  786. break;
  787. case SculptEP:
  788. ReadSculptData(data, i);
  789. i += 17;
  790. lGotSculpt = true;
  791. break;
  792. }
  793. }
  794. if (!lGotFlexi)
  795. _flexiEntry = false;
  796. if (!lGotLight)
  797. _lightEntry = false;
  798. if (!lGotSculpt)
  799. _sculptEntry = false;
  800. }
  801. public void ReadSculptData(byte[] data, int pos)
  802. {
  803. byte[] SculptTextureUUID = new byte[16];
  804. UUID SculptUUID = UUID.Zero;
  805. byte SculptTypel = data[16+pos];
  806. if (data.Length+pos >= 17)
  807. {
  808. _sculptEntry = true;
  809. SculptTextureUUID = new byte[16];
  810. SculptTypel = data[16 + pos];
  811. Array.Copy(data, pos, SculptTextureUUID,0, 16);
  812. SculptUUID = new UUID(SculptTextureUUID, 0);
  813. }
  814. else
  815. {
  816. _sculptEntry = false;
  817. SculptUUID = UUID.Zero;
  818. SculptTypel = 0x00;
  819. }
  820. if (_sculptEntry)
  821. {
  822. if (_sculptType != (byte)1 && _sculptType != (byte)2 && _sculptType != (byte)3 && _sculptType != (byte)4)
  823. _sculptType = 4;
  824. }
  825. _sculptTexture = SculptUUID;
  826. _sculptType = SculptTypel;
  827. //m_log.Info("[SCULPT]:" + SculptUUID.ToString());
  828. }
  829. public byte[] GetSculptBytes()
  830. {
  831. byte[] data = new byte[17];
  832. _sculptTexture.GetBytes().CopyTo(data, 0);
  833. data[16] = (byte)_sculptType;
  834. return data;
  835. }
  836. public void ReadFlexiData(byte[] data, int pos)
  837. {
  838. if (data.Length-pos >= 16)
  839. {
  840. _flexiEntry = true;
  841. _flexiSoftness = ((data[pos] & 0x80) >> 6) | ((data[pos + 1] & 0x80) >> 7);
  842. _flexiTension = (float)(data[pos++] & 0x7F) / 10.0f;
  843. _flexiDrag = (float)(data[pos++] & 0x7F) / 10.0f;
  844. _flexiGravity = (float)(data[pos++] / 10.0f) - 10.0f;
  845. _flexiWind = (float)data[pos++] / 10.0f;
  846. Vector3 lForce = new Vector3(data, pos);
  847. _flexiForceX = lForce.X;
  848. _flexiForceY = lForce.Y;
  849. _flexiForceZ = lForce.Z;
  850. }
  851. else
  852. {
  853. _flexiEntry = false;
  854. _flexiSoftness = 0;
  855. _flexiTension = 0.0f;
  856. _flexiDrag = 0.0f;
  857. _flexiGravity = 0.0f;
  858. _flexiWind = 0.0f;
  859. _flexiForceX = 0f;
  860. _flexiForceY = 0f;
  861. _flexiForceZ = 0f;
  862. }
  863. }
  864. public byte[] GetFlexiBytes()
  865. {
  866. byte[] data = new byte[16];
  867. int i = 0;
  868. // Softness is packed in the upper bits of tension and drag
  869. data[i] = (byte)((_flexiSoftness & 2) << 6);
  870. data[i + 1] = (byte)((_flexiSoftness & 1) << 7);
  871. data[i++] |= (byte)((byte)(_flexiTension * 10.01f) & 0x7F);
  872. data[i++] |= (byte)((byte)(_flexiDrag * 10.01f) & 0x7F);
  873. data[i++] = (byte)((_flexiGravity + 10.0f) * 10.01f);
  874. data[i++] = (byte)(_flexiWind * 10.01f);
  875. Vector3 lForce = new Vector3(_flexiForceX, _flexiForceY, _flexiForceZ);
  876. lForce.GetBytes().CopyTo(data, i);
  877. return data;
  878. }
  879. public void ReadLightData(byte[] data, int pos)
  880. {
  881. if (data.Length - pos >= 16)
  882. {
  883. _lightEntry = true;
  884. Color4 lColor = new Color4(data, pos, false);
  885. _lightIntensity = lColor.A;
  886. _lightColorA = 1f;
  887. _lightColorR = lColor.R;
  888. _lightColorG = lColor.G;
  889. _lightColorB = lColor.B;
  890. _lightRadius = Utils.BytesToFloat(data, pos + 4);
  891. _lightCutoff = Utils.BytesToFloat(data, pos + 8);
  892. _lightFalloff = Utils.BytesToFloat(data, pos + 12);
  893. }
  894. else
  895. {
  896. _lightEntry = false;
  897. _lightColorA = 1f;
  898. _lightColorR = 0f;
  899. _lightColorG = 0f;
  900. _lightColorB = 0f;
  901. _lightRadius = 0f;
  902. _lightCutoff = 0f;
  903. _lightFalloff = 0f;
  904. _lightIntensity = 0f;
  905. }
  906. }
  907. public byte[] GetLightBytes()
  908. {
  909. byte[] data = new byte[16];
  910. // Alpha channel in color is intensity
  911. Color4 tmpColor = new Color4(_lightColorR,_lightColorG,_lightColorB,_lightIntensity);
  912. tmpColor.GetBytes().CopyTo(data, 0);
  913. Utils.FloatToBytes(_lightRadius).CopyTo(data, 4);
  914. Utils.FloatToBytes(_lightCutoff).CopyTo(data, 8);
  915. Utils.FloatToBytes(_lightFalloff).CopyTo(data, 12);
  916. return data;
  917. }
  918. /// <summary>
  919. /// Creates a OpenMetaverse.Primitive and populates it with converted PrimitiveBaseShape values
  920. /// </summary>
  921. /// <returns></returns>
  922. public Primitive ToOmvPrimitive()
  923. {
  924. // position and rotation defaults here since they are not available in PrimitiveBaseShape
  925. return ToOmvPrimitive(new Vector3(0.0f, 0.0f, 0.0f),
  926. new Quaternion(0.0f, 0.0f, 0.0f, 1.0f));
  927. }
  928. /// <summary>
  929. /// Creates a OpenMetaverse.Primitive and populates it with converted PrimitiveBaseShape values
  930. /// </summary>
  931. /// <param name="position"></param>
  932. /// <param name="rotation"></param>
  933. /// <returns></returns>
  934. public Primitive ToOmvPrimitive(Vector3 position, Quaternion rotation)
  935. {
  936. OpenMetaverse.Primitive prim = new OpenMetaverse.Primitive();
  937. prim.Scale = this.Scale;
  938. prim.Position = position;
  939. prim.Rotation = rotation;
  940. if (this.SculptEntry)
  941. {
  942. prim.Sculpt = new Primitive.SculptData();
  943. prim.Sculpt.Type = (OpenMetaverse.SculptType)this.SculptType;
  944. prim.Sculpt.SculptTexture = this.SculptTexture;
  945. }
  946. prim.PrimData.PathShearX = this.PathShearX < 128 ? (float)this.PathShearX * 0.01f : (float)(this.PathShearX - 256) * 0.01f;
  947. prim.PrimData.PathShearY = this.PathShearY < 128 ? (float)this.PathShearY * 0.01f : (float)(this.PathShearY - 256) * 0.01f;
  948. prim.PrimData.PathBegin = (float)this.PathBegin * 2.0e-5f;
  949. prim.PrimData.PathEnd = 1.0f - (float)this.PathEnd * 2.0e-5f;
  950. prim.PrimData.PathScaleX = (200 - this.PathScaleX) * 0.01f;
  951. prim.PrimData.PathScaleY = (200 - this.PathScaleY) * 0.01f;
  952. prim.PrimData.PathTaperX = this.PathTaperX * 0.01f;
  953. prim.PrimData.PathTaperY = this.PathTaperY * 0.01f;
  954. prim.PrimData.PathTwistBegin = this.PathTwistBegin * 0.01f;
  955. prim.PrimData.PathTwist = this.PathTwist * 0.01f;
  956. prim.PrimData.ProfileBegin = (float)this.ProfileBegin * 2.0e-5f;
  957. prim.PrimData.ProfileEnd = 1.0f - (float)this.ProfileEnd * 2.0e-5f;
  958. prim.PrimData.ProfileHollow = (float)this.ProfileHollow * 2.0e-5f;
  959. prim.PrimData.profileCurve = this.ProfileCurve;
  960. prim.PrimData.ProfileHole = (HoleType)this.HollowShape;
  961. prim.PrimData.PathCurve = (PathCurve)this.PathCurve;
  962. prim.PrimData.PathRadiusOffset = 0.01f * this.PathRadiusOffset;
  963. prim.PrimData.PathRevolutions = 1.0f + 0.015f * this.PathRevolutions;
  964. prim.PrimData.PathSkew = 0.01f * this.PathSkew;
  965. prim.PrimData.PCode = OpenMetaverse.PCode.Prim;
  966. prim.PrimData.State = 0;
  967. if (this.FlexiEntry)
  968. {
  969. prim.Flexible = new Primitive.FlexibleData();
  970. prim.Flexible.Drag = this.FlexiDrag;
  971. prim.Flexible.Force = new Vector3(this.FlexiForceX, this.FlexiForceY, this.FlexiForceZ);
  972. prim.Flexible.Gravity = this.FlexiGravity;
  973. prim.Flexible.Softness = this.FlexiSoftness;
  974. prim.Flexible.Tension = this.FlexiTension;
  975. prim.Flexible.Wind = this.FlexiWind;
  976. }
  977. if (this.LightEntry)
  978. {
  979. prim.Light = new Primitive.LightData();
  980. prim.Light.Color = new Color4(this.LightColorR, this.LightColorG, this.LightColorB, this.LightColorA);
  981. prim.Light.Cutoff = this.LightCutoff;
  982. prim.Light.Falloff = this.LightFalloff;
  983. prim.Light.Intensity = this.LightIntensity;
  984. prim.Light.Radius = this.LightRadius;
  985. }
  986. prim.Textures = this.Textures;
  987. prim.Properties = new Primitive.ObjectProperties();
  988. prim.Properties.Name = "Primitive";
  989. prim.Properties.Description = "";
  990. prim.Properties.CreatorID = UUID.Zero;
  991. prim.Properties.GroupID = UUID.Zero;
  992. prim.Properties.OwnerID = UUID.Zero;
  993. prim.Properties.Permissions = new Permissions();
  994. prim.Properties.SalePrice = 10;
  995. prim.Properties.SaleType = new SaleType();
  996. return prim;
  997. }
  998. }
  999. }