mirror of
https://github.com/opensim/opensim.git
synced 2026-05-15 03:15:41 +08:00
* Important: HttpServer.dll was changed to HttpServer_OpenSim.dll so that the HttpServer references do not conflict if you've copied the OpenMetaverse.Http.dll and requirements to the OpenSimulator bin folder. This means that if you reference HttpServer.dll in any projects, you will need to change the reference to HttpServer_OpenSim.dll. It still uses the Same HttpServer namespace though.
1063 lines
29 KiB
C#
1063 lines
29 KiB
C#
/*
|
|
* Copyright (c) Contributors, http://opensimulator.org/
|
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
* * Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* * Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
* * Neither the name of the OpenSim Project nor the
|
|
* names of its contributors may be used to endorse or promote products
|
|
* derived from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
using System;
|
|
using System.Reflection;
|
|
using System.Xml.Serialization;
|
|
using log4net;
|
|
using OpenMetaverse;
|
|
|
|
namespace OpenSim.Framework
|
|
{
|
|
public enum ProfileShape : byte
|
|
{
|
|
Circle = 0,
|
|
Square = 1,
|
|
IsometricTriangle = 2,
|
|
EquilateralTriangle = 3,
|
|
RightTriangle = 4,
|
|
HalfCircle = 5
|
|
}
|
|
|
|
public enum HollowShape : byte
|
|
{
|
|
Same = 0,
|
|
Circle = 16,
|
|
Square = 32,
|
|
Triangle = 48
|
|
}
|
|
|
|
public enum PCodeEnum : byte
|
|
{
|
|
Primitive = 9,
|
|
Avatar = 47,
|
|
Grass = 95,
|
|
NewTree = 111,
|
|
ParticleSystem = 143,
|
|
Tree = 255
|
|
}
|
|
|
|
public enum Extrusion : byte
|
|
{
|
|
Straight = 16,
|
|
Curve1 = 32,
|
|
Curve2 = 48,
|
|
Flexible = 128
|
|
}
|
|
|
|
[Serializable]
|
|
public class PrimitiveBaseShape
|
|
{
|
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
|
|
|
private static readonly Primitive.TextureEntry m_defaultTexture;
|
|
|
|
private byte[] m_textureEntry;
|
|
|
|
private ushort _pathBegin;
|
|
private byte _pathCurve;
|
|
private ushort _pathEnd;
|
|
private sbyte _pathRadiusOffset;
|
|
private byte _pathRevolutions;
|
|
private byte _pathScaleX;
|
|
private byte _pathScaleY;
|
|
private byte _pathShearX;
|
|
private byte _pathShearY;
|
|
private sbyte _pathSkew;
|
|
private sbyte _pathTaperX;
|
|
private sbyte _pathTaperY;
|
|
private sbyte _pathTwist;
|
|
private sbyte _pathTwistBegin;
|
|
private byte _pCode;
|
|
private ushort _profileBegin;
|
|
private ushort _profileEnd;
|
|
private ushort _profileHollow;
|
|
private Vector3 _scale;
|
|
private byte _state;
|
|
private ProfileShape _profileShape;
|
|
private HollowShape _hollowShape;
|
|
|
|
// Sculpted
|
|
[XmlIgnore] private UUID _sculptTexture = UUID.Zero;
|
|
[XmlIgnore] private byte _sculptType = (byte)0;
|
|
[XmlIgnore] private byte[] _sculptData = new byte[0];
|
|
|
|
// Flexi
|
|
[XmlIgnore] private int _flexiSoftness = 0;
|
|
[XmlIgnore] private float _flexiTension = 0f;
|
|
[XmlIgnore] private float _flexiDrag = 0f;
|
|
[XmlIgnore] private float _flexiGravity = 0f;
|
|
[XmlIgnore] private float _flexiWind = 0f;
|
|
[XmlIgnore] private float _flexiForceX = 0f;
|
|
[XmlIgnore] private float _flexiForceY = 0f;
|
|
[XmlIgnore] private float _flexiForceZ = 0f;
|
|
|
|
//Bright n sparkly
|
|
[XmlIgnore] private float _lightColorR = 0f;
|
|
[XmlIgnore] private float _lightColorG = 0f;
|
|
[XmlIgnore] private float _lightColorB = 0f;
|
|
[XmlIgnore] private float _lightColorA = 1f;
|
|
[XmlIgnore] private float _lightRadius = 0f;
|
|
[XmlIgnore] private float _lightCutoff = 0f;
|
|
[XmlIgnore] private float _lightFalloff = 0f;
|
|
[XmlIgnore] private float _lightIntensity = 1f;
|
|
[XmlIgnore] private bool _flexiEntry = false;
|
|
[XmlIgnore] private bool _lightEntry = false;
|
|
[XmlIgnore] private bool _sculptEntry = false;
|
|
|
|
public byte ProfileCurve
|
|
{
|
|
get { return (byte)((byte)HollowShape | (byte)ProfileShape); }
|
|
|
|
set
|
|
{
|
|
// Handle hollow shape component
|
|
byte hollowShapeByte = (byte)(value & 0xf0);
|
|
|
|
if (!Enum.IsDefined(typeof(HollowShape), hollowShapeByte))
|
|
{
|
|
m_log.WarnFormat(
|
|
"[SHAPE]: Attempt to set a ProfileCurve with a hollow shape value of {0}, which isn't a valid enum. Replacing with default shape.",
|
|
hollowShapeByte);
|
|
|
|
this._hollowShape = HollowShape.Same;
|
|
}
|
|
else
|
|
{
|
|
this._hollowShape = (HollowShape)hollowShapeByte;
|
|
}
|
|
|
|
// Handle profile shape component
|
|
byte profileShapeByte = (byte)(value & 0xf);
|
|
|
|
if (!Enum.IsDefined(typeof(ProfileShape), profileShapeByte))
|
|
{
|
|
m_log.WarnFormat(
|
|
"[SHAPE]: Attempt to set a ProfileCurve with a profile shape value of {0}, which isn't a valid enum. Replacing with square.",
|
|
profileShapeByte);
|
|
|
|
this._profileShape = ProfileShape.Square;
|
|
}
|
|
else
|
|
{
|
|
this._profileShape = (ProfileShape)profileShapeByte;
|
|
}
|
|
}
|
|
}
|
|
|
|
static PrimitiveBaseShape()
|
|
{
|
|
m_defaultTexture =
|
|
new Primitive.TextureEntry(new UUID("89556747-24cb-43ed-920b-47caed15465f"));
|
|
}
|
|
|
|
public PrimitiveBaseShape()
|
|
{
|
|
PCode = (byte) PCodeEnum.Primitive;
|
|
ExtraParams = new byte[1];
|
|
Textures = m_defaultTexture;
|
|
}
|
|
|
|
public PrimitiveBaseShape(bool noShape)
|
|
{
|
|
if (noShape)
|
|
return;
|
|
|
|
PCode = (byte)PCodeEnum.Primitive;
|
|
ExtraParams = new byte[1];
|
|
Textures = m_defaultTexture;
|
|
}
|
|
|
|
[XmlIgnore]
|
|
public Primitive.TextureEntry Textures
|
|
{
|
|
get
|
|
{
|
|
//m_log.DebugFormat("[PRIMITIVE BASE SHAPE]: get m_textureEntry length {0}", m_textureEntry.Length);
|
|
return new Primitive.TextureEntry(m_textureEntry, 0, m_textureEntry.Length);
|
|
}
|
|
|
|
set { m_textureEntry = value.GetBytes(); }
|
|
}
|
|
|
|
public byte[] TextureEntry
|
|
{
|
|
get { return m_textureEntry; }
|
|
|
|
set
|
|
{
|
|
if (value == null)
|
|
m_textureEntry = new byte[1];
|
|
else
|
|
m_textureEntry = value;
|
|
}
|
|
}
|
|
|
|
public static PrimitiveBaseShape Default
|
|
{
|
|
get
|
|
{
|
|
PrimitiveBaseShape boxShape = CreateBox();
|
|
|
|
boxShape.SetScale(0.5f);
|
|
|
|
return boxShape;
|
|
}
|
|
}
|
|
|
|
public static PrimitiveBaseShape Create()
|
|
{
|
|
PrimitiveBaseShape shape = new PrimitiveBaseShape();
|
|
return shape;
|
|
}
|
|
|
|
public static PrimitiveBaseShape CreateBox()
|
|
{
|
|
PrimitiveBaseShape shape = Create();
|
|
|
|
shape._pathCurve = (byte) Extrusion.Straight;
|
|
shape._profileShape = ProfileShape.Square;
|
|
shape._pathScaleX = 100;
|
|
shape._pathScaleY = 100;
|
|
|
|
return shape;
|
|
}
|
|
|
|
public static PrimitiveBaseShape CreateSphere()
|
|
{
|
|
PrimitiveBaseShape shape = Create();
|
|
|
|
shape._pathCurve = (byte) Extrusion.Curve1;
|
|
shape._profileShape = ProfileShape.HalfCircle;
|
|
shape._pathScaleX = 100;
|
|
shape._pathScaleY = 100;
|
|
|
|
return shape;
|
|
}
|
|
|
|
public static PrimitiveBaseShape CreateCylinder()
|
|
{
|
|
PrimitiveBaseShape shape = Create();
|
|
|
|
shape._pathCurve = (byte) Extrusion.Curve1;
|
|
shape._profileShape = ProfileShape.Square;
|
|
|
|
shape._pathScaleX = 100;
|
|
shape._pathScaleY = 100;
|
|
|
|
return shape;
|
|
}
|
|
|
|
public void SetScale(float side)
|
|
{
|
|
_scale = new Vector3(side, side, side);
|
|
}
|
|
|
|
public void SetHeigth(float heigth)
|
|
{
|
|
_scale.Z = heigth;
|
|
}
|
|
|
|
public void SetRadius(float radius)
|
|
{
|
|
_scale.X = _scale.Y = radius * 2f;
|
|
}
|
|
|
|
// TODO: void returns need to change of course
|
|
public virtual void GetMesh()
|
|
{
|
|
}
|
|
|
|
public PrimitiveBaseShape Copy()
|
|
{
|
|
return (PrimitiveBaseShape) MemberwiseClone();
|
|
}
|
|
|
|
public static PrimitiveBaseShape CreateCylinder(float radius, float heigth)
|
|
{
|
|
PrimitiveBaseShape shape = CreateCylinder();
|
|
|
|
shape.SetHeigth(heigth);
|
|
shape.SetRadius(radius);
|
|
|
|
return shape;
|
|
}
|
|
|
|
public void SetPathRange(Vector3 pathRange)
|
|
{
|
|
_pathBegin = Primitive.PackBeginCut(pathRange.X);
|
|
_pathEnd = Primitive.PackEndCut(pathRange.Y);
|
|
}
|
|
|
|
public void SetSculptData(byte sculptType, UUID SculptTextureUUID)
|
|
{
|
|
_sculptType = sculptType;
|
|
_sculptTexture = SculptTextureUUID;
|
|
}
|
|
|
|
public void SetProfileRange(Vector3 profileRange)
|
|
{
|
|
_profileBegin = Primitive.PackBeginCut(profileRange.X);
|
|
_profileEnd = Primitive.PackEndCut(profileRange.Y);
|
|
}
|
|
|
|
public byte[] ExtraParams
|
|
{
|
|
get
|
|
{
|
|
return ExtraParamsToBytes();
|
|
}
|
|
set
|
|
{
|
|
ReadInExtraParamsBytes(value);
|
|
}
|
|
}
|
|
|
|
public ushort PathBegin {
|
|
get {
|
|
return _pathBegin;
|
|
}
|
|
set {
|
|
_pathBegin = value;
|
|
}
|
|
}
|
|
|
|
public byte PathCurve {
|
|
get {
|
|
return _pathCurve;
|
|
}
|
|
set {
|
|
_pathCurve = value;
|
|
}
|
|
}
|
|
|
|
public ushort PathEnd {
|
|
get {
|
|
return _pathEnd;
|
|
}
|
|
set {
|
|
_pathEnd = value;
|
|
}
|
|
}
|
|
|
|
public sbyte PathRadiusOffset {
|
|
get {
|
|
return _pathRadiusOffset;
|
|
}
|
|
set {
|
|
_pathRadiusOffset = value;
|
|
}
|
|
}
|
|
|
|
public byte PathRevolutions {
|
|
get {
|
|
return _pathRevolutions;
|
|
}
|
|
set {
|
|
_pathRevolutions = value;
|
|
}
|
|
}
|
|
|
|
public byte PathScaleX {
|
|
get {
|
|
return _pathScaleX;
|
|
}
|
|
set {
|
|
_pathScaleX = value;
|
|
}
|
|
}
|
|
|
|
public byte PathScaleY {
|
|
get {
|
|
return _pathScaleY;
|
|
}
|
|
set {
|
|
_pathScaleY = value;
|
|
}
|
|
}
|
|
|
|
public byte PathShearX {
|
|
get {
|
|
return _pathShearX;
|
|
}
|
|
set {
|
|
_pathShearX = value;
|
|
}
|
|
}
|
|
|
|
public byte PathShearY {
|
|
get {
|
|
return _pathShearY;
|
|
}
|
|
set {
|
|
_pathShearY = value;
|
|
}
|
|
}
|
|
|
|
public sbyte PathSkew {
|
|
get {
|
|
return _pathSkew;
|
|
}
|
|
set {
|
|
_pathSkew = value;
|
|
}
|
|
}
|
|
|
|
public sbyte PathTaperX {
|
|
get {
|
|
return _pathTaperX;
|
|
}
|
|
set {
|
|
_pathTaperX = value;
|
|
}
|
|
}
|
|
|
|
public sbyte PathTaperY {
|
|
get {
|
|
return _pathTaperY;
|
|
}
|
|
set {
|
|
_pathTaperY = value;
|
|
}
|
|
}
|
|
|
|
public sbyte PathTwist {
|
|
get {
|
|
return _pathTwist;
|
|
}
|
|
set {
|
|
_pathTwist = value;
|
|
}
|
|
}
|
|
|
|
public sbyte PathTwistBegin {
|
|
get {
|
|
return _pathTwistBegin;
|
|
}
|
|
set {
|
|
_pathTwistBegin = value;
|
|
}
|
|
}
|
|
|
|
public byte PCode {
|
|
get {
|
|
return _pCode;
|
|
}
|
|
set {
|
|
_pCode = value;
|
|
}
|
|
}
|
|
|
|
public ushort ProfileBegin {
|
|
get {
|
|
return _profileBegin;
|
|
}
|
|
set {
|
|
_profileBegin = value;
|
|
}
|
|
}
|
|
|
|
public ushort ProfileEnd {
|
|
get {
|
|
return _profileEnd;
|
|
}
|
|
set {
|
|
_profileEnd = value;
|
|
}
|
|
}
|
|
|
|
public ushort ProfileHollow {
|
|
get {
|
|
return _profileHollow;
|
|
}
|
|
set {
|
|
_profileHollow = value;
|
|
}
|
|
}
|
|
|
|
public Vector3 Scale {
|
|
get {
|
|
return _scale;
|
|
}
|
|
set {
|
|
_scale = value;
|
|
}
|
|
}
|
|
|
|
public byte State {
|
|
get {
|
|
return _state;
|
|
}
|
|
set {
|
|
_state = value;
|
|
}
|
|
}
|
|
|
|
public ProfileShape ProfileShape {
|
|
get {
|
|
return _profileShape;
|
|
}
|
|
set {
|
|
_profileShape = value;
|
|
}
|
|
}
|
|
|
|
public HollowShape HollowShape {
|
|
get {
|
|
return _hollowShape;
|
|
}
|
|
set {
|
|
_hollowShape = value;
|
|
}
|
|
}
|
|
|
|
public UUID SculptTexture {
|
|
get {
|
|
return _sculptTexture;
|
|
}
|
|
set {
|
|
_sculptTexture = value;
|
|
}
|
|
}
|
|
|
|
public byte SculptType {
|
|
get {
|
|
return _sculptType;
|
|
}
|
|
set {
|
|
_sculptType = value;
|
|
}
|
|
}
|
|
|
|
public byte[] SculptData {
|
|
get {
|
|
return _sculptData;
|
|
}
|
|
set {
|
|
_sculptData = value;
|
|
}
|
|
}
|
|
|
|
public int FlexiSoftness {
|
|
get {
|
|
return _flexiSoftness;
|
|
}
|
|
set {
|
|
_flexiSoftness = value;
|
|
}
|
|
}
|
|
|
|
public float FlexiTension {
|
|
get {
|
|
return _flexiTension;
|
|
}
|
|
set {
|
|
_flexiTension = value;
|
|
}
|
|
}
|
|
|
|
public float FlexiDrag {
|
|
get {
|
|
return _flexiDrag;
|
|
}
|
|
set {
|
|
_flexiDrag = value;
|
|
}
|
|
}
|
|
|
|
public float FlexiGravity {
|
|
get {
|
|
return _flexiGravity;
|
|
}
|
|
set {
|
|
_flexiGravity = value;
|
|
}
|
|
}
|
|
|
|
public float FlexiWind {
|
|
get {
|
|
return _flexiWind;
|
|
}
|
|
set {
|
|
_flexiWind = value;
|
|
}
|
|
}
|
|
|
|
public float FlexiForceX {
|
|
get {
|
|
return _flexiForceX;
|
|
}
|
|
set {
|
|
_flexiForceX = value;
|
|
}
|
|
}
|
|
|
|
public float FlexiForceY {
|
|
get {
|
|
return _flexiForceY;
|
|
}
|
|
set {
|
|
_flexiForceY = value;
|
|
}
|
|
}
|
|
|
|
public float FlexiForceZ {
|
|
get {
|
|
return _flexiForceZ;
|
|
}
|
|
set {
|
|
_flexiForceZ = value;
|
|
}
|
|
}
|
|
|
|
public float LightColorR {
|
|
get {
|
|
return _lightColorR;
|
|
}
|
|
set {
|
|
_lightColorR = value;
|
|
}
|
|
}
|
|
|
|
public float LightColorG {
|
|
get {
|
|
return _lightColorG;
|
|
}
|
|
set {
|
|
_lightColorG = value;
|
|
}
|
|
}
|
|
|
|
public float LightColorB {
|
|
get {
|
|
return _lightColorB;
|
|
}
|
|
set {
|
|
_lightColorB = value;
|
|
}
|
|
}
|
|
|
|
public float LightColorA {
|
|
get {
|
|
return _lightColorA;
|
|
}
|
|
set {
|
|
_lightColorA = value;
|
|
}
|
|
}
|
|
|
|
public float LightRadius {
|
|
get {
|
|
return _lightRadius;
|
|
}
|
|
set {
|
|
_lightRadius = value;
|
|
}
|
|
}
|
|
|
|
public float LightCutoff {
|
|
get {
|
|
return _lightCutoff;
|
|
}
|
|
set {
|
|
_lightCutoff = value;
|
|
}
|
|
}
|
|
|
|
public float LightFalloff {
|
|
get {
|
|
return _lightFalloff;
|
|
}
|
|
set {
|
|
_lightFalloff = value;
|
|
}
|
|
}
|
|
|
|
public float LightIntensity {
|
|
get {
|
|
return _lightIntensity;
|
|
}
|
|
set {
|
|
_lightIntensity = value;
|
|
}
|
|
}
|
|
|
|
public bool FlexiEntry {
|
|
get {
|
|
return _flexiEntry;
|
|
}
|
|
set {
|
|
_flexiEntry = value;
|
|
}
|
|
}
|
|
|
|
public bool LightEntry {
|
|
get {
|
|
return _lightEntry;
|
|
}
|
|
set {
|
|
_lightEntry = value;
|
|
}
|
|
}
|
|
|
|
public bool SculptEntry {
|
|
get {
|
|
return _sculptEntry;
|
|
}
|
|
set {
|
|
_sculptEntry = value;
|
|
}
|
|
}
|
|
|
|
public byte[] ExtraParamsToBytes()
|
|
{
|
|
ushort FlexiEP = 0x10;
|
|
ushort LightEP = 0x20;
|
|
ushort SculptEP = 0x30;
|
|
|
|
int i = 0;
|
|
uint TotalBytesLength = 1; // ExtraParamsNum
|
|
|
|
uint ExtraParamsNum = 0;
|
|
if (_flexiEntry)
|
|
{
|
|
ExtraParamsNum++;
|
|
TotalBytesLength += 16;// data
|
|
TotalBytesLength += 2 + 4; // type
|
|
}
|
|
if (_lightEntry)
|
|
{
|
|
ExtraParamsNum++;
|
|
TotalBytesLength += 16;// data
|
|
TotalBytesLength += 2 + 4; // type
|
|
}
|
|
if (_sculptEntry)
|
|
{
|
|
ExtraParamsNum++;
|
|
TotalBytesLength += 17;// data
|
|
TotalBytesLength += 2 + 4; // type
|
|
}
|
|
|
|
byte[] returnbytes = new byte[TotalBytesLength];
|
|
|
|
|
|
// uint paramlength = ExtraParamsNum;
|
|
|
|
// Stick in the number of parameters
|
|
returnbytes[i++] = (byte)ExtraParamsNum;
|
|
|
|
if (_flexiEntry)
|
|
{
|
|
byte[] FlexiData = GetFlexiBytes();
|
|
|
|
returnbytes[i++] = (byte)(FlexiEP % 256);
|
|
returnbytes[i++] = (byte)((FlexiEP >> 8) % 256);
|
|
|
|
returnbytes[i++] = (byte)(FlexiData.Length % 256);
|
|
returnbytes[i++] = (byte)((FlexiData.Length >> 8) % 256);
|
|
returnbytes[i++] = (byte)((FlexiData.Length >> 16) % 256);
|
|
returnbytes[i++] = (byte)((FlexiData.Length >> 24) % 256);
|
|
Array.Copy(FlexiData, 0, returnbytes, i, FlexiData.Length);
|
|
i += FlexiData.Length;
|
|
}
|
|
if (_lightEntry)
|
|
{
|
|
byte[] LightData = GetLightBytes();
|
|
|
|
returnbytes[i++] = (byte)(LightEP % 256);
|
|
returnbytes[i++] = (byte)((LightEP >> 8) % 256);
|
|
|
|
returnbytes[i++] = (byte)(LightData.Length % 256);
|
|
returnbytes[i++] = (byte)((LightData.Length >> 8) % 256);
|
|
returnbytes[i++] = (byte)((LightData.Length >> 16) % 256);
|
|
returnbytes[i++] = (byte)((LightData.Length >> 24) % 256);
|
|
Array.Copy(LightData, 0, returnbytes, i, LightData.Length);
|
|
i += LightData.Length;
|
|
}
|
|
if (_sculptEntry)
|
|
{
|
|
byte[] SculptData = GetSculptBytes();
|
|
|
|
returnbytes[i++] = (byte)(SculptEP % 256);
|
|
returnbytes[i++] = (byte)((SculptEP >> 8) % 256);
|
|
|
|
returnbytes[i++] = (byte)(SculptData.Length % 256);
|
|
returnbytes[i++] = (byte)((SculptData.Length >> 8) % 256);
|
|
returnbytes[i++] = (byte)((SculptData.Length >> 16) % 256);
|
|
returnbytes[i++] = (byte)((SculptData.Length >> 24) % 256);
|
|
Array.Copy(SculptData, 0, returnbytes, i, SculptData.Length);
|
|
i += SculptData.Length;
|
|
}
|
|
|
|
if (!_flexiEntry && !_lightEntry && !_sculptEntry)
|
|
{
|
|
byte[] returnbyte = new byte[1];
|
|
returnbyte[0] = 0;
|
|
return returnbyte;
|
|
}
|
|
|
|
|
|
return returnbytes;
|
|
//m_log.Info("[EXTRAPARAMS]: Length = " + m_shape.ExtraParams.Length.ToString());
|
|
|
|
}
|
|
|
|
public void ReadInUpdateExtraParam(ushort type, bool inUse, byte[] data)
|
|
{
|
|
const ushort FlexiEP = 0x10;
|
|
const ushort LightEP = 0x20;
|
|
const ushort SculptEP = 0x30;
|
|
|
|
switch (type)
|
|
{
|
|
case FlexiEP:
|
|
if (!inUse)
|
|
{
|
|
_flexiEntry = false;
|
|
return;
|
|
}
|
|
ReadFlexiData(data, 0);
|
|
break;
|
|
|
|
case LightEP:
|
|
if (!inUse)
|
|
{
|
|
_lightEntry = false;
|
|
return;
|
|
}
|
|
ReadLightData(data, 0);
|
|
break;
|
|
|
|
case SculptEP:
|
|
if (!inUse)
|
|
{
|
|
_sculptEntry = false;
|
|
return;
|
|
}
|
|
ReadSculptData(data, 0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
public void ReadInExtraParamsBytes(byte[] data)
|
|
{
|
|
if (data == null || data.Length == 1)
|
|
return;
|
|
|
|
const ushort FlexiEP = 0x10;
|
|
const ushort LightEP = 0x20;
|
|
const ushort SculptEP = 0x30;
|
|
|
|
bool lGotFlexi = false;
|
|
bool lGotLight = false;
|
|
bool lGotSculpt = false;
|
|
|
|
int i = 0;
|
|
byte extraParamCount = 0;
|
|
if (data.Length > 0)
|
|
{
|
|
extraParamCount = data[i++];
|
|
}
|
|
|
|
|
|
for (int k = 0; k < extraParamCount; k++)
|
|
{
|
|
ushort epType = Utils.BytesToUInt16(data, i);
|
|
|
|
i += 2;
|
|
// uint paramLength = Helpers.BytesToUIntBig(data, i);
|
|
|
|
i += 4;
|
|
switch (epType)
|
|
{
|
|
case FlexiEP:
|
|
ReadFlexiData(data, i);
|
|
i += 16;
|
|
lGotFlexi = true;
|
|
break;
|
|
|
|
case LightEP:
|
|
ReadLightData(data, i);
|
|
i += 16;
|
|
lGotLight = true;
|
|
break;
|
|
|
|
case SculptEP:
|
|
ReadSculptData(data, i);
|
|
i += 17;
|
|
lGotSculpt = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!lGotFlexi)
|
|
_flexiEntry = false;
|
|
if (!lGotLight)
|
|
_lightEntry = false;
|
|
if (!lGotSculpt)
|
|
_sculptEntry = false;
|
|
|
|
}
|
|
|
|
public void ReadSculptData(byte[] data, int pos)
|
|
{
|
|
byte[] SculptTextureUUID = new byte[16];
|
|
UUID SculptUUID = UUID.Zero;
|
|
byte SculptTypel = data[16+pos];
|
|
|
|
if (data.Length+pos >= 17)
|
|
{
|
|
_sculptEntry = true;
|
|
SculptTextureUUID = new byte[16];
|
|
SculptTypel = data[16 + pos];
|
|
Array.Copy(data, pos, SculptTextureUUID,0, 16);
|
|
SculptUUID = new UUID(SculptTextureUUID, 0);
|
|
}
|
|
else
|
|
{
|
|
_sculptEntry = false;
|
|
SculptUUID = UUID.Zero;
|
|
SculptTypel = 0x00;
|
|
}
|
|
|
|
if (_sculptEntry)
|
|
{
|
|
if (_sculptType != (byte)1 && _sculptType != (byte)2 && _sculptType != (byte)3 && _sculptType != (byte)4)
|
|
_sculptType = 4;
|
|
}
|
|
_sculptTexture = SculptUUID;
|
|
_sculptType = SculptTypel;
|
|
//m_log.Info("[SCULPT]:" + SculptUUID.ToString());
|
|
}
|
|
|
|
public byte[] GetSculptBytes()
|
|
{
|
|
byte[] data = new byte[17];
|
|
|
|
_sculptTexture.GetBytes().CopyTo(data, 0);
|
|
data[16] = (byte)_sculptType;
|
|
|
|
return data;
|
|
}
|
|
|
|
public void ReadFlexiData(byte[] data, int pos)
|
|
{
|
|
if (data.Length-pos >= 16)
|
|
{
|
|
_flexiEntry = true;
|
|
_flexiSoftness = ((data[pos] & 0x80) >> 6) | ((data[pos + 1] & 0x80) >> 7);
|
|
|
|
_flexiTension = (float)(data[pos++] & 0x7F) / 10.0f;
|
|
_flexiDrag = (float)(data[pos++] & 0x7F) / 10.0f;
|
|
_flexiGravity = (float)(data[pos++] / 10.0f) - 10.0f;
|
|
_flexiWind = (float)data[pos++] / 10.0f;
|
|
Vector3 lForce = new Vector3(data, pos);
|
|
_flexiForceX = lForce.X;
|
|
_flexiForceY = lForce.Y;
|
|
_flexiForceZ = lForce.Z;
|
|
}
|
|
else
|
|
{
|
|
_flexiEntry = false;
|
|
_flexiSoftness = 0;
|
|
|
|
_flexiTension = 0.0f;
|
|
_flexiDrag = 0.0f;
|
|
_flexiGravity = 0.0f;
|
|
_flexiWind = 0.0f;
|
|
_flexiForceX = 0f;
|
|
_flexiForceY = 0f;
|
|
_flexiForceZ = 0f;
|
|
}
|
|
}
|
|
|
|
public byte[] GetFlexiBytes()
|
|
{
|
|
byte[] data = new byte[16];
|
|
int i = 0;
|
|
|
|
// Softness is packed in the upper bits of tension and drag
|
|
data[i] = (byte)((_flexiSoftness & 2) << 6);
|
|
data[i + 1] = (byte)((_flexiSoftness & 1) << 7);
|
|
|
|
data[i++] |= (byte)((byte)(_flexiTension * 10.01f) & 0x7F);
|
|
data[i++] |= (byte)((byte)(_flexiDrag * 10.01f) & 0x7F);
|
|
data[i++] = (byte)((_flexiGravity + 10.0f) * 10.01f);
|
|
data[i++] = (byte)(_flexiWind * 10.01f);
|
|
Vector3 lForce = new Vector3(_flexiForceX, _flexiForceY, _flexiForceZ);
|
|
lForce.GetBytes().CopyTo(data, i);
|
|
|
|
return data;
|
|
}
|
|
|
|
public void ReadLightData(byte[] data, int pos)
|
|
{
|
|
if (data.Length - pos >= 16)
|
|
{
|
|
_lightEntry = true;
|
|
Color4 lColor = new Color4(data, pos, false);
|
|
_lightIntensity = lColor.A;
|
|
_lightColorA = 1f;
|
|
_lightColorR = lColor.R;
|
|
_lightColorG = lColor.G;
|
|
_lightColorB = lColor.B;
|
|
|
|
_lightRadius = Utils.BytesToFloat(data, pos + 4);
|
|
_lightCutoff = Utils.BytesToFloat(data, pos + 8);
|
|
_lightFalloff = Utils.BytesToFloat(data, pos + 12);
|
|
}
|
|
else
|
|
{
|
|
_lightEntry = false;
|
|
_lightColorA = 1f;
|
|
_lightColorR = 0f;
|
|
_lightColorG = 0f;
|
|
_lightColorB = 0f;
|
|
_lightRadius = 0f;
|
|
_lightCutoff = 0f;
|
|
_lightFalloff = 0f;
|
|
_lightIntensity = 0f;
|
|
}
|
|
}
|
|
|
|
public byte[] GetLightBytes()
|
|
{
|
|
byte[] data = new byte[16];
|
|
|
|
// Alpha channel in color is intensity
|
|
Color4 tmpColor = new Color4(_lightColorR,_lightColorG,_lightColorB,_lightIntensity);
|
|
|
|
tmpColor.GetBytes().CopyTo(data, 0);
|
|
Utils.FloatToBytes(_lightRadius).CopyTo(data, 4);
|
|
Utils.FloatToBytes(_lightCutoff).CopyTo(data, 8);
|
|
Utils.FloatToBytes(_lightFalloff).CopyTo(data, 12);
|
|
|
|
return data;
|
|
}
|
|
}
|
|
}
|