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)