diff --git a/OpenSim/Framework/PrimitiveBaseShape.cs b/OpenSim/Framework/PrimitiveBaseShape.cs index 811f8dbb53..47ad028f6f 100644 --- a/OpenSim/Framework/PrimitiveBaseShape.cs +++ b/OpenSim/Framework/PrimitiveBaseShape.cs @@ -27,13 +27,13 @@ using System; using System.Collections.Generic; -using System.Drawing; -using System.Drawing.Imaging; + using System.IO; using System.Reflection; using System.Xml; using System.Xml.Schema; using System.Xml.Serialization; +using System.Runtime.CompilerServices; using log4net; using OpenMetaverse; using OpenMetaverse.StructuredData; @@ -109,12 +109,12 @@ namespace OpenSim.Framework private ProfileShape _profileShape; private HollowShape _hollowShape; - // Sculpted + //extra parameters Sculpted [XmlIgnore] private UUID _sculptTexture; [XmlIgnore] private byte _sculptType; [XmlIgnore] private byte[] _sculptData = Utils.EmptyBytes; - // Flexi + //extra parameters Flexi [XmlIgnore] private int _flexiSoftness; [XmlIgnore] private float _flexiTension; [XmlIgnore] private float _flexiDrag; @@ -124,7 +124,7 @@ namespace OpenSim.Framework [XmlIgnore] private float _flexiForceY; [XmlIgnore] private float _flexiForceZ; - //Bright n sparkly + //extra parameters light [XmlIgnore] private float _lightColorR; [XmlIgnore] private float _lightColorG; [XmlIgnore] private float _lightColorB; @@ -134,13 +134,13 @@ namespace OpenSim.Framework [XmlIgnore] private float _lightFalloff; [XmlIgnore] private float _lightIntensity = 1.0f; - - // Light Projection Filter + //extra parameters Projection [XmlIgnore] private UUID _projectionTextureID; [XmlIgnore] private float _projectionFOV; [XmlIgnore] private float _projectionFocus; [XmlIgnore] private float _projectionAmb; + //extra parameters extramesh/flag [XmlIgnore] private uint _meshFlags; [XmlIgnore] private bool _flexiEntry; @@ -149,10 +149,19 @@ namespace OpenSim.Framework [XmlIgnore] private bool _projectionEntry; [XmlIgnore] private bool _meshFlagsEntry; + //extra parameters extramesh/flag + [XmlIgnore] + public Primitive.ReflectionProbe ReflectionProbe = null; + + //extra parameters extramesh/flag + [XmlIgnore] + public Primitive.RenderMaterials RenderMaterials = null; + public bool MeshFlagEntry { get { return _meshFlagsEntry;} } + public byte ProfileCurve { get { return (byte)((byte)HollowShape | (byte)ProfileShape); } @@ -993,24 +1002,19 @@ namespace OpenSim.Framework // TODO: Separate scale out from the primitive shape data (after // scaling is supported at the physics engine level) - byte[] scaleBytes = size.GetBytes(); - for (int i = 0; i < scaleBytes.Length; i++) - hash = djb2(hash, scaleBytes[i]); + hash = djb2(hash, size.X); + hash = djb2(hash, size.Y); + hash = djb2(hash, size.Z); // Include LOD in hash, accounting for endianness + hash = djb2(hash, lod); + byte[] lodBytes = new byte[4]; - Buffer.BlockCopy(BitConverter.GetBytes(lod), 0, lodBytes, 0, 4); - if (!BitConverter.IsLittleEndian) - { - Array.Reverse(lodBytes, 0, 4); - } - for (int i = 0; i < lodBytes.Length; i++) - hash = djb2(hash, lodBytes[i]); // include sculpt UUID if (this.SculptEntry) { - scaleBytes = this.SculptTexture.GetBytes(); + byte[] scaleBytes = this.SculptTexture.GetBytes(); for (int i = 0; i < scaleBytes.Length; i++) hash = djb2(hash, scaleBytes[i]); } @@ -1023,13 +1027,22 @@ namespace OpenSim.Framework private ulong djb2(ulong hash, byte c) { - return ((hash << 5) + hash) + (ulong)c; + //return ((hash << 5) + hash) + (ulong)c; + return 33 * hash + (ulong)c; } private ulong djb2(ulong hash, ushort c) { - hash = ((hash << 5) + hash) + (ulong)((byte)c); - return ((hash << 5) + hash) + (ulong)(c >> 8); + //hash = ((hash << 5) + hash) + (ulong)((byte)c); + //return ((hash << 5) + hash) + (ulong)(c >> 8); + return 33 * hash + c; + } + + private ulong djb2(ulong hash, float c) + { + //hash = ((hash << 5) + hash) + (ulong)((byte)c); + //return ((hash << 5) + hash) + (ulong)(c >> 8); + return 33 * hash + (ulong)c.GetHashCode(); } public byte[] ExtraParamsToBytes() @@ -1042,6 +1055,8 @@ namespace OpenSim.Framework const byte ProjectionEP = 0x40; //const byte MeshEP = 0x60; const byte MeshFlagsEP = 0x70; + const byte MaterialsEP = 0x80; + const byte ReflectionProbeEP = 0x90; int TotalBytesLength = 1; // ExtraParamsNum @@ -1075,8 +1090,25 @@ namespace OpenSim.Framework ExtraParamsNum++; TotalBytesLength += 4 + 2 + 4; // data } - byte[] returnBytes = new byte[TotalBytesLength]; + if (ReflectionProbe != null) + { + ExtraParamsNum++; + TotalBytesLength += 9 + 2 + 4; // data + } + + if (RenderMaterials != null) + { + ExtraParamsNum++; + if (RenderMaterials.entries == null || RenderMaterials.entries.Length == 0) + TotalBytesLength++; + else + { + TotalBytesLength += 1 + 17 * RenderMaterials.entries.Length + 2 + 4; // data + } + } + + byte[] returnBytes = new byte[TotalBytesLength]; returnBytes[0] = (byte)ExtraParamsNum; if(ExtraParamsNum == 0) @@ -1131,9 +1163,9 @@ namespace OpenSim.Framework returnBytes[i] = 17; i += 4; - _sculptTexture.GetBytes().CopyTo(returnBytes, i); - i += 16; - returnBytes[i++] = _sculptType; + _sculptTexture.ToBytes(returnBytes, i); + returnBytes[i+ 16] = _sculptType; + i += 17; } if (_projectionEntry) @@ -1157,10 +1189,45 @@ namespace OpenSim.Framework returnBytes[i] = 4; i += 4; Utils.UIntToBytes(_meshFlags, returnBytes, i); + i += 4; + } + + if (ReflectionProbe != null) + { + returnBytes[i] = ReflectionProbeEP; + i += 2; + returnBytes[i] = 9; + i += 4; + Utils.FloatToBytes(ReflectionProbe.Ambiance, returnBytes, i); + Utils.FloatToBytes(ReflectionProbe.ClipDistance, returnBytes, i + 4); + returnBytes[i + 8] = ReflectionProbe.Flags; + i += 9; + } + + if (RenderMaterials != null && RenderMaterials.entries != null && RenderMaterials.entries.Length > 0) + { + returnBytes[i] = MaterialsEP; + i += 2; + + int len = 1 + 17 * RenderMaterials.entries.Length; + returnBytes[i] = (byte)len; + returnBytes[i + 1] = (byte)(len >> 8); + returnBytes[i + 2] = (byte)(len >> 16); + returnBytes[i + 3] = (byte)(len >> 24); + //i += 4; + + returnBytes[i + 4] = (byte)RenderMaterials.entries.Length; + i += 5; + + for (int j = 0; j < RenderMaterials.entries.Length; ++j) + { + returnBytes[i] = RenderMaterials.entries[j].te_index; + RenderMaterials.entries[j].id.ToBytes(returnBytes, i + 1); + i += 17; + } } return returnBytes; - } public void ReadInUpdateExtraParam(ushort type, bool inUse, byte[] data) @@ -1171,6 +1238,8 @@ namespace OpenSim.Framework const ushort ProjectionEP = 0x40; const ushort MeshEP = 0x60; const ushort MeshFlagsEP = 0x70; + const ushort MaterialsEP = 0x80; + const ushort ReflectionProbeEP = 0x90; switch (type) { @@ -1217,6 +1286,22 @@ namespace OpenSim.Framework } ReadMeshFlagsData(data, 0); break; + case ReflectionProbeEP: + if (!inUse) + { + ReflectionProbe = null; + return; + } + ReadReflectionProbe(data, 0); + break; + case MaterialsEP: + if (!inUse) + { + RenderMaterials = null; + return; + } + ReadRenderMaterials(data, 0, data.Length); + break; } } @@ -1230,6 +1315,8 @@ namespace OpenSim.Framework _sculptEntry = false; _projectionEntry = false; _meshFlagsEntry = false; + RenderMaterials = null; + ReflectionProbe = null; if (data.Length == 1) return; @@ -1240,45 +1327,68 @@ namespace OpenSim.Framework const byte ProjectionEP = 0x40; const byte MeshEP = 0x60; const byte MeshFlagsEP = 0x70; + const byte MaterialsEP = 0x80; + const byte ReflectionProbeEP = 0x90; byte extraParamCount = data[0]; int i = 1; for (int k = 0; k < extraParamCount; ++k) { byte epType = data[i]; - i += 6; switch (epType) { case FlexiEP: + i += 6; ReadFlexiData(data, i); i += 16; break; case LightEP: + i += 6; ReadLightData(data, i); i += 16; break; case MeshEP: case SculptEP: + i += 6; ReadSculptData(data, i); i += 17; break; case ProjectionEP: + i += 6; ReadProjectionData(data, i); i += 28; break; case MeshFlagsEP: + i += 6; ReadMeshFlagsData(data, i); i += 4; break; + + case ReflectionProbeEP: + i += 6; + ReadReflectionProbe(data, i); + i += 9; + break; + + case MaterialsEP: + i += 2; + if (data.Length - i >= 4) + { + int size = Utils.BytesToInt(data, i); + i += 4; + i += ReadRenderMaterials(data, i, size); + } + break; } } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ReadSculptData(byte[] data, int pos) { if (data.Length-pos >= 17) @@ -1295,6 +1405,7 @@ namespace OpenSim.Framework } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ReadFlexiData(byte[] data, int pos) { if (data.Length-pos >= 16) @@ -1325,6 +1436,7 @@ namespace OpenSim.Framework } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ReadLightData(byte[] data, int pos) { if (data.Length - pos >= 16) @@ -1355,6 +1467,7 @@ namespace OpenSim.Framework } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ReadProjectionData(byte[] data, int pos) { if (data.Length - pos >= 28) @@ -1375,6 +1488,7 @@ namespace OpenSim.Framework } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ReadMeshFlagsData(byte[] data, int pos) { if (data.Length - pos >= 4) @@ -1389,10 +1503,50 @@ namespace OpenSim.Framework } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ReadReflectionProbe(byte[] data, int pos) + { + if (data.Length - pos >= 9) + { + ReflectionProbe = new Primitive.ReflectionProbe + { + Ambiance = Utils.Clamp(Utils.BytesToFloat(data, pos), 0, 1.0f), + ClipDistance = Utils.Clamp(Utils.BytesToFloat(data, pos + 4), 0, 1024f), + Flags = data[pos + 8] + }; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int ReadRenderMaterials(byte[] data, int pos, int size) + { + if (size > 17) + { + int count = data[pos]; + ++pos; + if (size >= 1 + 17 * count) + { + var entries = new Primitive.RenderMaterials.RenderMaterialEntry[count]; + for (int i = 0; i < count; ++i) + { + entries[i].te_index = data[pos++]; + entries[i].id = new UUID(data, pos); + pos += 16; + } + RenderMaterials = new Primitive.RenderMaterials + { + entries = entries + }; + } + } + return size + 4; + } + /// /// Creates a OpenMetaverse.Primitive and populates it with converted PrimitiveBaseShape values /// /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public Primitive ToOmvPrimitive() { // position and rotation defaults here since they are not available in PrimitiveBaseShape @@ -1536,11 +1690,13 @@ namespace OpenSim.Framework } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void WriteXml(XmlWriter writer) { writer.WriteRaw(ToXml()); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static MediaList FromXml(string rawXml) { MediaList ml = new MediaList(); @@ -1590,6 +1746,7 @@ namespace OpenSim.Framework } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ReadXml(XmlReader reader) { if (reader.IsEmptyElement)