corrade-vassal – Rev 16
?pathlinks?
/*
* Copyright (c) 2006-2014, openmetaverse.org
* All rights reserved.
*
* - 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.
* - Neither the name of the openmetaverse.org 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR 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.Collections.Generic;
using OpenMetaverse.Rendering;
using OpenMetaverse.StructuredData;
namespace OpenMetaverse.ImportExport
{
public class ModelMaterial
{
public string ID;
public Color4 DiffuseColor = Color4.White;
public string Texture;
public byte[] TextureData;
}
public class ModelFace
{
public List<Vertex> Vertices = new List<Vertex>();
public List<uint> Indices = new List<uint>();
public string MaterialID = string.Empty;
public ModelMaterial Material = new ModelMaterial();
Dictionary<Vertex, int> LookUp = new Dictionary<Vertex, int>();
public void AddVertex(Vertex v)
{
int index;
if (LookUp.ContainsKey(v))
{
index = LookUp[v];
}
else
{
index = Vertices.Count;
Vertices.Add(v);
LookUp[v] = index;
}
Indices.Add((uint)index);
}
}
public class ModelPrim
{
public List<Vector3> Positions;
public Vector3 BoundMin = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
public Vector3 BoundMax = new Vector3(float.MinValue, float.MinValue, float.MinValue);
public Vector3 Position;
public Vector3 Scale;
public Quaternion Rotation = Quaternion.Identity;
public List<ModelFace> Faces = new List<ModelFace>();
public string ID;
public byte[] Asset;
public void CreateAsset(UUID creator)
{
OSDMap header = new OSDMap();
header["version"] = 1;
header["creator"] = creator;
header["date"] = DateTime.Now;
OSDArray faces = new OSDArray();
foreach (var face in Faces)
{
OSDMap faceMap = new OSDMap();
// Find UV min/max
Vector2 uvMin = new Vector2(float.MaxValue, float.MaxValue);
Vector2 uvMax = new Vector2(float.MinValue, float.MinValue);
foreach (var v in face.Vertices)
{
if (v.TexCoord.X < uvMin.X) uvMin.X = v.TexCoord.X;
if (v.TexCoord.Y < uvMin.Y) uvMin.Y = v.TexCoord.Y;
if (v.TexCoord.X > uvMax.X) uvMax.X = v.TexCoord.X;
if (v.TexCoord.Y > uvMax.Y) uvMax.Y = v.TexCoord.Y;
}
OSDMap uvDomain = new OSDMap();
uvDomain["Min"] = uvMin;
uvDomain["Max"] = uvMax;
faceMap["TexCoord0Domain"] = uvDomain;
OSDMap positionDomain = new OSDMap();
positionDomain["Min"] = new Vector3(-0.5f, -0.5f, -0.5f);
positionDomain["Max"] = new Vector3(0.5f, 0.5f, 0.5f);
faceMap["PositionDomain"] = positionDomain;
List<byte> posBytes = new List<byte>(face.Vertices.Count * sizeof(UInt16) * 3);
List<byte> norBytes = new List<byte>(face.Vertices.Count * sizeof(UInt16) * 3);
List<byte> uvBytes = new List<byte>(face.Vertices.Count * sizeof(UInt16) * 2);
foreach (var v in face.Vertices)
{
posBytes.AddRange(Utils.UInt16ToBytes(Utils.FloatToUInt16(v.Position.X, -0.5f, 0.5f)));
posBytes.AddRange(Utils.UInt16ToBytes(Utils.FloatToUInt16(v.Position.Y, -0.5f, 0.5f)));
posBytes.AddRange(Utils.UInt16ToBytes(Utils.FloatToUInt16(v.Position.Z, -0.5f, 0.5f)));
norBytes.AddRange(Utils.UInt16ToBytes(Utils.FloatToUInt16(v.Normal.X, -1f, 1f)));
norBytes.AddRange(Utils.UInt16ToBytes(Utils.FloatToUInt16(v.Normal.Y, -1f, 1f)));
norBytes.AddRange(Utils.UInt16ToBytes(Utils.FloatToUInt16(v.Normal.Z, -1f, 1f)));
uvBytes.AddRange(Utils.UInt16ToBytes(Utils.FloatToUInt16(v.TexCoord.X, uvMin.X, uvMax.X)));
uvBytes.AddRange(Utils.UInt16ToBytes(Utils.FloatToUInt16(v.TexCoord.Y, uvMin.Y, uvMax.Y)));
}
faceMap["Position"] = posBytes.ToArray();
faceMap["Normal"] = norBytes.ToArray();
faceMap["TexCoord0"] = uvBytes.ToArray();
List<byte> indexBytes = new List<byte>(face.Indices.Count * sizeof(UInt16));
foreach (var t in face.Indices)
{
indexBytes.AddRange(Utils.UInt16ToBytes((ushort)t));
}
faceMap["TriangleList"] = indexBytes.ToArray();
faces.Add(faceMap);
}
byte[] physicStubBytes = Helpers.ZCompressOSD(PhysicsStub());
byte[] meshBytes = Helpers.ZCompressOSD(faces);
int n = 0;
OSDMap lodParms = new OSDMap();
lodParms["offset"] = n;
lodParms["size"] = meshBytes.Length;
header["high_lod"] = lodParms;
n += meshBytes.Length;
lodParms = new OSDMap();
lodParms["offset"] = n;
lodParms["size"] = physicStubBytes.Length;
header["physics_convex"] = lodParms;
n += physicStubBytes.Length;
byte[] headerBytes = OSDParser.SerializeLLSDBinary(header, false);
n += headerBytes.Length;
Asset = new byte[n];
int offset = 0;
Buffer.BlockCopy(headerBytes, 0, Asset, offset, headerBytes.Length);
offset += headerBytes.Length;
Buffer.BlockCopy(meshBytes, 0, Asset, offset, meshBytes.Length);
offset += meshBytes.Length;
Buffer.BlockCopy(physicStubBytes, 0, Asset, offset, physicStubBytes.Length);
offset += physicStubBytes.Length;
}
public static OSD PhysicsStub()
{
OSDMap ret = new OSDMap();
ret["Max"] = new Vector3(0.5f, 0.5f, 0.5f);
ret["Min"] = new Vector3(-0.5f, -0.5f, -0.5f);
ret["BoundingVerts"] = new byte[] { 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 255, 127, 0, 0, 255, 255, 255, 127, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 127, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 0, 0, 255, 255 };
return ret;
}
}
}
Generated by GNU Enscript 1.6.5.90.